geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From xuhaih...@apache.org
Subject svn commit: r1150977 [4/5] - in /geronimo/bundles/trunk/axis2: ./ src/main/java/org/apache/axis2/handlers/ src/main/java/org/apache/axis2/handlers/addressing/ src/main/java/org/apache/axis2/jaxws/ src/main/java/org/apache/axis2/jaxws/addressing/factory...
Date Tue, 26 Jul 2011 03:06:02 GMT
Added: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java?rev=1150977&view=auto
==============================================================================
--- geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java (added)
+++ geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java Tue Jul 26 03:06:00 2011
@@ -0,0 +1,3167 @@
+/*
+ * 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.impl;
+
+import org.apache.axis2.client.ServiceClient;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.java.security.AccessController;
+import org.apache.axis2.jaxws.ClientConfigurationFactory;
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.catalog.JAXWSCatalogManager;
+import org.apache.axis2.jaxws.catalog.impl.OASISCatalogManager;
+import org.apache.axis2.jaxws.description.DescriptionFactory;
+import org.apache.axis2.jaxws.description.EndpointDescription;
+import org.apache.axis2.jaxws.description.EndpointInterfaceDescription;
+import org.apache.axis2.jaxws.description.ResolvedHandlersDescription;
+import org.apache.axis2.jaxws.description.ServiceDescription;
+import org.apache.axis2.jaxws.description.ServiceDescriptionJava;
+import org.apache.axis2.jaxws.description.ServiceDescriptionWSDL;
+import org.apache.axis2.jaxws.description.ServiceRuntimeDescription;
+import org.apache.axis2.jaxws.description.builder.AddressingAnnot;
+import org.apache.axis2.jaxws.description.builder.DescriptionBuilderComposite;
+import org.apache.axis2.jaxws.description.builder.MDQConstants;
+import org.apache.axis2.jaxws.description.builder.MTOMAnnot;
+import org.apache.axis2.jaxws.description.builder.PortComposite;
+import org.apache.axis2.jaxws.description.builder.RespectBindingAnnot;
+
+import static org.apache.axis2.jaxws.description.builder.MDQConstants.RETURN_TYPE_FUTURE;
+import static org.apache.axis2.jaxws.description.builder.MDQConstants.RETURN_TYPE_RESPONSE;
+import org.apache.axis2.jaxws.description.builder.MethodDescriptionComposite;
+import org.apache.axis2.jaxws.description.builder.ParameterDescriptionComposite;
+import org.apache.axis2.jaxws.description.xml.handler.HandlerChainsType;
+import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.axis2.jaxws.util.WSDL4JWrapper;
+import org.apache.axis2.jaxws.util.WSDLWrapper;
+import org.apache.axis2.jaxws.util.WeakKey;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.engine.AxisConfiguration;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.xml.resolver.Catalog;
+
+import javax.jws.HandlerChain;
+import javax.wsdl.Definition;
+import javax.wsdl.Port;
+import javax.wsdl.PortType;
+import javax.wsdl.Service;
+import javax.wsdl.WSDLException;
+import javax.wsdl.extensions.ExtensibilityElement;
+import javax.xml.namespace.QName;
+import javax.xml.ws.WebServiceClient;
+import javax.xml.ws.WebServiceException;
+import javax.xml.ws.handler.PortInfo;
+import javax.xml.ws.soap.SOAPBinding;
+import javax.xml.ws.soap.AddressingFeature.Responses;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import java.net.ConnectException;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+/** @see ../ServiceDescription */
+public class ServiceDescriptionImpl
+        implements ServiceDescription, ServiceDescriptionWSDL, ServiceDescriptionJava {
+    private ClientConfigurationFactory clientConfigFactory;
+    private ConfigurationContext configContext;
+
+    // Number of times this instance is being used.  For service-providers, this is not decremented
+    // since the serice isn't un-used once it is created.  For service-requesters, the service
+    // is used by ServiceDelegates, and becomes un-used when the ServiceDelegate is released.
+    private int useCount = 0;
+    private String wsdlURL;
+    private QName serviceQName;
+
+    private WSDLWrapper wsdlWrapper;
+    private WSDLWrapper generatedWsdlWrapper;
+    
+    //ANNOTATION: @HandlerChain
+    private HandlerChain handlerChainAnnotation;
+    private HandlerChainsType handlerChainsType;
+
+    // EndpointDescriptions from annotations and wsdl
+    private Map<QName, EndpointDescription> definedEndpointDescriptions =
+                new HashMap<QName, EndpointDescription>();
+
+    // Endpoints for dynamic ports
+    // The WeakKey is an instance of a ServiceDelegate.  It is a Weak Reference so it does not
+    // prevent the service delegate from being GC'd
+    private Map<WeakKey, Map<QName, EndpointDescriptionImpl>> dynamicEndpointDescriptions =
+                new HashMap<WeakKey, Map<QName, EndpointDescriptionImpl>>();
+    // Used to cleanup entries in the dynamic port collection when the ServiceDelegate is
+    // GC'd
+    private ReferenceQueue dynamicPortRefQueue = new ReferenceQueue<WeakKey>();
+
+    // Cache classes for the info for resolved handlers
+    private SoftReference<Map<PortInfo, ResolvedHandlersDescription>> resolvedHandlersDescription =
+            new SoftReference<Map<PortInfo, ResolvedHandlersDescription>>
+        (new ConcurrentHashMap<PortInfo, ResolvedHandlersDescription>());
+    
+    private static final Log log = LogFactory.getLog(ServiceDescriptionImpl.class);
+
+    private HashMap<String, DescriptionBuilderComposite> dbcMap = null;
+
+    private DescriptionBuilderComposite composite = null;
+    private boolean isServerSide = false;
+
+    // Allow a unique XML CatalogManager per service description.
+    private JAXWSCatalogManager catalogManager = null;
+    
+    // RUNTIME INFORMATION
+    Map<String, ServiceRuntimeDescription> runtimeDescMap =
+            new ConcurrentHashMap<String, ServiceRuntimeDescription>();
+    
+    /**
+     * Property representing a collection of endpointDescription instances for dynamic ports 
+     * which are shared across all services on an AxisConfig.  Note that this behavior is incorrect; dynamic 
+     * ports should only be visible to the instance of the service that created them.  However, the sharing
+     * across services is maintained for backwards compatibility.
+     * @deprecated 
+     */
+    private static final String JAXWS_DYNAMIC_ENDPOINTS = "jaxws.dynamic.endpoints";
+
+    /**
+     * Create a service-requester side (aka client-side) service description.
+     * Construct a service description hierachy
+     * based on WSDL (may be null), the Service class, and a service QName.
+     *
+     * @param wsdlURL      The WSDL file (this may be null).
+     * @param serviceQName The name of the service in the WSDL.  This can not be null since a
+     *                     javax.xml.ws.Service can not be created with a null service QName.
+     * @param serviceClass The JAX-WS service class.  This could be an instance of
+     *                     javax.xml.ws.Service or a generated service subclass thereof.  This will
+     *                     not be null.
+     */
+    ServiceDescriptionImpl(URL wsdlURL, QName serviceQName, Class serviceClass) {
+        this(wsdlURL, serviceQName, serviceClass, null, null);
+    }
+    
+    /**
+     * Create a service-requester side service description.  Same as constructor above with an 
+     * additonal composite paramater.  Note that the composite is "sparse" in that any values it
+     * contains overrides any values on the corresponding class annotation HOWEVER if the composite
+     * doesn't specify a value, it is gotten from the class annotation. 
+     * @param wsdlURL
+     * @param serviceQName
+     * @param serviceClass
+     * @param sparseComposite a composite with any annotation overrides such as from a client deployment
+     *     descriptor.  CAN NOT BE NULL, but it can be an object created with a default constructor
+     */
+    ServiceDescriptionImpl(URL wsdlURL, QName serviceQName, Class serviceClass, 
+                           DescriptionBuilderComposite sparseComposite,
+                           Object sparseCompositeKey) {
+        if (log.isDebugEnabled()) {
+            log.debug("ServiceDescriptionImpl(URL,QName,Class,DescriptionBuilderComposite,Object)");
+
+            log.debug("entry");
+            log.debug("  wsdlURL = " + wsdlURL);
+            log.debug("  serviceQName = " + serviceQName);
+            log.debug("  serviceClass = " + serviceClass);
+            log.debug("  sparseComposite = " + DescriptionUtils.dumpString(sparseComposite));
+        }
+    	
+    	if (sparseComposite != null) {
+    	    catalogManager = sparseComposite.getCatalogManager();
+        }
+    	if (catalogManager == null) {
+    		catalogManager = new OASISCatalogManager();
+        }
+    	
+        if (serviceQName == null) {
+            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("serviceDescErr0"));
+        }
+        if (serviceClass == null) {
+            throw ExceptionFactory
+                    .makeWebServiceException(Messages.getMessage("serviceDescErr1", "null"));
+        }
+        if (!javax.xml.ws.Service.class.isAssignableFrom(serviceClass)) {
+            throw ExceptionFactory.makeWebServiceException(
+                    Messages.getMessage("serviceDescErr1", serviceClass.getName()));
+        }
+
+        composite = new DescriptionBuilderComposite();
+        composite.setIsServiceProvider(false);
+        composite.setCorrespondingClass(serviceClass);
+        // The classloader was originally gotten off this class, but it seems more logical to 
+        // get it off the application service class.
+//        composite.setClassLoader(this.getClass().getClassLoader());
+        composite.setClassLoader(getClassLoader(serviceClass));
+        composite.setSparseComposite(sparseCompositeKey, sparseComposite);
+        
+        // If there's a WSDL URL specified in the sparse composite, that is a override, for example
+        // from a JSR-109 deployment descriptor, and that's the one to use.
+        URL sparseCompositeWsdlURL = getSparseCompositeWsdlURL(sparseComposite);
+        if (sparseCompositeWsdlURL != null) {
+            if (log.isDebugEnabled()) {
+                log.debug("Wsdl location overriden by sparse composite; overriden value: " + this.wsdlURL);
+            }
+            this.wsdlURL = sparseCompositeWsdlURL.toString();
+        } else {
+            // need to call getWSDLURL here to flow through XML catalog during WSDL processing
+            this.wsdlURL = wsdlURL == null ? null : getWSDLURL(wsdlURL.toString()).toString();
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("Wsdl Location value used: " + this.wsdlURL);
+        }
+        // TODO: On the client side, we should not support partial WSDL; i.e. if the WSDL is specified it must be
+        //       complete and must contain the ServiceQName.  This is how the Sun RI behaves on the client.
+        //       When this is fixed, the check in ServiceDelegate(URL, QName, Class) should be removed
+        
+        // TODO: The serviceQName needs to be verified between the argument/WSDL/Annotation
+        this.serviceQName = serviceQName;
+
+        setupWsdlDefinition();
+        if (log.isDebugEnabled()) {
+            log.debug("exit " + this.toString());
+        }
+    }
+    
+    URL getSparseCompositeWsdlURL(DescriptionBuilderComposite sparseComposite) {
+        // Use the WSDL file if it is specified in the composite
+        URL url = null;
+        if (sparseComposite != null) {
+            WebServiceClient wsc = (WebServiceClient) sparseComposite.getWebServiceClientAnnot();
+            if (wsc != null && wsc.wsdlLocation() != null) {
+                String wsdlLocation = wsc.wsdlLocation();
+                URL wsdlUrl = getWSDLURL(wsdlLocation);
+                
+                if (wsdlUrl == null) {
+                    throw ExceptionFactory.makeWebServiceException(Messages.getMessage("serviceDescErr4", wsdlLocation));
+                } else {
+                    url = wsdlUrl;
+                }
+            }
+        }
+        return url;
+    }
+
+    private static URL createWsdlURL(String wsdlLocation) {
+        URL theUrl = null;
+        try {
+            theUrl = new URL(wsdlLocation);
+        } catch (Exception ex) {
+            // Just return a null to indicate we couldn't create a URL from the string
+            if (log.isDebugEnabled()) {
+                log.debug("Unable to obtain URL for WSDL file: " + wsdlLocation
+                        + " by using File reference");
+            }
+        }
+        return theUrl;
+    }
+
+    ServiceDescriptionImpl(
+                           HashMap<String, DescriptionBuilderComposite> dbcMap,
+                           DescriptionBuilderComposite composite) {
+        this(dbcMap, composite, null);
+    }
+    
+    ServiceDescriptionImpl(HashMap<String, DescriptionBuilderComposite> dbcMap,
+                           DescriptionBuilderComposite composite,
+                           ConfigurationContext configContext) {
+        this(dbcMap, composite, configContext, null);
+    }
+    
+    /**
+     * Create a service-provider side Service description hierachy.  The hierachy is created entirely
+     * from composite.  All relevant classes and interfaces referenced from the class represented by
+     * composite must be included in the map.
+     * @param dbcMap
+     * @param composite
+     */
+    ServiceDescriptionImpl(
+            HashMap<String, DescriptionBuilderComposite> dbcMap,
+            DescriptionBuilderComposite composite, 
+            ConfigurationContext configContext, 
+            QName serviceQName) {
+        if (log.isDebugEnabled()) {
+            log.debug("ServiceDescriptionImpl(HashMap<String,DescriptionBuilderComposite>,ConfigurationContext)");
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("entry");
+            log.debug("  composite = " + DescriptionUtils.dumpString(composite));
+            log.debug("  configContext = " + configContext);
+            log.debug("  serviceQName = " + serviceQName);
+        }
+        this.composite = composite;
+        
+        this.configContext = configContext;
+
+        String serviceImplName = this.composite.getClassName();
+
+        this.dbcMap = dbcMap;
+        this.isServerSide = true;
+        this.serviceQName = serviceQName;
+        this.catalogManager = this.composite.getCatalogManager();
+        // if the composit doesn't have a catalogManager, get one only if we have a catalog file
+        if (catalogManager == null) {
+            catalogManager = createCatalogManager(composite.getClassLoader());
+        }
+        
+
+        
+        // if the ServiceDescriptionImpl was constructed with a specific service QName
+        // we should use that to retrieve the potential list of PortComposite objects
+        List<PortComposite> portComposites = null;
+        
+        if(this.serviceQName != null) {
+            portComposites = composite.getPortComposites(this.serviceQName);
+        }
+        else {
+            portComposites = composite.getPortComposites();
+        }
+        
+        
+        
+        //capture the WSDL, if there is any...to be used for later processing
+        setupWsdlDefinition();
+
+        // Do a first pass validation for this DescriptionBuilderComposite.
+        // This is not intended to be a full integrity check, but rather a fail-fast mechanism
+        validateDBCLIntegrity();
+
+        // The ServiceQName instance variable is set based on annotation or default
+        // It will be set by the EndpointDescriptionImpl since it is the one that knows
+        // how to process the annotations and the defaults.
+
+        
+        
+        // If PortComposite instances were specified on the DBC we are currently processing
+        // we want to switch the context of processing to the PortComposites
+        if(portComposites != null
+                &&
+                !portComposites.isEmpty()) {
+            if(log.isDebugEnabled()) {
+                log.debug("Constructing EndpointDescription instance from PortComposites for " +
+                		"implementation class: " + composite.getClassName());
+            }
+            int i = 0;
+            for(PortComposite portComposite : portComposites) {
+                
+                // get the properties from the SEI and the Impl
+                Map<String, Object> props = getAllProps(portComposite, dbcMap);
+                
+                // here we pass in an index so the EndpointDescriptionImpl instance will know
+                // which PortComposite instance it is associated with and can retrieve that 
+                // instance as required
+                EndpointDescriptionImpl endpointDescription =
+                    new EndpointDescriptionImpl(this, serviceImplName, props, i);
+                addEndpointDescription(endpointDescription);
+                i++;
+            }
+        }
+        
+        // If no PortComposites then we build the EndpointDescriptionImpl instance from the
+        // DBC that was supplied
+        else {
+            if(log.isDebugEnabled()) {
+                log.debug("No PortComposites found for implementation class: " + composite.getClassName());
+            }
+            
+                // get the properties from the SEI and the Impl
+                Map<String, Object> props = getAllProps(composite, dbcMap);
+                
+                // Create the single EndpointDescription hierachy from the service impl annotations; Since the PortQName is null, 
+        	// it will be set to the annotation value.
+        	EndpointDescriptionImpl endpointDescription =
+                	new EndpointDescriptionImpl(this, serviceImplName, props, null);
+        	addEndpointDescription(endpointDescription);
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("exit " + this.toString());
+        }
+    }
+
+    /*=======================================================================*/
+    /*=======================================================================*/
+    // START of public accessor methods
+
+    /**
+     * Update or create an EndpointDescription. Updates to existing EndpointDescriptons will be
+     * based on the SEI class and its annotations.  Both declared ports and dynamic ports can be
+     * updated.  A declared port is one that is defined (e.g. in WSDL or via annotations); a dyamic
+     * port is one that is not defined (e.g. not via WSDL or annotations) and has been added via
+     * Serivce.addPort.
+     * <p/>
+     * For predefined ports, a composite of sparse metadata, such as from a deployment descriptor
+     * may be supplied.  This can be used to modify the endpoint interfaceannotations such as
+     * adding a handler chain.  The sparse composite is NOT supported for dynamic (i.e. ADD_PORT)
+     * or dispatch clients. 
+     * <p/>
+     * Notes on how an EndpointDescription can be updated or created: 1) Service.createDispatch can
+     * create a Dispatch client for either a declared or dynamic port 2) Note that creating a
+     * Dispatch does not associate an SEI with an endpoint 3) Service.getPort will associate an SEI
+     * with a port 4) A getPort on an endpoint which was originally created for a Distpatch will
+     * update that EndpointDescription with the SEI provided on the getPort 5) Service.getPort can
+     * not be called on a dynamic port (per the JAX-WS spec) 6) Service.addPort can not be called
+     * for a declared port
+     *
+     * @param sei        This will be non-null if the update is of type GET_PORT; it will be null if
+     *                   the update is ADD_PORT or CREATE_DISPATCH
+     * @param portQName
+     * @param updateType Indicates what is causing the update GET_PORT is an attempt to get a
+     *                   declared SEI-based port ADD_PORT is an attempt to add a previously
+     *                   non-existent dynamic port CREATE_DISPATCH is an attempt to create a
+     *                   Dispatch-based client to either a declared port or a pre-existing dynamic
+     *                   port.
+     * @param composite  May contain sparse metadata, for example from a deployment descriptor, that
+     *                   should be used in conjunction with the class annotations to update the
+     *                   description hierarchy.  For example, it may contain a HandlerChain annotation
+     *                   based on information in a JSR-109 deployment descriptor.                    
+     */
+
+    EndpointDescription updateEndpointDescription(Class sei, 
+                                                  QName portQName,
+                                                  DescriptionFactory.UpdateType updateType,
+                                                  DescriptionBuilderComposite composite,
+                                                  Object serviceDelegateKey,
+                                                  String bindingId,
+                                                  String endpointAddress) {
+
+	
+    	EndpointDescriptionImpl endpointDescription = getEndpointDescriptionImpl(portQName);
+    	boolean isPortDeclared = isPortDeclared(portQName);
+
+    	// If a defined endpointDescription is not available, try and locate a dynamic endpoint.
+    	// Note that a dynamic port will only be found for the client that created it, per the
+    	// serviceDelegateKey
+
+    	if (endpointDescription == null && serviceDelegateKey != null) {
+    		endpointDescription = getDynamicEndpointDescriptionImpl(portQName, serviceDelegateKey);
+    	}
+
+        // If no QName was specified in the arguments, one may have been specified in the sparse
+        // composite metadata when the service was created.
+        if (DescriptionUtils.isEmpty(portQName)) {
+            QName preferredPortQN = getPreferredPort(serviceDelegateKey);
+            if (!DescriptionUtils.isEmpty(preferredPortQN)) {
+                portQName = preferredPortQN;
+            }
+        }
+
+        switch (updateType) {
+
+            case ADD_PORT:
+                if (composite != null) {
+                    throw ExceptionFactory.makeWebServiceException(Messages.getMessage("serviceDescErr5", portQName.toString()));
+                }
+                // Port must NOT be declared (e.g. can not already exist in WSDL)
+                // If an EndpointDesc doesn't exist; create it as long as it doesn't exist in the WSDL
+                if (DescriptionUtils.isEmpty(portQName)) {
+                    throw ExceptionFactory
+                            .makeWebServiceException(Messages.getMessage("addPortErr2"));
+                }
+                if (getWSDLWrapper() != null && isPortDeclared) {
+                    throw ExceptionFactory.makeWebServiceException(
+                            Messages.getMessage("addPortDup", portQName.toString()));
+                } else if (endpointDescription == null) {
+                    // Use the SEI Class and its annotations to finish creating the Description hierarchy.  Note that EndpointInterface, Operations, Parameters, etc.
+                    // are not created for dynamic ports.  It would be an error to later do a getPort against a dynamic port (per the JAX-WS spec)
+                    // If we can't add the dynamic port under a specific service delegate, that is an error
+
+                    if (serviceDelegateKey == null) {
+                        throw ExceptionFactory.makeWebServiceException(
+                                 Messages.getMessage("serviceDescriptionImplAddPortErr"));
+                    }
+
+                    endpointDescription = getDynamicEndpointDescriptionImpl(sei, portQName, bindingId, endpointAddress);    
+                    addDynamicEndpointDescriptionImpl(endpointDescription, serviceDelegateKey);
+
+                } else {
+                    // All error chJeck above passed, the EndpointDescription already exists and needs no updating
+                }
+                break;
+
+            case GET_PORT:
+                
+                // try to find existing endpointDesc by SEI class if portQName was not specified 
+                if (endpointDescription == null && portQName == null && sei != null) {
+                    endpointDescription = getEndpointDescriptionImpl(sei);
+                }
+                
+                // If an endpointDesc doesn't exist, and the port exists in the WSDL, create it
+                // If an endpointDesc already exists and has an associated SEI already, make sure they match
+                // If an endpointDesc already exists and was created for Dispatch (no SEI), update that with the SEI provided on the getPort
+
+                // Port must be declared (e.g. in WSDL or via annotations)
+                // TODO: Once isPortDeclared understands annotations and not just WSDL, the 2nd part of this check can possibly be removed.
+                //       Although consider the check below that updates an existing EndpointDescritpion with an SEI.
+                if (!isPortDeclared ||
+                        (endpointDescription != null && endpointDescription.isDynamicPort())) {
+                    // This guards against the case where an addPort was done previously and now a getPort is done on it.
+                    throw ExceptionFactory.makeWebServiceException(
+                    		Messages.getMessage("updateEPDescrErr1",(portQName != null ? portQName.toString() : "not specified")));
+                } else if (sei == null) {
+                    throw ExceptionFactory.makeWebServiceException(
+                    		Messages.getMessage("updateEPDescrErr2",(portQName != null ? portQName.toString() : "not specified")));
+                } else if (endpointDescription == null) {
+                    // Use the SEI Class and its annotations to finish creating the Description hierachy: Endpoint, EndpointInterface, Operations, Parameters, etc.
+                    endpointDescription = new EndpointDescriptionImpl(sei, portQName, this, composite, serviceDelegateKey);
+                    addEndpointDescription(endpointDescription);
+                    /*
+                     * We must reset the service runtime description after adding a new endpoint
+                     * since the runtime description information could have references to old
+                     * information. See MarshalServiceRuntimeDescriptionFactory and 
+                     * MarshalServiceRuntimeDescription.
+                     */
+                    resetServiceRuntimeDescription();
+                } else
+                if (getEndpointSEI(portQName) == null && !endpointDescription.isDynamicPort()) {
+                    // Existing endpointDesc from a declared port needs to be updated with an SEI.
+                    // This could happen if the client first did a CREATE_DISPATCH on a declared
+                    // port, which would cause it to be created, and then did a GET_PORT on the 
+                    // same port later, providing an SEI.
+                    // Notes 
+                    // 1) An EndpointDescritption created from an addPort (i.e. a dynamic port) can 
+                    //    not do this.
+                    // 2) A sparse composite may be specified.  We don't allow mixing JAX-WS unmanaged
+                    //    apis (CREATE_DISPATCH) with JSR-109 managed apis (GET_PORT with sparse
+                    //    composite metadata from a DD).  Since the sparse composite is stored by
+                    //    a key AND CREATE_DISPATCH and ADD_PORT will thrown an exception of a composite
+                    //    is specified, having a composite and key on the GET_PORTs shouldn't be
+                    //    a problem.
+                    endpointDescription.updateWithSEI(sei, composite, serviceDelegateKey);
+                } else if (getEndpointSEI(portQName) != sei) {
+                    throw ExceptionFactory.makeWebServiceException(
+                    		Messages.getMessage("updateEPDescrErr3",portQName.toString(),
+                    				sei.getName(),getEndpointSEI(portQName).getName()));
+                } else {
+                    // All error check above passed, the EndpointDescription already exists and needs no updating
+                    // Just add the sparse composite if one was specified.
+                    endpointDescription.getDescriptionBuilderComposite().setSparseComposite(serviceDelegateKey, composite);
+                }
+                break;
+
+            case CREATE_DISPATCH:
+                if (composite != null) {
+                    throw ExceptionFactory.makeWebServiceException(Messages.getMessage("serviceDescErr6"));
+                }
+                
+                // Port may or may not exist in WSDL.
+                // If an endpointDesc doesn't exist and it is in the WSDL, it can be created
+                // Otherwise, it is an error.
+                if (DescriptionUtils.isEmpty(portQName)) {
+                    throw ExceptionFactory
+                            .makeWebServiceException(Messages.getMessage("createDispatchFail0"));
+                } else if (endpointDescription != null) {
+                    // The EndpointDescription already exists; nothing needs to be done
+                } else if (sei != null) {
+                    // The Dispatch should not have an SEI associated with it on the update call.
+                    throw ExceptionFactory.makeWebServiceException(
+                    		Messages.getMessage("createDispatchFail3",portQName.toString()));
+                } else if (getWSDLWrapper() != null && isPortDeclared) {
+                    // EndpointDescription doesn't exist and this is a declared Port, so create one
+                    // Use the SEI Class and its annotations to finish creating the Description hierarchy.  
+                    // Note that EndpointInterface, Operations, Parameters, etc. are not created for 
+                    // Dispatch-based ports, but might be updated later if a getPort is done against 
+                    // the same declared port.
+                    endpointDescription = new EndpointDescriptionImpl(sei, portQName, this);
+                    addEndpointDescription(endpointDescription);
+                } else {
+                    // The port is not a declared port and it does not have an EndpointDescription, 
+                    // meaning an addPort has not been done for it
+                    // This is an error.
+                    throw ExceptionFactory.makeWebServiceException(
+                            Messages.getMessage("createDispatchFail1", portQName.toString()));
+                }
+                break;
+        }
+        return endpointDescription;
+    }
+
+    /**
+     * Find or create an EndpointDescription instance for a dynamic port.  Dynamic ports should be scoped to
+     * the instance of the service that created them, so the method getDynamicEndpointDescriptionImpl should
+     * have find one if it already exists.  However, logic was introduced (in Apache Axis2 revision 664411) that
+     * also scoped dynamic ports to a configuration context based on port name, binding ID, and endpointAddress.
+     * Although that logic is incorrect, it is maintained for backwards compatability based on the setting of
+     * a property.
+     * 
+     * @param sei
+     * @param portQName
+     * @param bindingId
+     * @param endpointAddress
+     * @return
+     */
+    private EndpointDescriptionImpl getDynamicEndpointDescriptionImpl(Class sei, QName portQName, String bindingId, String endpointAddress) {
+        if (log.isDebugEnabled()) {
+            log.debug("Calling createEndpointDescriptionImpl : ("
+                      + portQName + "," + bindingId + "," + endpointAddress + ")");
+        }
+        EndpointDescriptionImpl endpointDescription = null;
+        SharedDynamicEndpointEntry sharedDynamicEndpointEntry = null;
+        boolean areDynamicPortsShared = isShareDynamicPortsAcrossServicesEnabled();
+        if (areDynamicPortsShared) {
+            // If ports are being shared, see if there's already one in the cache.  Note that this will
+            // always return an Entry value, but the endpoint in it may be null if one wasn't found.
+            sharedDynamicEndpointEntry = findSharedDynamicEndpoint(portQName, bindingId, endpointAddress);
+            endpointDescription = sharedDynamicEndpointEntry.endpointDescription;
+        }
+        
+        boolean endpointCreated = false;
+        if(endpointDescription == null) {
+            endpointDescription = new EndpointDescriptionImpl(sei, portQName, true, this);
+            endpointCreated = true;
+        }
+        if (areDynamicPortsShared && endpointCreated) {
+            // If ports are being shared and a new endpoint was created, then it needs to be 
+            // added to the cache.  Note that the other values in the entry (the cache hashmap and
+            // the key) were set when we looked for the entry above.
+            sharedDynamicEndpointEntry.endpointDescription = endpointDescription;
+            cacheSharedDynamicPointEndpoint(sharedDynamicEndpointEntry);
+        }
+        return endpointDescription;
+    }
+    
+    /**
+     * Add the EndpointDescriptionImpl representing the dynamic port to the cache of ports shared across 
+     * services.   
+     * @param sharedDynamicEndpointEntry Contains the EndpointDescriptionImpl instance and the key 
+     *  associated with to be added to the cache, which is also contained in the entry.
+     */
+    private void cacheSharedDynamicPointEndpoint(SharedDynamicEndpointEntry sharedDynamicEndpointEntry) {
+        
+        HashMap cachedDescriptions = sharedDynamicEndpointEntry.cachedDescriptions;
+        String key = sharedDynamicEndpointEntry.key;
+        EndpointDescriptionImpl endpointDescription = sharedDynamicEndpointEntry.endpointDescription;
+        
+        synchronized(cachedDescriptions) {
+            if (log.isDebugEnabled()) {
+                log.debug("Calling cachedDescriptions.put : ("
+                        + key.toString() + ") : size - " + cachedDescriptions.size());
+            }
+            cachedDescriptions.put(key.toString(), new WeakReference(endpointDescription));
+        }
+    }
+    
+    /**
+     * Look for an existing shared endpointDescriptionImpl instance corresponding to a dynamic port based on
+     * a key of(portQname, bindingId, endpointAddress).  Note that sharing dynamic ports across services is
+     * disable by default, and must be enabled via a property.  Dynamic ports, by default, should only be 
+     * visible to the instance of the service that added them.
+     * 
+     * Note that a SharedDynamicEntry will be returned whether or not an existing EndpointDescriptionImpl
+     * is found.  If one is not found, then one needs to be created and then added to the cache.  The information
+     * in the returned SharedDynamicEntry can be used to add it.
+     * 
+     * @see #isShareDynamicPortsAcrossServicesEnabled()
+     * @see #cacheSharedDynamicPointEndpoint(SharedDynamicEndpointEntry)
+     * @see SharedDynamicEndpointEntry
+     * @see #getDynamicEndpointDescriptionImpl(QName, Object)
+     * 
+     * @param portQName
+     * @param bindingId
+     * @param endpointAddress
+     * @return A non-null SharedDynamicEndpointEntry is always returned.  The key and cachedDescriptions
+     * variables will always be set.  If an existing endpoint is found, then endpointDescription will be non-null.
+     */
+    private SharedDynamicEndpointEntry findSharedDynamicEndpoint(QName portQName,
+            String bindingId, String endpointAddress) {
+        
+        SharedDynamicEndpointEntry returnDynamicEntry = new SharedDynamicEndpointEntry();
+        EndpointDescriptionImpl sharedDynamicEndpoint = null;
+        
+        AxisConfiguration configuration = configContext.getAxisConfiguration();
+        if (log.isDebugEnabled()) {
+            log.debug("looking for " + JAXWS_DYNAMIC_ENDPOINTS + " in AxisConfiguration : " + configuration);
+        }
+        Parameter parameter = configuration.getParameter(JAXWS_DYNAMIC_ENDPOINTS);
+        HashMap cachedDescriptions = (HashMap)((parameter == null) ? null : parameter.getValue());
+        if(cachedDescriptions == null) {
+            cachedDescriptions = new HashMap();
+            try {
+                configuration.addParameter(JAXWS_DYNAMIC_ENDPOINTS, cachedDescriptions);
+            } catch (AxisFault axisFault) {
+                throw new RuntimeException(axisFault);
+            }
+            if (log.isDebugEnabled()) {
+                log.debug("Added new instance of cachedDescriptions : " + cachedDescriptions);
+            }
+        } else {
+            if (log.isDebugEnabled()) {
+                log.debug("found old jaxws.dynamic.endpoints cache in AxisConfiguration ("  +  cachedDescriptions + ") with size : ("
+                        + cachedDescriptions.size() + ")");
+            }
+        }
+        
+        StringBuffer key = new StringBuffer();
+        key.append(portQName == null ? "NULL" : portQName.toString());
+        key.append(':');
+        key.append(bindingId == null ? "NULL" : bindingId);
+        key.append(':');
+        key.append(endpointAddress == null ? "NULL" : endpointAddress);
+        synchronized(cachedDescriptions) {
+            WeakReference ref = (WeakReference) cachedDescriptions.get(key.toString());
+            if (ref != null) {
+                sharedDynamicEndpoint = (EndpointDescriptionImpl) ref.get();
+                if (log.isDebugEnabled()) {
+                    log.debug("found old entry for endpointDescription in jaxws.dynamic.endpoints cache : ("
+                            + cachedDescriptions.size() + ")");
+                }
+            }
+        }
+        
+        returnDynamicEntry.cachedDescriptions = cachedDescriptions;
+        returnDynamicEntry.key = key.toString();
+        returnDynamicEntry.endpointDescription = sharedDynamicEndpoint;
+        
+        return returnDynamicEntry;
+    }
+
+    /**
+     * Answer if dynamic ports are to be shared across services.  The default value is FALSE, but it
+     * can be configured by an AxisConfig property.  Note that this can only be set via a config property 
+     * and not via a request context property since the setting affects multiple services.
+     * 
+     * @return true if dynamic ports are to be shared across services, false otherwise.
+     */
+    private boolean isShareDynamicPortsAcrossServicesEnabled() {
+        boolean resolutionEnabled = false;
+
+        // See if an  AxisConfig property enables the sharing of dynamic ports 
+        String flagValue = null;
+        AxisConfiguration axisConfig = getAxisConfigContext().getAxisConfiguration();
+        Parameter parameter = axisConfig.getParameter(MDQConstants.SHARE_DYNAMIC_PORTS_ACROSS_SERVICES);
+        if (parameter != null) {
+            flagValue = (String) parameter.getValue();
+        }
+
+        // If the property was set, check the value.
+        if (flagValue != null) {
+            if ("false".equalsIgnoreCase(flagValue)) {
+                resolutionEnabled = false;
+            } else if ("true".equalsIgnoreCase(flagValue)) {
+                resolutionEnabled = true;
+            }
+        }
+        return resolutionEnabled;
+    }
+
+    /**
+     * This method will get all properties that have been set on the DescriptionBuilderComposite
+     * instance. If the DBC represents an implementation class that references an SEI, the
+     * properties from the SEI will also be merged with the returned result.
+     */
+    private Map<String, Object> getAllProps(DescriptionBuilderComposite dbc, 
+                                            Map<String, DescriptionBuilderComposite> dbcMap) {
+        Map<String, Object> props = new HashMap<String, Object>();
+        
+        // first get the properties from the DBC
+        if(dbc.getProperties() != null
+                &&
+                !dbc.getProperties().isEmpty()) {
+            props.putAll(dbc.getProperties());
+        }
+        
+        // no need to continue if the 'dbcMap' is null
+        if(dbcMap != null) {
+            
+         // now if this is a web service impl with an SEI, get the SEI props
+            if(dbc.getWebServiceAnnot() != null
+                    &&
+                    !DescriptionUtils.isEmpty(dbc.getWebServiceAnnot().endpointInterface())) {
+                DescriptionBuilderComposite seiDBC = dbcMap.get(dbc.getWebServiceAnnot().endpointInterface());
+                if(seiDBC != null
+                        &&
+                        seiDBC.getProperties() != null
+                        &&
+                        !seiDBC.getProperties().isEmpty()) {
+                    props.putAll(seiDBC.getProperties());
+                }
+            }
+        }
+        
+        return props;
+    }
+
+    private Class getEndpointSEI(QName portQName) {
+        Class endpointSEI = null;
+        EndpointDescription endpointDesc = getEndpointDescription(portQName);
+        if (endpointDesc != null) {
+            EndpointInterfaceDescription endpointInterfaceDesc = 
+                endpointDesc.getEndpointInterfaceDescription();
+            if (endpointInterfaceDesc != null ) {
+                endpointSEI = endpointInterfaceDesc.getSEIClass();
+            }
+        }
+        return endpointSEI;
+    }
+
+    private boolean isPortDeclared(QName portQName) {
+        // TODO: This needs to account for declaration of the port via annotations in addition to just WSDL
+        // TODO: Add logic to check the portQN namespace against the WSDL Definition NS
+        boolean portIsDeclared = false;
+        if (!DescriptionUtils.isEmpty(portQName)) {
+            if (getWSDLWrapper() != null) {
+                Definition wsdlDefn = getWSDLWrapper().getDefinition();
+                Service wsdlService = wsdlDefn.getService(serviceQName);
+                Port wsdlPort = wsdlService.getPort(portQName.getLocalPart());
+                portIsDeclared = (wsdlPort != null);
+            } else {
+                // TODO: Add logic to determine if port is declared via annotations when no WSDL is present.  For now, we have to assume it is declared 
+                // so getPort(...) and createDispatch(...) calls work when there is no WSDL.
+                portIsDeclared = true;
+            }
+        } else {
+            // PortQName is null, so the runtime gets to choose which one to use.  Since there's no WSDL
+            // we'll use annotations, so it is implicitly declared
+            portIsDeclared = true;
+        }
+        return portIsDeclared;
+    }
+
+    /* (non-Javadoc)
+    * @see org.apache.axis2.jaxws.description.ServiceDescription#getEndpointDescriptions()
+    */
+    public EndpointDescription[] getEndpointDescriptions() {
+        return definedEndpointDescriptions.values().toArray(new EndpointDescriptionImpl[0]);
+    }
+
+    public Collection<EndpointDescriptionImpl> getDynamicEndpointDescriptions_AsCollection(Object serviceDelegateKey) {
+        Collection <EndpointDescriptionImpl> dynamicEndpoints = null;
+    	if (serviceDelegateKey != null ) {
+    		if (dynamicEndpointDescriptions.get(WeakKey.comparisonKey(serviceDelegateKey)) != null)
+    			dynamicEndpoints = dynamicEndpointDescriptions.get(WeakKey.comparisonKey(serviceDelegateKey)).values();
+        }
+    	return dynamicEndpoints;
+    }
+
+    public Collection<EndpointDescription> getEndpointDescriptions_AsCollection() {
+    	return definedEndpointDescriptions.values();
+    }
+
+    /* (non-Javadoc)
+    * @see org.apache.axis2.jaxws.description.ServiceDescription#getEndpointDescription(javax.xml.namespace.QName)
+    */
+    public EndpointDescription getEndpointDescription(QName portQName) {
+
+    	return getEndpointDescription(portQName, null);
+    }
+
+    public EndpointDescription getEndpointDescription(QName portQName, Object serviceDelegateKey) {
+        EndpointDescription returnDesc = null;
+        if (!DescriptionUtils.isEmpty(portQName)) {
+    		returnDesc = definedEndpointDescriptions.get(portQName);
+
+    		if (returnDesc == null && serviceDelegateKey != null) {
+		           returnDesc = getDynamicEndpointDescriptionImpl(portQName, serviceDelegateKey);
+    		}    		        	
+        }
+        return returnDesc;
+    }
+
+    EndpointDescriptionImpl getEndpointDescriptionImpl(QName portQName) {
+        return (EndpointDescriptionImpl)getEndpointDescription(portQName, null);
+    }
+    
+    EndpointDescriptionImpl getEndpointDescriptionImpl(QName portQName, Object serviceDelegateKey) {
+        return (EndpointDescriptionImpl)getEndpointDescription(portQName);
+    }
+    
+    EndpointDescriptionImpl getEndpointDescriptionImpl(Class seiClass) {
+        for (EndpointDescription endpointDescription : definedEndpointDescriptions.values()) {
+            EndpointInterfaceDescription endpointInterfaceDesc =
+                    endpointDescription.getEndpointInterfaceDescription();
+            // Note that Dispatch endpoints will not have an endpointInterface because the do not have an associated SEI
+            if (endpointInterfaceDesc != null) {
+                Class endpointSEIClass = endpointInterfaceDesc.getSEIClass();
+                if (endpointSEIClass != null && endpointSEIClass.equals(seiClass)) {
+                    return (EndpointDescriptionImpl)endpointDescription;
+                }
+            }
+        }
+        return null;
+    }
+    
+    public DescriptionBuilderComposite getDescriptionBuilderComposite() {
+        return getDescriptionBuilderComposite(null, null);
+    }
+
+    /**
+     * This method provides a means for accessing a DescriptionBuilderComposite instance.
+     * If the integer value passed in is an index in the list of PortComposite objects, 
+     * then the indiciated PortComposite will be returned. Otherwise, the instance DBC
+     * will be returned.
+     */
+    public DescriptionBuilderComposite getDescriptionBuilderComposite(QName serviceQName, 
+                                                                      Integer portCompositeIndex) {
+        
+        DescriptionBuilderComposite dbc = null;
+        
+        // if the service QName was specified let's attempt to get the correct 
+        // PortComposite list
+        if(serviceQName != null
+                &&
+                composite.getServiceQNames() != null
+                &&
+                !composite.getServiceQNames().isEmpty()
+                &&
+                portCompositeIndex != null) {
+            List<PortComposite> pcList = composite.getPortComposites(serviceQName);
+            if(pcList != null) {
+                dbc = pcList.get(portCompositeIndex);
+            }
+            else {
+                dbc = composite;
+            }
+        }
+        
+        // ignore null values or values that would cause an IndexOutOfBoundsException
+        else if(portCompositeIndex == null 
+                || 
+                composite.getPortComposites() == null
+                ||
+                portCompositeIndex < 0
+                ||
+                portCompositeIndex >= composite.getPortComposites().size()) {
+            dbc = composite;  
+        }
+        
+        // return the appropriate PortComposite instance
+        else {
+            if(log.isDebugEnabled()) {
+                log.debug("Returning PortComposite at index: " + portCompositeIndex + 
+                          " from ServiceDescriptionImpl: " + this.hashCode());
+            }
+            dbc = composite.getPortComposites().get(portCompositeIndex);
+        }
+        
+        return dbc;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.axis2.jaxws.description.ServiceDescription#getEndpointDescription(java.lang.Class)
+     */
+    public EndpointDescription[] getEndpointDescription(Class seiClass) {
+        EndpointDescription[] returnEndpointDesc = null;
+        ArrayList<EndpointDescriptionImpl> matchingEndpoints =
+                new ArrayList<EndpointDescriptionImpl>();
+        for (EndpointDescription endpointDescription : definedEndpointDescriptions.values()) {
+            EndpointInterfaceDescription endpointInterfaceDesc =
+                    endpointDescription.getEndpointInterfaceDescription();
+            // Note that Dispatch endpoints will not have an endpointInterface because the do not have an associated SEI
+            if (endpointInterfaceDesc != null) {
+                Class endpointSEIClass = endpointInterfaceDesc.getSEIClass();
+                if (endpointSEIClass != null && endpointSEIClass.equals(seiClass)) {
+                    matchingEndpoints.add((EndpointDescriptionImpl)endpointDescription);
+                }
+            }
+        }
+        if (matchingEndpoints.size() > 0) {
+            returnEndpointDesc = matchingEndpoints.toArray(new EndpointDescriptionImpl[0]);
+        }
+        return returnEndpointDesc;
+    }
+
+    // END of public accessor methods
+    /*=======================================================================*/
+    /*=======================================================================*/
+    private void addEndpointDescription(EndpointDescriptionImpl endpoint) {
+    	definedEndpointDescriptions.put(endpoint.getPortQName(), endpoint);
+    }
+
+    private void setupWsdlDefinition() {
+        // Note that there may be no WSDL provided, for example when called from 
+        // Service.create(QName serviceName).
+
+        if (log.isDebugEnabled()) {
+            log.debug("setupWsdlDefinition()");
+        }
+        
+        if (composite.isServiceProvider()) {
+            
+            //  Currently, there is a bug which allows the wsdlDefinition to be placed
+            //  on either the impl class composite or the sei composite, or both. We need to
+            //  look in both places and find the correct one, if it exists.
+            
+            if(serviceQName != null
+                    &&
+                    composite.getWsdlDefinition(serviceQName) != null) {
+                if(log.isDebugEnabled()) {
+                    log.debug("Found WSDL definition by service QName");
+                }
+                Definition def = composite.getWsdlDefinition(serviceQName);
+                URL url = composite.getWsdlURL(serviceQName);
+                this.wsdlURL = url != null ? url.toString() : null;
+                try {
+                    if (log.isDebugEnabled() ) {
+                        if (configContext != null) {
+                            log.debug("new WSDL4JWrapper-ConfigContext not null1"); 
+                        } else {
+                            log.debug("new WSDL4JWrapper-ConfigContext null1"); 
+                        }
+                    }
+
+                    this.wsdlWrapper = new WSDL4JWrapper(url,
+                                                         def, 
+                                                         configContext,
+                                                         this.catalogManager);
+                } catch (WSDLException e) {
+                    throw ExceptionFactory.makeWebServiceException(
+                            Messages.getMessage("wsdlException", e.getMessage()), e);
+                }
+            }
+
+            else if (((composite.getWebServiceAnnot() != null) &&
+                    DescriptionUtils.isEmpty(composite.getWebServiceAnnot().endpointInterface()))
+                    ||
+                    (!(composite.getWebServiceProviderAnnot() == null))) {
+                //This is either an implicit SEI, or a WebService Provider
+                if (composite.getWsdlDefinition() != null) {
+                    URL url = composite.getWsdlURL();
+                    this.wsdlURL = url == null ? null : url.toString();
+
+                    try {
+                        if (log.isDebugEnabled() ) {
+                            if (configContext != null) {
+                                log.debug("new WSDL4JWrapper-ConfigContext not null1"); 
+                            } else {
+                                log.debug("new WSDL4JWrapper-ConfigContext null1"); 
+                            }
+                        }
+
+                        this.wsdlWrapper = new WSDL4JWrapper(url,
+                                                             composite.getWsdlDefinition(), 
+                                                             configContext,
+                                                             this.catalogManager);
+                    } catch (WSDLException e) {
+                        throw ExceptionFactory.makeWebServiceException(
+                                Messages.getMessage("wsdlException", e.getMessage()), e);
+                    }
+                } else {
+                	String wsdlLocation = null;
+                	wsdlLocation = composite.getWebServiceAnnot() != null ? composite.getWebServiceAnnot().wsdlLocation() :
+                		composite.getWebServiceProviderAnnot().wsdlLocation();
+                	if(wsdlLocation != null
+                			&&
+                			!"".equals(wsdlLocation)) {
+                	    setWSDLDefinitionOnDBC(wsdlLocation);
+                	}
+                }
+
+            } else if (composite.getWebServiceAnnot() != null) {
+                //This impl class specifies an SEI...this is a special case. There is a bug
+                //in the tooling that allows for the wsdllocation to be specifed on either the
+                //impl. class, or the SEI, or both. So, we need to look for the wsdl as follows:
+                //          1. If the Wsdl exists on the SEI, then check for it on the impl.
+                //          2. If it is not found in either location, in that order, then generate
+
+                DescriptionBuilderComposite seic =
+                        getDBCMap().get(composite.getWebServiceAnnot().endpointInterface());
+
+                try {
+                    if (seic == null) {
+                        if (log.isDebugEnabled()) {
+                            log.debug("The SEI class " + composite.getWebServiceAnnot().endpointInterface() + " was not found.");
+                        }
+                    }
+                    if (seic != null && seic.getWsdlDefinition() != null) {
+                        // set the wsdl def from the SEI composite
+                        if (log.isDebugEnabled()) {
+                            log.debug("Get the wsdl definition from the SEI composite.");
+                        }
+                        URL url = seic.getWsdlURL(); 
+                        this.wsdlURL = url.toString();
+                        if (log.isDebugEnabled() ) {
+                            if (configContext != null) {
+                                log.debug("new WSDL4JWrapper-ConfigContext not null2"); 
+                            } else {
+                                log.debug("new WSDL4JWrapper-ConfigContext null2"); 
+                            }
+                        }
+                        this.wsdlWrapper =
+                                new WSDL4JWrapper(seic.getWsdlURL(), 
+                                                  seic.getWsdlDefinition(), 
+                                                  configContext,
+                                                  this.catalogManager);
+                            
+                    } else if (composite.getWsdlDefinition() != null) {
+                        
+                        //set the wsdl def from the impl. class composite
+                        if (log.isDebugEnabled()) {
+                            log.debug("Get the wsdl definition from the impl class composite.");
+                        }
+                        if (log.isDebugEnabled() ) {
+                            if (configContext != null) {
+                                log.debug("new WSDL4JWrapper-ConfigContext not null3"); 
+                            } else {
+                                log.debug("new WSDL4JWrapper-ConfigContext null3"); 
+                            }
+                        }
+                        URL url = composite.getWsdlURL();
+                        this.wsdlURL = url == null ? null : url.toString();
+                        this.wsdlWrapper = new WSDL4JWrapper(composite.getWsdlURL(),
+                                                             composite.getWsdlDefinition(), 
+                                                             configContext,
+                                                             this.catalogManager);
+                                                            
+                    } else {
+                    	String wsdlLocation = null;
+                    	// first check to see if the wsdlLocation is on the SEI
+                    	if(seic != null
+                    			&&
+                    			seic.getWebServiceAnnot() != null) {
+                    	    if (log.isDebugEnabled()) {
+                    	        log.debug("Get the wsdl location from the SEI composite.");
+                    	    }
+                    	    wsdlLocation = seic.getWebServiceAnnot().wsdlLocation();
+                    	}
+                    	                    	
+                    	// now check the impl
+                    	if(wsdlLocation == null
+                    	        ||
+                    	        "".equals(wsdlLocation)) {
+                    	    if (log.isDebugEnabled()) {
+                    	        log.debug("Get the wsdl location from the impl class composite.");
+                            }
+                    	    wsdlLocation = composite.getWebServiceAnnot().wsdlLocation();
+                    	}
+                    	
+                    	if(wsdlLocation != null
+                    	        &&
+                    	        !"".equals(wsdlLocation)) {
+                    	    if (log.isDebugEnabled()) {
+                    	        log.debug("wsdl location =" + wsdlLocation);
+                    	    }
+                    	    
+                    	    this.wsdlURL = wsdlLocation;
+                    	    setWSDLDefinitionOnDBC(wsdlLocation);
+                    	}
+                    }
+                } catch (WSDLException e) {
+                    throw ExceptionFactory.makeWebServiceException(
+                            Messages.getMessage("wsdlException", e.getMessage()), e);
+                }
+            }
+
+            //Deprecate this code block when MDQ is fully integrated
+        } else if (wsdlURL != null) {
+            try {
+                if (log.isDebugEnabled() ) {
+                    if (configContext != null) {
+                        log.debug("new WSDL4JWrapper-ConfigContext not null4"); 
+                    } else {
+                        log.debug("new WSDL4JWrapper-ConfigContext null4"); 
+                    }
+                }
+                this.wsdlWrapper = new WSDL4JWrapper(new URL(this.wsdlURL),configContext,
+                		                             this.catalogManager);
+             
+            }
+            catch (FileNotFoundException e) {
+                throw ExceptionFactory.makeWebServiceException(
+                        Messages.getMessage("wsdlNotFoundErr", e.getMessage()), e);
+            }
+            catch (UnknownHostException e) {
+                throw ExceptionFactory.makeWebServiceException(
+                        Messages.getMessage("unknownHost", e.getMessage()), e);
+            }
+            catch (ConnectException e) {
+                throw ExceptionFactory.makeWebServiceException(
+                        Messages.getMessage("connectionRefused", e.getMessage()), e);
+            }
+            catch(IOException e) {
+                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("urlStream", e.getMessage()), e);
+            }
+            catch (WSDLException e) {
+                throw ExceptionFactory.makeWebServiceException(
+                        Messages.getMessage("wsdlException", e.getMessage()), e);
+            }
+        }
+    }
+    
+    /**
+     * This method accepts a location of a WSDL document and attempts to
+     * load and set the WSDL definition on the DBC object.
+     * @param wsdlLocation
+     */
+    private void setWSDLDefinitionOnDBC(String wsdlLocation) {
+    	if(log.isDebugEnabled()) {
+			log.debug("Attempting to load WSDL file from location specified in annotation: " +
+					wsdlLocation);
+		}
+		if(composite.getClassLoader() == null) {
+			if(log.isDebugEnabled()) {
+				log.debug("A classloader could not be found for class: " + composite.
+						getClassName() + ". The WSDL file: " + wsdlLocation + " will not be " +
+								"processed, and the ServiceDescription will be built from " +
+								"annotations");
+			}
+		}
+		try {
+		    if(log.isDebugEnabled()) {
+		        log.debug("Attempting to read WSDL: " + wsdlLocation + " for web " +
+		        		"service endpoint: " + composite.getClassName());
+		    }
+                    if (log.isDebugEnabled() ) {
+                        if (configContext != null) {
+                            log.debug("new WSDL4JWrapper-ConfigContext not null5");
+                        } else {
+                            log.debug("new WSDL4JWrapper-ConfigContext null5");
+                        }
+                    }
+
+                    URL url = getWSDLURL(wsdlLocation);
+                    ConfigurationContext cc = composite.getConfigurationContext();
+                    if (cc != null) {
+                        this.wsdlWrapper = new WSDL4JWrapper(url, cc, this.catalogManager);
+                    } else {
+                        // Probably shouldn't get here.  But if we do, use a memory sensitive
+                        // wsdl wrapper
+                        this.wsdlWrapper = new WSDL4JWrapper(url, this.catalogManager, true, 2);
+                    }
+                    composite.setWsdlDefinition(wsdlWrapper.getDefinition());
+		}
+		catch(Exception e) {
+			if(log.isDebugEnabled()) {
+				log.debug("The WSDL file: " + wsdlLocation + " for class: " + composite.getClassName() + 
+						"could not be processed. The ServiceDescription will be built from " +
+								"annotations");
+			}
+		}
+    }
+    
+    /**
+     * This method will handle obtaining a URL for the given WSDL location.  The WSDL will be
+     * looked for in the following places in this order:
+     * 
+     * PreResolution) check for xmlcatalog resolver
+     * 1) As a resource on the classpath
+     * 2) As a fully specified URL
+     * 3) As a file on the filesystem.  This is analagous to what the generated
+     *    Service client does.  Is prepends "file:/" to whatever is specified in the
+     *    @WebServiceClient.wsdlLocation element.
+     * 
+     * @param wsdlLocation The WSDL for which a URL is wanted
+     * @return A URL if the WSDL can be located, or null
+     */
+    private URL getWSDLURL(String wsdlLocation) {
+        // Look for the WSDL file as follows:
+        // PreResolution) check for xmlcatalog resolver
+        wsdlLocation = resolveWSDLLocationByCatalog(wsdlLocation);
+        
+        
+        // 1) As a resource on the classpath
+
+        ClassLoader loader = composite.getClassLoader();
+        URL url = null;
+        if (loader != null) {
+            url = getResource(wsdlLocation, loader); 
+        }
+        
+        // Try the context class loader
+        if(url == null){
+            ClassLoader classLoader = getContextClassLoader(null);
+            if(classLoader != loader){
+                url = getResource(wsdlLocation, classLoader);
+            }
+        }
+
+        // 2) As a fully specified URL
+        if (url == null) {
+            if (log.isDebugEnabled()) {
+                log.debug("URL for wsdl file: " + wsdlLocation + " could not be "
+                        + "determined by classloader... looking for file reference");
+            }
+            url = createWsdlURL(wsdlLocation);
+        }
+        // 3) As a file on the filesystem.  This is analagous to what the generated
+        //    Service client does.  Is prepends "file:/" to whatever is specified in the
+        //    @WebServiceClient.wsdlLocation element.
+        if (url == null) {
+            if (log.isDebugEnabled()) {
+                log.debug("URL for wsdl file: " + wsdlLocation + " could not be "
+                        + "found as local file reference... prepending file: protocol");
+            }
+            // This check is necessary because Unix/Linux file paths begin
+            // with a '/'. When adding the prefix 'jar:file:/' we may end
+            // up with '//' after the 'file:' part. This causes the URL 
+            // object to treat this like a remote resource
+            if(wsdlLocation.indexOf("/") == 0) {
+                wsdlLocation = wsdlLocation.substring(1, wsdlLocation.length());
+            }
+            url = createWsdlURL("file:/" + wsdlLocation);
+
+        }
+        if (url == null) {
+            if (log.isDebugEnabled()) {
+                log.debug("Unable to obtain URL for WSDL file: " + wsdlLocation
+                        + " by using prepended file: protocol");
+            }
+        }
+        return url;
+    }
+
+    private URL getResource(final String wsdlLocation, final ClassLoader loader) {
+        return (URL) AccessController.doPrivileged(
+                new PrivilegedAction() {
+                    public Object run() {
+                        return loader.getResource(wsdlLocation);
+                    }
+                }
+        );
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.axis2.jaxws.description.ServiceDescriptionWSDL#getWSDLWrapper()
+     */
+    public WSDLWrapper getWSDLWrapper() {
+        return wsdlWrapper;
+    }
+
+    /* (non-Javadoc)
+    * @see org.apache.axis2.jaxws.description.ServiceDescriptionWSDL#getWSDLLocation()
+    */
+    public String getWSDLLocation() {
+        return wsdlURL;
+    }
+
+    public WSDLWrapper getGeneratedWsdlWrapper() {
+        return this.generatedWsdlWrapper;
+    }
+
+    void setAxisConfigContext(ConfigurationContext config) {
+        this.configContext = config;
+    }
+    
+    /* (non-Javadoc)
+    * @see org.apache.axis2.jaxws.description.ServiceDescription#getAxisConfigContext()
+    */
+    public ConfigurationContext getAxisConfigContext() {
+        if (configContext == null) {
+            configContext = getClientConfigurationFactory().getClientConfigurationContext();
+        }
+        return configContext;
+
+    }
+
+    ClientConfigurationFactory getClientConfigurationFactory() {
+
+        if (clientConfigFactory == null) {
+            clientConfigFactory = DescriptionFactory.createClientConfigurationFactory();
+        }
+        return clientConfigFactory;
+    }
+
+    /* (non-Javadoc)
+    * @see org.apache.axis2.jaxws.description.ServiceDescription#getServiceClient(javax.xml.namespace.QName)
+    */
+    public ServiceClient getServiceClient(QName portQName, Object serviceDelegateKey) {
+        ServiceClient returnServiceClient = null;
+        if (!DescriptionUtils.isEmpty(portQName)) {
+            EndpointDescription endpointDesc = getEndpointDescription(portQName, serviceDelegateKey);
+            
+            if (endpointDesc != null) {
+                returnServiceClient = endpointDesc.getServiceClient();
+            }
+            else {
+                // Couldn't find Endpoint Description for port QName
+                if (log.isDebugEnabled()) {
+                    log.debug("Could not find portQName: " + portQName 
+                            + " under ServiceDescription: " + toString());
+                }
+            }
+        }
+        else {
+            // PortQName is empty
+            if (log.isDebugEnabled()) {
+                log.debug("PortQName agrument is invalid; it can not be null or an empty string: " + portQName);
+            }
+        }
+        
+        return returnServiceClient;
+    }
+
+    /* (non-Javadoc)
+    * @see org.apache.axis2.jaxws.description.ServiceDescription#getServiceQName()
+    */
+    public QName getServiceQName() {
+        //It is assumed that this will always be set in the constructor rather than
+        //built up from the class or DBC
+        return serviceQName;
+    }
+
+    void setServiceQName(QName theName) {
+        if (log.isDebugEnabled()) {
+            log.debug("Set serviceQName to " + serviceQName);
+        }
+        serviceQName = theName;
+    }
+    
+    public JAXWSCatalogManager getCatalogManager() {
+    	return catalogManager;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.axis2.jaxws.description.ServiceDescription#isMTOMEnabled(java.lang.Object)
+     */
+    public boolean isMTOMEnabled(Object key) {
+        return getDescriptionBuilderComposite().isMTOMEnabled(key);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.axis2.jaxws.description.ServiceDescription#isMTOMEnabled(java.lang.Object, Class seiClass)
+     */
+    public boolean isMTOMEnabled(Object key, Class seiClass) {
+        if(log.isDebugEnabled()) {
+            log.debug("isMTOMEnabled, key= " + key + ", seiClass= " + seiClass);
+        }
+        
+        boolean mtomEnabled = false;
+        boolean checkOldEnablementMethod = true;
+        
+        /*
+         * This is the NEW way of setting MTOM enabled using a property on the DBC that contains the 
+         * WebServiceFeatures for the ports on that service.  One of those features indicats if MTOM should
+         * be enabled
+         */
+        List<Annotation> seiFeatureList = getSEIFeatureList(key, seiClass);
+        if (seiFeatureList != null) {
+            for (int i = 0; i < seiFeatureList.size(); i++) {
+                Annotation checkAnnotation = seiFeatureList.get(i);
+                if (checkAnnotation instanceof MTOMAnnot) {
+                    MTOMAnnot mtomAnnot = (MTOMAnnot) checkAnnotation;
+                    mtomEnabled = mtomAnnot.enabled();
+                    // We found an explicit setting for this port, so do not check the old way of enabling MTOM
+                    checkOldEnablementMethod = false;
+                }
+            }
+        }
+        
+        /*
+         * This is the OLD way of setting MTOM enabled and it is deprecated.  Within the OLD way, there are
+         * two ways to enable MTOM:
+         * 1) By setting isMTOMEnabled to true on a single DBC which represents a Service.  This enables MTOM
+         *    on all the ports under it.
+         * 2) By setting the property SEI_MTOM_ENABLEMENT_MAP to a list of ports keyed by SEI name with a
+         *    Boolean value indicating if MTOM should be enabled for that port.
+         */
+        if (checkOldEnablementMethod) {
+            DescriptionBuilderComposite sparseComposite = getDescriptionBuilderComposite().getSparseComposite(key);
+            if(sparseComposite != null
+                    &&
+                    seiClass != null) {
+                Map<String, Boolean> seiToMTOM = (Map<String, Boolean>) 
+                    sparseComposite.getProperties().get(MDQConstants.SEI_MTOM_ENABLEMENT_MAP);
+                if(seiToMTOM != null
+                        &&
+                        seiToMTOM.get(seiClass.getName()) != null) {
+                    mtomEnabled = seiToMTOM.get(seiClass.getName());
+                }
+                else {
+                    mtomEnabled = isMTOMEnabled(key);
+                }
+            }
+            else {
+                mtomEnabled = isMTOMEnabled(key);
+            }
+        }
+        
+        if(log.isDebugEnabled()) {
+            log.debug("isMTOMEnabled, key= " + key + ", seiClass= " + seiClass + ", isMTOMEnabled= " + mtomEnabled);
+        }
+        
+        return mtomEnabled;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.axis2.jaxws.description.ServiceDescription#getBindingProperites(java.lang.Object, String key)
+     */
+    public Map<String, Object> getBindingProperties(Object serviceDelegateKey, String key) {
+        if(log.isDebugEnabled()) {
+            log.debug("getBindingProperties, serviceDelegateKey= " + serviceDelegateKey + 
+                      ", key= " + key);
+        }
+
+        Map<String, Object> bindingProps = null;
+        DescriptionBuilderComposite sparseComposite = getDescriptionBuilderComposite().getSparseComposite(serviceDelegateKey);
+        if(sparseComposite != null) {
+            Map<String, Map<String, Object>> allBindingProps = (Map<String, Map<String, Object>>) 
+                sparseComposite.getProperties().get(MDQConstants.BINDING_PROPS_MAP);
+            bindingProps = allBindingProps != null ? (Map<String, Object>) allBindingProps.get(key) : null;
+        }
+
+        if(log.isDebugEnabled()) {
+            log.debug("getBindingProperties, serviceDelegateKey= " + serviceDelegateKey + 
+                      ", key= " + key + ", propsSize= " + (bindingProps != null ? bindingProps.size() : 0));
+        }    
+
+        return bindingProps;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.axis2.jaxws.description.ServiceDescription#getPreferredPort(java.lang.Object)
+     */
+    public QName getPreferredPort(Object key) {
+        return getDescriptionBuilderComposite().getPreferredPort(key);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.axis2.jaxws.description.ServiceDescription#isServerSide()
+     */
+    public boolean isServerSide() {
+        return isServerSide;
+    }
+
+    public HashMap<String, DescriptionBuilderComposite> getDBCMap() {
+        return dbcMap;
+    }
+
+    void setGeneratedWsdlWrapper(WSDL4JWrapper wrapper) {
+        this.generatedWsdlWrapper = wrapper;
+    }
+
+    void setWsdlWrapper(WSDL4JWrapper wrapper) {
+        this.wsdlWrapper = wrapper;
+    }
+
+    private void validateDBCLIntegrity() {
+
+        //First, check the integrity of this input composite
+        //and retrieve
+        //the composite that represents this impl
+
+        try {
+            validateIntegrity();
+        }
+        catch (Exception ex) {
+            throw ExceptionFactory.makeWebServiceException(
+            		Messages.getMessage("dbclIntegrityErr",ex.toString(),
+            		        DescriptionUtils.dumpString(composite)), ex);
+        }
+    }
+
+    /*
+      * Validates the integrity of an impl. class. This should not be called directly for an SEI composite
+      */
+    void validateIntegrity() {
+        //In General, this integrity checker should do gross level checking
+        //It should not be setting spec-defined default values, but can look
+        //at things like empty strings or null values
+
+        //Verify that, if this implements a strongly typed provider interface, that it
+        // also contain a WebServiceProvider annotation per JAXWS Sec. 5.1
+        Iterator<String> iter =
+                composite.getInterfacesList().iterator();
+
+        // Remember if we've validated the Provider interface.  Later we'll make sure that if we have an 
+        // WebServiceProvider annotation, we found a valid interface here.
+        boolean providerInterfaceValid = false;
+        while (iter.hasNext()) {
+            String interfaceString = iter.next();
+            if (interfaceString.equals(MDQConstants.PROVIDER_SOURCE)
+                    || interfaceString.equals(MDQConstants.PROVIDER_SOAP)
+                    || interfaceString.equals(MDQConstants.PROVIDER_DATASOURCE)
+                    || interfaceString.equals(MDQConstants.PROVIDER_STRING)
+                    || interfaceString.equals(MDQConstants.PROVIDER_OMELEMENT)) {
+                providerInterfaceValid = true;
+                //This is a provider based endpoint, make sure the annotation exists
+                if (composite.getWebServiceProviderAnnot() == null) {
+                    throw ExceptionFactory.makeWebServiceException(
+                    		Messages.getMessage("validateIntegrityErr1",composite.getClassName()));
+                }
+            }
+        }
+
+        //Verify that WebService and WebServiceProvider are not both specified
+        //per JAXWS - Sec. 7.7
+        if (composite.getWebServiceAnnot() != null &&
+                composite.getWebServiceProviderAnnot() != null) {
+            throw ExceptionFactory.makeWebServiceException(
+            		Messages.getMessage("validateIntegrityErr2",composite.getClassName()));
+        }
+
+        if (composite.getWebServiceProviderAnnot() != null) {
+            if (!providerInterfaceValid) {
+                throw ExceptionFactory.makeWebServiceException(
+                		Messages.getMessage("validateIntegrityErr3",composite.getClassName()));
+            }
+            // There must be a public default constructor per JAXWS - Sec 5.1
+            if (!validateDefaultConstructor()) {
+                throw ExceptionFactory.makeWebServiceException(
+                		Messages.getMessage("validateIntegrityErr4",composite.getClassName()));
+            }
+            // There must be an invoke method per JAXWS - Sec 5.1.1
+            if (!validateInvokeMethod()) {
+                throw ExceptionFactory.makeWebServiceException(
+                		Messages.getMessage("validateIntegrityErr5",composite.getClassName()));
+            }
+
+            //If ServiceMode annotation specifies 'payload', then make sure that it is not typed with
+            // SOAPMessage or DataSource
+            validateProviderInterfaces();
+
+        } else if (composite.getWebServiceAnnot() != null) {
+
+            if (composite.getServiceModeAnnot() != null) {
+                throw ExceptionFactory.makeWebServiceException(
+                		Messages.getMessage("validateIntegrityErr6",composite.getClassName()));
+            }
+
+            if (!composite.isInterface()) {
+                // TODO: Validate on the class that this.classModifiers Array does not contain the strings
+                //        FINAL or ABSTRACT, but does contain PUBLIC
+                // TODO: Validate on the class that a public constructor exists
+                // TODO: Validate on the class that a finalize() method does not exist
+                if (!DescriptionUtils.isEmpty(composite.getWebServiceAnnot().wsdlLocation())) {
+                    if (composite.getWsdlDefinition(getServiceQName()) == null
+                            &&
+                            composite.getWsdlDefinition() == null 
+                            &&
+                            composite.getWsdlURL() == null) {
+                        throw ExceptionFactory.makeWebServiceException(
+                        		Messages.getMessage("validateIntegrityErr7",composite.getClassName(),
+                        				composite.getWebServiceAnnot().wsdlLocation()));
+                    }
+                }
+
+                //		setWebServiceAnnotDefaults(true=impl); Must happen before we start checking annot
+                if (!DescriptionUtils.isEmpty(composite.getWebServiceAnnot().endpointInterface())) {
+
+                    DescriptionBuilderComposite seic =
+                            dbcMap.get(composite.getWebServiceAnnot().endpointInterface());
+
+                    //Verify that we can find the SEI in the composite list
+                    if (seic == null) {
+                        throw ExceptionFactory.makeWebServiceException(
+                        		Messages.getMessage("validateIntegrityErr8",composite.getClassName(),
+                        				composite.getWebServiceAnnot().endpointInterface()));
+                    }
+
+                    // Verify that the only class annotations are WebService and HandlerChain
+                    // (per JSR181 Sec. 3.1).  Note that this applies to JSR-181 annotations; the restriction
+                    // does not apply to JSR-224 annotations such as BindingType
+                    if (composite.getSoapBindingAnnot() != null
+                            || composite.getWebFaultAnnot() != null
+                            || composite.getWebServiceClientAnnot() != null
+                            ) {
+                        throw ExceptionFactory.makeWebServiceException(
+                        		Messages.getMessage("validateIntegrityErr9",composite.getClassName()));
+                    }
+
+                    //Verify that WebService annotation does not contain a name attribute
+                    //(per JSR181 Sec. 3.1)
+                    if (!DescriptionUtils.isEmpty(composite.getWebServiceAnnot().name())) {
+                        throw ExceptionFactory.makeWebServiceException(
+                        		Messages.getMessage("validateIntegrityErr10",composite.getClassName(),
+                        				composite.getWebServiceAnnot().name()));
+                    }
+
+                    validateSEI(seic);
+                    //Verify that that this implementation class implements all methods in the interface
+                    validateImplementation(seic);
+
+                    //Verify that this impl. class does not contain any @WebMethod annotations
+                    if (webMethodAnnotationsExist()) {
+                        throw ExceptionFactory.makeWebServiceException(
+                        		Messages.getMessage("validateIntegrityErr11",composite.getClassName()));
+                    }
+
+
+                } else { //this is an implicit SEI (i.e. impl w/out endpointInterface
+
+                    
+                    checkImplicitSEIAgainstWSDL();
+                    //	TODO:	Call ValidateWebMethodAnnots()
+                    //			- this method will check that all methods are public - ???
+                    //
+                }
+            } else { //this is an interface...we should not be processing interfaces here
+                throw ExceptionFactory.makeWebServiceException(
+                		Messages.getMessage("validateIntegrityErr12",composite.getClassName()));
+            }
+
+            // Verify that the SOAPBinding annotations are supported.
+            if (composite.getSoapBindingAnnot() != null) {
+                if (composite.getSoapBindingAnnot().use() == javax.jws.soap.SOAPBinding.Use.ENCODED) {
+                    throw ExceptionFactory.makeWebServiceException(
+                    		Messages.getMessage("validateIntegrityErr13",composite.getClassName()));  
+                }
+            }
+            
+            checkMethodsAgainstWSDL();
+        }
+    }
+
+    /**
+     * Validate there is an invoke method on the composite.
+     *
+     * @return
+     */
+    private boolean validateInvokeMethod() {
+        boolean validInvokeMethod = false;
+        List<MethodDescriptionComposite> invokeMethodList =
+                composite.getMethodDescriptionComposite("invoke");
+        if (invokeMethodList != null && !invokeMethodList.isEmpty()) {
+            validInvokeMethod = true;
+        }
+        return validInvokeMethod;
+    }
+
+    /**
+     * Validate that, if using PAYLOAD mode, then interfaces list cannot contain SOAPMessage or
+     * DataSource
+     *
+     * @return
+     */
+    private void validateProviderInterfaces() {
+
+        // Default for ServiceMode is 'PAYLOAD'. So, if it is specified  (explicitly or
+        // implicitly) then verify that we are not implementing improper interfaces)
+        if ((composite.getServiceModeAnnot() == null)
+                || composite.getServiceModeAnnot().value() == javax.xml.ws.Service.Mode.PAYLOAD) {
+
+            Iterator<String> iter = composite.getInterfacesList().iterator();
+
+            while (iter.hasNext()) {
+                String interfaceString = iter.next();
+                if (interfaceString.equals(MDQConstants.PROVIDER_SOAP)
+                        || interfaceString.equals(MDQConstants.PROVIDER_DATASOURCE)) {
+                	
+                    throw ExceptionFactory.makeWebServiceException(
+                    		Messages.getMessage("validatePIsErr1",composite.getClassName()));
+                }
+            }
+
+        } else {
+            // We are in MESSAGE mode
+            // Conformance: JAXWS Spec.- Sec. 4.3 (javax.activation.DataSource)
+
+            // REVIEW: Should the provider interface validation be moved to post-construction validation, 
+            // since it seems that the logic to understand the default values for binding type 
+            // (see comment below) should be left to the creation of the Description objects.
+            String bindingType = null;
+            if (composite.getBindingTypeAnnot() != null) {
+                bindingType = composite.getBindingTypeAnnot().value();
+            }
+
+            Iterator<String> iter = composite.getInterfacesList().iterator();
+
+            while (iter.hasNext()) {
+                String interfaceString = iter.next();
+
+                if (interfaceString.equals(MDQConstants.PROVIDER_SOAP)) {
+
+                    // Make sure BindingType is SOAP/HTTP with SOAPMessage
+					// object, Default for Binding Type is SOAP/HTTP
+					if (!DescriptionUtils.isEmpty(bindingType)
+							&& !bindingType
+									.equals(SOAPBinding.SOAP11HTTP_BINDING)
+							&& !bindingType
+									.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
+							&& !bindingType
+									.equals(SOAPBinding.SOAP12HTTP_BINDING)
+							&& !bindingType
+									.equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING)
+							&& !bindingType
+									.equals(MDQConstants.SOAP11JMS_BINDING)
+							&& !bindingType
+									.equals(MDQConstants.SOAP11JMS_MTOM_BINDING)
+							&& !bindingType
+									.equals(MDQConstants.SOAP12JMS_BINDING)
+							&& !bindingType
+									.equals(MDQConstants.SOAP12JMS_MTOM_BINDING)
+							&& !bindingType
+							        .equals(MDQConstants.SOAP_HTTP_BINDING))
+
+						throw ExceptionFactory.makeWebServiceException(Messages
+								.getMessage("validatePIsErr2", composite
+										.getClassName()));
+                
+                
+                
+                } else if (interfaceString
+                        .equals(MDQConstants.PROVIDER_DATASOURCE)) {
+
+                    // Make sure BindingType is XML/HTTP with DataSource object
+                    if (DescriptionUtils.isEmpty(bindingType)
+                            || !bindingType
+                            .equals(javax.xml.ws.http.HTTPBinding.HTTP_BINDING))
+                    	
+                        throw ExceptionFactory.makeWebServiceException(
+                        		Messages.getMessage("validatePIsErr3",composite.getClassName()));
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Validate there is a default no-argument constructor on the composite.
+     *
+     * @return
+     */
+    private boolean validateDefaultConstructor() {
+        boolean validDefaultCtor = false;
+        List<MethodDescriptionComposite> constructorList =
+                composite.getMethodDescriptionComposite("<init>");
+        if (constructorList != null && !constructorList.isEmpty()) {
+            // There are public constructors; make sure there is one that takes no arguments.
+            for (MethodDescriptionComposite checkCtor : constructorList) {
+                List<ParameterDescriptionComposite> paramList =
+                        checkCtor.getParameterDescriptionCompositeList();
+                if (paramList == null || paramList.isEmpty()) {

[... 1330 lines stripped ...]


Mime
View raw message