You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by ba...@apache.org on 2008/01/11 04:56:17 UTC

svn commit: r611042 [1/4] - in /webservices/axis2/trunk/java/modules: jaxws/src/org/apache/axis2/jaxws/ jaxws/src/org/apache/axis2/jaxws/spi/ jaxws/test-resources/wsdl/ jaxws/test/org/apache/axis2/jaxws/description/ jaxws/test/org/apache/axis2/jaxws/sp...

Author: barrettj
Date: Thu Jan 10 19:56:14 2008
New Revision: 611042

URL: http://svn.apache.org/viewvc?rev=611042&view=rev
Log:
AXIS2-3439
Add support for sparse DescriptionBuilderComposite on the client side to override some annotation member values in client artifacts on a per-ServiceDelgate basis.

Added:
    webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadata.wsdl
    webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadataMultiPort.wsdl
    webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadataOther.wsdl
    webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadataOverriden.wsdl
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/ClientAnnotationTests.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/ClientAnnotationTestsHandler.xml
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/ClientMetadataPortTest.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/ClientMetadataTest.java
    webservices/axis2/trunk/java/modules/metadata/test-resources/wsdl/ClientEndpointMetadata.wsdl
    webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/builder/SparseAnnotTests.java
    webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/impl/ClientDBCSupportEndpointTests.java
    webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/impl/ClientDBCSupportTests.java
Modified:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/BindingProvider.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/ServiceDelegate.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/DescriptionTestUtils2.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/DescriptionFactory.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/EndpointDescription.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/ServiceDescription.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/BindingTypeAnnot.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/DescriptionBuilderComposite.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/DescriptionBuilderUtils.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/HandlerChainAnnot.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/ServiceModeAnnot.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/SoapBindingAnnot.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/WebServiceAnnot.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/WebServiceClientAnnot.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/WebServiceProviderAnnot.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/WebServiceRefAnnot.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/DescriptionFactoryImpl.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/DescriptionUtils.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointDescriptionImpl.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointInterfaceDescriptionImpl.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java
    webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/DescriptionTestUtils.java
    webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/builder/DescriptionBuilderTests.java
    webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/builder/converter/ReflectiveConverterTests.java
    webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/impl/DescriptionFactoryImplTests.java

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/BindingProvider.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/BindingProvider.java?rev=611042&r1=611041&r2=611042&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/BindingProvider.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/BindingProvider.java Thu Jan 10 19:56:14 2008
@@ -77,6 +77,15 @@
         // so we can also set the handlerchain
         if (binding == null) {
             binding = BindingUtils.createBinding(endpointDesc);
+            
+            // See if the metadata from creating the service indicates that MTOM should be enabled
+            if (binding instanceof SOAPBinding) {
+                boolean enableMTOMFromMetadata = endpointDesc.getServiceDescription().isMTOMEnabled(serviceDelegate);
+                if (enableMTOMFromMetadata) {
+                    ((SOAPBinding) binding).setMTOMEnabled(true);
+                }
+            }
+            
             if(log.isDebugEnabled()){
                 log.debug("Lookign for Handler Resolver");
             }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/ServiceDelegate.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/ServiceDelegate.java?rev=611042&r1=611041&r2=611042&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/ServiceDelegate.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/ServiceDelegate.java Thu Jan 10 19:56:14 2008
@@ -32,6 +32,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;
@@ -66,6 +67,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 +78,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 +196,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()) {
@@ -226,9 +348,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()));

Added: webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadata.wsdl
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadata.wsdl?rev=611042&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadata.wsdl (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadata.wsdl Thu Jan 10 19:56:14 2008
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>  
+<definitions targetNamespace="http://description.jaxws.axis2.apache.org"
+             xmlns:tns="http://description.jaxws.axis2.apache.org"
+             xmlns="http://schemas.xmlsoap.org/wsdl/"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">     
+  <types>      
+    <xsd:schema targetNamespace="http://description.jaxws.axis2.apache.org" 
+                xmlns:ts="http://description.jaxws.axis2.apache.org/xsd"
+                xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">           
+      <complexType name="echoMessage">
+        <sequence>
+          <element name="request" type="xsd:string"/>
+        </sequence>          
+      </complexType>           
+      <complexType name="echoMessageResponse">             
+        <sequence>                
+          <element name="response" type="xsd:string"/>            
+        </sequence>          
+      </complexType>           
+      <element name="echoMessage" type="tns:echoMessage"/>          
+      <element name="echoMessageResponse" type="tns:echoMessageResponse"/>        
+    </xsd:schema>    
+  </types>     
+
+  <message name="echoMessage">       
+    <part name="message" element="tns:echoMessage"/>    
+  </message>     
+
+  <message name="echoMessageResponse">       
+    <part name="result" element="tns:echoMessageResponse"/>    
+  </message>     
+
+  <portType name="EchoMessagePortType">       
+    <operation name="echoMessage">          
+      <input message="tns:echoMessage" />          
+      <output message="tns:echoMessageResponse" />       
+    </operation>    
+  </portType>     
+
+  <binding name="EchoMessageBinding" type="tns:EchoMessagePortType">       
+    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>       
+    <operation name="echoMessage">          
+      <soap:operation soapAction=""/>         
+      <input>             
+        <soap:body use="literal" namespace="http://org.apache.binding.ns"/>          
+      </input>           
+      <output>             
+        <soap:body use="literal" namespace="http://org.apache.binding.ns"/>         
+      </output>       
+    </operation>    
+  </binding>     
+
+  <service name="svcLocalPart">       
+    <port binding="tns:EchoMessageBinding" name="portLocalPart">          
+      <soap:address location="http://localhost:8080/EchoMessageService/EchoMessageService"/>       
+    </port>     
+  </service>  
+</definitions>

Added: webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadataMultiPort.wsdl
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadataMultiPort.wsdl?rev=611042&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadataMultiPort.wsdl (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadataMultiPort.wsdl Thu Jan 10 19:56:14 2008
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>  
+<definitions targetNamespace="http://description.jaxws.axis2.apache.org"
+             xmlns:tns="http://description.jaxws.axis2.apache.org"
+             xmlns="http://schemas.xmlsoap.org/wsdl/"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">     
+  <types>      
+    <xsd:schema targetNamespace="http://description.jaxws.axis2.apache.org" 
+                xmlns:ts="http://description.jaxws.axis2.apache.org/xsd"
+                xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">           
+      <complexType name="echoMessage">
+        <sequence>
+          <element name="request" type="xsd:string"/>
+        </sequence>          
+      </complexType>           
+      <complexType name="echoMessageResponse">             
+        <sequence>                
+          <element name="response" type="xsd:string"/>            
+        </sequence>          
+      </complexType>           
+      <element name="echoMessage" type="tns:echoMessage"/>          
+      <element name="echoMessageResponse" type="tns:echoMessageResponse"/>        
+    </xsd:schema>    
+  </types>     
+
+  <message name="echoMessage">       
+    <part name="message" element="tns:echoMessage"/>    
+  </message>     
+
+  <message name="echoMessageResponse">       
+    <part name="result" element="tns:echoMessageResponse"/>    
+  </message>     
+
+  <portType name="EchoMessagePortType">       
+    <operation name="echoMessage">          
+      <input message="tns:echoMessage" />          
+      <output message="tns:echoMessageResponse" />       
+    </operation>    
+  </portType>     
+
+  <binding name="EchoMessageBinding" type="tns:EchoMessagePortType">       
+    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>       
+    <operation name="echoMessage">          
+      <soap:operation soapAction=""/>         
+      <input>             
+        <soap:body use="literal" namespace="http://org.apache.binding.ns"/>          
+      </input>           
+      <output>             
+        <soap:body use="literal" namespace="http://org.apache.binding.ns"/>         
+      </output>       
+    </operation>    
+  </binding>     
+
+  <service name="svcLocalPart">       
+    <port binding="tns:EchoMessageBinding" name="portLocalPartMulti1">          
+      <soap:address location="http://localhost:8080/EchoMessageService/EchoMessageService/portLocalPartMulti1"/>       
+    </port>     
+    <port binding="tns:EchoMessageBinding" name="portLocalPartMulti2">          
+      <soap:address location="http://localhost:8080/EchoMessageService/EchoMessageService/portLocalPartMulti2"/>       
+    </port>     
+    <port binding="tns:EchoMessageBinding" name="portLocalPartMulti3">          
+      <soap:address location="http://localhost:8080/EchoMessageService/EchoMessageService/portLocalPartMulti3"/>       
+    </port>     
+  </service>  
+</definitions>

Added: webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadataOther.wsdl
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadataOther.wsdl?rev=611042&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadataOther.wsdl (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadataOther.wsdl Thu Jan 10 19:56:14 2008
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>  
+<definitions targetNamespace="http://description.jaxws.axis2.apache.org"
+             xmlns:tns="http://description.jaxws.axis2.apache.org"
+             xmlns="http://schemas.xmlsoap.org/wsdl/"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">     
+  <types>      
+    <xsd:schema targetNamespace="http://description.jaxws.axis2.apache.org" 
+                xmlns:ts="http://description.jaxws.axis2.apache.org/xsd"
+                xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">           
+      <complexType name="echoMessage">
+        <sequence>
+          <element name="request" type="xsd:string"/>
+        </sequence>          
+      </complexType>           
+      <complexType name="echoMessageResponse">             
+        <sequence>                
+          <element name="response" type="xsd:string"/>            
+        </sequence>          
+      </complexType>           
+      <element name="echoMessage" type="tns:echoMessage"/>          
+      <element name="echoMessageResponse" type="tns:echoMessageResponse"/>        
+    </xsd:schema>    
+  </types>     
+
+  <message name="echoMessage">       
+    <part name="message" element="tns:echoMessage"/>    
+  </message>     
+
+  <message name="echoMessageResponse">       
+    <part name="result" element="tns:echoMessageResponse"/>    
+  </message>     
+
+  <portType name="EchoMessagePortType">       
+    <operation name="echoMessage">          
+      <input message="tns:echoMessage" />          
+      <output message="tns:echoMessageResponse" />       
+    </operation>    
+  </portType>     
+
+  <binding name="EchoMessageBinding" type="tns:EchoMessagePortType">       
+    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>       
+    <operation name="echoMessage">          
+      <soap:operation soapAction=""/>         
+      <input>             
+        <soap:body use="literal" namespace="http://org.apache.binding.ns"/>          
+      </input>           
+      <output>             
+        <soap:body use="literal" namespace="http://org.apache.binding.ns"/>         
+      </output>       
+    </operation>    
+  </binding>     
+
+  <service name="svcLocalPart">       
+    <port binding="tns:EchoMessageBinding" name="portLocalPartOther">          
+      <soap:address location="http://localhost:8080/EchoMessageService/EchoMessageService"/>       
+    </port>     
+  </service>  
+</definitions>

Added: webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadataOverriden.wsdl
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadataOverriden.wsdl?rev=611042&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadataOverriden.wsdl (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/ClientMetadataOverriden.wsdl Thu Jan 10 19:56:14 2008
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>  
+<definitions targetNamespace="http://description.jaxws.axis2.apache.org"
+             xmlns:tns="http://description.jaxws.axis2.apache.org"
+             xmlns="http://schemas.xmlsoap.org/wsdl/"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">     
+  <types>      
+    <xsd:schema targetNamespace="http://description.jaxws.axis2.apache.org" 
+                xmlns:ts="http://description.jaxws.axis2.apache.org/xsd"
+                xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">           
+      <complexType name="echoMessage">
+        <sequence>
+          <element name="request" type="xsd:string"/>
+        </sequence>          
+      </complexType>           
+      <complexType name="echoMessageResponse">             
+        <sequence>                
+          <element name="response" type="xsd:string"/>            
+        </sequence>          
+      </complexType>           
+      <element name="echoMessage" type="tns:echoMessage"/>          
+      <element name="echoMessageResponse" type="tns:echoMessageResponse"/>        
+    </xsd:schema>    
+  </types>     
+
+  <message name="echoMessage">       
+    <part name="message" element="tns:echoMessage"/>    
+  </message>     
+
+  <message name="echoMessageResponse">       
+    <part name="result" element="tns:echoMessageResponse"/>    
+  </message>     
+
+  <portType name="EchoMessagePortType">       
+    <operation name="echoMessage">          
+      <input message="tns:echoMessage" />          
+      <output message="tns:echoMessageResponse" />       
+    </operation>    
+  </portType>     
+
+  <binding name="EchoMessageBinding" type="tns:EchoMessagePortType">       
+    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>       
+    <operation name="echoMessage">          
+      <soap:operation soapAction=""/>         
+      <input>             
+        <soap:body use="literal" namespace="http://org.apache.binding.ns"/>          
+      </input>           
+      <output>             
+        <soap:body use="literal" namespace="http://org.apache.binding.ns"/>         
+      </output>       
+    </operation>    
+  </binding>     
+
+  <service name="svcLocalPart">       
+    <port binding="tns:EchoMessageBinding" name="portLocalPartOverriden">          
+      <soap:address location="http://localhost:8080/EchoMessageService/EchoMessageService"/>       
+    </port>     
+  </service>  
+</definitions>

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/ClientAnnotationTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/ClientAnnotationTests.java?rev=611042&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/ClientAnnotationTests.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/ClientAnnotationTests.java Thu Jan 10 19:56:14 2008
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *      
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axis2.jaxws.description;
+
+import javax.jws.HandlerChain;
+import javax.jws.Oneway;
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebResult;
+import javax.jws.WebService;
+import javax.xml.namespace.QName;
+import javax.xml.ws.RequestWrapper;
+import javax.xml.ws.ResponseWrapper;
+import javax.xml.ws.Service;
+import javax.xml.ws.WebServiceClient;
+
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+/**
+ * Test that the annotations valid on a service requester can be 
+ * processed. 
+ */
+public class ClientAnnotationTests extends TestCase {
+    private String namespaceURI = "http://org.apache.axis2.jaxws.description.ClientAnnotationTests";
+    private String svcLocalPart = "svcLocalPart";
+    private String portLocalPart = "portLocalPart";
+
+    public void testSEIAnnotations() {
+        QName serviceQName = new QName(namespaceURI, svcLocalPart);
+        Service service = new ClientAnnotationTestsService(null, serviceQName);
+        QName portQName = new QName(namespaceURI, portLocalPart);
+        ClientAnnotationTestsSEI port = service.getPort(portQName, ClientAnnotationTestsSEI.class);
+    }
+
+}
+
+@WebServiceClient
+class ClientAnnotationTestsService extends javax.xml.ws.Service {
+    protected ClientAnnotationTestsService(URL wsdlDocumentLocation, QName serviceName) {
+        super(wsdlDocumentLocation, serviceName);
+    }
+}
+
+@WebService
+@HandlerChain(file="ClientAnnotationTestsHandler.xml")
+interface ClientAnnotationTestsSEI {
+ 
+    @WebMethod
+    @WebResult
+    public String echo(@WebParam
+                       String arg);
+    
+    @Oneway
+    public void oneWay();
+    
+    @ResponseWrapper
+    @RequestWrapper
+    public String echoWrap(String art);
+}

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/ClientAnnotationTestsHandler.xml
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/ClientAnnotationTestsHandler.xml?rev=611042&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/ClientAnnotationTestsHandler.xml (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/ClientAnnotationTestsHandler.xml Thu Jan 10 19:56:14 2008
@@ -0,0 +1,28 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<jws:handler-chains xmlns:jws="http://java.sun.com/xml/ns/javaee">
+  <jws:handler-chain>
+    <jws:handler>
+      <jws:handler-class>org.apache.axis2.jaxws.spi.handler.DummySOAPHandler</jws:handler-class>
+    </jws:handler>
+    <jws:handler>
+      <jws:handler-class>org.apache.axis2.jaxws.spi.handler.DummyLogicalHandler</jws:handler-class>
+    </jws:handler>
+  </jws:handler-chain>
+</jws:handler-chains>

Modified: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/DescriptionTestUtils2.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/DescriptionTestUtils2.java?rev=611042&r1=611041&r2=611042&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/DescriptionTestUtils2.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/DescriptionTestUtils2.java Thu Jan 10 19:56:14 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;
     }
 
 }

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/ClientMetadataPortTest.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/ClientMetadataPortTest.java?rev=611042&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/ClientMetadataPortTest.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/ClientMetadataPortTest.java Thu Jan 10 19:56:14 2008
@@ -0,0 +1,465 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *      
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axis2.jaxws.spi;
+
+import org.apache.axis2.jaxws.description.DescriptionTestUtils2;
+import org.apache.axis2.jaxws.description.EndpointDescription;
+import org.apache.axis2.jaxws.description.ServiceDescription;
+import org.apache.axis2.jaxws.description.builder.DescriptionBuilderComposite;
+
+import javax.jws.WebService;
+import javax.xml.namespace.QName;
+import javax.xml.ws.Binding;
+import javax.xml.ws.Holder;
+import javax.xml.ws.Service;
+import javax.xml.ws.WebServiceClient;
+import javax.xml.ws.soap.SOAPBinding;
+
+import java.net.URL;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+/**
+ * 
+ */
+public class ClientMetadataPortTest extends TestCase {
+    static final String namespaceURI = "http://description.jaxws.axis2.apache.org";
+    static final String svcLocalPart = "svcLocalPart";
+
+    static final String originalWsdl = "ClientMetadata.wsdl";
+    static final String overridenWsdl = "ClientMetadataOverriden.wsdl";
+    static final String otherWsdl = "ClientMetadataOther.wsdl";
+    static final String multiPortWsdl = "ClientMetadataMultiPort.wsdl";
+
+    static final String originalWsdl_portLocalPart = "portLocalPart";
+    static final String overridenWsdl_portLocalPart = "portLocalPartOverriden";
+    static final String otherWsdl_portLocalPart = "portLocalPartOther";
+    static final String multiPortWsdl_portLocalPart1 = "portLocalPartMulti1";
+    static final String multiPortWsdl_portLocalPart2 = "portLocalPartMulti2";
+    static final String multiPortWsdl_portLocalPart3 = "portLocalPartMulti3";
+    
+    /**
+     * Test the getPort functionality without any composite specified.
+     */
+    public void testOriginalGetPort() {
+        QName serviceQName = new QName(namespaceURI, svcLocalPart);
+        URL wsdlUrl = ClientMetadataTest.getWsdlURL(otherWsdl);
+        Service service = Service.create(wsdlUrl, serviceQName);
+        assertNotNull(service);
+        ServiceDelegate serviceDelegate = DescriptionTestUtils2.getServiceDelegate(service);
+        assertNotNull(serviceDelegate);
+        ServiceDescription serviceDesc = serviceDelegate.getServiceDescription();
+        assertNotNull(serviceDesc);
+        DescriptionBuilderComposite dbcInServiceDesc = DescriptionTestUtils2.getServiceDescriptionComposite(serviceDesc);
+        assertNotNull(dbcInServiceDesc);
+        assertEquals(Service.class, dbcInServiceDesc.getCorrespondingClass());
+        // Since this is a generic Service with no overrides, there will be no WebServiceClient annotation
+        WebServiceClient wsClient = dbcInServiceDesc.getWebServiceClientAnnot();
+        assertNull(wsClient);
+
+        // WSDL was specified on the create, so make sure the right one was used by checking the ports
+        assertTrue("Wrong WSDL used", ClientMetadataTest.validatePort(service, otherWsdl_portLocalPart));
+        
+        QName portQN = new QName(namespaceURI, otherWsdl_portLocalPart);
+        ClientMetadataPortSEI port = service.getPort(portQN, ClientMetadataPortSEI.class);
+        assertNotNull(port);
+    }
+    
+    /**
+     * Specify a sparse composite on a getPort call
+     */
+    public void testGetPortWithComposite() {
+        QName serviceQName = new QName(namespaceURI, svcLocalPart);
+        URL wsdlUrl = ClientMetadataTest.getWsdlURL(otherWsdl);
+        Service service = Service.create(wsdlUrl, serviceQName);
+        ServiceDelegate serviceDelegate = DescriptionTestUtils2.getServiceDelegate(service);
+        assertNull(ServiceDelegate.getServiceMetadata());
+        ServiceDescription serviceDesc = serviceDelegate.getServiceDescription();
+
+        DescriptionBuilderComposite sparseComposite = new DescriptionBuilderComposite();
+        assertNull(ServiceDelegate.getPortMetadata());
+        ServiceDelegate.setPortMetadata(sparseComposite);
+        assertNull(ServiceDelegate.getServiceMetadata());
+        assertSame(sparseComposite, ServiceDelegate.getPortMetadata());
+        QName portQN = new QName(namespaceURI, otherWsdl_portLocalPart);
+        ClientMetadataPortSEI port = service.getPort(portQN, ClientMetadataPortSEI.class);
+        assertNotNull(port);
+        assertNull(ServiceDelegate.getPortMetadata());
+        
+        EndpointDescription epDescArray[] = serviceDesc.getEndpointDescriptions();
+        assertEquals(1, epDescArray.length);
+        DescriptionBuilderComposite epDBC = epDescArray[0].getDescriptionBuilderComposite();
+        assertNotNull(epDBC);
+        assertNotSame(sparseComposite, epDBC);
+        assertSame(sparseComposite, epDBC.getSparseComposite(serviceDelegate));
+    }
+    
+    /**
+     * Do multiple getPorts on the same service specifiying different sparse composite.  Verify that
+     * the sparse composite overwrites the previous one.
+     */
+    public void testMulitpleGetPortSameService() {
+        QName serviceQName = new QName(namespaceURI, svcLocalPart);
+        URL wsdlUrl = ClientMetadataTest.getWsdlURL(otherWsdl);
+        Service service = Service.create(wsdlUrl, serviceQName);
+        ServiceDelegate serviceDelegate = DescriptionTestUtils2.getServiceDelegate(service);
+        assertNull(ServiceDelegate.getServiceMetadata());
+        ServiceDescription serviceDesc = serviceDelegate.getServiceDescription();
+
+        // Do the first getPort on the first Service
+        DescriptionBuilderComposite sparseComposite1 = new DescriptionBuilderComposite();
+        assertNull(ServiceDelegate.getPortMetadata());
+        ServiceDelegate.setPortMetadata(sparseComposite1);
+        assertNull(ServiceDelegate.getServiceMetadata());
+        assertSame(sparseComposite1, ServiceDelegate.getPortMetadata());
+        QName portQN = new QName(namespaceURI, otherWsdl_portLocalPart);
+        ClientMetadataPortSEI port1 = service.getPort(portQN, ClientMetadataPortSEI.class);
+        EndpointDescription epDescArray1[] = serviceDesc.getEndpointDescriptions();
+        assertEquals(1, epDescArray1.length);
+        DescriptionBuilderComposite epDBC1 = epDescArray1[0].getDescriptionBuilderComposite();
+        assertNotNull(epDBC1);
+        assertNotSame(sparseComposite1, epDBC1);
+        assertSame(sparseComposite1, epDBC1.getSparseComposite(serviceDelegate));
+        
+        // Do a second getPort for the same port on the same service using a different composite
+        DescriptionBuilderComposite sparseComposite2 = new DescriptionBuilderComposite();
+        assertNull(ServiceDelegate.getPortMetadata());
+        ServiceDelegate.setPortMetadata(sparseComposite2);
+        assertNull(ServiceDelegate.getServiceMetadata());
+        assertSame(sparseComposite2, ServiceDelegate.getPortMetadata());
+
+        ClientMetadataPortSEI port2 = service.getPort(portQN, ClientMetadataPortSEI.class);
+        EndpointDescription epDescArray2[] = serviceDesc.getEndpointDescriptions();
+        assertEquals(1, epDescArray2.length);
+        DescriptionBuilderComposite epDBC2 = epDescArray2[0].getDescriptionBuilderComposite();
+        assertNotNull(epDBC2);
+        assertNotSame(sparseComposite2, epDBC2);
+        assertSame(sparseComposite2, epDBC1.getSparseComposite(serviceDelegate));
+        // Verify the previous sparse composite was overwritten for this delegate
+        assertNotSame(sparseComposite1, epDBC1.getSparseComposite(serviceDelegate));
+    }
+    
+    /**
+     * Test multiple getPorts using different composites on different services.  Validate the composite
+     * is for each service delegate is different.  Note that we have to install a configuration
+     * factory that will cause the ServiceDescriptions to be cached; the default factory will
+     * not.
+     */
+    public void testGetPortDifferentServices() {
+        
+        try {
+            ClientMetadataTest.installCachingFactory();
+            QName serviceQName = new QName(namespaceURI, svcLocalPart);
+            QName portQN = new QName(namespaceURI, otherWsdl_portLocalPart);
+            URL wsdlUrl = ClientMetadataTest.getWsdlURL(otherWsdl);
+
+            // Create the first service 
+            Service service1 = Service.create(wsdlUrl, serviceQName);
+            ServiceDelegate serviceDelegate1 = DescriptionTestUtils2.getServiceDelegate(service1);
+            assertNull(ServiceDelegate.getServiceMetadata());
+            ServiceDescription serviceDesc1 = serviceDelegate1.getServiceDescription();
+            
+            // Do the first getPort on the first Service
+            DescriptionBuilderComposite sparseComposite1 = new DescriptionBuilderComposite();
+            assertNull(ServiceDelegate.getPortMetadata());
+            ServiceDelegate.setPortMetadata(sparseComposite1);
+            assertNull(ServiceDelegate.getServiceMetadata());
+            assertSame(sparseComposite1, ServiceDelegate.getPortMetadata());
+            ClientMetadataPortSEI port1 = service1.getPort(portQN, ClientMetadataPortSEI.class);
+            EndpointDescription epDescArray1[] = serviceDesc1.getEndpointDescriptions();
+            assertEquals(1, epDescArray1.length);
+            DescriptionBuilderComposite epDBC1 = epDescArray1[0].getDescriptionBuilderComposite();
+            assertNotNull(epDBC1);
+            assertNotSame(sparseComposite1, epDBC1);
+            assertSame(sparseComposite1, epDBC1.getSparseComposite(serviceDelegate1));
+            
+            // Create the second service 
+            Service service2 = Service.create(wsdlUrl, serviceQName);
+            ServiceDelegate serviceDelegate2 = DescriptionTestUtils2.getServiceDelegate(service2);
+            assertNull(ServiceDelegate.getServiceMetadata());
+            ServiceDescription serviceDesc2 = serviceDelegate2.getServiceDescription();
+
+            // Do the getPort on the second Service
+            DescriptionBuilderComposite sparseComposite2 = new DescriptionBuilderComposite();
+            assertNull(ServiceDelegate.getPortMetadata());
+            ServiceDelegate.setPortMetadata(sparseComposite2);
+            assertNull(ServiceDelegate.getServiceMetadata());
+            assertSame(sparseComposite2, ServiceDelegate.getPortMetadata());
+            ClientMetadataPortSEI port2 = service2.getPort(portQN, ClientMetadataPortSEI.class);
+            EndpointDescription epDescArray2[] = serviceDesc2.getEndpointDescriptions();
+            assertEquals(1, epDescArray2.length);
+            DescriptionBuilderComposite epDBC2 = epDescArray2[0].getDescriptionBuilderComposite();
+            assertNotNull(epDBC2);
+            assertNotSame(sparseComposite2, epDBC2);
+            
+            // Since we installed a caching configuration factory above, the ServiceDescriptions
+            // should match for the two service delegates.  The EndpointDesc and the composite
+            // in the EndpointDesc should be the same.  The sparse composite should be unique to
+            // each service delegate.
+            assertNotSame(serviceDelegate1, serviceDelegate2);
+            assertSame(serviceDesc1, serviceDesc2);
+            assertSame(epDBC1, epDBC2);
+            assertSame(epDescArray1[0], epDescArray2[0]);
+            assertNotSame(sparseComposite1, sparseComposite2);
+            assertSame(sparseComposite1, epDBC1.getSparseComposite(serviceDelegate1));
+            assertSame(sparseComposite2, epDBC2.getSparseComposite(serviceDelegate2));
+        } finally {
+            ClientMetadataTest.restoreOriginalFactory();
+        }
+    }
+    
+    /**
+     * Test doing GET_PORT on seperate ports under the same service.  They should have unique
+     * EndpointDesriptions and the sparse composites should be unique to the service delegate and
+     * endpoint.
+     */
+    public void testMultiplePortsSameService() {
+        QName serviceQName = new QName(namespaceURI, svcLocalPart);
+        URL wsdlUrl = ClientMetadataTest.getWsdlURL(multiPortWsdl);
+        QName portQN1 = new QName(namespaceURI, multiPortWsdl_portLocalPart1);
+        QName portQN2 = new QName(namespaceURI, multiPortWsdl_portLocalPart2);
+
+        Service service = Service.create(wsdlUrl, serviceQName);
+        ServiceDelegate serviceDelegate = DescriptionTestUtils2.getServiceDelegate(service);
+        assertNull(ServiceDelegate.getServiceMetadata());
+        ServiceDescription serviceDesc = serviceDelegate.getServiceDescription();
+
+        // Do the first getPort on the first Service
+        DescriptionBuilderComposite sparseComposite1 = new DescriptionBuilderComposite();
+        ServiceDelegate.setPortMetadata(sparseComposite1);
+        assertNull(ServiceDelegate.getServiceMetadata());
+        assertSame(sparseComposite1, ServiceDelegate.getPortMetadata());
+        ClientMetadataPortSEI port1 = service.getPort(portQN1, ClientMetadataPortSEI.class);
+        EndpointDescription epDescArray1[] = serviceDesc.getEndpointDescriptions();
+        assertEquals(1, epDescArray1.length);
+        DescriptionBuilderComposite epDBC1 = epDescArray1[0].getDescriptionBuilderComposite();
+        assertNotNull(epDBC1);
+        assertNotSame(sparseComposite1, epDBC1);
+        assertSame(sparseComposite1, epDBC1.getSparseComposite(serviceDelegate));
+        
+        // Do a second getPort for a different port on the same service using a different composite
+        DescriptionBuilderComposite sparseComposite2 = new DescriptionBuilderComposite();
+        assertNull(ServiceDelegate.getPortMetadata());
+        ServiceDelegate.setPortMetadata(sparseComposite2);
+        assertNull(ServiceDelegate.getServiceMetadata());
+        assertSame(sparseComposite2, ServiceDelegate.getPortMetadata());
+        ClientMetadataPortSEI port2 = service.getPort(portQN2, ClientMetadataPortSEI.class);
+        EndpointDescription epDescArray2[] = serviceDesc.getEndpointDescriptions();
+        assertEquals(2, epDescArray2.length);
+        EndpointDescription epdPort1 = serviceDesc.getEndpointDescription(portQN1);
+        EndpointDescription epdPort2 = serviceDesc.getEndpointDescription(portQN2);
+        assertNotNull(epdPort1);
+        assertNotNull(epdPort2);
+        assertNotSame(epdPort1, epdPort2);
+        
+        DescriptionBuilderComposite epDBC2 = epdPort2.getDescriptionBuilderComposite();
+        assertNotNull(epDBC2);
+        
+        assertSame(epDescArray1[0], epdPort1);
+        assertNotSame(epDBC1, epDBC2);
+        
+        assertSame(sparseComposite2, epDBC2.getSparseComposite(serviceDelegate));
+        assertNotSame(sparseComposite2, epDBC1.getSparseComposite(serviceDelegate));
+        
+        assertSame(sparseComposite1, epDBC1.getSparseComposite(serviceDelegate));
+        assertNotSame(sparseComposite1, epDBC2.getSparseComposite(serviceDelegate));
+    }
+
+    /**
+     * Validate setting a prefered port when creating the service results in a particular
+     * port being returned on the getPort(Class) call.
+     */
+    public void testPreferredPort() {
+        // Without setting a prefered port, the first port in the WSDL should
+        // be returned.
+        QName serviceQName = new QName(namespaceURI, svcLocalPart);
+        URL wsdlUrl = ClientMetadataTest.getWsdlURL(multiPortWsdl);
+        QName portQN1 = new QName(namespaceURI, multiPortWsdl_portLocalPart1);
+        
+        Service service1 = Service.create(wsdlUrl, serviceQName);
+        ClientMetadataPortSEI port1 = service1.getPort(ClientMetadataPortSEI.class);
+        assertNotNull(port1);
+        // Get the endpoint address to verify which port we got.  Note that the WSDL is setup
+        // so that the endpoint address ends with the name of the port for testing.
+        BindingProvider bindingProvider1 = (BindingProvider) port1;
+        Map<String, Object> requestContext1 = bindingProvider1.getRequestContext();
+        String endpointAddress1 = (String) requestContext1.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
+        assertNotNull(endpointAddress1);
+        // FIXME: We should get the first port in the WSDL, but that isn't working
+//        assertTrue(endpointAddress.endsWith(multiPortWsdl_portLocalPart1));
+        assertTrue(endpointAddress1.endsWith(multiPortWsdl_portLocalPart3));
+        
+        // Set a prefered port and create the service
+        QName portQN2 = new QName(namespaceURI, multiPortWsdl_portLocalPart2);
+        DescriptionBuilderComposite sparseComposite2 = new DescriptionBuilderComposite();
+        sparseComposite2.setPreferredPort(portQN2);
+        ServiceDelegate.setServiceMetadata(sparseComposite2);
+        Service service2 = Service.create(wsdlUrl, serviceQName);
+        ClientMetadataPortSEI port2 = service2.getPort(ClientMetadataPortSEI.class);
+        BindingProvider bindingProvider2 = (BindingProvider) port2;
+        Map<String, Object> requestContext2 = bindingProvider2.getRequestContext();
+        String endpointAddress2 = (String) requestContext2.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
+        assertNotNull(endpointAddress2);
+        assertTrue(endpointAddress2.endsWith(multiPortWsdl_portLocalPart2));
+        
+    }
+    /**
+     * Validate setting a prefered port when creating the service results in a particular
+     * port being returned on the getPort(Class) call.  The ServiceDesc in this case 
+     * are cached.
+     */
+    public void testPreferredPortCachedService() {
+        try {
+            ClientMetadataTest.installCachingFactory();
+
+            // Without setting a prefered port, the first port in the WSDL should
+            // be returned.
+            QName serviceQName = new QName(namespaceURI, svcLocalPart);
+            URL wsdlUrl = ClientMetadataTest.getWsdlURL(multiPortWsdl);
+            QName portQN1 = new QName(namespaceURI, multiPortWsdl_portLocalPart1);
+            
+            Service service1 = Service.create(wsdlUrl, serviceQName);
+            ServiceDelegate serviceDelegate1 = DescriptionTestUtils2.getServiceDelegate(service1);
+            ServiceDescription svcDesc1 = serviceDelegate1.getServiceDescription();
+            ClientMetadataPortSEI port1 = service1.getPort(ClientMetadataPortSEI.class);
+            assertNotNull(port1);
+            // Get the endpoint address to verify which port we got.  Note that the WSDL is setup
+            // so that the endpoint address ends with the name of the port for testing.
+            BindingProvider bindingProvider1 = (BindingProvider) port1;
+            Map<String, Object> requestContext1 = bindingProvider1.getRequestContext();
+            String endpointAddress1 = (String) requestContext1.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
+            assertNotNull(endpointAddress1);
+            // FIXME: We should get the first port in the WSDL, but that isn't working
+//            assertTrue(endpointAddress.endsWith(multiPortWsdl_portLocalPart1));
+            assertTrue(endpointAddress1.endsWith(multiPortWsdl_portLocalPart3));
+            
+            // Set a prefered port and create the service
+            QName portQN2 = new QName(namespaceURI, multiPortWsdl_portLocalPart2);
+            DescriptionBuilderComposite sparseComposite2 = new DescriptionBuilderComposite();
+            sparseComposite2.setPreferredPort(portQN2);
+            ServiceDelegate.setServiceMetadata(sparseComposite2);
+            Service service2 = Service.create(wsdlUrl, serviceQName);
+            ServiceDelegate serviceDelegate2 = DescriptionTestUtils2.getServiceDelegate(service2);
+            ServiceDescription svcDesc2 = serviceDelegate2.getServiceDescription();
+            assertNotSame(service1, service2);
+            assertNotSame(serviceDelegate1, serviceDelegate2);
+            assertSame(svcDesc1, svcDesc2);
+            
+            ClientMetadataPortSEI port2 = service2.getPort(ClientMetadataPortSEI.class);
+            BindingProvider bindingProvider2 = (BindingProvider) port2;
+            Map<String, Object> requestContext2 = bindingProvider2.getRequestContext();
+            String endpointAddress2 = (String) requestContext2.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
+            assertNotNull(endpointAddress2);
+            assertTrue(endpointAddress2.endsWith(multiPortWsdl_portLocalPart2));
+            
+            // Create a third service without a composite and make sure the previous composite
+            // setting of preferred port doesn't affect this one.
+            Service service3 = Service.create(wsdlUrl, serviceQName);
+            ServiceDelegate serviceDelegate3 = DescriptionTestUtils2.getServiceDelegate(service3);
+            ServiceDescription svcDesc3 = serviceDelegate3.getServiceDescription();
+            assertNotSame(service2, service3);
+            assertNotSame(serviceDelegate1, serviceDelegate3);
+            assertNotSame(serviceDelegate2, serviceDelegate3);
+            assertSame(svcDesc1, svcDesc3);
+            
+            ClientMetadataPortSEI port3 = service3.getPort(ClientMetadataPortSEI.class);
+            assertNotNull(port3);
+            BindingProvider bindingProvider3 = (BindingProvider) port3;
+            Map<String, Object> requestContext3 = bindingProvider3.getRequestContext();
+            String endpointAddress3 = (String) requestContext3.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
+            assertNotNull(endpointAddress1);
+            // FIXME: We should get the first port in the WSDL, but that isn't working
+//            assertTrue(endpointAddress.endsWith(multiPortWsdl_portLocalPart1));
+            assertTrue(endpointAddress1.endsWith(multiPortWsdl_portLocalPart3));
+
+        } finally {
+            ClientMetadataTest.restoreOriginalFactory();
+        }
+    }
+    
+    /**
+     * Validate enabling MTOM when creating the service results ports created under that service
+     * have MTOM enabled.
+     */
+    public void testEnableMTOM() {
+        QName serviceQName = new QName(namespaceURI, svcLocalPart);
+        URL wsdlUrl = ClientMetadataTest.getWsdlURL(multiPortWsdl);
+        DescriptionBuilderComposite sparseComposite = new DescriptionBuilderComposite();
+        sparseComposite.setIsMTOMEnabled(true);
+        ServiceDelegate.setServiceMetadata(sparseComposite);
+        Service service = Service.create(wsdlUrl, serviceQName);
+        ClientMetadataPortSEI port = service.getPort(ClientMetadataPortSEI.class);
+        assertNotNull(port);
+        // Verify that MTOM is enabled on this port.
+        BindingProvider bindingProvider = (BindingProvider) port;
+        SOAPBinding binding = (SOAPBinding) bindingProvider.getBinding();
+        assertTrue(binding.isMTOMEnabled());
+        
+        // Verify that specific ports under this service also have MTOM enabled
+        QName port1QN = new QName(namespaceURI, multiPortWsdl_portLocalPart1);
+        ClientMetadataPortSEI port1 = service.getPort(port1QN, ClientMetadataPortSEI.class);
+        SOAPBinding binding1 = ((SOAPBinding) ((BindingProvider) port1).getBinding());
+        assertTrue(binding1.isMTOMEnabled());
+        
+        QName port2QN = new QName(namespaceURI, multiPortWsdl_portLocalPart2);
+        ClientMetadataPortSEI port2 = service.getPort(port2QN, ClientMetadataPortSEI.class);
+        SOAPBinding binding2 = ((SOAPBinding) ((BindingProvider) port2).getBinding());
+        assertTrue(binding2.isMTOMEnabled());
+    }
+    
+    /**
+     * Validate enabling MTOM when creating the service results in enablement only
+     * for that service delegate, and not a different service delegate referencing
+     * the same service.
+     */
+    public void testEnableMTOMCachedService() {
+        try {
+            ClientMetadataTest.installCachingFactory();
+
+            QName serviceQName = new QName(namespaceURI, svcLocalPart);
+            URL wsdlUrl = ClientMetadataTest.getWsdlURL(multiPortWsdl);
+
+            DescriptionBuilderComposite sparseComposite = new DescriptionBuilderComposite();
+            sparseComposite.setIsMTOMEnabled(true);
+            ServiceDelegate.setServiceMetadata(sparseComposite);
+            Service service1 = Service.create(wsdlUrl, serviceQName);
+            
+            Service service2 = Service.create(wsdlUrl, serviceQName);
+            
+            QName portQN = new QName(namespaceURI, multiPortWsdl_portLocalPart1);
+            ClientMetadataPortSEI port1 = service1.getPort(portQN, ClientMetadataPortSEI.class);
+            ClientMetadataPortSEI port2 = service2.getPort(portQN, ClientMetadataPortSEI.class);
+
+            SOAPBinding binding1 = ((SOAPBinding) ((BindingProvider) port1).getBinding());
+            assertTrue(binding1.isMTOMEnabled());
+            
+            SOAPBinding binding2 = ((SOAPBinding) ((BindingProvider) port2).getBinding());
+            assertFalse(binding2.isMTOMEnabled());
+
+        } finally {
+            ClientMetadataTest.restoreOriginalFactory();
+        }
+    }
+}
+
+@WebService(name="EchoMessagePortType", targetNamespace="http://description.jaxws.axis2.apache.org")
+interface ClientMetadataPortSEI {
+    public String echoMessage(String string);
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org