/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink

package org.eclipse.persistence.tools.dbws;

//javase imports
import java.io.OutputStream;

//Java extension imports
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.Input;
import javax.wsdl.Message;
import javax.wsdl.Output;
import javax.wsdl.Part;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.Types;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.ExtensionRegistry;
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.SOAPOperation;
import javax.wsdl.extensions.soap12.SOAP12Address;
import javax.wsdl.extensions.soap12.SOAP12Binding;
import javax.wsdl.extensions.soap12.SOAP12Body;
import javax.wsdl.extensions.soap12.SOAP12Fault;
import javax.wsdl.extensions.soap12.SOAP12Operation;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLWriter;
import javax.xml.namespace.QName;
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
//import static

//EclipseLink imports
import org.eclipse.persistence.internal.oxm.schema.SchemaModelProject;
import org.eclipse.persistence.internal.oxm.schema.model.Any;
import org.eclipse.persistence.internal.oxm.schema.model.ComplexType;
import org.eclipse.persistence.internal.oxm.schema.model.Element;
import org.eclipse.persistence.internal.oxm.schema.model.Import;
import org.eclipse.persistence.internal.oxm.schema.model.Schema;
import org.eclipse.persistence.internal.oxm.schema.model.Sequence;
import org.eclipse.persistence.internal.xr.Operation;
import org.eclipse.persistence.internal.xr.Parameter;
import org.eclipse.persistence.internal.xr.QueryOperation;
import org.eclipse.persistence.internal.xr.XRServiceModel;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLMarshaller;
import static org.eclipse.persistence.internal.xr.Util.DBWS_SCHEMA_XML;
import static org.eclipse.persistence.internal.xr.Util.TARGET_NAMESPACE_PREFIX;
import static org.eclipse.persistence.internal.xr.Util.SERVICE_SUFFIX;
import static org.eclipse.persistence.tools.dbws.Util.THE_INSTANCE_NAME;
import static org.eclipse.persistence.tools.dbws.Util.WSI_SWAREF;
import static org.eclipse.persistence.tools.dbws.Util.WSI_SWAREF_PREFIX;
import static org.eclipse.persistence.tools.dbws.Util.WSI_SWAREF_URI;
import static org.eclipse.persistence.tools.dbws.Util.WSI_SWAREF_XSD_FILE;

public class WSDLGenerator {

    public static final String BINDING_SUFFIX = "_SOAP_HTTP";
    public static final String EMPTY_RESPONSE = "EmptyResponse";
    public static final String EXCEPTION_SUFFIX = "Exception";
    public static final String FAULT_SUFFIX = "Fault";
    public static final String NS_SCHEMA_PREFIX = "xsd";
    public static final String NS_TNS_PREFIX = "tns";
    public static final String SOAP_11_NAMESPACE_URI = "http://schemas.xmlsoap.org/wsdl/soap/";
    public static final String SOAP_11_NAMESPACE_PREFIX = "soap";
    public static final String SOAP_12_NAMESPACE_URI = "http://schemas.xmlsoap.org/wsdl/soap12/";
    public static final String SOAP_12_NAMESPACE_PREFIX = "soap12";
    public static final String PORT_SUFFIX = "_Interface";
    public static final String REQUEST_SUFFIX = "Request";
    public static final String RESPONSE_SUFFIX = "Response";
    public static final String SOAP_STYLE = "document";
    public static final String SOAP_HTTP_TRANSPORT = "http://schemas.xmlsoap.org/soap/http";
    public static final String SOAP_USE = "literal";
    public static final String TAG_SCHEMA = "schema";
    public static final String TAG_SOAP_ADDRESS = "address";
    public static final String TAG_SOAP_BINDING = "binding";
    public static final String TAG_SOAP_BODY = "body";
    public static final String TAG_SOAP_FAULT = "fault";
    public static final String TAG_SOAP_OPERATION = "operation";
    public static final String TYPE_SUFFIX = "Type";

    protected XRServiceModel xrServiceModel;
    protected NamingConventionTransformer nct;
    protected String serviceName;
    protected String serviceNameSpace;
    protected String importedSchemaNameSpace;
    protected String wsdlLocationURI;
    protected boolean hasAttachments;
    protected OutputStream os;

    public WSDLGenerator(XRServiceModel xrServiceModel, NamingConventionTransformer nct,
        String wsdlLocationURI, boolean hasAttachments, String importedSchemaNameSpace,
        OutputStream os) {
        this.xrServiceModel = xrServiceModel;
        this.nct = nct;
        this.wsdlLocationURI = wsdlLocationURI;
        this.hasAttachments = hasAttachments;
        this.os = os;
        this.importedSchemaNameSpace = importedSchemaNameSpace;
        serviceName = xrServiceModel.getName() + SERVICE_SUFFIX;
        serviceNameSpace = importedSchemaNameSpace + SERVICE_SUFFIX;
    }

    public Definition generateWSDL() throws WSDLException {
        return generateWSDL(false);
    }

    public Definition generateWSDL(boolean useSOAP12) throws WSDLException {
        WSDLFactory factory = WSDLFactory.newInstance();
        ExtensionRegistry registry = factory.newPopulatedExtensionRegistry();

        Definition def = factory.newDefinition();
        if (useSOAP12) {
            def.addNamespace(SOAP_12_NAMESPACE_PREFIX, SOAP_12_NAMESPACE_URI);
        }
        else {
            def.addNamespace(SOAP_11_NAMESPACE_PREFIX, SOAP_11_NAMESPACE_URI);
        }
        def.setTargetNamespace(serviceNameSpace);
        def.setQName(new QName(serviceNameSpace, serviceName));
        def.addNamespace(NS_TNS_PREFIX, serviceNameSpace);
        def.addNamespace(TARGET_NAMESPACE_PREFIX, importedSchemaNameSpace);
        def.addNamespace(NS_SCHEMA_PREFIX, W3C_XML_SCHEMA_NS_URI);

        Types types = def.createTypes();
        javax.wsdl.extensions.schema.Schema schema =
            (javax.wsdl.extensions.schema.Schema)registry.createExtension(Types.class, new QName(
                W3C_XML_SCHEMA_NS_URI, TAG_SCHEMA));
        schema.setElement(createInlineSchema());
        types.addExtensibilityElement(schema);
        def.setTypes(types);

        PortType portType = def.createPortType();
        portType.setUndefined(false);
        portType.setQName(new QName(serviceNameSpace, serviceName + PORT_SUFFIX));
        def.addPortType(portType);

        ExtensibilityElement soap = null;
        if (useSOAP12) {
            soap = registry.createExtension(Binding.class, new QName(
                SOAP_12_NAMESPACE_URI, TAG_SOAP_BINDING));
            ((SOAP12Binding)soap).setStyle(SOAP_STYLE);
            ((SOAP12Binding)soap).setTransportURI(SOAP_HTTP_TRANSPORT);
        }
        else {
            soap = registry.createExtension(Binding.class, new QName(SOAP_11_NAMESPACE_URI,
                TAG_SOAP_BINDING));
            ((SOAPBinding)soap).setStyle(SOAP_STYLE);
            ((SOAPBinding)soap).setTransportURI(SOAP_HTTP_TRANSPORT);
        }
        Binding binding = def.createBinding();
        binding.setUndefined(false);
        binding.setQName(new QName(serviceNameSpace, serviceName + BINDING_SUFFIX));
        binding.setPortType(portType);
        binding.addExtensibilityElement(soap);
        def.addBinding(binding);

        ExtensibilityElement sa = null;
        if (useSOAP12) {
            sa = registry.createExtension(Port.class, new QName(SOAP_12_NAMESPACE_URI,
                TAG_SOAP_ADDRESS));
            ((SOAP12Address)sa).setLocationURI(wsdlLocationURI);
        }
        else {
            sa = registry.createExtension(Port.class, new QName(SOAP_11_NAMESPACE_URI,
                TAG_SOAP_ADDRESS));
            ((SOAPAddress)sa).setLocationURI(wsdlLocationURI);
        }
        Service ws = def.createService();
        ws.setQName(new QName(serviceNameSpace, serviceName));
        Port port = def.createPort();
        port.setName(serviceName + "Port");
        port.setBinding(binding);
        port.addExtensibilityElement(sa);
        ws.addPort(port);
        def.addService(ws);

        boolean requireEmptyResponseMessages = false;
        for (Operation op : xrServiceModel.getOperationsList()) {
            if (!(op instanceof QueryOperation)) {
                requireEmptyResponseMessages = true;
                break;
            }
        }
        if (requireEmptyResponseMessages) {
            /*
             * Add in empty response message
             * <wsdl:message name="EmptyResponse">
             *   <wsdl:part name="emptyResponse" element="tns:EmptyResponse"></wsdl:part>
             * </wsdl:message>
             */
            Message emptyResponseMessage = def.createMessage();
            emptyResponseMessage.setUndefined(false);
            emptyResponseMessage.setQName(new QName(serviceNameSpace, EMPTY_RESPONSE));
            Part responsePart = def.createPart();
            responsePart.setName("emptyResponse");
            responsePart.setElementName(new QName(serviceNameSpace, EMPTY_RESPONSE));
            emptyResponseMessage.addPart(responsePart);
            def.addMessage(emptyResponseMessage);
            /*
             * Add in Fault message
             * <wsdl:message name="FaultType">
             *   <wsdl:part name="fault" element="tns:FaultType"></wsdl:part>
             * </wsdl:message>
             */
            Message faultMessage = def.createMessage();
            faultMessage.setUndefined(false);
            faultMessage.setQName(new QName(serviceNameSpace, FAULT_SUFFIX + TYPE_SUFFIX));
            Part faultPart = def.createPart();
            faultPart.setName("fault");
            faultPart.setElementName(new QName(serviceNameSpace, FAULT_SUFFIX + TYPE_SUFFIX));
            faultMessage.addPart(faultPart);
            def.addMessage(faultMessage);
        }
        for (Operation op : xrServiceModel.getOperationsList()) {
            createMethodDefinition(factory, registry, def, op, useSOAP12);
        }

        if (os != null) {
            WSDLWriter writer = factory.newWSDLWriter();
            writer.writeWSDL(def, os);
        }
        return def;
    }

    private void createMethodDefinition(WSDLFactory factory, ExtensionRegistry registry,
        Definition def, Operation operation, boolean useSOAP12) throws WSDLException {
        Message requestMessage = def.createMessage();
        requestMessage.setUndefined(false);
        requestMessage.setQName(new QName(serviceNameSpace, operation.getName() + REQUEST_SUFFIX));
        Part requestPart = def.createPart();
        requestPart.setName(operation.getName() + REQUEST_SUFFIX);
        requestPart.setElementName(new QName(serviceNameSpace, operation.getName()));
        requestMessage.addPart(requestPart);
        def.addMessage(requestMessage);

        Message responseMessage = null;
        if (operation.hasResponse()) {
            responseMessage = def.createMessage();
            responseMessage.setUndefined(false);
            responseMessage.setQName(new QName(serviceNameSpace, operation.getName()
                + RESPONSE_SUFFIX));
            Part responsePart = def.createPart();
            responsePart.setName(operation.getName() + RESPONSE_SUFFIX);
            responsePart.setElementName(new QName(serviceNameSpace, operation.getName()
                + RESPONSE_SUFFIX));
            responseMessage.addPart(responsePart);
            def.addMessage(responseMessage);
        }

        PortType portType =
            def.getPortType(new QName(serviceNameSpace, serviceName + PORT_SUFFIX));
        javax.wsdl.Operation op = def.createOperation();
        op.setUndefined(false);
        op.setName(operation.getName());
        Input input = def.createInput();
        input.setMessage(requestMessage);
        op.setInput(input);
        if (operation.hasResponse()) {
            Output output = def.createOutput();
            output.setMessage(responseMessage);
            op.setOutput(output);
        }
        portType.addOperation(op);

        Binding binding =
            def.getBinding(new QName(serviceNameSpace, serviceName + BINDING_SUFFIX));
        BindingOperation bop = def.createBindingOperation();
        bop.setName(operation.getName());
        ExtensibilityElement so = null;
        if (useSOAP12) {
            so = registry.createExtension(BindingOperation.class, new QName(
                SOAP_12_NAMESPACE_URI, TAG_SOAP_OPERATION));
            ((SOAP12Operation)so).setSoapActionURI(serviceNameSpace + ":" + op.getName());
        }
        else {
            so = registry.createExtension(BindingOperation.class, new QName(
                SOAP_11_NAMESPACE_URI, TAG_SOAP_OPERATION));
            ((SOAPOperation)so).setSoapActionURI(serviceNameSpace + ":" + op.getName());
        }
        bop.addExtensibilityElement(so);
        BindingInput bi = def.createBindingInput();
        ExtensibilityElement soapInputBody = null;
        if (useSOAP12) {
            soapInputBody = registry.createExtension(BindingInput.class, new QName(
                SOAP_12_NAMESPACE_URI, TAG_SOAP_BODY));
            ((SOAP12Body)soapInputBody).setUse(SOAP_USE);
        }
        else {
            soapInputBody = registry.createExtension(BindingInput.class, new QName(
                SOAP_11_NAMESPACE_URI, TAG_SOAP_BODY));
            ((SOAPBody)soapInputBody).setUse(SOAP_USE);
        }
        bi.addExtensibilityElement(soapInputBody);
        bop.setBindingInput(bi);

        if (operation.hasResponse()) {
            BindingOutput bo = def.createBindingOutput();
            ExtensibilityElement soapOutputBody = null;
            if (useSOAP12) {
                soapOutputBody = registry.createExtension(BindingOutput.class, new QName(
                    SOAP_12_NAMESPACE_URI, TAG_SOAP_BODY));
                ((SOAP12Body)soapOutputBody).setUse(SOAP_USE);
            }
            else {
                soapOutputBody = registry.createExtension(BindingOutput.class, new QName(
                    SOAP_11_NAMESPACE_URI, TAG_SOAP_BODY));
                ((SOAPBody)soapOutputBody).setUse(SOAP_USE);
            }
            bo.addExtensibilityElement(soapOutputBody);
            bop.setBindingOutput(bo);
        }
        if (!(operation instanceof QueryOperation)) {
            // non-QueryOperations don't have Responses, but the fault requirements
            // mean we have to create 'dummy' WSDL outputs
            BindingOutput bo = def.createBindingOutput();
            ExtensibilityElement soapOutputBody = null;
            if (useSOAP12) {
                soapOutputBody = registry.createExtension(BindingOutput.class, new QName(
                    SOAP_12_NAMESPACE_URI, TAG_SOAP_BODY));
                ((SOAP12Body)soapOutputBody).setUse(SOAP_USE);
            }
            else {
                soapOutputBody = registry.createExtension(BindingOutput.class, new QName(
                    SOAP_11_NAMESPACE_URI, TAG_SOAP_BODY));
                ((SOAPBody)soapOutputBody).setUse(SOAP_USE);
            }
            bo.addExtensibilityElement(soapOutputBody);
            bop.setBindingOutput(bo);
            // add WSDL fault to binding operations
            BindingFault bindingFault = def.createBindingFault();
            String exceptionName = FAULT_SUFFIX + EXCEPTION_SUFFIX;
            bindingFault.setName(exceptionName);
            ExtensibilityElement soapFaultBody = null;
            if (useSOAP12) {
                soapFaultBody = registry.createExtension(BindingFault.class, new QName(
                    SOAP_12_NAMESPACE_URI, TAG_SOAP_FAULT));
                ((SOAP12Fault)soapFaultBody).setUse(SOAP_USE);
                ((SOAP12Fault)soapFaultBody).setName(exceptionName);
            }
            else {
                soapFaultBody = registry.createExtension(BindingFault.class, new QName(
                    SOAP_11_NAMESPACE_URI, TAG_SOAP_FAULT));
                ((SOAPFault)soapFaultBody).setUse(SOAP_USE);
                ((SOAPFault)soapFaultBody).setName(exceptionName);
            }
            bindingFault.addExtensibilityElement(soapFaultBody);
            bop.addBindingFault(bindingFault);
            Message emptyResponseMessage = def.getMessage(new QName(serviceNameSpace, EMPTY_RESPONSE));
            Output output = def.createOutput();
            output.setName(operation.getName() + EMPTY_RESPONSE);
            output.setMessage(emptyResponseMessage);
            op.setOutput(output);
            Message faultMessage = def.getMessage(new QName(serviceNameSpace,
                FAULT_SUFFIX + TYPE_SUFFIX));
            Fault fault = def.createFault();
            fault.setMessage(faultMessage);
            fault.setName(exceptionName);
            op.addFault(fault);
        }
        binding.addBindingOperation(bop);
    }

    /**
     * Build the inline schema that will make up the content of the
     * {@code <wsdl:types>} section of the WSDL.
     * @return
     */
    @SuppressWarnings("unchecked")
    private org.w3c.dom.Element createInlineSchema() {

        SchemaModelProject project = new SchemaModelProject();
        XMLContext context = new XMLContext(project);
        XMLMarshaller marshaller = context.createMarshaller();
        XMLDescriptor descriptor = (XMLDescriptor) project.getClassDescriptor(Schema.class);
        if (descriptor.getNamespaceResolver() == null) {
            descriptor.setNamespaceResolver(new NamespaceResolver());
        }
        descriptor.getNamespaceResolver().put(NS_TNS_PREFIX, serviceNameSpace);
        descriptor.getNamespaceResolver().put(NS_SCHEMA_PREFIX, W3C_XML_SCHEMA_NS_URI);
        if (hasAttachments) {
            descriptor.getNamespaceResolver().put(WSI_SWAREF_PREFIX, WSI_SWAREF_URI);
        }

        Schema schema = new Schema();
        schema.setTargetNamespace(serviceNameSpace);
        schema.setElementFormDefault(true);
        Import parent = new Import();
        parent.setNamespace(importedSchemaNameSpace);
        parent.setSchemaLocation(DBWS_SCHEMA_XML);
        schema.getImports().add(parent);
        if (hasAttachments) {
            Import ref = new Import();
            ref.setNamespace(WSI_SWAREF_URI);
            // ref.setSchemaLocation("http://ws-i.org/profiles/basic/1.1/swaref.xsd"); // later version
            ref.setSchemaLocation(WSI_SWAREF_XSD_FILE);
            schema.getImports().add(ref);
        }
        boolean requireFaultTypeEmptyResponse = false;
        for (Operation op : xrServiceModel.getOperationsList()) {
            String opName = op.getName();
            ComplexType requestType = new ComplexType();
            // may need to extract tableNameAlias from operation name - everything after first
            // underscore '_' character (for cases where a QueryOperation is not user defined)
            // i.e. String tableNameAlias = opName.substring(opName.indexOf('_') + 1);
            requestType.setName(opName + REQUEST_SUFFIX + TYPE_SUFFIX);
            Sequence requestSequence = null;
            if (op.getParameters().size() > 0) {
                requestSequence = new Sequence();
                for (Parameter p : op.getParameters()) {
                    Element arg = new Element();
                    if (p.isOptional()) {
                        arg.setMinOccurs("0");
                    }
                    arg.setName(p.getName());
                    if (THE_INSTANCE_NAME.equals(p.getName())) {
                        ComplexType nestedComplexType = new ComplexType();
                        Sequence nestedSequence = new Sequence();
                        nestedComplexType.setSequence(nestedSequence);
                        Element nestedElement = new Element();
                        nestedElement.setRef(TARGET_NAMESPACE_PREFIX + ":" + p.getType().getLocalPart());
                        // here we may need to use 'tableNameAlias' instead, i.e.
                        // nestedElement.setRef(TARGET_NAMESPACE_PREFIX + ":" + tableNameAlias);
                        nestedSequence.addElement(nestedElement);
                        arg.setComplexType(nestedComplexType);
                    } else {
                        arg.setName(p.getName());
                        if (p.getType().getNamespaceURI().equals(W3C_XML_SCHEMA_NS_URI)) {
                            arg.setType(NS_SCHEMA_PREFIX + ":" + p.getType().getLocalPart());
                        } else if (p.getType().getNamespaceURI().equals(importedSchemaNameSpace)) {
                            arg.setType(TARGET_NAMESPACE_PREFIX + ":" + p.getType().getLocalPart());
                        } else {
                            arg.setType(p.getType().getLocalPart());
                        }
                    }
                    requestSequence.addElement(arg);
                }
                requestType.setSequence(requestSequence);
            }
            schema.addTopLevelComplexTypes(requestType);
            Element requestElement = new Element();
            requestElement.setName(op.getName());
            requestElement.setType(NS_TNS_PREFIX + ":" + requestType.getName());
            schema.addTopLevelElement(requestElement);
            // build response message based on operation type
            if (op instanceof QueryOperation) {
                QueryOperation q = (QueryOperation) op;
                ComplexType responseType = new ComplexType();
                responseType.setName(op.getName() + RESPONSE_SUFFIX + TYPE_SUFFIX);
                Sequence responseSequence = new Sequence();
                Element result = new Element();
                result.setName("result");
                if (q.isAttachment()) {
                    result.setType(WSI_SWAREF_PREFIX + ":" + WSI_SWAREF);
                } else if (q.isSimpleXMLFormat() || q.getResultType().equals(new QName(W3C_XML_SCHEMA_NS_URI, "any"))) {
                    ComplexType anyType = new ComplexType();
                    Sequence anySequence = new Sequence();
                    anySequence.addAny(new Any());
                    anyType.setSequence(anySequence);
                    result.setComplexType(anyType);
                } else {
                    if (q.getResultType().getNamespaceURI().equals(W3C_XML_SCHEMA_NS_URI)) {
                        result.setType(NS_SCHEMA_PREFIX + ":" + q.getResultType().getLocalPart());
                    } else {
                        ComplexType nestedComplexType = new ComplexType();
                        Sequence nestedSequence = new Sequence();
                        nestedComplexType.setSequence(nestedSequence);
                        Element nestedElement = new Element();
                        // may need if/else based on if the operation is/isn't user defined, i.e.
                        //if (!q.isUserDefined()) {
                        //    nestedElement.setRef(TARGET_NAMESPACE_PREFIX + ":" + tableNameAlias);
                        //} else {
                        //    nestedElement.setRef(TARGET_NAMESPACE_PREFIX + ":" + q.getResultType().getLocalPart());
                        //}
                        nestedElement.setRef(TARGET_NAMESPACE_PREFIX + ":" + q.getResultType().getLocalPart());
                        nestedElement.setMinOccurs("0");
                        if (q.isCollection()) {
                            nestedElement.setMaxOccurs("unbounded");
                        }
                        nestedSequence.addElement(nestedElement);
                        result.setComplexType(nestedComplexType);
                    }
                }
                responseSequence.addElement(result);
                responseType.setSequence(responseSequence);
                schema.addTopLevelComplexTypes(responseType);
                Element responseElement = new Element();
                responseElement.setName(op.getName() + RESPONSE_SUFFIX);
                responseElement.setType(NS_TNS_PREFIX + ":" + responseType.getName());
                schema.addTopLevelElement(responseElement);
            } else {
                requireFaultTypeEmptyResponse = true;
            }
        }
        if (requireFaultTypeEmptyResponse) {
            // <element name="EmptyResponse">
            //   <xsd:complexType/>
            // </element>
            Element emptyResponseElement = new Element();
            emptyResponseElement.setName(EMPTY_RESPONSE);
            ComplexType emptyResponseComplexType = new ComplexType();
            emptyResponseElement.setComplexType(emptyResponseComplexType);
            schema.addTopLevelElement(emptyResponseElement);
            // <xsd:element name="FaultType">
            //   <xsd:complexType>
            //     <xsd:sequence>
            //       <xsd:element name="faultCode" type="xsd:string"/>
            //       <xsd:element name="faultString" type="xsd:string"/>
            //     </xsd:sequence>
            //   </xsd:complexType>
            // </element>
            Element elementFaultType = new Element();
            elementFaultType.setName(FAULT_SUFFIX + TYPE_SUFFIX);
            ComplexType faultComplexType = new ComplexType();
            elementFaultType.setComplexType(faultComplexType);
            Sequence nestedSequence = new Sequence();
            faultComplexType.setSequence(nestedSequence);
            Element faultCodeElement = new Element();
            faultCodeElement.setName("faultCode");
            faultCodeElement.setMinOccurs("1");
            faultCodeElement.setType(NS_SCHEMA_PREFIX + ":string");
            nestedSequence.addElement(faultCodeElement);
            Element faultStringElement = new Element();
            faultStringElement.setMinOccurs("1");
            faultStringElement.setName("faultString");
            faultStringElement.setType(NS_SCHEMA_PREFIX + ":string");
            nestedSequence.addElement(faultStringElement);
            schema.addTopLevelElement(elementFaultType);
        }
        return marshaller.objectToXML(schema).getDocumentElement();
    }

    /**
     * Return the name of the service.
     */
    public String getServiceName() {
        return serviceName;
    }

    /**
     * Return the namespace of the service.
     */
    public String getServiceNameSpace() {
        return serviceNameSpace;
    }
}
