org.apache.axis.wsdl.fromJava.Emitter Maven / Gradle / Ivy
/*
 * Copyright 2001-2004 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.axis.wsdl.fromJava;
import com.ibm.wsdl.extensions.soap.SOAPAddressImpl;
import com.ibm.wsdl.extensions.soap.SOAPBindingImpl;
import com.ibm.wsdl.extensions.soap.SOAPBodyImpl;
import com.ibm.wsdl.extensions.soap.SOAPHeaderImpl;
import com.ibm.wsdl.extensions.soap.SOAPOperationImpl;
import org.apache.axis.AxisFault;
import org.apache.axis.Constants;
import org.apache.axis.InternalException;
import org.apache.axis.Version;
import org.apache.axis.components.logger.LogFactory;
import org.apache.axis.constants.Style;
import org.apache.axis.constants.Use;
import org.apache.axis.description.FaultDesc;
import org.apache.axis.description.JavaServiceDesc;
import org.apache.axis.description.OperationDesc;
import org.apache.axis.description.ParameterDesc;
import org.apache.axis.description.ServiceDesc;
import org.apache.axis.encoding.TypeMapping;
import org.apache.axis.encoding.TypeMappingRegistry;
import org.apache.axis.encoding.TypeMappingRegistryImpl;
import org.apache.axis.utils.ClassUtils;
import org.apache.axis.utils.JavaUtils;
import org.apache.axis.utils.Messages;
import org.apache.axis.utils.XMLUtils;
import org.apache.axis.wsdl.symbolTable.SymbolTable;
import org.apache.commons.logging.Log;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;
import javax.wsdl.Binding;
import javax.wsdl.BindingFault;
import javax.wsdl.BindingInput;
import javax.wsdl.BindingOperation;
import javax.wsdl.BindingOutput;
import javax.wsdl.Definition;
import javax.wsdl.Fault;
import javax.wsdl.Import;
import javax.wsdl.Input;
import javax.wsdl.Message;
import javax.wsdl.Operation;
import javax.wsdl.OperationType;
import javax.wsdl.Output;
import javax.wsdl.Part;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.wsdl.extensions.soap.SOAPBinding;
import javax.wsdl.extensions.soap.SOAPBody;
import javax.wsdl.extensions.soap.SOAPFault;
import javax.wsdl.extensions.soap.SOAPHeader;
import javax.wsdl.extensions.soap.SOAPOperation;
import javax.wsdl.factory.WSDLFactory;
import javax.xml.namespace.QName;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;
/**
 * This class emits WSDL from Java classes.  It is used by the ?WSDL
 * Axis browser function and Java2WSDL commandline utility.
 * See Java2WSDL and Java2WSDLFactory for more information.
 * 
 * @author Glen Daniels ([email protected])
 * @author Rich Scheuerle ([email protected])
 */
public class Emitter {
    /** Field log */
    protected static Log log = LogFactory.getLog(Emitter.class.getName());
    // Generated WSDL Modes
    /** Field MODE_ALL */
    public static final int MODE_ALL = 0;
    /** Field MODE_INTERFACE */
    public static final int MODE_INTERFACE = 1;
    /** Field MODE_IMPLEMENTATION */
    public static final int MODE_IMPLEMENTATION = 2;
    /** Field cls */
    private Class cls;
    /** Field extraClasses */
    private Class[] extraClasses;               // Extra classes to emit WSDL for
    /** Field implCls */
    private Class implCls;                      // Optional implementation class
    /** Field allowedMethods */
    private Vector allowedMethods = null;       // Names of methods to consider
    /** Field disallowedMethods */
    private Vector disallowedMethods = null;    // Names of methods to exclude
    /** Field stopClasses */
    private ArrayList stopClasses =
            new ArrayList();                        // class names which halt inheritace searches
    /** Field useInheritedMethods */
    private boolean useInheritedMethods = false;
    /** Field intfNS */
    private String intfNS;
    /** Field implNS */
    private String implNS;
    /** Field inputSchema */
    private String inputSchema;
    /** Field inputWSDL */
    private String inputWSDL;
    /** Field locationUrl */
    private String locationUrl;
    /** Field importUrl */
    private String importUrl;
    /** Field servicePortName */
    private String servicePortName;
    /** Field serviceElementName */
    private String serviceElementName;
    /** Field targetService */
    private String targetService = null;
    /** Field description */
    private String description;
    /** Field style */
    private Style style = Style.RPC;
    /** Field use */
    private Use use = null;                     // Default depends on style setting
    /** Field tm */
    private TypeMapping tm = null;              // Registered type mapping
    /** Field tmr */
    private TypeMappingRegistry tmr = new TypeMappingRegistryImpl();
    /** Field namespaces */
    private Namespaces namespaces;
    /** Field exceptionMsg */
    private Map exceptionMsg = null;
    /** Global element names already in use */
    private Map usedElementNames;
    /** Field encodingList */
    private ArrayList encodingList;
    /** Field types */
    protected Types types;
    /** Field clsName */
    private String clsName;
    /** Field portTypeName */
    private String portTypeName;
    /** Field bindingName */
    private String bindingName;
    /** Field serviceDesc */
    private ServiceDesc serviceDesc;
    /** Field serviceDesc2 */
    private JavaServiceDesc serviceDesc2;
    /** Field soapAction */
    private String soapAction = "DEFAULT";
    
    /** Should we emit all mapped types in every WSDL? */
    private boolean emitAllTypes = false;
    /** Version string to put at top of WSDL */
    private String versionMessage = null;
    
    /** The mapping of generated type qname to its corresponding java type. For use with java<-->wsdl roundtripping */
    private HashMap qName2ClassMap;
    // Style Modes
    /** DEPRECATED - Indicates style=rpc use=encoded */
    public static final int MODE_RPC = 0;
    /** DEPRECATED - Indicates style=document use=literal */
    public static final int MODE_DOCUMENT = 1;
    /** DEPRECATED - Indicates style=wrapped use=literal */
    public static final int MODE_DOC_WRAPPED = 2;
    /**
     * Construct Emitter.
     * Set the contextual information using set* methods
     * Invoke emit to emit the code
     */
    public Emitter() {
        createDocumentFragment();
        namespaces = new Namespaces();
        exceptionMsg = new HashMap();
        usedElementNames = new HashMap();
        qName2ClassMap = new HashMap();
    }
    /**
     * Generates WSDL documents for a given Class
     * 
     * @param filename1 interface WSDL
     * @param filename2 implementation WSDL
     * @throws IOException                  
     * @throws WSDLException                
     * @throws SAXException                 
     * @throws ParserConfigurationException 
     */
    public void emit(String filename1, String filename2)
            throws IOException, WSDLException, SAXException,
            ParserConfigurationException {
        // Get interface and implementation defs
        Definition intf = getIntfWSDL();
        Definition impl = getImplWSDL();
        // Supply reasonable file names if not supplied
        if (filename1 == null) {
            filename1 = getServicePortName() + "_interface.wsdl";
        }
        if (filename2 == null) {
            filename2 = getServicePortName() + "_implementation.wsdl";
        }
        for (int i = 0; (extraClasses != null) && (i < extraClasses.length);
             i++) {
            types.writeTypeForPart(extraClasses[i], null);
        }
        // types.updateNamespaces();
        // Write out the interface def
        Document doc =
                WSDLFactory.newInstance().newWSDLWriter().getDocument(intf);
        types.insertTypesFragment(doc);
        prettyDocumentToFile(doc, filename1);
        // Write out the implementation def
        doc = WSDLFactory.newInstance().newWSDLWriter().getDocument(impl);
        prettyDocumentToFile(doc, filename2);
    }
    /**
     * Generates a complete WSDL document for a given Class
     * 
     * @param filename WSDL
     * @throws IOException                  
     * @throws WSDLException                
     * @throws SAXException                 
     * @throws ParserConfigurationException 
     */
    public void emit(String filename)
            throws IOException, WSDLException, SAXException,
            ParserConfigurationException {
        emit(filename, MODE_ALL);
    }
    /**
     * Generates a WSDL document for a given Class.
     * The WSDL generated is controlled by the mode parameter
     * mode 0: All
     * mode 1: Interface
     * mode 2: Implementation
     * 
     * @param mode generation mode - all, interface, implementation
     * @return Document
     * @throws IOException                  
     * @throws WSDLException                
     * @throws SAXException                 
     * @throws ParserConfigurationException 
     */
    public Document emit(int mode)
            throws IOException, WSDLException, SAXException,
            ParserConfigurationException {
        Document doc;
        Definition def;
        switch (mode) {
            default:
            case MODE_ALL:
                def = getWSDL();
                for (int i = 0;
                     (extraClasses != null) && (i < extraClasses.length);
                     i++) {
                    types.writeTypeForPart(extraClasses[i], null);
                }
                // types.updateNamespaces();
                doc = WSDLFactory.newInstance().newWSDLWriter().getDocument(
                        def);
                types.insertTypesFragment(doc);
                break;
            case MODE_INTERFACE:
                def = getIntfWSDL();
                for (int i = 0;
                     (extraClasses != null) && (i < extraClasses.length);
                     i++) {
                    types.writeTypeForPart(extraClasses[i], null);
                }
                // types.updateNamespaces();
                doc = WSDLFactory.newInstance().newWSDLWriter().getDocument(
                        def);
                types.insertTypesFragment(doc);
                break;
            case MODE_IMPLEMENTATION:
                def = getImplWSDL();
                doc = WSDLFactory.newInstance().newWSDLWriter().getDocument(
                        def);
                break;
        }
        // Add Axis version info as comment to beginnning of generated WSDL
        if (versionMessage == null) {
            versionMessage = Messages.getMessage(
                    "wsdlCreated00",
                    XMLUtils.xmlEncodeString(Version.getVersion()));
        }
        // If version is empty string, don't emit one
        if (versionMessage != null && versionMessage.length() > 0) {
            Comment wsdlVersion = doc.createComment(versionMessage);
            doc.getDocumentElement().insertBefore(
                    wsdlVersion, doc.getDocumentElement().getFirstChild());
        }
        // Return the document
        return doc;
    }
    /**
     * Generates a String containing the WSDL for a given Class.
     * The WSDL generated is controlled by the mode parameter
     * mode 0: All
     * mode 1: Interface
     * mode 2: Implementation
     * 
     * @param mode generation mode - all, interface, implementation
     * @return String
     * @throws IOException                  
     * @throws WSDLException                
     * @throws SAXException                 
     * @throws ParserConfigurationException 
     */
    public String emitToString(int mode)
            throws IOException, WSDLException, SAXException,
            ParserConfigurationException {
        Document doc = emit(mode);
        StringWriter sw = new StringWriter();
        XMLUtils.PrettyDocumentToWriter(doc, sw);
        return sw.toString();
    }
    /**
     * Generates a WSDL document for a given Class.
     * The WSDL generated is controlled by the mode parameter
     * mode 0: All
     * mode 1: Interface
     * mode 2: Implementation
     * 
     * @param filename WSDL
     * @param mode     generation mode - all, interface, implementation
     * @throws IOException                  
     * @throws WSDLException                
     * @throws SAXException                 
     * @throws ParserConfigurationException 
     */
    public void emit(String filename, int mode)
            throws IOException, WSDLException, SAXException,
            ParserConfigurationException {
        Document doc = emit(mode);
        // Supply a reasonable file name if not supplied
        if (filename == null) {
            filename = getServicePortName();
            switch (mode) {
                case MODE_ALL:
                    filename += ".wsdl";
                    break;
                case MODE_INTERFACE:
                    filename += "_interface.wsdl";
                    break;
                case MODE_IMPLEMENTATION:
                    filename += "_implementation.wsdl";
                    break;
            }
        }
        prettyDocumentToFile(doc, filename);
    }
    /**
     * Get a Full WSDL Definition for the current
     * configuration parameters
     * 
     * @return WSDL Definition
     * @throws IOException                  
     * @throws WSDLException                
     * @throws SAXException                 
     * @throws ParserConfigurationException 
     */
    public Definition getWSDL()
            throws IOException, WSDLException, SAXException,
            ParserConfigurationException {
        // Invoke the init() method to ensure configuration is setup
        init(MODE_ALL);
        // Create a Definition for the output wsdl
        Definition def = createDefinition();
        // Write interface header
        writeDefinitions(def, intfNS);
        // Create Types
        types = createTypes(def);
        // Write the WSDL constructs and return full Definition
        Binding binding = writeBinding(def, true);
        writePortType(def, binding);
        writeService(def, binding);
        return def;
    }
    /**
     * Get a interface WSDL Definition for the
     * current configuration parameters
     * 
     * @return WSDL Definition
     * @throws IOException                  
     * @throws WSDLException                
     * @throws SAXException                 
     * @throws ParserConfigurationException 
     */
    public Definition getIntfWSDL()
            throws IOException, WSDLException, SAXException,
            ParserConfigurationException {
        // Invoke the init() method to ensure configuration is setup
        init(MODE_INTERFACE);
        // Create a definition for the output wsdl
        Definition def = createDefinition();
        // Write interface header
        writeDefinitions(def, intfNS);
        // Create Types
        types = createTypes(def);
        // Write the interface WSDL constructs and return the Definition
        Binding binding = writeBinding(def, true);
        writePortType(def, binding);
        return def;
    }
    /**
     * Get implementation WSDL Definition for the
     * current configuration parameters
     * 
     * @return WSDL Definition
     * @throws IOException                  
     * @throws WSDLException                
     * @throws SAXException                 
     * @throws ParserConfigurationException 
     */
    public Definition getImplWSDL()
            throws IOException, WSDLException, SAXException,
            ParserConfigurationException {
        // Invoke the init() method to ensure configuration is setup
        init(MODE_IMPLEMENTATION);
        // Create a Definition for the output wsdl
        Definition def = createDefinition();
        // Write implementation header and import
        writeDefinitions(def, implNS);
        writeImport(def, intfNS, importUrl);
        // Write the implementation WSDL constructs and return Definition
        Binding binding = writeBinding(def, false);    // Don't add binding to def
        writeService(def, binding);
        return def;
    }
    /**
     * Invoked prior to building a definition to ensure parms
     * and data are set up.
     * 
     * @param mode 
     */
    protected void init(int mode) {
        // Default use depending on setting of style
        if (use == null) {
            if (style == Style.RPC) {
                use = Use.ENCODED;
            } else {
                use = Use.LITERAL;
            }
        }
        if (tm == null) {
            String encodingStyle = "";
            if (use == Use.ENCODED) {
                encodingStyle = Constants.URI_SOAP11_ENC;
                /** TODO : Set this correctly if we do SOAP 1.2 support here */
            }
            tm = (TypeMapping)tmr.getTypeMapping(encodingStyle);
        }
        // Set up a ServiceDesc to use to introspect the Service
        if (serviceDesc == null) {
            JavaServiceDesc javaServiceDesc = new JavaServiceDesc();
            serviceDesc = javaServiceDesc;
            javaServiceDesc.setImplClass(cls);
            // Set the typeMapping to the one provided.
            serviceDesc.setTypeMapping(tm);
            javaServiceDesc.setStopClasses(stopClasses);
            serviceDesc.setAllowedMethods(allowedMethods);
            javaServiceDesc.setDisallowedMethods(disallowedMethods);
            serviceDesc.setStyle(style);
            serviceDesc.setUse(use);
            // If the class passed in is a portType,
            // there may be an implClass that is used to
            // obtain the method parameter names.  In this case,
            // a serviceDesc2 is built to get the method parameter names.
            if ((implCls != null) && (implCls != cls)
                    && (serviceDesc2 == null)) {
                serviceDesc2 = new JavaServiceDesc();
                serviceDesc2.setImplClass(implCls);
                // Set the typeMapping to the one provided.
                serviceDesc2.setTypeMapping(tm);
                serviceDesc2.setStopClasses(stopClasses);
                serviceDesc2.setAllowedMethods(allowedMethods);
                serviceDesc2.setDisallowedMethods(disallowedMethods);
                serviceDesc2.setStyle(style);
            }
        }
        if (encodingList == null) {
            // if cls contains a Class object with the service implementation use the Name of the
            // class else use the service name
            if (cls != null) {
                clsName = cls.getName();
                clsName = clsName.substring(clsName.lastIndexOf('.') + 1);
            } else {
                clsName = getServiceDesc().getName();
            }
            // Default the portType name
            if (getPortTypeName() == null) {
                setPortTypeName(clsName);
            }
            // Default the serviceElementName
            if (getServiceElementName() == null) {
                setServiceElementName(getPortTypeName() + "Service");
            }
            // If service port name is null, construct it from location or className
            if (getServicePortName() == null) {
                String name = getLocationUrl();
                if (name != null) {
                    if (name.lastIndexOf('/') > 0) {
                        name = name.substring(name.lastIndexOf('/') + 1);
                    } else if (name.lastIndexOf('\\') > 0) {
                        name = name.substring(name.lastIndexOf('\\') + 1);
                    } else {
                        name = null;
                    }
                    // if we got the name from the location, strip .jws from it
                    if ((name != null) && name.endsWith(".jws")) {
                        name = name.substring(0, (name.length()
                                - ".jws".length()));
                    }
                }
                if ((name == null) || name.equals("")) {
                    name = clsName;
                }
                setServicePortName(name);
            }
            // Default the bindingName
            if (getBindingName() == null) {
                setBindingName(getServicePortName() + "SoapBinding");
            }
            encodingList = new ArrayList();
            encodingList.add(Constants.URI_DEFAULT_SOAP_ENC);
            if (intfNS == null) {
                Package pkg = cls.getPackage();
                intfNS = namespaces.getCreate((pkg == null)
                        ? null
                        : pkg.getName());
            }
            // Default the implementation namespace to the interface
            // namespace if not split wsdl mode.
            if (implNS == null) {
                if (mode == MODE_ALL) {
                    implNS = intfNS;
                } else {
                    implNS = intfNS + "-impl";
                }
            }
            // set the namespaces in the serviceDesc(s)
            serviceDesc.setDefaultNamespace(intfNS);
            if (serviceDesc2 != null) {
                serviceDesc2.setDefaultNamespace(implNS);
            }
            if (cls != null) {
                String clsName = cls.getName();
                int idx = clsName.lastIndexOf(".");
                if (idx > 0) {
                    String pkgName = clsName.substring(0, idx);
                    namespaces.put(pkgName, intfNS, "intf");
                }
            }
            namespaces.putPrefix(implNS, "impl");
        }
    }
    /**
     * Build a Definition from the input wsdl file or create
     * a new Definition
     * 
     * @return WSDL Definition
     * @throws WSDLException                
     * @throws SAXException                 
     * @throws IOException                  
     * @throws ParserConfigurationException 
     */
    protected Definition createDefinition()
            throws WSDLException, SAXException, IOException,
            ParserConfigurationException {
        Definition def;
        if (inputWSDL == null) {
            def = WSDLFactory.newInstance().newDefinition();
        } else {
            javax.wsdl.xml.WSDLReader reader =
                    WSDLFactory.newInstance().newWSDLReader();
            Document doc = XMLUtils.newDocument(inputWSDL);
            def = reader.readWSDL(null, doc);
            // The input wsdl types section is deleted.  The
            // types will be added back in at the end of processing.
            def.setTypes(null);
        }
        return def;
    }
    /** Field standardTypes */
    protected static TypeMapping standardTypes =
            (TypeMapping) new org.apache.axis.encoding.TypeMappingRegistryImpl().getTypeMapping(
                    null);
    /**
     * Build a Types object and load the input wsdl types
     * 
     * @param def Corresponding wsdl Definition
     * @return Types object
     * @throws IOException                  
     * @throws WSDLException                
     * @throws SAXException                 
     * @throws ParserConfigurationException 
     */
    protected Types createTypes(Definition def)
            throws IOException, WSDLException, SAXException,
            ParserConfigurationException {
        types = new Types(def, tm, (TypeMapping)tmr.getDefaultTypeMapping(),
                          namespaces, intfNS, stopClasses, serviceDesc, this);
        if (inputWSDL != null) {
            types.loadInputTypes(inputWSDL);
        }
        if (inputSchema != null) {
            StringTokenizer tokenizer = new StringTokenizer(inputSchema, ", ");
            while (tokenizer.hasMoreTokens()) {
                String token = tokenizer.nextToken();
                types.loadInputSchema(token);
            }
        }
        
        // If we're supposed to emit all mapped types, do it now.
        if (emitAllTypes && tm != null) { 
            Class[] mappedTypes = tm.getAllClasses(); 
            
            for (int i = 0; i < mappedTypes.length; i++) { 
                Class mappedType = mappedTypes[i]; 
                QName name = tm.getTypeQName(mappedType); 
                if (name.getLocalPart().indexOf(SymbolTable.ANON_TOKEN) != -1) { 
                    // If this is an anonymous type, it doesn't need to be
                    // written out here (and trying to do so will generate an
                    // error). Skip it. 
                    continue; 
                } 
                
                /** 
                 * If it's a non-standard type, make sure it shows up in 
                 * our WSDL 
                 */ 
                if (standardTypes.getSerializer(mappedType) == null) { 
                    types.writeTypeForPart(mappedType, name); 
                } 
            }
            
            // Don't bother checking for subtypes, since we already wrote
            // all the possibilities.
            types.mappedTypes = null;
        }
        
        return types;
    }
    
    /**
     * Create a documentation element
     *  
     * @param documentation
     * @return
     */
    protected Element createDocumentationElement(String documentation) {
        Element element = docHolder.createElementNS(Constants.NS_URI_WSDL11, "documentation");
        element.setPrefix(Constants.NS_PREFIX_WSDL);
        Text textNode =
                docHolder.createTextNode(documentation);
        element.appendChild(textNode);
        return element;
    }
    
    /**
     * Create the definition header information.
     * 
     * @param def Definition
     * @param tns target namespace
     */
    protected void writeDefinitions(Definition def, String tns) {
        def.setTargetNamespace(tns);
        def.addNamespace("intf", intfNS);
        def.addNamespace("impl", implNS);
        def.addNamespace(Constants.NS_PREFIX_WSDL_SOAP,
                Constants.URI_WSDL11_SOAP);
        namespaces.putPrefix(Constants.URI_WSDL11_SOAP,
                Constants.NS_PREFIX_WSDL_SOAP);
        def.addNamespace(Constants.NS_PREFIX_WSDL, Constants.NS_URI_WSDL11);
        namespaces.putPrefix(Constants.NS_URI_WSDL11, Constants.NS_PREFIX_WSDL);
        if (use == Use.ENCODED) {
            def.addNamespace(Constants.NS_PREFIX_SOAP_ENC,
                    Constants.URI_DEFAULT_SOAP_ENC);
            namespaces.putPrefix(Constants.URI_DEFAULT_SOAP_ENC,
                    Constants.NS_PREFIX_SOAP_ENC);
        }
        def.addNamespace(Constants.NS_PREFIX_SCHEMA_XSD,
                Constants.URI_DEFAULT_SCHEMA_XSD);
        namespaces.putPrefix(Constants.URI_DEFAULT_SCHEMA_XSD,
                Constants.NS_PREFIX_SCHEMA_XSD);
        def.addNamespace(Constants.NS_PREFIX_XMLSOAP, Constants.NS_URI_XMLSOAP);
        namespaces.putPrefix(Constants.NS_URI_XMLSOAP,
                Constants.NS_PREFIX_XMLSOAP);
    }
    /**
     * Create and add an import
     * 
     * @param def Definition
     * @param tns target namespace
     * @param loc target location
     */
    protected void writeImport(Definition def, String tns, String loc) {
        Import imp = def.createImport();
        imp.setNamespaceURI(tns);
        if ((loc != null) && !loc.equals("")) {
            imp.setLocationURI(loc);
        }
        def.addImport(imp);
    }
    /**
     * Create the binding.
     * 
     * @param def Definition
     * @param add true if binding should be added to the def
     * @return 
     */
    protected Binding writeBinding(Definition def, boolean add) {
        QName bindingQName = new QName(intfNS, getBindingName());
        // If a binding already exists, don't replace it.
        Binding binding = def.getBinding(bindingQName);
        if (binding != null) {
            return binding;
        }
        // Create a binding
        binding = def.createBinding();
        binding.setUndefined(false);
        binding.setQName(bindingQName);
        SOAPBinding soapBinding = new SOAPBindingImpl();
        String styleStr = (style == Style.RPC)
                ? "rpc"
                : "document";
        soapBinding.setStyle(styleStr);
        soapBinding.setTransportURI(Constants.URI_SOAP11_HTTP);
        binding.addExtensibilityElement(soapBinding);
        if (add) {
            def.addBinding(binding);
        }
        return binding;
    }
    /** Field docHolder */
    Document docHolder;
    /**
     * Method createDocumentFragment
     */
    private void createDocumentFragment() {
        try {
            this.docHolder = XMLUtils.newDocument();
        } catch (ParserConfigurationException e) {
            // This should not occur
            throw new InternalException(e);
        }
    }
    /**
     * Create the service.
     * 
     * @param def     
     * @param binding 
     */
    protected void writeService(Definition def, Binding binding) {
        QName serviceElementQName = new QName(implNS, getServiceElementName());
        // Locate an existing service, or get a new service
        Service service = def.getService(serviceElementQName);
        if (service == null) {
            service = def.createService();
            service.setQName(serviceElementQName);
            def.addService(service);
        }
        if (description != null) {
            service.setDocumentationElement(
                    createDocumentationElement(description));
        } else if (serviceDesc.getDocumentation() != null) {
            service.setDocumentationElement(
                    createDocumentationElement(
                            serviceDesc.getDocumentation()));
        }
        // Add the port
        Port port = def.createPort();
        port.setBinding(binding);
        // Probably should use the end of the location Url
        port.setName(getServicePortName());
        SOAPAddress addr = new SOAPAddressImpl();
        addr.setLocationURI(locationUrl);
        port.addExtensibilityElement(addr);
        service.addPort(port);
    }
    /**
     * Create a PortType
     * 
     * @param def     
     * @param binding 
     * @throws WSDLException 
     * @throws AxisFault     
     */
    protected void writePortType(Definition def, Binding binding)
            throws WSDLException, AxisFault {
        QName portTypeQName = new QName(intfNS, getPortTypeName());
        // Get or create a portType
        PortType portType = def.getPortType(portTypeQName);
        boolean newPortType = false;
        if (portType == null) {
            portType = def.createPortType();
            portType.setUndefined(false);
            portType.setQName(portTypeQName);
            newPortType = true;
        } else if (binding.getBindingOperations().size() > 0) {
            // If both portType and binding already exist,
            // no additional processing is needed.
            return;
        }
        // Add the port and binding operations.
        ArrayList operations = serviceDesc.getOperations();
        for (Iterator i = operations.iterator(); i.hasNext();) {
            OperationDesc thisOper = (OperationDesc) i.next();
            BindingOperation bindingOper = writeOperation(def, binding,
                    thisOper);
            Operation oper = bindingOper.getOperation();
            OperationDesc messageOper = thisOper;
            // add the documentation to oper
            if (messageOper.getDocumentation() != null) {
                oper.setDocumentationElement(
                        createDocumentationElement(
                                messageOper.getDocumentation()));
            }
            if (serviceDesc2 != null) {
                // If a serviceDesc containing an impl class is provided,
                // try and locate the corresponding operation
                // (same name, same parm types and modes).  If a
                // corresponding operation is found, it is sent
                // to the writeMessages method so that its parameter
                // names will be used in the wsdl file.
                OperationDesc[] operArray =
                        serviceDesc2.getOperationsByName(thisOper.getName());
                boolean found = false;
                if (operArray != null) {
                    for (int j = 0; (j < operArray.length) && !found; j++) {
                        OperationDesc tryOper = operArray[j];
                        if (tryOper.getParameters().size()
                                == thisOper.getParameters().size()) {
                            boolean parmsMatch = true;
                            for (int k =
                                    0; (k < thisOper.getParameters().size())
                                    && parmsMatch; k++) {
                                if ((tryOper.getParameter(
                                        k).getMode() != thisOper.getParameter(
                                                k).getMode())
                                        || (!tryOper.getParameter(
                                                k).getJavaType().equals(
                                                        thisOper.getParameter(
                                                                k).getJavaType()))) {
                                    parmsMatch = false;
                                }
                            }
                            if (parmsMatch) {
                                messageOper = tryOper;
                                found = true;
                            }
                        }
                    }
                }
            }
            writeMessages(def, oper, messageOper, bindingOper);
            if (newPortType) {
                portType.addOperation(oper);
            }
        }
        if (newPortType) {
            def.addPortType(portType);
        }
        binding.setPortType(portType);
    }
    /**
     * Create a Message
     * 
     * @param def         Definition, the WSDL definition
     * @param oper        Operation, the wsdl operation
     * @param desc        OperationDesc, the Operation Description
     * @param bindingOper BindingOperation, corresponding Binding Operation
     * @throws WSDLException 
     * @throws AxisFault     
     */
    protected void writeMessages(Definition def,
                                 Operation oper,
                                 OperationDesc desc,
                                 BindingOperation bindingOper)
            throws WSDLException, AxisFault {
        Input input = def.createInput();
        Message msg = writeRequestMessage(def, desc, bindingOper);
        input.setMessage(msg);
        // Give the input element a name that matches the
        // message.  This is necessary for overloading.
        // The msg QName is unique.
        String name = msg.getQName().getLocalPart();
        input.setName(name);
        bindingOper.getBindingInput().setName(name);
        oper.setInput(input);
        def.addMessage(msg);
        
        if (OperationType.REQUEST_RESPONSE.equals(desc.getMep())) {
            msg = writeResponseMessage(def, desc, bindingOper);
            
            Output output = def.createOutput();
            
            output.setMessage(msg);
            
            // Give the output element a name that matches the
            // message.  This is necessary for overloading.
            // The message QName is unique.
            name = msg.getQName().getLocalPart();
            
            output.setName(name);
            bindingOper.getBindingOutput().setName(name);
            oper.setOutput(output);
            def.addMessage(msg);
        }
        
        ArrayList exceptions = desc.getFaults();
        for (int i = 0; (exceptions != null) && (i < exceptions.size()); i++) {
            FaultDesc faultDesc = (FaultDesc) exceptions.get(i);
            msg = writeFaultMessage(def, faultDesc);
            // Add the fault to the portType
            Fault fault = def.createFault();
            fault.setMessage(msg);
            fault.setName(faultDesc.getName());
            oper.addFault(fault);
            // Add the fault to the binding
            BindingFault bFault = def.createBindingFault();
            bFault.setName(faultDesc.getName());
            SOAPFault soapFault = writeSOAPFault(faultDesc);
            bFault.addExtensibilityElement(soapFault);
            bindingOper.addBindingFault(bFault);
            // Add the fault message
            if (def.getMessage(msg.getQName()) == null) {
                def.addMessage(msg);
            }
        }
        // Set the parameter ordering using the parameter names
        ArrayList parameters = desc.getParameters();
        Vector names = new Vector();
        for (int i = 0; i < parameters.size(); i++) {
            ParameterDesc param = (ParameterDesc) parameters.get(i);
            names.add(param.getName());
        }
        if (names.size() > 0) {
            if (style == Style.WRAPPED) {
                names.clear();
            } else {
                oper.setParameterOrdering(names);
            }
        }
    }
    /**
     * Create a Operation
     * 
     * @param def     
     * @param binding 
     * @param desc    
     * @return 
     */
    protected BindingOperation writeOperation(Definition def, Binding binding,
                                              OperationDesc desc) {
        Operation oper = def.createOperation();
        QName elementQName = desc.getElementQName();
        if(elementQName != null && elementQName.getLocalPart() != null) {
            oper.setName(elementQName.getLocalPart());
        } else {
            oper.setName(desc.getName());
        }
        oper.setUndefined(false);
        return writeBindingOperation(def, binding, oper, desc);
    }
    /**
     * Create a Binding Operation
     * 
     * @param def     
     * @param binding 
     * @param oper    
     * @param desc    
     * @return 
     */
    protected BindingOperation writeBindingOperation(Definition def,
                                                     Binding binding,
                                                     Operation oper,
                                                     OperationDesc desc) {
        BindingOperation bindingOper = def.createBindingOperation();
        BindingInput bindingInput = def.createBindingInput();
        BindingOutput bindingOutput = null;
        
        // TODO : Make this deal with all MEPs
        if (OperationType.REQUEST_RESPONSE.equals(desc.getMep())) 
            bindingOutput = def.createBindingOutput();
        bindingOper.setName(oper.getName());
        bindingOper.setOperation(oper);
        SOAPOperation soapOper = new SOAPOperationImpl();
        // If the soapAction option is OPERATION, force
        // soapAction to the name of the operation. If NONE,
        // force soapAction to "".
        // Otherwise use the information in the operationDesc.
        String soapAction;
        if (getSoapAction().equalsIgnoreCase("OPERATION")) {
            soapAction = oper.getName();
        } else if (getSoapAction().equalsIgnoreCase("NONE")) {
            soapAction = "";
        } else {
            soapAction = desc.getSoapAction();
            if (soapAction == null) {
                soapAction = "";
            }
        }
        soapOper.setSoapActionURI(soapAction);
        // Until we have per-operation configuration, this will always be
        // the same as the binding default.
        // soapOper.setStyle("rpc");
        bindingOper.addExtensibilityElement(soapOper);
        // Add soap:body element to the binding  element
        ExtensibilityElement inputBody = writeSOAPBody(desc.getElementQName());
        bindingInput.addExtensibilityElement(inputBody);
        // add soap:headers, if any, to binding  element
        // only when we write the Message and parts.
        // Add soap:body element to the binding     © 2015 - 2025 Weber Informatics LLC | Privacy Policy