You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by pr...@apache.org on 2008/01/15 17:22:27 UTC

svn commit: r612147 [9/17] - in /webservices/axis2/branches/java/jaxws21: ./ modules/adb-codegen/ modules/adb-codegen/src/org/apache/axis2/schema/ modules/adb-codegen/src/org/apache/axis2/schema/template/ modules/adb-codegen/src/org/apache/axis2/schema...

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: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org