Package org.apache.axis2.wsdl.codegen.emitter

Source Code of org.apache.axis2.wsdl.codegen.emitter.AxisServiceBasedMultiLanguageEmitter

package org.apache.axis2.wsdl.codegen.emitter;

import org.apache.axis2.description.AxisMessage;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.PolicyInclude;
import org.apache.axis2.namespace.Constants;
import org.apache.axis2.util.JavaUtils;
import org.apache.axis2.util.PolicyUtil;
import org.apache.axis2.util.XSLTUtils;
import org.apache.axis2.wsdl.SOAPHeaderMessage;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.axis2.wsdl.codegen.CodeGenConfiguration;
import org.apache.axis2.wsdl.codegen.CodeGenerationException;
import org.apache.axis2.wsdl.codegen.writer.*;
import org.apache.axis2.wsdl.databinding.TypeMapper;
import org.apache.axis2.wsdl.util.XSLTConstants;
import org.apache.axis2.wsdl.util.XSLTIncludeResolver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.policy.Policy;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.*;

/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* MultiLanguageClientEmitter we have now is based on WOM. This one will directly infer the information
* from the AxisService.
*/

public class AxisServiceBasedMultiLanguageEmitter implements Emitter {

    private static final String CALL_BACK_HANDLER_SUFFIX = "CallbackHandler";
    private static final String STUB_SUFFIX = "Stub";
    private static final String TEST_SUFFIX = "Test";
    private static final String SKELETON_CLASS_SUFFIX = "Skeleton";
    private static final String SKELETON_INTERFACE_SUFFIX = "SkeletonInterface";
    private static final String MESSAGE_RECEIVER_SUFFIX = "MessageReceiver";
    private static final String FAULT_SUFFIX = "Exception";
    private static final String DATABINDING_SUPPORTER_NAME_SUFFIX = "DatabindingSupporter";
//    private static final String DATABINDING_PACKAGE_NAME_SUFFIX = ".databinding";

    private static Map MEPtoClassMap;
    private static Map MEPtoSuffixMap;

    private int uniqueFaultNameCounter = 0;
    /**
     * Field constructorMap
     */
    private static HashMap constructorMap = new HashMap(50);

    //~--- static initializers ------------------------------------------------

    static {

        // Type maps to a valid initialization value for that type
        // Type var = new Type(arg)
        // Where "Type" is the key and "new Type(arg)" is the string stored
        // Used in emitting test cases and server skeletons.
        constructorMap.put("int", "0");
        constructorMap.put("float", "0");
        constructorMap.put("boolean", "true");
        constructorMap.put("double", "0");
        constructorMap.put("byte", "(byte)0");
        constructorMap.put("short", "(short)0");
        constructorMap.put("long", "0");
        constructorMap.put("java.lang.Boolean", "new java.lang.Boolean(false)");
        constructorMap.put("java.lang.Byte", "new java.lang.Byte((byte)0)");
        constructorMap.put("java.lang.Double", "new java.lang.Double(0)");
        constructorMap.put("java.lang.Float", "new java.lang.Float(0)");
        constructorMap.put("java.lang.Integer", "new java.lang.Integer(0)");
        constructorMap.put("java.lang.Long", "new java.lang.Long(0)");
        constructorMap.put("java.lang.Short", "new java.lang.Short((short)0)");
        constructorMap.put("java.math.BigDecimal", "new java.math.BigDecimal(0)");
        constructorMap.put("java.math.BigInteger", "new java.math.BigInteger(\"0\")");
        constructorMap.put("java.lang.Object", "new java.lang.String()");
        constructorMap.put("byte[]", "new byte[0]");
        constructorMap.put("java.util.Calendar", "java.util.Calendar.getInstance()");
        constructorMap.put("javax.xml.namespace.QName",
                "new javax.xml.namespace.QName(\"http://double-double\", \"toil-and-trouble\")");

        //populate the MEP -> class map
        MEPtoClassMap = new HashMap();
        MEPtoClassMap.put(WSDLConstants.MEP_URI_IN_ONLY, "org.apache.axis2.receivers.AbstractInMessageReceiver");
        MEPtoClassMap.put(WSDLConstants.MEP_URI_IN_OUT, "org.apache.axis2.receivers.AbstractInOutSyncMessageReceiver");

        //populate the MEP -> suffix map
        MEPtoSuffixMap = new HashMap();
        MEPtoSuffixMap.put(WSDLConstants.MEP_URI_IN_ONLY, MESSAGE_RECEIVER_SUFFIX + "InOnly");
        MEPtoSuffixMap.put(WSDLConstants.MEP_URI_IN_OUT, MESSAGE_RECEIVER_SUFFIX + "InOut");
        //register the other types as necessary
    }

    //~--- fields -------------------------------------------------------------
  private static final Log log = LogFactory.getLog(AxisServiceBasedMultiLanguageEmitter.class);
    protected URIResolver resolver;

    private Map infoHolder;

    CodeGenConfiguration codeGenConfiguration;

    protected TypeMapper mapper;

    private AxisService axisService;

    //a map to keep the fault classNames
    private Map fullyQualifiedFaultClassNameMap = new HashMap();
    private Map InstantiatableFaultClassNameMap = new HashMap();
    private Map faultClassNameMap = new HashMap();

    private Map instantiatableMessageClassNames = new HashMap();
    ;


    public AxisServiceBasedMultiLanguageEmitter() {
        infoHolder = new HashMap();
    }

    public void setCodeGenConfiguration(CodeGenConfiguration configuration) {
        this.codeGenConfiguration = configuration;
        this.axisService = codeGenConfiguration.getAxisService();
        resolver = new XSLTIncludeResolver(this.codeGenConfiguration.getProperties());
    }

    public void setMapper(TypeMapper mapper) {
        this.mapper = mapper;
    }


    /**
     * @see org.apache.axis2.wsdl.codegen.emitter.Emitter#emitStub()
     */
    public void emitStub() throws CodeGenerationException {

        try {
            emitStubFromService();
        } catch (Exception e) {
            throw new CodeGenerationException(e);
        }
    }

    /**
     * Update mapper for the stub
     */
    private void updateMapperForStub() {
        updateMapperClassnames(getFullyQualifiedStubName());
    }

    private String getFullyQualifiedStubName() {
        String packageName = codeGenConfiguration.getPackageName();
        String localPart = makeJavaClassName(axisService.getName());
        return packageName + "." + localPart + STUB_SUFFIX;
    }

    /**
     *
     */
    private void resetFaultNames() {
        fullyQualifiedFaultClassNameMap.clear();
        faultClassNameMap.clear();
    }

    /**
     * Populate a map of fault class names
     */
    private void generateAndPopulateFaultNames() {
        //loop through and find the faults
        Iterator operations = axisService.getOperations();
        AxisOperation operation;
        AxisMessage faultMessage;
        while (operations.hasNext()) {
            operation = (AxisOperation) operations.next();
            ArrayList faultMessages = operation.getFaultMessages();
            for (int i = 0; i < faultMessages.size(); i++) {
                faultMessage = (AxisMessage) faultMessages.get(i);
                //make a unique name and put that in the hashmap
                if (!fullyQualifiedFaultClassNameMap.
                        containsKey(faultMessage.getElementQName())) {
                    //make a name
                    String className = makeJavaClassName(faultMessage.getName()
                            + FAULT_SUFFIX);
                    while (fullyQualifiedFaultClassNameMap.containsValue(className)) {
                        className = makeJavaClassName(className + (uniqueFaultNameCounter++));
                    }

                    fullyQualifiedFaultClassNameMap.put(
                            faultMessage.getElementQName(),
                            className);
                    //this needs to be kept seperate and updated later
                    InstantiatableFaultClassNameMap.put(
                            faultMessage.getElementQName(),
                            className);
                    //we've to keep track of the fault base names seperately
                    faultClassNameMap.put(faultMessage.getElementQName(),
                            className);

                }
            }

        }
    }

    /**
     * Emits the stubcode with bindings.
     *
     * @throws Exception
     */
    private void emitStubFromService() throws Exception {

        // see the comment at updateMapperClassnames for details and reasons for
        // calling this method
        if (mapper.isObjectMappingPresent()) {
            updateMapperForStub();
        } else {
            copyToFaultMap();
        }

        //generate and populate the fault names before hand. We need that for
        //the smooth opration of the thing
        //first reset the fault names and recreate it
        resetFaultNames();
        generateAndPopulateFaultNames();
        updateFaultPackageForStub();

        // write the inteface
        // feed the binding information also
        // note that we do not create this interface if the user switched on the wrap classes mode
        if (!codeGenConfiguration.isPackClasses()) {
            writeInterface(false);
        }

        // write the call back handlers
        writeCallBackHandlers();

        // write interface implementations
        writeInterfaceImplementation();

        // write the test classes
        writeTestClasses();

        // write an ant build file
        //Note that ant build is generated only once
        //and that has to happen here only if the
        //client side code is required
        if (!codeGenConfiguration.isGenerateAll()) {
            writeAntBuild();
        }

    }

    /**
     * Writes the Ant build.
     *
     * @throws Exception
     */
    protected void writeAntBuild() throws Exception {

        // Write the service xml in a folder with the
        Document skeletonModel = createDOMDocumentForAntBuild();
        debugLogDocument("Document for ant build:", skeletonModel);
        AntBuildWriter antBuildWriter = new AntBuildWriter(codeGenConfiguration.getOutputLocation(),
                codeGenConfiguration.getOutputLanguage());

        antBuildWriter.setDatabindingFramework(codeGenConfiguration.getDatabindingType());
        writeClass(skeletonModel, antBuildWriter);
    }

    /**
     * Creates the DOM tree for the Ant build. Uses the interface.
     */
    protected Document createDOMDocumentForAntBuild() {
        Document doc = getEmptyDocument();
        Element rootElement = doc.createElement("ant");
        String serviceName = makeJavaClassName(axisService.getName());
        String packageName = codeGenConfiguration.getPackageName();
        String[]      dotSeparatedValues = packageName.split("\\.");

        addAttribute(doc, "package", dotSeparatedValues[0], rootElement);
        addAttribute(doc, "name", serviceName, rootElement);
        addAttribute(doc, "servicename", serviceName, rootElement);
        doc.appendChild(rootElement);

        return doc;
    }

    /**
     * Write the test classes
     */
    protected void writeTestClasses() throws Exception {
        if (codeGenConfiguration.isWriteTestCase()) {
            Document classModel = createDOMDocumentForTestCase();
            debugLogDocument("Document for test case:", classModel);
            TestClassWriter callbackWriter =
                    new TestClassWriter(getOutputDirectory(codeGenConfiguration.getOutputLocation(), "test"),
                            codeGenConfiguration.getOutputLanguage());

            writeClass(classModel, callbackWriter);
        }
    }

    protected Document createDOMDocumentForTestCase() {
        String coreClassName = makeJavaClassName(axisService.getName());
        Document doc = getEmptyDocument();
        Element rootElement = doc.createElement("class");

        addAttribute(doc, "package", codeGenConfiguration.getPackageName(), rootElement);
        addAttribute(doc, "name", coreClassName + TEST_SUFFIX, rootElement);
        //todo is this right ???
        addAttribute(doc, "namespace", axisService.getTargetNamespace(), rootElement);
        addAttribute(doc, "interfaceName", coreClassName, rootElement);
        addAttribute(doc, "callbackname", coreClassName + CALL_BACK_HANDLER_SUFFIX, rootElement);
        addAttribute(doc, "stubname", coreClassName + STUB_SUFFIX, rootElement);

        fillSyncAttributes(doc, rootElement);
        loadOperations(doc, rootElement, null);

        // add the databind supporters. Now the databind supporters are completly contained inside
        // the stubs implementation and not visible outside
        rootElement.appendChild(createDOMElementforDatabinders(doc));
        doc.appendChild(rootElement);

        return doc;
    }

    /**
     * Writes the implementations.
     *
     * @throws Exception
     */
    protected void writeInterfaceImplementation() throws Exception {

        // first check for the policies in this service and write them
        Document interfaceImplModel = createDOMDocumentForInterfaceImplementation();
        debugLogDocument("Document for interface implementation:", interfaceImplModel);
        InterfaceImplementationWriter writer =
                new InterfaceImplementationWriter(getOutputDirectory(codeGenConfiguration.getOutputLocation(), "src"),
                        codeGenConfiguration.getOutputLanguage());

        writeClass(interfaceImplModel, writer);
    }

    /**
     * Creates the DOM tree for implementations.
     */
    protected Document createDOMDocumentForInterfaceImplementation() throws Exception {

        String packageName = codeGenConfiguration.getPackageName();
        String localPart = makeJavaClassName(axisService.getName());
        String stubName = localPart + STUB_SUFFIX;
        Document doc = getEmptyDocument();
        Element rootElement = doc.createElement("class");

        addAttribute(doc, "package", packageName, rootElement);
        addAttribute(doc, "name", stubName, rootElement);
        addAttribute(doc, "servicename", localPart, rootElement);
        //todo is this right ??
        addAttribute(doc, "namespace", axisService.getTargetNamespace(), rootElement);
        addAttribute(doc, "interfaceName", localPart, rootElement);
        addAttribute(doc, "callbackname", localPart + CALL_BACK_HANDLER_SUFFIX, rootElement);

        // add the wrap classes flag
        if (codeGenConfiguration.isPackClasses()) {
            addAttribute(doc, "wrapped", "yes", rootElement);
        }

        // add SOAP version
        addSoapVersion(doc, rootElement);

        // add the end point
        addEndpoint(doc, rootElement);

        // set the sync/async attributes
        fillSyncAttributes(doc, rootElement);

        // ###########################################################################################
        // this block of code specifically applies to the integration of databinding code into the
        // generated classes tightly (probably as inner classes)
        // ###########################################################################################
        // check for the special models in the mapper and if they are present process them
        if (mapper.isObjectMappingPresent()) {

            // add an attribute to the root element showing that the writing has been skipped
            addAttribute(doc, "skip-write", "yes", rootElement);

            // process the mapper objects
            processModelObjects(mapper.getAllMappedObjects(), rootElement, doc);
        }

        // #############################################################################################

        // load the operations
        loadOperations(doc, rootElement, null);

        // add the databind supporters. Now the databind supporters are completly contained inside
        // the stubs implementation and not visible outside
        rootElement.appendChild(createDOMElementforDatabinders(doc));

        Object stubMethods;

        //if some extension has added the stub methods property, add them to the
        //main document
        if ((stubMethods = codeGenConfiguration.getProperty("stubMethods")) != null) {
            rootElement.appendChild(doc.importNode((Element) stubMethods, true));
        }

        //add another element to have the unique list of faults
        rootElement.appendChild(getUniqueListofFaults(doc));

        /////////////////////////////////////////////////////
        //System.out.println(DOM2Writer.nodeToString(rootElement));
        /////////////////////////////////////////////////////


        doc.appendChild(rootElement);
        return doc;
    }

    private Element getUniqueListofFaults(Document doc) {
        Element rootElement = doc.createElement("fault-list");
        Element faultElement;
        QName key;
        Iterator iterator = fullyQualifiedFaultClassNameMap.keySet().iterator();
        while (iterator.hasNext()) {
            faultElement = doc.createElement("fault");
            key = (QName) iterator.next();

            //as for the name of a fault, we generate an exception
            addAttribute(doc, "name",
                    (String) fullyQualifiedFaultClassNameMap.get(key),
                    faultElement);
            addAttribute(doc, "intantiatiableName",
                    (String) InstantiatableFaultClassNameMap.get(key),
                    faultElement);
            addAttribute(doc, "shortName",
                    (String) faultClassNameMap.get(key),
                    faultElement);

            //the type represents the type that will be wrapped by this
            //name
            String typeMapping =
                    this.mapper.getTypeMappingName(key);
            addAttribute(doc, "type", (typeMapping == null)
                    ? ""
                    : typeMapping, faultElement);
            String attribValue = (String) instantiatableMessageClassNames.
                    get(key);

            addAttribute(doc, "instantiatableType",
                    attribValue == null ? "" : attribValue,
                    faultElement);

            // add an extra attribute to say whether the type mapping is
            // the default
            if (TypeMapper.DEFAULT_CLASS_NAME.equals(typeMapping)) {
                addAttribute(doc, "default", "yes", faultElement);
            }
            addAttribute(doc, "value", getParamInitializer(typeMapping),
                    faultElement);


            rootElement.appendChild(faultElement);
        }
        return rootElement;
    }

    /**
     * Adds the endpoint to the document.
     *
     * @param doc
     * @param rootElement
     */
    protected void addEndpoint(Document doc, Element rootElement) throws Exception {

        PolicyInclude policyInclude = axisService.getPolicyInclude();
        Policy servicePolicy = policyInclude.getPolicy();

        if (servicePolicy != null) {
            String policyString = PolicyUtil.getPolicyAsString(servicePolicy);
            addAttribute(doc, "policy", policyString, rootElement);
        }

        Element endpointElement = doc.createElement("endpoint");

        String endpoint = axisService.getEndpoint();
        Text text = doc.createTextNode((endpoint != null)
                ? endpoint
                : "");

        endpointElement.appendChild(text);
        rootElement.appendChild(endpointElement);
    }

    /**
     * Looks for the SOAPVersion and adds it.
     *
     * @param doc
     * @param rootElement
     */
    protected void addSoapVersion(Document doc, Element rootElement) {

        // loop through the extensibility elements to get to the bindings element

        String soapNsUri = axisService.getSoapNsUri();
        if (Constants.URI_WSDL11_SOAP.equals(soapNsUri)) {
            addAttribute(doc, "soap-version", "1.1", rootElement);
        } else if (Constants.URI_WSDL12_SOAP.equals(soapNsUri)) {
            addAttribute(doc, "soap-version", "1.2", rootElement);
        }

    }


    /**
     * Writes the callback handlers.
     */
    protected void writeCallBackHandlers() throws Exception {
        if (codeGenConfiguration.isAsyncOn()) {
            Document interfaceModel = createDOMDocumentForCallbackHandler();
            debugLogDocument("Document for callback handler:", interfaceModel);
            CallbackHandlerWriter callbackWriter =
                    new CallbackHandlerWriter(getOutputDirectory(codeGenConfiguration.getOutputLocation(), "src"),
                            codeGenConfiguration.getOutputLanguage());

            writeClass(interfaceModel, callbackWriter);
        }
    }

    /**
     * Generates the model for the callbacks.
     */
    protected Document createDOMDocumentForCallbackHandler() {
        Document doc = getEmptyDocument();
        Element rootElement = doc.createElement("callback");

        addAttribute(doc, "package", codeGenConfiguration.getPackageName(), rootElement);
        addAttribute(doc, "name", makeJavaClassName(axisService.getName()) + CALL_BACK_HANDLER_SUFFIX, rootElement);

        // TODO JAXRPC mapping support should be considered
        this.loadOperations(doc, rootElement, null);

        doc.appendChild(rootElement);
        return doc;
    }

    /**
     * Writes the interfaces.
     *
     * @throws Exception
     */
    protected void writeInterface(boolean writeDatabinders) throws Exception {
        Document interfaceModel = createDOMDocumentForInterface(writeDatabinders);
        debugLogDocument("Document for interface:", interfaceModel);
        InterfaceWriter interfaceWriter =
                new InterfaceWriter(getOutputDirectory(codeGenConfiguration.getOutputLocation(), "src"),
                        this.codeGenConfiguration.getOutputLanguage());

        writeClass(interfaceModel, interfaceWriter);
    }

    /**
     * Creates the DOM tree for the interface creation. Uses the interface.
     */
    protected Document createDOMDocumentForInterface(boolean writeDatabinders) {
        Document doc = getEmptyDocument();
        Element rootElement = doc.createElement("interface");
        String localPart = makeJavaClassName(axisService.getName());

        addAttribute(doc, "package", codeGenConfiguration.getPackageName(), rootElement);
        addAttribute(doc, "name", localPart, rootElement);
        addAttribute(doc, "callbackname", localPart + CALL_BACK_HANDLER_SUFFIX,
                rootElement);
        fillSyncAttributes(doc, rootElement);
        loadOperations(doc, rootElement, null);

        // ###########################################################################################
        // this block of code specifically applies to the integration of databinding code into the
        // generated classes tightly (probably as inner classes)
        // ###########################################################################################
        // check for the special models in the mapper and if they are present process them
        if (writeDatabinders) {
            if (mapper.isObjectMappingPresent()) {

                // add an attribute to the root element showing that the writing has been skipped
                addAttribute(doc, "skip-write", "yes", rootElement);

                // process the mapper objects
                processModelObjects(mapper.getAllMappedObjects(), rootElement, doc);
            }
        }

        // #############################################################################################
        doc.appendChild(rootElement);

        return doc;
    }


    /**
     * Emit the skeltons
     *
     * @throws CodeGenerationException
     */
    public void emitSkeleton() throws CodeGenerationException {
        try {
            emitSkeletonService();
        } catch (Exception e) {
            throw new CodeGenerationException(e);
        }
    }

    /**
     * Update mapper for message receiver
     */
    private void updateMapperForMessageReceiver() {
        updateMapperClassnames(getFullyQualifiedMessageReceiverName());
    }

    /**
     * @return fully qualified MR name
     */
    private String getFullyQualifiedMessageReceiverName() {
        String packageName = codeGenConfiguration.getPackageName();
        String localPart = makeJavaClassName(axisService.getName());
        return packageName + "." + localPart + MESSAGE_RECEIVER_SUFFIX;
    }

    /**
     * @return fully qualified MR name
     */
    private String getFullyQualifiedSkeletonName() {
        String packageName = codeGenConfiguration.getPackageName();
        String localPart = makeJavaClassName(axisService.getName());
        return packageName + "." + localPart + SKELETON_CLASS_SUFFIX;
    }

    /**
     * @throws Exception
     */
    private void emitSkeletonService() throws Exception {
        // see the comment at updateMapperClassnames for details and reasons for
        // calling this method
        if (mapper.isObjectMappingPresent()) {
            updateMapperForMessageReceiver();
        } else {
            copyToFaultMap();
        }

        //handle faults
        generateAndPopulateFaultNames();
        updateFaultPackageForSkeleton();

        if (codeGenConfiguration.isServerSideInterface()){
            //write skeletonInterface
            writeSkeletonInterface();
        }
        // write skeleton
        writeSkeleton();

        // write a MessageReceiver for this particular service.
        writeMessageReceiver();

        // write interface implementations
        writeServiceXml();

        //write the ant build
        writeAntBuild();

        //for the server side codegen
        //we need to serialize the WSDL's
        writeWSDLFiles();
    }

    /**
     * Write out the WSDL files (and the schemas)
     * writing the WSDL (and schemas) is somewhat special so we cannot follow
     * the usual pattern of using the class writer
     */
    private void writeWSDLFiles() {
        //first modify the schema names (and locations) so that
        //they have unique (flattened) names and the schema locations
        //are adjusted to suit it
        axisService.setCustomSchemaNamePrefix("");//prefix with nothing
        axisService.setCustomSchemaNameSuffix(".xsd");//suffix with .xsd - the file name extension
        //force the mappings to be reconstructed
        axisService.setSchemaLocationsAdjusted(false);
        axisService.populateSchemaMappings();

        //now get the schema list and write it out
        SchemaWriter schemaWriter = new SchemaWriter(
                codeGenConfiguration.getOutputLocation());
        Hashtable schemaMappings = axisService.getSchemaMappingTable();
        Iterator keys = schemaMappings.keySet().iterator();
        while (keys.hasNext()) {
            Object key = keys.next();
            schemaWriter.writeSchema(
                    (XmlSchema) schemaMappings.get(key),
                    (String) key
            );
        }


        WSDLWriter wsdlWriter = new WSDLWriter(
                codeGenConfiguration.getOutputLocation());
        wsdlWriter.writeWSDL(axisService);


    }

    private void copyToFaultMap() {
        Map classNameMap = mapper.getAllMappedNames();
        Iterator keys = classNameMap.keySet().iterator();
        while (keys.hasNext()) {
            Object key = keys.next();
            instantiatableMessageClassNames.put(key,
                    classNameMap.get(key));
        }
    }

    /**
     *
     */
    private void updateFaultPackageForStub() {
        Iterator faultClassNameKeys = fullyQualifiedFaultClassNameMap.keySet().iterator();
        while (faultClassNameKeys.hasNext()) {
            Object key = faultClassNameKeys.next();
            String className = (String) fullyQualifiedFaultClassNameMap.get(key);
            //append the skelton name
            String fullyQualifiedStubName = getFullyQualifiedStubName();
            fullyQualifiedFaultClassNameMap.put(key, fullyQualifiedStubName + "."
                    + className);
            InstantiatableFaultClassNameMap.put(key, fullyQualifiedStubName + "$"
                    + className);
        }
    }

    /**
     *
     */
    private void updateFaultPackageForSkeleton() {
        Iterator faultClassNameKeys = fullyQualifiedFaultClassNameMap.keySet().iterator();
        while (faultClassNameKeys.hasNext()) {
            Object key = faultClassNameKeys.next();
            String className = (String) fullyQualifiedFaultClassNameMap.get(key);
            //append the skelton name
            String fullyQualifiedSkeletonName = getFullyQualifiedSkeletonName();
            fullyQualifiedFaultClassNameMap.put(key, fullyQualifiedSkeletonName + "."
                    + className);
            InstantiatableFaultClassNameMap.put(key, fullyQualifiedSkeletonName + "$"
                    + className);
        }
    }

    /**
     * @throws Exception
     */
    protected void writeMessageReceiver() throws Exception {

        if (codeGenConfiguration.isWriteMessageReceiver()) {
            //loop through the meps and generate code for each mep
            Iterator it = MEPtoClassMap.keySet().iterator();
            while (it.hasNext()) {
                String mep = (String) it.next();
                Document classModel = createDocumentForMessageReceiver(
                        mep,
                        codeGenConfiguration.isServerSideInterface());
                debugLogDocument("Document for message receiver:", classModel);
                //write the class only if any methods are found
                if (Boolean.TRUE.equals(infoHolder.get(mep))) {
                    MessageReceiverWriter writer =
                            new MessageReceiverWriter(getOutputDirectory(codeGenConfiguration.getOutputLocation(), "src"),
                                    codeGenConfiguration.getOutputLanguage());

                    writeClass(classModel, writer);
                }
            }
        }
    }

    protected Document createDocumentForMessageReceiver(String mep,boolean isServerSideInterface) {

        Document doc = getEmptyDocument();
        Element rootElement = doc.createElement("interface");

        addAttribute(doc, "package", codeGenConfiguration.getPackageName(), rootElement);

        String localPart = makeJavaClassName(axisService.getName());

        addAttribute(doc, "name", localPart + MEPtoSuffixMap.get(mep), rootElement);
        addAttribute(doc, "skeletonname", localPart + SKELETON_CLASS_SUFFIX, rootElement);
        if (isServerSideInterface){
            addAttribute(doc, "skeletonInterfaceName", localPart + SKELETON_INTERFACE_SUFFIX,
                    rootElement);
        }else{
             addAttribute(doc, "skeletonInterfaceName", localPart + SKELETON_CLASS_SUFFIX,
                    rootElement);
        }
        addAttribute(doc, "basereceiver", (String) MEPtoClassMap.get(mep), rootElement);
        fillSyncAttributes(doc, rootElement);

        // ###########################################################################################
        // this block of code specifically applies to the integration of databinding code into the
        // generated classes tightly (probably as inner classes)
        // ###########################################################################################
        // check for the special models in the mapper and if they are present process them
        if (mapper.isObjectMappingPresent()) {
            // add an attribute to the root element showing that the writing has been skipped
            addAttribute(doc, "skip-write", "yes", rootElement);
            // process the mapper objects
            processModelObjects(mapper.getAllMappedObjects(), rootElement, doc);
        }
        // #############################################################################################

        boolean isOpsFound = loadOperations(doc, rootElement, mep);
        //put the result in the property map
        infoHolder.put(mep, isOpsFound ? Boolean.TRUE : Boolean.FALSE);
        rootElement.appendChild(createDOMElementforDatabinders(doc));

        //attach a list of faults
        rootElement.appendChild(getUniqueListofFaults(doc));

        doc.appendChild(rootElement);

        //////////////////////////////////
        //System.out.println(DOM2Writer.nodeToString(rootElement));
        ////////////////////////////////
        return doc;
    }

    /**
     * create a dom doc for databinders
     *
     * @param doc
     */
    protected Element createDOMElementforDatabinders(Document doc) {

        // First Iterate through the operations and find the relevant fromOM and toOM methods to be generated
        Map parameterMap = new HashMap();
        Iterator operationsIterator = axisService.getOperations();

        while (operationsIterator.hasNext()) {
            AxisOperation axisOperation = (AxisOperation) operationsIterator.next();
            // Add the parameters to a map with their type as the key
            // this step is needed to remove repetitions

            // process the input parameters
            String MEP = axisOperation.getMessageExchangePattern();
            if (isInputPresentForMEP(MEP)) {
                Element inputParamElement = getInputParamElement(doc, axisOperation);
                if (inputParamElement != null) {
                    parameterMap.put(inputParamElement.getAttribute("type"), inputParamElement);
                }
            }
            // process output parameters
            if (isOutputPresentForMEP(MEP)) {
                Element outputParamElement = getOutputParamElement(doc, axisOperation);
                if (outputParamElement != null) {
                    parameterMap.put(outputParamElement.getAttribute("type"), outputParamElement);
                }
            }
            //process faults
            Element[] faultParamElements = getFaultParamElements(doc, axisOperation);
            for (int i = 0; i < faultParamElements.length; i++) {
                parameterMap.put(
                        faultParamElements[i].getAttribute("type"),
                        faultParamElements[i]);
            }

            // process the header parameters
            Element newChild;
            List headerParameterQNameList = new ArrayList();

            addHeaderOperations(headerParameterQNameList, axisOperation, true);

            List parameterElementList = getParameterElementList(doc, headerParameterQNameList, "header");

            for (int i = 0; i < parameterElementList.size(); i++) {
                newChild = (Element) parameterElementList.get(i);
                parameterMap.put(newChild.getAttribute("type"), newChild);
            }

            headerParameterQNameList.clear();
            parameterElementList.clear();
            addHeaderOperations(headerParameterQNameList, axisOperation, false);
            parameterElementList = getParameterElementList(doc, headerParameterQNameList, "header");

            for (int i = 0; i < parameterElementList.size(); i++) {
                newChild = (Element) parameterElementList.get(i);
                parameterMap.put(newChild.getAttribute("type"), newChild);
            }
        }

        Element rootElement = doc.createElement("databinders");

        addAttribute(doc, "dbtype", codeGenConfiguration.getDatabindingType(), rootElement);

        // add the names of the elements that have base 64 content
        // if the base64 name list is missing then this whole step is skipped
        rootElement.appendChild(getBase64Elements(doc));

        // Now run through the parameters and add them to the root element
        Collection parameters = parameterMap.values();

        for (Iterator iterator = parameters.iterator(); iterator.hasNext();) {
            rootElement.appendChild((Element) iterator.next());
        }

        return rootElement;
    }

    private boolean isInputPresentForMEP(String MEP) {
        return WSDLConstants.MEP_URI_IN_ONLY.equals(MEP) ||
                WSDLConstants.MEP_URI_IN_OPTIONAL_OUT.equals(MEP) ||
                WSDLConstants.MEP_URI_OUT_OPTIONAL_IN.equals(MEP) ||
                WSDLConstants.MEP_URI_ROBUST_OUT_ONLY.equals(MEP) ||
                WSDLConstants.MEP_URI_ROBUST_IN_ONLY.equals(MEP) ||
                WSDLConstants.MEP_URI_IN_OUT.equals(MEP);
    }

    /**
     * Gets the base64 types. If not available this will be empty!!!
     *
     * @param doc
     * @return Returns Element.
     */
    private Element getBase64Elements(Document doc) {
        Element root = doc.createElement("base64Elements");
        Element elt;
        QName qname;

        // this is a list of QNames
        List list = (List) codeGenConfiguration.getProperties().get(XSLTConstants.BASE_64_PROPERTY_KEY);

        if ((list != null) && !list.isEmpty()) {
            int count = list.size();

            for (int i = 0; i < count; i++) {
                qname = (QName) list.get(i);
                elt = doc.createElement("name");
                addAttribute(doc, "ns-url", qname.getNamespaceURI(), elt);
                addAttribute(doc, "localName", qname.getLocalPart(), elt);
                root.appendChild(elt);
            }
        }

        return root;
    }

    /**
     * @param objectMappings
     * @param root
     * @param doc
     */
    private void processModelObjects(Map objectMappings, Element root, Document doc) {
        Iterator objectIterator = objectMappings.values().iterator();

        while (objectIterator.hasNext()) {
            Object o = objectIterator.next();

            if (o instanceof Document) {
                root.appendChild(doc.importNode(((Document) o).getDocumentElement(), true));
            } else {

                // oops we have no idea how to do this, if the model provided is not a DOM document
                // we are done. we might as well skip  it here
            }
        }
    }

    /**
     * we need to modify the mapper's class name list. The issue here is that in this case we do not
     * expect the fully qulified class names to be present in the class names list due to the simple
     * reason that they've not been written yet! Hence the mappers class name list needs to be updated
     * to suit the expected package to be written
     * in this case we modify the package name to have make the class a inner class of the stub,
     * interface or the message receiver depending on the style
     */
    private void updateMapperClassnames(String fullyQulifiedIncludingClassNamePrefix) {
        Map classNameMap = mapper.getAllMappedNames();
        Iterator keys = classNameMap.keySet().iterator();

        while (keys.hasNext()) {
            Object key = keys.next();
            String className = (String) classNameMap.get(key);
            classNameMap.put(key, fullyQulifiedIncludingClassNamePrefix + "." + className);
            instantiatableMessageClassNames.put(key,
                    fullyQulifiedIncludingClassNamePrefix + "$" + className);
        }
    }

    /**
     * Write the service XML
     *
     * @throws Exception
     */
    private void writeServiceXml() throws Exception {
        if (this.codeGenConfiguration.isGenerateDeployementDescriptor()) {

            // Write the service xml in a folder with the
            Document serviceXMLModel = createDOMDocumentForServiceXML();
            debugLogDocument("Document for service XML:", serviceXMLModel);
            ClassWriter serviceXmlWriter =
                    new ServiceXMLWriter(getOutputDirectory(this.codeGenConfiguration.getOutputLocation(), "resources"),
                            this.codeGenConfiguration.getOutputLanguage());

            writeClass(serviceXMLModel, serviceXmlWriter);
        }
    }

    private Document createDOMDocumentForServiceXML() {
        Document doc = getEmptyDocument();
        String serviceName = axisService.getName();
        String className = makeJavaClassName(serviceName);

        doc.appendChild(getServiceElement(serviceName, className, doc));
        return doc;

    }

    private Node getServiceElement(String serviceName, String className, Document doc) {
        Element rootElement = doc.createElement("interface");

        addAttribute(doc, "package", "", rootElement);
        addAttribute(doc, "classpackage", codeGenConfiguration.getPackageName(), rootElement);
        addAttribute(doc, "name", className + SKELETON_CLASS_SUFFIX, rootElement);
        if (!codeGenConfiguration.isWriteTestCase()) {
            addAttribute(doc, "testOmit", "true", rootElement);
        }
        addAttribute(doc, "servicename", serviceName, rootElement);

        Iterator it = MEPtoClassMap.keySet().iterator();
        while (it.hasNext()) {
            Object key = it.next();

            if (Boolean.TRUE.equals(infoHolder.get(key))) {
                Element elt = addElement(doc, "messagereceiver", className + MEPtoSuffixMap.get(key), rootElement);
                addAttribute(doc, "mep", key.toString(), elt);
            }

        }

        loadOperations(doc, rootElement, null);

        return rootElement;
    }

    private void writeSkeleton() throws Exception {
        Document skeletonModel = createDOMDocumentForSkeleton(codeGenConfiguration.isServerSideInterface());
        debugLogDocument("Document for skeleton:", skeletonModel);
        ClassWriter skeletonWriter = new SkeletonWriter(getOutputDirectory(this.codeGenConfiguration.getOutputLocation(),
                "src"), this.codeGenConfiguration.getOutputLanguage());

        writeClass(skeletonModel, skeletonWriter);
    }

    /**
     * Write the skeletonInterface
     *
     * @throws Exception
     */
    private void writeSkeletonInterface() throws Exception {
        Document skeletonModel = createDOMDocumentForSkeletonInterface();
        debugLogDocument("Document for skeleton Interface:", skeletonModel);
        ClassWriter skeletonInterfaceWriter = new SkeletonInterfaceWriter(getOutputDirectory(this.codeGenConfiguration.getOutputLocation(),
                "src"), this.codeGenConfiguration.getOutputLanguage());

        writeClass(skeletonModel, skeletonInterfaceWriter);
    }


    private Document createDOMDocumentForSkeleton(boolean isSkeletonInterface) {
        Document doc = getEmptyDocument();
        Element rootElement = doc.createElement("interface");

        String serviceName = makeJavaClassName(axisService.getName());
        addAttribute(doc, "package", codeGenConfiguration.getPackageName(), rootElement);
        addAttribute(doc, "name", serviceName + SKELETON_CLASS_SUFFIX, rootElement);
        addAttribute(doc, "callbackname", serviceName + CALL_BACK_HANDLER_SUFFIX,
                rootElement);
        if (isSkeletonInterface){
            addAttribute(doc, "skeletonInterfaceName", serviceName + SKELETON_INTERFACE_SUFFIX,
                    rootElement);
        }
        fillSyncAttributes(doc, rootElement);
        loadOperations(doc, rootElement, null);

        //attach a list of faults
        rootElement.appendChild(getUniqueListofFaults(doc));

        doc.appendChild(rootElement);
        return doc;

    }

    private Document createDOMDocumentForSkeletonInterface() {
        Document doc = getEmptyDocument();
        Element rootElement = doc.createElement("interface");

        String serviceName = makeJavaClassName(axisService.getName());
        addAttribute(doc, "package", codeGenConfiguration.getPackageName(), rootElement);
        addAttribute(doc, "name", serviceName + SKELETON_INTERFACE_SUFFIX, rootElement);
        addAttribute(doc, "callbackname", serviceName + CALL_BACK_HANDLER_SUFFIX,
                rootElement);

        fillSyncAttributes(doc, rootElement);
        loadOperations(doc, rootElement, null);

        //attach a list of faults
        rootElement.appendChild(getUniqueListofFaults(doc));

        doc.appendChild(rootElement);
        return doc;

    }

    private boolean loadOperations(Document doc, Element rootElement, String mep) {
        Element methodElement;
        String portTypeName = makeJavaClassName(axisService.getName());

        Iterator operations = axisService.getOperations();
        boolean opsFound = false;
        while (operations.hasNext()) {
            AxisOperation axisOperation = (AxisOperation) operations.next();

            // populate info holder with mep information. This will used in determining which
            // message receiver to use, etc.,

            String messageExchangePattern = axisOperation.getMessageExchangePattern();
            if (infoHolder.get(messageExchangePattern) == null) {
                infoHolder.put(messageExchangePattern, Boolean.TRUE);
            }

            if (mep == null) {

                opsFound = true;

                List soapHeaderInputParameterList = new ArrayList();
                List soapHeaderOutputParameterList = new ArrayList();

                methodElement = doc.createElement("method");

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

                addAttribute(doc, "name", localPart, methodElement);
                addAttribute(doc, "namespace", axisOperation.getName().getNamespaceURI(), methodElement);
                String style = axisOperation.getStyle();
                addAttribute(doc, "style", style, methodElement);
                addAttribute(doc, "dbsupportname", portTypeName + localPart + DATABINDING_SUPPORTER_NAME_SUFFIX,
                        methodElement);

                addAttribute(doc, "mep", axisOperation.getMessageExchangePattern(), methodElement);

                addSOAPAction(doc, methodElement, axisOperation);
                //add header ops for input
                addHeaderOperations(soapHeaderInputParameterList, axisOperation, true);
                //add header ops for output
                addHeaderOperations(soapHeaderOutputParameterList, axisOperation, false);

                PolicyInclude policyInclude = axisOperation.getPolicyInclude();
                Policy policy = policyInclude.getPolicy();
                if (policy != null) {
                    addAttribute(doc, "policy", PolicyUtil.getPolicyAsString(policy), methodElement);
                }

                methodElement.appendChild(getInputElement(doc, axisOperation, soapHeaderInputParameterList));
                methodElement.appendChild(getOutputElement(doc, axisOperation, soapHeaderOutputParameterList));
                methodElement.appendChild(getFaultElement(doc, axisOperation));

                rootElement.appendChild(methodElement);
            } else {
                //mep is present - we move ahead only if the given mep matches the mep of this operation

                if (mep.equals(axisOperation.getMessageExchangePattern())) {
                    //at this point we know it's true
                    opsFound = true;
                    List soapHeaderInputParameterList = new ArrayList();
                    List soapHeaderOutputParameterList = new ArrayList();
                    methodElement = doc.createElement("method");
                    String localPart = axisOperation.getName().getLocalPart();

                    addAttribute(doc, "name", localPart, methodElement);
                    addAttribute(doc, "namespace", axisOperation.getName().getNamespaceURI(), methodElement);
                    addAttribute(doc, "style", axisOperation.getStyle(), methodElement);
                    addAttribute(doc, "dbsupportname", portTypeName + localPart + DATABINDING_SUPPORTER_NAME_SUFFIX,
                            methodElement);

                    addAttribute(doc, "mep", axisOperation.getMessageExchangePattern(), methodElement);


                    addSOAPAction(doc, methodElement, axisOperation);
                    addHeaderOperations(soapHeaderInputParameterList, axisOperation, true);
                    addHeaderOperations(soapHeaderOutputParameterList, axisOperation, false);

                    /*
                     * Setting the policy of the operation
                     */

                    Policy policy = axisOperation.getPolicyInclude().getPolicy();
                    if (policy != null) {
                        addAttribute(doc, "policy",
                                PolicyUtil.getPolicyAsString(policy),
                                methodElement);
                    }


                    methodElement.appendChild(getInputElement(doc,
                            axisOperation, soapHeaderInputParameterList));
                    methodElement.appendChild(getOutputElement(doc,
                            axisOperation, soapHeaderOutputParameterList));
                    methodElement.appendChild(getFaultElement(doc,
                            axisOperation));

                    rootElement.appendChild(methodElement);
                    //////////////////////
                }
            }

        }

        return opsFound;
    }

    // ==================================================================
    //                   Util Methods
    // ==================================================================

    private Document getEmptyDocument() {
        try {
            DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            return documentBuilder.newDocument();
        } catch (ParserConfigurationException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @param word
     * @return Returns character removed string.
     */
    protected String makeJavaClassName(String word) {
        if (JavaUtils.isJavaKeyword(word)) {
            return JavaUtils.makeNonJavaKeyword(word);
        } else {
            return JavaUtils.capitalizeFirstChar(JavaUtils.xmlNameToJava(word));
        }
    }

    /**
     * Utility method to add an attribute to a given element.
     *
     * @param document
     * @param AttribName
     * @param attribValue
     * @param element
     */
    protected void addAttribute(Document document, String AttribName, String attribValue, Element element) {
        XSLTUtils.addAttribute(document, AttribName, attribValue, element);
    }

    /**
     * @param doc
     * @param rootElement
     */
    private void fillSyncAttributes(Document doc, Element rootElement) {
        addAttribute(doc, "isAsync", this.codeGenConfiguration.isAsyncOn()
                ? "1"
                : "0", rootElement);
        addAttribute(doc, "isSync", this.codeGenConfiguration.isSyncOn()
                ? "1"
                : "0", rootElement);
    }

    /**
     * debugging method - write the output to the debugger
     *
     * @param description
     * @param doc
     */
    private void debugLogDocument(String description, Document doc) {
        if (log.isDebugEnabled()) {
            try {
                DOMSource source = new DOMSource(doc);
                StringWriter swrite = new StringWriter();
                swrite.write(description);
                swrite.write("\n");
                Transformer transformer =
                        TransformerFactory.newInstance().newTransformer();
                transformer.setOutputProperty("omit-xml-declaration", "yes");
                transformer.setOutputProperty(OutputKeys.INDENT, "yes");
                transformer.transform(source, new StreamResult(swrite));
                log.debug(swrite.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Gets the output directory for source files.
     *
     * @param outputDir
     * @return Returns File.
     */
    protected File getOutputDirectory(File outputDir, String dir2) {
        outputDir = new File(outputDir, dir2);

        if (!outputDir.exists()) {
            outputDir.mkdirs();
        }

        return outputDir;
    }

    /**
     * A resusable method for the implementation of interface and implementation writing.
     *
     * @param model
     * @param writer
     * @throws java.io.IOException
     * @throws Exception
     */
    protected void writeClass(Document model, ClassWriter writer) throws IOException, Exception {
        writer.loadTemplate();

        String packageName = model.getDocumentElement().getAttribute("package");
        String className = model.getDocumentElement().getAttribute("name");

        writer.createOutFile(packageName, className);

        // use the global resolver
        writer.parse(model, resolver);
    }

    /**
     * Adds the soap action
     *
     * @param doc
     * @param rootElement
     * @param axisOperation
     */
    private void addSOAPAction(Document doc, Element rootElement, AxisOperation axisOperation) {
        addAttribute(doc, "soapaction", axisOperation.getSoapAction(), rootElement);
    }

    /**
     * populate the header parameters
     *
     * @param soapHeaderParameterQNameList
     * @param axisOperation
     * @param input
     */
    private void addHeaderOperations(List soapHeaderParameterQNameList, AxisOperation axisOperation,
                                     boolean input) {
        ArrayList headerparamList = new ArrayList();
        String MEP = axisOperation.getMessageExchangePattern();
        if (input) {
            if (isInputPresentForMEP(MEP)) {
                AxisMessage inaxisMessage = axisOperation
                        .getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
                if (inaxisMessage != null) {
                    headerparamList = inaxisMessage.getSoapHeaders();

                }
            }
        } else {
            if (isOutputPresentForMEP(MEP)) {
                AxisMessage outAxisMessage = axisOperation
                        .getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
                if (outAxisMessage != null) {
                    headerparamList = outAxisMessage.getSoapHeaders();
                }
            }
        }

        for (Iterator iterator = headerparamList.iterator(); iterator.hasNext();) {
            SOAPHeaderMessage header = (SOAPHeaderMessage) iterator.next();
            soapHeaderParameterQNameList.add(header.getElement());
        }
    }

    private boolean isOutputPresentForMEP(String MEP) {
        return WSDLConstants.MEP_URI_OUT_ONLY.equals(MEP) ||
                WSDLConstants.MEP_URI_OUT_OPTIONAL_IN.equals(MEP) ||
                WSDLConstants.MEP_URI_IN_OPTIONAL_OUT.equals(MEP) ||
                WSDLConstants.MEP_URI_ROBUST_OUT_ONLY.equals(MEP) ||
                WSDLConstants.MEP_URI_ROBUST_IN_ONLY.equals(MEP) ||
                WSDLConstants.MEP_URI_IN_OUT.equals(MEP);
    }

    protected Element getInputElement(Document doc, AxisOperation operation, List headerParameterQNameList) {
        Element inputElt = doc.createElement("input");
        String MEP = operation.getMessageExchangePattern();
        if (isInputPresentForMEP(MEP)) {
            Element param = getInputParamElement(doc, operation);

            if (param != null) {
                inputElt.appendChild(param);
            }

            List parameterElementList = getParameterElementList(doc, headerParameterQNameList, "header");

            for (int i = 0; i < parameterElementList.size(); i++) {
                inputElt.appendChild((Element) parameterElementList.get(i));
            }
        }
        return inputElt;
    }

    /**
     * Get the fault element - No header faults are supported
     *
     * @param doc
     * @param operation
     */
    protected Element getFaultElement(Document doc, AxisOperation operation) {
        Element faultElt = doc.createElement("fault");
        Element[] param = getFaultParamElements(doc, operation);

        for (int i = 0; i < param.length; i++) {
            faultElt.appendChild(param[i]);
        }

        return faultElt;
    }

    /**
     * Finds the output element.
     *
     * @param doc
     * @param operation
     * @param headerParameterQNameList
     */
    protected Element getOutputElement(Document doc, AxisOperation operation, List headerParameterQNameList) {
        Element outputElt = doc.createElement("output");
        String MEP = operation.getMessageExchangePattern();
        if (isOutputPresentForMEP(MEP)) {
            Element param = getOutputParamElement(doc, operation);

            if (param != null) {
                outputElt.appendChild(param);
            }

            List outputElementList = getParameterElementList(doc, headerParameterQNameList, "header");
            for (int i = 0; i < outputElementList.size(); i++) {
                outputElt.appendChild((Element) outputElementList.get(i));
            }
        }
        return outputElt;
    }

    /**
     * @param doc
     * @param operation
     * @return Returns the parameter element.
     */
    private Element[] getFaultParamElements(Document doc, AxisOperation operation) {
        ArrayList params = new ArrayList();
        ArrayList faultMessages = operation.getFaultMessages();

        if (faultMessages != null && !faultMessages.isEmpty()) {
            Element paramElement;
            AxisMessage msg;
            for (int i = 0; i < faultMessages.size(); i++) {
                paramElement = doc.createElement("param");
                msg = (AxisMessage) faultMessages.get(i);

                //as for the name of a fault, we generate an exception
                addAttribute(doc, "name",
                        (String) fullyQualifiedFaultClassNameMap.get(msg.getElementQName()),
                        paramElement);
                addAttribute(doc, "intantiatiableName",
                        (String) InstantiatableFaultClassNameMap.get(msg.getElementQName()),
                        paramElement);
                addAttribute(doc, "shortName",
                        (String) faultClassNameMap.get(msg.getElementQName()),
                        paramElement);

                // attach the namespace and the localName
                addAttribute(doc, "namespace",
                        msg.getElementQName().getNamespaceURI(),
                        paramElement);
                addAttribute(doc, "localname",
                        msg.getElementQName().getLocalPart(),
                        paramElement);
                //the type represents the type that will be wrapped by this
                //name
                String typeMapping =
                        this.mapper.getTypeMappingName(msg.getElementQName());
                addAttribute(doc, "type", (typeMapping == null)
                        ? ""
                        : typeMapping, paramElement);
                String attribValue = (String) instantiatableMessageClassNames.
                        get(msg.getElementQName());

                addAttribute(doc, "instantiatableType",
                        attribValue == null ? "" : attribValue,
                        paramElement);

                // add an extra attribute to say whether the type mapping is
                // the default
                if (TypeMapper.DEFAULT_CLASS_NAME.equals(typeMapping)) {
                    addAttribute(doc, "default", "yes", paramElement);
                }
                addAttribute(doc, "value", getParamInitializer(typeMapping),
                        paramElement);

                Iterator iter = msg.getExtensibilityAttributes().iterator();
                while (iter.hasNext()) {
                    //TODO : implement this
//
                }
                params.add(paramElement);
            }

            return (Element[]) params.toArray(new Element[params.size()]);
        } else {
            return new Element[]{};//return empty array
        }


    }


    /**
     * @param doc
     * @param operation
     * @return Returns the parameter element.
     */
    private Element getInputParamElement(Document doc, AxisOperation operation) {
        Element param = doc.createElement("param");
        AxisMessage inputMessage = operation.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);

        if (inputMessage != null) {
            addAttribute(doc, "name", this.mapper.getParameterName(inputMessage.getElementQName()), param);

            // todo modify the code here to unwrap if requested
            String typeMapping = this.mapper.getTypeMappingName(inputMessage.getElementQName());

            addAttribute(doc, "type", (typeMapping == null)
                    ? ""
                    : typeMapping, param);

            // add an extra attribute to say whether the type mapping is the default
            if (TypeMapper.DEFAULT_CLASS_NAME.equals(typeMapping)) {
                addAttribute(doc, "default", "yes", param);
            }

            addAttribute(doc, "value", getParamInitializer(typeMapping), param);

            // add this as a body parameter
            addAttribute(doc, "location", "body", param);

            Iterator iter = inputMessage.getExtensibilityAttributes().iterator();

            while (iter.hasNext()) {
                //TODO : pls implement this
//                WSDLExtensibilityAttribute att = (WSDLExtensibilityAttribute) iter.next();
//                addAttribute(doc, att.getKey().getLocalPart(), att.getValue().toString(), param);
            }
        } else {
            param = null;
        }

        return param;
    }

    /**
     * @param doc
     * @param operation
     * @return Returns Element.
     */
    private Element getOutputParamElement(Document doc, AxisOperation operation) {
        Element param = doc.createElement("param");
        AxisMessage outputMessage = operation.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
        String typeMappingStr;
        String parameterName;

        if (outputMessage != null) {
            parameterName = this.mapper.getParameterName(outputMessage.getElementQName());
            String typeMapping = this.mapper.getTypeMappingName(outputMessage.getElementQName());
            typeMappingStr = (typeMapping == null)
                    ? ""
                    : typeMapping;
        } else {
            parameterName = "";
            typeMappingStr = "";
        }

        addAttribute(doc, "name", parameterName, param);
        addAttribute(doc, "type", typeMappingStr, param);

        // add an extra attribute to say whether the type mapping is the default
        if (TypeMapper.DEFAULT_CLASS_NAME.equals(typeMappingStr)) {
            addAttribute(doc, "default", "yes", param);
        }

        // add this as a body parameter
        addAttribute(doc, "location", "body", param);

        return param;
    }

    /**
     * @param paramType
     */
    private String getParamInitializer(String paramType) {

        // Look up paramType in the table
        String out = (String) constructorMap.get(paramType);

        if (out == null) {
            out = "null";
        }

        return out;
    }

    /**
     * @param doc
     * @param parameters
     * @param location
     */
    private List getParameterElementList(Document doc, List parameters, String location) {
        List parameterElementList = new ArrayList();

        if ((parameters != null) && !parameters.isEmpty()) {
            int count = parameters.size();

            for (int i = 0; i < count; i++) {
                Element param = doc.createElement("param");
                QName name = (QName) parameters.get(i);

                addAttribute(doc, "name", this.mapper.getParameterName(name), param);

                String typeMapping = this.mapper.getTypeMappingName(name);
                String typeMappingStr = (typeMapping == null)
                        ? ""
                        : typeMapping;

                addAttribute(doc, "type", typeMappingStr, param);
                addAttribute(doc, "location", location, param);
                parameterElementList.add(param);
            }
        }

        return parameterElementList;
    }

    /**
     * Utility method to add an attribute to a given element.
     *
     * @param document
     * @param eltName
     * @param eltValue
     * @param element
     */
    protected Element addElement(Document document, String eltName, String eltValue, Element element) {
        Element elt = XSLTUtils.addChildElement(document, eltName, element);
        elt.appendChild(document.createTextNode(eltValue));
        return elt;
    }

//    ///////////////////////////////////////////////////////////////////////////
//    /////////////  Utility methods to travel the schemas and
//    /**
//     * run 1 -calcualte unique names
//     * @param schemas
//     */
//    private void calcualteSchemaNames(List schemas, Hashtable nameTable) {
//        //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(i);
//                XmlSchema s = null;
//                if (item instanceof XmlSchemaExternal) {
//                    //recursively call the calculating
//                    XmlSchemaExternal externalSchema = (XmlSchemaExternal) item;
//                    s = externalSchema.getSchema();
//                    calcualteSchemaNames(Arrays.asList(
//                            new XmlSchema[]{s}),
//                            nameTable);
//                    nameTable.put(s,
//                            ("xsd" + count++));
//
//                }
//            }
//        }
//    }
//
//    /**
//     * Run 2  - adjust the names
//     * @param schemas
//     */
//    private void adjustSchemaNames(List schemas, Hashtable nameTable) {
//        //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(i);
//                if (item instanceof XmlSchemaExternal) {
//                    //recursively call the name adjusting
//                    XmlSchemaExternal xmlSchemaExternal = (XmlSchemaExternal) item;
//                    adjustSchemaNames(Arrays.asList(
//                            new XmlSchema[]{xmlSchemaExternal.getSchema()}), nameTable);
//                    xmlSchemaExternal.setSchemaLocation(
//                            //this should return the correct end point!
//                            getName() +
//                                    "?xsd=" +
//                                    nameTable.get(xmlSchemaExternal.getSchema()));
//                }
//            }
//        }
//    }
//
//    /**
//     * Swap the key,value pairs
//     *
//     * @param originalTable
//     * @return
//     */
//    private Hashtable swapMappingTable(Hashtable originalTable) {
//        Hashtable swappedTable = new Hashtable(originalTable.size());
//        Iterator keys = originalTable.keySet().iterator();
//        Object key;
//        while (keys.hasNext()) {
//            key = keys.next();
//            swappedTable.put(originalTable.get(key), key);
//        }
//
//        return swappedTable;
//    }


}
TOP

Related Classes of org.apache.axis2.wsdl.codegen.emitter.AxisServiceBasedMultiLanguageEmitter

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