io.github.tavernaextras.biocatalogue.integration.Integration.java Source code

Java tutorial

Introduction

Here is the source code for io.github.tavernaextras.biocatalogue.integration.Integration.java

Source

package io.github.tavernaextras.biocatalogue.integration;
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JLabel;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Logger;
import org.biocatalogue.x2009.xml.rest.ResourceLink;
import org.biocatalogue.x2009.xml.rest.RestMethod;
import org.biocatalogue.x2009.xml.rest.RestService;
import org.biocatalogue.x2009.xml.rest.Service;
import org.biocatalogue.x2009.xml.rest.ServiceTechnologyType;
import org.biocatalogue.x2009.xml.rest.SoapOperation;
import org.biocatalogue.x2009.xml.rest.SoapService;
import org.biocatalogue.x2009.xml.rest.Service.Variants;

import io.github.tavernaextras.biocatalogue.model.HTTPMethodInterpreter;
import io.github.tavernaextras.biocatalogue.model.HTTPMethodInterpreter.UnsupportedHTTPMethodException;
import io.github.tavernaextras.biocatalogue.model.Resource;
import io.github.tavernaextras.biocatalogue.model.Resource.TYPE;
import io.github.tavernaextras.biocatalogue.model.connectivity.BioCatalogueClient;
import io.github.tavernaextras.biocatalogue.model.ResourceManager;
import io.github.tavernaextras.biocatalogue.model.SoapOperationIdentity;
import io.github.tavernaextras.biocatalogue.model.SoapOperationPortIdentity;
import io.github.tavernaextras.biocatalogue.model.SoapProcessorIdentity;
import io.github.tavernaextras.biocatalogue.model.Util;
import org.apache.taverna.activities.rest.RESTActivity;
import org.apache.taverna.activities.rest.RESTActivity.HTTP_METHOD;
import org.apache.taverna.activities.wsdl.WSDLActivity;
import org.apache.taverna.activities.wsdl.servicedescriptions.WSDLServiceDescription;
import org.apache.taverna.ui.menu.ContextualSelection;
import io.github.tavernaextras.biocatalogue.MainComponentFactory;
import io.github.tavernaextras.biocatalogue.integration.service_panel.BioCatalogueRESTServiceProvider;
import io.github.tavernaextras.biocatalogue.integration.service_panel.BioCatalogueWSDLOperationServiceProvider;
import io.github.tavernaextras.biocatalogue.integration.service_panel.RESTFromBioCatalogueServiceDescription;
import io.github.tavernaextras.biocatalogue.integration.service_panel.WSDLOperationFromBioCatalogueServiceDescription;
import org.apache.taverna.workbench.file.FileManager;
import org.apache.taverna.workbench.ui.workflowview.WorkflowView;
import org.apache.taverna.workflowmodel.Dataflow;
import org.apache.taverna.workflowmodel.Port;
import org.apache.taverna.workflowmodel.Processor;
import org.apache.taverna.workflowmodel.processor.activity.Activity;
import org.apache.taverna.workflowmodel.processor.activity.ActivityInputPort;
import org.apache.taverna.workflowmodel.processor.activity.ActivityOutputPort;
import org.apache.taverna.workflowmodel.utils.Tools;

/**
 * This class contains helpers for deeper integration with Taverna UI.
 * 
 * @author Sergejs Aleksejevs
 */
public class Integration {
    private static final Logger logger = Logger.getLogger(Integration.class);

    // deny instantiation of this class
    private Integration() {
    }

    /**
     * Adds a processor to the current workflow.
     * The processor is specified by WSDL location and the operation name.
     * 
     * @param processorResource Resource to add to the current workflow.
     * @return Outcome of inserting the processor into the current workflow as a
     *         HTML-formatted string (with no opening and closing HTML tags).
     */
    public static JComponent insertProcessorIntoCurrentWorkflow(ResourceLink processorResource) {
        // check if this type of resource can be added to workflow diagram
        TYPE resourceType = Resource.getResourceTypeFromResourceURL(processorResource.getHref());
        if (resourceType.isSuitableForAddingToWorkflowDiagram()) {
            switch (resourceType) {
            case SOAPOperation:
                SoapOperation soapOp = (SoapOperation) processorResource;
                try {
                    SoapService soapService = BioCatalogueClient.getInstance()
                            .getBioCatalogueSoapService(soapOp.getAncestors().getSoapService().getHref());

                    try {
                        WSDLServiceDescription myServiceDescription = new WSDLServiceDescription();
                        myServiceDescription.setOperation(soapOp.getName());
                        myServiceDescription.setUse("literal"); // or "encoded"
                        myServiceDescription.setStyle("document"); // or "rpc"
                        myServiceDescription.setURI(new URI(soapService.getWsdlLocation()));
                        myServiceDescription
                                .setDescription(StringEscapeUtils.escapeHtml(soapService.getDescription())); // TODO - not sure where this is used

                        if (WorkflowView.importServiceDescription(myServiceDescription, false) != null) {
                            return (new JLabel(
                                    "Selected " + TYPE.SOAPOperation.getTypeName()
                                            + " was successfully added to the current workflow",
                                    ResourceManager.getImageIcon(ResourceManager.TICK_ICON), JLabel.CENTER));
                        } else {
                            return (new JLabel("<html><center>Taverna was unable to add selected "
                                    + TYPE.SOAPOperation.getTypeName()
                                    + " as a service to the current workflow.<br>This could be because the service is currently not accessible.</center></html>",
                                    ResourceManager.getImageIcon(ResourceManager.ERROR_ICON), JLabel.CENTER));
                        }
                    } catch (URISyntaxException e) {
                        logger.error("Couldn't add " + TYPE.SOAPOperation + " to the current workflow", e);
                        return (new JLabel(
                                "<html>Could not add the selected " + TYPE.SOAPOperation.getTypeName()
                                        + " to the current workflow.<br>"
                                        + "Log file will containt additional details about this error.</html>",
                                ResourceManager.getImageIcon(ResourceManager.ERROR_ICON), JLabel.CENTER));
                    }

                } catch (Exception e) {
                    logger.error("Failed to fetch required details to add this " + TYPE.SOAPOperation
                            + " into the current workflow.", e);
                    return (new JLabel(
                            "<html>Failed to fetch required details to add this<br>"
                                    + TYPE.SOAPOperation.getTypeName() + " into the current workflow.</html>",
                            ResourceManager.getImageIcon(ResourceManager.ERROR_ICON), JLabel.CENTER));
                }

            case RESTMethod:
                // received object may only contain limited data, therefore need to fetch full details first
                try {
                    RestMethod restMethod = BioCatalogueClient.getInstance()
                            .getBioCatalogueRestMethod(processorResource.getHref());

                    // actual import of the service into the workflow
                    RESTFromBioCatalogueServiceDescription restServiceDescription = createRESTServiceDescriptionFromRESTMethod(
                            restMethod);
                    WorkflowView.importServiceDescription(restServiceDescription, false);

                    // prepare result of the operation to be shown in the the waiting dialog window
                    String warnings = extractWarningsFromRESTServiceDescription(restServiceDescription, false);
                    JLabel outcomes = new JLabel(
                            "<html>Selected " + TYPE.RESTMethod.getTypeName()
                                    + " was successfully added to the current workflow" + warnings + "</html>",
                            ResourceManager.getImageIcon(warnings.length() > 0 ? ResourceManager.WARNING_ICON
                                    : ResourceManager.TICK_ICON),
                            JLabel.CENTER);
                    outcomes.setIconTextGap(20);
                    return (outcomes);
                } catch (UnsupportedHTTPMethodException e) {
                    logger.error(e);
                    return (new JLabel(e.getMessage(), ResourceManager.getImageIcon(ResourceManager.ERROR_ICON),
                            JLabel.CENTER));
                } catch (Exception e) {
                    logger.error("Failed to fetch required details to add this " + TYPE.RESTMethod
                            + " as a service to the current workflow.", e);
                    return (new JLabel(
                            "<html>Failed to fetch required details to add this " + TYPE.RESTMethod.getTypeName()
                                    + "<br>" + "as a service to the current workflow.</html>",
                            ResourceManager.getImageIcon(ResourceManager.ERROR_ICON), JLabel.CENTER));
                }

                // type not currently supported, but maybe in the future?
            default:
                return (new JLabel(
                        "Adding " + resourceType.getCollectionName()
                                + " to the current workflow is not yet possible",
                        ResourceManager.getImageIcon(ResourceManager.ERROR_ICON), JLabel.CENTER));
            }
        }

        // definitely not supported type
        return (new JLabel(
                "<html>It is not possible to add resources of the provided type<br>"
                        + "into the current workflow.</html>",
                ResourceManager.getImageIcon(ResourceManager.ERROR_ICON), JLabel.CENTER));
    }

    /**
     * 
     * @param processorResource
     * @return Outcome of inserting the processor into the current workflow as a
     *         HTML-formatted string (with no opening and closing HTML tags).
     */
    public static JComponent insertProcesorIntoServicePanel(ResourceLink processorResource) {
        // check if this type of resource can be added to Service Panel
        TYPE resourceType = Resource.getResourceTypeFromResourceURL(processorResource.getHref());
        if (resourceType.isSuitableForAddingToServicePanel()) {
            switch (resourceType) {
            case SOAPOperation:
                SoapOperation soapOp = (SoapOperation) processorResource;
                try {
                    SoapService soapService = BioCatalogueClient.getInstance()
                            .getBioCatalogueSoapService(soapOp.getAncestors().getSoapService().getHref());
                    SoapOperationIdentity soapOpId = new SoapOperationIdentity(soapService.getWsdlLocation(),
                            soapOp.getName(), StringEscapeUtils.escapeHtml(soapOp.getDescription()));
                    WSDLOperationFromBioCatalogueServiceDescription wsdlOperationDescription = new WSDLOperationFromBioCatalogueServiceDescription(
                            soapOpId);
                    BioCatalogueWSDLOperationServiceProvider.registerWSDLOperation(wsdlOperationDescription, null);

                    return (new JLabel("Selected SOAP operation has been successfully added to the Service Panel.",
                            ResourceManager.getImageIcon(ResourceManager.TICK_ICON), JLabel.CENTER));
                } catch (Exception e) {
                    logger.error(
                            "Failed to fetch required details to add this SOAP service into the Service Panel.", e);
                    return (new JLabel(
                            "Failed to fetch required details to add this "
                                    + "SOAP service into the Service Panel.",
                            ResourceManager.getImageIcon(ResourceManager.ERROR_ICON), JLabel.CENTER));
                }

            case RESTMethod:
                try {
                    // received object may only contain limited data, therefore need to fetch full details first
                    RestMethod restMethod = BioCatalogueClient.getInstance()
                            .getBioCatalogueRestMethod(processorResource.getHref());
                    RESTFromBioCatalogueServiceDescription restServiceDescription = createRESTServiceDescriptionFromRESTMethod(
                            restMethod);

                    // actual insertion of the REST method into Service Panel
                    BioCatalogueRESTServiceProvider.registerNewRESTMethod(restServiceDescription, null);

                    // prepare result of the operation to be shown in the the waiting dialog window
                    String warnings = extractWarningsFromRESTServiceDescription(restServiceDescription, true);
                    JLabel outcomes = new JLabel(
                            "<html>Selected REST method has been successfully added to the Service Panel" + warnings
                                    + "</html>",
                            ResourceManager.getImageIcon(warnings.length() > 0 ? ResourceManager.WARNING_ICON
                                    : ResourceManager.TICK_ICON),
                            JLabel.CENTER);
                    outcomes.setIconTextGap(20);
                    return (outcomes);
                } catch (UnsupportedHTTPMethodException e) {
                    logger.error(e);
                    return (new JLabel(e.getMessage(), ResourceManager.getImageIcon(ResourceManager.ERROR_ICON),
                            JLabel.CENTER));
                } catch (Exception e) {
                    logger.error(
                            "Failed to fetch required details to add this REST service into the Service Panel.", e);
                    return (new JLabel(
                            "Failed to fetch required details to add this "
                                    + "REST service into the Service Panel.",
                            ResourceManager.getImageIcon(ResourceManager.ERROR_ICON), JLabel.CENTER));
                }

                // type not currently supported, but maybe in the future?
            default:
                return (new JLabel(
                        "Adding " + resourceType.getCollectionName() + " to the Service Panel is not yet possible",
                        ResourceManager.getImageIcon(ResourceManager.ERROR_ICON), JLabel.CENTER));
            }
        }

        // definitely not supported type
        return (new JLabel(
                "<html>It is not possible to add resources of the provided type<br>"
                        + "into the Service Panel.</html>",
                ResourceManager.getImageIcon(ResourceManager.ERROR_ICON), JLabel.CENTER));
    }

    /**
     * Inserts all operations of the given parent SOAP or REST Web service resource link
     * into Service Panel. Works for SOAP operations only at the moment.
     * 
     * @return Outcome of inserting operations into Service Panel as a
     *         HTML-formatted string (with no opening and closing HTML tags).
     */
    public static JComponent insertAllOperationsIntoServicePanel(ResourceLink serviceResource) {
        // Check if this type of resource is a parent SOAP Web service
        // whose operations can be added to the Service Panel
        TYPE resourceType = Resource.getResourceTypeFromResourceURL(serviceResource.getHref());

        Service service = null;
        if (resourceType == TYPE.SOAPOperation) {
            SoapService soapService = ((SoapOperation) serviceResource).getAncestors().getSoapService();

            // Get the WSDL URL of the SOAP service
            String wsdlURL = soapService.getWsdlLocation();

            // Import this WSDL into Service panel - it will add all
            // of
            // its operations
            if (BioCatalogueWSDLOperationServiceProvider.registerWSDLService(wsdlURL, null)) {
                return (new JLabel(
                        "Operation(s) of the SOAP service have been successfully added to the Service Panel.",
                        ResourceManager.getImageIcon(ResourceManager.TICK_ICON), JLabel.CENTER));
            } else {
                return (new JLabel(
                        "Failed to insert the operations of the SOAP service " + " to the Service Panel.",
                        ResourceManager.getImageIcon(ResourceManager.ERROR_ICON), JLabel.CENTER));
            }
        } else if (resourceType == TYPE.RESTMethod) {
            RestService restService = ((RestMethod) serviceResource).getAncestors().getRestService();
            for (RestMethod method : restService.getMethods().getRestMethodList()) {

            }
        }

        return (new JLabel(
                "<html>It is not possible to add resources of the provided type<br>"
                        + "into the Service Panel.</html>",
                ResourceManager.getImageIcon(ResourceManager.ERROR_ICON), JLabel.CENTER));
    }

    /**
     * Instantiates a {@link RESTFromBioCatalogueServiceDescription} object from the {@link RestMethod}
     * XML data obtained from BioCatalogue API.
     * 
     * @param restMethod
     * @return
     */
    public static RESTFromBioCatalogueServiceDescription createRESTServiceDescriptionFromRESTMethod(
            RestMethod restMethod) throws UnsupportedHTTPMethodException {
        // if the type of the HTTP method is not supported, an exception will be throws
        HTTP_METHOD httpMethod = HTTPMethodInterpreter.getHTTPMethodForRESTActivity(restMethod.getHttpMethodType());

        RESTFromBioCatalogueServiceDescription restServiceDescription = new RESTFromBioCatalogueServiceDescription();
        restServiceDescription.setServiceName(Resource.getDisplayNameForResource(restMethod));
        restServiceDescription.setDescription(StringEscapeUtils.escapeHtml(restMethod.getDescription()));
        restServiceDescription.setHttpMethod(httpMethod);
        restServiceDescription.setURLSignature(restMethod.getUrlTemplate());

        int outputRepresentationCount = restMethod.getOutputs().getRepresentations().getRestRepresentationList()
                .size();
        if (outputRepresentationCount > 0) {
            if (outputRepresentationCount > 1) {
                restServiceDescription.getDataWarnings()
                        .add(RESTFromBioCatalogueServiceDescription.AMBIGUOUS_ACCEPT_HEADER_VALUE);
            }
            restServiceDescription.setAcceptHeaderValue(restMethod.getOutputs().getRepresentations()
                    .getRestRepresentationList().get(0).getContentType());
        } else {
            restServiceDescription.getDataWarnings()
                    .add(RESTFromBioCatalogueServiceDescription.DEFAULT_ACCEPT_HEADER_VALUE);
        }

        int inputRepresentationCount = restMethod.getInputs().getRepresentations().getRestRepresentationList()
                .size();
        if (inputRepresentationCount > 0) {
            if (inputRepresentationCount > 1) {
                restServiceDescription.getDataWarnings()
                        .add(RESTFromBioCatalogueServiceDescription.AMBIGUOUS_CONTENT_TYPE_HEADER_VALUE);
            }
            restServiceDescription.setOutgoingContentType(restMethod.getInputs().getRepresentations()
                    .getRestRepresentationList().get(0).getContentType());
        } else if (RESTActivity.hasMessageBodyInputPort(httpMethod)) {
            restServiceDescription.getDataWarnings()
                    .add(RESTFromBioCatalogueServiceDescription.DEFAULT_CONTENT_TYPE_HEADER_VALUE);
        }

        return (restServiceDescription);
    }

    /**
     * @param restServiceDescription {@link RESTFromBioCatalogueServiceDescription} to process.
     * @param addingToServicePanel <code>true</code> indicates that the warning messages
     *                             will assume that the processor is added to the service panel;
     *                             <code>false</code> would mean that the processor is added to
     *                             the current workflow.
     * @return An HTML-formatted string (with no opening-closing HTML tags) that lists
     *         any warnings that have been recorded during the {@link RESTFromBioCatalogueServiceDescription}
     *         object creation. Empty string will be returned if there are no warnings.
     */
    public static String extractWarningsFromRESTServiceDescription(
            RESTFromBioCatalogueServiceDescription restServiceDescription, boolean addingToServicePanel) {
        String messageSuffix = addingToServicePanel ? " once you add it into the workflow" : "";

        String warnings = "";
        if (restServiceDescription.getDataWarnings()
                .contains(RESTFromBioCatalogueServiceDescription.AMBIGUOUS_ACCEPT_HEADER_VALUE)) {
            warnings += "<br><br>Service Catalogue description of this REST method contains more than one<br>"
                    + "representation of the method's outputs - the first one was used.<br>"
                    + "Please check value of the 'Accept' header in the configuration<br>"
                    + "of the imported service" + messageSuffix + ".";
        } else if (restServiceDescription.getDataWarnings()
                .contains(RESTFromBioCatalogueServiceDescription.DEFAULT_ACCEPT_HEADER_VALUE)) {
            warnings += "<br><br>Service Catalogue description of this REST method does not contain any<br>"
                    + "representations of the method's outputs - default value was used.<br>"
                    + "Please check value of the 'Accept' header in the configuration<br>"
                    + "of the imported service" + messageSuffix + ".";
        }

        if (restServiceDescription.getDataWarnings()
                .contains(RESTFromBioCatalogueServiceDescription.AMBIGUOUS_CONTENT_TYPE_HEADER_VALUE)) {
            warnings += "<br><br>Service Catalogue description of this REST method contains more than one<br>"
                    + "representation of the method's input data - the first one was used.<br>"
                    + "Please check value of the 'Content-Type' header in the configuration<br>"
                    + "of the imported service" + messageSuffix + ".";
        } else if (restServiceDescription.getDataWarnings()
                .contains(RESTFromBioCatalogueServiceDescription.DEFAULT_CONTENT_TYPE_HEADER_VALUE)) {
            warnings += "<br><br>Service Catalogue description of this REST method does not contain any<br>"
                    + "representations of the method's input data - default value was used.<br>"
                    + "Please check value of the 'Content-Type' header in the configuration<br>"
                    + "of the imported service" + messageSuffix + ".";
        }

        if (warnings.length() > 0) {
            warnings = "<br><br>WARNINGS:" + warnings;
        }

        return (warnings);
    }

    /**
     * @param activityPort Probably comes from contextual selection - must be either
     *         ActivityInputPort or ActivityOutputPort.
     * @return SOAP input / output port details (WSDL location, operation name, port name) from
     *         ActivityInputPort/ActivityOutputPort which is obtained from contextual selection in the Dataflow.
     */
    public static <T extends Port> SoapOperationPortIdentity extractSoapOperationPortDetailsFromActivityInputOutputPort(
            T activityPort) {
        // check that we have the correct instance of Port here - either ActivityInputPort or ActivityOutputPort
        boolean hasInputPort;
        if (activityPort instanceof ActivityInputPort) {
            hasInputPort = true;
        } else if (activityPort instanceof ActivityOutputPort) {
            hasInputPort = false;
        } else {
            // ERROR - wrong type supplied
            return new SoapOperationPortIdentity(
                    "Activity port from the contextual selection was not of correct type. Impossible to create preview.");
        }

        // get parent processor details
        Dataflow currentDataflow = FileManager.getInstance().getCurrentDataflow();
        Collection<Processor> processors = null;
        if (hasInputPort) {
            processors = Tools.getProcessorsWithActivityInputPort(currentDataflow,
                    (ActivityInputPort) activityPort);
        } else {
            processors = Tools.getProcessorsWithActivityOutputPort(currentDataflow,
                    (ActivityOutputPort) activityPort);
        }

        // TODO - doesn't take into account that it's possible to have several
        SoapOperationIdentity soapOperationDetails = extractSoapOperationDetailsFromProcessor(
                processors.toArray(new Processor[] {})[0]);

        // if no error happened, add port details and return
        if (!soapOperationDetails.hasError()) {
            return (new SoapOperationPortIdentity(soapOperationDetails.getWsdlLocation(),
                    soapOperationDetails.getOperationName(), activityPort.getName(), hasInputPort));
        } else {
            // error...
            return (new SoapOperationPortIdentity(soapOperationDetails.getErrorDetails()));
        }
    }

    /**
     * Uses contextual selection to extract WSDL location and operation name of the
     * currently selected processor within the Design view of current workflow. 
     * 
     * @param contextualSelection Selection that was made in the Design view.
     * @return Details of the SOAP operation that acts as a processor wrapped into
     *         this single instance. If any problems occurred while performing
     *         contextual selection analysis, these are also recorded into the same
     *         instance - before using the returned value the caller must check
     *         <code>SoapOperationIdentity.hasError()</code> value.
     */
    public static SoapOperationIdentity extractSoapOperationDetailsFromProcessorContextualSelection(
            ContextualSelection contextualSelection) {
        if (!(contextualSelection.getSelection() instanceof Processor)) {
            return (new SoapOperationIdentity(
                    "ERROR: It is only possible to extract " + "SOAP operation details from the service."));
        }

        // now we know it's a Processor
        Processor processor = (Processor) contextualSelection.getSelection();
        return (extractSoapOperationDetailsFromProcessor(processor));
    }

    /**
     * Worker method for <code>extractSoapOperationDetailsFromProcessorContextualSelection()</code>.
     * 
     * @param processor
     * @return
     */
    public static SoapOperationIdentity extractSoapOperationDetailsFromProcessor(Processor processor) {
        List<? extends Activity> activityList = (List<? extends Activity>) processor.getActivityList();

        if (activityList == null || activityList.size() == 0) {
            return (new SoapOperationIdentity("ERROR: Selected processor doesn't have any activities - "
                    + "impossible to extract SOAP operation details."));
        } else {
            // take only the first activity - TODO: figure out what should be done here...
            Activity activity = activityList.get(0);
            if (activity instanceof WSDLActivity) {
                WSDLActivity a = (WSDLActivity) activity;
                return (new SoapOperationIdentity(a.getConfiguration().getWsdl(),
                        a.getConfiguration().getOperation(), null));
            } else {
                return (new SoapOperationIdentity(
                        "Service Catalogue integration only works with WSDL Activities at the moment"));
            }
        }
    }

    /**
     * @param contextualSelection
     * @return A list of all WSDL activities (the only supported processors by BioCatalogue plugin for now).
     */
    public static List<SoapProcessorIdentity> extractSupportedProcessorsFromDataflow(
            ContextualSelection contextualSelection) {
        // check that there was a correct contextual selection
        if (!(contextualSelection.getSelection() instanceof Dataflow)) {
            logger.error("It is only possible to extract supported services from the workflow.");
            return (new ArrayList<SoapProcessorIdentity>());
        }

        // first extract all processors
        Dataflow dataflow = (Dataflow) contextualSelection.getSelection();
        List<? extends Processor> allProcessors = dataflow.getEntities(Processor.class);

        // now filter out any processors that are not WSDL activities
        List<SoapProcessorIdentity> supportedProcessors = new ArrayList<SoapProcessorIdentity>();
        for (Processor proc : allProcessors) {
            List<? extends Activity> activityList = (List<? extends Activity>) proc.getActivityList();
            if (activityList != null && activityList.size() > 0) {
                // take only the first activity - TODO: figure out what should be done here...
                Activity activity = activityList.get(0);
                if (activity instanceof WSDLActivity) {
                    WSDLActivity a = (WSDLActivity) activity;
                    supportedProcessors.add(new SoapProcessorIdentity(a.getConfiguration().getWsdl(),
                            a.getConfiguration().getOperation(), proc.getLocalName()));
                }
            }
        }

        // return all found processors
        return (supportedProcessors);
    }

}