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

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

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

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

import org.apache.axis2.util.JavaUtils;
import org.apache.axis2.wsdl.codegen.CodeGenConfiguration;
import org.apache.axis2.wsdl.codegen.CodeGenerationException;
import org.apache.axis2.wsdl.codegen.XSLTConstants;
import org.apache.axis2.wsdl.codegen.writer.*;
import org.apache.axis2.wsdl.databinding.TypeMapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wsdl.*;
import org.apache.wsdl.extensions.ExtensionConstants;
import org.apache.wsdl.extensions.SOAPHeader;
import org.apache.wsdl.extensions.SOAPOperation;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
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.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public abstract class MultiLanguageClientEmitter implements Emitter {

    private Log log = LogFactory.getLog(getClass());

    /*
    *  Important! These constants are used in some places in the templates. Care should
    *  be taken when changing them
    */
    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 LOCAL_TEST_SUFFIX = "LocalTest";
    private static final String SERVICE_CLASS_SUFFIX = "Skeleton";
    private static final String TEST_PACKAGE_NAME_SUFFIX = ".test";
    private static final String DATABINDING_SUPPORTER_NAME_SUFFIX = "DatabindingSupporter";
    private static final String DATABINDING_PACKAGE_NAME_SUFFIX = ".databinding";
    private static final String TEST_SERVICE_CLASS_NAME_SUFFIX = "SkeletonTest";
    private static final String MESSAGE_RECEIVER_SUFFIX = "MessageReceiver";
    private static final String SERVICE_XML_OUTPUT_FOLDER_NAME = "service_descriptors.";


    protected InputStream xsltStream = null;
    protected CodeGenConfiguration configuration;
    protected TypeMapper mapper;


    /**
     * Sets the mapper
     *
     * @param mapper
     * @see org.apache.axis2.wsdl.databinding.TypeMapper
     */
    public void setMapper(TypeMapper mapper) {
        this.mapper = mapper;
    }

    /**
     * Sets the code generator configuration
     *
     * @param configuration
     */
    public void setCodeGenConfiguration(CodeGenConfiguration configuration) {
        this.configuration = configuration;
    }
    /**
     * @see org.apache.axis2.wsdl.codegen.emitter.Emitter#emitSkeleton()
     */
    public void emitSkeleton() throws CodeGenerationException {
        try {
            //get the interface
            WSDLDescription wom = this.configuration.getWom();
            int codegenStyle = this.configuration.getCodeGenerationStyle();
            if (codegenStyle== XSLTConstants.CodegenStyle.INTERFACE){
                emitSkeletonInterface(wom);
            }else if (codegenStyle== XSLTConstants.CodegenStyle.BINDING){
                emitSkeletonBinding(wom);
            }else if (codegenStyle==XSLTConstants.CodegenStyle.AUTOMATIC){
                emitSkeletonAutomatic(wom);
            }else{
                throw new Exception("Unknown code generation style!!! " + codegenStyle);
            }

            // Call the emit stub method to generate the client side too
            // Do we need to enforce this here ?????
            // Perhaps we can introduce a flag to determine this!
            emitStub();

        } catch (Exception e) {
            throw new CodeGenerationException(e);
        }
    }
    /**
     * @see org.apache.axis2.wsdl.codegen.emitter.Emitter#emitStub()
     */
    public void emitStub() throws CodeGenerationException {
        try {
            //get the interface
            WSDLDescription wom = this.configuration.getWom();
            int codegenStyle = this.configuration.getCodeGenerationStyle();
            if (codegenStyle== XSLTConstants.CodegenStyle.INTERFACE){
                emitStubInterface(wom);
            }else if (codegenStyle== XSLTConstants.CodegenStyle.BINDING){
                emitStubBinding(wom);
            }else if (codegenStyle==XSLTConstants.CodegenStyle.AUTOMATIC){
                emitStubAutomatic(wom);
            }else{
                throw new Exception("Unknown code generation style!!! " + codegenStyle);
            }

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

    /**
     * Emit the skeleton with inteface only
     * @param wom
     */
    private void emitSkeletonInterface(WSDLDescription wom) throws Exception{

        Map interfaces = wom.getWsdlInterfaces();

        //loop through the wsdlInterfaces to generate the interface code
        //theoretically the interface should be the base for the interfaces
        Collection interfaceCollection =interfaces.values();
        for (Iterator iterator = interfaceCollection.iterator(); iterator.hasNext();) {
            WSDLInterface axisInteface = (WSDLInterface) iterator.next();
            //write skeleton
            writeSkeleton(axisInteface, null);
            //write interface implementations
            writeServiceXml(axisInteface, null);
        }


        log.info("Interface mode is selected.The following items will not be generated");
        log.info("1. Message Receiver");
    }

    /**
     * Emit the skelton with binding
     * @param wom
     */
    private void emitSkeletonBinding(WSDLDescription wom) throws Exception{
        Map bindings = wom.getBindings();
        if (bindings==null || bindings.isEmpty()){
            //asking for a code generation with a binding when a binding is
            //not present should be the cause of an Exception !
            throw new Exception("Cannot find a binding!!");

        }else{
            WSDLBinding axisBinding;
            Collection bindingCollection = bindings.values();
            for (Iterator iterator = bindingCollection.iterator(); iterator.hasNext();) {
                axisBinding  =  (WSDLBinding)iterator.next();

                //write skeleton
                writeSkeleton(axisBinding.getBoundInterface(), axisBinding);
                //write service xml
                writeServiceXml(axisBinding.getBoundInterface(), axisBinding);
                //write a MessageReceiver for this particular service.
                writeMessageReceiver(axisBinding);
            }
        }
    }

    /**
     * Skeleton emission - Automatic mode
     * @param wom
     */
    private void emitSkeletonAutomatic(WSDLDescription wom) throws Exception{
        Map bindings = wom.getBindings();
        if (bindings==null || bindings.isEmpty()){
            //No binding is not present.use the interface mode
            emitSkeletonInterface(wom);
        }else{
            //use the binding mode
            emitSkeletonBinding(wom);
        }

    }
    /**
     * Emits the stub code with the interfaces only
     * @param wom
     * @throws Exception
     */
    private void emitStubInterface(WSDLDescription wom) throws Exception{
        Map interfaces = wom.getWsdlInterfaces();
        //loop through the wsdlInterfaces to generate the interface code
        Collection interfaceCollection =interfaces.values();
        for (Iterator iterator = interfaceCollection.iterator(); iterator.hasNext();) {
            //Write the interfaces
            WSDLInterface axisInterface = (WSDLInterface) iterator.next();
            writeInterface(axisInterface, null);
            //write the call back handlers
            writeCallBackHandlers(axisInterface, null);
        }

        //log the message stating that the binding dependent parts are not generated
        log.info("Interface code generation was selected! The following items are not generated");
        log.info("1. Stub");
        log.info("2. CallbackHandler");
        log.info("3. Test Classes");
        log.info("4. Databinding Supporters");
    }

    /**
     * Emit the stubcode with bindings
     * @param wom
     * @throws Exception
     */
    private void emitStubBinding(WSDLDescription wom) throws Exception{
        Map bindings = wom.getBindings();
        if (bindings==null || bindings.isEmpty()){
            //asking for a code generation with a binding when a binding is
            //not present should be the cause of an Exception !
            throw new Exception("Cannot find a binding!!");
        }else{
            WSDLBinding axisBinding ;
            WSDLService axisService = null;
            Collection bindingCollection = bindings.values();
            for (Iterator iterator = bindingCollection.iterator(); iterator.hasNext();) {

                axisBinding  =  (WSDLBinding)iterator.next();
                //Check the service
                axisService = checkService(wom, axisService);
                //write the inteface
                //feed the binding information also
                writeInterface(axisBinding.getBoundInterface(), axisBinding);
                //write the call back handlers
                writeCallBackHandlers(axisBinding.getBoundInterface(), axisBinding);
                //write interface implementations
                writeInterfaceImplementation(axisBinding, axisService);
                //write the test classes
                writeTestClasses(axisBinding);
                //write the databinding supporters
                writeDatabindingSupporters(axisBinding);
                //write a dummy implementation call for the tests to run.
                //writeTestSkeletonImpl(axisBinding);
                //write a testservice.xml that will load the dummy skeleton impl for testing
                //writeTestServiceXML(axisBinding);
            }
        }
    }

    /**
     * emit the stubcode with the automatic mode. Look for the binding and if present
     * emit the skeleton with the binding. Else go for the interface
     * @param wom
     */
    private void emitStubAutomatic(WSDLDescription wom) throws Exception{
        Map bindings = wom.getBindings();
        if (bindings==null || bindings.isEmpty()){
            //No binding is not present.use the interface mode
            emitStubInterface(wom);
        }else{
            //use the binding mode
            emitStubBinding(wom);
        }
    }

    /**
     * Check the service for compatibility. Am incompatible service consists of
     * multiple services ATM
     * @param wom
     * @param axisService
     * @return  the WSDLService object
     */
    private WSDLService checkService(WSDLDescription wom, WSDLService axisService) {
        Map services = wom.getServices();
        if (!services.isEmpty()) {
            if (services.size() == 1) {
                axisService = (WSDLService) services.values().toArray()[0];
            } else {
                throw new UnsupportedOperationException(
                        "Single service WSDL files only");
            }
        }
        return axisService;
    }




    /**
     * Write the callback handlers
     */
    protected void writeCallBackHandlers(WSDLInterface wsdlInterface, WSDLBinding axisBinding) throws Exception {

        if (configuration.isAsyncOn()) {
            Document interfaceModel = createDOMDocumentForCallbackHandler(
                    wsdlInterface, axisBinding);
            CallbackHandlerWriter callbackWriter =
                    new CallbackHandlerWriter(
                            this.configuration.getOutputLocation(),
                            this.configuration.getOutputLanguage());
            writeClass(interfaceModel, callbackWriter);
        }

    }



    /**
     *
     */
    protected void writeTestClasses(WSDLBinding binding) throws Exception {

        if (configuration.isWriteTestCase()) {
            Document classModel = createDOMDocumentForTestCase(binding);
            TestClassWriter callbackWriter =
                    new TestClassWriter(this.configuration.getOutputLocation(),
                            this.configuration.getOutputLanguage());
            writeClass(classModel, callbackWriter);
        }

    }

    /**
     * Writes the interfaces
     * @param axisInterface
     * @param axisBinding
     * @throws Exception
     */
    protected void writeInterface(WSDLInterface axisInterface, WSDLBinding axisBinding) throws Exception {
        Document interfaceModel = createDOMDocumentForInterface(axisInterface, axisBinding);
        InterfaceWriter interfaceWriter =
                new InterfaceWriter(this.configuration.getOutputLocation(),
                        this.configuration.getOutputLanguage());
        writeClass(interfaceModel, interfaceWriter);
    }


    /**
     * Writes the skeleton
     *
     * @param axisInteface
     * @param axisBinding
     * @throws Exception
     */
    protected void writeSkeleton(WSDLInterface axisInteface, WSDLBinding axisBinding) throws Exception {

        //Note -  One can generate the skeleton using the interface XML
        Document skeletonModel = createDOMDocumentForSkeleton(axisInteface, axisBinding);
        ClassWriter skeletonWriter = new SkeletonWriter(
                this.configuration.getOutputLocation(),
                this.configuration.getOutputLanguage());
        writeClass(skeletonModel, skeletonWriter);


    }

    /**
     * Writes the skeleton
     *
     * @param axisBinding
     * @throws Exception
     */
    protected void writeDatabindingSupporters(WSDLBinding axisBinding) throws Exception {
        Collection col = axisBinding.getBoundInterface().getOperations()
                .values();

        String portTypeName = axisBinding.getBoundInterface().getName().getLocalPart();
        for (Iterator iterator = col.iterator(); iterator.hasNext();) {
            //Note -  there will be a supporter generated per method and will contain the methods to serilize and
            //deserailize the relevant objects

            WSDLOperation operation = (WSDLOperation) iterator.next();
            WSDLBindingOperation bindingop = axisBinding.getBindingOperation(operation.getName());
            Document databindingSupporterModel = createDOMDocumentforSerialization(
                    operation,portTypeName, bindingop);
            ClassWriter databindingSupportWriter = new DatabindingSupportClassWriter(
                    this.configuration.getOutputLocation(),
                    this.configuration.getOutputLanguage(),
                    this.configuration.getDatabindingType());
            writeClass(databindingSupporterModel, databindingSupportWriter);
        }

    }


    /**
     * Writes the skeleton
     *
     * @param axisInterface
     * @param axisBinding
     * @throws Exception
     */
    protected void writeServiceXml(WSDLInterface axisInterface, WSDLBinding axisBinding) throws Exception {
        if (this.configuration.isGenerateDeployementDescriptor()) {
            //Write the service xml in a folder with the
            Document skeletonModel = createDOMDocumentForServiceXML(
                    axisInterface, false, axisBinding);
            ClassWriter serviceXmlWriter = new ServiceXMLWriter(
                    this.configuration.getOutputLocation(),
                    this.configuration.getOutputLanguage());
            writeClass(skeletonModel, serviceXmlWriter);
        }
    }


    /**
     * Writes the implementations
     *
     * @param axisBinding
     * @throws Exception
     */
    protected void writeInterfaceImplementation(WSDLBinding axisBinding,
                                                WSDLService service) throws Exception {
        Document interfaceImplModel = createDOMDocumentForInterfaceImplementation(
                axisBinding, service);
        InterfaceImplementationWriter writer =
                new InterfaceImplementationWriter(
                        this.configuration.getOutputLocation(),
                        this.configuration.getOutputLanguage());
        writeClass(interfaceImplModel, writer);
    }

    protected void writeMessageReceiver(WSDLBinding axisBinding) throws Exception {
        if (configuration.isWriteMessageReceiver()) {
            Document classModel = createDocumentForMessageReceiver(
                    axisBinding);
            MessageReceiverWriter writer =
                    new MessageReceiverWriter(
                            this.configuration.getOutputLocation(),
                            this.configuration.getOutputLanguage());
            writeClass(classModel, writer);
        }
    }



    /**
     * A resusable method for the implementation of interface and implementation writing
     *
     * @param model
     * @param writer
     * @throws IOException
     * @throws Exception
     */
    protected void writeClass(Document model, ClassWriter writer) throws IOException,
            Exception {
        ByteArrayOutputStream memoryStream = new ByteArrayOutputStream();
        // Use a Transformer for output
        TransformerFactory tFactory =
                TransformerFactory.newInstance();
        Transformer transformer = tFactory.newTransformer();

        DOMSource source = new DOMSource(model);
        StreamResult result = new StreamResult(memoryStream);
        transformer.transform(source, result);

        writer.loadTemplate();
        writer.createOutFile(
                model.getDocumentElement().getAttribute("package"),
                model.getDocumentElement().getAttribute("name"));
        writer.writeOutFile(
                new ByteArrayInputStream(memoryStream.toByteArray()));
    }




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

    /**
     * Generating the model for the callbacks
     * @param boundInterface
     * @param axisBinding
     */
    protected Document createDOMDocumentForCallbackHandler(
            WSDLInterface boundInterface, WSDLBinding axisBinding) {
        Document doc = getEmptyDocument();
        Element rootElement = doc.createElement("callback");
        addAttribute(doc,
                "package",
                configuration.getPackageName(),
                rootElement);
        addAttribute(doc,
                "name",
                reformatName(boundInterface.getName().getLocalPart(),false) +
                        CALL_BACK_HANDLER_SUFFIX,
                rootElement);
        addAttribute(doc,
                "namespace",
                boundInterface.getName().getNamespaceURI(),
                rootElement);

        //TODO JAXRPC mapping support should be considered
        this.loadOperations(boundInterface, doc, rootElement,axisBinding);
        //this.loadOperations(boundInterface, doc, rootElement, "on", "Complete");

        doc.appendChild(rootElement);
        return doc;
    }



    /**
     * Finds the input element for the xml document
     *
     * @param doc
     * @param operation
     * @param headerParameterQNameList
     */
    protected Element getInputElement(Document doc,
                                      WSDLOperation operation, List headerParameterQNameList) {
        Element inputElt = doc.createElement("input");
        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;
    }





    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.getTypeMapping(name);
                String typeMappingStr = typeMapping == null ? "" : typeMapping;
                addAttribute(doc, "type", typeMappingStr, param);
                addAttribute(doc,"location",location,param);
                parameterElementList.add(param);
            }

        }
        return parameterElementList;
    }

    /**
     *
     * @param doc
     * @param operation
     * @return the parameter element
     */
    private Element getInputParamElement(Document doc,
                                         WSDLOperation operation) {
        //todo this should go in a loop
        Element param = doc.createElement("param");
        MessageReference inputMessage = operation.getInputMessage();
        if (inputMessage!=null){
            addAttribute(doc,
                    "name",
                    this.mapper.getParameterName(inputMessage.getElement()),
                    param);
            String typeMapping = this.mapper.getTypeMapping(
                    inputMessage.getElement());
            String typeMappingStr = typeMapping == null ? "org.apache.axis2.om.OMElement" : typeMapping;
            addAttribute(doc, "type", typeMappingStr, param);
            //add this as a body parameter
            addAttribute(doc,"location","body",param);
            Iterator iter = inputMessage.getExtensibilityAttributes().iterator();
            while(iter.hasNext()){
                WSDLExtensibilityAttribute att = (WSDLExtensibilityAttribute) iter.next();
                addAttribute(doc, att.getKey().getLocalPart(), att.getValue().toString(), param);
            }
        }else{
            param = null;
        }



        return param;
    }

    /**
     * Finds the output element for the output element
     *
     * @param doc
     * @param operation
     * @param headerParameterQNameList
     */
    protected Element getOutputElement(Document doc,
                                       WSDLOperation operation, List headerParameterQNameList) {
        Element outputElt = doc.createElement("output");
        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;
    }


    private Element getOutputParamElement(Document doc,
                                          WSDLOperation operation) {
        Element param = doc.createElement("param");
        MessageReference outputMessage = operation.getOutputMessage();
        String typeMappingStr;
        String parameterName;

        if (outputMessage!=null){
            parameterName =  this.mapper.getParameterName(
                    outputMessage.getElement()) ;
            String typeMapping = this.mapper.getTypeMapping(
                    operation.getOutputMessage().getElement());
            typeMappingStr = typeMapping == null ? "" : typeMapping;

        }else{
            parameterName = "" ;
            typeMappingStr = "";
        }
        addAttribute(doc,"name",parameterName,param);
        addAttribute(doc,"type", typeMappingStr, param);
        //add this as a body parameter
        addAttribute(doc,"location","body",param);

        return param;
    }




    protected Document createDOMDocumentForServiceXML(WSDLInterface boundInterface,
                                                      boolean forTesting, WSDLBinding axisBinding) {

        Document doc = getEmptyDocument();
        Element rootElement = doc.createElement("interface");
        String localPart = reformatName(boundInterface.getName().getLocalPart(),false);
        if (forTesting) {
            addAttribute(doc,
                    "package",
                    configuration.getPackageName() + TEST_PACKAGE_NAME_SUFFIX,
                    rootElement);
            addAttribute(doc,
                    "name",
                    localPart + TEST_SERVICE_CLASS_NAME_SUFFIX,
                    rootElement);
            addAttribute(doc,
                    "servicename",
                    localPart + TEST_SERVICE_CLASS_NAME_SUFFIX,
                    rootElement);
        } else {
            //put the package to be SERVICE_XML_OUTPUT_FOLDER_NAME.interface name
            //this forces the service XML to be written in a folder of it's porttype
            //name
            addAttribute(doc,
                    "package",
                    SERVICE_XML_OUTPUT_FOLDER_NAME+localPart,
                    rootElement);
            addAttribute(doc,
                    "classpackage",
                    configuration.getPackageName(),
                    rootElement);
            addAttribute(doc,
                    "name",
                    localPart + SERVICE_CLASS_SUFFIX,
                    rootElement);
            addAttribute(doc, "servicename", localPart, rootElement);
        }

        addAttribute(doc,
                "messagereceiver",
                localPart + MESSAGE_RECEIVER_SUFFIX,
                rootElement);
        fillSyncAttributes(doc, rootElement);
        loadOperations(boundInterface, doc, rootElement,axisBinding);
        doc.appendChild(rootElement);

        return doc;
    }


    protected Document createDocumentForMessageReceiver(WSDLBinding binding) {
        WSDLInterface boundInterface = binding.getBoundInterface();

        Document doc = getEmptyDocument();
        Element rootElement = doc.createElement("interface");
        addAttribute(doc,
                "package",
                configuration.getPackageName(),
                rootElement);
        String localPart = reformatName(boundInterface.getName().getLocalPart(),false);
        addAttribute(doc,
                "name",
                localPart + MESSAGE_RECEIVER_SUFFIX,
                rootElement);
        addAttribute(doc,
                "skeletonname",
                localPart + SERVICE_CLASS_SUFFIX,
                rootElement);
        addAttribute(doc,
                "basereceiver",
                "org.apache.axis2.receivers.AbstractInOutSyncMessageReceiver",
                rootElement);
        addAttribute(doc,
                "dbsupportpackage",
                configuration.getPackageName() +
                        DATABINDING_PACKAGE_NAME_SUFFIX,
                rootElement);
        fillSyncAttributes(doc, rootElement);
        loadOperations(boundInterface, doc, rootElement, binding);
        doc.appendChild(rootElement);


        return doc;
    }

    /**
     * Creates the DOM tree for the interface creation. Uses the interface
     * @param wsdlInterface
     * @param axisBinding
     */
    protected Document createDOMDocumentForInterface(WSDLInterface wsdlInterface, WSDLBinding axisBinding) {

        Document doc = getEmptyDocument();
        Element rootElement = doc.createElement("interface");
        String localPart = reformatName(wsdlInterface.getName().getLocalPart(),false);
        addAttribute(doc,
                "package",
                configuration.getPackageName(),
                rootElement);

        addAttribute(doc,
                "name",
                localPart,
                rootElement);
        addAttribute(doc,
                "callbackname",
                wsdlInterface.getName().getLocalPart() +
                        CALL_BACK_HANDLER_SUFFIX,
                rootElement);
        fillSyncAttributes(doc, rootElement);
        loadOperations(wsdlInterface, doc, rootElement,axisBinding);
        doc.appendChild(rootElement);
        return doc;

    }


    /**
     * Create the model for the skeleton
     * @param boundInterface
     * @param axisBinding
     * @return documentModel for the skeleton
     */
    protected Document createDOMDocumentForSkeleton(WSDLInterface boundInterface, WSDLBinding axisBinding) {

        Document doc = getEmptyDocument();
        Element rootElement = doc.createElement("interface");
        String localpart = reformatName(boundInterface.getName().getLocalPart(),false);
        addAttribute(doc,
                "package",
                configuration.getPackageName(),
                rootElement);

        addAttribute(doc,
                "name",
                localpart + SERVICE_CLASS_SUFFIX,
                rootElement);
        addAttribute(doc,
                "callbackname",
                boundInterface.getName().getLocalPart() +
                        CALL_BACK_HANDLER_SUFFIX,
                rootElement);
        fillSyncAttributes(doc, rootElement);
        loadOperations(boundInterface, doc, rootElement,axisBinding);
        doc.appendChild(rootElement);
        return doc;

    }

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

    /**
     * Loads operations based on the interface
     * @param boundInterface
     * @param doc
     * @param rootElement
     */
    private void loadOperations(WSDLInterface boundInterface,
                                Document doc,
                                Element rootElement) {
        loadOperations(boundInterface, doc, rootElement, null);
    }


    /**
     *
     * @param boundInterface
     * @param doc
     * @param rootElement
     * @param binding
     */
    private void loadOperations(WSDLInterface boundInterface,
                                Document doc,
                                Element rootElement,
                                WSDLBinding binding) {

        Collection col = boundInterface.getOperations().values();
        String portTypeName = reformatName(boundInterface.getName().getLocalPart(),false);

        List soapHeaderInputParameterList = new ArrayList();
        List soapHeaderOutputParameterList = new ArrayList();
        Element methodElement ;
        WSDLOperation operation ;

        for (Iterator iterator = col.iterator(); iterator.hasNext();) {
            operation = (WSDLOperation) iterator.next();
            methodElement = doc.createElement("method");
            String localPart = reformatName(operation.getName().getLocalPart(),false);
            addAttribute(doc, "name", localPart, methodElement);
            addAttribute(doc,
                    "namespace",
                    operation.getName().getNamespaceURI(),
                    methodElement);
            addAttribute(doc, "style", operation.getStyle(), methodElement);
            addAttribute(doc,
                    "dbsupportname",
                    portTypeName + localPart + DATABINDING_SUPPORTER_NAME_SUFFIX,
                    methodElement);

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

            if (null != binding) {
                WSDLBindingOperation bindingOperation =
                        binding.getBindingOperation(operation.getName());
                addSOAPAction(doc, methodElement, bindingOperation);
                addHeaderOperations(soapHeaderInputParameterList,bindingOperation,true);
                addHeaderOperations(soapHeaderOutputParameterList,bindingOperation,false);
            }

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

            rootElement.appendChild(methodElement);

        }
    }

    private void addHeaderOperations(List soapHeaderParameterQNameList, WSDLBindingOperation bindingOperation,boolean input) {
        Iterator extIterator;
        if (input){
            extIterator = bindingOperation.getInput().getExtensibilityElements().iterator();
        }else{
            extIterator = bindingOperation.getOutput().getExtensibilityElements().iterator();
        }

        while (extIterator.hasNext()) {
            WSDLExtensibilityElement element = (WSDLExtensibilityElement) extIterator.next();
            if (element.getType().equals(ExtensionConstants.SOAP_11_HEADER)) {
                SOAPHeader header = (SOAPHeader)element;
                soapHeaderParameterQNameList.add(header.getElement());
            }
        }
    }


    private void addSOAPAction(Document doc,
                               Element rootElement,
                               WSDLBindingOperation binding) {
        Iterator extIterator = binding.getExtensibilityElements().iterator();
        boolean actionAdded = false;
        while (extIterator.hasNext()) {
            WSDLExtensibilityElement element = (WSDLExtensibilityElement) extIterator.next();
            if (ExtensionConstants.SOAP_11_OPERATION.equals(element.getType())) {
                addAttribute(doc,
                        "soapaction",
                        ((SOAPOperation) element).getSoapAction(),
                        rootElement);
                actionAdded = true;
            }
        }

        if (!actionAdded) {
            addAttribute(doc, "soapaction", "", rootElement);
        }
    }

    protected Document createDOMDocumentForTestCase(WSDLBinding binding) {
        WSDLInterface boundInterface = binding.getBoundInterface();
        String localPart = reformatName(boundInterface.getName().getLocalPart(),false);
        Document doc = getEmptyDocument();
        Element rootElement = doc.createElement("class");
        addAttribute(doc,
                "package",
                configuration.getPackageName(),
                rootElement);

        addAttribute(doc, "name", localPart + TEST_SUFFIX, rootElement);
        addAttribute(doc,
                "namespace",
                boundInterface.getName().getNamespaceURI(),
                rootElement);
        addAttribute(doc, "interfaceName", localPart, rootElement);
        addAttribute(doc,
                "callbackname",
                localPart + CALL_BACK_HANDLER_SUFFIX,
                rootElement);
        addAttribute(doc, "stubname", localPart + STUB_SUFFIX, rootElement);
        addAttribute(doc,
                "dbsupportpackage",
                configuration.getPackageName() +
                        DATABINDING_PACKAGE_NAME_SUFFIX,
                rootElement);
        fillSyncAttributes(doc, rootElement);
        loadOperations(boundInterface, doc, rootElement);
        doc.appendChild(rootElement);
        return doc;

    }



    protected Document createDOMDocumentforSerialization(
            WSDLOperation operation, String portTypeName, WSDLBindingOperation bindingOperation) {

        Document doc = getEmptyDocument();
        Element rootElement = doc.createElement("class");
        addAttribute(doc,
                "package",
                configuration.getPackageName() +
                        DATABINDING_PACKAGE_NAME_SUFFIX,
                rootElement);
        String localPart = reformatName(operation.getName().getLocalPart(),false);
        portTypeName = reformatName(portTypeName,false);
        addAttribute(doc,
                "name",
                portTypeName + localPart + DATABINDING_SUPPORTER_NAME_SUFFIX,
                rootElement);
        addAttribute(doc, "methodname", localPart, rootElement);
        addAttribute(doc,
                "namespace",
                operation.getName().getNamespaceURI(),
                rootElement);

        //Add the parameters to a map with their type as the key
        //this step is needed to remove repetitions
        Map parameterMap = new HashMap();
        Element inputParamElement = getInputParamElement(doc, operation);
        if (inputParamElement!=null){
            parameterMap.put(inputParamElement.getAttribute("type"),inputParamElement);
        }

        Element outputParamElement = getOutputParamElement(doc, operation);
        if (outputParamElement!=null){
            parameterMap.put(outputParamElement.getAttribute("type"),outputParamElement);
        }
        Element newChild;

        if (bindingOperation!=null) {
            List headerParameterQNameList= new ArrayList();
            addHeaderOperations(headerParameterQNameList,bindingOperation,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,bindingOperation,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);
            }
        }

        //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());
        }

        doc.appendChild(rootElement);
        ///////////////////////////////////////////////////
        //System.out.println("rootElement = " + rootElement);
        ///////////////////////////////////////////////////
        return doc;
    }

    /**
     * Get the base64 types. If not available this will be empty!!!
     * @param doc
     * @return element
     */
    private Element getBase64Elements(Document doc){
        Element root = doc.createElement("base64Elements");
        Element elt;
        QName qname;
        //this is a list of QNames
        List list = (List)configuration.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;
    }
    /**
     * Creates the DOM tree for implementations
     *
     * @param binding
     * @param service
     */
    protected Document createDOMDocumentForInterfaceImplementation(
            WSDLBinding binding, WSDLService service) {
        WSDLInterface boundInterface = binding.getBoundInterface();
        HashMap endpoints = new HashMap(1);
        if (service!=null){
            endpoints = service.getEndpoints();
        }

        Document doc = getEmptyDocument();
        Element rootElement = doc.createElement("class");
        addAttribute(doc,
                "package",
                configuration.getPackageName(),
                rootElement);
        String localPart = reformatName(boundInterface.getName().getLocalPart(),false);
        addAttribute(doc, "name", localPart + STUB_SUFFIX, rootElement);
        addAttribute(doc, "servicename", localPart, rootElement);
        addAttribute(doc,
                "namespace",
                boundInterface.getName().getNamespaceURI(),
                rootElement);
        addAttribute(doc, "interfaceName", localPart, rootElement);
        addAttribute(doc,
                "callbackname",
                localPart + CALL_BACK_HANDLER_SUFFIX,
                rootElement);
        addAttribute(doc,
                "dbsupportpackage",
                configuration.getPackageName() +
                        DATABINDING_PACKAGE_NAME_SUFFIX,
                rootElement);
        addAttribute(doc,
                "dbsupportpackage",
                configuration.getPackageName() +
                        DATABINDING_PACKAGE_NAME_SUFFIX,
                rootElement);
        //add SOAP version
        addSoapVersion(binding,doc,rootElement);
        //add the end point
        addEndpoints(doc, rootElement, endpoints);
        //set the sync/async attributes
        fillSyncAttributes(doc, rootElement);
        //load the operations
        loadOperations(boundInterface, doc, rootElement, binding);
        doc.appendChild(rootElement);

        return doc;


    }

    protected void addSoapVersion(WSDLBinding binding,Document doc,Element rootElement){
        //loop through the extensibility elements to get to the bindings element
        List extensibilityElementsList = binding.getExtensibilityElements();
        int count = extensibilityElementsList.size();
        for (int i = 0; i < count; i++) {
            WSDLExtensibilityElement extElement =  (WSDLExtensibilityElement)extensibilityElementsList.get(i);
            if (ExtensionConstants.SOAP_11_BINDING.equals(extElement.getType())){
                addAttribute(doc,"soap-version", "1.1",rootElement);
                break;
            }else if (ExtensionConstants.SOAP_12_BINDING.equals(extElement.getType())){
                addAttribute(doc,"soap-version", "1.2",rootElement);
                break;
            }
        }
    }
    /**
     * Add the endpoint to the document
     * @param doc
     * @param rootElement
     * @param endpointMap
     */

    protected void addEndpoints(Document doc,
                                Element rootElement,
                                HashMap endpointMap) {
        Object[] endpoints = endpointMap.values().toArray();
        WSDLEndpoint endpoint;
        Element endpointElement;
        Text text;
        for (int i = 0; i < endpoints.length; i++) {
            endpoint = (WSDLEndpoint) endpoints[i];
            endpointElement = doc.createElement("endpoint");
            org.apache.wsdl.extensions.SOAPAddress address = null;
            Iterator iterator = endpoint.getExtensibilityElements().iterator();
            while (iterator.hasNext()) {
                WSDLExtensibilityElement element = (WSDLExtensibilityElement) iterator.next();
                if (ExtensionConstants.SOAP_11_ADDRESS.equals(element.getType()) ||
                        ExtensionConstants.SOAP_12_ADDRESS.equals(element.getType())){
                    address = (org.apache.wsdl.extensions.SOAPAddress) element;
                }
            }
            text = doc.createTextNode(address!=null?address.getLocationURI():"");
            endpointElement.appendChild(text);
            rootElement.appendChild(endpointElement);
        }

    }

    /**
     * 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) {
        Attr attribute = document.createAttribute(AttribName);
        attribute.setValue(attribValue);
        element.setAttributeNode(attribute);
    }


    /**
     *
     * @param word
     * @return character removed string
     */
    protected String reformatName(String word) {
        return reformatName(word,true);
    }
    /**
     *
     * @param word
     * @return character removed string
     */
    protected String reformatName(String word, boolean decapitalizaFirst) {
        if (JavaUtils.isJavaKeyword(word)){
            return JavaUtils.makeNonJavaKeyword(word);
        }else{
            return JavaUtils.xmlNameToJava(word,decapitalizaFirst);
        }
    }


}

TOP

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

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.