All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.axis2.jaxws.description.impl.EndpointDescriptionImpl Maven / Gradle / Ivy

There is a newer version: 1.8.2
Show newest version
/*
 * 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.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.Constants.Configuration;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.deployment.util.Utils;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.AxisEndpoint;
import org.apache.axis2.description.AxisServiceGroup;
import org.apache.axis2.description.OutInAxisOperation;
import org.apache.axis2.description.OutOnlyAxisOperation;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.description.WSDL11ToAllAxisServicesBuilder;
import org.apache.axis2.description.WSDL11ToAxisServiceBuilder;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.java.security.AccessController;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.catalog.JAXWSCatalogManager;
import org.apache.axis2.jaxws.common.config.WSDLValidatorElement;
import org.apache.axis2.jaxws.description.EndpointDescription;
import org.apache.axis2.jaxws.description.EndpointDescriptionJava;
import org.apache.axis2.jaxws.description.EndpointDescriptionWSDL;
import org.apache.axis2.jaxws.description.EndpointInterfaceDescription;
import org.apache.axis2.jaxws.description.ServiceDescription;
import org.apache.axis2.jaxws.description.ServiceDescriptionWSDL;
import org.apache.axis2.jaxws.description.builder.CustomAnnotationInstance;
import org.apache.axis2.jaxws.description.builder.CustomAnnotationProcessor;
import org.apache.axis2.jaxws.description.builder.DescriptionBuilderComposite;
import org.apache.axis2.jaxws.description.builder.MDQConstants;
import org.apache.axis2.jaxws.description.builder.WsdlComposite;
import org.apache.axis2.jaxws.description.builder.JAXWSRIWSDLGenerator;
import org.apache.axis2.jaxws.description.xml.handler.HandlerChainsType;
import org.apache.axis2.jaxws.feature.ServerConfigurator;
import org.apache.axis2.jaxws.feature.ServerFramework;
import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.axis2.jaxws.registry.ServerConfiguratorRegistry;
import org.apache.axis2.jaxws.util.CatalogURIResolver;
import org.apache.axis2.jaxws.util.WSDL4JWrapper;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.axis2.wsdl.util.WSDLDefinitionWrapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.jws.HandlerChain;
import javax.jws.WebService;
import javax.wsdl.Binding;
import javax.wsdl.Definition;
import javax.wsdl.Port;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.http.HTTPBinding;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.wsdl.extensions.soap12.SOAP12Address;
import javax.wsdl.extensions.soap12.SOAP12Binding;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingType;
import javax.xml.ws.Service;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.handler.PortInfo;
import javax.xml.ws.soap.MTOM;
import javax.xml.ws.soap.MTOMFeature;
import javax.xml.ws.soap.SOAPBinding;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

/** @see ../EndpointDescription */
/*
 * IMPORTANT NOTE: Axis2 currently only supports 1 service and 1 port under that service.  When that is
 * fixed, that will probably have an impact on this class.  In particular, I think this should be created 
 * somehow from an AxisService/AxisPort combination, and not directly from the WSDL.
 */
public class EndpointDescriptionImpl
        implements EndpointDescription, EndpointDescriptionJava, EndpointDescriptionWSDL {

    private ServiceDescriptionImpl parentServiceDescription;
    private AxisService axisService;
    private AxisConfiguration axisConfig;
    // In some environments some of the resources on an AxisService can lead to OOMs.
    // However, releasing these resources can have other implications.  
    private boolean releaseAxisServiceResources = false;

    private QName portQName;
    private QName serviceQName;

    // Corresponds to a port that was added dynamically via addPort and is not declared (either in WSDL or annotations)
    private boolean isDynamicPort;

    // If the WSDL is fully specified, we could build the AxisService from the WSDL
    private boolean isAxisServiceBuiltFromWSDL;

    private String serviceImplName;    //class name of the service impl or SEI

    // Note that an EndpointInterfaceDescription will ONLY be set for an Endpoint-based implementation;
    // it will NOT be set for a Provider-based implementation
    private EndpointInterfaceDescription endpointInterfaceDescription;

    //On Client side, there should be One ServiceClient instance per AxisSerivce
    private ServiceClient serviceClient = null;

    //This is the base WebService or WebServiceProvider that we are processing
    DescriptionBuilderComposite composite = null;

    // Set of packages that are needed to marshal/unmashal data (used to set JAXBContext)
    TreeSet packages = null;

    // The JAX-WS Handler port information corresponding to this endpoint
    private PortInfo portInfo;

    private String clientBindingID;
    // The effective endpoint address.  It could be set by the client or come from the WSDL SOAP address
    private String endpointAddress;
    // The endpoint address from the WSDL soap:address extensibility element if present.
    private String wsdlSOAPAddress;

    private static final Log log = LogFactory.getLog(EndpointDescriptionImpl.class);

    // ===========================================
    // ANNOTATION related information
    // ===========================================

    // ANNOTATION: @WebService and @WebServiceProvider
    // Only one of these two annotations will be set; they are mutually exclusive
    private WebService webServiceAnnotation;
    private WebServiceProvider webServiceProviderAnnotation;

    //ANNOTATION: @HandlerChain
    private HandlerChain handlerChainAnnotation;
    private HandlerChainsType handlerChainsType;

    // Information common to both WebService and WebServiceProvider annotations
    private String annotation_WsdlLocation;
    private String annotation_ServiceName;
    private String annotation_PortName;
    private String annotation_TargetNamespace;

    // Information only set on WebService annotation
    // ANNOTATION: @WebService
    private String webService_EndpointInterface;
    private String webService_Name;

    // ANNOTATION: @ServiceMode
    // Note this is only valid on a Provider-based endpoint
    private ServiceMode serviceModeAnnotation;
    private Service.Mode serviceModeValue;
    // Default ServiceMode.value per JAXWS Spec 7.1 "javax.xml.ServiceMode" pg 79
    public static final javax.xml.ws.Service.Mode ServiceMode_DEFAULT =
            javax.xml.ws.Service.Mode.PAYLOAD;

    // ANNOTATION: @BindingType
    private BindingType bindingTypeAnnotation;
    private String bindingTypeValue;
    // Default BindingType.value per JAXWS Spec Sec 7.8 "javax.xml.ws.BindingType" pg 83 
    // and Sec 1.4 "SOAP Transport and Transfer Bindings" pg 119
    public static final String BindingType_DEFAULT =
            javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING;
    
    // ANNOTATION: @RespectBinding
    private Boolean respectBinding = false;
    private Set requiredBindings = new HashSet();
    
    private Integer portCompositeIndex = null;
    
    private List customAnnotations;
    
    private Map customAnnotationProcessors;

    // Supports WebServiceFeatureAnnotations
    private ServerFramework framework = new ServerFramework();
    
    private Map properties;
    
    // Remembers if this endpoint description is MTOMEnabled
    private Boolean isMTOMEnabledCache = null;

    
    /**
     * Create a service-requester side EndpointDescription based on the WSDL port.  
     * Note that per the JAX-WS Spec (Final
     * Release, 4/19/2006 Section 4.2.3 Proxies, page 55)the "namespace component of the port is the
     * target namespace of the WSDL definition document". Note this is currently only used on the
     * client-side (this may change).
     *
     * @param theClass The SEI or Impl class.  This will be NULL for Dispatch clients since they
     *                 don't use an SEI
     */
    EndpointDescriptionImpl(Class theClass, QName portName, ServiceDescriptionImpl parent) {
        this(theClass, portName, parent, null, null);
    }
    EndpointDescriptionImpl(Class theClass, QName portName, ServiceDescriptionImpl parent, 
                            DescriptionBuilderComposite dbc, Object compositeKey ) {
        this(theClass, portName, false, parent, dbc, compositeKey);
    }
    EndpointDescriptionImpl(Class theClass, QName portName, boolean dynamicPort,
                            ServiceDescriptionImpl parent) {
        this(theClass, portName, dynamicPort, parent, null, null);
    }
    EndpointDescriptionImpl(Class theClass, QName portName, boolean dynamicPort,
                            ServiceDescriptionImpl parent, 
                            DescriptionBuilderComposite sparseComposite,
                            Object sparseCompositeKey) {
        
        if (log.isDebugEnabled()) {
            log.debug("entry ");
            log.debug("  theClass=" + theClass);
            log.debug("  portName= " + portName);
            log.debug("  dynamicPort= " + dynamicPort);
            log.debug("  parent=" + parent);
            log.debug("  sparseComposite=" + DescriptionUtils.dumpString(sparseComposite));
        }

        this.axisConfig = parent.getAxisConfigContext().getAxisConfiguration();

        this.parentServiceDescription = parent;
        composite = new DescriptionBuilderComposite();
        composite.setSparseComposite(sparseCompositeKey, sparseComposite);
        composite.setCorrespondingClass(theClass);
        ClassLoader loader = (ClassLoader) AccessController.doPrivileged(
                new PrivilegedAction() {
                    public Object run() {
                        return this.getClass().getClassLoader();
                    }
                }
        );
        composite.setClassLoader(loader);
        composite.setIsServiceProvider(false);

        webServiceAnnotation = composite.getWebServiceAnnot();
        
        this.isDynamicPort = dynamicPort;
        if (DescriptionUtils.isEmpty(portName)) {
            // If the port name is null, then per JAX-WS 2.0 spec p. 55, the runtime is responsible for selecting the port.
            this.portQName = selectPortToUse();
        } else {
            this.portQName = portName;
        }
        // At this point, there must be a port QName set, either as passed in, or determined from the WSDL and/or annotations.
        // If not, that is an error.
        if (this.portQName == null) {
            String msg = Messages.getMessage("endpointDescriptionErr1",theClass.getName(),parent.getClass().getName());
            throw ExceptionFactory.makeWebServiceException(msg);
        }

        setupAxisService(sparseCompositeKey);
        addToAxisService();
        setupReleaseResources(getServiceDescription().getAxisConfigContext());

        buildDescriptionHierachy();
        addAnonymousAxisOperations();

        // This will set the serviceClient field after adding the AxisService to the AxisConfig
        getServiceClient();
        // Give the configuration builder a chance to finalize configuration for this service
        try {
            getServiceDescriptionImpl().getClientConfigurationFactory()
                    .completeAxis2Configuration(axisService);
        } catch (Exception e) {
            String msg = Messages.getMessage("endpointDescriptionErr2",e.getClass().getName(),parent.getClass().getName());
            throw ExceptionFactory.makeWebServiceException(msg, e);
        } finally {
            releaseAxisServiceResources();
        }
        if (log.isDebugEnabled()) {
            log.debug("exit");
        }
    }
    
    private void setupReleaseResources(ConfigurationContext configurationContext) {
        if (configurationContext != null) {
            AxisConfiguration axisConfiguration = configurationContext.getAxisConfiguration();
            if (axisConfiguration != null) {
                Parameter param = 
                    axisConfiguration.getParameter(Constants.Configuration.REDUCE_WSDL_MEMORY_CACHE);
                if (param != null) {
                    releaseAxisServiceResources = ((String) param.getValue()).equalsIgnoreCase("true");
                    if (log.isDebugEnabled()) {
                        log.debug("EndpointDescription configured to release AxisService resources via "
                                  + Constants.Configuration.REDUCE_WSDL_MEMORY_CACHE);
                    }
                }
            }
        }
        else if(composite != null) {
            Boolean reduceCache = (Boolean) composite.getProperties().get(Constants.Configuration.REDUCE_WSDL_MEMORY_CACHE);
            if(reduceCache != null) {
                if(log.isDebugEnabled()) {
                    log.debug("Retrieved the following reduce WSDL cache value: " + reduceCache + 
                              " from the composite: " + composite.getClassName());
                }
                releaseAxisServiceResources = reduceCache;
            }
        }
        
    }
    EndpointDescriptionImpl(ServiceDescriptionImpl parent, String serviceImplName) {
        this(parent, serviceImplName, null, null);
    }

    /**
     * Create a service-provider side EndpointDescription based on the DescriptionBuilderComposite. 
     * Note that per the
     * JAX-WS Spec (Final Release, 4/19/2006 Section 4.2.3 Proxies, page 55)the "namespace component
     * of the port is the target namespace of the WSDL definition document".
     *
     * @param theClass The SEI or Impl class.  This will be NULL for Dispatch clients since they
     *                 don't use an SEI
     */
    EndpointDescriptionImpl(ServiceDescriptionImpl parent, String serviceImplName, Map
        properties, Integer portCompositeIndex) {
        
        if (log.isDebugEnabled()) {
            log.debug("entry EndpointDescriptionImpl(ServiceDescriptionImpl, String, Map, Integer)");
            log.debug("  parent=" + parent);
            log.debug("  serviceImplName=" + parent);
            log.debug("  portCompositeIndex=" + portCompositeIndex);
        }

        this.axisConfig = parent.getAxisConfigContext().getAxisConfiguration();
        
        // initialize CustomAnnotationIntance list and CustomAnnotationProcessor map
        customAnnotations = new ArrayList();
        customAnnotationProcessors = new HashMap();
        this.portCompositeIndex = portCompositeIndex;
        
        // set properties map
        this.properties = properties;
        
        this.parentServiceDescription = parent;
        this.serviceImplName = serviceImplName;

        // if the ServiceDescription's service QName is specified, let's use that to get the
        // correct DescriptionBuilderComposite
        if(parent.getServiceQName() != null) {
            composite = getServiceDescriptionImpl().getDescriptionBuilderComposite(parent.getServiceQName(),
                                                                                   portCompositeIndex); 
        }
        
        // otherwise we will get the DescriptionBuilderComposite by the current index
        else {
            composite = getServiceDescriptionImpl().getDescriptionBuilderComposite(null,
                                                                                   portCompositeIndex);
        }
        
        if (composite == null) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("endpointDescriptionErr3"));
        }
        
        if(composite.getHandlerChainAnnot() != null && composite.getHandlerChainsType() != null) {
        	throw ExceptionFactory.makeWebServiceException(
            Messages.getMessage("handlerSourceFail", composite.getClassName()));
        }
        
        handlerChainsType = composite.getHandlerChainsType();

        //Set the base level of annotation that we are processing...currently
        // a 'WebService' or a 'WebServiceProvider'
        if (composite.getWebServiceAnnot() != null)
            webServiceAnnotation = composite.getWebServiceAnnot();
        else
            webServiceProviderAnnotation = composite.getWebServiceProviderAnnot();

        
        // now get the custom annotation and process information from the DBC
        customAnnotations.addAll(composite.getCustomAnnotationInstances());
        customAnnotationProcessors.putAll(composite.getCustomAnnotationProcessors());
        
        // Note that on the client side, the service QN should be set; on the server side it will not be.
        if (DescriptionUtils.isEmpty(getServiceDescription().getServiceQName())) {
            getServiceDescriptionImpl().setServiceQName(getServiceQName());
        }
        //Call the getter to insure the qualified port name is set. 
        getPortQName();

        setupAxisServiceFromDBL();
        addToAxisService();    //Add a reference to this EndpointDescription to the AxisService

        buildDescriptionHierachy();

        WsdlComposite wsdlComposite = null;
        
        String bindingType = getBindingType();

        boolean isSOAP11 =
                (bindingType.equals(javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING) || 
                        bindingType.equals(javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING))
                        ? true : false;


        // Determine if we need to generate WSDL
        // First, make sure that this is only a SOAP 1.1 based binding, per JAXWS spec. we cannot 
        // generate WSDL if the binding type is not SOAP 1.1 based.
        // Then, assuming the composite does not contain a 
        // Wsdl Definition, go ahead and generate it
        if (isSOAP11){
            if (
                    (isEndpointBased() &&
                            DescriptionUtils.isEmpty(getAnnoWebServiceEndpointInterface()))
                            ||
                            (!isEndpointBased())
                    ) {
                //This is either an implicit SEI, or a WebService Provider
    
                wsdlComposite = generateWSDL(composite);
    
            } else if (isEndpointBased()) {
                //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 =
                        getServiceDescriptionImpl().getDBCMap()
                                .get(composite.getWebServiceAnnot().endpointInterface());
    
                //Only generate WSDL if a definition doesn't already exist
                if (seic.getWsdlDefinition() == null)
                    wsdlComposite = generateWSDL(composite);
            }

        } else if (composite.getWsdlDefinition() == null) {
            //This is a SOAP12 binding that does not contain a WSDL definition, log a WARNING
            log.warn(Messages.getMessage("generateWSDLNonSoap11", composite.getClassName()));
        }

        if (isSOAP11){
    
            //Save the WSDL Location and the WsdlDefinition, value depends on whether wsdl was generated
            Parameter wsdlLocationParameter = new Parameter();
            wsdlLocationParameter.setName(MDQConstants.WSDL_LOCATION);
    
            Parameter wsdlDefParameter = new Parameter();
            wsdlDefParameter.setName(MDQConstants.WSDL_DEFINITION);
    
            Parameter wsdlCompositeParameter = new Parameter();
            wsdlCompositeParameter.setName(MDQConstants.WSDL_COMPOSITE);
    
            if (wsdlComposite != null) {
    
                //We have a wsdl composite, so set these values for the generated wsdl
                wsdlCompositeParameter.setValue(wsdlComposite);
                wsdlLocationParameter.setValue(wsdlComposite.getWsdlFileName());

                Definition def =
                        getServiceDescriptionImpl().getGeneratedWsdlWrapper().getDefinition();
                URL wsdlUrl = getServiceDescriptionImpl().getGeneratedWsdlWrapper().getWSDLLocation();
                if (def instanceof WSDLDefinitionWrapper) {
                    wsdlDefParameter.setValue(def);
                } else {
                    // Create WSDLDefinitionWrapper
                    WSDLDefinitionWrapper wrap = null;
                    ConfigurationContext cc = composite.getConfigurationContext();
                    if (cc != null && cc.getAxisConfiguration() != null) {
                        wrap = new WSDLDefinitionWrapper(def, wsdlUrl, 
                                                         cc.getAxisConfiguration());
                    } else {
                        // Probably shouldn't get here.  But if we do, use
                        // a memory sensitve wsdl wrapper
                        wrap = new WSDLDefinitionWrapper(def, wsdlUrl, true, 2);
                    }
                    wsdlDefParameter.setValue(wrap);
                }

            } else if (getServiceDescriptionImpl().getWSDLWrapper() != null) {
                //No wsdl composite because wsdl already exists

                wsdlLocationParameter.setValue(getAnnoWebServiceWSDLLocation());

                Definition def = getServiceDescriptionImpl().getWSDLWrapper().getDefinition();
                URL wsdlUrl = getServiceDescriptionImpl().getWSDLWrapper().getWSDLLocation();
                if (def instanceof WSDLDefinitionWrapper) {
                    wsdlDefParameter.setValue(def);
                } else {
                    // Create WSDLDefinitionWrapper
                    WSDLDefinitionWrapper wrap = null;
                    ConfigurationContext cc = composite.getConfigurationContext();
                    if (cc != null && cc.getAxisConfiguration() != null) {
                        wrap = new WSDLDefinitionWrapper(def, wsdlUrl, 
                                                         cc.getAxisConfiguration());
                    } else {
                        // Probably shouldn't get here.  But if we do, use
                        // a memory sensitve wsdl wrapper
                        wrap = new WSDLDefinitionWrapper(def, wsdlUrl, true, 2);
                    }
                    wsdlDefParameter.setValue(wrap);
                }

            } else {
                //There is no wsdl composite and there is NOT a wsdl definition
                wsdlLocationParameter.setValue(null);
                wsdlDefParameter.setValue(null);
    
            }
    
            try {
                if (wsdlComposite != null) {
                    axisService.addParameter(wsdlCompositeParameter);
                }
                axisService.addParameter(wsdlDefParameter);
                axisService.addParameter(wsdlLocationParameter);
            } catch (Exception e) {
                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("endpointDescriptionErr4"));
            }
        }
        else {
            // Need to account for SOAP 1.2 WSDL when supplied with application
            Parameter wsdlDefParameter = new Parameter();
            wsdlDefParameter.setName(MDQConstants.WSDL_DEFINITION);
            Parameter wsdlLocationParameter = new Parameter();
            wsdlLocationParameter.setName(MDQConstants.WSDL_LOCATION);
            if (getServiceDescriptionImpl().getWSDLWrapper() != null) {
                wsdlLocationParameter.setValue(getAnnoWebServiceWSDLLocation());

                Definition def = getServiceDescriptionImpl().getWSDLWrapper().getDefinition();
                URL wsdlUrl = getServiceDescriptionImpl().getWSDLWrapper().getWSDLLocation();
                if (def instanceof WSDLDefinitionWrapper) {
                    wsdlDefParameter.setValue(def);
                } else {
                    // Create WSDLDefinitionWrapper
                    WSDLDefinitionWrapper wrap = null;
                    ConfigurationContext cc = composite.getConfigurationContext();
                    if (cc != null && cc.getAxisConfiguration() != null) {
                        wrap = new WSDLDefinitionWrapper(def, wsdlUrl, 
                                                         cc.getAxisConfiguration());
                    } else {
                        // Probably shouldn't get here.  But if we do, use
                        // a memory sensitve wsdl wrapper
                        wrap = new WSDLDefinitionWrapper(def, wsdlUrl, true, 2);
                    }
                    wsdlDefParameter.setValue(wrap);
                }
            }
            // No WSDL supplied and we do not generate for non-SOAP 1.1/HTTP
            // endpoints
            else {
                wsdlLocationParameter.setValue(null);
                wsdlDefParameter.setValue(null);
            }
            try {
                axisService.addParameter(wsdlDefParameter);
                axisService.addParameter(wsdlLocationParameter);

            } catch (Exception e) {
                throw ExceptionFactory
                    .makeWebServiceException(Messages.getMessage("endpointDescriptionErr4"),e);
            }
        }
        
        // Before we leave we need to drive the CustomAnnotationProcessors if 
        // there were any CustomAnnotationInstance objects registered
        Iterator annotationIter = customAnnotations.iterator();
        while(annotationIter.hasNext()) {
            CustomAnnotationInstance annotation = annotationIter.next();
            if(log.isDebugEnabled()) {
                log.debug("Checking for CustomAnnotationProcessor for CustomAnnotationInstance " +
                                "class: " + annotation.getClass().getName());
            }
            CustomAnnotationProcessor processor = customAnnotationProcessors.get(annotation.getClass().getName());
            if(processor != null) {
                if(log.isDebugEnabled()) {
                    log.debug("Found CustomAnnotationProcessor: " + processor.getClass().getName() + 
                              " for CustomAnnotationInstance: " + annotation.getClass().getName());
                }
                processor.processTypeLevelAnnotation(this, annotation);
            }
        }
        
        // Configure any available WebServiceFeatures on the endpoint.
        configureWebServiceFeatures();
        
        // REVIEW: there are some throws above that won't cause the release
        setupReleaseResources(composite.getConfigurationContext());
        releaseAxisServiceResources();
        if (log.isDebugEnabled()) {
            log.debug("exit EndpointDescriptionImpl(ServiceDescriptionImpl, String, Map, Integer)");
        }
    }

    private void addToAxisService() {
        // Add a reference to this EndpointDescription object to the AxisService
        if (axisService != null) {
            Parameter parameter = new Parameter();
            parameter.setName(EndpointDescription.AXIS_SERVICE_PARAMETER);
            parameter.setValue(this);
            try {
                axisService.addParameter(parameter);
            } catch (AxisFault e) {
            	throw ExceptionFactory.makeWebServiceException(Messages.getMessage("endpointDescriptionErr5", EndpointDescription.AXIS_SERVICE_PARAMETER), e);
            }
        }
    }

    private void buildEndpointDescriptionFromAnnotations() {
        // TODO: The comments below are not quite correct; this method is used on BOTH the 
        //       client and server.  On the client the class is always an SEI.  On the server it 
        //		 is always a service impl which may be a provider or endpoint based;
        //		 endpoint based may reference an SEI class

        // The Service Implementation class could be either Provider-based or Endpoint-based.  The 
        // annotations that are present are similar but different.  Conformance requirements 
        // per JAX-WS
        // - A Provider based implementation MUST carry the @WebServiceProvider annotation
        //   per section 5.1 javax.xml.ws.Provider on page 63
        // - An Endpoint based implementation MUST carry the @WebService annotation per JSR-181 
        //   (reference TBD) and JAX-WS (reference TBD)
        // - An Endpoint based implementation @WebService annotation MAY reference an endpoint
        //   interface 
        // - The @WebService and @WebServiceProvider annotations can not appear in the same class per 
        //   JAX-WS section 7.7 on page 82.

        // If portName was specified, set it.  Otherwise, we will get it from the appropriate
        // annotation when the getter is called.

        // If this is an Endpoint-based service implementation (i.e. not a 
        // Provider-based one), then create the EndpointInterfaceDescription to contain
        // the operations on the endpoint.  Provider-based endpoints don't have operations
        // associated with them, so they don't have an EndpointInterfaceDescription.
        if (webServiceAnnotation != null) {
            // If this impl class references an SEI, then use that SEI to create the EndpointInterfaceDesc.
            String seiClassName = getAnnoWebServiceEndpointInterface();

            if (!composite.isServiceProvider()) {
                Class seiClass = null;
                if (DescriptionUtils.isEmpty(seiClassName)) {
                    // This is the client code path; the @WebServce will not have an endpointInterface member
                    // For now, just build the EndpointInterfaceDesc based on the class itself.
                    seiClass = composite.getCorrespondingClass();
                }
                endpointInterfaceDescription = new EndpointInterfaceDescriptionImpl(seiClass, this);
            } else {
                if (DescriptionUtils.isEmpty(getAnnoWebServiceEndpointInterface())) {

                    endpointInterfaceDescription =
                            new EndpointInterfaceDescriptionImpl(composite, true, this);

                } else {
                    //Otherwise, build the EID based on the SEI composite
                    endpointInterfaceDescription = new EndpointInterfaceDescriptionImpl(
                            getServiceDescriptionImpl().getDBCMap().get(seiClassName),
                            false,
                            this);
                    
                    // after this is constructed, we need to update the @WebService.name 
                    // attribute on the axisService instance
                    if(axisService != null) {
                        updateWebServiceNameParameter(((EndpointInterfaceDescriptionImpl) 
                                endpointInterfaceDescription).getAnnoWebServiceName(), axisService); 
                    }
                }
            }
        } else {
            if (log.isDebugEnabled()) {
                log.debug("WebServiceProvider without WSDL encountered");
            }
            String bindingType = getBindingType();
            if (javax.xml.ws.http.HTTPBinding.HTTP_BINDING.equals(bindingType)||
                    SOAPBinding.SOAP11HTTP_BINDING.equals(bindingType)||
                    SOAPBinding.SOAP12HTTP_BINDING.equals(bindingType)||
                    MDQConstants.SOAP_HTTP_BINDING.equals(bindingType)) {
                endpointInterfaceDescription = new EndpointInterfaceDescriptionImpl(composite, this);
            }
        }
    }

    public QName getPortQName() {
        if (portQName == null) {
            // The name was not set by the constructors, so get it from the
            // appropriate annotation.
            String name = getAnnoWebServicePortName();
            String tns = getAnnoWebServiceTargetNamespace();
            portQName = new QName(tns, name);
        }
        return portQName;
    }

    public QName getServiceQName() {
        if (serviceQName == null) {
            // If the service name has been set on the Service, use that.  Otherwise
            // get the name off the annotations
            QName serviceDescQName = getServiceDescription().getServiceQName();
            if (!DescriptionUtils.isEmpty(serviceDescQName)) {
                serviceQName = serviceDescQName;
            } else {
                String localPart = getAnnoWebServiceServiceName();
                String tns = getAnnoWebServiceTargetNamespace();
                serviceQName = new QName(tns, localPart);
            }
        }
        return serviceQName;
    }

    public ServiceDescription getServiceDescription() {
        return parentServiceDescription;
    }

    public ServiceDescriptionImpl getServiceDescriptionImpl() {
        return (ServiceDescriptionImpl)parentServiceDescription;
    }

    public EndpointInterfaceDescription getEndpointInterfaceDescription() {
        return endpointInterfaceDescription;
    }

    public AxisService getAxisService() {
        return axisService;
    }

    boolean isDynamicPort() {
        return isDynamicPort;
    }

    void updateWithSEI(Class sei, DescriptionBuilderComposite sparseComposite, Object sparseCompositeKey) {
        // Updating with an SEI is only valid for declared ports; it is not valid for dynamic ports.
        if (isDynamicPort()) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("updateWithSEIErr1",portQName.toString()));
        }
        if (sei == null) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("updateWithSEIErr2",portQName.toString()));
        }
        
        composite.setSparseComposite(sparseCompositeKey, sparseComposite);

        if (endpointInterfaceDescription != null) {
            // The EndpointInterfaceDescription was created previously based on the port declaration (i.e. WSDL)
            // so update that with information from the SEI annotations
            ((EndpointInterfaceDescriptionImpl)endpointInterfaceDescription).updateWithSEI(sei);
        } else {
            // An EndpointInterfaceDescription does not exist yet.  This currently happens in the case where there is 
            // NO WSDL provided and a Dispatch client is created for prior to a getPort being done for that port.
            // There was no WSDL to create the EndpointInterfaceDescription from and there was no annotated SEI to
            // use at that time.  Now we have an annotated SEI, so create the EndpointInterfaceDescription now.
            endpointInterfaceDescription = new EndpointInterfaceDescriptionImpl(sei, this);
        }
        return;
    }

    private void setupAxisService(Object sparseCompositeKey) {
        // Build up the AxisService.  Note that if this is a dynamic port, then we don't use the
        // WSDL to build up the AxisService since the port added to the Service by the client is not
        // one that will be present in the WSDL.  A null class passed in as the SEI indicates this 
        // is a dispatch client.
        if (!isDynamicPort && getServiceDescriptionImpl().getWSDLWrapper() != null) {
            isAxisServiceBuiltFromWSDL = buildAxisServiceFromWSDL();
        } else {
            if (useGeneratedWSDL()) {
                buildAxisServiceFromGeneratedWSDL();
            } else {
                buildAxisServiceFromAnnotations();
                addAnnotationParamToService();
            }
        }

        if (axisService == null) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("setupAxisServiceErr1",createAxisServiceName()));
        }

        // Save the Service QName as a parameter.
        Parameter serviceNameParameter = new Parameter();
        serviceNameParameter.setName(WSDL11ToAllAxisServicesBuilder.WSDL_SERVICE_QNAME);
        serviceNameParameter.setValue(getServiceDescription().getServiceQName());

        // Save the Port name.  Note: Axis does not expect a QName since the namespace for the port is the ns from the WSDL definition 
        Parameter portParameter = new Parameter();
        portParameter.setName(WSDL11ToAllAxisServicesBuilder.WSDL_PORT);
        portParameter.setValue(portQName.getLocalPart());
        
        // Store the service class fully qualified name
        Parameter serviceClassNameParam = new Parameter();
        serviceClassNameParam.setName(MDQConstants.CLIENT_SERVICE_CLASS);
        String serviceClassName = this.getServiceDescriptionImpl().getServiceClassName();
        if(log.isDebugEnabled()) {
            log.debug("Setting service class name parameter to: " + serviceClassName + 
                      " on AxisService: " + axisService + "@" + axisService.hashCode());
        }
        serviceClassNameParam.setValue(serviceClassName);
        
        // Store the sei class fully qualified name, if it is available
        Parameter seiClassNameParam = new Parameter();
        seiClassNameParam.setName(MDQConstants.CLIENT_SEI_CLASS);
        String seiClassName = composite.getClassName();
        if(log.isDebugEnabled()) {
            log.debug("Setting sei class name parameter to: " + seiClassName + 
                      " on AxisService: " + axisService + "@" + axisService.hashCode());
        }
        seiClassNameParam.setValue(seiClassName);
        
        // If a ServiceRef Name was set on the sparse composite for the service, then store that
        Parameter serviceRefNameParam = getServiceRefNameParam(sparseCompositeKey);
     
        try {
            axisService.addParameter(serviceNameParameter);
            axisService.addParameter(portParameter);
            axisService.addParameter(serviceClassNameParam);
            axisService.addParameter(seiClassNameParam);
            if (serviceRefNameParam != null) {
                axisService.addParameter(serviceRefNameParam);
            }
        }
        catch (AxisFault e) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("setupAxisServiceErr2"),e);
        }
    }
    /**
     * Return a Parameter instance for ServiceRefName if that name was specified on the sparse composite when the Service was created.
     * @param sparseCompositeKey identifies the instance of the service (i.e. Service Delegate)
     * @return A Parameter containing the ServiceRefName or null if one was not specified.
     */
    private Parameter getServiceRefNameParam(Object sparseCompositeKey) {
        Parameter serviceRefNameParam = null;
        
        // The ServiceRefName, if specified, is set on the sparse composite associated with the service.
        String serviceRefName = getServiceDescriptionImpl().getDescriptionBuilderComposite().getServiceRefName(sparseCompositeKey);
        if (!DescriptionUtils.isEmpty(serviceRefName)) {
            if (log.isDebugEnabled()) {
                log.debug("Setting service ref name: " + serviceRefName 
                        + " on AxisService: " + axisService + "@" + axisService.hashCode());
            }
            serviceRefNameParam = new Parameter();
            serviceRefNameParam.setName(MDQConstants.SERVICE_REF_NAME);
            serviceRefNameParam.setValue(serviceRefName);
        }
        return serviceRefNameParam;
    }

    /*
     * This setups and builds the AxisService using only the DescriptionBuilderCompositeList
     * 
     */
    private void setupAxisServiceFromDBL() {
        // Build up the AxisService.  Note that if this is a dispatch client, then we don't use the
        // WSDL to build up the AxisService since the port added to the Service by the client is not
        // one that will be present in the WSDL.  A null class passed in as the SEI indicates this 
        // is a dispatch client.

        // If WSDL is present, it may be full or only partial.  If we can create the AxisService from 
        // the WSDL, that WSDL is fully specified.  Otherwise, it is "partial WSDL".  In that case
        // we use annotaions to build the AxisService
        isAxisServiceBuiltFromWSDL = false;
        if (getServiceDescriptionImpl().getWSDLWrapper() != null) {
            isAxisServiceBuiltFromWSDL = buildAxisServiceFromWSDL();

        }

        if (!isAxisServiceBuiltFromWSDL) {
            //generateWSDL(composite);
            if (useGeneratedWSDL()) {
                buildAxisServiceFromGeneratedWSDL();
            } else {
                buildAxisServiceFromAnnotations();
                addAnnotationParamToService();
            }
        }

        if (axisService == null) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("setupAxisServiceErr1",createAxisServiceName()));
        }
        
        //Save the Port Type name
        Parameter portTypeNameParameter = new Parameter();
        portTypeNameParameter.setName(MDQConstants.WSDL_PORTTYPE_NAME);
        portTypeNameParameter.setValue(getName());

        // Save the Service QName as a parameter.
        Parameter serviceNameParameter = new Parameter();
        serviceNameParameter.setName(MDQConstants.WSDL_SERVICE_QNAME);
        serviceNameParameter.setValue(getServiceDescription().getServiceQName());

        // Save the Port name.  Note: Axis does not expect a QName since the namespace
        //   for the port is the ns from the WSDL definition 
        Parameter portParameter = new Parameter();
        portParameter.setName(MDQConstants.WSDL_PORT);
        portParameter.setValue(getPortQName().getLocalPart());

        //Save the fully qualified class name for the serviceImpl
        Parameter serviceClassNameParameter = new Parameter();
        serviceClassNameParameter.setName(MDQConstants.SERVICE_CLASS);
        serviceClassNameParameter
                .setValue(DescriptionUtils.javifyClassName(composite.getClassName()));

        try {
            axisService.addParameter(portTypeNameParameter);
            axisService.addParameter(serviceNameParameter);
            axisService.addParameter(portParameter);
            axisService.addParameter(serviceClassNameParameter);
        }
        catch (AxisFault e) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("setupAxisServiceErr2"),e);
        }
    }

    private boolean buildAxisServiceFromWSDL() {
        if (log.isDebugEnabled()) {
            log.debug("entry");
        }
        boolean isBuiltFromWSDL = false;
        try {

            // Note that the axis service builder takes only the localpart of the port qname.
            // TODO:: This should check that the namespace of the definition matches the namespace of the portQName per JAXRPC spec

            
            // Use getDefinition() so that we have the advantages of the memory features.
            Definition def = getServiceDescriptionImpl().getWSDLWrapper().getDefinition();

            WSDL11ToAxisServiceBuilder serviceBuilder =
                    new WSDL11ToAxisServiceBuilder(def,
                            getServiceDescription().getServiceQName(),
                            getPortQName().getLocalPart());

            if (log.isDebugEnabled()) {
                log.debug("Building AxisService from wsdl: " + getServiceDescriptionImpl().getWSDLWrapper().getWSDLLocation());  
                log.debug("Build Axis Service from WSDL ");
                log.debug("  Service QName =" + getServiceDescription().getServiceQName());
                log.debug("  Port QName = "  + getPortQName());
                log.debug("  WSDL = " + def.toString()); 
            }
                        
            ClassLoader classLoader;
            if (composite.isServiceProvider()) {
                classLoader = composite.getClassLoader();
            } else {
                classLoader = getContextClassLoader(null);
            }
            JAXWSCatalogManager catalogManager = getServiceDescriptionImpl().getCatalogManager();
            CatalogURIResolver uriResolver = new CatalogURIResolver(catalogManager, classLoader);
            serviceBuilder.setCustomResolver(uriResolver);

            if (getServiceDescriptionImpl().isServerSide())
                serviceBuilder.setServerSide(true);
            else
                serviceBuilder.setServerSide(false);

            // Associate the AxisConfiguration with the ServiceBuilder if it
            // is available.  This is done so that the serviceBuilder can
            // use the appropriate WSDL wrapper memory parameters.
            AxisConfiguration ac = null;
            if (composite.getConfigurationContext() != null) {
                ac = composite.getConfigurationContext().getAxisConfiguration();
                if (ac != null) {
                    serviceBuilder.useAxisConfiguration(ac);
                }
            }
            // Create and populate the AxisService
            axisService = serviceBuilder.populateService();
            
            // If an AxisConfiguration was not available,
            // default to using a memory efficient wrapper
            if (ac == null) {
                Parameter wsdlWrapperParam = 
                    axisService.getParameter(WSDLConstants.WSDL_4_J_DEFINITION);
                if (wsdlWrapperParam != null &&
                    wsdlWrapperParam.getValue() instanceof WSDLDefinitionWrapper) {
                    
                    WSDLDefinitionWrapper wrapper = 
                        (WSDLDefinitionWrapper)  wsdlWrapperParam.getValue();
                    
                    // If only the basic wrapper is being used, upgrade to the
                    // RELOAD wrapper
                    if (wrapper.getMemoryLimitType() == 0) {
                        Definition wsdlDef = wrapper.getUnwrappedDefinition();

                        WSDLDefinitionWrapper wrapper2 = 
                            new WSDLDefinitionWrapper(wsdlDef, true, 2);

                        wsdlWrapperParam.setValue(wrapper2);
                    }
                }
            }
            axisService.setName(createAxisServiceName());
            isBuiltFromWSDL = true;

        } catch (AxisFault e) {
            String wsdlLocation = (getServiceDescriptionImpl().getWSDLLocation() != null) ?
                    getServiceDescriptionImpl().getWSDLLocation().toString() : null;
            String implClassName = composite.getClassName();
            log.warn(Messages.getMessage("bldAxisSrvcFromWSDLErr", implClassName, wsdlLocation, e.getMessage()));
            if (log.isDebugEnabled()) {
                log.debug("Exception processing WSDL file.  Impl class: " + implClassName + "; WSDL Location: "+ wsdlLocation, e);
            }

            isBuiltFromWSDL = false;
        }
        if (log.isDebugEnabled()) {
            log.debug("exit isBuiltFromWSDL = " + isBuiltFromWSDL);

        }
        return isBuiltFromWSDL;
    }

    /**
     * If a WSDL is not already found, this method can be used to generate a WSDL and create
     * the AxisService using that WSDL
     */

    private void buildAxisServiceFromGeneratedWSDL() {
        /**
         * First we create a dummy axis service to get the information for WSDL generation.
         * When the new axis service is created from the WSDL, this one is overidden by the
         * new service.
         */
        buildAxisServiceFromAnnotations();

        //Save the fully qualified class name for the serviceImpl
        Parameter serviceClassNameParameter = new Parameter();
        serviceClassNameParameter.setName(MDQConstants.SERVICE_CLASS);
        serviceClassNameParameter
                .setValue(DescriptionUtils.javifyClassName(composite.getClassName()));
        try {
            this.axisService.addParameter(serviceClassNameParameter);
        } catch (AxisFault axisFault) {
            throw ExceptionFactory.makeWebServiceException(Messages
                    .getMessage("setupAxisServiceErr2"), axisFault);
        }

        addToAxisService();

        JAXWSRIWSDLGenerator wsdlGenerator =
                new JAXWSRIWSDLGenerator(this.axisService, this.axisConfig);

        try {
            //generate the wsdl
            Definition def = wsdlGenerator.getWSDL(axisService);

            //create the new axis service from the generated wsdl
            WSDL11ToAxisServiceBuilder axisServiceBuilder = new WSDL11ToAxisServiceBuilder(def,
                    getServiceDescription().getServiceQName(), getPortQName().getLocalPart());

            if (getServiceDescriptionImpl().isServerSide()) {
                axisServiceBuilder.setServerSide(true);
            } else {
                axisServiceBuilder.setServerSide(false);
            }

            this.axisService = axisServiceBuilder.populateService();
            axisService.setName(getServiceDescription().getServiceQName().getLocalPart());
            axisService.setParent(axisConfig);

            // we always get only one endpoint as there's only one port in the generated WSDL
            // from wsgen. Set the transport for that endpoint as http by default.
            for (AxisEndpoint axisEndpoint : axisService.getEndpoints().values()) {
                axisEndpoint.setTransportInDescription("http");
                axisEndpoint.setEndpointURL(null);
            }

        } catch (AxisFault e) {
            throw ExceptionFactory.makeWebServiceException(Messages
                    .getMessage("setupAxisServiceErr3"),e);
        }
    }

    /**
     * Reads the property in axis config (comes from axis2.xml) and decides whether we have to
     * build the AxisService using a generated WSDL.
     * @return true if param true
     */
    private boolean useGeneratedWSDL(){
        Parameter param = this.axisConfig.getParameter(MDQConstants.USE_GENERATED_WSDL);
        return param != null && "true".equals(param.getValue());
    }

    private void addAnnotationParamToService() {
        //Add a parameter to identify that this AxisService is created only using annotations
        try {
            axisService.addParameter(MDQConstants.USED_ANNOTATIONS_ONLY, "true");
        } catch (AxisFault axisFault) {
            throw ExceptionFactory.makeWebServiceException(Messages
                    .getMessage("setupAxisServiceErr2"), axisFault);
        }
    }

    private void buildAxisServiceFromAnnotations() {
        String serviceName = null;
        if (portQName != null) {
            serviceName = createAxisServiceName();
        } else {
            // Make this service name unique.  The Axis2 engine assumes that a service it can not find is a client-side service.
            serviceName = ServiceClient.ANON_SERVICE + this.hashCode() + System.currentTimeMillis();
        }
        axisService = new AxisService(serviceName);

        // Now we have to add an Endpoint to the AxisService instance according to the generated
        // WSDL. Binding type can be SOAP 1.1, SOAP 1.2 or HTTP. Always we have to use the
        // annotated port name as the endpoint name.
        try {
            String bindingType = getBindingType();
            // Default transport protocol is set to HTTP
            String protocol = "http";
            if (bindingType.startsWith(SOAPBinding.SOAP12HTTP_BINDING)) {
                Utils.addSoap12Endpoint(axisService, protocol, getPortQName().getLocalPart());
            } else if (bindingType.startsWith(javax.xml.ws.http.HTTPBinding.HTTP_BINDING)) {
                Utils.addHttpEndpoint(axisService, protocol, getPortQName().getLocalPart());
            } else {
                // Assume SOAP 1.1 over HTTP for all other cases
                Utils.addSoap11Endpoint(axisService, protocol, getPortQName().getLocalPart());
            }
        } catch (Exception e) {
            log.error("Error while generating the Endpoint for service :" + axisService.getName());
        }

    }

    private void releaseAxisServiceResources() {
        // release the schema list in the AxisService
        if (releaseAxisServiceResources && axisService != null) {
            axisService.releaseSchemaList();
        }
    }

    private void buildDescriptionHierachy() {
        // Build up the Description Hierachy.  Note that if this is a dynamic port, then we don't use the
        // WSDL to build up the hierachy since the port added to the Service by the client is not
        // one that will be present in the WSDL.

        if (composite.isServiceProvider()) {
            if (!isDynamicPort && isWSDLFullySpecified())
                buildEndpointDescriptionFromWSDL();
            else
                buildEndpointDescriptionFromAnnotations();
        } else {
            //Still processing annotations from the class
            // This path was not updated
            if (!isDynamicPort && isWSDLFullySpecified()) {
                buildEndpointDescriptionFromWSDL();
            } else if (composite.getCorrespondingClass() != null) {
                // Create the rest of the description hierachy from annotations on the class.
                // If there is no SEI class, then this is a Distpach case, and we currently
                // don't create the rest of the description hierachy (since it is not an SEI and thus
                // not operation-based client.
                buildEndpointDescriptionFromAnnotations();
            }
        }
    }

    private void buildEndpointDescriptionFromWSDL() {
        Definition wsdlDefinition = getServiceDescriptionImpl().getWSDLWrapper().getDefinition();
        javax.wsdl.Service wsdlService =
                wsdlDefinition.getService(getServiceDescription().getServiceQName());
        if (wsdlService == null) {
            throw ExceptionFactory.makeWebServiceException(
                    Messages.getMessage("serviceDescErr2", createAxisServiceName()));
        }

        Map wsdlPorts = wsdlService.getPorts();
        boolean wsdlPortFound = false;
        if (wsdlPorts != null && wsdlPorts.size() > 0) {
            Iterator wsdlPortIterator = wsdlPorts.values().iterator();

            while (wsdlPortIterator.hasNext() && !wsdlPortFound) {
                Port wsdlPort = (Port)wsdlPortIterator.next();
                // Note the namespace is not included on the WSDL Port.
                if (wsdlPort.getName().equals(portQName.getLocalPart())) {

                    // Build the EndpointInterface based on the specified SEI if there is one
                    // or on the service impl class (i.e. an implicit SEI).
                    if (composite.isServiceProvider()) {
                        String seiClassName = getAnnoWebServiceEndpointInterface();
                        if (DescriptionUtils.isEmpty(seiClassName)) {
                            // No SEI specified, so use the service impl as an implicit SEI
                            endpointInterfaceDescription =
                                    new EndpointInterfaceDescriptionImpl(composite, true, this);
                        } else {
                            // Otherwise, build the EID based on the SEI composite
                            endpointInterfaceDescription = new EndpointInterfaceDescriptionImpl(
                                    getServiceDescriptionImpl().getDBCMap().get(seiClassName),
                                    false,
                                    this);
                            
                            // after this is constructed, we need to update the @WebService.name 
                            // attribute on the axisService instance
                            if(axisService != null) {
                                updateWebServiceNameParameter(((EndpointInterfaceDescriptionImpl) 
                                        endpointInterfaceDescription).getAnnoWebServiceName(), axisService); 
                            }
                        }

                    } else {
                        // Create the Endpoint Interface Description based on the WSDL.
                        endpointInterfaceDescription = new EndpointInterfaceDescriptionImpl(this);

                        // Update the EndpointInterfaceDescription created with WSDL with information from the
                        // annotations in the SEI
                        ((EndpointInterfaceDescriptionImpl)endpointInterfaceDescription)
                                .updateWithSEI(composite.getCorrespondingClass());
                    }
                    wsdlPortFound = true;
                }
            }
        }

        if (!wsdlPortFound) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("serviceDescErr3",portQName.getLocalPart()));
        }
    }

    /**
     * Adds the anonymous axis operations to the AxisService.  Note that this is only needed on the
     * client side, and they are currently used in two cases (1) For Dispatch clients (which don't
     * use SEIs and thus don't use operations) (2) TEMPORARLIY for Services created without WSDL
     * (and thus which have no AxisOperations created) See the AxisInvocationController invoke
     * methods for more details.
     * 

* Based on ServiceClient.createAnonymouService */ private void addAnonymousAxisOperations() { if (axisService != null) { OutOnlyAxisOperation outOnlyOperation = new OutOnlyAxisOperation(ServiceClient.ANON_OUT_ONLY_OP); axisService.addOperation(outOnlyOperation); outOnlyOperation.setSoapAction(null); OutInAxisOperation outInOperation = new OutInAxisOperation(ServiceClient.ANON_OUT_IN_OP); axisService.addOperation(outInOperation); outInOperation.setSoapAction(null); } } public synchronized ServiceClient getServiceClient() { try { if (serviceClient == null) { ConfigurationContext configCtx = getServiceDescription().getAxisConfigContext(); AxisService axisSvc = getAxisService(); AxisConfiguration axisCfg = configCtx.getAxisConfiguration(); // The method synchronization prevents more than 1 service client being created // for the same EndpointDescription instance by multiple threads. We also need // to prevent different EndpointDescription instances from creating service client // instances using the same AxisService name under multiple threads. We do that by // synchronizing on the AxisConfiguration instance. synchronized(axisCfg) { if (axisCfg.getService(axisSvc.getName()) != null) { axisSvc.setName(axisSvc.getName() + uniqueID()); if (log.isDebugEnabled()) { log.debug("AxisService name is now " + axisSvc.getName() + ". This name should be unique; if not, errors might occur."); } } serviceClient = new ServiceClient(configCtx, axisSvc); // Disable automatic cleanup to avoid threading issues in Axis2 during the cleanup. JAXWS will // drive the cleanup based on ServiceDelegate finalization serviceClient.getOptions().setProperty(ServiceClient.AUTO_OPERATION_CLEANUP, false); } } } catch (AxisFault e) { throw ExceptionFactory.makeWebServiceException( Messages.getMessage("serviceClientCreateError"), e); } return serviceClient; } //This should eventually be deprecated in favor 'createAxisServiceNameFromDBL private String createAxisServiceName() { return getServiceDescription().getServiceQName().getLocalPart(); } public boolean isWSDLFullySpecified() { return isAxisServiceBuiltFromWSDL; } public boolean isProviderBased() { return webServiceProviderAnnotation != null; } public boolean isEndpointBased() { return webServiceAnnotation != null; } // =========================================== // ANNOTATION: WebService and WebServiceProvider // =========================================== public String getAnnoWebServiceWSDLLocation() { if (annotation_WsdlLocation == null) { if (getAnnoWebService() != null) { annotation_WsdlLocation = getAnnoWebService().wsdlLocation(); //If this is not an implicit SEI, then make sure that its not on the SEI if (composite.isServiceProvider()) { if (!DescriptionUtils.isEmpty(getAnnoWebServiceEndpointInterface())) { DescriptionBuilderComposite seic = getServiceDescriptionImpl().getDBCMap() .get(composite.getWebServiceAnnot().endpointInterface()); if (!DescriptionUtils.isEmpty(seic.getWebServiceAnnot().wsdlLocation())) { annotation_WsdlLocation = seic.getWebServiceAnnot().wsdlLocation(); } } } } else if (getAnnoWebServiceProvider() != null && !DescriptionUtils.isEmpty(getAnnoWebServiceProvider().wsdlLocation())) { annotation_WsdlLocation = getAnnoWebServiceProvider().wsdlLocation(); } else { // There is no default value per JSR-181 MR Sec 4.1 pg 16 annotation_WsdlLocation = ""; } } return annotation_WsdlLocation; } public String getAnnoWebServiceServiceName() { if (annotation_ServiceName == null) { if (getAnnoWebService() != null && !DescriptionUtils.isEmpty(getAnnoWebService().serviceName())) { annotation_ServiceName = getAnnoWebService().serviceName(); } else if (getAnnoWebServiceProvider() != null && !DescriptionUtils.isEmpty(getAnnoWebServiceProvider().serviceName())) { annotation_ServiceName = getAnnoWebServiceProvider().serviceName(); } else { // Default value is the "simple name" of the class or interface + "Service" // Per JSR-181 MR Sec 4.1, pg 15 annotation_ServiceName = DescriptionUtils.getSimpleJavaClassName(composite.getClassName()) + "Service"; } } return annotation_ServiceName; } public String getAnnoWebServicePortName() { if (annotation_PortName == null) { if (getAnnoWebService() != null && !DescriptionUtils.isEmpty(getAnnoWebService().portName())) { annotation_PortName = getAnnoWebService().portName(); } else if (getAnnoWebServiceProvider() != null && !DescriptionUtils.isEmpty(getAnnoWebServiceProvider().portName())) { annotation_PortName = getAnnoWebServiceProvider().portName(); } else { // Default the value if (isProviderBased()) { // This is the @WebServiceProvider annotation path // Default value is not specified in JSR-224, but we can assume it is // similar to the default in the WebService case, however there is no // name attribute for a WebServiceProvider. So in this case we use // the default value for WebService.name per JSR-181 MR sec 4.1 pg 15. // Note that this is really the same thing as the call to getWebServiceName() // in the WebService case; it is done sepertely just to be clear there is no // name element on the WebServiceProvider annotation annotation_PortName = DescriptionUtils.getSimpleJavaClassName(composite.getClassName()) + "Port"; } else { // This is the @WebService annotation path // Default value is the @WebService.name of the class or interface + "Port" // Per JSR-181 MR Sec 4.1, pg 15 annotation_PortName = getAnnoWebServiceName() + "Port"; } } } return annotation_PortName; } public String getAnnoWebServiceTargetNamespace() { if (annotation_TargetNamespace == null) { if (getAnnoWebService() != null && !DescriptionUtils.isEmpty(getAnnoWebService().targetNamespace())) { annotation_TargetNamespace = getAnnoWebService().targetNamespace(); } else if (getAnnoWebServiceProvider() != null && !DescriptionUtils.isEmpty(getAnnoWebServiceProvider().targetNamespace())) { annotation_TargetNamespace = getAnnoWebServiceProvider().targetNamespace(); } else { // Default value per JSR-181 MR Sec 4.1 pg 15 defers to "Implementation defined, // as described in JAX-WS 2.0, section 3.2" which is JAX-WS 2.0 Sec 3.2, pg 29. annotation_TargetNamespace = DescriptionUtils.makeNamespaceFromPackageName( DescriptionUtils.getJavaPackageName(composite.getClassName()), "http"); } } return annotation_TargetNamespace; } // =========================================== // ANNOTATION: WebServiceProvider // =========================================== public WebServiceProvider getAnnoWebServiceProvider() { return webServiceProviderAnnotation; } // =========================================== // ANNOTATION: WebService // =========================================== public WebService getAnnoWebService() { return webServiceAnnotation; } public String getAnnoWebServiceEndpointInterface() { // TODO: Validation: Not allowed on WebServiceProvider if (webService_EndpointInterface == null) { if (!isProviderBased() && getAnnoWebService() != null && !DescriptionUtils.isEmpty(getAnnoWebService().endpointInterface())) { webService_EndpointInterface = getAnnoWebService().endpointInterface(); } else { // This element is not valid on a WebServiceProvider annotation webService_EndpointInterface = ""; } } return webService_EndpointInterface; } public String getAnnoWebServiceName() { // TODO: Validation: Not allowed on WebServiceProvider //TODO: Per JSR109 v1.2 Sec. 5.3.2.1 // If not specified then we can use the default value as specified in JSR 181 // (but only if it is unique within the module)...or If the name is // not specified in the Service Implementation Bean then fully // qualified name of the Bean class is used to guarantee uniqueness // If the above is not unique then fully qualified name of the // Bean class is used to guarantee uniqueness if (webService_Name == null) { if (!isProviderBased()) { if (getAnnoWebService() != null && !DescriptionUtils.isEmpty(getAnnoWebService().name())) { webService_Name = getAnnoWebService().name(); } else { webService_Name = DescriptionUtils.getSimpleJavaClassName(composite.getClassName()); } } else { // This element is not valid on a WebServiceProvider annotation webService_Name = ""; } } return webService_Name; } // =========================================== // ANNOTATION: ServiceMode // =========================================== public ServiceMode getAnnoServiceMode() { if (serviceModeAnnotation == null) { serviceModeAnnotation = composite.getServiceModeAnnot(); } return serviceModeAnnotation; } public Service.Mode getServiceMode() { return getAnnoServiceModeValue(); } public Service.Mode getAnnoServiceModeValue() { // This annotation is only valid on Provider-based endpoints. if (isProviderBased() && serviceModeValue == null) { if (getAnnoServiceMode() != null) { serviceModeValue = getAnnoServiceMode().value(); } else { serviceModeValue = ServiceMode_DEFAULT; } } return serviceModeValue; } // =========================================== // ANNOTATION: BindingType // =========================================== public BindingType getAnnoBindingType() { if (bindingTypeAnnotation == null) { bindingTypeAnnotation = composite.getBindingTypeAnnot(); } return bindingTypeAnnotation; } public String getBindingType() { return getAnnoBindingTypeValue(); } public String getAnnoBindingTypeValue() { if (bindingTypeValue == null) { if (getAnnoBindingType() != null && !DescriptionUtils.isEmpty(getAnnoBindingType().value())) { bindingTypeValue = getAnnoBindingType().value(); } else { // No BindingType annotation present or value was empty; use default value bindingTypeValue = BindingType_DEFAULT; } } return bindingTypeValue; } // =========================================== // ANNOTATION: HandlerChain // =========================================== public void setHandlerChain(HandlerChainsType handlerChain) { handlerChainsType = handlerChain; } public HandlerChainsType getHandlerChain() { return getHandlerChain(null); } /** * Returns a schema derived java class containing the the handler configuration information. * That information, returned in the HandlerChainsType object, is looked for in the following * places in this order: * - Set on the sparseComposite for the given key * - Set on the composite * - Read in from the file specified on HandlerChain annotation * * @return HandlerChainsType This is the top-level element for the Handler configuration file * */ public HandlerChainsType getHandlerChain(Object sparseCompositeKey) { DescriptionBuilderComposite sparseComposite = null; // If there is a HandlerChainsType in the sparse composite for this ServiceDelegate // (i.e. this sparseCompositeKey), then return that. if (sparseCompositeKey != null) { sparseComposite = composite.getSparseComposite(sparseCompositeKey); if (sparseComposite != null && sparseComposite.getHandlerChainsType() != null) { HandlerChainsType hct = sparseComposite.getHandlerChainsType(); return hct; } } // If there is no HandlerChainsType in the composite, then read in the file specified // on the HandlerChain annotation if it is present. if (handlerChainsType == null) { getAnnoHandlerChainAnnotation(sparseCompositeKey); if (handlerChainAnnotation != null) { String handlerFileName = handlerChainAnnotation.file(); if (log.isDebugEnabled()) { log.debug(Messages.getMessage("handlerChainsTypeErr",handlerFileName,composite.getClassName())); } String className = composite.getClassName(); // REVIEW: This is using the classloader for EndpointDescriptionImpl; is that OK? ClassLoader classLoader = (composite.isServiceProvider()) ? composite.getClassLoader() : (ClassLoader) AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return this.getClass().getClassLoader(); } } ); if(log.isDebugEnabled()){ log.debug("Trying to load file " + handlerFileName + " relative to " + className); } InputStream is = DescriptionUtils.openHandlerConfigStream( handlerFileName, className, classLoader); if (is == null) { // config stream is still null. This may mean the @HandlerChain annotation is on a *driver* class // next to a @WebServiceRef annotation, so the path is relative to the class declaring @HandlerChain // and NOT relative to the Service or Endpoint class, which also means we should use the sparseComposite // since that is where the @HandlerChain annotation info would have been loaded. if (sparseComposite != null) { String handlerChainDeclaringClass = (String)sparseComposite.getProperties().get(MDQConstants.HANDLER_CHAIN_DECLARING_CLASS); if (handlerChainDeclaringClass != null) { className = handlerChainDeclaringClass; is = DescriptionUtils.openHandlerConfigStream(handlerFileName, className, classLoader); } } } if(is == null) { throw ExceptionFactory.makeWebServiceException(Messages.getMessage("handlerChainNS", handlerFileName, className)); } else { ClassLoader classLoader1 = (ClassLoader) AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return this.getClass().getClassLoader(); } } ); handlerChainsType = DescriptionUtils.loadHandlerChains(is, classLoader1); } } } return handlerChainsType; } public HandlerChain getAnnoHandlerChainAnnotation(Object sparseCompositeKey) { if (this.handlerChainAnnotation == null) { if (composite.isServiceProvider()) { /* * Per JSR-181 The @HandlerChain annotation MAY be present on * the endpoint interface and service implementation bean. The * service implementations bean's @HandlerChain is used if * @HandlerChain is present on both. So, if we do find the * annotation on this impl, then don't worry about else * Otherwise, check to see if the SEI might be annotated with * @HandlerChain */ handlerChainAnnotation = composite.getHandlerChainAnnot(); if (handlerChainAnnotation == null) { // If this is NOT an implicit SEI, then check for the // annotation on the SEI if (!DescriptionUtils.isEmpty(getAnnoWebServiceEndpointInterface())) { DescriptionBuilderComposite seic = getServiceDescriptionImpl().getDBCMap() .get(composite.getWebServiceAnnot().endpointInterface()); if (seic != null) { handlerChainAnnotation = seic.getHandlerChainAnnot(); } } } } else { handlerChainAnnotation = composite.getHandlerChainAnnot(); } } if (handlerChainAnnotation == null) { if (sparseCompositeKey != null) { DescriptionBuilderComposite sparseComposite = composite.getSparseComposite(sparseCompositeKey); if (sparseComposite != null && sparseComposite.getHandlerChainAnnot() != null) { handlerChainAnnotation = sparseComposite.getHandlerChainAnnot(); } } } return handlerChainAnnotation; } // =========================================== // ANNOTATION: MTOM // =========================================== /* * (non-Javadoc) * @see org.apache.axis2.jaxws.description.EndpointDescription#isMTOMEnabled() */ public boolean isMTOMEnabled() { if (isMTOMEnabledCache != null) { return isMTOMEnabledCache.booleanValue(); } // isMTOMEnabled is a combination of the @BindingType and the @MTOM setting. MTOM mtomAnnotation = (MTOM) getAnnoFeature(MTOMFeature.ID); // If the @MTOM annotation is set, it wins if (mtomAnnotation != null) { isMTOMEnabledCache = Boolean.valueOf(mtomAnnotation.enabled()); return isMTOMEnabledCache.booleanValue(); } // Else look at the bindingType String bindingType = getBindingType(); isMTOMEnabledCache = Boolean.valueOf(isMTOMBinding(bindingType)); return isMTOMEnabledCache.booleanValue(); } private static boolean isMTOMBinding(String url) { if (url != null && (url.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING) || url.equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING) || url.equals(MDQConstants.SOAP11JMS_MTOM_BINDING) || url.equals(MDQConstants.SOAP12JMS_MTOM_BINDING))) { return true; } return false; } // =========================================== // ANNOTATION: RespectBinding // =========================================== public boolean respectBinding() { return respectBinding; } public void setRespectBinding(boolean r) { respectBinding = r; } public boolean addRequiredBinding(WSDLValidatorElement element) { return requiredBindings.add(element); } public Set getRequiredBindings() { return requiredBindings; } /* * (non-Javadoc) * @see org.apache.axis2.jaxws.description.EndpointDescription#getMTOMThreshold() */ public int getMTOMThreshold() { if (axisService != null) { // We should cache this call here so we don't have to make // it on every pass through. Parameter mtomThreshold = axisService.getParameter(Configuration.MTOM_THRESHOLD); if (mtomThreshold != null) { return (Integer) mtomThreshold.getValue(); } } return -1; } // Get the specified WebServiceFeatureAnnotation public Annotation getAnnoFeature(String id) { return framework.getAnnotation(id); } //The WebServiceFeatures should be configued last so that any other //configuration can be overridden. Should only be called on the //server side. private void configureWebServiceFeatures() { if(log.isDebugEnabled()){ log.debug("Start configureWebServiceFeatures()."); } String bindingType = getBindingType(); Set ids = ServerConfiguratorRegistry.getIds(); for (String id : ids) { ServerConfigurator configurator = ServerConfiguratorRegistry.getConfigurator(id); if (configurator.supports(bindingType)) framework.addConfigurator(id, configurator); } // The feature instances are stored on the composite from either the // Java class or from something else building the list and setting it there. List features = composite.getWebServiceFeatures(); if (features != null && features.size() > 0) { // Add each of the annotation instances to the WebServiceFeature framework Iterator itr = features.iterator(); while (itr.hasNext()) { Annotation feature = (Annotation) itr.next(); framework.addAnnotation(feature); } // Kick off the configuration of the WebServiceFeature instances. framework.configure(this); } else { if (log.isDebugEnabled()) { log.debug("No WebServiceFeatureAnnotation instances were found on the composite."); } } if(log.isDebugEnabled()){ log.debug("Exit configureWebServiceFeatures()."); } } public Definition getWSDLDefinition() { return ((ServiceDescriptionWSDL)getServiceDescription()).getWSDLDefinition(); } public javax.wsdl.Service getWSDLService() { Definition defn = getWSDLDefinition(); if (defn != null) { return defn.getService(getServiceQName()); } else { return null; } } public Port getWSDLPort() { javax.wsdl.Service service = getWSDLService(); if (service != null) { return service.getPort(getPortQName().getLocalPart()); } else { return null; } } public Binding getWSDLBinding() { Binding wsdlBinding = null; Port wsdlPort = getWSDLPort(); Definition wsdlDef = getWSDLDefinition(); if (wsdlPort != null && wsdlDef != null) { wsdlBinding = wsdlPort.getBinding(); } return wsdlBinding; } public String getWSDLBindingType() { String wsdlBindingType = null; String soapTransport = null; Binding wsdlBinding = getWSDLBinding(); if (wsdlBinding != null) { // If a WSDL binding was found, we need to find the proper extensibility // element and return the namespace. The namespace for the binding element will // determine whether it is SOAP 1.1 vs. SOAP 1.2 vs. HTTP (or other). If the namespace // indicates SOAP we then need to determine what the transport is (HTTP vs. JMS) // TODO: What do we do if no extensibility element exists? List elements = wsdlBinding.getExtensibilityElements(); Iterator itr = elements.iterator(); while (itr.hasNext()) { ExtensibilityElement e = itr.next(); if (javax.wsdl.extensions.soap.SOAPBinding.class.isAssignableFrom(e.getClass())) { javax.wsdl.extensions.soap.SOAPBinding soapBnd = (javax.wsdl.extensions.soap.SOAPBinding)e; //representation: this is soap:binding = elementType where NamespaceURI is "soap" // The transport is represented by the 'transport' attribute within this binding element wsdlBindingType = soapBnd.getElementType().getNamespaceURI(); soapTransport = soapBnd.getTransportURI(); break; } else if (SOAP12Binding.class.isAssignableFrom(e.getClass())) { SOAP12Binding soapBnd = (SOAP12Binding)e; wsdlBindingType = soapBnd.getElementType().getNamespaceURI(); soapTransport = soapBnd.getTransportURI(); break; } else if (HTTPBinding.class.isAssignableFrom(e.getClass())) { HTTPBinding httpBnd = (HTTPBinding)e; wsdlBindingType = httpBnd.getElementType().getNamespaceURI(); break; } } // We need to convert the wsdl-based SOAP and HTTP namespace into the expected Binding Type for // HTTP or SOAPBindings with the appropriate transport (HTTP, JMS, etc.) // // Note that what we're actually returning is the WSDL binding type value conveted // to the corresponding SOAPBinding or HTTPBinding value. We are overwite the // wsdlBindingType with that converted JAXWS annotation binding type value and // return it. wsdlBindingType = DescriptionUtils.mapBindingTypeWsdlToAnnotation(wsdlBindingType, soapTransport); } return wsdlBindingType; } public String getName() { return getAnnoWebServiceName(); } public String getTargetNamespace() { return getAnnoWebServiceTargetNamespace(); } public PortInfo getPortInfo() { if (portInfo == null) { portInfo = new PortInfoImpl(getServiceQName(), getPortQName(), getBindingType()); } return portInfo; } public void setClientBindingID(String clientBindingID) { if (clientBindingID == null) { this.clientBindingID = DEFAULT_CLIENT_BINDING_ID; } else if (validateClientBindingID(clientBindingID)) { this.clientBindingID = clientBindingID; } else { throw ExceptionFactory.makeWebServiceException( Messages.getMessage("addPortErr0", getPortQName().toString())); } } private boolean validateClientBindingID(String bindingId) { boolean isValid = true; if (bindingId != null && !(bindingId.equals(SOAPBinding.SOAP11HTTP_BINDING) || bindingId.equals(javax.xml.ws.http.HTTPBinding.HTTP_BINDING) || bindingId.equals(SOAPBinding.SOAP12HTTP_BINDING) || bindingId.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING) || bindingId.equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING) || bindingId.equals(MDQConstants.SOAP11JMS_BINDING) || bindingId.equals(MDQConstants.SOAP12JMS_BINDING) || bindingId.equals(MDQConstants.SOAP11JMS_MTOM_BINDING) || bindingId.equals(MDQConstants.SOAP12JMS_MTOM_BINDING))) { throw ExceptionFactory.makeWebServiceException( Messages.getMessage("addPortErr0", getPortQName().toString())); } return isValid; } public String getClientBindingID() { if (clientBindingID == null) { if (getWSDLDefinition() != null) { clientBindingID = getWSDLBindingType(); if (clientBindingID == null) { clientBindingID = DEFAULT_CLIENT_BINDING_ID; } } else { clientBindingID = DEFAULT_CLIENT_BINDING_ID; } } return clientBindingID; } public void setEndpointAddress(String endpointAddress) { // REVIEW: Should this be called whenever BindingProvider.ENDPOINT_ADDRESS_PROPERTY is set by the client? if (!DescriptionUtils.isEmpty(endpointAddress)) { this.endpointAddress = endpointAddress; } else { // Since a port can be added without setting an endpoint address, this is not an error. if (log.isDebugEnabled()) log.debug("A null or empty endpoint address was attempted to be set", new Throwable("Stack Traceback")); } } public String getEndpointAddress() { if (endpointAddress == null) { // If the endpointAddress has not been set explicitly by a call to setEndpointAddress() // then try to get it from the WSDL endpointAddress = getWSDLSOAPAddress(); } return endpointAddress; } public void setProperty(String key, Object value) { if(properties == null) { properties = new HashMap(); } properties.put(key, value); } public Object getProperty(String key) { if(properties != null) { return properties.get(key); } return null; } /** * Return the SOAP Address from the WSDL for this port. * * @return The SOAP Address from the WSDL for this port or null. */ public String getWSDLSOAPAddress() { if (wsdlSOAPAddress == null) { Port wsdlPort = getWSDLPort(); if (wsdlPort != null) { // The port is in the WSDL, so see if it has a SOAP address extensibility element specified. List extElementList = wsdlPort.getExtensibilityElements(); for (Object listElement : extElementList) { ExtensibilityElement extElement = (ExtensibilityElement)listElement; if (isSOAPAddressElement(extElement)) { String soapAddress = getSOAPAddressFromElement(extElement); if (!DescriptionUtils.isEmpty(soapAddress)) { wsdlSOAPAddress = soapAddress; } } } } } return wsdlSOAPAddress; } /** * Determine if the WSDL Extensibility element corresponds to the SOAP Address element. * * @param exElement * @return */ static boolean isSOAPAddressElement(ExtensibilityElement exElement) { boolean isAddress = false; if (exElement != null) { isAddress = (SOAP_11_ADDRESS_ELEMENT.equals(exElement.getElementType()) || (SOAP_12_ADDRESS_ELEMENT.equals(exElement.getElementType()))); } return isAddress; } static String getSOAPAddressFromElement(ExtensibilityElement extElement) { String returnAddress = null; if (extElement != null) { if (SOAP_11_ADDRESS_ELEMENT.equals(extElement.getElementType())) { returnAddress = ((SOAPAddress)extElement).getLocationURI(); } else if (SOAP_12_ADDRESS_ELEMENT.equals(extElement.getElementType())) { returnAddress = ((SOAP12Address)extElement).getLocationURI(); } } return returnAddress; } /** * Selects a port to use in the case where a portQName was not specified by the client on the * Service.getPort(Class) call. If WSDL is present, then an appropriate port is looked for * under the service element, and an exception is thrown if none can be found. If WSDL is not * present, then the selected port is simply the one determined by annotations. * * @return A QName representing the port that is to be used. */ private QName selectPortToUse() { QName portToUse = null; // If WSDL Service for this port is present, then we'll find an appropriate port defined in there and set // the name accordingly. If no WSDL is present, the the PortQName getter will use annotations to set the value. if (getWSDLService() != null) { portToUse = selectWSDLPortToUse(); } else { // No WSDL, so the port to use is the one defined by the annotations. portToUse = getPortQName(); } return portToUse; } /** * Look through the WSDL Service for a port that should be used. If none can be found, then * throw an exception. * * @param wsdlService * @return A QName representing the port from the WSDL that should be used. */ private QName selectWSDLPortToUse() { QName wsdlPortToUse = null; // To select which WSDL Port to use, we do the following // 1) Find the subset of all ports under the service that use the PortType represented by the SEI // 2) From the subset in (1) find all those ports that specify a SOAP Address // 3) Use the first port from (2) // Per JSR-181, // - The portType name corresponds to the WebService.name annotation value, which is // returned by getName() // - The portType namespace corresponds to the WebService.targetNamespace annotation, which // is returned by getTargetNamespace() String portTypeLP = getName(); String portTypeTNS = getTargetNamespace(); QName portTypeQN = new QName(portTypeTNS, portTypeLP); ServiceDescriptionWSDL serviceDescWSDL = (ServiceDescriptionWSDL)getServiceDescription(); List wsdlPortsUsingPortType = serviceDescWSDL.getWSDLPortsUsingPortType(portTypeQN); List wsdlPortsUsingSOAPAddresses = serviceDescWSDL.getWSDLPortsUsingSOAPAddress(wsdlPortsUsingPortType); if (wsdlPortsUsingSOAPAddresses != null && !wsdlPortsUsingSOAPAddresses.isEmpty()) { // We return the first port that uses the particluar PortType and has a SOAP address. // HOWEVER, that is not necessarily the first one in the WSDL that meets that criteria! // The problem is that WSDL4J Service.getPorts(), which is used to get a Map of ports under the service // DOES NOT return the ports in the order they are defined in the WSDL. // Therefore, we can't necessarily predict which one we'll get back as the "first" one in the collection. // REVIEW: Note the above comment; is there anything more predictible and determinstic we can do? Port portToUse = (Port)wsdlPortsUsingSOAPAddresses.toArray()[0]; String portLocalPart = portToUse.getName(); String portNamespace = serviceDescWSDL.getWSDLService().getQName().getNamespaceURI(); wsdlPortToUse = new QName(portNamespace, portLocalPart); } return wsdlPortToUse; } private WsdlComposite generateWSDL(DescriptionBuilderComposite dbc) { WsdlComposite wsdlComposite = null; Definition defn = dbc.getWsdlDefinition(getServiceQName()); if(defn == null) { defn = dbc.getWsdlDefinition(); } if (defn == null || !isAxisServiceBuiltFromWSDL) { //Invoke the callback for generating the wsdl if (dbc.getCustomWsdlGenerator() != null) { String implName = null; if (axisService == null) { implName = DescriptionUtils.javifyClassName(composite.getClassName()); } else { implName = (String)axisService.getParameterValue(MDQConstants.SERVICE_CLASS); } wsdlComposite = dbc.getCustomWsdlGenerator().generateWsdl(implName, this); if (wsdlComposite != null) { if(wsdlComposite.getWsdlFileName() == null || "".equals(wsdlComposite.getWsdlFileName())) { wsdlComposite.setWsdlFileName( (this.getAnnoWebServiceServiceName() + ".wsdl").toLowerCase()); } Definition wsdlDef = wsdlComposite.getRootWsdlDefinition(); try { ConfigurationContext cc = dbc.getConfigurationContext(); WSDL4JWrapper wsdl4jWrapper = null; if (cc != null) { wsdl4jWrapper = new WSDL4JWrapper(dbc.getWsdlURL(), wsdlDef, cc); } else { wsdl4jWrapper = new WSDL4JWrapper(dbc.getWsdlURL(), wsdlDef, true, 2); } getServiceDescriptionImpl().setGeneratedWsdlWrapper(wsdl4jWrapper); } catch (Exception e) { throw ExceptionFactory.makeWebServiceException(Messages.getMessage("generateWSDLErr"),e); } } else { // REVIEW:Determine if we should always throw an exception on this, or at this point //throw ExceptionFactory.makeWebServiceException("EndpointDescriptionImpl: Unable to find custom WSDL generator"); if (log.isDebugEnabled()) { log.debug( "The custom WSDL generator returned null, so no generated WSDL is available"); } } } else { // REVIEW: This used to throw an exception, but it seems we shouldn't require // a wsdl generator be provided. // throw ExceptionFactory.makeWebServiceException("EndpointDescriptionImpl: Unable to find custom WSDL generator"); if (log.isDebugEnabled()) { log.debug( "No custom WSDL generator was supplied, so WSDL can not be generated"); } } } return wsdlComposite; } List getCustomAnnotationInstances() { return customAnnotations; } CustomAnnotationProcessor getCustomAnnotationProcessor(String annotationInstanceClassName) { return customAnnotationProcessors != null ? customAnnotationProcessors.get(annotationInstanceClassName) : null; } public DescriptionBuilderComposite getDescriptionBuilderComposite() { return composite; } public String toString() { final String newline = "\n"; final String sameline = "; "; StringBuffer string = new StringBuffer(); try { string.append(super.toString()); string.append(newline); string.append("Name: " + getName()); string.append(sameline); string.append("Endpoint Address: " + getEndpointAddress()); // string.append(newline); string.append("ServiceQName: " + getServiceQName()); string.append(sameline); string.append("PortQName: " + getPortQName()); string.append(sameline); string.append("TargetNamespace: " + getTargetNamespace()); // string.append(newline); string.append("Service Mode: " + getServiceMode()); string.append(sameline); string.append("Binding Type: " + getBindingType()); string.append(sameline); string.append("Client Binding Type: " + getClientBindingID()); // string.append(newline); string.append("Is provider-based: " + (isProviderBased() == true)); string.append(sameline); string.append("Is proxy-based: " + (isEndpointBased() == true)); string.append(sameline); string.append("Is WSDL fully specified: " + (isWSDLFullySpecified() == true)); // string.append(newline); string.append("AxisService: " + getAxisService()); // string.append(newline); EndpointInterfaceDescription endpointInterfaceDesc = getEndpointInterfaceDescription(); if (endpointInterfaceDesc != null) { string.append("EndpointInterfaceDescription: " + endpointInterfaceDesc.toString()); } else { string.append("EndpointInterfaceDescription is null."); } } catch (Throwable t) { string.append(newline); string.append("Complete debug information not currently available for " + "EndpointDescription"); return string.toString(); } return string.toString(); } /** * Get an annotation. This is wrappered to avoid a Java2Security violation. * @param cls Class that contains annotation * @param annotation Class of requrested Annotation * @return annotation or null */ private static Annotation getAnnotation(final Class cls, final Class annotation) { return (Annotation) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { return cls.getAnnotation(annotation); } }); } /** * Return the class for this name * * @return Class */ private static Class forName(final String className, final boolean initialize, final ClassLoader classloader) throws ClassNotFoundException { Class cl = null; try { cl = (Class) AccessController.doPrivileged( new PrivilegedExceptionAction() { public Object run() throws ClassNotFoundException { return Class.forName(className, initialize, classloader); } } ); } catch (PrivilegedActionException e) { if (log.isDebugEnabled()) { log.debug("Exception thrown from AccessController: " + e.getMessage(), e); } throw (ClassNotFoundException) e.getException(); } return cl; } private static ClassLoader getContextClassLoader(final ClassLoader classLoader) { ClassLoader cl; try { cl = (ClassLoader) AccessController.doPrivileged( new PrivilegedExceptionAction() { public Object run() throws ClassNotFoundException { return classLoader != null ? classLoader : Thread.currentThread().getContextClassLoader(); } } ); } catch (PrivilegedActionException e) { if (log.isDebugEnabled()) { log.debug("Exception thrown from AccessController: " + e.getMessage(), e); } throw ExceptionFactory.makeWebServiceException(e.getException()); } return cl; } /** * This will update or set the parameter on the AxisService that represents the * value of the @WebService.name attribute. This is needed since the @WebService.name * value may not be known until the EndpointInterfaceDescription is created for * the explicitly defined SEI. */ void updateWebServiceNameParameter(String newName, AxisService service) { if(log.isDebugEnabled()) { log.debug("Setting @WebService.name value on the " + service.getName() + " AxisService to: " + newName); } Parameter param = service.getParameter(MDQConstants.WSDL_PORTTYPE_NAME); if(param != null) { param.setValue(newName); } else { param = new Parameter(); param.setName(MDQConstants.WSDL_PORTTYPE_NAME); param.setValue(newName); try { service.addParameter(param); } catch (AxisFault e) { throw ExceptionFactory.makeWebServiceException(Messages.getMessage("setupAxisServiceErr2"),e); } } } private static long currentUniqueID = 0; private long uniqueID() { if (currentUniqueID == 0) { currentUniqueID = System.currentTimeMillis(); } return currentUniqueID++; } /** * Release the AxisService objects associated with this EndpointDescription. Note that * this should only be called by the ServiceDescription that owns this EndpointDescrition. * * @param configurationContext The Axis2 ConfigurationContext holding the AxisConfiguration * from which the AxisServices should be removed. */ void releaseResources(ConfigurationContext configurationContext) { if (configurationContext != null) { AxisConfiguration axisConfig = configurationContext.getAxisConfiguration(); AxisService axisService = getAxisService(); AxisServiceGroup axisServiceGroup = axisService.getAxisServiceGroup(); try { axisConfig.removeServiceGroup(axisServiceGroup.getServiceGroupName()); } catch (AxisFault e) { if (log.isDebugEnabled()) { log.debug("EndpointDescriptionImpl release resources caught exception which it is ignoring", e); } } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy