blob: 9b199874811c1dfbe9767e87ef61b5e6bcb13b83 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 IONA Technologies PLC
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IONA Technologies PLC - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.ws.internal.cxf.core.utils;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.wsdl.Definition;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.xml.namespace.QName;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jst.ws.internal.common.J2EEUtils;
import org.eclipse.jst.ws.internal.cxf.core.CXFCorePlugin;
import org.eclipse.jst.ws.internal.cxf.core.model.CXFDataModel;
import org.eclipse.jst.ws.internal.cxf.core.model.WSDL2JavaDataModel;
import org.eclipse.jst.ws.jaxws.core.utils.WSDLUtils;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
@SuppressWarnings("restriction")
public final class SpringUtils {
private static Namespace SPRING_BEANS_NS = Namespace
.getNamespace("http://www.springframework.org/schema/beans"); //$NON-NLS-1$
private static Namespace XMLNS_XSI = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); //$NON-NLS-1$ //$NON-NLS-2$
private static Namespace JAXWS_NS = Namespace.getNamespace("jaxws", "http://cxf.apache.org/jaxws"); //$NON-NLS-1$ //$NON-NLS-2$
private static Namespace SOAP_NS = Namespace.getNamespace("soap", "http://cxf.apache.org/bindings/soap"); //$NON-NLS-1$ //$NON-NLS-2$
private static String DOC_ROOT = "beans"; //$NON-NLS-1$
private SpringUtils() {
}
public static IFile getBeansFile(IProject project) throws IOException {
IFile beansFile = null;
IPath webContentPath = J2EEUtils.getWebContentPath(project);
if (!webContentPath.hasTrailingSeparator()) {
webContentPath = webContentPath.addTrailingSeparator();
IPath webINFPath = webContentPath.append(new Path("WEB-INF/")); //$NON-NLS-1$
IFolder webINFFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(webINFPath);
beansFile = webINFFolder.getFile("beans.xml"); //$NON-NLS-1$
if (!beansFile.exists()) {
try {
IProgressMonitor progressMonitor = new NullProgressMonitor();
beansFile.create(new ByteArrayInputStream(new byte[] {}), true, progressMonitor);
createBaseBeansFile(beansFile);
} catch (CoreException ce) {
CXFCorePlugin.log(ce);
}
}
}
return beansFile;
}
public static IFile getBeansFile(String projectName) throws IOException {
return SpringUtils.getBeansFile(FileUtils.getProject(projectName));
}
/**
* Returns a handle to the cxf-servlet file in the Web projects WEB-INF
* folder.
*
* @param project
* @return {@link IFile}
*/
public static IFile getCXFServlet(IProject project) throws IOException {
IFile cxfServlet = null;
IPath webContentPath = J2EEUtils.getWebContentPath(project);
if (!webContentPath.hasTrailingSeparator()) {
webContentPath = webContentPath.addTrailingSeparator();
IPath webINFPath = webContentPath.append(new Path("WEB-INF/")); //$NON-NLS-1$
IFolder webINFFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(webINFPath);
cxfServlet = webINFFolder.getFile("cxf-servlet.xml"); //$NON-NLS-1$
if (!cxfServlet.exists()) {
try {
IProgressMonitor progressMonitor = new NullProgressMonitor();
cxfServlet.create(new ByteArrayInputStream(new byte[] {}), true, progressMonitor);
createBaseCXFServletFile(cxfServlet);
} catch (CoreException ce) {
CXFCorePlugin.log(ce.getStatus());
}
}
}
return cxfServlet;
}
public static IFile getCXFServlet(String projectName) throws IOException {
return SpringUtils.getCXFServlet(FileUtils.getProject(projectName));
}
private static void createBaseCXFServletFile(IFile cxfServlet) throws IOException {
Element beans = new Element(DOC_ROOT);
beans.setNamespace(SPRING_BEANS_NS);
beans.addNamespaceDeclaration(XMLNS_XSI);
beans.addNamespaceDeclaration(JAXWS_NS);
beans.addNamespaceDeclaration(SOAP_NS);
Attribute schemaLocation = new Attribute(
"schemaLocation", //$NON-NLS-1$
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd " //$NON-NLS-1$
+ "http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd " //$NON-NLS-1$
+ "http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd", XMLNS_XSI); //$NON-NLS-1$
beans.setAttribute(schemaLocation);
writeConfig(new Document(beans), cxfServlet);
}
private static void createBaseBeansFile(IFile beansFile) throws IOException {
Element beans = new Element(DOC_ROOT);
beans.setNamespace(SPRING_BEANS_NS);
beans.addNamespaceDeclaration(XMLNS_XSI);
beans.addNamespaceDeclaration(JAXWS_NS);
Attribute schemaLocation = new Attribute(
"schemaLocation", //$NON-NLS-1$
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd " //$NON-NLS-1$
+ "http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd", XMLNS_XSI); //$NON-NLS-1$
beans.setAttribute(schemaLocation);
Element importCXFResource = new Element("import", SPRING_BEANS_NS); //$NON-NLS-1$
importCXFResource.setAttribute("resource", "classpath:META-INF/cxf/cxf.xml"); //$NON-NLS-1$ //$NON-NLS-2$
Element importCXFSoapExtensionResource = new Element("import", SPRING_BEANS_NS); //$NON-NLS-1$
importCXFSoapExtensionResource.setAttribute("resource", //$NON-NLS-1$
"classpath:META-INF/cxf/cxf-extension-soap.xml"); //$NON-NLS-1$
Element importCXFServeltResource = new Element("import", SPRING_BEANS_NS); //$NON-NLS-1$
importCXFServeltResource.setAttribute("resource", "classpath:META-INF/cxf/cxf-servlet.xml"); //$NON-NLS-1$ //$NON-NLS-2$
beans.addContent(importCXFResource);
beans.addContent(importCXFSoapExtensionResource);
beans.addContent(importCXFServeltResource);
writeConfig(new Document(beans), beansFile);
}
public static boolean isSpringBeansFile(IFile springBeansFile) throws IOException {
FileInputStream springBeansInputStream = new FileInputStream(springBeansFile.getLocation().toFile());
if (springBeansInputStream.available() > 0) {
SAXBuilder builder = new SAXBuilder();
try {
Document doc = builder.build(springBeansInputStream);
Element root = doc.getRootElement();
if (root.getName().equals(DOC_ROOT) && root.getNamespace().equals(SPRING_BEANS_NS)) {
return true;
}
} catch (JDOMException jdome) {
CXFCorePlugin.log(jdome);
} finally {
springBeansInputStream.close();
}
}
return false;
}
@SuppressWarnings("unchecked")
private static boolean isBeanDefined(CXFDataModel cxfDataModel, String projectName, String elementName,
Namespace namespace, String id) throws IOException {
IFile springConfigFile = null;
if (CXFCorePlugin.getDefault().getJava2WSContext().isUseSpringApplicationContext()) {
springConfigFile = SpringUtils.getBeansFile(projectName);
} else {
springConfigFile = SpringUtils.getCXFServlet(projectName);
}
if (isSpringBeansFile(springConfigFile)) {
SAXBuilder builder = new SAXBuilder();
FileInputStream springConfigInputSteam = new FileInputStream(springConfigFile.getLocation()
.toFile());
try {
Document doc = builder.build(springConfigInputSteam);
Element beans = doc.getRootElement();
List<Element> endpoints = beans.getChildren(elementName, namespace);
for (Element element : endpoints) {
if (element != null && element.getAttribute("id") != null) { //$NON-NLS-1$
Attribute idAttribute = element.getAttribute("id"); //$NON-NLS-1$
if (idAttribute.getValue().equals(id)) {
return true;
}
}
}
} catch (JDOMException jdome) {
CXFCorePlugin.log(jdome);
} finally {
springConfigInputSteam.close();
}
}
return false;
}
@SuppressWarnings("unchecked")
public static String getEndpointAddress(IProject project, String jaxwsEndpointId) throws IOException {
IFile springConfigFile = null;
if (CXFCorePlugin.getDefault().getJava2WSContext().isUseSpringApplicationContext()) {
springConfigFile = SpringUtils.getBeansFile(project);
} else {
springConfigFile = SpringUtils.getCXFServlet(project);
}
if (isSpringBeansFile(springConfigFile)) {
SAXBuilder builder = new SAXBuilder();
FileInputStream springConfigInputSteam = new FileInputStream(springConfigFile.getLocation()
.toFile());
try {
Document doc = builder.build(springConfigInputSteam);
Element beans = doc.getRootElement();
List<Element> endpoints = beans.getChildren("endpoint", JAXWS_NS); //$NON-NLS-1$
for (Element element : endpoints) {
if (element != null && element.getAttribute("id") != null) { //$NON-NLS-1$
Attribute idAttribute = element.getAttribute("id"); //$NON-NLS-1$
if (idAttribute.getValue().equals(jaxwsEndpointId)) {
return element.getAttribute("address").getValue(); //$NON-NLS-1$
}
}
}
} catch (JDOMException jdome) {
CXFCorePlugin.log(jdome);
} finally {
springConfigInputSteam.close();
}
}
return ""; //$NON-NLS-1$
}
@SuppressWarnings("unchecked")
public static void createConfigurationFromWSDL(WSDL2JavaDataModel model) throws IOException {
String targetNamespace = model.getTargetNamespace();
String packageName = model.getIncludedNamespaces().get(targetNamespace);
Definition definition = model.getWsdlDefinition();
Map servicesMap = definition.getServices();
Set<Map.Entry> servicesSet = servicesMap.entrySet();
for (Map.Entry serviceEntry : servicesSet) {
Service service = (Service) serviceEntry.getValue();
model.setServiceName(service.getQName().getLocalPart());
Map portsMap = service.getPorts();
Set<Map.Entry> portsSet = portsMap.entrySet();
for (Map.Entry portEntry : portsSet) {
Port port = (Port) portEntry.getValue();
model.setEndpointName(port.getName());
PortType portType = port.getBinding().getPortType();
QName qName = portType.getQName();
String portTypeName = qName.getLocalPart();
String fullyQualifiedClassName = packageName + "." + //$NON-NLS-1$
convertPortTypeName(portTypeName) + "Impl"; //$NON-NLS-1$
model.setFullyQualifiedJavaClassName(fullyQualifiedClassName);
SpringUtils.createJAXWSEndpoint(model);
}
}
}
@SuppressWarnings("unchecked")
public static void loadSpringConfigInformationFromWSDL(CXFDataModel model) {
IFile wsdlFile = WSDLUtils.getWSDLFolder(model.getProjectName()).getFile(model.getWsdlFileName());
if (wsdlFile.exists()) {
try {
model.setWsdlURL(wsdlFile.getLocationURI().toURL());
Definition definition = WSDLUtils.readWSDL(model.getWsdlURL());
Map servicesMap = definition.getServices();
Set<Map.Entry> servicesSet = servicesMap.entrySet();
for (Map.Entry serviceEntry : servicesSet) {
Service service = (Service) serviceEntry.getValue();
model.setServiceName(service.getQName().getLocalPart());
Map portsMap = service.getPorts();
Set<Map.Entry> portsSet = portsMap.entrySet();
for (Map.Entry portEntry : portsSet) {
Port port = (Port) portEntry.getValue();
model.setEndpointName(port.getName());
}
}
model.setWsdlDefinition(definition);
} catch (MalformedURLException murle) {
CXFCorePlugin.log(murle);
} catch (IOException ioe) {
CXFCorePlugin.log(ioe);
}
}
}
private static String convertPortTypeName(String portTypeName) {
String[] segments = portTypeName.split("[\\-\\.\\:\\_\\u00b7\\u0387\\u06dd\\u06de]");
StringBuilder stringBuilder = new StringBuilder();
for (String segment : segments) {
if (segment.length() == 0) {
continue;
}
char firstCharacter = segment.charAt(0);
if (!Character.isDigit(firstCharacter) && Character.isLowerCase(firstCharacter)) {
segment = segment.substring(0, 1).toUpperCase() + segment.substring(1);
}
for (int i = 1; i < segment.length(); i++) {
char currentChar = segment.charAt(i);
char precedingChar = segment.charAt(i - 1);
if (Character.isLetter(currentChar) && Character.isDigit(precedingChar)
&& Character.isLowerCase(currentChar)) {
segment = segment.substring(0, i) + segment.substring(i, i + 1).toUpperCase()
+ segment.substring(i + 1, segment.length());
}
}
stringBuilder.append(segment);
}
return stringBuilder.toString();
}
public static void createJAXWSEndpoint(CXFDataModel model) throws IOException {
String projectName = model.getProjectName();
IFile springConfigFile = null;
if (CXFCorePlugin.getDefault().getJava2WSContext().isUseSpringApplicationContext()) {
springConfigFile = SpringUtils.getBeansFile(projectName);
} else {
springConfigFile = SpringUtils.getCXFServlet(projectName);
}
if (isSpringBeansFile(springConfigFile)) {
SAXBuilder builder = new SAXBuilder();
FileInputStream springConfigInputSteam = new FileInputStream(springConfigFile.getLocation()
.toFile());
try {
Document doc = builder.build(springConfigInputSteam);
Element beans = doc.getRootElement();
Element jaxwsEndpoint = new Element("endpoint", JAXWS_NS); //$NON-NLS-1$
String id = getJAXWSEndpointID(model);
model.setConfigId(id);
jaxwsEndpoint.setAttribute("id", id); //$NON-NLS-1$
jaxwsEndpoint.setAttribute("implementor", model.getFullyQualifiedJavaClassName()); //$NON-NLS-1$
if (model.getConfigWsdlLocation() != null) {
jaxwsEndpoint.setAttribute("wsdlLocation", model.getConfigWsdlLocation()); //$NON-NLS-1$
if (model.getEndpointName() != null && model.getServiceName() != null) {
jaxwsEndpoint.setAttribute("endpointName", "tns:" + model.getEndpointName()); //$NON-NLS-1$ //$NON-NLS-2$
jaxwsEndpoint.setAttribute("serviceName", "tns:" + model.getServiceName()); //$NON-NLS-1$ //$NON-NLS-2$
Namespace XMLNS_TNS = Namespace.getNamespace("tns", model.getTargetNamespace()); //$NON-NLS-1$
jaxwsEndpoint.addNamespaceDeclaration(XMLNS_TNS);
}
}
if (model.getEndpointName() != null) {
jaxwsEndpoint.setAttribute("address", "/" + model.getEndpointName()); //$NON-NLS-1$ //$NON-NLS-2$
} else {
jaxwsEndpoint.setAttribute("address", "/" + id); //$NON-NLS-1$ //$NON-NLS-2$
}
Element jaxwsFeatures = new Element("features", JAXWS_NS); //$NON-NLS-1$
Element bean = new Element("bean", SPRING_BEANS_NS); //$NON-NLS-1$
bean.setAttribute("class", "org.apache.cxf.feature.LoggingFeature"); //$NON-NLS-1$ //$NON-NLS-2$
jaxwsFeatures.addContent(bean);
jaxwsEndpoint.addContent(jaxwsFeatures);
if (!isBeanDefined(model, projectName, "endpoint", JAXWS_NS, id)) { //$NON-NLS-1$
beans.addContent(jaxwsEndpoint);
writeConfig(doc, springConfigFile);
}
} catch (JDOMException jdome) {
CXFCorePlugin.log(jdome);
} finally {
springConfigInputSteam.close();
}
}
}
private static String getJAXWSEndpointID(CXFDataModel model) {
String implementor = model.getFullyQualifiedJavaClassName();
if (implementor.indexOf(".") != -1) { //$NON-NLS-1$
implementor = implementor.substring(implementor.lastIndexOf(".") + 1, implementor.length());
}
if (!implementor.startsWith("Impl") && implementor.indexOf("Impl") != -1) {
implementor = implementor.substring(0, implementor.indexOf("Impl")).toLowerCase(); //$NON-NLS-1$;
} else {
implementor = implementor.toLowerCase();
}
return implementor;
}
private static void writeConfig(Document document, IFile springConfigFile) throws IOException {
OutputStream outputStream = new FileOutputStream(springConfigFile.getLocation().toFile());
try {
XMLOutputter outputter = new XMLOutputter();
outputter.output(document, outputStream);
springConfigFile.refreshLocal(IResource.DEPTH_ONE, new NullProgressMonitor());
FileUtils.formatXMLFile(springConfigFile);
} catch (CoreException ce) {
CXFCorePlugin.log(ce.getStatus());
} finally {
outputStream.close();
}
}
}