You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2015/03/20 15:22:27 UTC
[13/51] [abbrv] [partial] incubator-taverna-workbench git commit:
taverna-workbench-* -> taverna-*
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/Integration.java
----------------------------------------------------------------------
diff --git a/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/Integration.java b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/Integration.java
new file mode 100644
index 0000000..ec792d4
--- /dev/null
+++ b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/Integration.java
@@ -0,0 +1,518 @@
+package net.sf.taverna.t2.ui.perspectives.biocatalogue.integration;
+
+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 net.sf.taverna.biocatalogue.model.HTTPMethodInterpreter;
+import net.sf.taverna.biocatalogue.model.HTTPMethodInterpreter.UnsupportedHTTPMethodException;
+import net.sf.taverna.biocatalogue.model.Resource;
+import net.sf.taverna.biocatalogue.model.Resource.TYPE;
+import net.sf.taverna.biocatalogue.model.connectivity.BioCatalogueClient;
+import net.sf.taverna.biocatalogue.model.ResourceManager;
+import net.sf.taverna.biocatalogue.model.SoapOperationIdentity;
+import net.sf.taverna.biocatalogue.model.SoapOperationPortIdentity;
+import net.sf.taverna.biocatalogue.model.SoapProcessorIdentity;
+import net.sf.taverna.biocatalogue.model.Util;
+import net.sf.taverna.t2.activities.rest.RESTActivity;
+import net.sf.taverna.t2.activities.rest.RESTActivity.HTTP_METHOD;
+import net.sf.taverna.t2.activities.wsdl.WSDLActivity;
+import net.sf.taverna.t2.activities.wsdl.servicedescriptions.WSDLServiceDescription;
+import net.sf.taverna.t2.ui.menu.ContextualSelection;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.MainComponentFactory;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.service_panel.BioCatalogueRESTServiceProvider;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.service_panel.BioCatalogueWSDLOperationServiceProvider;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.service_panel.RESTFromBioCatalogueServiceDescription;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.service_panel.WSDLOperationFromBioCatalogueServiceDescription;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.ui.workflowview.WorkflowView;
+import net.sf.taverna.t2.workflowmodel.Dataflow;
+import net.sf.taverna.t2.workflowmodel.Port;
+import net.sf.taverna.t2.workflowmodel.Processor;
+import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityInputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityOutputPort;
+import net.sf.taverna.t2.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);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/config/BioCataloguePluginConfiguration.java
----------------------------------------------------------------------
diff --git a/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/config/BioCataloguePluginConfiguration.java b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/config/BioCataloguePluginConfiguration.java
new file mode 100644
index 0000000..3985ac5
--- /dev/null
+++ b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/config/BioCataloguePluginConfiguration.java
@@ -0,0 +1,68 @@
+package net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.config;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import uk.org.taverna.configuration.AbstractConfigurable;
+
+import net.sf.taverna.biocatalogue.model.connectivity.BioCatalogueClient;
+
+/**
+ *
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class BioCataloguePluginConfiguration extends AbstractConfigurable
+{
+ public static final String SERVICE_CATALOGUE_BASE_URL = "ServiceCatalogue_Base_URL";
+ public static final String SOAP_OPERATIONS_IN_SERVICE_PANEL = "SOAP_Operations_in_Service_Panel";
+ public static final String REST_METHODS_IN_SERVICE_PANEL = "REST_Methods_in_Service_Panel";
+
+
+ private static class Singleton {
+ private static BioCataloguePluginConfiguration instance = new BioCataloguePluginConfiguration();
+ }
+
+ // private static Logger logger = Logger.getLogger(MyExperimentConfiguration.class);
+
+ private Map<String, String> defaultPropertyMap;
+
+
+ public static BioCataloguePluginConfiguration getInstance() {
+ return Singleton.instance;
+ }
+
+ public String getCategory() {
+ return "general";
+ }
+
+ public Map<String,String> getDefaultPropertyMap() {
+ if (defaultPropertyMap == null) {
+ defaultPropertyMap = new HashMap<String,String>();
+ defaultPropertyMap.put(SERVICE_CATALOGUE_BASE_URL, BioCatalogueClient.DEFAULT_API_LIVE_SERVER_BASE_URL);
+ }
+ return defaultPropertyMap;
+ }
+
+ public String getDisplayName() {
+ return "Service catalogue";
+ }
+
+ public String getFilePrefix() {
+ return "ServiceCatalogue";
+ }
+
+ public String getUUID() {
+ return "4daac25c-bd56-4f90-b909-1e49babe5197";
+ }
+
+
+ /**
+ * Just a "proxy" method - {@link AbstractConfigurable#store()}
+ * is not visible to the users of instances of this class otherwise.
+ */
+ public void store() {
+ super.store();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/config/BioCataloguePluginConfigurationPanel.java
----------------------------------------------------------------------
diff --git a/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/config/BioCataloguePluginConfigurationPanel.java b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/config/BioCataloguePluginConfigurationPanel.java
new file mode 100644
index 0000000..a83a223
--- /dev/null
+++ b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/config/BioCataloguePluginConfigurationPanel.java
@@ -0,0 +1,448 @@
+package net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.config;
+
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.ProxySelector;
+import java.net.URL;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+//import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.ProxySelectorRoutePlanner;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
+import org.apache.log4j.Logger;
+import org.jdom.Attribute;
+import org.jdom.Document;
+import org.jdom.input.SAXBuilder;
+
+import net.sf.taverna.biocatalogue.model.connectivity.BioCatalogueClient;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.MainComponentFactory;
+
+
+/**
+ *
+ * @author Sergejs Aleksejevs
+ */
+@SuppressWarnings("serial")
+public class BioCataloguePluginConfigurationPanel extends JPanel
+{
+ public static final String APPLICATION_XML_MIME_TYPE = "application/xml";
+
+ public static String PROXY_HOST = "http.proxyHost";
+ public static String PROXY_PORT = "http.proxyPort";
+ public static String PROXY_USERNAME = "http.proxyUser";
+ public static String PROXY_PASSWORD = "http.proxyPassword";
+
+ // 1.0.0b and higher until the first digit changes, as according to "Semantic Versioning"
+ // from http://www.biocatalogue.org/wiki/doku.php?id=public:api:changelog
+ // "Major version X (X.y.z | X > 0) MUST be incremented if any backwards
+ // incompatible changes are introduced to the public API. It MAY include minor and patch level changes."
+ public static String[] MIN_SUPPORTED_BIOCATALOGUE_API_VERSION = {"1", "1", "0"}; // major, minor and patch versions
+ public static String API_VERSION = "apiVersion";
+
+ private BioCataloguePluginConfiguration configuration =
+ BioCataloguePluginConfiguration.getInstance();
+
+
+ // UI elements
+ JTextField tfBioCatalogueAPIBaseURL;
+
+ private Logger logger = Logger.getLogger(BioCataloguePluginConfigurationPanel.class);
+
+ public BioCataloguePluginConfigurationPanel() {
+ initialiseUI();
+ resetFields();
+ }
+
+ private void initialiseUI()
+ {
+ this.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.anchor = GridBagConstraints.NORTHWEST;
+ c.weightx = 1.0;
+
+ c.gridx = 0;
+ c.gridy = 0;
+ JTextArea taDescription = new JTextArea("Configure the Service Catalogue integration functionality");
+ taDescription.setFont(taDescription.getFont().deriveFont(Font.PLAIN, 11));
+ taDescription.setLineWrap(true);
+ taDescription.setWrapStyleWord(true);
+ taDescription.setEditable(false);
+ taDescription.setFocusable(false);
+ taDescription.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ this.add(taDescription, c);
+
+
+ c.gridy++;
+ c.insets = new Insets(20, 0, 0, 0);
+ JLabel jlBioCatalogueAPIBaseURL = new JLabel("Base URL of the Service Catalogue instance to connect to:");
+ this.add(jlBioCatalogueAPIBaseURL, c);
+
+ c.gridy++;
+ c.insets = new Insets(0, 0, 0, 0);
+ tfBioCatalogueAPIBaseURL = new JTextField();
+ this.add(tfBioCatalogueAPIBaseURL, c);
+
+
+ c.gridy++;
+ c.insets = new Insets(30, 0, 0, 0);
+ // We are not removing BioCatalogue services from its config panel any more -
+ // they are being handled by the Taverna's Service Registry
+// JButton bForgetStoredServices = new JButton("Forget services added to Service Panel by BioCatalogue Plugin");
+// bForgetStoredServices.addActionListener(new ActionListener() {
+// public void actionPerformed(ActionEvent e)
+// {
+// int response = JOptionPane.showConfirmDialog(null, // no way T2ConfigurationFrame instance can be obtained to be used as a parent...
+// "Are you sure you want to clear all SOAP operations and REST methods\n" +
+// "that were added to the Service Panel by the BioCatalogue Plugin?\n\n" +
+// "This action is permanent is cannot be undone.\n\n" +
+// "Do you want to proceed?", "BioCatalogue Plugin", JOptionPane.YES_NO_OPTION);
+//
+// if (response == JOptionPane.YES_OPTION)
+// {
+// BioCatalogueServiceProvider.clearRegisteredServices();
+// JOptionPane.showMessageDialog(null, // no way T2ConfigurationFrame instance can be obtained to be used as a parent...
+// "Stored services have been successfully cleared, but will remain\n" +
+// "being shown in Service Panel during this session.\n\n" +
+// "They will not appear in the Service Panel after you restart Taverna.",
+// "BioCatalogue Plugin", JOptionPane.INFORMATION_MESSAGE);
+// }
+// }
+// });
+// this.add(bForgetStoredServices, c);
+
+
+ JButton bLoadDefaults = new JButton("Load Defaults");
+ bLoadDefaults.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ loadDefaults();
+ }
+ });
+
+ JButton bReset = new JButton("Reset");
+ bReset.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ resetFields();
+ }
+ });
+
+ JButton bApply = new JButton("Apply");
+ bApply.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ applyChanges();
+ }
+ });
+
+ JPanel jpActionButtons = new JPanel();
+ jpActionButtons.add(bLoadDefaults);
+ jpActionButtons.add(bReset);
+ jpActionButtons.add(bApply);
+ c.insets = new Insets(30, 0, 0, 0);
+ c.gridy++;
+ c.weighty = 1.0;
+ this.add(jpActionButtons, c);
+ }
+
+
+ /**
+ * Resets all fields to the last saved configuration.
+ */
+ private void resetFields() {
+ tfBioCatalogueAPIBaseURL.setText(configuration.getProperty(BioCataloguePluginConfiguration.SERVICE_CATALOGUE_BASE_URL));
+ }
+
+ /**
+ * Resets all fields to the default values.
+ */
+ private void loadDefaults() {
+ tfBioCatalogueAPIBaseURL.setText(configuration.getDefaultProperty(BioCataloguePluginConfiguration.SERVICE_CATALOGUE_BASE_URL));
+ }
+
+ /**
+ * Saves recent changes to the configuration parameter map.
+ * Some input validation is performed as well.
+ */
+ private void applyChanges() {
+ // --- BioCatalogue BASE URL ---
+
+ String candidateBaseURL = tfBioCatalogueAPIBaseURL.getText();
+ if (candidateBaseURL.length() == 0) {
+ JOptionPane.showMessageDialog(this,
+ "Service Catalogue base URL must not be blank",
+ "Service Catalogue Configuration", JOptionPane.WARNING_MESSAGE);
+ tfBioCatalogueAPIBaseURL.requestFocusInWindow();
+ return;
+ } else {
+ try {
+ new URL(candidateBaseURL);
+ } catch (MalformedURLException e) {
+ JOptionPane
+ .showMessageDialog(
+ this,
+ "Currently set Service Catalogue instance URL is not valid\n." +
+ "Please check the URL and try again.",
+ "Service Catalogue Configuration",
+ JOptionPane.WARNING_MESSAGE);
+ tfBioCatalogueAPIBaseURL.selectAll();
+ tfBioCatalogueAPIBaseURL.requestFocusInWindow();
+ return;
+ }
+
+ // check if the base URL has changed from the last saved state
+ if (!candidateBaseURL
+ .equals(configuration
+ .getProperty(BioCataloguePluginConfiguration.SERVICE_CATALOGUE_BASE_URL))) {
+ // Perform various checks on the new URL
+
+ // Do a GET with "Accept" header set to "application/xml"
+ // We are expecting a 200 OK and an XML doc in return that
+ // contains the BioCataogue version number element.
+ DefaultHttpClient httpClient = new DefaultHttpClient();
+
+ // Set the proxy settings, if any
+ if (System.getProperty(PROXY_HOST) != null
+ && !System.getProperty(PROXY_HOST).equals("")) {
+ // Instruct HttpClient to use the standard
+ // JRE proxy selector to obtain proxy information
+ ProxySelectorRoutePlanner routePlanner = new ProxySelectorRoutePlanner(
+ httpClient.getConnectionManager().getSchemeRegistry(), ProxySelector
+ .getDefault());
+ httpClient.setRoutePlanner(routePlanner);
+ // Do we need to authenticate the user to the proxy?
+ if (System.getProperty(PROXY_USERNAME) != null
+ && !System.getProperty(PROXY_USERNAME).equals("")) {
+ // Add the proxy username and password to the list of credentials
+ httpClient.getCredentialsProvider().setCredentials(
+ new AuthScope(System.getProperty(PROXY_HOST),Integer.parseInt(System.getProperty(PROXY_PORT))),
+ new UsernamePasswordCredentials(System.getProperty(PROXY_USERNAME), System.getProperty(PROXY_PASSWORD)));
+ }
+ }
+
+ HttpGet httpGet = new HttpGet(candidateBaseURL);
+ httpGet.setHeader("Accept", APPLICATION_XML_MIME_TYPE);
+
+ // Execute the request
+ HttpContext localContext = new BasicHttpContext();
+ HttpResponse httpResponse;
+ try {
+ httpResponse = httpClient.execute(httpGet, localContext);
+ } catch (Exception ex1) {
+ logger.error("Service Catalogue preferences configuration: Failed to do "
+ + httpGet.getRequestLine(), ex1);
+ // Warn the user
+ JOptionPane.showMessageDialog(this,
+ "Failed to connect to the URL of the Service Catalogue instance.\n"
+ + "Please check the URL and try again.",
+ "Service Catalogue Configuration",
+ JOptionPane.INFORMATION_MESSAGE);
+
+ // Release resource
+ httpClient.getConnectionManager().shutdown();
+
+ tfBioCatalogueAPIBaseURL.requestFocusInWindow();
+ return;
+ }
+
+ if (httpResponse.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK) { // HTTP/1.1 200 OK
+ HttpEntity httpEntity = httpResponse.getEntity();
+ String contentType = httpEntity.getContentType().getValue()
+ .toLowerCase().trim();
+ logger
+ .info("Service Catalogue preferences configuration: Got 200 OK when testing the Service Catalogue instance by doing "
+ + httpResponse.getStatusLine()
+ + ". Content type of response "
+ + contentType);
+ if (contentType.startsWith(APPLICATION_XML_MIME_TYPE)) {
+ String value = null;
+ Document doc = null;
+ try {
+ value = readResponseBodyAsString(httpEntity)
+ .trim();
+ // Try to read this string into an XML document
+ SAXBuilder builder = new SAXBuilder();
+ byte[] bytes = value.getBytes("UTF-8");
+ doc = builder.build(new ByteArrayInputStream(bytes));
+ } catch (Exception ex2) {
+ logger.error("Service Catalogue preferences configuration: Failed to build an XML document from the response.", ex2);
+ // Warn the user
+ JOptionPane.showMessageDialog(this,
+ "Failed to get the expected response body when testing the Service Catalogue instance.\n"
+ + "The URL is probably wrong. Please check it and try again.",
+ "Service Catalogue Configuration",
+ JOptionPane.INFORMATION_MESSAGE);
+ tfBioCatalogueAPIBaseURL.requestFocusInWindow();
+ return;
+ }
+ finally{
+ // Release resource
+ httpClient.getConnectionManager().shutdown();
+ }
+ // Get the version element from the XML document
+ Attribute apiVersionAttribute = doc.getRootElement().getAttribute(API_VERSION);
+ if (apiVersionAttribute != null){
+ String apiVersion = apiVersionAttribute.getValue();
+ String versions[] = apiVersion.split("[.]");
+ String majorVersion = versions[0];
+ String minorVersion = versions[1];
+ try {
+ //String patchVersion = versions[2]; // we are not comparing the patch versions
+ String supportedMajorVersion = MIN_SUPPORTED_BIOCATALOGUE_API_VERSION[0];
+ String supportedMinorVersion = MIN_SUPPORTED_BIOCATALOGUE_API_VERSION[1];
+ Integer iSupportedMajorVersion = Integer.parseInt(supportedMajorVersion);
+ Integer iMajorVersion = Integer.parseInt(majorVersion);
+ Integer iSupportedMinorVersion = Integer.parseInt(supportedMinorVersion);
+ Integer iMinorVersion = Integer.parseInt(minorVersion);
+ if (!(iSupportedMajorVersion == iMajorVersion &&
+ iSupportedMinorVersion <= iMinorVersion)){
+ // Warn the user
+ JOptionPane
+ .showMessageDialog(
+ this,
+ "The version of the Service Catalogue instance you are trying to connect to is not supported.\n"
+ + "Please change the URL and try again.",
+ "Service Catalogue Configuration",
+ JOptionPane.INFORMATION_MESSAGE);
+ tfBioCatalogueAPIBaseURL.requestFocusInWindow();
+ return;
+ }
+ } catch (Exception e) {
+ logger.error(e);
+ }
+ } // if null - we'll try to do our best to connect to BioCatalogue anyway
+ } else {
+ logger
+ .error("Service Catalogue preferences configuration: Failed to get the expected response content type when testing the Service Catalogue instance. "
+ + httpGet.getRequestLine()
+ + " returned content type '"
+ + contentType
+ + "'; expected response content type is 'application/xml'.");
+ // Warn the user
+ JOptionPane
+ .showMessageDialog(
+ this,
+ "Failed to get the expected response content type when testing the Service Catalogue instance.\n"
+ + "The URL is probably wrong. Please check it and try again.",
+ "Service Catalogue Plugin",
+ JOptionPane.INFORMATION_MESSAGE);
+ tfBioCatalogueAPIBaseURL.requestFocusInWindow();
+ return;
+ }
+ }
+ else{
+ logger
+ .error("Service Catalogue preferences configuration: Failed to get the expected response status code when testing the Service Catalogue instance. "
+ + httpGet.getRequestLine()
+ + " returned the status code "
+ + httpResponse.getStatusLine()
+ .getStatusCode() + "; expected status code is 200 OK.");
+ // Warn the user
+ JOptionPane
+ .showMessageDialog(
+ this,
+ "Failed to get the expected response status code when testing the Service Catalogue instance.\n"
+ + "The URL is probably wrong. Please check it and try again.",
+ "Service Catalogue Configuration",
+ JOptionPane.INFORMATION_MESSAGE);
+ tfBioCatalogueAPIBaseURL.requestFocusInWindow();
+ return;
+ }
+
+ // Warn the user of the changes in the BioCatalogue base URL
+ JOptionPane
+ .showMessageDialog(
+ this,
+ "You have updated the Service Catalogue base URL.\n"
+ + "This does not take effect until you restart Taverna.",
+ "Service catalogue Configuration",
+ JOptionPane.INFORMATION_MESSAGE);
+
+ }
+
+ // the new base URL seems to be valid - can save it into config
+ // settings
+ configuration.setProperty(
+ BioCataloguePluginConfiguration.SERVICE_CATALOGUE_BASE_URL,
+ candidateBaseURL);
+
+/* // also update the base URL in the BioCatalogueClient
+ BioCatalogueClient.getInstance()
+ .setBaseURL(candidateBaseURL);*/
+ }
+
+ }
+
+
+ /**
+ * For testing only.
+ */
+ public static void main(String[] args) {
+ JFrame theFrame = new JFrame();
+ theFrame.add(new BioCataloguePluginConfigurationPanel());
+ theFrame.pack();
+ theFrame.setLocationRelativeTo(null);
+ theFrame.setVisible(true);
+ }
+
+ /**
+ * Worker method that extracts the content of the received HTTP message as a
+ * string. It also makes use of the charset that is specified in the
+ * Content-Type header of the received data to read it appropriately.
+ *
+ * @param entity
+ * @return
+ * @throws IOException
+ */
+ // Taken from HTTPRequestHandler in rest-activity by Sergejs Aleksejevs
+ private static String readResponseBodyAsString(HttpEntity entity)
+ throws IOException {
+ // get charset name
+ String charset = null;
+ String contentType = entity.getContentType().getValue().toLowerCase();
+
+ String[] contentTypeParts = contentType.split(";");
+ for (String contentTypePart : contentTypeParts) {
+ contentTypePart = contentTypePart.trim();
+ if (contentTypePart.startsWith("charset=")) {
+ charset = contentTypePart.substring("charset=".length());
+ }
+ }
+
+ // read the data line by line
+ StringBuilder responseBodyString = new StringBuilder();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(entity
+ .getContent(), charset));
+
+ String str;
+ while ((str = reader.readLine()) != null) {
+ responseBodyString.append(str + "\n");
+ }
+
+ return (responseBodyString.toString());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/config/BioCataloguePluginConfigurationUIFactory.java
----------------------------------------------------------------------
diff --git a/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/config/BioCataloguePluginConfigurationUIFactory.java b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/config/BioCataloguePluginConfigurationUIFactory.java
new file mode 100644
index 0000000..f5baa70
--- /dev/null
+++ b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/config/BioCataloguePluginConfigurationUIFactory.java
@@ -0,0 +1,27 @@
+package net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.config;
+
+import javax.swing.JPanel;
+
+import uk.org.taverna.configuration.Configurable;
+import uk.org.taverna.configuration.ConfigurationUIFactory;
+
+/**
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class BioCataloguePluginConfigurationUIFactory implements ConfigurationUIFactory
+{
+
+ public boolean canHandle(String uuid) {
+ return uuid.equals(getConfigurable().getUUID());
+ }
+
+ public Configurable getConfigurable() {
+ return BioCataloguePluginConfiguration.getInstance();
+ }
+
+ public JPanel getConfigurationPanel() {
+ return new BioCataloguePluginConfigurationPanel();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/BioCataloguePluginInputPortContextViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/BioCataloguePluginInputPortContextViewFactory.java b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/BioCataloguePluginInputPortContextViewFactory.java
new file mode 100644
index 0000000..d067cce
--- /dev/null
+++ b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/BioCataloguePluginInputPortContextViewFactory.java
@@ -0,0 +1,45 @@
+package net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.contextual_views;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import net.sf.taverna.biocatalogue.model.SoapOperationPortIdentity;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.Integration;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityInputPort;
+
+
+public class BioCataloguePluginInputPortContextViewFactory implements
+ ContextualViewFactory<ActivityInputPort> {
+
+ public boolean canHandle(Object selection)
+ {
+ // TODO - HACK: this would stop showing the contextual view in case of any error,
+ // not just in case of unsupported contextual selection; this needs to be
+ // changed, so that useful error messages are still displayed in the
+ // contextual view
+ if (selection instanceof ActivityInputPort)
+ {
+ SoapOperationPortIdentity portDetails = Integration.
+ extractSoapOperationPortDetailsFromActivityInputOutputPort((ActivityInputPort)selection);
+ boolean canHandleSelection = !portDetails.hasError();
+ if (!canHandleSelection) {
+ Logger.getLogger(BioCataloguePluginProcessorContextViewFactory.class).debug(
+ "Input port contextual view not shown due to some condition: " + portDetails.getErrorDetails());
+ }
+
+ return (canHandleSelection);
+ }
+ else {
+ return (false);
+ }
+ }
+
+ public List<ContextualView> getViews(ActivityInputPort selection) {
+ return Arrays.<ContextualView>asList(new ProcessorInputPortView(selection));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/BioCataloguePluginOutputPortContextViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/BioCataloguePluginOutputPortContextViewFactory.java b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/BioCataloguePluginOutputPortContextViewFactory.java
new file mode 100644
index 0000000..1014a54
--- /dev/null
+++ b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/BioCataloguePluginOutputPortContextViewFactory.java
@@ -0,0 +1,45 @@
+package net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.contextual_views;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import net.sf.taverna.biocatalogue.model.SoapOperationPortIdentity;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.Integration;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityOutputPort;
+
+
+public class BioCataloguePluginOutputPortContextViewFactory implements
+ ContextualViewFactory<ActivityOutputPort> {
+
+ public boolean canHandle(Object selection)
+ {
+ // TODO - HACK: this would stop showing the contextual view in case of any error,
+ // not just in case of unsupported contextual selection; this needs to be
+ // changed, so that useful error messages are still displayed in the
+ // contextual view
+ if (selection instanceof ActivityOutputPort)
+ {
+ SoapOperationPortIdentity portDetails = Integration.
+ extractSoapOperationPortDetailsFromActivityInputOutputPort((ActivityOutputPort)selection);
+ boolean canHandleSelection = !portDetails.hasError();
+ if (!canHandleSelection) {
+ Logger.getLogger(BioCataloguePluginProcessorContextViewFactory.class).debug(
+ "Output port contextual view not shown due to some condition: " + portDetails.getErrorDetails());
+ }
+
+ return (canHandleSelection);
+ }
+ else {
+ return (false);
+ }
+ }
+
+ public List<ContextualView> getViews(ActivityOutputPort selection) {
+ return Arrays.<ContextualView>asList(new ProcessorOutputPortView(selection));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/BioCataloguePluginProcessorContextViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/BioCataloguePluginProcessorContextViewFactory.java b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/BioCataloguePluginProcessorContextViewFactory.java
new file mode 100644
index 0000000..05380d3
--- /dev/null
+++ b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/BioCataloguePluginProcessorContextViewFactory.java
@@ -0,0 +1,43 @@
+package net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.contextual_views;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import net.sf.taverna.biocatalogue.model.SoapOperationIdentity;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.Integration;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
+import net.sf.taverna.t2.workflowmodel.Processor;
+
+public class BioCataloguePluginProcessorContextViewFactory implements
+ ContextualViewFactory<Processor> {
+
+ public boolean canHandle(Object selection)
+ {
+ // TODO - HACK: this would stop showing the contextual view in case of any error,
+ // not just in case of unsupported contextual selection; this needs to be
+ // changed, so that useful error messages are still displayed in the
+ // contextual view
+ if (selection instanceof Processor)
+ {
+ SoapOperationIdentity opId = Integration.extractSoapOperationDetailsFromProcessor((Processor) selection);
+ boolean canHandleSelection = !opId.hasError();
+ if (!canHandleSelection) {
+ Logger.getLogger(BioCataloguePluginProcessorContextViewFactory.class).debug(
+ "Service's contextual view not shown due to some condition: " + opId.getErrorDetails());
+ }
+
+ return (canHandleSelection);
+ }
+ else {
+ return (false);
+ }
+ }
+
+ public List<ContextualView> getViews(Processor selection) {
+ return Arrays.<ContextualView>asList(new ProcessorView(selection));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/ProcessorInputPortView.java
----------------------------------------------------------------------
diff --git a/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/ProcessorInputPortView.java b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/ProcessorInputPortView.java
new file mode 100644
index 0000000..4e307f1
--- /dev/null
+++ b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/ProcessorInputPortView.java
@@ -0,0 +1,52 @@
+package net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.contextual_views;
+
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+
+import net.sf.taverna.biocatalogue.model.BioCataloguePluginConstants;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityInputPort;
+
+
+public class ProcessorInputPortView extends ContextualView
+{
+ private final ActivityInputPort inputPort;
+ private JPanel jPanel;
+
+ public ProcessorInputPortView(ActivityInputPort inputPort) {
+ this.inputPort = inputPort;
+
+ jPanel = new JPanel();
+
+ // NB! This is required to have the body of this contextual
+ // view added to the main view; otherwise, body will be
+ // blank
+ initView();
+ }
+
+ @Override
+ public JComponent getMainFrame()
+ {
+ return jPanel;
+ }
+
+ @Override
+ public String getViewTitle() {
+ return "Service Catalogue Information";
+ }
+
+ @Override
+ public void refreshView()
+ {
+ // this actually causes the parent container to validate itself,
+ // which is what is needed here
+ this.revalidate();
+ this.repaint();
+ }
+
+ @Override
+ public int getPreferredPosition() {
+ return BioCataloguePluginConstants.CONTEXTUAL_VIEW_PREFERRED_POSITION;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/ProcessorOutputPortView.java
----------------------------------------------------------------------
diff --git a/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/ProcessorOutputPortView.java b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/ProcessorOutputPortView.java
new file mode 100644
index 0000000..feff0f4
--- /dev/null
+++ b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/ProcessorOutputPortView.java
@@ -0,0 +1,52 @@
+package net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.contextual_views;
+
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+
+import net.sf.taverna.biocatalogue.model.BioCataloguePluginConstants;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityOutputPort;
+
+
+public class ProcessorOutputPortView extends ContextualView
+{
+ private final ActivityOutputPort outputPort;
+ private JPanel jPanel;
+
+ public ProcessorOutputPortView(ActivityOutputPort outputPort) {
+ this.outputPort = outputPort;
+
+ jPanel = new JPanel();
+
+ // NB! This is required to have the body of this contextual
+ // view added to the main view; otherwise, body will be
+ // blank
+ initView();
+ }
+
+ @Override
+ public JComponent getMainFrame()
+ {
+ return jPanel;
+ }
+
+ @Override
+ public String getViewTitle() {
+ return "Service Catalogue Information";
+ }
+
+ @Override
+ public void refreshView()
+ {
+ // this actually causes the parent container to validate itself,
+ // which is what is needed here
+ this.revalidate();
+ this.repaint();
+ }
+
+ @Override
+ public int getPreferredPosition() {
+ return BioCataloguePluginConstants.CONTEXTUAL_VIEW_PREFERRED_POSITION;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/ProcessorView.java
----------------------------------------------------------------------
diff --git a/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/ProcessorView.java b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/ProcessorView.java
new file mode 100644
index 0000000..ea41805
--- /dev/null
+++ b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/contextual_views/ProcessorView.java
@@ -0,0 +1,229 @@
+package net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.contextual_views;
+
+import java.awt.Component;
+import java.awt.Desktop;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.net.URI;
+import java.rmi.activation.UnknownObjectException;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+import net.sf.taverna.biocatalogue.model.BioCataloguePluginConstants;
+import net.sf.taverna.biocatalogue.model.ResourceManager;
+import net.sf.taverna.biocatalogue.model.SoapOperationIdentity;
+import net.sf.taverna.biocatalogue.model.connectivity.BioCatalogueClient;
+import net.sf.taverna.t2.lang.ui.DeselectingButton;
+import net.sf.taverna.t2.lang.ui.ReadOnlyTextArea;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.MainComponentFactory;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.Integration;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.health_check.ServiceHealthChecker;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.health_check.ServiceMonitoringStatusInterpreter;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workflowmodel.Processor;
+
+import org.apache.log4j.Logger;
+import org.biocatalogue.x2009.xml.rest.Service;
+import org.biocatalogue.x2009.xml.rest.SoapOperation;
+
+
+public class ProcessorView extends ContextualView {
+ private final Processor processor;
+ private JPanel jPanel;
+
+ private static Logger logger = Logger.getLogger(ProcessorView.class);
+
+
+
+ public ProcessorView(Processor processor) {
+ this.processor = processor;
+
+ jPanel = new JPanel();
+
+ // this is required to have the body of this contextual
+ // view added to the main view; otherwise, body will be
+ // blank
+ initView();
+ }
+
+
+
+ @Override
+ public JComponent getMainFrame()
+ {
+ Thread t = new Thread("loading processor data") {
+ public void run() {
+ final SoapOperationIdentity operationDetails = Integration.extractSoapOperationDetailsFromProcessor(processor);
+
+ if (operationDetails.hasError()) {
+ SwingUtilities.invokeLater(new RefreshThread(new JLabel(operationDetails.getErrorDetails().toString(),
+ UIManager.getIcon("OptionPane.warningIcon"), JLabel.CENTER)));
+ return;
+ }
+ else {
+ BioCatalogueClient client = BioCatalogueClient.getInstance();
+
+ if (client != null) {
+ try {
+ final SoapOperation soapOperation = client.lookupSoapOperation(operationDetails);
+ if (soapOperation == null) {
+ SwingUtilities.invokeLater(new RefreshThread(new JLabel("This service is not registered in the Service Catalogue",
+ UIManager.getIcon("OptionPane.warningIcon"), JLabel.CENTER)));
+ return;
+ }
+
+ Service parentService = client.getBioCatalogueService(soapOperation.getAncestors().getService().getHref());
+ if (parentService == null) {
+ SwingUtilities.invokeLater(new RefreshThread(new JLabel("Problem while fetching monitoring data from the Service Catalogue",
+ UIManager.getIcon("OptionPane.warningIcon"), JLabel.CENTER)));
+ return;
+ }
+
+
+ // *** managed to get all necessary data successfully - present it ***
+
+ // create status update panel
+ JButton jclServiceStatus = new DeselectingButton(
+ new AbstractAction("Check monitoring status") {
+ public void actionPerformed(ActionEvent e) {
+ ServiceHealthChecker.checkWSDLProcessor(operationDetails);
+ }
+ });
+ jclServiceStatus.setAlignmentX(Component.LEFT_ALIGNMENT);
+ JLabel jlStatusMessage = new JLabel(parentService.getLatestMonitoringStatus().getMessage());
+ jlStatusMessage.setAlignmentX(Component.LEFT_ALIGNMENT);
+
+ // operation description
+ String operationDescription = (soapOperation.getDescription().length() > 0 ?
+ soapOperation.getDescription() :
+ "No description is available for this service");
+
+ ReadOnlyTextArea jlOperationDescription = new ReadOnlyTextArea(operationDescription);
+
+ jlOperationDescription.setAlignmentX(Component.LEFT_ALIGNMENT);
+
+ // a button to open preview of the service
+ JButton jbLaunchProcessorPreview = new DeselectingButton("Show on the Service Catalogue",
+ new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if (!operationDetails.hasError()) {
+ String hrefString = soapOperation.getHref();
+ try {
+ Desktop.getDesktop().browse(new URI(hrefString));
+ }
+ catch (Exception ex) {
+ logger.error("Failed while trying to open the URL in a standard browser; URL was: " +
+ hrefString, ex);
+ };
+ }
+ else {
+ // this error message comes from Integration class extracting SOAP operation details from the contextual selection
+ JOptionPane.showMessageDialog(null, operationDetails.getErrorDetails(), "Service Catalogue Error", JOptionPane.WARNING_MESSAGE);
+ }
+ }
+ },
+ "View this service on the Service Catalogue");
+
+ JPanel jpPreviewButtonPanel = new JPanel();
+ jpPreviewButtonPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
+ jbLaunchProcessorPreview.setAlignmentX(Component.LEFT_ALIGNMENT);
+ // jpPreviewButtonPanel.add(jbLaunchProcessorPreview);
+ // put everything together
+ JPanel jpInnerPane = new JPanel();
+ jpInnerPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+ jpInnerPane.setLayout(new BoxLayout(jpInnerPane, BoxLayout.Y_AXIS));
+ jpInnerPane.add(jlOperationDescription);
+ jpInnerPane.add(Box.createVerticalStrut(10));
+ jpInnerPane.add(jlStatusMessage);
+ jpInnerPane.add(Box.createVerticalStrut(10));
+ jpInnerPane.add(jclServiceStatus);
+ jpInnerPane.add(Box.createVerticalStrut(10));
+ jpInnerPane.add(jbLaunchProcessorPreview);
+
+ JScrollPane spInnerPane = new JScrollPane(jpInnerPane);
+
+ SwingUtilities.invokeLater(new RefreshThread(spInnerPane));
+ return;
+ }
+ catch (UnknownObjectException e) {
+ SwingUtilities.invokeLater(new RefreshThread(new JLabel(e.getMessage(),
+ UIManager.getIcon("OptionPane.informationIcon"), JLabel.CENTER)));
+ return;
+ }
+ catch (Exception e) {
+ // a real error occurred while fetching data about selected processor
+ logger.error("ERROR: unexpected problem while trying to ", e);
+ SwingUtilities.invokeLater(new RefreshThread(new JLabel("An unknown problem has prevented Taverna from loading this preview",
+ UIManager.getIcon("OptionPane.errorIcon"), JLabel.CENTER)));
+ return;
+ }
+ }
+ else {
+ SwingUtilities.invokeLater(new RefreshThread(new JLabel("Service Catalogue integration has not initialised yet. Please wait and try again.",
+ UIManager.getIcon("OptionPane.warningIcon"), JLabel.CENTER)));
+ return;
+ }
+ }
+ }
+ };
+
+ jPanel.removeAll();
+ jPanel.setPreferredSize(new Dimension(200,200));
+ jPanel.setLayout(new GridLayout());
+ jPanel.add(new JLabel(ResourceManager.getImageIcon(ResourceManager.BAR_LOADER_ORANGE), JLabel.CENTER));
+ t.start();
+ return jPanel;
+ }
+
+ @Override
+ public String getViewTitle() {
+ return "Service Catalogue Information";
+ }
+
+ @Override
+ public void refreshView()
+ {
+ // this actually causes the parent container to validate itself,
+ // which is what is needed here
+ this.revalidate();
+ this.repaint();
+ }
+
+ @Override
+ public int getPreferredPosition() {
+ return BioCataloguePluginConstants.CONTEXTUAL_VIEW_PREFERRED_POSITION;
+ }
+
+ class RefreshThread extends Thread {
+ private final Component component;
+
+ public RefreshThread (Component component) {
+ this.component = component;
+ }
+
+ public void run() {
+ jPanel.removeAll();
+ if (component != null) {
+ jPanel.add(component);
+ }
+ refreshView();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/health_check/BioCatalogueWSDLActivityHealthCheck.java
----------------------------------------------------------------------
diff --git a/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/health_check/BioCatalogueWSDLActivityHealthCheck.java b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/health_check/BioCatalogueWSDLActivityHealthCheck.java
new file mode 100644
index 0000000..2461c2c
--- /dev/null
+++ b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/health_check/BioCatalogueWSDLActivityHealthCheck.java
@@ -0,0 +1,40 @@
+package net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.health_check;
+
+import net.sf.taverna.t2.visit.VisitKind;
+import net.sf.taverna.t2.visit.Visitor;
+
+/**
+ * A {@link BioCatalogueWSDLActivityHealthCheck} is a kind of visit that determines
+ * if the corresponding WSDL activity in a workflow will work during a workflow run -
+ * checks will be made based on the monitoring status held about that service in BioCatalogue.
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class BioCatalogueWSDLActivityHealthCheck extends VisitKind
+{
+ // The following values indicate the type of results that can be associated
+ // with a VisitReport generated by a health-checking visitor.
+ public static final int MESSAGE_IN_VISIT_REPORT = 0;
+
+
+ // property names to be placed into VisitReport generated by BioCatalogueWSDLActivityHealthChecker
+ public static final String WSDL_LOCATION_PROPERTY = "wsdlLocation";
+ public static final String OPERATION_NAME_PROPERTY = "soapOperationName";
+ public static final String EXPLANATION_MSG_PROPERTY = "fullExplanationMessage";
+
+
+
+
+ @Override
+ public Class<? extends Visitor> getVisitorClass() {
+ return BioCatalogueWSDLActivityHealthChecker.class;
+ }
+
+ private static class Singleton {
+ private static BioCatalogueWSDLActivityHealthCheck instance = new BioCatalogueWSDLActivityHealthCheck();
+ }
+
+ public static BioCatalogueWSDLActivityHealthCheck getInstance() {
+ return Singleton.instance;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/health_check/BioCatalogueWSDLActivityHealthCheckVisitExplainer.java
----------------------------------------------------------------------
diff --git a/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/health_check/BioCatalogueWSDLActivityHealthCheckVisitExplainer.java b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/health_check/BioCatalogueWSDLActivityHealthCheckVisitExplainer.java
new file mode 100644
index 0000000..8bee663
--- /dev/null
+++ b/taverna-perspective-biocatalogue/src/main/java/net/sf/taverna/t2/ui/perspectives/biocatalogue/integration/health_check/BioCatalogueWSDLActivityHealthCheckVisitExplainer.java
@@ -0,0 +1,111 @@
+package net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.health_check;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+
+import net.sf.taverna.biocatalogue.model.SoapOperationIdentity;
+import net.sf.taverna.t2.lang.ui.ReadOnlyTextArea;
+import net.sf.taverna.t2.visit.VisitKind;
+import net.sf.taverna.t2.visit.VisitReport;
+import net.sf.taverna.t2.workbench.report.explainer.VisitExplainer;
+
+// import status constants
+import static net.sf.taverna.t2.ui.perspectives.biocatalogue.integration.health_check.BioCatalogueWSDLActivityHealthCheck.*;
+
+/**
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class BioCatalogueWSDLActivityHealthCheckVisitExplainer implements VisitExplainer
+{
+
+ public boolean canExplain(VisitKind vk, int resultId) {
+ return (vk instanceof BioCatalogueWSDLActivityHealthCheck);
+ }
+
+
+ /**
+ * This class only handles {@link VisitReport} instances that are of
+ * {@link BioCatalogueWSDLActivityHealthCheck} kind. Therefore, decisions on
+ * the explanations / solutions are made solely by visit result IDs.
+ */
+ public JComponent getExplanation(final VisitReport vr)
+ {
+ int resultId = vr.getResultId();
+ String explanation = null;
+
+ switch (resultId) {
+ case MESSAGE_IN_VISIT_REPORT:
+ explanation = (String) vr.getProperty(EXPLANATION_MSG_PROPERTY); break;
+
+ default:
+ explanation = "Unknown issue - no expalanation available"; break;
+ }
+
+
+ JButton bRunBioCatalogueHealthCheck = new JButton("View monitoring status details");
+ bRunBioCatalogueHealthCheck.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ SoapOperationIdentity soapOpIdentity =
+ new SoapOperationIdentity((String)vr.getProperty(BioCatalogueWSDLActivityHealthCheck.WSDL_LOCATION_PROPERTY),
+ (String)vr.getProperty(BioCatalogueWSDLActivityHealthCheck.OPERATION_NAME_PROPERTY), null);
+
+ ServiceHealthChecker.checkWSDLProcessor(soapOpIdentity);
+ }
+ });
+ JPanel jpButton = new JPanel();
+ jpButton.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
+ jpButton.add(bRunBioCatalogueHealthCheck);
+ jpButton.setOpaque(false);
+
+ JPanel jpExplanation = new JPanel(new BorderLayout());
+ jpExplanation.add(new ReadOnlyTextArea(explanation), BorderLayout.CENTER);
+ jpExplanation.add(jpButton, BorderLayout.SOUTH);
+
+ return (jpExplanation);
+ }
+
+
+
+ /**
+ * This class only handles {@link VisitReport} instances that are of
+ * {@link BioCatalogueWSDLActivityHealthCheck} kind. Therefore, decisions on
+ * the explanations / solutions are made solely by visit result IDs.
+ */
+ public JComponent getSolution(VisitReport vr)
+ {
+ String explanation = null;
+
+ // instead of switching between possible health check resultIDs,
+ // simply choose from possible statuses: for all failures there's
+ // nothing specific that can be done, so no need to differentiate
+ // displayed messages
+ switch (vr.getStatus()) {
+ case OK:
+ explanation = "This WSDL service works fine - no change necessary"; break;
+
+ case WARNING:
+ case SEVERE:
+ explanation = "This remote WSDL service appears to have an internal problem. There is nothing " +
+ "specific that can be done to fix it locally.\n\n" +
+ "It is possible that the current state of the service will still allow to execute " +
+ "the workflow successfully. Also, the service may have already recovered since the " +
+ "last time it's monitoring status has been checked.\n\n" +
+ "If this problem does affect the current workflow, it may be resolved by the " +
+ "service provider. It may be worth contacting them to report the issue.";
+ break;
+
+ default:
+ explanation = "Unknown issue - no solution available"; break;
+ }
+
+ return (new ReadOnlyTextArea(explanation));
+ }
+
+}