Package org.apache.axis2.jaxws.description.impl

Source Code of org.apache.axis2.jaxws.description.impl.ServiceDescriptionImpl

/*
* Copyright 2004,2005 The Apache Software Foundation.
* Copyright 2006 International Business Machines Corp.
*
* Licensed 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 java.io.FileNotFoundException;
import java.net.ConnectException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.wsdl.Definition;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.xml.namespace.QName;
import javax.xml.ws.soap.SOAPBinding;

import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.jaxws.ClientConfigurationFactory;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.description.DescriptionFactory;
import org.apache.axis2.jaxws.description.EndpointDescription;
import org.apache.axis2.jaxws.description.EndpointInterfaceDescription;
import org.apache.axis2.jaxws.description.ServiceDescription;
import org.apache.axis2.jaxws.description.ServiceDescriptionJava;
import org.apache.axis2.jaxws.description.ServiceDescriptionWSDL;
import org.apache.axis2.jaxws.description.ServiceRuntimeDescription;
import org.apache.axis2.jaxws.description.builder.DescriptionBuilderComposite;
import org.apache.axis2.jaxws.description.builder.MDQConstants;
import org.apache.axis2.jaxws.description.builder.MethodDescriptionComposite;
import org.apache.axis2.jaxws.description.builder.ParameterDescriptionComposite;
import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.axis2.jaxws.util.WSDL4JWrapper;
import org.apache.axis2.jaxws.util.WSDLWrapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* @see ../ServiceDescription
*/
class ServiceDescriptionImpl implements ServiceDescription, ServiceDescriptionWSDL, ServiceDescriptionJava {
    private ClientConfigurationFactory clientConfigFactory;
    private ConfigurationContext configContext;

    private URL wsdlURL;
    private QName serviceQName;
   
    // Only ONE of the following will be set in a ServiceDescription, depending on whether this Description
    // was created from a service-requester or service-provider flow.
    private Class serviceClass;         // A service-requester generated service or generic service class
   
    // TODO: Possibly remove Definition and delegate to the Defn on the AxisSerivce set as a paramater by WSDLtoAxisServicBuilder?
    private WSDLWrapper wsdlWrapper;
    private WSDLWrapper generatedWsdlWrapper;
   
    private Hashtable<QName, EndpointDescriptionImpl> endpointDescriptions = new Hashtable<QName, EndpointDescriptionImpl>();
   
    private static final Log log = LogFactory.getLog(ServiceDescriptionImpl.class);

    private HashMap<String, DescriptionBuilderComposite> dbcMap = null;
   
    private DescriptionBuilderComposite  composite = null;
    private boolean isServerSide = false;
   
//  RUNTIME INFORMATION
    Map<String, ServiceRuntimeDescription> runtimeDescMap = Collections.synchronizedMap(new HashMap<String, ServiceRuntimeDescription>());

   
    /**
     * This is (currently) the client-side-only constructor
     * Construct a service description hierachy based on WSDL (may be null), the Service class, and
     * a service QName.
     *
     * @param wsdlURL  The WSDL file (this may be null).
     * @param serviceQName  The name of the service in the WSDL.  This can not be null since a
     *   javax.xml.ws.Service can not be created with a null service QName.
     * @param serviceClass  The JAX-WS service class.  This could be an instance of
     *   javax.xml.ws.Service or a generated service subclass thereof.  This will not be null.
     */
    ServiceDescriptionImpl(URL wsdlURL, QName serviceQName, Class serviceClass) {
        if (serviceQName == null) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("serviceDescErr0"));
        }
        if (serviceClass == null) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("serviceDescErr1", "null"));
        }
        if (!javax.xml.ws.Service.class.isAssignableFrom(serviceClass)) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("serviceDescErr1", serviceClass.getName()));
        }
       
        // TODO: On the client side, we should not support partial WSDL; i.e. if the WSDL is specified it must be
        //       complete and must contain the ServiceQName.  This is how the Sun RI behaves on the client.
        //       When this is fixed, the check in ServiceDelegate(URL, QName, Class) should be removed
        this.wsdlURL = wsdlURL;
        // TODO: The serviceQName needs to be verified between the argument/WSDL/Annotation
        this.serviceQName = serviceQName;
        this.serviceClass = serviceClass;
       
        setupWsdlDefinition();
    }

    /**
     * This is (currently) the service-provider-side-only constructor.
     * Create a service Description based on a service implementation class
     *
     * @param serviceImplClass
     */
    ServiceDescriptionImpl(Class serviceImplClass, AxisService axisService) {
        // Create the EndpointDescription hierachy from the service impl annotations; Since the PortQName is null,
        // it will be set to the annotation value.
        EndpointDescriptionImpl endpointDescription = new EndpointDescriptionImpl(serviceImplClass, null, axisService, this);
        addEndpointDescription(endpointDescription);
       
        // TODO: The ServiceQName instance variable should be set based on annotation or default
    }

    /**
     * This is (currently) the service-provider-side-only constructor.
     * Create a service Description based on a service implementation class
     *
     * @param serviceImplClass
     */
    ServiceDescriptionImpl
        HashMap<String, DescriptionBuilderComposite> dbcMap,
        DescriptionBuilderComposite composite ) {
      this.composite = composite;
     
      String serviceImplName = this.composite.getClassName();
     
      this.dbcMap = dbcMap;
//TODO: How to we get this when called from server side, create here for now
      this.isServerSide = true;
 
      //capture the WSDL, if there is any...to be used for later processing
      setupWsdlDefinition();
     
    // Do a first pass validation for this DescriptionBuilderComposite.
      // This is not intended to be a full integrity check, but rather a fail-fast mechanism
        // TODO: Refactor this to a seperate validator class?
      validateDBCLIntegrity();
     
        // The ServiceQName instance variable is set based on annotation or default
        // It will be set by the EndpointDescriptionImpl since it is the one that knows
        // how to process the annotations and the defaults.
        //TODO: When we get this, need to consider verifying service name between WSDL
        //      and annotations, so

        // Create the EndpointDescription hierachy from the service impl annotations; Since the PortQName is null,
        // it will be set to the annotation value.
        //EndpointDescription endpointDescription = new EndpointDescription(null, this, serviceImplName);
        EndpointDescriptionImpl endpointDescription = new EndpointDescriptionImpl(this, serviceImplName);
        addEndpointDescription(endpointDescription);      
    }
   
    /*=======================================================================*/
    /*=======================================================================*/
    // START of public accessor methods
   
    /**
     * Update or create an EndpointDescription. Updates to existing
     * EndpointDescriptons will be based on the SEI class and its annotations.  Both declared
     * ports and dynamic ports can be updated.  A declared port is one that is defined (e.g. in WSDL or
     * via annotations); a dyamic port is one that is not defined (e.g. not via WSDL or annotations) and
     * has been added via Serivce.addPort. 
     *
     * Notes on how an EndpointDescription can be updated or created:
     * 1) Service.createDispatch can create a Dispatch client for either a declared or dynamic port
     * 2) Note that creating a Dispatch does not associate an SEI with an endpoint
     * 3) Service.getPort will associate an SEI with a port
     * 4) A getPort on an endpoint which was originally created for a Distpatch will update that
     *    EndpointDescription with the SEI provided on the getPort
     * 5) Service.getPort can not be called on a dynamic port (per the JAX-WS spec)
     * 6) Service.addPort can not be called for a declared port
     *
     * @param sei
     *            This will be non-null if the update is of type GET_PORT; it
     *            will be null if the update is ADD_PORT or CREATE_DISPATCH
     * @param portQName
     * @param updateType
     *            Indicates what is causing the update GET_PORT is an attempt to
     *            get a declared SEI-based port ADD_PORT is an attempt to add a
     *            previously non-existent dynamic port CREATE_DISPATCH is an
     *            attempt to create a Dispatch-based client to either a declared
     *            port or a pre-existing dynamic port.
     */

    EndpointDescription updateEndpointDescription(Class sei, QName portQName, DescriptionFactory.UpdateType updateType) {
       
        EndpointDescriptionImpl endpointDescription = getEndpointDescriptionImpl(portQName);
        boolean isPortDeclared = isPortDeclared(portQName);

        switch (updateType) {

        case ADD_PORT:
            // Port must NOT be declared (e.g. can not already exist in WSDL)
            // If an EndpointDesc doesn't exist; create it as long as it doesn't exist in the WSDL
            // TODO: This test can be simplified once isPortDeclared(QName) understands annotations and WSDL as ways to declare a port.
            if (DescriptionUtils.isEmpty(portQName)) {
                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("addPortErr2"));
            }
            if (getWSDLWrapper() != null && isPortDeclared) {
                // TODO: RAS & NLS
                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("addPortDup", portQName.toString()));
            }
            else if (endpointDescription == null) {
                // Use the SEI Class and its annotations to finish creating the Description hierachy.  Note that EndpointInterface, Operations, Parameters, etc.
                // are not created for dynamic ports.  It would be an error to later do a getPort against a dynamic port (per the JAX-WS spec)
                endpointDescription = new EndpointDescriptionImpl(sei, portQName, true, this);
                addEndpointDescription(endpointDescription);
            }
            else {
                // All error check above passed, the EndpointDescription already exists and needs no updating
            }
            break;

        case GET_PORT:
            // If an endpointDesc doesn't exist, and the port exists in the WSDL, create it
            // If an endpointDesc already exists and has an associated SEI already, make sure they match
            // If an endpointDesc already exists and was created for Dispatch (no SEI), update that with the SEI provided on the getPort

            // Port must be declared (e.g. in WSDL or via annotations)
            // TODO: Once isPortDeclared understands annotations and not just WSDL, the 2nd part of this check can possibly be removed.
            //       Although consider the check below that updates an existing EndpointDescritpion with an SEI.
            if (!isPortDeclared || (endpointDescription != null && endpointDescription.isDynamicPort())) {
                // This guards against the case where an addPort was done previously and now a getPort is done on it.
                // TODO: RAS & NLS
                throw ExceptionFactory.makeWebServiceException("ServiceDescription.updateEndpointDescription: Can not do a getPort on a port added via addPort().  PortQN: " +
                        portQName != null ? portQName.toString() : "not specified");
            }
            else if (sei == null) {
                // TODO: RAS & NLS
                throw ExceptionFactory.makeWebServiceException("ServiceDescription.updateEndpointDescription: Can not do a getPort with a null SEI.  PortQN: " +
                        portQName != null ? portQName.toString() : "not specified");
            }
            else if (endpointDescription == null) {
                // Use the SEI Class and its annotations to finish creating the Description hierachy: Endpoint, EndpointInterface, Operations, Parameters, etc.
                // TODO: Need to create the Axis Description objects after we have all the config info (i.e. from this SEI)
                endpointDescription = new EndpointDescriptionImpl(sei, portQName, this);
                addEndpointDescription(endpointDescription);
            }
            else if (getEndpointSEI(portQName) == null && !endpointDescription.isDynamicPort()) {
                // Existing endpointDesc from a declared port needs to be updated with an SEI
                // Note that an EndpointDescritption created from an addPort (i.e. a dynamic port) can not do this.
                endpointDescription.updateWithSEI(sei);
            }
            else if (getEndpointSEI(portQName) != sei) {
                // TODO: RAS & NLS
                throw ExceptionFactory.makeWebServiceException("ServiceDescription.updateEndpointDescription: Can't do a getPort() specifiying a different SEI than the previous getPort().  PortQN: "
                        + portQName + "; current SEI: " + sei + "; previous SEI: " + getEndpointSEI(portQName));
            }
            else {
                // All error check above passed, the EndpointDescription already exists and needs no updating
            }
            break;

        case CREATE_DISPATCH:
            // Port may or may not exist in WSDL. 
            // If an endpointDesc doesn't exist and it is in the WSDL, it can be created
            // Otherwise, it is an error.
            if (DescriptionUtils.isEmpty(portQName)) {
                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("createDispatchFail0"));
            }
            else if (endpointDescription != null) {
                // The EndpoingDescription already exists; nothing needs to be done
            }
            else if (sei != null) {
                // The Dispatch should not have an SEI associated with it on the update call.
                // REVIEW: Is this a valid check?
                throw ExceptionFactory.makeWebServiceException("ServiceDescription.updateEndpointDescription: Can not specify an SEI when creating a Dispatch. PortQN: " + portQName);
            }
            else if (getWSDLWrapper() != null && isPortDeclared) {
                // EndpointDescription doesn't exist and this is a declared Port, so create one
                // Use the SEI Class and its annotations to finish creating the Description hierachy.  Note that EndpointInterface, Operations, Parameters, etc.
                // are not created for Dipsatch-based ports, but might be updated later if a getPort is done against the same declared port.
                // TODO: Need to create the Axis Description objects after we have all the config info (i.e. from this SEI)
                endpointDescription = new EndpointDescriptionImpl(sei, portQName, this);
                addEndpointDescription(endpointDescription);
            }
            else {
                // The port is not a declared port and it does not have an EndpointDescription, meaning an addPort has not been done for it
                // This is an error.
                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("createDispatchFail1", portQName.toString()));
            }
            break;
        }
        return endpointDescription;
    }

    private Class getEndpointSEI(QName portQName) {
        Class endpointSEI = null;
        EndpointInterfaceDescription endpointInterfaceDesc = getEndpointDescription(portQName).getEndpointInterfaceDescription();
        if (endpointInterfaceDesc != null ) {
            endpointSEI = endpointInterfaceDesc.getSEIClass();
        }
        return endpointSEI;
    }

    private boolean isPortDeclared(QName portQName) {
        // TODO: This needs to account for declaration of the port via annotations in addition to just WSDL
        // TODO: Add logic to check the portQN namespace against the WSDL Definition NS
        boolean portIsDeclared = false;
        if (!DescriptionUtils.isEmpty(portQName)) {
            if (getWSDLWrapper() != null) {
                Definition wsdlDefn = getWSDLWrapper().getDefinition();
                Service wsdlService = wsdlDefn.getService(serviceQName);
                Port wsdlPort = wsdlService.getPort(portQName.getLocalPart());
                portIsDeclared = (wsdlPort != null);
            }
            else {
                // TODO: Add logic to determine if port is declared via annotations when no WSDL is present.  For now, we have to assume it is declared
                // so getPort(...) and createDispatch(...) calls work when there is no WSDL.
                portIsDeclared = true;
            }
        }
        else {
            // PortQName is null, so the runtime gets to choose which one to use.  Since there's no WSDL
            // we'll use annotations, so it is implicitly declared
            portIsDeclared = true;
        }
        return portIsDeclared;
    }
   
    /* (non-Javadoc)
     * @see org.apache.axis2.jaxws.description.ServiceDescription#getEndpointDescriptions()
     */
    public EndpointDescription[] getEndpointDescriptions() {
        return endpointDescriptions.values().toArray(new EndpointDescriptionImpl[0]);
    }
   
    /* (non-Javadoc)
     * @see org.apache.axis2.jaxws.description.ServiceDescription#getEndpointDescription(javax.xml.namespace.QName)
     */
    public EndpointDescription getEndpointDescription(QName portQName) {
        EndpointDescription returnDesc = null;
        if (!DescriptionUtils.isEmpty(portQName)) {
            returnDesc = endpointDescriptions.get(portQName);
        }
        return returnDesc;
    }
   
    EndpointDescriptionImpl getEndpointDescriptionImpl(QName portQName) {
        return (EndpointDescriptionImpl) getEndpointDescription(portQName);
    }
   
    DescriptionBuilderComposite getDescriptionBuilderComposite() {
      return composite;
    }

    /* (non-Javadoc)
     * @see org.apache.axis2.jaxws.description.ServiceDescription#getEndpointDescription(java.lang.Class)
     */
    public EndpointDescription[] getEndpointDescription(Class seiClass) {
        EndpointDescription[] returnEndpointDesc = null;
        ArrayList<EndpointDescriptionImpl> matchingEndpoints = new ArrayList<EndpointDescriptionImpl>();
        Enumeration<EndpointDescriptionImpl> endpointEnumeration = endpointDescriptions.elements();
        while (endpointEnumeration.hasMoreElements()) {
            EndpointDescriptionImpl endpointDescription = endpointEnumeration.nextElement();
            EndpointInterfaceDescription endpointInterfaceDesc = endpointDescription.getEndpointInterfaceDescription();
            // Note that Dispatch endpoints will not have an endpointInterface because the do not have an associated SEI
            if (endpointInterfaceDesc != null) {
                Class endpointSEIClass = endpointInterfaceDesc.getSEIClass();
                if (endpointSEIClass != null && endpointSEIClass.equals(seiClass)) {
                    matchingEndpoints.add(endpointDescription);
                }
            }
        }
        if (matchingEndpoints.size() > 0) {
            returnEndpointDesc = matchingEndpoints.toArray(new EndpointDescriptionImpl[0]);
        }
        return returnEndpointDesc;
    }
   
    /*
     * @return True - if we are processing with the DBC List instead of reflection
     */
    boolean isDBCMap() {
      if (dbcMap == null)
        return false;
      else
        return true;
    }
   
    // END of public accessor methods
    /*=======================================================================*/
    /*=======================================================================*/
    private void addEndpointDescription(EndpointDescriptionImpl endpoint) {
        endpointDescriptions.put(endpoint.getPortQName(), endpoint);
    }

    private void setupWsdlDefinition() {
        // Note that there may be no WSDL provided, for example when called from
        // Service.create(QName serviceName).
     
      if (isDBCMap()) {

        //  Currently, there is a bug which allows the wsdlDefinition to be placed
        //  on either the impl class composite or the sei composite, or both. We need to
        //  look in both places and find the correct one, if it exists.

          if (((composite.getWebServiceAnnot() != null) &&
                DescriptionUtils.isEmpty(composite.getWebServiceAnnot().endpointInterface()))                       
                     ||
                (!(composite.getWebServiceProviderAnnot() == null))) {
              //This is either an implicit SEI, or a WebService Provider
              if (composite.getWsdlDefinition() != null) {
                  this.wsdlURL = composite.getWsdlURL();
                 
                  try {
                      this.wsdlWrapper = new WSDL4JWrapper(this.wsdlURL,
                              composite.getWsdlDefinition());
                  } catch (WSDLException e) {
                      throw ExceptionFactory.makeWebServiceException(Messages.getMessage("wsdlException", e.getMessage()), e);
                  }
              }
             
          } else if (composite.getWebServiceAnnot() != null) {
              //This impl class specifies an SEI...this is a special case. There is a bug
              //in the tooling that allows for the wsdllocation to be specifed on either the
              //impl. class, or the SEI, or both. So, we need to look for the wsdl as follows:
              //          1. If the Wsdl exists on the SEI, then check for it on the impl.
              //          2. If it is not found in either location, in that order, then generate
             
              DescriptionBuilderComposite seic =
                  getDBCMap().get(composite.getWebServiceAnnot().endpointInterface());
             
              try {
                  if (seic.getWsdlDefinition() != null) {
                      //set the sdimpl from the SEI composite
                      this.wsdlURL = seic.getWsdlURL();
                      this.wsdlWrapper = new WSDL4JWrapper(seic.getWsdlURL(), seic.getWsdlDefinition());
                  } else if (composite.getWsdlDefinition() != null) {
                      //set the sdimpl from the impl. class composite
                      this.wsdlURL = composite.getWsdlURL();
                      this.wsdlWrapper = new WSDL4JWrapper(composite.getWsdlURL(), composite.getWsdlDefinition());
                  }
              } catch (WSDLException e) {
                  throw ExceptionFactory.makeWebServiceException(Messages.getMessage("wsdlException", e.getMessage()), e);
              }
          }          
         
        //Deprecate this code block when MDQ is fully integrated
      } else if (wsdlURL != null) {
            try {
                this.wsdlWrapper = new WSDL4JWrapper(this.wsdlURL);
            }
            catch(FileNotFoundException e) {
              throw ExceptionFactory.makeWebServiceException(Messages.getMessage("wsdlNotFoundErr", e.getMessage()), e);
            }
            catch(UnknownHostException e) {
              throw ExceptionFactory.makeWebServiceException(Messages.getMessage("unknownHost", e.getMessage()), e);
            }
            catch(ConnectException e) {
              throw ExceptionFactory.makeWebServiceException(Messages.getMessage("connectionRefused", e.getMessage()), e);
            }
            catch (WSDLException e) {
                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("wsdlException", e.getMessage()), e);
            }
        }
    }

    // TODO: Remove these and replace with appropraite get* methods for WSDL information
    /* (non-Javadoc)
     * @see org.apache.axis2.jaxws.description.ServiceDescriptionWSDL#getWSDLWrapper()
     */
    public WSDLWrapper getWSDLWrapper() {
        return wsdlWrapper;
    }
   
    /* (non-Javadoc)
     * @see org.apache.axis2.jaxws.description.ServiceDescriptionWSDL#getWSDLLocation()
     */
    public URL getWSDLLocation() {
        return wsdlURL;
    }

    /**
     * TODO: This method should be replaced with specific methods for getWSDLGenerated... similar
     * to how getWsdlWrapper should be replaced.
     */
    public WSDLWrapper getGeneratedWsdlWrapper() {
      return this.generatedWsdlWrapper;
    }
   
    /* (non-Javadoc)
     * @see org.apache.axis2.jaxws.description.ServiceDescription#getAxisConfigContext()
     */
    public ConfigurationContext getAxisConfigContext() {
        if (configContext == null) {
            configContext = getClientConfigurationFactory().getClientConfigurationContext();
        }
      return configContext;
     
    }
   
    ClientConfigurationFactory getClientConfigurationFactory() {
       
        if (clientConfigFactory == null ) {
            clientConfigFactory = ClientConfigurationFactory.newInstance();
        }
        return clientConfigFactory;
    }
   
    /* (non-Javadoc)
     * @see org.apache.axis2.jaxws.description.ServiceDescription#getServiceClient(javax.xml.namespace.QName)
     */
    public ServiceClient getServiceClient(QName portQName) {
        // TODO: RAS if no portQName found
        return getEndpointDescription(portQName).getServiceClient();
    }
   
    /* (non-Javadoc)
     * @see org.apache.axis2.jaxws.description.ServiceDescription#getServiceQName()
     */
    public QName getServiceQName() {
      //It is assumed that this will always be set in the constructor rather than
      //built up from the class or DBC
        return serviceQName;
    }
    void setServiceQName(QName theName) {
        serviceQName = theName;
    }


    boolean isServerSide() {
     return isServerSide;
    }

    HashMap<String, DescriptionBuilderComposite> getDBCMap() {
      return dbcMap;
    }
   
    void setGeneratedWsdlWrapper(WSDL4JWrapper wrapper) {
      this.generatedWsdlWrapper = wrapper;
    }
   
    void setWsdlWrapper(WSDL4JWrapper wrapper) {
      this.wsdlWrapper = wrapper;
    }
   
  private void validateDBCLIntegrity() {
   
    //First, check the integrity of this input composite
    //and retrieve
    //the composite that represents this impl
   
//TODO: Currently, we are calling this method on the DBC. However, the DBC
//will eventually need access to to the whole DBC map to do proper validation.
//We don't want to pass the map of DBC's back into a single DBC.
//So, for starters, this method and all the privates that it calls should be
// moved to here. At some point, we should consider using a new class that we
//can implement scenarios of, like validateServiceImpl implements validator
   
    try {
      validateIntegrity();
    }
    catch (Exception ex) {
            if (log.isDebugEnabled()) {
                log.debug("Validation phase 1 failure: " + ex.toString(), ex);
                log.debug("Failing composite: " + composite.toString());
            }
            throw ExceptionFactory.makeWebServiceException("Validation Exception " + ex, ex);
    }
  }

  /*
   * Validates the integrity of an impl. class. This should not be called directly for an SEI composite
   */
  void validateIntegrity() {
    //TODO: Consider moving this to a utils area, do we really want a public
    //      method that checks integrity...possibly
   
    //In General, this integrity checker should do gross level checking
    //It should not be setting spec-defined default values, but can look
    //at things like empty strings or null values
   
    //TODO: This method will validate the integrity of this object. Basically, if
    //consumer set this up improperly, then we should fail fast, should consider placing
    //this method in a utils class within the 'description' package

        //Verify that, if this implements a strongly typed provider interface, that it
        // also contain a WebServiceProvider annotation per JAXWS Sec. 5.1
        Iterator<String> iter =
                    composite.getInterfacesList().iterator();

        // Remember if we've validated the Provider interface.  Later we'll make sure that if we have an
        // WebServiceProvider annotation, we found a valid interface here.
        boolean providerInterfaceValid = false;
        while (iter.hasNext()) {
            String interfaceString = iter.next();
            if (interfaceString.equals(MDQConstants.PROVIDER_SOURCE)
                    || interfaceString.equals(MDQConstants.PROVIDER_SOAP)
                    || interfaceString.equals(MDQConstants.PROVIDER_DATASOURCE)
                    || interfaceString.equals(MDQConstants.PROVIDER_STRING)) {
                providerInterfaceValid = true;
                //This is a provider based endpoint, make sure the annotation exists
                if (composite.getWebServiceProviderAnnot() == null) {
                    // TODO: RAS/NLS
                    throw ExceptionFactory.makeWebServiceException("Validation error: This is a Provider based endpoint that does not contain a WebServiceProvider annotation.  Provider class: " + composite.getClassName());
                }
            }
        }
                   

   
    //Verify that WebService and WebServiceProvider are not both specified
    //per JAXWS - Sec. 7.7
    if (composite.getWebServiceAnnot() != null && composite.getWebServiceProviderAnnot() != null) {
            // TODO: RAS/NLS
      throw ExceptionFactory.makeWebServiceException("Validation error: WebService annotation and WebServiceProvider annotation cannot coexist.  Implementation class: " + composite.getClassName());
    }
   
    if (composite.getWebServiceProviderAnnot() != null ) {
            if (!providerInterfaceValid) {
                // TODO: RAS/NLS
                throw ExceptionFactory.makeWebServiceException("Validation error: This is a Provider that does not specify a valid Provider interface.   Implementation class: " + composite.getClassName());
            }
            // There must be a public default constructor per JAXWS - Sec 5.1
            if (!validateDefaultConstructor()) {
                // TODO: RAS/NLS
                throw ExceptionFactory.makeWebServiceException("Validation error: Provider must have a public default constructor.  Implementation class: " + composite.getClassName());
            }
            // There must be an invoke method per JAXWS - Sec 5.1.1
            if (!validateInvokeMethod()) {
                // TODO: RAS/NLS
                throw ExceptionFactory.makeWebServiceException("Validation error: Provider must have a public invoke method.  Implementation class: " + composite.getClassName());
            }
           
            //If ServiceMode annotation specifies 'payload', then make sure that it is not typed with
            // SOAPMessage or DataSource
            validateProviderInterfaces();

    } else if (composite.getWebServiceAnnot() != null) {
     
      if ( composite.getServiceModeAnnot() != null) {
                // TODO: RAS/NLS
        throw ExceptionFactory.makeWebServiceException("Validation error: ServiceMode annotation can only be specified for WebServiceProvider.   Implementation class: " + composite.getClassName());
      }
     
      //TODO: hmmm, will we ever actually validate an interface directly...don't think so
      if (!composite.isInterface()) {
        // TODO: Validate on the class that this.classModifiers Array does not contain the strings
        //        FINAL or ABSTRACT, but does contain PUBLIC
        // TODO: Validate on the class that a public constructor exists
        // TODO: Validate on the class that a finalize() method does not exist
        if (!DescriptionUtils.isEmpty(composite.getWebServiceAnnot().wsdlLocation())) {
          if (composite.getWsdlDefinition() == null && composite.getWsdlURL() == null) {
                        // TODO: RAS/NLS
            throw ExceptionFactory.makeWebServiceException("Validation error: cannot find WSDL Definition specified by this WebService annotation. Implementation class: "
                                + composite.getClassName() + "; WSDL location: " + composite.getWebServiceAnnot().wsdlLocation());
          }
        }
       
        //    setWebServiceAnnotDefaults(true=impl); Must happen before we start checking annot
        if (!DescriptionUtils.isEmpty(composite.getWebServiceAnnot().endpointInterface())) {
         
          DescriptionBuilderComposite seic =
            dbcMap.get(composite.getWebServiceAnnot().endpointInterface());
         
          //Verify that we can find the SEI in the composite list
          if (seic == null){
                        // TODO: RAS/NLS
            throw ExceptionFactory.makeWebServiceException("Validation error: cannot find SEI specified by the WebService.endpointInterface.  Implementaiton class: "
                                + composite.getClassName() + "; EndpointInterface: " + composite.getWebServiceAnnot().endpointInterface());
          }
         
          // Verify that the only class annotations are WebService and HandlerChain
          // (per JSR181 Sec. 3.1).  Note that this applies to JSR-181 annotations; the restriction
                    // does not apply to JSR-224 annotations such as BindingType
          if ( composite.getSoapBindingAnnot() != null
              || composite.getWebFaultAnnot() != null
              || composite.getWebServiceClientAnnot() != null
              || composite.getWebServiceContextAnnot()!= null
              || !composite.getAllWebServiceRefAnnots().isEmpty()
          ) {
                        // TODO: RAS/NLS
            throw ExceptionFactory.makeWebServiceException("Validation error: invalid annotations specified when WebService annotation specifies an endpoint interface.  Implemntation class:  "
                + composite.getClassName());
          }
         
          //Verify that WebService annotation does not contain a name attribute
          //(per JSR181 Sec. 3.1)
          if (composite.getWebServiceAnnot().name() != null) {
                        // TODO: RAS/NLS
                        throw ExceptionFactory.makeWebServiceException("Validation error: WebService.name must not be specified when the bean specifies an endpoint interface.  Implentation class: " 
                                + composite.getClassName() + "; WebService.name: " + composite.getWebServiceAnnot().name());
          }
         
                    validateSEI(seic);
          //Verify that that this implementation class implements all methods in the interface
          validateImplementation(seic);
         
          //Verify that this impl. class does not contain any @WebMethod annotations
          if (webMethodAnnotationsExist()) {
                        // TODO: RAS/NLS
            throw ExceptionFactory.makeWebServiceException("Validation error: WebMethod annotations cannot exist on implentation when WebService.endpointInterface is set.  Implementation class: " +
                                composite.getClassName())
          }
         
         
        } else { //this is an implicit SEI (i.e. impl w/out endpointInterface
         
          checkImplicitSEIAgainstWSDL();
          //  TODO:  Call ValidateWebMethodAnnots()
          //      - this method will check that all methods are public - ???
          //
        }
      } else { //this is an interface...we should not be processing interfaces here
                // TODO: RAS/NLS
        throw ExceptionFactory.makeWebServiceException("Validation error: Improper usage: cannot invoke this method with an interface.  Implementation class: "
                        + composite.getClassName())
      }
         
      //TODO: don't think this is necessary
      checkMethodsAgainstWSDL();
    }
  }
 
    /**
     * Validate there is an invoke method on the composite.
     * @return
     */
  private boolean validateInvokeMethod() {
        boolean validInvokeMethod = false;
        List<MethodDescriptionComposite> invokeMethodList = composite.getMethodDescriptionComposite("invoke");
        if (invokeMethodList != null && !invokeMethodList.isEmpty()) {
            validInvokeMethod = true;
        }
        return validInvokeMethod;
    }

    /**
     * Validate that, if using PAYLOAD mode, then interfaces list cannot contain
     * SOAPMessage or DataSource
     *
     * @return
     */
    private void validateProviderInterfaces() {

        // Default for ServiceMode is 'PAYLOAD'. So, if it is specified  (explicitly or
        // implicitly) then verify that we are not implementing improper interfaces)
        if ((composite.getServiceModeAnnot() == null)
                || composite.getServiceModeAnnot().value() == javax.xml.ws.Service.Mode.PAYLOAD) {

            Iterator<String> iter = composite.getInterfacesList().iterator();

            while (iter.hasNext()) {
                String interfaceString = iter.next();
                if (interfaceString.equals(MDQConstants.PROVIDER_SOAP)
                        || interfaceString.equals(MDQConstants.PROVIDER_DATASOURCE)) {

                    throw ExceptionFactory
                            .makeWebServiceException("Validation error: SOAPMessage and DataSource objects cannot be used when ServiceMode specifies PAYLOAD. Implementation class: "
                                    + composite.getClassName());
                }
            }

        } else {
            // We are in MESSAGE mode
            // Conformance: JAXWS Spec.- Sec. 4.3 (javax.activation.DataSource)
           
            // REVIEW: Should the provider interface validation be moved to post-construction validation,
            // since it seems that the logic to understand the default values for binding type
            // (see comment below) should be left to the creation of the Description objects.
            String bindingType = null;
            if (composite.getBindingTypeAnnot() != null ) {
                bindingType = composite.getBindingTypeAnnot().value();
            }

            Iterator<String> iter = composite.getInterfacesList().iterator();

            while (iter.hasNext()) {
                String interfaceString = iter.next();

                if (interfaceString.equals(MDQConstants.PROVIDER_SOAP)) {

                    // Make sure BindingType is SOAP/HTTP with SOAPMessage
                    // object, Default for Binding Type is SOAP/HTTP
                    if (!DescriptionUtils.isEmpty(bindingType)
                            && !bindingType
                                    .equals(SOAPBinding.SOAP11HTTP_BINDING)
                            && !bindingType
                                    .equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
                            && !bindingType
                                    .equals(SOAPBinding.SOAP12HTTP_BINDING)
                            && !bindingType
                                    .equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING))

                        throw ExceptionFactory
                                .makeWebServiceException("Validation error: SOAPMessage objects cannot be used with HTTP binding type. Implementation class: "
                                        + composite.getClassName());

                } else if (interfaceString
                        .equals(MDQConstants.PROVIDER_DATASOURCE)) {

                    // Make sure BindingType is XML/HTTP with DataSource object
                    if (DescriptionUtils.isEmpty(bindingType)
                            || !bindingType
                                    .equals(javax.xml.ws.http.HTTPBinding.HTTP_BINDING))

                        throw ExceptionFactory
                                .makeWebServiceException("Validation error: DataSource objects must be used with HTTP binding type. Implementation class: "
                                        + composite.getClassName());
                }
            }
        }
    }


    /**
     * Validate there is a default no-argument constructor on the composite.
     * @return
     */
    private boolean validateDefaultConstructor() {
        boolean validDefaultCtor = false;
        List<MethodDescriptionComposite> constructorList = composite.getMethodDescriptionComposite("<init>");
        if (constructorList != null && !constructorList.isEmpty()) {
            // There are public constructors; make sure there is one that takes no arguments.
            for (MethodDescriptionComposite checkCtor : constructorList) {
                List<ParameterDescriptionComposite> paramList = checkCtor.getParameterDescriptionCompositeList();
                if (paramList == null || paramList.isEmpty()) {
                    validDefaultCtor = true;
                    break;
                }
            }
        }
       
        return validDefaultCtor;
    }

    private void validateImplementation(DescriptionBuilderComposite seic) {
    /*
     *  Verify that an impl class implements all the methods of the SEI. We
     *  have to verify this because an impl class is not required to actually use
     *  the 'implements' clause. So, if it doesn't, the Java compiler won't
     *  catch it. Don't need to worry about chaining because only one EndpointInterface
     *  can be specified, and the SEI cannot specify an EndpointInterface, so the Java
     *  compiler will take care of everything else.
     */
   
    HashMap compositeHashMap = new HashMap();
    Iterator<MethodDescriptionComposite> compIterator = composite.getMethodDescriptionsList().iterator();
    while (compIterator.hasNext()) {
      MethodDescriptionComposite mdc = compIterator.next();
      compositeHashMap.put(mdc.getMethodName(),mdc);
    }
        // Add methods declared in the implementation's superclass
        addSuperClassMethods(compositeHashMap, composite);
   
        HashMap seiMethodHashMap = new HashMap();
        Iterator<MethodDescriptionComposite> seiMethodIterator =  seic.getMethodDescriptionsList().iterator();
        while (seiMethodIterator.hasNext()) {
            MethodDescriptionComposite mdc = seiMethodIterator.next();
            seiMethodHashMap.put(mdc.getMethodName(),mdc);
        }
        // Add any methods declared in superinterfaces of the SEI
        addSuperClassMethods(seiMethodHashMap, seic);
   
        // Make sure all the methods in the SEI (including any inherited from superinterfaces) are
        // implemented by the bean (including inherited methods on the bean).
        Iterator<MethodDescriptionComposite> verifySEIIterator = seiMethodHashMap.values().iterator();
    while (verifySEIIterator.hasNext()) {
      MethodDescriptionComposite mdc = verifySEIIterator.next();
      // REVIEW:  Only the names are checked; this isn't checking signatures
      if (compositeHashMap.get(mdc.getMethodName()) == null) {
                // TODO: RAS/NLS
          throw ExceptionFactory.makeWebServiceException("Validation error: Implementation subclass does not implement method on specified interface.  Implementation class: "
                        + composite.getClassName() + "; missing method name: " + mdc.getMethodName() + "; endpointInterface: " + seic.getClassName());       
      }
    }
  }
    /**
     * Adds any methods declared in superclasses to the HashMap.  The hierachy starting with the DBC will be walked
     * up recursively, adding methods from each parent DBC encountered. 
     *
     * Note that this can be used for either classes or interfaces.
     * @param methodMap
     * @param dbc
     */
    private void addSuperClassMethods(HashMap methodMap, DescriptionBuilderComposite dbc) {
        DescriptionBuilderComposite superDBC = dbcMap.get(dbc.getSuperClassName());
        if(superDBC != null) {
            Iterator<MethodDescriptionComposite> mIter = superDBC.getMethodDescriptionsList().iterator();
            while(mIter.hasNext()) {
                MethodDescriptionComposite mdc = mIter.next();
                methodMap.put(mdc.getMethodName(), mdc);
            }
            addSuperClassMethods(methodMap, superDBC);
        }
    }

 
  /*
   * This method verifies that, if there are any WebMethod with exclude == false, then
   * make sure that we find all of those methods represented in the wsdl. However, if
   * there are no exclusions == false, or there are no WebMethod annotations, then verify
   * that all the public methods are in the wsdl
   */
  private void checkMethodsAgainstWSDL() { 
//Verify that, for ImplicitSEI, that all methods that should exist(if one false found, then
//only look for WebMethods w/ False, else take all public methods but ignore those with
//exclude == true
    if (webMethodAnnotationsExist()) {
      if (DescriptionUtils.falseExclusionsExist(composite))
        verifyFalseExclusionsWithWSDL();
      else
        verifyPublicMethodsWithWSDL();
    } else {
      verifyPublicMethodsWithWSDL();
    }
  }
 
  private void checkImplicitSEIAgainstWSDL() {
   
    //TODO: If there is a WSDL, then verify that all WebMethods on this class and in the
    //    superclasses chain are represented in the WSDL...Look at logic below to make
    //    sure this really happening
   
   
    if (webMethodAnnotationsExist()) {
      if (DescriptionUtils.falseExclusionsExist(composite))
        verifyFalseExclusionsWithWSDL();
      else
        verifyPublicMethodsWithWSDL();
    } else {
      verifyPublicMethodsWithWSDL();
    }
   
  }
 
  private void checkSEIAgainstWSDL() {
    //TODO: Place logic here to verify that each publicMethod with WebMethod annot
    //      is contained in the WSDL (If there is a WSDL) If we find
    //      a WebMethod annotation, use its values for looking in the WSDL

  }
 
  private void validateSEI(DescriptionBuilderComposite seic) {
   
    //TODO: Validate SEI superclasses -- hmmm, may be doing this below
    //   
    if (seic.getWebServiceAnnot() == null) {
            // TODO: RAS & NLS
            throw ExceptionFactory.makeWebServiceException("Validation error: SEI does not contain a WebService annotation.  Implementation class: "
                    + composite.getClassName() + "; SEI: " + seic.getClassName());
        }
    if (!seic.getWebServiceAnnot().endpointInterface().equals("")) {
            // TODO: RAS & NLS
      throw ExceptionFactory.makeWebServiceException("Validation error: SEI must not set a value for @WebService.endpointInterface.  Implementation class: "
                    + composite.getClassName() + "; SEI: " + seic.getClassName()
                    + "; Invalid endpointInterface value: " + seic.getWebServiceAnnot().endpointInterface())
    }

    checkSEIAgainstWSDL();
   
    //TODO: More validation here
   
    //TODO: Make sure we don't find any WebMethod annotations with exclude == true
    //    anywhere in the superclasses chain
   
    //TODO: Check that all WebMethod annotations in the superclass chain are represented in
    //    WSDL, assuming there is WSDL
   
   
    //TODO:  Validate that the interface is public
   
    //    Call ValidateWebMethodAnnots()
    //
   
    //This will perform validation for all methods, regardless of WebMethod annotations
    //It is called for the SEI, and an impl. class that does not specify an endpointInterface
    validateMethods();
  }
 
  /**
   * @return Returns TRUE if we find just one WebMethod Annotation
   */
  private boolean webMethodAnnotationsExist() {
    MethodDescriptionComposite mdc = null;
    Iterator<MethodDescriptionComposite> iter = composite.getMethodDescriptionsList().iterator();
   
    while (iter.hasNext()) {
      mdc = iter.next();

      if (mdc.getWebMethodAnnot() != null)
        return true;
    }
   
    return false;
  }
 
  private void verifyFalseExclusionsWithWSDL() {
    //TODO: Place logic here to verify that each exclude==false WebMethod annot we find
    //      is contained in the WSDL
  }
 
  private void verifyPublicMethodsWithWSDL() {
    //TODO: Place logic here to verify that each publicMethod with no WebMethod annot
    //      is contained in the WSDL

  }

 
  /**
   */
  private void validateMethods() {
    //TODO: Fill this out to validate all MethodDescriptionComposite (and their inclusive
    //      annotations on this SEI (SEI is assumed here)
    //check oneway
    //
   
    //This could be an SEI, or an impl. class that doesn' specify an EndpointInterface (so, it
    //is implicitly an SEI...need to consider this
    //
   
    //TODO: Verify that, if this is an interface...that there are no Methods with WebMethod
    //      annotations that contain exclude == true
 
    //TODO: Verify that, if a SOAPBinding annotation exists, that its style be set to
    //      only DOCUMENT JSR181-Sec 4.7.1
 
  }
 
  private void validateWSDLOperations() {
    //Verifies that all operations on the wsdl are found in the impl/sei class
  }

    public boolean isWSDLSpecified() {
        boolean wsdlSpecified = false;
        if (getWSDLWrapper() != null) {
            wsdlSpecified = (getWSDLWrapper().getDefinition() != null);
        }
        return wsdlSpecified;
    }

    /**
     * Returns the WSDL definiton as specified in the metadata.  Note that this
     * WSDL may not be complete.
     */
    public Definition getWSDLDefinition() {
        Definition defn = null;
        if (getWSDLWrapper() != null) {
            defn = getWSDLWrapper().getDefinition();
        }
        return defn;
    }
    /**
     * Returns the WSDL definiton as created by calling the WSDL generator.  This will be null
     * unless the WSDL definition provided by the metadata is incomplete
     */
    public Definition getWSDLGeneratedDefinition() {
        Definition defn = null;
        if (getGeneratedWsdlWrapper() != null) {
            defn = getGeneratedWsdlWrapper().getDefinition();
        }
        return defn;
    }
   
    public Service getWSDLService() {
        Service returnWSDLService = null;
        Definition defn = getWSDLDefinition();
        if (defn != null) {
            returnWSDLService = defn.getService(getServiceQName());
        }
        return returnWSDLService;
    }
   
    public Map getWSDLPorts() {
        Service wsdlService = getWSDLService();
        if (wsdlService != null) {
            return wsdlService.getPorts();
        }
        else {
            return null;
        }
    }

    public List<QName> getPorts() {
        ArrayList<QName> portList = new ArrayList<QName>();
        // Note that we don't cache these results because the list of ports can be added
        // to via getPort(...) and addPort(...).

        // If the WSDL is specified, get the list of ports under this service
        Map wsdlPortsMap = getWSDLPorts();
        if (wsdlPortsMap != null) {
            Iterator wsdlPortsIterator = wsdlPortsMap.values().iterator();
            // Note that the WSDL Ports do not have a target namespace associated with them.
            // JAXWS says to use the TNS from the Service.
            String serviceTNS = getServiceQName().getNamespaceURI();
            for (Port wsdlPort = null; wsdlPortsIterator.hasNext(); ) {
                wsdlPort = (Port) wsdlPortsIterator.next();
                String wsdlPortLocalPart = wsdlPort.getName();
                portList.add(new QName(serviceTNS, wsdlPortLocalPart));
            }
        }

        // Go through the list of Endpoints that have been created and add any
        // not already in the list.  This will include ports added to the Service
        // via getPort(...) and addPort(...)
        EndpointDescription[] endpointDescArray = getEndpointDescriptions();
        for (EndpointDescription endpointDesc : endpointDescArray) {
            QName endpointPortQName = endpointDesc.getPortQName();
            if (!portList.contains(endpointPortQName)) {
                portList.add(endpointPortQName);
            }
        }
        return portList;
    }

    public List<Port> getWSDLPortsUsingPortType(QName portTypeQN) {
        ArrayList<Port> portList = new ArrayList<Port>();
        if (!DescriptionUtils.isEmpty(portTypeQN)) {
            Map wsdlPortMap = getWSDLPorts();
            if (wsdlPortMap != null && !wsdlPortMap.isEmpty()) {
                for (Object mapElement : wsdlPortMap.values()) {
                    Port wsdlPort = (Port) mapElement;
                    PortType wsdlPortType = wsdlPort.getBinding().getPortType();
                    QName wsdlPortTypeQN = wsdlPortType.getQName();
                    if (portTypeQN.equals(wsdlPortTypeQN)) {
                        portList.add(wsdlPort);
                    }
                }
            }
        }
        return portList;
    }

    public List<Port> getWSDLPortsUsingSOAPAddress(List<Port> wsdlPorts) {
        ArrayList<Port> portsUsingAddress = new ArrayList<Port>();
        if (wsdlPorts != null && !wsdlPorts.isEmpty()) {
            for (Port checkPort : wsdlPorts) {
                List extensibilityElementList = checkPort.getExtensibilityElements();
                for (Object checkElement : extensibilityElementList) {
                    if (EndpointDescriptionImpl.isSOAPAddressElement((ExtensibilityElement) checkElement)) {
                        portsUsingAddress.add(checkPort);
                    }
                }
            }
        }
        return portsUsingAddress;
    }
   
    public ServiceRuntimeDescription getServiceRuntimeDesc(String name) {
        // TODO Add toString support
        return runtimeDescMap.get(name);
    }

    public void setServiceRuntimeDesc(ServiceRuntimeDescription srd) {
        // TODO Add toString support
        runtimeDescMap.put(srd.getKey(), srd);
    }
   
    /**
     * Return a string representing this Description object and all the objects
     * it contains.
     */
    public String toString() {
        final String newline = "\n";
        final String sameline = "; ";
        // This produces a TREMENDOUS amount of output if we have the WSDL Definition objects
        // do a toString on themselves.
        boolean dumpWSDLContents = false;
        StringBuffer string = new StringBuffer();
       
        // Basic information
        string.append(super.toString());
        string.append(newline);
        string.append("ServiceQName: " + getServiceQName());
        // WSDL information
        string.append(newline);
        string.append("isWSDLSpecified: " + isWSDLSpecified());
        string.append(sameline);
        string.append("WSDL Location: " + getWSDLLocation());
        string.append(newline);
        if (dumpWSDLContents) {
            string.append("WSDL Definition: " + getWSDLDefinition());
            string.append(newline);
            string.append("Generated WSDL Definition: " + getWSDLGeneratedDefinition());
        }
        else {
            string.append("WSDL Definition available: " + (getWSDLDefinition() != null));
            string.append(sameline);
            string.append("Generated WSDL Definition available: " + (getWSDLGeneratedDefinition() != null));
        }
        // Ports
        string.append(newline);
        List<QName> ports = getPorts();
        string.append("Number of ports: " + ports.size());
        string.append(newline);
        string.append("Port QNames: ");
        for (QName port : ports) {
            string.append(port + sameline);
        }
        // Axis Config information
        // We don't print out the config context because it will force one to be created
        // if it doesn't already exist.
//        string.append(newline);
//        string.append("ConfigurationContext: " + getAxisConfigContext());
        // EndpointDescriptions
        string.append(newline);
        EndpointDescription[] endpointDescs = getEndpointDescriptions();
        if (endpointDescs == null) {
            string.append("EndpointDescription array is null");
        }
        else {
            string.append("Number of EndpointDescrptions: " + endpointDescs.length);
            string.append(newline);
            for (EndpointDescription endpointDesc : endpointDescs) {
                string.append(endpointDesc.toString());
                string.append(newline);
            }
        }
        string.append("RuntimeDescriptions:" +this.runtimeDescMap.size());
        string.append(newline);
        for (ServiceRuntimeDescription runtimeDesc:runtimeDescMap.values()) {
            string.append(runtimeDesc.toString());
            string.append(newline);
        }
        return string.toString();
       
    }
}
TOP

Related Classes of org.apache.axis2.jaxws.description.impl.ServiceDescriptionImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.