org.apache.axis2.description.AxisService.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.axis2.description.AxisService.java

Source

/*
 * 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.description;

import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.AddressingConstants;
import org.apache.axis2.addressing.AddressingHelper;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.dataretrieval.AxisDataLocator;
import org.apache.axis2.dataretrieval.AxisDataLocatorImpl;
import org.apache.axis2.dataretrieval.DRConstants;
import org.apache.axis2.dataretrieval.Data;
import org.apache.axis2.dataretrieval.DataRetrievalException;
import org.apache.axis2.dataretrieval.DataRetrievalRequest;
import org.apache.axis2.dataretrieval.LocatorType;
import org.apache.axis2.dataretrieval.OutputForm;
import org.apache.axis2.dataretrieval.SchemaSupplier;
import org.apache.axis2.dataretrieval.WSDLSupplier;
import org.apache.axis2.deployment.DeploymentConstants;
import org.apache.axis2.deployment.util.ExcludeInfo;
import org.apache.axis2.deployment.util.PhasesInfo;
import org.apache.axis2.deployment.util.Utils;
import org.apache.axis2.description.java2wsdl.DefaultSchemaGenerator;
import org.apache.axis2.description.java2wsdl.DocLitBareSchemaGenerator;
import org.apache.axis2.description.java2wsdl.Java2WSDLConstants;
import org.apache.axis2.description.java2wsdl.SchemaGenerator;
import org.apache.axis2.description.java2wsdl.TypeTable;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.engine.DefaultObjectSupplier;
import org.apache.axis2.engine.MessageReceiver;
import org.apache.axis2.engine.ObjectSupplier;
import org.apache.axis2.engine.ServiceLifeCycle;
import org.apache.axis2.i18n.Messages;
import org.apache.axis2.jsr181.JSR181Helper;
import org.apache.axis2.jsr181.WebMethodAnnotation;
import org.apache.axis2.phaseresolver.PhaseResolver;
import org.apache.axis2.transport.TransportListener;
import org.apache.axis2.util.IOUtils;
import org.apache.axis2.util.JavaUtils;
import org.apache.axis2.util.Loader;
import org.apache.axis2.util.LoggingControl;
import org.apache.axis2.util.XMLPrettyPrinter;
import org.apache.axis2.util.XMLUtils;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.neethi.Policy;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaExternal;
import org.apache.ws.commons.schema.XmlSchemaObjectCollection;
import org.apache.ws.commons.schema.utils.NamespaceMap;
import org.apache.ws.commons.schema.utils.NamespacePrefixList;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.wsdl.Definition;
import javax.wsdl.Import;
import javax.wsdl.Port;
import javax.wsdl.Service;
import javax.wsdl.Types;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.UnknownExtensibilityElement;
import javax.wsdl.extensions.http.HTTPAddress;
import javax.wsdl.extensions.schema.Schema;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.wsdl.extensions.soap12.SOAP12Address;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import javax.wsdl.xml.WSDLWriter;
import javax.xml.namespace.QName;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.SocketException;
import java.net.URL;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
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 java.util.Vector;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Class AxisService
 */
public class AxisService extends AxisDescription {

    // ////////////////////////////////////////////////////////////////
    // Standard Parameter names

    /**
     * If this param is true, and the service has exactly one AxisOperation,
     * normal operation dispatch (via URI/soapAction/etc) will not be necessary,
     * and we'll just default to funneling all messages to that op. This is
     * useful for passthrough/ESB/embedded applications.
     */
    public static final String SUPPORT_SINGLE_OP = "supportSingleOperation";
    // ////////////////////////////////////////////////////////////////

    public static final String IMPORT_TAG = "import";
    public static final String INCLUDE_TAG = "include";
    public static final String SCHEMA_LOCATION = "schemaLocation";

    private Map<String, AxisEndpoint> endpointMap = new HashMap<String, AxisEndpoint>();

    /*
     * This is a map between the QName of the element of a message specified in
     * the WSDL and an Operation. It enables SOAP Body-based dispatching for
     * doc-literal bindings.
     */
    private Map<QName, AxisOperation> messageElementQNameToOperationMap = new HashMap<QName, AxisOperation>();

    private int nsCount = 0;
    private static final Log log = LogFactory.getLog(AxisService.class);
    private URL fileName;

    // Maps httpLocations to corresponding operations. Used to dispatch rest
    // messages.
    private HashMap<String, AxisOperation> httpLocationDispatcherMap = null;

    // A map of (String alias, AxisOperation operation). The aliases might
    // include: SOAPAction,
    // WS-Addressing action, the operation name, the AxisInputMessage name. See:
    // - invalidOperationsAliases
    // - mapActionToOperatoin()
    // - getOperationByAction()
    // REVIEW: This really should be seperate maps for the different types of
    // aliases so they don't
    // conflict with each other. For example, so that an identical operation
    // name and soap action
    // on different operatoins don't cause a collision; the following can't be
    // routed because
    // "foo" is not unique across different operations:
    // operation 1: action = foo, name = bar
    // operation 2: action = bar, name = foo
    private HashMap<String, AxisOperation> operationsAliasesMap = null;

    // Collection of aliases that are invalid for this service because they are
    // duplicated across
    // multiple operations under this service.
    private List<String> invalidOperationsAliases = null;
    // private HashMap operations = new HashMap();

    // to store module ref at deploy time parsing
    private ArrayList<String> moduleRefs = null;

    // to keep the time that last update time of the service
    private long lastupdate;
    private HashMap<String, ModuleConfiguration> moduleConfigmap;
    private String name;
    private ClassLoader serviceClassLoader;

    // to keep the XMLScheam getting either from WSDL or java2wsdl
    private ArrayList<XmlSchema> schemaList;
    // private XmlSchema schema;

    // wsdl is there for this service or not (in side META-INF)
    private boolean wsdlFound = false;

    // to store the scope of the service
    private String scope;

    // to store default message receivers
    private HashMap<String, MessageReceiver> messageReceivers;

    // to set the handler chain available in phase info
    private boolean useDefaultChains = true;

    // to keep the status of the service , since service can stop at the run
    // time
    private boolean active = true;

    private boolean elementFormDefault = true;

    // to keep the service target name space
    private String targetNamespace = Java2WSDLConstants.DEFAULT_TARGET_NAMESPACE;
    private String targetNamespacePrefix = Java2WSDLConstants.TARGETNAMESPACE_PREFIX;

    // to store the target namespace for the schema
    private String schematargetNamespace;// = Java2WSDLConstants.AXIS2_XSD;
    private String schematargetNamespacePrefix = Java2WSDLConstants.SCHEMA_NAMESPACE_PRFIX;

    private boolean enableAllTransports = true;
    private List<String> exposedTransports = new ArrayList<String>();

    // To keep reference to ServiceLifeCycle instance , if the user has
    // specified in services.xml
    private ServiceLifeCycle serviceLifeCycle;

    /**
     * Keeps track whether the schema locations are adjusted
     */
    private boolean schemaLocationsAdjusted = false;

    private boolean wsdlImportLocationAdjusted = false;

    /**
     * A table that keeps a mapping of unique xsd names (Strings) against the
     * schema objects. This is populated in the first instance the schemas are
     * asked for and then used to serve the subsequent requests
     */
    private Map schemaMappingTable = null;

    /**
     * counter variable for naming the schemas
     */
    private int count = 0;
    /**
     * A custom schema Name prefix. if set this will be used to modify the
     * schema names
     */
    private String customSchemaNamePrefix = null;

    /**
     * A custom schema name suffix. will be attached to the schema file name
     * when the files are uniquely named. A good place to add a file extension
     * if needed
     */
    private String customSchemaNameSuffix = null;

    // ///////////////////////////////////////
    // WSDL related stuff ////////////////////
    // //////////////////////////////////////

    /** Map of prefix -> namespaceURI */
    private NamespaceMap namespaceMap;

    private String soapNsUri;
    private String endpointName;
    private String endpointURL;

    private List importedNamespaces;

    private boolean clientSide = false;

    // To keep a ref to ObjectSupplier instance
    private ObjectSupplier objectSupplier;

    // package to namespace mapping
    private Map p2nMap;

    // to keep the exclude property details
    private ExcludeInfo excludeInfo;

    private TypeTable typeTable;

    // Data Locators for WS-Mex Support
    private HashMap dataLocators;
    private HashMap<String, String> dataLocatorClassNames;
    private AxisDataLocatorImpl defaultDataLocator;
    // Define search sequence for datalocator based on Data Locator types.
    LocatorType[] availableDataLocatorTypes = new LocatorType[] { LocatorType.SERVICE_DIALECT,
            LocatorType.SERVICE_LEVEL, LocatorType.GLOBAL_DIALECT, LocatorType.GLOBAL_LEVEL,
            LocatorType.DEFAULT_AXIS };

    // name of the binding used : use in codegeneration
    private String bindingName;

    // List of MessageContextListeners that listen for events on the MessageContext
    private CopyOnWriteArrayList<MessageContextListener> messageContextListeners = new CopyOnWriteArrayList<MessageContextListener>();

    // names list keep to preserve the parameter order
    private List operationsNameList;

    private String[] eprs;
    private boolean customWsdl = false;

    private HashMap policyMap = new HashMap();

    public AxisEndpoint getEndpoint(String key) {
        return (AxisEndpoint) endpointMap.get(key);
    }

    public void addEndpoint(String key, AxisEndpoint axisEndpoint) {
        this.endpointMap.put(key, axisEndpoint);
    }

    /**
     * @deprecated Use AddressingHelper.getAddressingRequirementParemeterValue
     */
    public String getWSAddressingFlag() {
        return AddressingHelper.getAddressingRequirementParemeterValue(this);
    }

    /**
     * @deprecated Use AddressingHelper.setAddressingRequirementParemeterValue
     */
    public void setWSAddressingFlag(String ar) {
        AddressingHelper.setAddressingRequirementParemeterValue(this, ar);
    }

    public boolean isSchemaLocationsAdjusted() {
        return schemaLocationsAdjusted;
    }

    public void setSchemaLocationsAdjusted(boolean schemaLocationsAdjusted) {
        this.schemaLocationsAdjusted = schemaLocationsAdjusted;
    }

    public Map getSchemaMappingTable() {
        return schemaMappingTable;
    }

    public void setSchemaMappingTable(Map schemaMappingTable) {
        this.schemaMappingTable = schemaMappingTable;
    }

    public String getCustomSchemaNamePrefix() {
        return customSchemaNamePrefix;
    }

    public void setCustomSchemaNamePrefix(String customSchemaNamePrefix) {
        this.customSchemaNamePrefix = customSchemaNamePrefix;
    }

    public String getCustomSchemaNameSuffix() {
        return customSchemaNameSuffix;
    }

    public void setCustomSchemaNameSuffix(String customSchemaNameSuffix) {
        this.customSchemaNameSuffix = customSchemaNameSuffix;
    }

    /**
     * Constructor AxisService.
     */
    public AxisService() {
        super();
        this.operationsAliasesMap = new HashMap();
        this.invalidOperationsAliases = new ArrayList();
        moduleConfigmap = new HashMap();
        // by default service scope is for the request
        scope = Constants.SCOPE_REQUEST;
        httpLocationDispatcherMap = new HashMap();
        messageReceivers = new HashMap();
        moduleRefs = new ArrayList();
        schemaList = new ArrayList();
        serviceClassLoader = (ClassLoader) org.apache.axis2.java.security.AccessController
                .doPrivileged(new PrivilegedAction<ClassLoader>() {
                    public ClassLoader run() {
                        return Thread.currentThread().getContextClassLoader();
                    }
                });
        objectSupplier = new DefaultObjectSupplier();
        dataLocators = new HashMap();
        dataLocatorClassNames = new HashMap();
    }

    /**
     * @return name of the port type
     * @deprecated use AxisService#getEndpointName() instead.
     */
    public String getPortTypeName() {
        return endpointName;
    }

    /**
     * @param portTypeName
     * @deprecated use AxisService#setEndpointName() instead
     */
    public void setPortTypeName(String portTypeName) {
        this.endpointName = portTypeName;
    }

    public String getBindingName() {
        return bindingName;
    }

    public void setBindingName(String bindingName) {
        this.bindingName = bindingName;
    }

    /**
     * get the SOAPVersion
     */
    public String getSoapNsUri() {
        return soapNsUri;
    }

    public void setSoapNsUri(String soapNsUri) {
        this.soapNsUri = soapNsUri;
    }

    /**
     * get the endpointName
     */
    public String getEndpointName() {
        return endpointName;
    }

    public void setEndpointName(String endpoint) {
        this.endpointName = endpoint;
    }

    /**
     * Constructor AxisService.
     */
    public AxisService(String name) {
        this();
        this.name = name;
    }

    @SuppressWarnings("deprecation")
    public void addMessageReceiver(String mepURI, MessageReceiver messageReceiver) {
        if (WSDL2Constants.MEP_URI_IN_ONLY.equals(mepURI)
                || WSDLConstants.WSDL20_2006Constants.MEP_URI_IN_ONLY.equals(mepURI)
                || WSDLConstants.WSDL20_2004_Constants.MEP_URI_IN_ONLY.equals(mepURI)) {
            messageReceivers.put(WSDL2Constants.MEP_URI_IN_ONLY, messageReceiver);
            messageReceivers.put(WSDLConstants.WSDL20_2006Constants.MEP_URI_IN_ONLY, messageReceiver);
            messageReceivers.put(WSDLConstants.WSDL20_2004_Constants.MEP_URI_IN_ONLY, messageReceiver);
        } else if (WSDL2Constants.MEP_URI_OUT_ONLY.equals(mepURI)
                || WSDLConstants.WSDL20_2006Constants.MEP_URI_OUT_ONLY.equals(mepURI)
                || WSDLConstants.WSDL20_2004_Constants.MEP_URI_OUT_ONLY.equals(mepURI)) {
            messageReceivers.put(WSDL2Constants.MEP_URI_OUT_ONLY, messageReceiver);
            messageReceivers.put(WSDLConstants.WSDL20_2006Constants.MEP_URI_OUT_ONLY, messageReceiver);
            messageReceivers.put(WSDLConstants.WSDL20_2004_Constants.MEP_URI_OUT_ONLY, messageReceiver);
        } else if (WSDL2Constants.MEP_URI_IN_OUT.equals(mepURI)
                || WSDLConstants.WSDL20_2006Constants.MEP_URI_IN_OUT.equals(mepURI)
                || WSDLConstants.WSDL20_2004_Constants.MEP_URI_IN_OUT.equals(mepURI)) {
            messageReceivers.put(WSDL2Constants.MEP_URI_IN_OUT, messageReceiver);
            messageReceivers.put(WSDLConstants.WSDL20_2006Constants.MEP_URI_IN_OUT, messageReceiver);
            messageReceivers.put(WSDLConstants.WSDL20_2004_Constants.MEP_URI_IN_OUT, messageReceiver);
        } else if (WSDL2Constants.MEP_URI_IN_OPTIONAL_OUT.equals(mepURI)
                || WSDLConstants.WSDL20_2006Constants.MEP_URI_IN_OPTIONAL_OUT.equals(mepURI)
                || WSDLConstants.WSDL20_2004_Constants.MEP_URI_IN_OPTIONAL_OUT.equals(mepURI)) {
            messageReceivers.put(WSDL2Constants.MEP_URI_IN_OPTIONAL_OUT, messageReceiver);
            messageReceivers.put(WSDLConstants.WSDL20_2006Constants.MEP_URI_IN_OPTIONAL_OUT, messageReceiver);
            messageReceivers.put(WSDLConstants.WSDL20_2004_Constants.MEP_URI_IN_OPTIONAL_OUT, messageReceiver);
        } else if (WSDL2Constants.MEP_URI_OUT_IN.equals(mepURI)
                || WSDLConstants.WSDL20_2006Constants.MEP_URI_OUT_IN.equals(mepURI)
                || WSDLConstants.WSDL20_2004_Constants.MEP_URI_OUT_IN.equals(mepURI)) {
            messageReceivers.put(WSDL2Constants.MEP_URI_OUT_IN, messageReceiver);
            messageReceivers.put(WSDLConstants.WSDL20_2006Constants.MEP_URI_OUT_IN, messageReceiver);
            messageReceivers.put(WSDLConstants.WSDL20_2004_Constants.MEP_URI_OUT_IN, messageReceiver);
        } else if (WSDL2Constants.MEP_URI_OUT_OPTIONAL_IN.equals(mepURI)
                || WSDLConstants.WSDL20_2006Constants.MEP_URI_OUT_OPTIONAL_IN.equals(mepURI)
                || WSDLConstants.WSDL20_2004_Constants.MEP_URI_OUT_OPTIONAL_IN.equals(mepURI)) {
            messageReceivers.put(WSDL2Constants.MEP_URI_OUT_OPTIONAL_IN, messageReceiver);
            messageReceivers.put(WSDLConstants.WSDL20_2006Constants.MEP_URI_OUT_OPTIONAL_IN, messageReceiver);
            messageReceivers.put(WSDLConstants.WSDL20_2004_Constants.MEP_URI_OUT_OPTIONAL_IN, messageReceiver);
        } else if (WSDL2Constants.MEP_URI_ROBUST_OUT_ONLY.equals(mepURI)
                || WSDLConstants.WSDL20_2006Constants.MEP_URI_ROBUST_OUT_ONLY.equals(mepURI)
                || WSDLConstants.WSDL20_2004_Constants.MEP_URI_ROBUST_OUT_ONLY.equals(mepURI)) {
            messageReceivers.put(WSDL2Constants.MEP_URI_ROBUST_OUT_ONLY, messageReceiver);
            messageReceivers.put(WSDLConstants.WSDL20_2006Constants.MEP_URI_ROBUST_OUT_ONLY, messageReceiver);
            messageReceivers.put(WSDLConstants.WSDL20_2004_Constants.MEP_URI_ROBUST_OUT_ONLY, messageReceiver);
        } else if (WSDL2Constants.MEP_URI_ROBUST_IN_ONLY.equals(mepURI)
                || WSDLConstants.WSDL20_2006Constants.MEP_URI_ROBUST_IN_ONLY.equals(mepURI)
                || WSDLConstants.WSDL20_2004_Constants.MEP_URI_ROBUST_IN_ONLY.equals(mepURI)) {
            messageReceivers.put(WSDL2Constants.MEP_URI_ROBUST_IN_ONLY, messageReceiver);
            messageReceivers.put(WSDLConstants.WSDL20_2006Constants.MEP_URI_ROBUST_IN_ONLY, messageReceiver);
            messageReceivers.put(WSDLConstants.WSDL20_2004_Constants.MEP_URI_ROBUST_IN_ONLY, messageReceiver);
        } else {
            messageReceivers.put(mepURI, messageReceiver);
        }
    }

    public MessageReceiver getMessageReceiver(String mepURL) {
        return messageReceivers.get(mepURL);
    }

    /**
     * Adds module configuration , if there is moduleConfig tag in service.
     * 
     * @param moduleConfiguration
     */
    public void addModuleConfig(ModuleConfiguration moduleConfiguration) {
        moduleConfigmap.put(moduleConfiguration.getModuleName(), moduleConfiguration);
    }

    /**
     * Add any control operations defined by a Module to this service.
     * 
     * @param module
     *            the AxisModule which has just been engaged
     * @throws AxisFault
     *             if a problem occurs
     */
    void addModuleOperations(AxisModule module) throws AxisFault {
        HashMap<QName, AxisOperation> map = module.getOperations();
        Collection<AxisOperation> col = map.values();
        PhaseResolver phaseResolver = new PhaseResolver(getAxisConfiguration());
        for (Iterator<AxisOperation> iterator = col.iterator(); iterator.hasNext();) {
            AxisOperation axisOperation = copyOperation((AxisOperation) iterator.next());
            if (this.getOperation(axisOperation.getName()) == null) {
                ArrayList<String> wsamappings = axisOperation.getWSAMappingList();
                if (wsamappings != null) {
                    for (int j = 0, size = wsamappings.size(); j < size; j++) {
                        String mapping = (String) wsamappings.get(j);
                        //If there is already an operation with this action
                        //mapping (e.g. if the service has a matching operation)
                        //then we're going to check to see if the module's
                        //operation says that it's OK to be overridden and
                        //if so, we'll simply ignore the mapping, otherwise
                        //we continue as before
                        AxisOperation mappedOperation = getOperationByAction(mapping);
                        if ((mappedOperation != null)
                                && (axisOperation.isParameterTrue(DeploymentConstants.TAG_ALLOWOVERRIDE))) {
                            if (log.isDebugEnabled()) {
                                log.debug("addModuleOperations: Mapping already exists for action: " + mapping
                                        + " to operation: " + axisOperation + " named: " + axisOperation.getName()
                                        + " and an override is allowed, so the module mapping for module: "
                                        + module.getName() + " is being ignored.");
                                log.debug(JavaUtils.callStackToString());
                            }
                        } else {
                            mapActionToOperation(mapping, axisOperation);
                        }
                    }
                }
                // If we've set the "expose" parameter for this operation, it's
                // normal (non-
                // control) and therefore it will appear in generated WSDL. If
                // we haven't,
                // it's a control operation and will be ignored at WSDL-gen
                // time.
                if (axisOperation.isParameterTrue(DeploymentConstants.TAG_EXPOSE)) {
                    axisOperation.setControlOperation(false);
                } else {
                    axisOperation.setControlOperation(true);
                }

                phaseResolver.engageModuleToOperation(axisOperation, module);

                this.addOperation(axisOperation);
            }
        }
    }

    public void addModuleref(String moduleref) {
        moduleRefs.add(moduleref);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.axis2.description.AxisService#addOperation(org.apache.axis2.description.AxisOperation)
     */

    /**
     * Method addOperation.
     * 
     * @param axisOperation
     */
    public void addOperation(AxisOperation axisOperation) {
        axisOperation.setParent(this);

        if (log.isDebugEnabled()) {
            if (axisOperation.getName().equals(ServiceClient.ANON_OUT_ONLY_OP)
                    || (axisOperation.getName().equals(ServiceClient.ANON_OUT_ONLY_OP))
                    || (axisOperation.getName().equals(ServiceClient.ANON_OUT_ONLY_OP))) {
                log.debug("Client-defined operation name matches default operation name. "
                        + "this may cause interoperability issues.  Name is: "
                        + axisOperation.getName().toString());
            }
        }

        Iterator<AxisModule> modules = getEngagedModules().iterator();

        while (modules.hasNext()) {
            AxisModule module = (AxisModule) modules.next();
            try {
                axisOperation.engageModule(module);
            } catch (AxisFault axisFault) {
                log.info(Messages.getMessage("modulealredyengagetoservice", module.getName()));
            }
        }
        if (axisOperation.getMessageReceiver() == null) {
            axisOperation.setMessageReceiver(
                    loadDefaultMessageReceiver(axisOperation.getMessageExchangePattern(), this));
        }
        if (axisOperation.getInputAction() == null) {
            axisOperation.setSoapAction("urn:" + axisOperation.getName().getLocalPart());
        }

        if (axisOperation.getOutputAction() == null) {
            axisOperation
                    .setOutputAction("urn:" + axisOperation.getName().getLocalPart() + Java2WSDLConstants.RESPONSE);
        }
        addChild(axisOperation);

        String operationName = axisOperation.getName().getLocalPart();

        /*
         * Some times name of the operation can be different from the name of
         * the first child of the SOAPBody. This will put the correct mapping
         * associating that name with the operation. This will be useful
         * especially for the SOAPBodyBasedDispatcher
         */

        Iterator axisMessageIter = axisOperation.getChildren();

        while (axisMessageIter.hasNext()) {
            AxisMessage axisMessage = (AxisMessage) axisMessageIter.next();
            String messageName = axisMessage.getName();
            if (messageName != null && !messageName.equals(operationName)) {
                mapActionToOperation(messageName, axisOperation);
            }
        }

        mapActionToOperation(operationName, axisOperation);

        String action = axisOperation.getInputAction();
        if (action.length() > 0) {
            mapActionToOperation(action, axisOperation);
        }

        ArrayList<String> wsamappings = axisOperation.getWSAMappingList();
        if (wsamappings != null) {
            for (int j = 0, size = wsamappings.size(); j < size; j++) {
                String mapping = (String) wsamappings.get(j);
                mapActionToOperation(mapping, axisOperation);
            }
        }

        if (axisOperation.getMessageReceiver() == null) {
            axisOperation.setMessageReceiver(
                    loadDefaultMessageReceiver(axisOperation.getMessageExchangePattern(), this));
        }
    }

    private MessageReceiver loadDefaultMessageReceiver(String mepURL, AxisService service) {
        MessageReceiver messageReceiver;
        if (mepURL == null) {
            mepURL = WSDL2Constants.MEP_URI_IN_OUT;
        }
        if (service != null) {
            messageReceiver = service.getMessageReceiver(mepURL);
            if (messageReceiver != null) {
                return messageReceiver;
            }
        }
        if (getAxisConfiguration() != null) {
            return getAxisConfiguration().getMessageReceiver(mepURL);
        }
        return null;
    }

    /**
     * Gets a copy from module operation.
     * 
     * @param axisOperation
     * @return Returns AxisOperation.
     * @throws AxisFault
     */
    private AxisOperation copyOperation(AxisOperation axisOperation) throws AxisFault {
        AxisOperation operation = AxisOperationFactory
                .getOperationDescription(axisOperation.getMessageExchangePattern());

        operation.setMessageReceiver(axisOperation.getMessageReceiver());
        operation.setName(axisOperation.getName());

        Iterator<Parameter> parameters = axisOperation.getParameters().iterator();

        while (parameters.hasNext()) {
            Parameter parameter = (Parameter) parameters.next();

            operation.addParameter(parameter);
        }

        PolicyInclude policyInclude = new PolicyInclude(operation);
        PolicyInclude axisOperationPolicyInclude = axisOperation.getPolicyInclude();

        if (axisOperationPolicyInclude != null) {
            Policy policy = axisOperationPolicyInclude.getPolicy();
            if (policy != null) {
                policyInclude.setPolicy(axisOperationPolicyInclude.getPolicy());
            }
        }
        operation.setPolicyInclude(policyInclude);

        operation.setWsamappingList(axisOperation.getWSAMappingList());
        operation.setRemainingPhasesInFlow(axisOperation.getRemainingPhasesInFlow());
        operation.setPhasesInFaultFlow(axisOperation.getPhasesInFaultFlow());
        operation.setPhasesOutFaultFlow(axisOperation.getPhasesOutFaultFlow());
        operation.setPhasesOutFlow(axisOperation.getPhasesOutFlow());

        operation.setOutputAction(axisOperation.getOutputAction());
        String[] faultActionNames = axisOperation.getFaultActionNames();
        for (int i = 0; i < faultActionNames.length; i++) {
            operation.addFaultAction(faultActionNames[i], axisOperation.getFaultAction(faultActionNames[i]));
        }

        return operation;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.axis2.description.AxisService#addToengagedModules(javax.xml.namespace.QName)
     */

    /**
     * Engages a module. It is required to use this method.
     * 
     * @param axisModule
     * @param engager
     */
    public void onEngage(AxisModule axisModule, AxisDescription engager) throws AxisFault {
        // adding module operations
        addModuleOperations(axisModule);

        Iterator<AxisOperation> operations = getOperations();
        while (operations.hasNext()) {
            AxisOperation axisOperation = (AxisOperation) operations.next();
            axisOperation.engageModule(axisModule, engager);
        }
    }

    /**
     * Maps an alias (such as a SOAPAction, WSA action, or an operation name) to
     * the given AxisOperation. This is used by dispatching (both SOAPAction-
     * and WSAddressing- based dispatching) to figure out which operation a
     * given message is for. Some notes on restrictions of "action" - A null or
     * empty action will be ignored - An action that is a duplicate and
     * references an idential operation is allowed - An acton that is a
     * duplicate and references a different operation is NOT allowed. In this
     * case, the action for the original operation is removed from the alias
     * table, thus removing the ability to route based on this action. This is
     * necessary to prevent mis-directing incoming message to the wrong
     * operation based on SOAPAction.
     * 
     * Note that an alias could be a SOAPAction, WS-Addressing Action, the
     * operation name, or some other alias.
     * 
     * @see #getOperationByAction(String)
     * 
     * @param action
     *            the alias key
     * @param axisOperation
     *            the operation to map to
     */
    public void mapActionToOperation(String action, AxisOperation axisOperation) {
        if (action == null || "".equals(action)) {
            if (log.isDebugEnabled()) {
                log.debug("mapActionToOperation: A null or empty action cannot be used to map to an operation.");
            }
            return;
        }
        if (log.isDebugEnabled()) {
            log.debug("mapActionToOperation: Mapping Action to Operation: action: " + action + "; operation: "
                    + axisOperation + "named: " + axisOperation.getName());
            log.debug(JavaUtils.callStackToString());
        }

        //If there is already an operation with this action
        //mapping then we're going to check to see if the
        //operation says that it's OK to be overridden and
        //if so, we'll simply ignore the mapping, otherwise
        //we continue as before
        AxisOperation mappedOperation = getOperationByAction(action);
        if ((mappedOperation != null) && (axisOperation.isParameterTrue(DeploymentConstants.TAG_ALLOWOVERRIDE))) {
            if (log.isDebugEnabled()) {
                log.debug("addModuleOperations: Mapping already exists for action: " + action + " to operation: "
                        + axisOperation + " named: " + axisOperation.getName()
                        + " and an override is allowed, so the mapping is being ignored.");
                log.debug(JavaUtils.callStackToString());
            }
            return;
        }

        // First check if this action has already been flagged as invalid
        // because it is a duplicate.
        if (invalidOperationsAliases.contains(action)) {
            // This SOAPAction has already been determined to be invalid; log a
            // message
            // and do not add it to the operation alias map.
            if (log.isDebugEnabled()) {
                log.debug("mapActionToOperation: The action: " + action + " can not be used for operation: "
                        + axisOperation + " with operation name: " + axisOperation.getName()
                        + " because that SOAPAction is not unique for this service.");
            }
            return;
        }

        // Check if the action is currently mapping to an operation.
        AxisOperation currentlyMappedOperation = getOperationByAction(action);
        if (currentlyMappedOperation != null) {
            if (currentlyMappedOperation == axisOperation) {
                // This maps to the same operation, then it is already in the
                // alias table, so
                // just silently ignore this mapping request.
                if (log.isDebugEnabled()) {
                    log.debug("mapActionToOperation: This operation is already mapped to this action: " + action
                            + "; AxisOperation: " + currentlyMappedOperation + " named: "
                            + currentlyMappedOperation.getName());
                }
            } else {
                // This action is already mapped, but it is to a different
                // operation. Remove
                // the action mapping from the alias table and add it to the
                // list of invalid mappings
                operationsAliasesMap.remove(action);
                invalidOperationsAliases.add(action);
                if (log.isDebugEnabled()) {
                    log.debug("mapActionToOperation: The action is already mapped to a different "
                            + "operation.  The mapping of the action to any operations will be "
                            + "removed.  Action: " + action + "; original operation: " + currentlyMappedOperation
                            + " named " + currentlyMappedOperation.getName() + "; new operation: " + axisOperation
                            + " named " + axisOperation.getName());
                }
            }
        } else {
            operationsAliasesMap.put(action, axisOperation);
            // Adding operation name to the mapping table
            // operationsAliasesMap.put(axisOperation.getName().getLocalPart(),
            // axisOperation);
        }
    }

    /**
     * Maps an constant string in the whttp:location to the given operation.
     * This is used by RequestURIOperationDispatcher based dispatching to figure
     * out which operation it is that a given message is for.
     * 
     * @param string
     *            the constant drawn from whttp:location
     * @param axisOperation
     *            the operation to map to
     */
    public void addHttpLocationDispatcherString(String string, AxisOperation axisOperation) {
        httpLocationDispatcherMap.put(string, axisOperation);
    }

    /**
     * Prints the schema to the given output stream.
     * @param out The output stream for the data to be written. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @throws AxisFault
     */
    public void printSchema(OutputStream out) throws AxisFault {
        for (int i = 0; i < schemaList.size(); i++) {
            XmlSchema schema = addNameSpaces(i);
            schema.write(out);
        }
    }

    public XmlSchema getSchema(int index) {
        return addNameSpaces(index);
    }

    /**
     * Release the list of schema objects. <p/> In some environments, this can
     * provide significant relief of memory consumption in the java heap, as
     * long as the need for the schema list has completed.
     */
    public void releaseSchemaList() {
        if (schemaList != null) {
            // release the schema list
            schemaList.clear();
        }

        if (log.isDebugEnabled()) {
            log.debug("releaseSchemaList: schema list has been released.");
        }
    }

    private XmlSchema addNameSpaces(int i) {
        XmlSchema schema = (XmlSchema) schemaList.get(i);
        NamespaceMap map = (NamespaceMap) namespaceMap.clone();
        NamespacePrefixList namespaceContext = schema.getNamespaceContext();
        String prefixes[] = namespaceContext.getDeclaredPrefixes();
        for (int j = 0; j < prefixes.length; j++) {
            String prefix = prefixes[j];
            map.add(prefix, namespaceContext.getNamespaceURI(prefix));
        }
        schema.setNamespaceContext(map);
        return schema;
    }

    public void setEPRs(String[] eprs) {
        this.eprs = eprs;
    }

    public String[] getEPRs() {
        if (eprs != null && eprs.length != 0) {
            return eprs;
        }
        eprs = calculateEPRs();
        return eprs;
    }

    private String[] calculateEPRs() {
        try {
            String requestIP = org.apache.axis2.util.Utils.getIpAddress(getAxisConfiguration());
            return calculateEPRs(requestIP);
        } catch (SocketException e) {
            log.error("Cannot get local IP address", e);
        }
        return new String[0];
    }

    private String[] calculateEPRs(String requestIP) {
        AxisConfiguration axisConfig = getAxisConfiguration();
        if (axisConfig == null) {
            return null;
        }
        ArrayList<String> eprList = new ArrayList<String>();
        if (enableAllTransports) {
            for (Iterator<TransportInDescription> transports = axisConfig.getTransportsIn().values()
                    .iterator(); transports.hasNext();) {
                TransportInDescription transportIn = (TransportInDescription) transports.next();
                TransportListener listener = transportIn.getReceiver();
                if (listener != null) {
                    try {
                        EndpointReference[] eprsForService = listener.getEPRsForService(this.name, requestIP);
                        if (eprsForService != null) {
                            for (int i = 0; i < eprsForService.length; i++) {
                                EndpointReference endpointReference = eprsForService[i];
                                if (endpointReference != null) {
                                    String address = endpointReference.getAddress();
                                    if (address != null) {
                                        eprList.add(address);
                                    }
                                }
                            }
                        }
                    } catch (AxisFault axisFault) {
                        log.warn(axisFault.getMessage());
                    }
                }
            }
        } else {
            List<String> trs = this.exposedTransports;
            for (int i = 0; i < trs.size(); i++) {
                String trsName = (String) trs.get(i);
                TransportInDescription transportIn = axisConfig.getTransportIn(trsName);
                if (transportIn != null) {
                    TransportListener listener = transportIn.getReceiver();
                    if (listener != null) {
                        try {
                            EndpointReference[] eprsForService = listener.getEPRsForService(this.name, requestIP);
                            if (eprsForService != null) {
                                for (int j = 0; j < eprsForService.length; j++) {
                                    EndpointReference endpointReference = eprsForService[j];
                                    if (endpointReference != null) {
                                        String address = endpointReference.getAddress();
                                        if (address != null) {
                                            eprList.add(address);
                                        }
                                    }
                                }
                            }
                        } catch (AxisFault axisFault) {
                            log.warn(axisFault.getMessage());
                        }
                    }
                }
            }
        }
        eprs = (String[]) eprList.toArray(new String[eprList.size()]);
        return eprs;
    }

    /**
     * Prints the given definition object.
     * @param definition The definition.
     * @param out The output stream the data to be written to. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @param requestIP The host IP address.
     * @throws AxisFault
     * @throws WSDLException
     */
    private synchronized void printDefinitionObject(Definition definition, OutputStream out, String requestIP)
            throws AxisFault, WSDLException {
        // Synchronized this method to fix the NullPointer exception occurred when load is high.
        // This error happens because wsdl4j is not thread safe and we are using same WSDL Definition for printing the
        // WSDL.
        // Please refer AXIS2-4511,AXIS2-4517,AXIS2-3276.
        if (isModifyUserWSDLPortAddress()) {
            setPortAddress(definition, requestIP);
        }
        if (!wsdlImportLocationAdjusted) {
            changeImportAndIncludeLocations(definition);
            wsdlImportLocationAdjusted = true;
        }
        WSDLWriter writer = WSDLFactory.newInstance().newWSDLWriter();
        writer.writeWSDL(definition, out);
    }

    public void printUserWSDL(OutputStream out, String wsdlName) throws AxisFault {
        printUserWSDL(out, wsdlName, null);
    }

    /**
     * Prints the user WSDL.
     * @param out The output stream for the data to be written. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @param wsdlName The name of the WSDL.
     * @param ip The host IP address.
     * @throws AxisFault
     */
    public void printUserWSDL(OutputStream out, String wsdlName, String ip) throws AxisFault {
        Definition definition = null;
        // first find the correct wsdl definition
        Parameter wsdlParameter = getParameter(WSDLConstants.WSDL_4_J_DEFINITION);
        if (wsdlParameter != null) {
            definition = (Definition) wsdlParameter.getValue();
        }

        if (definition != null) {
            try {
                printDefinitionObject(getWSDLDefinition(definition, wsdlName), out, ip);
            } catch (WSDLException e) {
                throw AxisFault.makeFault(e);
            }
        } else {
            printWSDLError(out);
        }

    }

    /**
     * find the defintion object for given name
     * 
     * @param parentDefinition
     * @param name
     * @return wsdl definition
     */
    private Definition getWSDLDefinition(Definition parentDefinition, String name) {

        if (name == null)
            return parentDefinition;

        Definition importedDefinition = null;
        Iterator iter = parentDefinition.getImports().values().iterator();
        Vector values = null;
        Import wsdlImport = null;
        for (; iter.hasNext();) {
            values = (Vector) iter.next();
            for (Iterator valuesIter = values.iterator(); valuesIter.hasNext();) {
                wsdlImport = (Import) valuesIter.next();
                if (wsdlImport.getLocationURI().endsWith(name)) {
                    importedDefinition = wsdlImport.getDefinition();
                    break;
                } else {
                    importedDefinition = getWSDLDefinition(wsdlImport.getDefinition(), name);
                }
                if (importedDefinition != null) {
                    break;
                }
            }
            if (importedDefinition != null) {
                break;
            }
        }
        return importedDefinition;
    }

    /**
     * this procesdue recursively adjust the wsdl imports locations and the
     * schmea import and include locations.
     * 
     * @param definition
     */
    private void changeImportAndIncludeLocations(Definition definition) throws AxisFault {

        // adjust the schema locations in types section
        Types types = definition.getTypes();
        if (types != null) {
            List extensibilityElements = types.getExtensibilityElements();
            Object extensibilityElement = null;
            Schema schema = null;
            for (Iterator iter = extensibilityElements.iterator(); iter.hasNext();) {
                extensibilityElement = iter.next();
                if (extensibilityElement instanceof Schema) {
                    schema = (Schema) extensibilityElement;
                    changeLocations(schema.getElement());
                }
            }
        }

        Iterator iter = definition.getImports().values().iterator();
        Vector values = null;
        Import wsdlImport = null;
        String originalImprotString = null;
        for (; iter.hasNext();) {
            values = (Vector) iter.next();
            for (Iterator valuesIter = values.iterator(); valuesIter.hasNext();) {
                wsdlImport = (Import) valuesIter.next();
                originalImprotString = wsdlImport.getLocationURI();
                if (originalImprotString.indexOf("://") == -1 && originalImprotString.indexOf("?wsdl=") == -1) {
                    wsdlImport.setLocationURI(this.getServiceEPR() + "?wsdl=" + originalImprotString);
                }
                changeImportAndIncludeLocations(wsdlImport.getDefinition());
            }
        }

    }

    /**
     * change the schema Location in the elemment
     * 
     * @param element
     */

    private void changeLocations(Element element) throws AxisFault {
        NodeList nodeList = element.getChildNodes();
        String tagName;
        for (int i = 0; i < nodeList.getLength(); i++) {
            tagName = nodeList.item(i).getLocalName();
            if (IMPORT_TAG.equals(tagName) || INCLUDE_TAG.equals(tagName)) {
                processImport(nodeList.item(i));
            }
        }
    }

    private void updateSchemaLocation(XmlSchema schema) throws AxisFault {
        XmlSchemaObjectCollection includes = schema.getIncludes();
        for (int j = 0; j < includes.getCount(); j++) {
            Object item = includes.getItem(j);
            if (item instanceof XmlSchemaExternal) {
                XmlSchemaExternal xmlSchemaExternal = (XmlSchemaExternal) item;
                XmlSchema s = xmlSchemaExternal.getSchema();
                updateSchemaLocation(s, xmlSchemaExternal);
            }
        }
    }

    private void updateSchemaLocation(XmlSchema s, XmlSchemaExternal xmlSchemaExternal) throws AxisFault {
        if (s != null) {
            String schemaLocation = xmlSchemaExternal.getSchemaLocation();

            if (schemaLocation.indexOf("://") == -1 && schemaLocation.indexOf("?xsd=") == -1) {
                String newscheamlocation = this.getServiceEPR() + "?xsd=" + schemaLocation;
                xmlSchemaExternal.setSchemaLocation(newscheamlocation);
            }
        }
    }

    private void processImport(Node importNode) throws AxisFault {
        NamedNodeMap nodeMap = importNode.getAttributes();
        Node attribute;
        String attributeValue;
        for (int i = 0; i < nodeMap.getLength(); i++) {
            attribute = nodeMap.item(i);
            if (attribute.getNodeName().equals(SCHEMA_LOCATION)) {
                attributeValue = attribute.getNodeValue();
                if (getParameter(Constants.CUSTOM_SCHEMA_NAME_PREFIX) != null) {
                    String customSchemaNamePrefix = getParameter(Constants.CUSTOM_SCHEMA_NAME_PREFIX).getValue()
                            .toString();
                    URL customUrl = null;
                    try {
                        URL base = new URL(customSchemaNamePrefix);
                        customUrl = new URL(base, attributeValue);
                    } catch (MalformedURLException e) {
                        log.error("Malformed schema URL: " + customUrl, e);
                        throw AxisFault.makeFault(e);
                    }
                    attribute.setNodeValue(customUrl.toString());
                } else if (attributeValue.indexOf("://") == -1 && attributeValue.indexOf("?xsd=") == -1) {
                    attribute.setNodeValue(this.getServiceEPR() + "?xsd=" + attributeValue);
                }
            }
        }
    }

    private String getServiceEPR() {
        String serviceEPR = null;
        boolean fromServiceName = false;
        Parameter parameter = this.getParameter(Constants.Configuration.GENERATE_ABSOLUTE_LOCATION_URIS);
        if ((parameter != null) && JavaUtils.isTrueExplicitly(parameter.getValue())) {
            String[] eprs = this.getEPRs();
            for (int i = 0; i < eprs.length; i++) {
                if ((eprs[i] != null) && (eprs[i].startsWith("http:"))) {
                    serviceEPR = eprs[i];
                    break;
                }
            }
            if (serviceEPR == null) {
                serviceEPR = eprs[0];
            }
        } else {
            serviceEPR = this.name;
            fromServiceName = true;
        }
        if (serviceEPR.endsWith("/")) {
            serviceEPR = serviceEPR.substring(0, serviceEPR.lastIndexOf("/"));
        }
        // if the service is a hierarchical service, we have to drop the hierarchical path
        if (fromServiceName && serviceEPR.indexOf('/') != -1) {
            serviceEPR = serviceEPR.substring(serviceEPR.lastIndexOf('/') + 1);
        }
        return serviceEPR;
    }

    /**
    * Produces a XSD for this AxisService and prints it to the specified
    * OutputStream.
    * 
    * @param out
    *            destination stream, NOTE: the stream is not closed after the operation, 
    *            it is the responsibility of the caller to close the stream after usage.
    * @param xsd
    *            schema name
    * @return -1 implies not found, 0 implies redirect to root, 1 implies
    *         found/printed a schema
    * @throws IOException
    */
    public int printXSD(OutputStream out, String xsd) throws IOException {

        // If we find a SchemaSupplier, use that
        SchemaSupplier supplier = (SchemaSupplier) getParameterValue("SchemaSupplier");
        if (supplier != null) {
            XmlSchema schema = supplier.getSchema(this, xsd);
            if (schema != null) {
                updateSchemaLocation(schema);
                schema.write(new OutputStreamWriter(out, "UTF8"));
                out.flush();
                return 1;
            }
        }

        // call the populator
        populateSchemaMappings();
        Map schemaMappingtable = getSchemaMappingTable();
        ArrayList<XmlSchema> schemas = getSchema();

        // a name is present - try to pump the requested schema
        if ((xsd != null) && (!"".equals(xsd))) {
            XmlSchema schema = (XmlSchema) schemaMappingtable.get(xsd);
            if (schema == null) {
                int dotIndex = xsd.indexOf('.');
                if (dotIndex > 0) {
                    String schemaKey = xsd.substring(0, dotIndex);
                    schema = (XmlSchema) schemaMappingtable.get(schemaKey);
                }
            }
            if (schema != null) {
                // schema is there - pump it outs
                schema.write(new OutputStreamWriter(out, "UTF8"));
                out.flush();
            } else {
                // make sure we are only serving .xsd files and ignore requests with
                // ".." in the name.
                if (xsd.endsWith(".xsd") && xsd.indexOf("..") == -1) {
                    InputStream in = getClassLoader().getResourceAsStream(DeploymentConstants.META_INF + "/" + xsd);
                    if (in != null) {
                        IOUtils.copy(in, out, true);
                    } else {
                        // Can't find the schema
                        return -1;
                    }
                } else {
                    // bad schema request
                    return -1;
                }
            }
        } else if (schemas.size() > 1) {
            // multiple schemas are present and the user specified
            // no name - in this case we cannot possibly pump a schema
            // so redirect to the service root
            return 0;
        } else {
            // user specified no name and there is only one schema
            // so pump that out
            ArrayList<XmlSchema> list = getSchema();
            if (list.size() > 0) {
                XmlSchema schema = getSchema(0);
                if (schema != null) {
                    schema.write(new OutputStreamWriter(out, "UTF8"));
                    out.flush();
                }
            } else {
                String xsdNotFound = "<error>"
                        + "<description>Unable to access schema for this service</description>" + "</error>";
                out.write(xsdNotFound.getBytes());
                out.flush();
            }
        }
        return 1;
    }

    /**
     * Produces a WSDL for this AxisService and prints it to the specified
     * OutputStream.
     * 
     * @param out
     *            destination stream. The WSDL will be sent here. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @param requestIP
     *            the hostname the WSDL request was directed at. This should be
     *            the address that appears in the generated WSDL.
     * @throws AxisFault
     *             if an error occurs
     */
    public void printWSDL(OutputStream out, String requestIP) throws AxisFault {
        // If we're looking for pre-existing WSDL, use that.
        if (isUseUserWSDL()) {
            printUserWSDL(out, null, requestIP);
            return;
        }

        // If we find a WSDLSupplier, use that
        WSDLSupplier supplier = (WSDLSupplier) getParameterValue("WSDLSupplier");
        if (supplier != null) {
            try {
                Definition definition = supplier.getWSDL(this);
                if (definition != null) {
                    changeImportAndIncludeLocations(definition);
                    printDefinitionObject(getWSDLDefinition(definition, null), out, requestIP);
                }
            } catch (Exception e) {
                printWSDLError(out, e);
            }
            return;
        }

        if (isSetEndpointsToAllUsedBindings()) {
            Utils.setEndpointsToAllUsedBindings(this);
        }

        // Otherwise, generate WSDL ourselves
        String[] eprArray = requestIP == null ? new String[] { this.endpointName } : calculateEPRs(requestIP);
        getWSDL(out, eprArray);
    }

    /**
     * users can use this parameter when they supply a wsdl file with the .aar file
     * but wants to generate the endpoints for all available transports. here it assume
     * that the user has not set the useOriginalwsdl
     * @return
     */
    public boolean isSetEndpointsToAllUsedBindings() {
        Parameter parameter = getParameter("setEndpointsToAllUsedBindings");
        if (parameter != null) {
            String value = (String) parameter.getValue();
            if ("true".equals(value)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Print the WSDL with a default URL. This will be called only during
     * codegen time.
     * 
     * @param out The output stream for the data to be written. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @throws AxisFault
     */
    public void printWSDL(OutputStream out) throws AxisFault {
        printWSDL(out, null);
    }

    private AxisEndpoint getAxisEndpoint(String port) {
        // if service has a single endpoint, this will cause the [serviceName] address
        // to be used in wsdl instead of the [serviceName].[endpointName]
        if (endpointMap.size() == 1 && endpointMap.containsKey(getEndpointName())) {
            return null;
        } else {
            return (AxisEndpoint) endpointMap.get(port);
        }
    }

    private void setPortAddress(Definition definition, String requestIP) throws AxisFault {
        Iterator serviceItr = definition.getServices().values().iterator();
        while (serviceItr.hasNext()) {
            Service serviceElement = (Service) serviceItr.next();
            Iterator portItr = serviceElement.getPorts().values().iterator();
            while (portItr.hasNext()) {
                Port port = (Port) portItr.next();
                AxisEndpoint endpoint = getAxisEndpoint(port.getName());
                List list = port.getExtensibilityElements();
                for (int i = 0; i < list.size(); i++) {
                    Object extensibilityEle = list.get(i);
                    if (extensibilityEle instanceof SOAPAddress) {
                        SOAPAddress soapAddress = (SOAPAddress) extensibilityEle;
                        String existingAddress = soapAddress.getLocationURI();
                        if (existingAddress == null || existingAddress.equals("REPLACE_WITH_ACTUAL_URL")) {
                            if (endpoint != null) {
                                ((SOAPAddress) extensibilityEle)
                                        .setLocationURI(endpoint.calculateEndpointURL(requestIP));
                            } else {
                                ((SOAPAddress) extensibilityEle).setLocationURI(getEPRs()[0]);
                            }
                        } else {
                            if (requestIP == null) {
                                if (endpoint != null) {
                                    ((SOAPAddress) extensibilityEle)
                                            .setLocationURI(endpoint.calculateEndpointURL());
                                } else {
                                    ((SOAPAddress) extensibilityEle)
                                            .setLocationURI(getLocationURI(getEPRs(), existingAddress));
                                }
                            } else {
                                if (endpoint != null) {
                                    ((SOAPAddress) extensibilityEle)
                                            .setLocationURI(endpoint.calculateEndpointURL(requestIP));
                                } else {
                                    ((SOAPAddress) extensibilityEle).setLocationURI(
                                            getLocationURI(calculateEPRs(requestIP), existingAddress));
                                }
                            }
                        }
                    } else if (extensibilityEle instanceof SOAP12Address) {
                        SOAP12Address soapAddress = (SOAP12Address) extensibilityEle;
                        String exsistingAddress = soapAddress.getLocationURI();
                        if (requestIP == null) {
                            if (endpoint != null) {
                                ((SOAP12Address) extensibilityEle).setLocationURI(endpoint.calculateEndpointURL());

                            } else {
                                ((SOAP12Address) extensibilityEle)
                                        .setLocationURI(getLocationURI(getEPRs(), exsistingAddress));
                            }
                        } else {
                            if (endpoint != null) {
                                ((SOAP12Address) extensibilityEle)
                                        .setLocationURI(endpoint.calculateEndpointURL(requestIP));
                            } else {
                                ((SOAP12Address) extensibilityEle)
                                        .setLocationURI(getLocationURI(calculateEPRs(requestIP), exsistingAddress));

                            }
                        }
                    } else if (extensibilityEle instanceof HTTPAddress) {
                        HTTPAddress httpAddress = (HTTPAddress) extensibilityEle;
                        String exsistingAddress = httpAddress.getLocationURI();
                        if (requestIP == null) {
                            if (endpoint != null) {
                                ((HTTPAddress) extensibilityEle).setLocationURI(endpoint.calculateEndpointURL());
                            } else {
                                ((HTTPAddress) extensibilityEle)
                                        .setLocationURI(getLocationURI(getEPRs(), exsistingAddress));
                            }
                        } else {
                            if (endpoint != null) {
                                ((HTTPAddress) extensibilityEle)
                                        .setLocationURI(endpoint.calculateEndpointURL(requestIP));
                            } else {
                                ((HTTPAddress) extensibilityEle)
                                        .setLocationURI(getLocationURI(calculateEPRs(requestIP), exsistingAddress));
                            }
                        }
                    } else if (extensibilityEle instanceof UnknownExtensibilityElement) {
                        UnknownExtensibilityElement unknownExtensibilityElement = (UnknownExtensibilityElement) extensibilityEle;
                        Element element = unknownExtensibilityElement.getElement();
                        if (AddressingConstants.ENDPOINT_REFERENCE.equals(element.getLocalName())) {
                            NodeList nodeList = element.getChildNodes();
                            Node node = null;
                            Element currentElement = null;
                            for (int j = 0; j < nodeList.getLength(); j++) {
                                node = nodeList.item(j);
                                if (node instanceof Element) {
                                    currentElement = (Element) node;
                                    if (AddressingConstants.EPR_ADDRESS.equals(currentElement.getLocalName())) {
                                        String exsistingAddress = currentElement.getTextContent();
                                        if (requestIP == null) {
                                            if (endpoint != null) {
                                                currentElement.setTextContent(endpoint.calculateEndpointURL());
                                            } else {
                                                currentElement.setTextContent(
                                                        getLocationURI(getEPRs(), exsistingAddress));
                                            }
                                        } else {
                                            if (endpoint != null) {
                                                currentElement
                                                        .setTextContent(endpoint.calculateEndpointURL(requestIP));
                                            } else {
                                                currentElement.setTextContent(
                                                        getLocationURI(calculateEPRs(requestIP), exsistingAddress));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * this method returns the new IP address corresponding to the already
     * existing ip
     * 
     * @param eprs
     * @param epr
     * @return corresponding Ip address
     */
    private String getLocationURI(String[] eprs, String epr) throws AxisFault {
        String returnIP = null;
        if (epr != null) {
            String existingProtocol = org.apache.axis2.util.Utils.getURIScheme(epr);
            if (existingProtocol != null) {
                for (int i = 0; i < eprs.length; i++) {
                    if (existingProtocol.equals(org.apache.axis2.util.Utils.getURIScheme(eprs[i]))) {
                        returnIP = eprs[i];
                        break;
                    }
                }
                if (returnIP != null) {
                    return returnIP;
                } else {
                    throw new AxisFault("Server does not have an epr for the wsdl epr==>" + epr);
                }
            } else {
                throw new AxisFault("invalid epr is given epr ==> " + epr);
            }
        } else {
            throw new AxisFault("No epr is given in the wsdl port");
        }
    }

    /**
     * Retrieves the WSDL data associated with the given serviceURL.
     * @param out The output stream for the WSDL data to be written, NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @param serviceURL The fist element of this array i.e. serviceURL[0] is taken in retrieving the target service.
     */
    private void getWSDL(OutputStream out, String[] serviceURL) throws AxisFault {
        // Retrieve WSDL using the same data retrieval path for GetMetadata
        // request.
        DataRetrievalRequest request = new DataRetrievalRequest();
        request.putDialect(DRConstants.SPEC.DIALECT_TYPE_WSDL);
        request.putOutputForm(OutputForm.INLINE_FORM);

        MessageContext context = new MessageContext();
        context.setAxisService(this);
        context.setTo(new EndpointReference(serviceURL[0]));

        Data[] result = getData(request, context);
        OMElement wsdlElement;
        if (result != null && result.length > 0) {
            wsdlElement = (OMElement) (result[0].getData());
            try {
                XMLPrettyPrinter.prettify(wsdlElement, out);
                out.flush();
            } catch (Exception e) {
                throw AxisFault.makeFault(e);
            }
        }
    }

    /**
     * Prints generic WSDL error to the given output stream.
     * @param out The output stream the data to be written to. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @throws AxisFault
     */
    private void printWSDLError(OutputStream out) throws AxisFault {
        printWSDLError(out, null);
    }

    /**
     * Prints WSDL error condition that is given in the exception.
     * @param out The output stream for the error message to be written. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @param e The exception describing the error condition.
     * @throws AxisFault
     */
    private void printWSDLError(OutputStream out, Exception e) throws AxisFault {
        try {
            String wsdlntfound = "<error>"
                    + "<description>Unable to generate WSDL 1.1 for this service</description>"
                    + "<reason>If you wish Axis2 to automatically generate the WSDL 1.1, then please "
                    + "set useOriginalwsdl as false in your services.xml</reason>";
            out.write(wsdlntfound.getBytes());
            if (e != null) {
                PrintWriter pw = new PrintWriter(out);
                e.printStackTrace(pw);
                pw.flush();
            }
            out.write("</error>".getBytes());
            out.flush();
        } catch (IOException ex) {
            throw AxisFault.makeFault(ex);
        }
    }

    /**
     * Print the WSDL2.0 with a default URL. This will be called only during
     * codegen time.
     * 
     * @param out The output stream for the data to be written for. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @throws AxisFault
     */
    public void printWSDL2(OutputStream out) throws AxisFault {
        printWSDL2(out, null);
    }

    /**
     * Prints WSDL2.0 data for the service with the given host IP address.
     * @param out The output stream for the data to be written for. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @param requestIP The host IP address.
     * @throws AxisFault
     */
    public void printWSDL2(OutputStream out, String requestIP) throws AxisFault {
        AxisService2WSDL20 axisService2WSDL2 = new AxisService2WSDL20(this);
        try {
            if (requestIP != null) {
                axisService2WSDL2.setEPRs(calculateEPRs(requestIP));
            }
            OMElement wsdlElement = axisService2WSDL2.generateOM();
            wsdlElement.serialize(out);
            out.flush();
        } catch (Exception e) {
            throw AxisFault.makeFault(e);
        }
    }

    /**
     * Produces a WSDL2 for this AxisService and prints it to the specified
     * OutputStream.
     * 
     * @param out
     *            destination stream. NOTE: the stream is not closed after the operation, 
    *            it is the responsibility of the caller to close the stream after usage.
     * @param wsdl
     *            wsdl name
     * @return -1 implies not found, 0 implies redirect to root, 1 implies
     *         found/printed wsdl
     * @throws IOException
     */
    public int printWSDL2(OutputStream out, String requestIP, String wsdl) throws IOException, AxisFault {
        // if the wsdl2 parameter is not empty or null in the requested URL, get the wsdl  from the META-INF and serve.
        //else construct the wsdl out of axis service and serve.
        if ((wsdl != null) && (!"".equals(wsdl))) {
            // make sure we are only serving .wsdl files and ignore requests with
            // ".." in the name.
            if (wsdl.endsWith(".wsdl") && wsdl.indexOf("..") == -1) {
                InputStream in = getClassLoader().getResourceAsStream(DeploymentConstants.META_INF + "/" + wsdl);
                if (in != null) {
                    IOUtils.copy(in, out, true);
                } else {
                    // can't find the wsdl
                    return -1;
                }
            } else {
                // bad wsdl2 request
                return -1;
            }
        } else {
            printWSDL2(out, requestIP);
        }

        return 1;
    }

    /**
     * Gets the description about the service which is specified in
     * services.xml.
     * 
     * @return Returns String.
     * @deprecated Use getDocumentation() instead
     */
    public String getServiceDescription() {
        return getDocumentation();
    }

    /**
     * Method getClassLoader.
     * 
     * @return Returns ClassLoader.
     */
    public ClassLoader getClassLoader() {
        return this.serviceClassLoader;
    }

    /**
     * Gets the control operation which are added by module like RM.
     */
    public ArrayList<AxisOperation> getControlOperations() {
        Iterator<AxisOperation> op_itr = getOperations();
        ArrayList<AxisOperation> operationList = new ArrayList<AxisOperation>();

        while (op_itr.hasNext()) {
            AxisOperation operation = (AxisOperation) op_itr.next();

            if (operation.isControlOperation()) {
                operationList.add(operation);
            }
        }

        return operationList;
    }

    public URL getFileName() {
        return fileName;
    }

    /**
     * @deprecated please use getLastUpdate
     * @return
     */
    public long getLastupdate() {
        return lastupdate;
    }

    public long getLastUpdate() {
        return lastupdate;
    }

    public ModuleConfiguration getModuleConfig(String moduleName) {
        return (ModuleConfiguration) moduleConfigmap.get(moduleName);
    }

    public ArrayList<String> getModules() {
        return moduleRefs;
    }

    public String getName() {
        return name;
    }

    /**
     * Method getOperation.
     * 
     * @param operationName
     * @return Returns AxisOperation.
     */
    public AxisOperation getOperation(QName operationName) {
        if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled())
            log.debug("Get operation for " + operationName);

        AxisOperation axisOperation = (AxisOperation) getChild(operationName);

        if (axisOperation == null) {
            axisOperation = (AxisOperation) getChild(new QName(getTargetNamespace(), operationName.getLocalPart()));

            if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled())
                log.debug("Target namespace: " + getTargetNamespace());
        }

        if (axisOperation == null) {
            axisOperation = (AxisOperation) operationsAliasesMap.get(operationName.getLocalPart());

            if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled())
                log.debug("Operations aliases map: " + operationsAliasesMap);
        }

        //The operation may be associated with a namespace other than the
        //target namespace, e.g. if the operation is from an imported wsdl.
        if (axisOperation == null) {
            List namespaces = getImportedNamespaces();

            if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled())
                log.debug("Imported namespaces: " + namespaces);

            if (namespaces != null) {
                Iterator iterator = namespaces.iterator();

                while (iterator.hasNext()) {
                    String namespace = (String) iterator.next();
                    axisOperation = (AxisOperation) getChild(new QName(namespace, operationName.getLocalPart()));

                    if (axisOperation != null)
                        break;
                }
            }
        }

        if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled())
            log.debug("Found axis operation:  " + axisOperation);

        return axisOperation;
    }

    /**
     * Returns the AxisOperation which has been mapped to the given alias.
     * 
     * @see #mapActionToOperation(String, AxisOperation)
     * 
     * @param action
     *            the alias key
     * @return Returns the corresponding AxisOperation or null if it isn't
     *         found.
     */
    public AxisOperation getOperationByAction(String action) {
        return (AxisOperation) operationsAliasesMap.get(action);
    }

    /**
     * Returns the operation given a SOAP Action. This method should be called
     * if only one Endpoint is defined for this Service. If more than one
     * Endpoint exists, one of them will be picked. If more than one Operation
     * is found with the given SOAP Action; null will be returned. If no
     * particular Operation is found with the given SOAP Action; null will be
     * returned. If the action is in the list of invaliad aliases, which means
     * it did not uniquely identify an operation, a null will be returned.
     * 
     * @param soapAction
     *            SOAP Action defined for the particular Operation
     * @return Returns an AxisOperation if a unique Operation can be found with
     *         the given SOAP Action otherwise will return null.
     */
    public AxisOperation getOperationBySOAPAction(String soapAction) {

        // Check for illegal soapActions
        if ((soapAction == null) || soapAction.length() == 0) {
            if (log.isDebugEnabled()) {
                log.debug("getOperationBySOAPAction: " + soapAction + " is null or ''. Returning null.");
            }
            return null;
        }

        // If the action maps to an alais that is not unique, then it can't be
        // used to map to
        // an operation.
        if (invalidOperationsAliases.contains(soapAction)) {
            if (log.isDebugEnabled()) {
                log.debug("getOperationBySOAPAction: " + soapAction
                        + " is an invalid operation alias. Returning null.");
            }
            return null;
        }

        // Get the operation from the action->operation map
        AxisOperation operation = (AxisOperation) operationsAliasesMap.get(soapAction);

        if (operation != null) {
            if (log.isDebugEnabled()) {
                log.debug("getOperationBySOAPAction: Operation (" + operation + "," + operation.getName()
                        + ") for soapAction: " + soapAction + " found in action map.");
            }
            return operation;
        }

        // The final fallback is to check the operations for a matching name.

        Iterator children = getChildren();
        // I could not find any spec statement that explicitly forbids using a
        // short name in the SOAPAction header or wsa:Action element,
        // so I believe this to be valid. There may be customers using the
        // shortname as the SOAPAction in their client code that would
        // also require this support.
        while (children.hasNext() && (operation == null)) {
            AxisOperation op = (AxisOperation) children.next();
            if (op.getName().getLocalPart().equals(soapAction)) {
                operation = op;
            }
        }

        if (operation != null) {
            if (log.isDebugEnabled()) {
                log.debug("getOperationBySOAPAction: Operation (" + operation + "," + operation.getName()
                        + ") for soapAction: " + soapAction + " found as child.");
            }
        }

        return operation;
    }

    /**
     * Method getOperations.
     * 
     * @return Returns HashMap
     */
    public Iterator<AxisOperation> getOperations() {
        return (Iterator<AxisOperation>) getChildren();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.axis2.description.ParameterInclude#getParameter(java.lang.String)
     */

    /**
     * Gets only the published operations.
     */
    public ArrayList<AxisOperation> getPublishedOperations() {
        Iterator<AxisOperation> op_itr = getOperations();
        ArrayList<AxisOperation> operationList = new ArrayList<AxisOperation>();

        while (op_itr.hasNext()) {
            AxisOperation operation = (AxisOperation) op_itr.next();

            if (!operation.isControlOperation()) {
                operationList.add(operation);
            }
        }

        return operationList;
    }

    /**
     * Sets the description about the service which is specified in services.xml
     * 
     * @param documentation
     * @deprecated Use setDocumentation() instead
     */
    public void setServiceDescription(String documentation) {
        setDocumentation(documentation);
    }

    /**
     * Method setClassLoader.
     * 
     * @param classLoader
     */
    public void setClassLoader(ClassLoader classLoader) {
        this.serviceClassLoader = classLoader;
    }

    public void setFileName(URL fileName) {
        this.fileName = fileName;
    }

    /**
     * Sets the current time as last update time of the service.
      * @deprecated please use setLastUpdate
     */
    public void setLastupdate() {
        lastupdate = new Date().getTime();
    }

    /**
     * Sets the current time as last update time of the service.
     */
    public void setLastUpdate() {
        lastupdate = new Date().getTime();
    }

    public void setName(String name) {
        this.name = name;
    }

    public ArrayList<XmlSchema> getSchema() {
        return schemaList;
    }

    public void addSchema(XmlSchema schema) {
        if (schema != null) {
            schemaList.add(schema);
            if (schema.getTargetNamespace() != null) {
                addSchemaNameSpace(schema);
            }
        }
    }

    public void addSchema(Collection<XmlSchema> schemas) {
        Iterator<XmlSchema> iterator = schemas.iterator();
        while (iterator.hasNext()) {
            XmlSchema schema = (XmlSchema) iterator.next();
            schemaList.add(schema);
            addSchemaNameSpace(schema);
        }
    }

    public boolean isWsdlFound() {
        return wsdlFound;
    }

    public void setWsdlFound(boolean wsdlFound) {
        this.wsdlFound = wsdlFound;
    }

    public String getScope() {
        return scope;
    }

    /**
     * @param scope -
     *            Available scopes : Constants.SCOPE_APPLICATION
     *            Constants.SCOPE_TRANSPORT_SESSION Constants.SCOPE_SOAP_SESSION
     *            Constants.SCOPE_REQUEST.equals
     */
    public void setScope(String scope) {
        if (Constants.SCOPE_APPLICATION.equals(scope) || Constants.SCOPE_TRANSPORT_SESSION.equals(scope)
                || Constants.SCOPE_SOAP_SESSION.equals(scope) || Constants.SCOPE_REQUEST.equals(scope)) {
            this.scope = scope;
        }
    }

    public boolean isUseDefaultChains() {
        return useDefaultChains;
    }

    public void setUseDefaultChains(boolean useDefaultChains) {
        this.useDefaultChains = useDefaultChains;
    }

    public Object getKey() {
        return this.name;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    /**
     * @deprecated please use getSchemaTargetNamespace
     * @return
     */
    public String getSchematargetNamespace() {
        return schematargetNamespace;
    }

    public String getSchemaTargetNamespace() {
        return schematargetNamespace;
    }

    public void setSchemaTargetNamespace(String schematargetNamespace) {
        this.schematargetNamespace = schematargetNamespace;
    }

    public String getSchemaTargetNamespacePrefix() {
        return schematargetNamespacePrefix;
    }

    /**
     * @deprecated please use setSchemaTargetNamespacePrefix
     * @param schematargetNamespacePrefix
     */
    public void setSchematargetNamespacePrefix(String schematargetNamespacePrefix) {
        this.schematargetNamespacePrefix = schematargetNamespacePrefix;
    }

    public void setSchemaTargetNamespacePrefix(String schematargetNamespacePrefix) {
        this.schematargetNamespacePrefix = schematargetNamespacePrefix;
    }

    public String getTargetNamespace() {
        return targetNamespace;
    }

    public void setTargetNamespace(String targetNamespace) {
        this.targetNamespace = targetNamespace;
    }

    public String getTargetNamespacePrefix() {
        return targetNamespacePrefix;
    }

    public void setTargetNamespacePrefix(String targetNamespacePrefix) {
        this.targetNamespacePrefix = targetNamespacePrefix;
    }

    public XmlSchemaElement getSchemaElement(QName elementQName) {
        XmlSchemaElement element;
        for (int i = 0; i < schemaList.size(); i++) {
            XmlSchema schema = (XmlSchema) schemaList.get(i);
            if (schema != null) {
                element = schema.getElementByName(elementQName);
                if (element != null) {
                    return element;
                }
            }
        }
        return null;
    }

    public boolean isEnableAllTransports() {
        return enableAllTransports;
    }

    /**
     * To eneble service to be expose in all the transport
     * 
     * @param enableAllTransports
     */
    public void setEnableAllTransports(boolean enableAllTransports) {
        this.enableAllTransports = enableAllTransports;
        eprs = calculateEPRs();
    }

    public List<String> getExposedTransports() {
        return this.exposedTransports;
    }

    public void setExposedTransports(List transports) {
        enableAllTransports = false;
        this.exposedTransports = transports;
        eprs = null; // Do not remove this. We need to force EPR
                     // recalculation.
    }

    public void addExposedTransport(String transport) {
        enableAllTransports = false;
        if (!this.exposedTransports.contains(transport)) {
            this.exposedTransports.add(transport);
            try {
                eprs = calculateEPRs();
            } catch (Exception e) {
                eprs = null;
            }
        }
    }

    public void removeExposedTransport(String transport) {
        enableAllTransports = false;
        this.exposedTransports.remove(transport);
        try {
            eprs = calculateEPRs();
        } catch (Exception e) {
            eprs = null;
        }
    }

    public boolean isExposedTransport(String transport) {
        return exposedTransports.contains(transport);
    }

    public void onDisengage(AxisModule module) throws AxisFault {
        removeModuleOperations(module);
        for (Iterator operations = getChildren(); operations.hasNext();) {
            AxisOperation axisOperation = (AxisOperation) operations.next();
            axisOperation.disengageModule(module);
        }
        AxisConfiguration config = getAxisConfiguration();
        if (!config.isEngaged(module.getName())) {
            PhaseResolver phaseResolver = new PhaseResolver(config);
            phaseResolver.disengageModuleFromGlobalChains(module);
        }
    }

    /**
     * Remove any operations which were added by a given module.
     * 
     * @param module
     *            the module in question
     */
    private void removeModuleOperations(AxisModule module) {
        HashMap<QName, AxisOperation> moduleOperations = module.getOperations();
        if (moduleOperations != null) {
            for (Iterator<AxisOperation> modOpsIter = moduleOperations.values().iterator(); modOpsIter.hasNext();) {
                AxisOperation operation = (AxisOperation) modOpsIter.next();
                removeOperation(operation.getName());
            }
        }
    }

    // #######################################################################################
    // APIs to create AxisService

    //

    /**
     * To create a AxisService for a given WSDL and the created client is most
     * suitable for client side invocation not for server side invocation. Since
     * all the soap action and wsa action is added to operations
     * 
     * @param wsdlURL
     *            location of the WSDL
     * @param wsdlServiceName
     *            name of the service to be invoke , if it is null then the
     *            first one will be selected if there are more than one
     * @param portName
     *            name of the port , if there are more than one , if it is null
     *            then the first one in the iterator will be selected
     * @param options
     *            Service client options, to set the target EPR
     * @return AxisService , the created service will be return
     */
    public static AxisService createClientSideAxisService(URL wsdlURL, QName wsdlServiceName, String portName,
            Options options) throws AxisFault {
        try {
            InputStream in = wsdlURL.openConnection().getInputStream();
            Document doc = XMLUtils.newDocument(in);
            WSDLReader reader = WSDLFactory.newInstance().newWSDLReader();
            reader.setFeature("javax.wsdl.importDocuments", true);
            Definition wsdlDefinition = reader.readWSDL(getBaseURI(wsdlURL.toString()), doc);
            if (wsdlDefinition != null) {
                wsdlDefinition.setDocumentBaseURI(getDocumentURI(wsdlURL.toString()));
            }
            return createClientSideAxisService(wsdlDefinition, wsdlServiceName, portName, options);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw AxisFault.makeFault(e);
        } catch (ParserConfigurationException e) {
            log.error(e.getMessage(), e);
            throw AxisFault.makeFault(e);
        } catch (SAXException e) {
            log.error(e.getMessage(), e);
            throw AxisFault.makeFault(e);
        } catch (WSDLException e) {
            log.error(e.getMessage(), e);
            throw AxisFault.makeFault(e);
        }
    }

    private static String getBaseURI(String currentURI) {
        try {
            File file = new File(currentURI);
            if (file.exists()) {
                return file.getCanonicalFile().getParentFile().toURI().toString();
            }
            String uriFragment = currentURI.substring(0, currentURI.lastIndexOf("/"));
            return uriFragment + (uriFragment.endsWith("/") ? "" : "/");
        } catch (IOException e) {
            return null;
        }
    }

    private static String getDocumentURI(String currentURI) {
        try {
            File file = new File(currentURI);
            return file.getCanonicalFile().toURI().toString();
        } catch (IOException e) {
            return null;
        }
    }

    public static AxisService createClientSideAxisService(Definition wsdlDefinition, QName wsdlServiceName,
            String portName, Options options) throws AxisFault {
        WSDL11ToAxisServiceBuilder serviceBuilder = new WSDL11ToAxisServiceBuilder(wsdlDefinition, wsdlServiceName,
                portName);
        serviceBuilder.setServerSide(false);
        AxisService axisService = serviceBuilder.populateService();
        AxisEndpoint axisEndpoint = (AxisEndpoint) axisService.getEndpoints().get(axisService.getEndpointName());

        if (axisEndpoint != null) {
            options.setTo(new EndpointReference(axisEndpoint.getEndpointURL()));
            options.setSoapVersionURI(
                    (String) axisEndpoint.getBinding().getProperty(WSDL2Constants.ATTR_WSOAP_VERSION));
        }
        return axisService;
    }

    /**
     * To create an AxisService using given service impl class name first
     * generate schema corresponding to the given java class , next for each
     * methods AxisOperation will be created. If the method is in-out it will
     * uses RPCMessageReceiver else RPCInOnlyMessageReceiver <p/> Note : Inorder
     * to work this properly RPCMessageReceiver should be available in the class
     * path otherewise operation can not continue
     * 
     * @param implClass
     *            Service implementation class
     * @param axisConfig
     *            Current AxisConfiguration
     * @return return created AxisSrevice the creted service , it can either be
     *         null or valid service
     */
    public static AxisService createService(String implClass, AxisConfiguration axisConfig) throws AxisFault {

        try {
            HashMap<String, MessageReceiver> messageReciverMap = new HashMap<String, MessageReceiver>();
            Class inOnlyMessageReceiver = Loader
                    .loadClass("org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver");
            MessageReceiver messageReceiver = (MessageReceiver) inOnlyMessageReceiver.newInstance();
            messageReciverMap.put(WSDL2Constants.MEP_URI_IN_ONLY, messageReceiver);
            Class inoutMessageReceiver = Loader.loadClass("org.apache.axis2.rpc.receivers.RPCMessageReceiver");
            MessageReceiver inOutmessageReceiver = (MessageReceiver) inoutMessageReceiver.newInstance();
            messageReciverMap.put(WSDL2Constants.MEP_URI_IN_OUT, inOutmessageReceiver);
            messageReciverMap.put(WSDL2Constants.MEP_URI_ROBUST_IN_ONLY, inOutmessageReceiver);

            return createService(implClass, axisConfig, messageReciverMap, null, null,
                    axisConfig.getSystemClassLoader());
        } catch (Exception e) {
            throw AxisFault.makeFault(e);
        }
    }

    /**
     * messageReceiverClassMap will hold the MessageReceivers for given meps.
     * Key will be the mep and value will be the instance of the MessageReceiver
     * class. Ex: Map mrMap = new HashMap();
     * mrMap.put("http://www.w3.org/2004/08/wsdl/in-only",
     * RPCInOnlyMessageReceiver.class.newInstance());
     * mrMap.put("http://www.w3.org/2004/08/wsdl/in-out",
     * RPCMessageReceiver.class.newInstance());
     * 
     * @param implClass
     * @param axisConfiguration
     * @param messageReceiverClassMap
     * @param targetNamespace
     * @param schemaNamespace
     * @throws AxisFault
     */
    public static AxisService createService(String implClass, AxisConfiguration axisConfiguration,
            Map messageReceiverClassMap, String targetNamespace, String schemaNamespace, ClassLoader loader)
            throws AxisFault {
        int index = implClass.lastIndexOf(".");
        String serviceName;
        if (index > 0) {
            serviceName = implClass.substring(index + 1, implClass.length());
        } else {
            serviceName = implClass;
        }

        SchemaGenerator schemaGenerator;
        ArrayList excludeOpeartion = new ArrayList();
        AxisService service = new AxisService();
        service.setParent(axisConfiguration);
        service.setName(serviceName);

        try {
            Parameter generateBare = service.getParameter(Java2WSDLConstants.DOC_LIT_BARE_PARAMETER);
            if (generateBare != null && "true".equals(generateBare.getValue())) {
                schemaGenerator = new DocLitBareSchemaGenerator(loader, implClass, schemaNamespace,
                        Java2WSDLConstants.SCHEMA_NAMESPACE_PRFIX, service);
            } else {
                schemaGenerator = new DefaultSchemaGenerator(loader, implClass, schemaNamespace,
                        Java2WSDLConstants.SCHEMA_NAMESPACE_PRFIX, service);
            }
            schemaGenerator.setElementFormDefault(Java2WSDLConstants.FORM_DEFAULT_UNQUALIFIED);
            Utils.addExcludeMethods(excludeOpeartion);
            schemaGenerator.setExcludeMethods(excludeOpeartion);
        } catch (Exception e) {
            throw AxisFault.makeFault(e);
        }

        return createService(implClass, serviceName, axisConfiguration, messageReceiverClassMap, targetNamespace,
                loader, schemaGenerator, service);
    }

    /**
     * messageReceiverClassMap will hold the MessageReceivers for given meps.
     * Key will be the mep and value will be the instance of the MessageReceiver
     * class. Ex: Map mrMap = new HashMap();
     * mrMap.put("http://www.w3.org/2004/08/wsdl/in-only",
     * RPCInOnlyMessageReceiver.class.newInstance());
     * mrMap.put("http://www.w3.org/2004/08/wsdl/in-out",
     * RPCMessageReceiver.class.newInstance());
     * 
     * @param implClass
     * @param axisConfiguration
     * @param messageReceiverClassMap
     * @param targetNamespace
     * @throws AxisFault
     */
    public static AxisService createService(String implClass, String serviceName,
            AxisConfiguration axisConfiguration, Map<String, MessageReceiver> messageReceiverClassMap,
            String targetNamespace, ClassLoader loader, SchemaGenerator schemaGenerator, AxisService axisService)
            throws AxisFault {
        Parameter parameter = new Parameter(Constants.SERVICE_CLASS, implClass);
        OMElement paraElement = Utils.getParameter(Constants.SERVICE_CLASS, implClass, false);
        parameter.setParameterElement(paraElement);
        axisService.setUseDefaultChains(false);
        axisService.addParameter(parameter);
        axisService.setName(serviceName);
        axisService.setClassLoader(loader);

        NamespaceMap map = new NamespaceMap();
        map.put(Java2WSDLConstants.AXIS2_NAMESPACE_PREFIX, Java2WSDLConstants.AXIS2_XSD);
        map.put(Java2WSDLConstants.DEFAULT_SCHEMA_NAMESPACE_PREFIX, Java2WSDLConstants.URI_2001_SCHEMA_XSD);
        axisService.setNamespaceMap(map);
        Utils.processBeanPropertyExclude(axisService);
        axisService.setElementFormDefault(false);
        try {
            axisService.addSchema(schemaGenerator.generateSchema());
        } catch (Exception e) {
            throw AxisFault.makeFault(e);
        }
        axisService.setSchemaTargetNamespace(schemaGenerator.getSchemaTargetNameSpace());
        axisService.setTypeTable(schemaGenerator.getTypeTable());
        if (targetNamespace == null) {
            targetNamespace = schemaGenerator.getSchemaTargetNameSpace();
        }
        if (targetNamespace != null && !"".equals(targetNamespace)) {
            axisService.setTargetNamespace(targetNamespace);
        }
        Method[] method = schemaGenerator.getMethods();
        PhasesInfo pinfo = axisConfiguration.getPhasesInfo();
        for (int i = 0; i < method.length; i++) {
            Method jmethod = method[i];

            String methodName = jmethod.getName();
            WebMethodAnnotation methodAnnon = JSR181Helper.INSTANCE.getWebMethodAnnotation(jmethod);
            if (methodAnnon != null) {
                if (methodAnnon.getOperationName() != null) {
                    methodName = methodAnnon.getOperationName();
                }
            }
            AxisOperation operation = axisService.getOperation(new QName(methodName));

            String mep = operation.getMessageExchangePattern();
            MessageReceiver mr;
            if (messageReceiverClassMap != null) {

                if (messageReceiverClassMap.get(mep) != null) {
                    Object obj = messageReceiverClassMap.get(mep);
                    if (obj instanceof MessageReceiver) {
                        mr = (MessageReceiver) obj;
                        operation.setMessageReceiver(mr);
                    } else {
                        log.error(
                                "Object is not an instance of MessageReceiver, thus, default MessageReceiver has been set");
                        mr = axisConfiguration.getMessageReceiver(operation.getMessageExchangePattern());
                        operation.setMessageReceiver(mr);
                    }
                } else {
                    log.error(
                            "Required MessageReceiver couldn't be found, thus, default MessageReceiver has been used");
                    mr = axisConfiguration.getMessageReceiver(operation.getMessageExchangePattern());
                    operation.setMessageReceiver(mr);
                }
            } else {
                log.error("MessageRecevierClassMap couldn't be found, thus, default MessageReceiver has been used");
                mr = axisConfiguration.getMessageReceiver(operation.getMessageExchangePattern());
                operation.setMessageReceiver(mr);
            }
            pinfo.setOperationPhases(operation);
            axisService.addOperation(operation);
        }

        String endpointName = axisService.getEndpointName();
        if ((endpointName == null || endpointName.length() == 0) && axisService.getAxisConfiguration() != null) {
            Utils.addEndpointsToService(axisService, axisService.getAxisConfiguration());
        }

        return axisService;

    }

    public void removeOperation(QName opName) {
        AxisOperation operation = getOperation(opName);
        if (operation != null) {
            removeChild(opName);
            ArrayList<String> mappingList = operation.getWSAMappingList();
            if (mappingList != null) {
                for (int i = 0; i < mappingList.size(); i++) {
                    String actionMapping = (String) mappingList.get(i);
                    operationsAliasesMap.remove(actionMapping);
                    invalidOperationsAliases.remove(actionMapping);
                }
            }
            operationsAliasesMap.remove(operation.getName().getLocalPart());
            invalidOperationsAliases.remove(operation.getName().getLocalPart());
        }
    }

    /**
     * Get the namespace map for this service.
     * 
     * @return a Map of prefix (String) to namespace URI (String)
     * @deprecated please use getNamespaceMap()
     */
    public Map<String, String> getNameSpacesMap() {
        return namespaceMap;
    }

    /**
     * Get the namespace map for this service.
     * 
     * @return a Map of prefix (String) to namespace URI (String)
     */
    public Map getNamespaceMap() {
        return namespaceMap;
    }

    /**
     * Get the namespaces associated with imported WSDLs
     * 
     * @return a <code>List</code> of namespace URIs (String)
     */
    public List getImportedNamespaces() {
        return importedNamespaces;
    }

    /**
     * Set the namespaces associated with imported WSDLs
     * 
     * @param importedNamespaces
     */
    public void setImportedNamespaces(List importedNamespaces) {
        this.importedNamespaces = importedNamespaces;
    }

    /**
     * @deprecated please use setNamespaceMap
     * @param nameSpacesMap
     */
    public void setNameSpacesMap(NamespaceMap nameSpacesMap) {
        this.namespaceMap = nameSpacesMap;
    }

    public void setNamespaceMap(NamespaceMap namespaceMap) {
        this.namespaceMap = namespaceMap;
    }

    private void addSchemaNameSpace(XmlSchema schema) {
        String targetNameSpace = schema.getTargetNamespace();
        String prefix = schema.getNamespaceContext().getPrefix(targetNameSpace);

        if (namespaceMap == null) {
            namespaceMap = new NamespaceMap();
        }

        if (!namespaceMap.values().contains(targetNameSpace)) {
            // i.e this target namespace not exists in the namesapce map
            // find a non exists prefix to add this target namesapce
            while ((prefix == null) || namespaceMap.keySet().contains(prefix)) {
                prefix = "ns" + nsCount++;
            }
            namespaceMap.put(prefix, targetNameSpace);
        }

    }

    public Map populateSchemaMappings() {
        // when calling from other than codegen. i.e from deployment
        // engine we don't have to override the absolute http locations.
        return populateSchemaMappings(false);
    }

    /**
     * runs the schema mappings if it has not been run previously it is best
     * that this logic be in the axis service since one can call the axis
     * service to populate the schema mappings
     */
    public Map populateSchemaMappings(boolean overrideAbsoluteAddress) {

        // populate the axis service with the necessary schema references
        ArrayList schema = this.schemaList;
        Map changedSchemaLocations = null;
        if (!this.schemaLocationsAdjusted) {
            Hashtable nameTable = new Hashtable();
            Hashtable sourceURIToNewLocationMap = new Hashtable();
            // calculate unique names for the schemas
            calculateSchemaNames(schema, nameTable, sourceURIToNewLocationMap, overrideAbsoluteAddress);
            // adjust the schema locations as per the calculated names
            changedSchemaLocations = adjustSchemaNames(schema, nameTable, sourceURIToNewLocationMap);
            // reverse the nametable so that there is a mapping from the
            // name to the schemaObject
            setSchemaMappingTable(swapMappingTable(nameTable));
            setSchemaLocationsAdjusted(true);
        }
        return changedSchemaLocations;
    }

    /**
     * run 1 -calcualte unique names
     * 
     * @param schemas
     */
    private void calculateSchemaNames(List schemas, Hashtable nameTable, Hashtable sourceURIToNewLocationMap,
            boolean overrideAbsoluteAddress) {
        // first traversal - fill the hashtable
        for (int i = 0; i < schemas.size(); i++) {
            XmlSchema schema = (XmlSchema) schemas.get(i);
            XmlSchemaObjectCollection includes = schema.getIncludes();

            for (int j = 0; j < includes.getCount(); j++) {
                Object item = includes.getItem(j);
                XmlSchema s;
                if (item instanceof XmlSchemaExternal) {
                    XmlSchemaExternal externalSchema = (XmlSchemaExternal) item;
                    s = externalSchema.getSchema();

                    if (s != null && getScheamLocationWithDot(sourceURIToNewLocationMap, s) == null) {
                        // insert the name into the table
                        insertIntoNameTable(nameTable, s, sourceURIToNewLocationMap, overrideAbsoluteAddress);
                        // recursively call the same procedure
                        calculateSchemaNames(Arrays.asList(new XmlSchema[] { s }), nameTable,
                                sourceURIToNewLocationMap, overrideAbsoluteAddress);
                    }
                }
            }
        }
    }

    /**
     * A quick private sub routine to insert the names
     * 
     * @param nameTable
     * @param s
     */
    private void insertIntoNameTable(Hashtable nameTable, XmlSchema s, Hashtable sourceURIToNewLocationMap,
            boolean overrideAbsoluteAddress) {
        String sourceURI = s.getSourceURI();
        // check whether the sourece uri is an absolute one and are
        // we allowed to override it.
        // if the absolute uri overriding is not allowed the use the
        // original sourceURI as new one
        if (sourceURI.startsWith("http") && !overrideAbsoluteAddress) {
            nameTable.put(s, sourceURI);
            sourceURIToNewLocationMap.put(sourceURI, sourceURI);
        } else {
            String newURI = sourceURI.substring(sourceURI.lastIndexOf('/') + 1);
            if (newURI.endsWith(".xsd")) {
                // remove the .xsd extention
                newURI = newURI.substring(0, newURI.lastIndexOf("."));
            } else {
                newURI = "xsd" + count++;
            }

            newURI = customSchemaNameSuffix != null ? newURI + customSchemaNameSuffix : newURI;
            // make it unique
            while (nameTable.containsValue(newURI)) {
                newURI = newURI + count++;
            }

            nameTable.put(s, newURI);
            sourceURIToNewLocationMap.put(sourceURI, newURI);
        }

    }

    /**
     * Run 2 - adjust the names
     */
    private Map adjustSchemaNames(List schemas, Hashtable nameTable, Hashtable sourceURIToNewLocationMap) {
        Hashtable importedSchemas = new Hashtable();
        // process the schemas in the main schema list
        for (int i = 0; i < schemas.size(); i++) {
            adjustSchemaName((XmlSchema) schemas.get(i), nameTable, importedSchemas, sourceURIToNewLocationMap);
        }
        // process all the rest in the name table
        Enumeration nameTableKeys = nameTable.keys();
        while (nameTableKeys.hasMoreElements()) {
            adjustSchemaName((XmlSchema) nameTableKeys.nextElement(), nameTable, importedSchemas,
                    sourceURIToNewLocationMap);

        }
        return importedSchemas;
    }

    /**
     * Adjust a single schema
     * 
     * @param parentSchema
     * @param nameTable
     */
    private void adjustSchemaName(XmlSchema parentSchema, Hashtable nameTable, Hashtable importedScheams,
            Hashtable sourceURIToNewLocationMap) {
        XmlSchemaObjectCollection includes = parentSchema.getIncludes();
        for (int j = 0; j < includes.getCount(); j++) {
            Object item = includes.getItem(j);
            if (item instanceof XmlSchemaExternal) {
                XmlSchemaExternal xmlSchemaExternal = (XmlSchemaExternal) item;
                XmlSchema s = xmlSchemaExternal.getSchema();
                adjustSchemaLocation(s, xmlSchemaExternal, nameTable, importedScheams, sourceURIToNewLocationMap);
            }
        }

    }

    /**
     * Adjusts a given schema location
     * 
     * @param s
     * @param xmlSchemaExternal
     * @param nameTable
     */
    private void adjustSchemaLocation(XmlSchema s, XmlSchemaExternal xmlSchemaExternal, Hashtable nameTable,
            Hashtable importedScheams, Hashtable sourceURIToNewLocationMap) {
        if (s != null) {
            String schemaLocation = xmlSchemaExternal.getSchemaLocation();

            String newscheamlocation;
            // use the default mode
            if (customSchemaNamePrefix == null)
                newscheamlocation = (this.getServiceEPR() + "?xsd="
                        + getScheamLocationWithDot(sourceURIToNewLocationMap, s));
            // use the full service url as the customNamePrefix
            else if (customSchemaNamePrefix.equalsIgnoreCase("fullschemaurl"))
                newscheamlocation = (this.getEndpointURL() + "?xsd="
                        + getScheamLocationWithDot(sourceURIToNewLocationMap, s));
            // custom prefix is present - add the custom prefix
            else
                newscheamlocation = (customSchemaNamePrefix
                        + getScheamLocationWithDot(sourceURIToNewLocationMap, s));
            xmlSchemaExternal.setSchemaLocation(newscheamlocation);
            importedScheams.put(schemaLocation, newscheamlocation);
        }
    }

    private Object getScheamLocationWithDot(Hashtable sourceURIToNewLocationMap, XmlSchema s) {
        String o = (String) sourceURIToNewLocationMap.get(s.getSourceURI());
        if (o != null && o.indexOf(".") < 0) {
            return o + ".xsd";
        }
        return o;
    }

    /**
     * Swap the key,value pairs
     * 
     * @param originalTable
     */
    private Map swapMappingTable(Map originalTable) {
        HashMap swappedTable = new HashMap(originalTable.size());
        Iterator keys = originalTable.keySet().iterator();
        Object key;
        while (keys.hasNext()) {
            key = keys.next();
            swappedTable.put(originalTable.get(key), key);
        }

        return swappedTable;
    }

    public boolean isClientSide() {
        return clientSide;
    }

    public void setClientSide(boolean clientSide) {
        this.clientSide = clientSide;
    }

    public boolean isElementFormDefault() {
        return elementFormDefault;
    }

    public void setElementFormDefault(boolean elementFormDefault) {
        this.elementFormDefault = elementFormDefault;
    }

    /**
     * User can set a parameter in services.xml saying he want to show the
     * original wsdl that he put into META-INF once someone ask for ?wsdl so if
     * you want to use your own wsdl then add following parameter into
     * services.xml <parameter name="useOriginalwsdl">true</parameter>
     */
    public boolean isUseUserWSDL() {
        Parameter parameter = getParameter("useOriginalwsdl");
        if (parameter != null) {
            String value = (String) parameter.getValue();
            if ("true".equals(value)) {
                return true;
            }
        }
        return false;
    }

    /**
     * By default the port address in user WSDLs is modified, set the following
     * parameter to override this behaviour <parameter
     * name="modifyUserWSDLPortAddress">false</parameter>
     */
    public boolean isModifyUserWSDLPortAddress() {
        Parameter parameter = getParameter("modifyUserWSDLPortAddress");
        if (parameter != null) {
            String value = (String) parameter.getValue();
            if ("false".equals(value)) {
                return false;
            }
        }
        return true;
    }

    public ServiceLifeCycle getServiceLifeCycle() {
        return serviceLifeCycle;
    }

    public void setServiceLifeCycle(ServiceLifeCycle serviceLifeCycle) {
        this.serviceLifeCycle = serviceLifeCycle;
    }

    public Map getP2nMap() {
        return p2nMap;
    }

    public void setP2nMap(Map p2nMap) {
        this.p2nMap = p2nMap;
    }

    public ObjectSupplier getObjectSupplier() {
        return objectSupplier;
    }

    public void setObjectSupplier(ObjectSupplier objectSupplier) {
        this.objectSupplier = objectSupplier;
    }

    public TypeTable getTypeTable() {
        return typeTable;
    }

    public void setTypeTable(TypeTable typeTable) {
        this.typeTable = typeTable;
    }

    /**
     * Find a data locator from the available data locators (both configured and
     * default ones) to retrieve Metadata or data specified in the request.
     * 
     * @param request
     *            an {@link DataRetrievalRequest} object
     * @param msgContext
     *            message context
     * @return array of {@link Data} object for the request.
     * @throws AxisFault
     */

    public Data[] getData(DataRetrievalRequest request, MessageContext msgContext) throws AxisFault {

        Data[] data;
        String dialect = request.getDialect();
        AxisDataLocator dataLocator = null;
        int nextDataLocatorIndex = 0;
        int totalLocators = availableDataLocatorTypes.length;
        for (int i = 0; i < totalLocators; i++) {
            dataLocator = getDataLocator(availableDataLocatorTypes[i], dialect);
            if (dataLocator != null) {
                nextDataLocatorIndex = i + 1;
                break;
            }
        }

        if (dataLocator == null) {
            return null;
        }

        data = dataLocator.getData(request, msgContext);
        // Null means Data Locator not understood request. Automatically find
        // Data Locator in the hierarchy to process the request.
        if (data == null) {
            if (nextDataLocatorIndex < totalLocators) {
                data = bubbleupDataLocators(nextDataLocatorIndex, request, msgContext);
            }

        }
        return data;
    }

    /*
     * To search the next Data Locator from the available Data Locators that
     * understood the data retrieval request.
     */
    private Data[] bubbleupDataLocators(int nextIndex, DataRetrievalRequest request, MessageContext msgContext)
            throws AxisFault {
        Data[] data = null;
        if (nextIndex < availableDataLocatorTypes.length) {
            AxisDataLocator dataLocator = getDataLocator(availableDataLocatorTypes[nextIndex],
                    request.getDialect());
            nextIndex++;
            if (dataLocator != null) {
                data = dataLocator.getData(request, msgContext);
                if (data == null) {
                    data = bubbleupDataLocators(nextIndex, request, msgContext);
                } else {
                    return data;
                }

            } else {
                data = bubbleupDataLocators(nextIndex, request, msgContext);
            }

        }
        return data;
    }

    /**
     * Save data Locator configured at service level for this Axis Service
     * 
     * @param dialect-
     *            an absolute URI represents the Dialect i.e. WSDL, Policy,
     *            Schema or "ServiceLevel" for non-dialect service level data
     *            locator.
     * @param dataLocatorClassName -
     *            class name of the Data Locator configured to support data
     *            retrieval for the specified dialect.
     */
    public void addDataLocatorClassNames(String dialect, String dataLocatorClassName) {
        dataLocatorClassNames.put(dialect, dataLocatorClassName);
    }

    /*
     * Get data locator instance based on the LocatorType and dialect.
     */
    public AxisDataLocator getDataLocator(LocatorType locatorType, String dialect) throws AxisFault {
        AxisDataLocator locator;
        if (locatorType == LocatorType.SERVICE_DIALECT) {
            locator = getServiceDataLocator(dialect);
        } else if (locatorType == LocatorType.SERVICE_LEVEL) {
            locator = getServiceDataLocator(DRConstants.SERVICE_LEVEL);
        } else if (locatorType == LocatorType.GLOBAL_DIALECT) {
            locator = getGlobalDataLocator(dialect);
        } else if (locatorType == LocatorType.GLOBAL_LEVEL) {
            locator = getGlobalDataLocator(DRConstants.GLOBAL_LEVEL);
        } else if (locatorType == LocatorType.DEFAULT_AXIS) {
            locator = getDefaultDataLocator();
        } else {
            locator = getDefaultDataLocator();
        }

        return locator;
    }

    // Return default Axis2 Data Locator
    private AxisDataLocator getDefaultDataLocator() throws DataRetrievalException {

        if (defaultDataLocator == null) {
            defaultDataLocator = new AxisDataLocatorImpl(this);
        }

        defaultDataLocator.loadServiceData();

        return defaultDataLocator;
    }

    /*
     * Checks if service level data locator configured for specified dialect.
     * Returns an instance of the data locator if exists, and null otherwise.
     */
    private AxisDataLocator getServiceDataLocator(String dialect) throws AxisFault {
        AxisDataLocator locator;
        locator = (AxisDataLocator) dataLocators.get(dialect);
        if (locator == null) {
            String className = (String) dataLocatorClassNames.get(dialect);
            if (className != null) {
                locator = loadDataLocator(className);
                dataLocators.put(dialect, locator);
            }

        }

        return locator;

    }

    /*
     * Checks if global level data locator configured for specified dialect.
     * @param dialect- an absolute URI represents the Dialect i.e. WSDL, Policy,
     * Schema or "GlobalLevel" for non-dialect Global level data locator.
     * Returns an instance of the data locator if exists, and null otherwise.
     */

    public AxisDataLocator getGlobalDataLocator(String dialect) throws AxisFault {
        AxisConfiguration axisConfig = getAxisConfiguration();
        AxisDataLocator locator = null;
        if (axisConfig != null) {
            locator = axisConfig.getDataLocator(dialect);
            if (locator == null) {
                String className = axisConfig.getDataLocatorClassName(dialect);
                if (className != null) {
                    locator = loadDataLocator(className);
                    axisConfig.addDataLocator(dialect, locator);
                }
            }
        }

        return locator;

    }

    protected AxisDataLocator loadDataLocator(String className) throws AxisFault {

        AxisDataLocator locator;

        try {
            Class dataLocator;
            dataLocator = Class.forName(className, true, serviceClassLoader);
            locator = (AxisDataLocator) dataLocator.newInstance();
        } catch (ClassNotFoundException e) {
            throw AxisFault.makeFault(e);
        } catch (IllegalAccessException e) {
            throw AxisFault.makeFault(e);
        } catch (InstantiationException e) {
            throw AxisFault.makeFault(e);

        }

        return locator;
    }

    /**
     * Set the map of WSDL message element QNames to AxisOperations for this
     * service. This map is used during SOAP Body-based routing for
     * document/literal bare services to match the first child element of the
     * SOAP Body element to an operation. (Routing for RPC and document/literal
     * wrapped services occurs via the operationsAliasesMap.) <p/> From section
     * 4.7.6 of the WS-I BP 1.1: the "operation signature" is "the fully
     * qualified name of the child element of SOAP body of the SOAP input
     * message described by an operation in a WSDL binding," and thus this map
     * must be from a QName to an operation.
     * 
     * @param messageElementQNameToOperationMap
     *            The map from WSDL message element QNames to AxisOperations.
     */
    public void setMessageElementQNameToOperationMap(Map messageElementQNameToOperationMap) {
        this.messageElementQNameToOperationMap = messageElementQNameToOperationMap;
    }

    /**
     * Look up an AxisOperation for this service based off of an element QName
     * from a WSDL message element.
     * 
     * @param messageElementQName
     *            The QName to search for.
     * @return The AxisOperation registered to the QName or null if no match was
     *         found.
     * @see #setMessageElementQNameToOperationMap(Map)
     */
    public AxisOperation getOperationByMessageElementQName(QName messageElementQName) {
        return (AxisOperation) messageElementQNameToOperationMap.get(messageElementQName);
    }

    /**
     * Add an entry to the map between element QNames in WSDL messages and
     * AxisOperations for this service.
     * 
     * @param messageElementQName
     *            The QName of the element on the input message that maps to the
     *            given operation.
     * @param operation
     *            The AxisOperation to be mapped to.
     * @see #setMessageElementQNameToOperationMap(Map)
     */
    public void addMessageElementQNameToOperationMapping(QName messageElementQName, AxisOperation operation) {
        // when setting an operation we have to set it only if the
        // messegeElementQName does not
        // exists in the map.
        // does exists means there are two or more operations which has the same
        // input element (in doc/literal
        // this is possible. In this case better to set it as null without
        // giving
        // a random operation.
        if (messageElementQNameToOperationMap.containsKey(messageElementQName)
                && messageElementQNameToOperationMap.get(messageElementQName) != operation) {
            messageElementQNameToOperationMap.put(messageElementQName, null);
        } else {
            messageElementQNameToOperationMap.put(messageElementQName, operation);
        }

    }

    /**
     * @deprecated use {@link AxisEndpoint#getEndpointURL()}
     */
    public String getEndpointURL() {
        return endpointURL;
    }

    /**
     * @deprecated use {@link AxisEndpoint#setEndpointURL(String)}
     */
    public void setEndpointURL(String endpointURL) {
        this.endpointURL = endpointURL;
    }

    // TODO : Explain what goes in this map!
    public Map<String, AxisEndpoint> getEndpoints() {
        return endpointMap;
    }

    public boolean isCustomWsdl() {
        return customWsdl;
    }

    public void setCustomWsdl(boolean customWsdl) {
        this.customWsdl = customWsdl;
    }

    public List getOperationsNameList() {
        return operationsNameList;
    }

    public void setOperationsNameList(List operationsNameList) {
        this.operationsNameList = operationsNameList;
    }

    public AxisServiceGroup getAxisServiceGroup() {
        return (AxisServiceGroup) parent;
    }

    public void setParent(AxisServiceGroup parent) {
        this.parent = parent;
    }

    public String toString() {
        return getName();
    }

    public ExcludeInfo getExcludeInfo() {
        return excludeInfo;
    }

    public void setExcludeInfo(ExcludeInfo excludeInfo) {
        this.excludeInfo = excludeInfo;
    }

    public void registerPolicy(String key, Policy policy) {
        policyMap.put(key, policy);
    }

    public Policy lookupPolicy(String key) {
        return (Policy) policyMap.get(key);
    }

    /**
     * Add a ServiceContextListener
     * @param scl
     */
    public void addMessageContextListener(MessageContextListener scl) {
        messageContextListeners.add(scl);
    }

    /**
     * Remove a ServiceContextListener
     * @param scl
     */
    public void removeMessageContextListener(MessageContextListener scl) {
        messageContextListeners.remove(scl);
    }

    /**
     * @param cls Class of ServiceContextListener
     * @return true if ServiceContextLister is in the list
     */
    public boolean hasMessageContextListener(Class cls) {
        for (int i = 0; i < messageContextListeners.size(); i++) {
            if (messageContextListeners.get(i).getClass() == cls) {
                return true;
            }
        }
        return false;
    }

    /**
     * Signal an Attach ServiceContext Event
     * @param sc ServiceContext
     * @param mc MessageContext
     */
    public void attachServiceContextEvent(ServiceContext sc, MessageContext mc) {
        for (int i = 0; i < messageContextListeners.size(); i++) {
            messageContextListeners.get(i).attachServiceContextEvent(sc, mc);
        }
    }

    /**
     * Signal an Attach Envelope Event
     * @param mc MessageContext
     */
    public void attachEnvelopeEvent(MessageContext mc) {
        for (int i = 0; i < messageContextListeners.size(); i++) {
            messageContextListeners.get(i).attachEnvelopeEvent(mc);
        }
    }
}