Author: alessio.soldano(a)jboss.com
Date: 2010-04-15 11:54:24 -0400 (Thu, 15 Apr 2010)
New Revision: 12003
Added:
stack/cxf/trunk/modules/server/src/main/java/org/jboss/wsf/stack/cxf/metadata/MetadataBuilder.java
Modified:
stack/cxf/trunk/modules/server/src/main/java/org/jboss/wsf/stack/cxf/deployment/aspect/DescriptorDeploymentAspect.java
stack/cxf/trunk/modules/server/src/main/java/org/jboss/wsf/stack/cxf/metadata/services/DDEndpoint.java
Log:
[JBWS-2999] Refactoring DDEnpoint creation to a dedicated builder and adding
webservices.xml override checks
Modified:
stack/cxf/trunk/modules/server/src/main/java/org/jboss/wsf/stack/cxf/deployment/aspect/DescriptorDeploymentAspect.java
===================================================================
---
stack/cxf/trunk/modules/server/src/main/java/org/jboss/wsf/stack/cxf/deployment/aspect/DescriptorDeploymentAspect.java 2010-04-15
15:48:09 UTC (rev 12002)
+++
stack/cxf/trunk/modules/server/src/main/java/org/jboss/wsf/stack/cxf/deployment/aspect/DescriptorDeploymentAspect.java 2010-04-15
15:54:24 UTC (rev 12003)
@@ -26,20 +26,15 @@
import java.util.HashMap;
import java.util.Map;
-import javax.xml.ws.BindingType;
-import javax.xml.ws.soap.MTOM;
-import javax.xml.ws.soap.SOAPBinding;
-
import org.jboss.logging.Logger;
import org.jboss.wsf.common.integration.AbstractDeploymentAspect;
import org.jboss.wsf.common.integration.WSConstants;
import org.jboss.wsf.spi.deployment.ArchiveDeployment;
import org.jboss.wsf.spi.deployment.Deployment;
-import org.jboss.wsf.spi.deployment.Endpoint;
import org.jboss.wsf.spi.deployment.Deployment.DeploymentType;
import org.jboss.wsf.stack.cxf.configuration.BusHolder;
+import org.jboss.wsf.stack.cxf.metadata.MetadataBuilder;
import org.jboss.wsf.stack.cxf.metadata.services.DDBeans;
-import org.jboss.wsf.stack.cxf.metadata.services.DDEndpoint;
/**
* A deployer that locates or generates cxf.xml
@@ -160,34 +155,9 @@
private URL generateCXFConfigFromDeployment(Deployment dep)
{
// Generate the jbossws-cxf.xml descriptor
- DeploymentType depType = dep.getType();
-
- DDBeans dd = new DDBeans();
- for (Endpoint ep : dep.getService().getEndpoints())
- {
- String id = ep.getShortName();
- String address = ep.getAddress();
- String implementor = ep.getTargetBeanName();
+ MetadataBuilder builder = new MetadataBuilder();
+ DDBeans dd = builder.build(dep, invokerEJB3, invokerJSE);
- boolean mtomEnabled = isMtomEnabled(ep.getTargetBeanClass());
-
- DDEndpoint ddep = new DDEndpoint(id, address, implementor, mtomEnabled);
-
- if (depType == DeploymentType.JAXWS_EJB3)
- {
- ddep.setInvoker(invokerEJB3);
- }
-
- if (depType == DeploymentType.JAXWS_JSE)
- {
- ddep.setInvoker(invokerJSE);
- }
-
-
- log.info("Add " + ddep);
- dd.addEndpoint(ddep);
- }
-
URL cxfURL = dd.createFileURL();
log.info("JBossWS-CXF configuration generated: " + cxfURL);
@@ -218,19 +188,4 @@
contextParams.put(BusHolder.PARAM_CXF_BEANS_URL, cxfURL.toExternalForm());
}
- private static boolean isMtomEnabled(Class<?> beanClass)
- {
- BindingType bindingType = (BindingType)beanClass.getAnnotation(BindingType.class);
- MTOM mtom = (MTOM)beanClass.getAnnotation(MTOM.class);
-
- boolean mtomEnabled = mtom != null;
- if (!mtomEnabled && bindingType != null)
- {
- String binding = bindingType.value();
- mtomEnabled = binding.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING) ||
binding.equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING);
- }
-
- return mtomEnabled;
- }
-
}
Added:
stack/cxf/trunk/modules/server/src/main/java/org/jboss/wsf/stack/cxf/metadata/MetadataBuilder.java
===================================================================
---
stack/cxf/trunk/modules/server/src/main/java/org/jboss/wsf/stack/cxf/metadata/MetadataBuilder.java
(rev 0)
+++
stack/cxf/trunk/modules/server/src/main/java/org/jboss/wsf/stack/cxf/metadata/MetadataBuilder.java 2010-04-15
15:54:24 UTC (rev 12003)
@@ -0,0 +1,258 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.wsf.stack.cxf.metadata;
+
+import java.util.Stack;
+import java.util.StringTokenizer;
+
+import javax.jws.WebService;
+import javax.xml.namespace.QName;
+import javax.xml.ws.BindingType;
+import javax.xml.ws.WebServiceProvider;
+import javax.xml.ws.soap.MTOM;
+import javax.xml.ws.soap.SOAPBinding;
+
+import org.jboss.logging.Logger;
+import org.jboss.wsf.common.JavaUtils;
+import org.jboss.wsf.spi.deployment.ArchiveDeployment;
+import org.jboss.wsf.spi.deployment.Deployment;
+import org.jboss.wsf.spi.deployment.Endpoint;
+import org.jboss.wsf.spi.deployment.Deployment.DeploymentType;
+import org.jboss.wsf.spi.metadata.webservices.PortComponentMetaData;
+import org.jboss.wsf.spi.metadata.webservices.WebserviceDescriptionMetaData;
+import org.jboss.wsf.spi.metadata.webservices.WebservicesFactory;
+import org.jboss.wsf.spi.metadata.webservices.WebservicesMetaData;
+import org.jboss.wsf.stack.cxf.metadata.services.DDBeans;
+import org.jboss.wsf.stack.cxf.metadata.services.DDEndpoint;
+
+/**
+ * Builds the DDBeans metadata used for generating the jboss-cxf.xml deployment
descriptor
+ *
+ * @author alessio.soldano(a)jboss.com
+ * @since 15-Apr-2010
+ *
+ */
+public class MetadataBuilder
+{
+ private static final Logger log = Logger.getLogger(MetadataBuilder.class);
+
+ public MetadataBuilder()
+ {
+
+ }
+
+ public DDBeans build(Deployment dep, String invokerEJB3, String invokerJSE)
+ {
+ DeploymentType depType = dep.getType();
+ DDBeans dd = new DDBeans();
+ for (Endpoint ep : dep.getService().getEndpoints())
+ {
+ DDEndpoint ddep = createDDEndpoint(ep.getTargetBeanClass(),
(ArchiveDeployment)dep, ep);
+
+ if (depType == DeploymentType.JAXWS_EJB3)
+ {
+ ddep.setInvoker(invokerEJB3);
+ }
+
+ if (depType == DeploymentType.JAXWS_JSE)
+ {
+ ddep.setInvoker(invokerJSE);
+ }
+
+ processWSDDContribution(ddep, (ArchiveDeployment)dep);
+
+ log.info("Add " + ddep);
+ dd.addEndpoint(ddep);
+ }
+ return dd;
+ }
+
+ protected boolean isMtomEnabled(Class<?> beanClass)
+ {
+ BindingType bindingType = (BindingType)beanClass.getAnnotation(BindingType.class);
+ MTOM mtom = (MTOM)beanClass.getAnnotation(MTOM.class);
+
+ boolean mtomEnabled = mtom != null;
+ if (!mtomEnabled && bindingType != null)
+ {
+ String binding = bindingType.value();
+ mtomEnabled = binding.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING) ||
binding.equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING);
+ }
+
+ return mtomEnabled;
+ }
+
+ private void processWSDDContribution(DDEndpoint endpoint, ArchiveDeployment dep)
+ {
+ WebservicesMetaData webservices =
WebservicesFactory.loadFromVFSRoot(dep.getRootFile());
+ if (webservices != null)
+ {
+ for (WebserviceDescriptionMetaData wsDesc :
webservices.getWebserviceDescriptions())
+ {
+ for (PortComponentMetaData portComp : wsDesc.getPortComponents())
+ {
+ // We match portComp's by SEI first and portQName second
+ // In the first case the portComp may override the portQName that derives
from the annotation
+ String portCompSEI = portComp.getServiceEndpointInterface();
+ boolean doesMatch = portCompSEI != null ?
portCompSEI.equals(endpoint.getEpClass().getName()) : false;
+ if (!doesMatch)
+ {
+ doesMatch = portComp.getWsdlPort().equals(endpoint.getPortName());
+ }
+
+ if (doesMatch)
+ {
+ // PortQName overrides
+ if (portComp.getWsdlPort() != null)
+ {
+ if (log.isDebugEnabled())
+ log.debug("Override portName " + endpoint.getPortName()
+ " with " + portComp.getWsdlPort());
+ endpoint.setPortName(portComp.getWsdlPort());
+ }
+ //ServiceQName overrides
+ if (portComp.getWsdlService() != null)
+ {
+ if (log.isDebugEnabled())
+ log.debug("Override serviceName " +
endpoint.getServiceName() + " with " + portComp.getWsdlService());
+ endpoint.setServiceName(portComp.getWsdlService());
+ }
+
+ //TODO implement handler chain override
+
+ // MTOM settings
+ if (portComp.isEnableMtom())
+ {
+ log.debug("Enabling MTOM");
+ endpoint.setMtomEnabled(true);
+ }
+
+ //wsdlLocation override
+ String wsdlFile = portComp.getWebserviceDescription().getWsdlFile();
+ if (wsdlFile != null)
+ {
+ if (log.isDebugEnabled())
+ log.debug("Override wsdlFile location with " +
wsdlFile);
+ endpoint.setWsdlLocation(wsdlFile);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ protected DDEndpoint createDDEndpoint(Class<?> sepClass, ArchiveDeployment dep,
Endpoint ep)
+ {
+ WebService anWebService = sepClass.getAnnotation(WebService.class);
+ WebServiceProvider anWebServiceProvider =
sepClass.getAnnotation(WebServiceProvider.class);
+
+ Class<?> seiClass = null;
+ String seiName;
+
+ String name = (anWebService != null) ? anWebService.name() : "";
+ if (name.length() == 0)
+ name = JavaUtils.getJustClassName(sepClass);
+
+ String serviceName = (anWebService != null) ? anWebService.serviceName() :
anWebServiceProvider.serviceName();
+ if (serviceName.length() == 0)
+ serviceName = JavaUtils.getJustClassName(sepClass) + "Service";
+
+ String serviceNS = (anWebService != null) ? anWebService.targetNamespace() :
anWebServiceProvider.targetNamespace();
+ if (serviceNS.length() == 0)
+ serviceNS = getTypeNamespace(JavaUtils.getPackageName(sepClass));
+
+ String portName = (anWebService != null) ? anWebService.portName() :
anWebServiceProvider.portName();
+ if (portName.length() == 0)
+ portName = name + "Port";
+
+ if (anWebService != null && anWebService.endpointInterface().length() >
0)
+ {
+ seiName = anWebService.endpointInterface();
+ ClassLoader runtimeClassLoader = dep.getRuntimeClassLoader();
+ if(null == runtimeClassLoader)
+ throw new IllegalArgumentException("Runtime loader cannot be
null");
+
+ try
+ {
+ seiClass = runtimeClassLoader.loadClass(seiName);
+ }
+ catch (ClassNotFoundException cnfe)
+ {
+ throw new RuntimeException("Cannot load service endpoint interface
class!", cnfe);
+ }
+ WebService seiAnnotation = seiClass.getAnnotation(WebService.class);
+
+ if (seiAnnotation == null)
+ throw new RuntimeException("Interface does not have a @WebService
annotation: " + seiName);
+
+ if (seiAnnotation.portName().length() > 0 ||
seiAnnotation.serviceName().length() > 0 || seiAnnotation.endpointInterface().length()
> 0)
+ throw new RuntimeException("@WebService cannot have attribute
'portName', 'serviceName', 'endpointInterface' on: " +
seiName);
+
+ }
+
+ DDEndpoint result = new DDEndpoint();
+
+ result.setId(ep.getShortName());
+ result.setAddress(ep.getAddress());
+ result.setImplementor(ep.getTargetBeanName());
+ result.setMtomEnabled(isMtomEnabled(ep.getTargetBeanClass()));
+ result.setEpClass(seiClass != null ? seiClass : sepClass);
+ result.setPortName(new QName(serviceNS, portName));
+ result.setServiceName(new QName(serviceNS, serviceName));
+
+ return result;
+ }
+
+
+
+ /**
+ * Extracts the typeNS given the package name
+ * Algorithm is based on the one specified in JAWS v2.0 spec
+ */
+ private static String getTypeNamespace(String packageName)
+ {
+ StringBuilder sb = new StringBuilder("http://");
+
+ //Generate tokens with '.' as delimiter
+ StringTokenizer st = new StringTokenizer(packageName, ".");
+
+ //Have a LIFO queue for the tokens
+ Stack<String> stk = new Stack<String>();
+ while (st != null && st.hasMoreTokens())
+ {
+ stk.push(st.nextToken());
+ }
+
+ String next;
+ while (!stk.isEmpty() && (next = stk.pop()) != null)
+ {
+ if (sb.toString().equals("http://") == false)
+ sb.append('.');
+ sb.append(next);
+ }
+
+ // trailing slash
+ sb.append('/');
+
+ return sb.toString();
+ }
+
+}
Modified:
stack/cxf/trunk/modules/server/src/main/java/org/jboss/wsf/stack/cxf/metadata/services/DDEndpoint.java
===================================================================
---
stack/cxf/trunk/modules/server/src/main/java/org/jboss/wsf/stack/cxf/metadata/services/DDEndpoint.java 2010-04-15
15:48:09 UTC (rev 12002)
+++
stack/cxf/trunk/modules/server/src/main/java/org/jboss/wsf/stack/cxf/metadata/services/DDEndpoint.java 2010-04-15
15:54:24 UTC (rev 12003)
@@ -24,38 +24,140 @@
import java.io.IOException;
import java.io.Writer;
+import javax.xml.namespace.QName;
+
/**
* Metadata model for cxf.xml
*
* @author Thomas.Diesler(a)jboss.org
* @author ropalka(a)redhat.com
+ * @author alessio.soldano(a)jboss.com
*/
public class DDEndpoint
{
+ //fields mapped to jboss-cxf.xml
private String id;
private String address;
private String implementor;
private String invoker;
private boolean mtomEnabled;
+ private String wsdlLocation;
+ private QName portName;
+ private QName serviceName;
+
+ //additional fields
+ private Class<?> epClass;
+
+ private int counter = 0;
- public DDEndpoint(String id, String address, String implementor, boolean mtomEnabled)
+
+ public QName getPortName()
{
+ return portName;
+ }
+
+ public void setPortName(QName portName)
+ {
+ this.portName = portName;
+ }
+
+ public QName getServiceName()
+ {
+ return serviceName;
+ }
+
+ public void setServiceName(QName serviceName)
+ {
+ this.serviceName = serviceName;
+ }
+
+ public String getId()
+ {
+ return id;
+ }
+
+ public void setId(String id)
+ {
this.id = id;
+ }
+
+ public String getAddress()
+ {
+ return address;
+ }
+
+ public void setAddress(String address)
+ {
this.address = address;
+ }
+
+ public String getImplementor()
+ {
+ return implementor;
+ }
+
+ public void setImplementor(String implementor)
+ {
this.implementor = implementor;
- this.mtomEnabled = mtomEnabled;
}
+ public String getWsdlLocation()
+ {
+ return wsdlLocation;
+ }
+
+ public void setWsdlLocation(String wsdlLocation)
+ {
+ this.wsdlLocation = wsdlLocation;
+ }
+
+ public Class<?> getEpClass()
+ {
+ return epClass;
+ }
+
+ public void setEpClass(Class<?> epClass)
+ {
+ this.epClass = epClass;
+ }
+
+ public String getInvoker()
+ {
+ return invoker;
+ }
+
+ public boolean isMtomEnabled()
+ {
+ return mtomEnabled;
+ }
+
public void setInvoker(String invoker)
{
this.invoker = invoker;
}
+ public void setMtomEnabled(boolean mtomEnabled)
+ {
+ this.mtomEnabled = mtomEnabled;
+ }
+
public void writeTo(Writer writer) throws IOException
{
writer.write("<jaxws:endpoint id='" + this.id +
"'");
writer.write(" address='" + this.address + "'");
writer.write(" implementor='" + this.implementor +
"'");
+ if (this.serviceName != null)
+ {
+ this.writeQNameElementTo("serviceName", this.serviceName, writer);
+ }
+ if (this.portName != null)
+ {
+ this.writeQNameElementTo("endpointName", this.portName, writer);
+ }
+ if (this.wsdlLocation != null)
+ {
+ writer.write(" wsdlLocation='" + this.wsdlLocation +
"'");
+ }
writer.write(">");
if (this.mtomEnabled)
@@ -72,6 +174,13 @@
writer.write("</jaxws:endpoint>");
}
+
+ private void writeQNameElementTo(String elementName, QName qname, Writer writer)
throws IOException
+ {
+ String prefix = "ns" + counter++;
+ writer.write(" " + elementName + "='" + prefix +
":" + qname.getLocalPart() + "'");
+ writer.write(" xmlns:" + prefix + "='" +
qname.getNamespaceURI() + "'");
+ }
public String toString()
{
@@ -80,6 +189,9 @@
str.append("\n address=" + this.address);
str.append("\n implementor=" + this.implementor);
str.append("\n invoker=" + this.invoker);
+ str.append("\n serviceName=" + this.serviceName);
+ str.append("\n portName=" + this.portName);
+ str.append("\n wsdlLocation=" + this.wsdlLocation);
str.append("\n mtomEnabled=" + this.mtomEnabled);
return str.toString();
}