Modified: webservices/axis2/branches/java/jaxws21/modules/jaxws/src/org/apache/axis2/jaxws/spi/ServiceDelegate.java URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/jaxws21/modules/jaxws/src/org/apache/axis2/jaxws/spi/ServiceDelegate.java?rev=612147&r1=612146&r2=612147&view=diff ============================================================================== --- webservices/axis2/branches/java/jaxws21/modules/jaxws/src/org/apache/axis2/jaxws/spi/ServiceDelegate.java (original) +++ webservices/axis2/branches/java/jaxws21/modules/jaxws/src/org/apache/axis2/jaxws/spi/ServiceDelegate.java Tue Jan 15 08:21:22 2008 @@ -18,12 +18,13 @@ */ package org.apache.axis2.jaxws.spi; -import javax.xml.ws.handler.HandlerResolver; import org.apache.axis2.client.ServiceClient; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.java.security.AccessController; import org.apache.axis2.jaxws.ExceptionFactory; +import org.apache.axis2.jaxws.binding.BindingImpl; +import org.apache.axis2.jaxws.binding.BindingUtils; import org.apache.axis2.jaxws.addressing.util.EndpointReferenceUtils; import org.apache.axis2.jaxws.client.PropertyMigrator; import org.apache.axis2.jaxws.client.dispatch.JAXBDispatch; @@ -33,6 +34,7 @@ import org.apache.axis2.jaxws.description.EndpointDescription; import org.apache.axis2.jaxws.description.ServiceDescription; import org.apache.axis2.jaxws.description.ServiceDescriptionWSDL; +import org.apache.axis2.jaxws.description.builder.DescriptionBuilderComposite; import org.apache.axis2.jaxws.handler.HandlerResolverImpl; import org.apache.axis2.jaxws.i18n.Messages; import org.apache.axis2.jaxws.registry.FactoryRegistry; @@ -51,8 +53,11 @@ import javax.xml.ws.EndpointReference; import javax.xml.ws.Service; import javax.xml.ws.WebServiceFeature; -import javax.xml.ws.Service.Mode; import javax.xml.ws.WebServiceException; +import javax.xml.ws.Service.Mode; +import javax.xml.ws.handler.HandlerResolver; +import javax.xml.ws.http.HTTPBinding; + import java.lang.reflect.Proxy; import java.net.URL; import java.security.PrivilegedActionException; @@ -66,6 +71,9 @@ */ public class ServiceDelegate extends javax.xml.ws.spi.ServiceDelegate { private static final Log log = LogFactory.getLog(ServiceDelegate.class); + private static ThreadLocal<DescriptionBuilderComposite> sparseServiceCompositeThreadLocal = new ThreadLocal<DescriptionBuilderComposite>(); + private static ThreadLocal<DescriptionBuilderComposite> sparsePortCompositeThreadLocal = new ThreadLocal<DescriptionBuilderComposite>(); + private Executor executor; private ServiceDescription serviceDescription; @@ -74,6 +82,116 @@ private HandlerResolver handlerResolver = null; + /** + * NON-STANDARD SPI! Set any metadata to be used on the creation of the NEXT Service by this thread. + * NOTE that this uses ThreadLocal to store the metadata, and that ThreadLocal is cleared after it is + * used to create a Service. That means: + * 1) The thread that sets the metadata to use MUST be the thread that creates the Service + * 2) Creation of the Service should be the very next thing the thread does + * 3) The metadata will be set to null when the Service is created, so to create another + * service with the same metadata, it will need to be set again prior to creating the + * service + * 4) The metadata can be set prior to creating both generic Service and generated Service + * instances. + * + * This allows creating a generic Service (javax.xml.ws.Service) or a generated Service + * (subclass of javax.xml.ws.Service) specifying additional metadata via a + * sparse composite. This can be used by a runtime to create a Service for a requester using + * additional metadata such as might come from a deployment descriptor or from resource + * injection processing of @Resource or @WebServiceRef(s) annotations. Additional metadata + * may include things like @WebServiceClient.wsdlLocation or a @HandlerChain specification. + * + * @see javax.xml.ws.Service#create(QName) + * @see javax.xml.ws.Service#create(URL, QName) + * + * @param composite Additional metadata (if any) to be used in creation of the service + */ + static public void setServiceMetadata(DescriptionBuilderComposite composite) { + sparseServiceCompositeThreadLocal.set(composite); + } + + /** + * NON-STANDARD SPI! Returns the composite that will be used on the creation of the next + * Service by this thread. + * + * @see #setServiceMetadata(DescriptionBuilderComposite) + * + * @return composite that will be used on the creation of the next Service by this thread, or null + * if no composite is to be used. + */ + static DescriptionBuilderComposite getServiceMetadata() { + return sparseServiceCompositeThreadLocal.get(); + } + + /** + * Remove any composite so that creation of the next Service by this thread will NOT be + * affected by any additional metadata. + * + * @see #setServiceMetadata(DescriptionBuilderComposite) + * + */ + static void resetServiceMetadata() { + sparseServiceCompositeThreadLocal.set(null); + } + + /** + * NON-STANDARD SPI! Set any metadata to be used on the creation of the NEXT Port by this thread. + * NOTE that this uses ThreadLocal to store the metadata, and that ThreadLocal is cleared after it is + * used to create a Port. That means: + * 1) The thread that sets the metadata to use MUST be the thread that creates the Port + * 2) Creation of the Port should be the very next thing the thread does + * 3) The metadata will be set to null when the Port is created, so to create another + * Port with the same metadata, it will need to be set again prior to creating the + * Port + * 4) The metadata can be set prior to creating Port which specifies a QName via + * Service.getPort(QName, Class) or one that only specifies the SEI class via + * Service.getPort(Class) + * 5) Metadata can not be specified for dynamic ports, i.e. those added via + * Service.addPort(...). + * 6) Metadata can not be specfied when creating a dispatch client, i.e. via + * Service.createDispatch(...) + * 7) The Service used to create the port can be the generic service or a generated + * service. + * + * This allows creating Port specifying additional metadata via a sparse composite. + * This can be used by a runtime to create a Port for a requester using + * additional metadata such as might come from a deployment descriptor or from resource + * injection processing. Additional metadata might include things like + * a @HandlerChain specification. + * + * @see javax.xml.ws.Service#getPort(Class) + * @see javax.xml.ws.Service#getPort(QName, Class) + * + * @param composite Additional metadata (if any) to be used in creation of the port + */ + static public void setPortMetadata(DescriptionBuilderComposite composite) { + sparsePortCompositeThreadLocal.set(composite); + } + + /** + * NON-STANDARD SPI! Returns the composite that will be used on the creation of the next + * Port by this thread. + * + * @see #setPortMetadata(DescriptionBuilderComposite) + * + * @return composite that will be used on the creation of the next Port by this thread, or null + * if no composite is to be used. + */ + static DescriptionBuilderComposite getPortMetadata() { + return sparsePortCompositeThreadLocal.get(); + } + + /** + * Remove any composite so that creation of the next Port by this thread will NOT be + * affected by any additional metadata. + * + * @see #setPortMetadata(DescriptionBuilderComposite) + * + */ + static void resetPortMetadata() { + sparsePortCompositeThreadLocal.set(null); + } + public ServiceDelegate(URL url, QName qname, Class clazz) throws WebServiceException { super(); this.serviceQname = qname; @@ -82,7 +200,15 @@ throw ExceptionFactory .makeWebServiceException(Messages.getMessage("serviceDelegateConstruct0", "")); } - serviceDescription = DescriptionFactory.createServiceDescription(url, serviceQname, clazz); + // Get any metadata that is to be used to build up this service, then reset it so it isn't used + // to create any other services. + DescriptionBuilderComposite sparseComposite = getServiceMetadata(); + resetServiceMetadata(); + if (sparseComposite != null) { + serviceDescription = DescriptionFactory.createServiceDescription(url, serviceQname, clazz, sparseComposite, this); + } else { + serviceDescription = DescriptionFactory.createServiceDescription(url, serviceQname, clazz); + } // TODO: This check should be done when the Service Description is created above; that should throw this exception. // That is because we (following the behavior of the RI) require the WSDL be fully specified (not partial) on the client if (isValidWSDLLocation()) { @@ -378,9 +504,22 @@ Messages.getMessage("getPortInvalidSEI", portName.toString(), "null")); } - EndpointDescription endpointDesc = + DescriptionBuilderComposite sparseComposite = getPortMetadata(); + resetPortMetadata(); + EndpointDescription endpointDesc = null; + if (sparseComposite != null) { + endpointDesc = DescriptionFactory.updateEndpoint(serviceDescription, sei, portName, - DescriptionFactory.UpdateType.GET_PORT); + DescriptionFactory.UpdateType.GET_PORT, + sparseComposite, this); + } + else { + endpointDesc = + DescriptionFactory.updateEndpoint(serviceDescription, sei, portName, + DescriptionFactory.UpdateType.GET_PORT, + null, this); + + } if (endpointDesc == null) { throw ExceptionFactory.makeWebServiceException( Messages.getMessage("portErr",portName.toString())); @@ -561,6 +700,23 @@ private boolean isServiceDefined(QName serviceName) { return getWSDLWrapper().getService(serviceName) != null; + } + + private BindingImpl addBinding(EndpointDescription endpointDesc, String bindingId) { + // TODO: before creating binding do I have to do something with Handlers ... how is Binding related to Handler, this mistry sucks!!! + if (bindingId != null) { + //TODO: create all the bindings here + if (BindingUtils.isSOAPBinding(bindingId)) { + //instantiate soap11 binding implementation here and call setBinding in BindingProvider + return new org.apache.axis2.jaxws.binding.SOAPBinding(endpointDesc); + } + + if (bindingId.equals(HTTPBinding.HTTP_BINDING)) { + //instantiate http binding implementation here and call setBinding in BindingProvider + return new org.apache.axis2.jaxws.binding.HTTPBinding(endpointDesc); + } + } + return new org.apache.axis2.jaxws.binding.SOAPBinding(endpointDesc); } private boolean isValidDispatchType(Class clazz) {
Modified: webservices/axis2/branches/java/jaxws21/modules/jaxws/src/org/apache/axis2/jaxws/utility/JavaUtils.java URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/jaxws21/modules/jaxws/src/org/apache/axis2/jaxws/utility/JavaUtils.java?rev=612147&r1=612146&r2=612147&view=diff ============================================================================== --- webservices/axis2/branches/java/jaxws21/modules/jaxws/src/org/apache/axis2/jaxws/utility/JavaUtils.java (original) +++ webservices/axis2/branches/java/jaxws21/modules/jaxws/src/org/apache/axis2/jaxws/utility/JavaUtils.java Tue Jan 15 08:21:22 2008 @@ -19,6 +19,9 @@ package org.apache.axis2.jaxws.utility; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; @@ -27,6 +30,8 @@ /** Common Java Utilites */ public class JavaUtils extends org.apache.axis2.util.JavaUtils { + private static Log log = LogFactory.getLog(JavaUtils.class); + /** Private Constructor...All methods of this class are static */ private JavaUtils() { } @@ -40,6 +45,9 @@ public static String getPackageFromNamespace(String namespace) { // The following steps correspond to steps described in the JAXB Specification + if (log.isDebugEnabled()) { + log.debug("namespace (" +namespace +")"); + } // Step 1: Scan off the host name String hostname = null; String path = null; @@ -57,6 +65,11 @@ hostname = namespace; } } + if (log.isDebugEnabled()) { + log.debug("hostname (" +hostname +")"); + log.debug("path (" +path +")"); + } + // Step 3: Tokenize the host name using ":" and "/" StringTokenizer st = new StringTokenizer(hostname, ":/"); @@ -95,16 +108,22 @@ // Step 6: Tokenize the first word with "." and reverse the order. (the www is also removed). // TODO This is not exactly equivalent to the JAXB Rule. - StringTokenizer st2 = new StringTokenizer(words[0], "."); ArrayList<String> list = new ArrayList<String>(); - while (st2.hasMoreTokens()) { - // Add the strings so they are in reverse order - list.add(0, st2.nextToken()); + if (words.length > 0) { + StringTokenizer st2 = new StringTokenizer(words[0], "."); + + while (st2.hasMoreTokens()) { + // Add the strings so they are in reverse order + list.add(0, st2.nextToken()); + } } + // Remove www - String last = list.get(list.size() - 1); - if (last.equals("www")) { - list.remove(list.size() - 1); + if (list.size() > 0) { + String last = list.get(list.size() - 1); + if (last.equals("www")) { + list.remove(list.size() - 1); + } } // Now each of words is represented by list for (int i = 1; i < words.length; i++) { @@ -147,6 +166,10 @@ } else { name = name + "." + list.get(i); } + } + + if (log.isDebugEnabled()) { + log.debug("package name (" +name +")"); } return name; } Modified: webservices/axis2/branches/java/jaxws21/modules/jaxws/test/org/apache/axis2/jaxws/description/DescriptionTestUtils2.java URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/jaxws21/modules/jaxws/test/org/apache/axis2/jaxws/description/DescriptionTestUtils2.java?rev=612147&r1=612146&r2=612147&view=diff ============================================================================== --- webservices/axis2/branches/java/jaxws21/modules/jaxws/test/org/apache/axis2/jaxws/description/DescriptionTestUtils2.java (original) +++ webservices/axis2/branches/java/jaxws21/modules/jaxws/test/org/apache/axis2/jaxws/description/DescriptionTestUtils2.java Tue Jan 15 08:21:22 2008 @@ -21,6 +21,8 @@ package org.apache.axis2.jaxws.description; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.net.URL; import javax.wsdl.Definition; @@ -28,6 +30,7 @@ import javax.wsdl.xml.WSDLReader; import javax.xml.ws.Service; +import org.apache.axis2.jaxws.description.builder.DescriptionBuilderComposite; import org.apache.axis2.jaxws.spi.ServiceDelegate; import org.apache.axis2.jaxws.TestLogger; @@ -46,11 +49,17 @@ return getWSDLURL("WSDLTests.wsdl"); } - static public URL getWSDLURL(String wsdlFileName) { - URL wsdlURL = null; + + static public String getWSDLLocation(String wsdlFileName) { // Get the URL to the WSDL file. Note that 'basedir' is setup by Maven String basedir = System.getProperty("basedir"); String urlString = "file://localhost/" + basedir + "/test-resources/wsdl/" + wsdlFileName; + return urlString; + } + + static public URL getWSDLURL(String wsdlFileName) { + URL wsdlURL = null; + String urlString = getWSDLLocation(wsdlFileName); try { wsdlURL = new URL(urlString); } catch (Exception e) { @@ -82,9 +91,16 @@ // Need to get to the private Service._delegate field in order to get to the ServiceDescription to test ServiceDelegate returnServiceDelegate = null; try { - Field serviceDelgateField = service.getClass().getDeclaredFields()[0]; - serviceDelgateField.setAccessible(true); - returnServiceDelegate = (ServiceDelegate) serviceDelgateField.get(service); + try { + Field serviceDelgateField = service.getClass().getDeclaredFields()[0]; + serviceDelgateField.setAccessible(true); + returnServiceDelegate = (ServiceDelegate) serviceDelgateField.get(service); + } catch (ArrayIndexOutOfBoundsException e) { + // This may be a generated service subclass, so get the delegate from the superclass + Field serviceDelegateField = service.getClass().getSuperclass().getDeclaredFields()[0]; + serviceDelegateField.setAccessible(true); + returnServiceDelegate = (ServiceDelegate) serviceDelegateField.get(service); + } } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -93,6 +109,34 @@ e.printStackTrace(); } return returnServiceDelegate; + } + + static public DescriptionBuilderComposite getServiceDescriptionComposite(ServiceDescription svcDesc) { + DescriptionBuilderComposite returnComposite = null; + // Need to get the composite off the implementation using the getter method, but it is all + // packaged protected and not part of the interface. + try { + Method getComposite = svcDesc.getClass().getDeclaredMethod("getDescriptionBuilderComposite"); + getComposite.setAccessible(true); + returnComposite = (DescriptionBuilderComposite) getComposite.invoke(svcDesc, null); + } catch (SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (NoSuchMethodException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return returnComposite; } } Modified: webservices/axis2/branches/java/jaxws21/modules/jaxws/test/org/apache/axis2/jaxws/dispatch/SOAP12Dispatch.java URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/jaxws21/modules/jaxws/test/org/apache/axis2/jaxws/dispatch/SOAP12Dispatch.java?rev=612147&r1=612146&r2=612147&view=diff ============================================================================== --- webservices/axis2/branches/java/jaxws21/modules/jaxws/test/org/apache/axis2/jaxws/dispatch/SOAP12Dispatch.java (original) +++ webservices/axis2/branches/java/jaxws21/modules/jaxws/test/org/apache/axis2/jaxws/dispatch/SOAP12Dispatch.java Tue Jan 15 08:21:22 2008 @@ -18,8 +18,7 @@ */ package org.apache.axis2.jaxws.dispatch; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; +import org.apache.axis2.jaxws.description.builder.MDQConstants; import javax.xml.namespace.QName; import javax.xml.transform.Source; @@ -33,6 +32,9 @@ import javax.xml.ws.soap.SOAPBinding; import javax.xml.ws.soap.SOAPFaultException; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + import junit.framework.TestCase; /** @@ -117,6 +119,47 @@ assertTrue(responseText.contains("echoStringResponse")); } + /** + * Test sending a SOAP 1.2 request in PAYLOAD mode using SOAP/JMS + */ + public void testSOAP12JMSDispatchPayloadMode() throws Exception { + // Create the JAX-WS client needed to send the request + Service service = Service.create(QNAME_SERVICE); + service.addPort(QNAME_PORT, MDQConstants.SOAP12JMS_BINDING, URL_ENDPOINT); + Dispatch<Source> dispatch = service.createDispatch( + QNAME_PORT, Source.class, Mode.PAYLOAD); + + // Create the Source object with the payload contents. Since + // we're in PAYLOAD mode, we don't have to worry about the envelope. + byte[] bytes = sampleRequest.getBytes(); + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + StreamSource request = new StreamSource(bais); + + // Send the SOAP 1.2 request + Source response = dispatch.invoke(request); + + assertTrue("The response was null. We expected content to be returned.", response != null); + + // Convert the response to a more consumable format + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + StreamResult result = new StreamResult(baos); + + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer trans = factory.newTransformer(); + trans.transform(response, result); + + // Check to make sure the contents are correct. Again, since we're + // in PAYLOAD mode, we shouldn't have anything related to the envelope + // in the return, just the contents of the Body. + String responseText = baos.toString(); + assertTrue(!responseText.contains("soap")); + assertTrue(!responseText.contains("Envelope")); + assertTrue(!responseText.contains("Body")); + assertTrue(responseText.contains("echoStringResponse")); + + } + + /** * Test sending a SOAP 1.2 request in MESSAGE mode */ --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]