net.sf.taverna.t2.uiexts.bioswr.model.HTTPBindingTemplateService.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.taverna.t2.uiexts.bioswr.model.HTTPBindingTemplateService.java

Source

/**
 * *****************************************************************************
 * Copyright (C) 2014 Spanish National Bioinformatics Institute (INB),
 * Barcelona Supercomputing Center and The University of Manchester
 *
 * Modifications to the initial code base are copyright of their respective
 * authors, or their employers as appropriate.
 *
 * This program 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.
 *
 * This program 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.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307
 *****************************************************************************
 */

package net.sf.taverna.t2.uiexts.bioswr.model;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.Icon;
import javax.xml.bind.DatatypeConverter;
import javax.xml.namespace.QName;
import net.sf.taverna.t2.activities.rest.RESTActivity;
import net.sf.taverna.t2.activities.rest.ui.servicedescription.GenericRESTTemplateService;
import net.sf.taverna.t2.activities.rest.ui.servicedescription.RESTActivityIcon;
import net.sf.taverna.t2.servicedescriptions.ServiceDescription;
import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaCollection;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaParticle;
import org.apache.ws.commons.schema.XmlSchemaSequence;
import org.apache.ws.commons.schema.XmlSchemaSequenceMember;
import org.apache.ws.commons.schema.XmlSchemaType;
import org.inb.bsc.wsdl20.Binding;
import org.inb.bsc.wsdl20.BindingMessageReference;
import org.inb.bsc.wsdl20.BindingOperation;
import org.inb.bsc.wsdl20.Description;
import org.inb.bsc.wsdl20.ElementDeclaration;
import org.inb.bsc.wsdl20.Endpoint;
import org.inb.bsc.wsdl20.Interface;
import org.inb.bsc.wsdl20.InterfaceMessageReference;
import org.inb.bsc.wsdl20.MessageContentModel;
import org.inb.bsc.wsdl20.Service;
import org.inb.bsc.wsdl20.extensions.WSDLPredefinedExtension;
import org.inb.bsc.wsdl20.extensions.http.HTTPBindingMessageReferenceExtensions;
import org.inb.bsc.wsdl20.extensions.http.HTTPBindingOperationExtensions;
import org.inb.bsc.wsdl20.extensions.http.HTTPHeader;
import uk.org.taverna.scufl2.api.configurations.Configuration;

/**
 * @author Dmitry Repchevsky
 */

public class HTTPBindingTemplateService extends ServiceDescription implements ServiceDescriptionProvider {

    private final BindingOperation operation;

    public HTTPBindingTemplateService(BindingOperation operation) {
        this.operation = operation;
    }

    @Override
    public URI getActivityType() {
        return GenericRESTTemplateService.ACTIVITY_TYPE;
    }

    @Override
    public Icon getIcon() {
        return RESTActivityIcon.getRESTActivityIcon();
    }

    @Override
    public String getName() {
        return "REST";
    }

    @Override
    public String getId() {
        return "http://www.taverna.org.uk/2010/services/rest";
    }

    @Override
    public boolean isTemplateService() {
        return false;
    }

    @Override
    public List<? extends Comparable<?>> getPath() {
        return Arrays.asList(SERVICE_TEMPLATES);
    }

    @Override
    protected List<? extends Object> getIdentifyingData() {
        return null;
    }

    @Override
    public void findServiceDescriptionsAsync(FindServiceDescriptionsCallBack callBack) {
        callBack.partialResults(Collections.singleton(this));
        callBack.finished();
    }

    @Override
    public Configuration getActivityConfiguration() {
        Configuration configuration = new Configuration();
        configuration.setType(GenericRESTTemplateService.ACTIVITY_TYPE.resolve("#Config"));

        Binding binding = operation.getParent();
        Interface _interface = binding.getInterface();

        Description description = binding.getParentElement();
        for (Service service : description.getAllServices()) {
            if (_interface.equals(service.getInterface())) {
                for (Endpoint endpoint : service.getEndpoints()) {
                    if (binding.equals(endpoint.getBinding())) {
                        ObjectNode json = (ObjectNode) configuration.getJson();
                        ObjectNode requestNode = json.objectNode();
                        ArrayNode headersNode = requestNode.arrayNode();

                        HTTPBindingOperationExtensions ext = (HTTPBindingOperationExtensions) operation
                                .getComponentExtensions(WSDLPredefinedExtension.HTTP.URI);
                        String httpMethod = ext.getHttpMethod();
                        requestNode.put("httpMethod", httpMethod == null ? "GET" : httpMethod);

                        URI address = endpoint.getAddress();
                        StringBuilder url = new StringBuilder(address.toString());

                        String location = operation
                                .getExtensionAttribute(HTTPBindingOperationExtensions.HTTP_LOCATION_ATTR);
                        if (location != null) {
                            url.append(location);
                        }

                        String inputSerialization = ext.getHttpInputSerialization();
                        if ("application/x-www-form-urlencoded".equals(inputSerialization)) {
                            putUrlEncodedInputs(operation, httpMethod, headersNode, url);
                        } else if ("application/xml".equals(inputSerialization)
                                && ("POST".equals(httpMethod) || "PUT".equals(httpMethod))) {
                            putXMLInputs(operation, headersNode);
                            headersNode.addObject().put("header", "Content-Type").put("value", "application/xml");
                        }

                        requestNode.put("absoluteURITemplate", url.toString());

                        String outputSerialization = ext.getHttpOutputSerialization();
                        if (outputSerialization != null) {
                            headersNode.addObject().put("header", "Accept").put("value", outputSerialization);
                        }

                        requestNode.set("headers", headersNode);
                        json.set("request", requestNode);
                        json.put("outgoingDataFormat", RESTActivity.DATA_FORMAT.String.name());
                        json.put("showRedirectionOutputPort", false);
                        json.put("showActualURLPort", false);
                        json.put("showResponseHeadersPort", false);
                        json.put("escapeParameters", true);

                    }
                }
            }
        }

        return configuration;
    }

    private void putXMLInputs(BindingOperation operation, ArrayNode headersNode) {
        List<BindingMessageReference> inputs = operation.getBindingInputs();
        for (BindingMessageReference input : inputs) {
            writeHeaders(input, headersNode);

            InterfaceMessageReference in = input.getInterfaceMessageReference();
            ElementDeclaration<XmlSchemaElement> elementDeclaration = in.getElementDeclaration();
            XmlSchemaElement element = elementDeclaration.getContent();
            if (element != null) {
                QName elementName = element.getQName();
            }
        }
    }

    private void putUrlEncodedInputs(BindingOperation operation, String method, ArrayNode headersNode,
            StringBuilder url) {
        Set<String> cited = null;

        String ignoreUncited = operation
                .getExtensionAttribute(HTTPBindingOperationExtensions.HTTP_IGNORE_UNCITED_ATTR);
        if (ignoreUncited == null || !DatatypeConverter.parseBoolean(ignoreUncited)) {
            String location = operation.getExtensionAttribute(HTTPBindingOperationExtensions.HTTP_LOCATION_ATTR);
            if (location != null) {
                cited = new TreeSet<String>();
                Pattern pattern = Pattern.compile("\\{(\\w+\\d*)\\}");
                Matcher m = pattern.matcher(location);
                while (m.find()) {
                    cited.add(m.group(1));
                }
            }
        }
        List<BindingMessageReference> inputs = operation.getBindingInputs();
        for (BindingMessageReference input : inputs) {
            writeHeaders(input, headersNode);

            if (cited != null) {
                if ("GET".equals(method) || "DELETE".equals(method)) {
                    addUrlEncodedParams(input, cited, url);
                } else {
                    headersNode.addObject().put("header", "Content-Type").put("value",
                            "application/x-www-form-urlencoded");
                    addUrlEncodedParams(input, cited, url);
                }
            }
        }
    }

    private void addUrlEncodedParams(BindingMessageReference input, Set<String> cited, StringBuilder sb) {
        InterfaceMessageReference in = input.getInterfaceMessageReference();

        ElementDeclaration<XmlSchemaElement> elementDeclaration = in.getElementDeclaration();
        if (elementDeclaration != null) {
            XmlSchemaElement wrapperElement = elementDeclaration.getContent();
            XmlSchemaType wrapperType = wrapperElement.getSchemaType();
            if (wrapperType == null) {
                QName wrapperTypeName = wrapperElement.getSchemaTypeName();
                if (wrapperTypeName != null) {
                    XmlSchema xmlSchema = wrapperElement.getParent();
                    XmlSchemaCollection xmlSchemaCollection = xmlSchema.getParent();
                    wrapperType = xmlSchemaCollection != null ? xmlSchemaCollection.getTypeByQName(wrapperTypeName)
                            : xmlSchema.getTypeByName(wrapperTypeName);
                }
            }

            if (wrapperType instanceof XmlSchemaComplexType) {
                XmlSchemaComplexType complexWrapperType = (XmlSchemaComplexType) wrapperType;
                XmlSchemaParticle particle = complexWrapperType.getParticle();
                if (particle instanceof XmlSchemaSequence) {
                    List<String> parameters = new ArrayList<String>();

                    XmlSchemaSequence sequence = (XmlSchemaSequence) particle;
                    List<XmlSchemaSequenceMember> items = sequence.getItems();
                    for (XmlSchemaSequenceMember item : items) {
                        if (item instanceof XmlSchemaElement) {
                            XmlSchemaElement element = (XmlSchemaElement) item;
                            // some parameters may be from URL template...
                            String name = element.getName();
                            if (name != null && !cited.contains(name)) {
                                parameters.add(name);
                            }
                        }
                    }

                    if (!parameters.isEmpty()) {
                        HTTPBindingOperationExtensions ext = (HTTPBindingOperationExtensions) operation
                                .getComponentExtensions(WSDLPredefinedExtension.HTTP.URI);
                        Character separator = ext.getHttpQueryParameterSeparator();

                        sb.append('?');
                        final int n = parameters.size() - 1;
                        for (int i = 0; i < n; i++) {
                            String parameter = parameters.get(i);
                            sb.append(parameter).append("={").append(parameter).append("}")
                                    .append(separator != null ? separator : '&');
                        }
                        String parameter = parameters.get(n);
                        sb.append(parameter).append("={").append(parameter).append("}");
                    }
                }
            }
        }
    }

    private static void putOutputs(BindingOperation operation) {
        List<BindingMessageReference> outputs = operation.getBindingOutputs();
        for (BindingMessageReference output : outputs) {

            InterfaceMessageReference out = output.getInterfaceMessageReference();
            MessageContentModel messageContentModel = out.getMessageContentModel();
            if (MessageContentModel.none == messageContentModel) {
                continue; // no body content;
            }

            if (MessageContentModel.other != messageContentModel) {
                ElementDeclaration<XmlSchemaElement> elementDeclaration = out.getElementDeclaration();
                if (elementDeclaration != null) {
                    XmlSchemaElement element = elementDeclaration.getContent();
                    if (element != null) {
                        QName elementName = element.getQName();
                    }
                }
            }

        }
    }

    private static void writeHeaders(BindingMessageReference message, ArrayNode headersNode) {
        HTTPBindingMessageReferenceExtensions ext = (HTTPBindingMessageReferenceExtensions) message
                .getComponentExtensions(WSDLPredefinedExtension.HTTP.URI);

        List<HTTPHeader> headers = ext.getHttpHeaders();
        for (HTTPHeader header : headers) {
            headersNode.addObject().put("header", header.getName()).put("value", "");
        }
    }

}