com.eviware.soapui.impl.wsdl.support.soap.SoapRequestBuilder.java Source code

Java tutorial

Introduction

Here is the source code for com.eviware.soapui.impl.wsdl.support.soap.SoapRequestBuilder.java

Source

/*
 *  soapui, copyright (C) 2006 eviware.com 
 *
 *  SoapUI is free software; you can redistribute it and/or modify it under the 
 *  terms of the GNU Lesser General Public License as published by the Free Software Foundation; 
 *  either version 2.1 of the License, or (at your option) any later version.
 *
 *  SoapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
 *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 *  See the GNU Lesser General Public License for more details at gnu.org.
 */

package com.eviware.soapui.impl.wsdl.support.soap;

import java.io.StringWriter;
import java.util.Map;

import javax.wsdl.BindingOperation;
import javax.wsdl.Message;
import javax.wsdl.Part;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.soap.SOAPBody;
import javax.wsdl.extensions.soap.SOAPHeader;
import javax.xml.namespace.QName;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlbeans.SchemaGlobalElement;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;

import com.eviware.soapui.impl.wsdl.WsdlInterface;
import com.eviware.soapui.impl.wsdl.support.Constants;
import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlContext;
import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils;
import com.eviware.soapui.impl.wsdl.support.xsd.SampleXmlUtil;
import com.eviware.soapui.model.iface.Interface;
import com.eviware.soapui.model.iface.Operation;
import com.eviware.soapui.model.iface.Request;
import com.eviware.soapui.model.iface.RequestBuilder;
import com.eviware.soapui.settings.WsdlSettings;
import com.eviware.soapui.support.xml.XmlUtils;

/**
 * Builds SOAP requests according to WSDL/XSD definitions
 * 
 * @author Ole.Matzura
 */

public class SoapRequestBuilder implements RequestBuilder {
    private final static Log log = LogFactory.getLog(SoapRequestBuilder.class);

    private WsdlContext wsdlContext;
    private WsdlInterface iface;

    public SoapRequestBuilder(WsdlInterface iface) throws Exception {
        this.iface = iface;
        this.wsdlContext = iface.getWsdlContext();
    }

    public SoapRequestBuilder(WsdlContext wsdlContext) {
        this.wsdlContext = wsdlContext;
    }

    public Interface getInterface() {
        return iface;
    }

    public Request buildRequest(Operation operation, Map params) {
        return null;
    }

    public String buildSoapRequest(BindingOperation bindingOperation, boolean buildOptional) throws Exception {
        boolean inputSoapEncoded = WsdlUtils.isInputSoapEncoded(bindingOperation);
        SampleXmlUtil xmlGenerator = new SampleXmlUtil(inputSoapEncoded);
        xmlGenerator.setIgnoreOptional(!buildOptional);

        XmlObject object = XmlObject.Factory.newInstance();
        XmlCursor cursor = object.newCursor();
        cursor.toNextToken();
        cursor.beginElement(wsdlContext.getSoapVersion().getEnvelopeQName());

        if (inputSoapEncoded) {
            cursor.insertNamespace("xsi", Constants.XSI_NS);
            cursor.insertNamespace("xsd", Constants.XSD_NS);
        }

        cursor.toFirstChild();

        cursor.beginElement(wsdlContext.getSoapVersion().getBodyQName());
        cursor.toFirstChild();

        if (WsdlUtils.isRpc(wsdlContext.getDefinition(), bindingOperation)) {
            buildRpcRequest(bindingOperation, cursor, xmlGenerator);
        } else {
            buildDocumentRequest(bindingOperation, cursor, xmlGenerator);
        }

        addHeaders(bindingOperation, cursor, xmlGenerator);
        cursor.dispose();

        try {
            StringWriter writer = new StringWriter();
            XmlUtils.serializePretty(object, writer);
            return writer.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return object.xmlText();
        }
    }

    private void buildMultipartRequest(BindingOperation bindingOperation, XmlCursor cursor,
            SampleXmlUtil xmlGenerator) throws Exception {
        buildDocumentRequest(bindingOperation, cursor, xmlGenerator);
    }

    private void addHeaders(BindingOperation bindingOperation, XmlCursor cursor, SampleXmlUtil xmlGenerator)
            throws Exception {
        ExtensibilityElement[] headers = WsdlUtils.getExtensiblityElements(
                bindingOperation.getBindingInput().getExtensibilityElements(), SOAPHeader.class);

        // reposition
        cursor.toStartDoc();
        cursor.toChild(wsdlContext.getSoapVersion().getEnvelopeQName());
        cursor.toFirstChild();

        cursor.beginElement(wsdlContext.getSoapVersion().getHeaderQName());
        cursor.toFirstChild();

        for (int i = 0; i < headers.length; i++) {
            SOAPHeader header = (SOAPHeader) headers[i];

            Message message = wsdlContext.getDefinition().getMessage(header.getMessage());
            if (message == null) {
                log.error("Missing message for header: " + header.getMessage());
                continue;
            }

            Part part = message.getPart(header.getPart());

            if (part != null)
                createElementForPart(part, cursor, xmlGenerator);
            else
                log.error("Missing part for header; " + header.getPart());
        }
    }

    private void createElementForPart(Part part, XmlCursor cursor, SampleXmlUtil xmlGenerator) throws Exception {
        QName elementName = part.getElementName();
        QName typeName = part.getTypeName();

        if (elementName != null) {
            cursor.beginElement(elementName);

            if (wsdlContext.hasSchemaTypes()) {
                SchemaGlobalElement elm = wsdlContext.getSchemaTypeLoader().findElement(elementName);
                if (elm != null) {
                    cursor.toFirstChild();
                    xmlGenerator.createSampleForType(elm.getType(), cursor);
                } else
                    log.error("Could not find element [" + elementName + "] specified in part [" + part.getName()
                            + "]");
            }

            cursor.toParent();
        } else {
            cursor.beginElement(new QName(wsdlContext.getDefinition().getTargetNamespace(), part.getName()));
            if (typeName != null && wsdlContext.hasSchemaTypes()) {
                SchemaType type = wsdlContext.getSchemaTypeLoader().findType(typeName);

                if (type != null) {
                    cursor.toFirstChild();
                    xmlGenerator.createSampleForType(type, cursor);
                } else
                    log.error("Could not find type [" + typeName + "] specified in part [" + part.getName() + "]");
            }

            cursor.toParent();
        }
    }

    private void buildDocumentRequest(BindingOperation bindingOperation, XmlCursor cursor,
            SampleXmlUtil xmlGenerator) throws Exception {
        Part[] parts = WsdlUtils.getInputParts(bindingOperation);

        for (int i = 0; i < parts.length; i++) {
            if (!WsdlUtils.isAttachmentInputPart(parts[i], bindingOperation)) {
                XmlCursor c = cursor.newCursor();
                c.toLastChild();
                createElementForPart(parts[i], c, xmlGenerator);
                c.dispose();
            }
        }
    }

    private void buildRpcRequest(BindingOperation bindingOperation, XmlCursor cursor, SampleXmlUtil xmlGenerator)
            throws Exception {
        // rpc requests use the operation name as root element
        SOAPBody body = (SOAPBody) WsdlUtils.getExtensiblityElement(
                bindingOperation.getBindingInput().getExtensibilityElements(), SOAPBody.class);

        String ns = wsdlContext.getDefinition().getTargetNamespace();
        if (body != null && body.getNamespaceURI() != null)
            ns = body.getNamespaceURI();
        else
            log.warn("missing namespace on soapbind:body, using targetNamespace instead (BP violation)");

        cursor.beginElement(new QName(ns, bindingOperation.getName()));
        if (xmlGenerator.isSoapEnc())
            cursor.insertAttributeWithValue(
                    new QName(wsdlContext.getSoapVersion().getEnvelopeNamespace(), "encodingStyle"),
                    wsdlContext.getSoapVersion().getEncodingNamespace());

        Part[] inputParts = WsdlUtils.getInputParts(bindingOperation);
        for (int i = 0; i < inputParts.length; i++) {
            Part part = inputParts[i];
            if (WsdlUtils.isAttachmentInputPart(part, bindingOperation)) {
                if (iface.getSettings().getBoolean(WsdlSettings.ATTACHMENT_PARTS)) {
                    XmlCursor c = cursor.newCursor();
                    c.toLastChild();
                    c.beginElement(part.getName());
                    c.insertAttributeWithValue("href", part.getName() + "Attachment");
                    c.dispose();
                }
            } else {
                if (wsdlContext.hasSchemaTypes()) {
                    QName typeName = part.getTypeName();
                    if (typeName != null) {
                        SchemaType type = wsdlContext.findType(typeName);

                        if (type != null) {
                            XmlCursor c = cursor.newCursor();
                            c.toLastChild();
                            c.insertElement(part.getName());
                            c.toPrevToken();

                            xmlGenerator.createSampleForType(type, c);
                            c.dispose();
                        } else
                            log.warn("Failed to find type [" + typeName + "]");
                    } else {
                        SchemaGlobalElement element = wsdlContext.getSchemaTypeLoader()
                                .findElement(part.getElementName());
                        if (element != null) {
                            XmlCursor c = cursor.newCursor();
                            c.toLastChild();
                            c.insertElement(element.getName());
                            c.toPrevToken();

                            xmlGenerator.createSampleForType(element.getType(), c);
                            c.dispose();
                        } else
                            log.warn("Failed to find element [" + part.getElementName() + "]");
                    }
                }
            }
        }
    }

    public void setWsdlContext(WsdlContext wsdlContext) {
        this.wsdlContext = wsdlContext;
    }

    public void setInterface(WsdlInterface iface) {
        this.iface = iface;
    }
}