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/02/23 11:22:38 UTC
[15/51] [partial] incubator-taverna-workbench git commit: Revert
"temporarily empty repository"
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/ResourceManager.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/ResourceManager.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/ResourceManager.java
new file mode 100644
index 0000000..666cd6c
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/ResourceManager.java
@@ -0,0 +1,326 @@
+package net.sf.taverna.biocatalogue.model;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.image.BufferedImage;
+import java.net.URL;
+import java.util.HashMap;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+
+import net.sf.taverna.t2.activities.rest.ui.servicedescription.RESTActivityIcon;
+import net.sf.taverna.t2.activities.wsdl.servicedescriptions.WSDLActivityIcon;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.BioCataloguePerspective;
+
+/**
+ * This class will be a single point of lookup of all resource files.
+ * (Icons, images, CSS files, etc).
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class ResourceManager
+{
+ // subfolders, where some icons / other resources are kept
+ public static final String FAMFAMFAM_PATH = "famfamfam_silk/"; // free collection of icons
+ public static final String SERVICE_ICONS_PATH = "service_icons/"; // icons related to web services (e.g. service types)
+ public static final String FOLDS_PATH = "folds/"; // icons for 'folding' menus (like 'Search for...')
+ public static final String TRISTATE_TREE_ICONS_PATH = "tristate_checkbox/"; // icons for the tri-state filtering tree
+
+ // all known resources to follow
+ public static final int FAVICON = 1;
+
+ public static final int INFORMATION_ICON_LARGE = 10;
+
+ public static final int SPINNER_STILL = 20;
+ public static final int SPINNER = 21;
+ public static final int BAR_LOADER_GREY = 25;
+ public static final int BAR_LOADER_GREY_STILL = 26;
+ public static final int BAR_LOADER_ORANGE = 30;
+ public static final int BAR_LOADER_ORANGE_STILL = 31;
+
+ public static final int FOLD_ICON = 40;
+ public static final int UNFOLD_ICON = 41;
+ public static final int FOLD_ICON_16x16 = 42;
+ public static final int UNFOLD_ICON_16x16 = 43;
+
+ public static final int SERVICE_TYPE_SOAP_ICON = 50;
+ public static final int SERVICE_TYPE_REST_ICON = 51;
+ public static final int SERVICE_TYPE_MULTITYPE_ICON = 65;
+ public static final int SERVICE_TYPE_UNKNOWN_ICON = 70;
+
+ public static final int TRISTATE_CHECKBOX_CHECKED_ICON = 80;
+ public static final int TRISTATE_CHECKBOX_PARTIAL_ICON = 82;
+ public static final int TRISTATE_CHECKBOX_UNCHECKED_ICON = 85;
+ public static final int UNCHECKED_ICON = 86;
+
+ public static final int SERVICE_STATUS_PASSED_ICON = 100;
+ public static final int SERVICE_STATUS_PASSED_ICON_LARGE = 101;
+ public static final int SERVICE_STATUS_WARNING_ICON = 110;
+ public static final int SERVICE_STATUS_WARNING_ICON_LARGE = 111;
+ public static final int SERVICE_STATUS_FAILED_ICON = 120;
+ public static final int SERVICE_STATUS_FAILED_ICON_LARGE = 121;
+ public static final int SERVICE_STATUS_UNCHECKED_ICON = 130;
+ public static final int SERVICE_STATUS_UNCHECKED_ICON_LARGE = 131;
+ public static final int SERVICE_STATUS_UNKNOWN_ICON = 140;
+
+ public static final int UNKNOWN_RESOURCE_TYPE_ICON = 200;
+ public static final int USER_ICON = 205;
+ public static final int REGISTRY_ICON = 210;
+ public static final int SERVICE_PROVIDER_ICON = 215;
+ public static final int SERVICE_ICON = 220;
+ public static final int SOAP_OPERATION_ICON = 225;
+ public static final int REST_METHOD_ICON = 227;
+ public static final int SERVICE_CATEGORY_ICON = 230;
+ public static final int WSDL_DOCUMENT_ICON = 235;
+ public static final int TAG_ICON = 240;
+
+ public static final int OPEN_IN_BIOCATALOGUE_ICON = 310;
+ public static final int SEARCH_ICON = 315;
+ public static final int HISTORY_ICON = 320;
+ public static final int REFRESH_ICON = 330;
+ public static final int FAVOURITE_ICON = 335;
+ public static final int TICK_ICON = 340;
+ public static final int CROSS_ICON = 341;
+ public static final int WARNING_ICON = 342;
+ public static final int ERROR_ICON = 343;
+ public static final int SAVE_ICON = 345;
+ public static final int DELETE_ITEM_ICON = 350;
+ public static final int CLEAR_ICON = 355;
+ public static final int LOCKED_ICON = 360;
+ public static final int UNLOCKED_ICON = 365;
+
+ public static final int BACK_ICON = 370;
+ public static final int FORWARD_ICON = 375;
+ public static final int FILTER_ICON = 380;
+ public static final int PREVIEW_ICON = 385;
+ public static final int SUGGESTION_TO_USER_ICON = 390;
+ public static final int ADD_PROCESSOR_TO_WORKFLOW_ICON = 395;
+ public static final int ADD_PROCESSOR_AS_FAVOURITE_ICON = 396;
+ public static final int EXECUTE_HEALTH_CHECK_ICON = 397;
+ public static final int ADD_ALL_SERVICES_AS_FAVOURITE_ICON = 398;
+
+ public static final int SELECT_ALL_ICON = 400;
+ public static final int DESELECT_ALL_ICON = 405;
+ public static final int EXPAND_ALL_ICON = 410;
+ public static final int COLLAPSE_ALL_ICON = 420;
+
+ public static final int SORT_BY_NAME_ICON = 450;
+ public static final int SORT_BY_COUNTS_ICON = 455;
+
+ public static final int STYLES_CSS = 1000;
+
+
+ /**
+ * Simple method to retrieve relative path of a required resource.
+ */
+ public static String getResourceRelPath(int resourceId)
+ {
+ String resPath = "";
+
+ switch (resourceId) {
+ case FAVICON: resPath += "favicon.png";
+ break;
+ case INFORMATION_ICON_LARGE: resPath += "info-sphere-35.png";
+ break;
+ case SPINNER_STILL: resPath += "ajax-loader-still.gif";
+ break;
+ case SPINNER: resPath += "ajax-loader.gif";
+ break;
+ case BAR_LOADER_GREY: resPath += "ajax-loader-grey-bert2.gif";
+ break;
+ case BAR_LOADER_GREY_STILL: resPath += "ajax-loader-grey-bert2-still.png";
+ break;
+ case BAR_LOADER_ORANGE: resPath += "ajax-loader-orange-bert2.gif";
+ break;
+ case BAR_LOADER_ORANGE_STILL: resPath += "ajax-loader-orange-bert2-still.png";
+ break;
+ case FOLD_ICON: resPath += FOLDS_PATH + "fold.png";
+ break;
+ case UNFOLD_ICON: resPath += FOLDS_PATH + "unfold.png";
+ break;
+ case FOLD_ICON_16x16: resPath += FOLDS_PATH + "fold_16x16.png";
+ break;
+ case UNFOLD_ICON_16x16: resPath += FOLDS_PATH + "unfold_16x16.png";
+ break;
+ case SERVICE_TYPE_SOAP_ICON: resPath += SERVICE_ICONS_PATH + "service_type_soap.png";
+ break;
+ case SERVICE_TYPE_REST_ICON: resPath += SERVICE_ICONS_PATH + "service_type_rest.png";
+ break;
+ case SERVICE_TYPE_MULTITYPE_ICON: resPath += SERVICE_ICONS_PATH + "service_type_multitype.png";
+ break;
+ case SERVICE_TYPE_UNKNOWN_ICON: resPath += SERVICE_ICONS_PATH + "service_type_unknown.png";
+ break;
+ case SERVICE_STATUS_PASSED_ICON: resPath += FAMFAMFAM_PATH + "accept.png";
+ break;
+ case SERVICE_STATUS_PASSED_ICON_LARGE: resPath += "tick-sphere-35.png";
+ break;
+ case SERVICE_STATUS_WARNING_ICON: resPath += FAMFAMFAM_PATH + "error.png";
+ break;
+ case SERVICE_STATUS_WARNING_ICON_LARGE: resPath += "pling-sphere-35.png";
+ break;
+ case SERVICE_STATUS_FAILED_ICON: resPath += FAMFAMFAM_PATH + "exclamation.png";
+ break;
+ case SERVICE_STATUS_FAILED_ICON_LARGE: resPath += "cross-sphere-35.png";
+ break;
+ case SERVICE_STATUS_UNCHECKED_ICON: resPath += FAMFAMFAM_PATH + "help.png";
+ break;
+ case SERVICE_STATUS_UNCHECKED_ICON_LARGE: resPath += "query-sphere-35.png";
+ break;
+ case SERVICE_STATUS_UNKNOWN_ICON: resPath += FAMFAMFAM_PATH + "grey_circle.png";
+ break;
+ case TRISTATE_CHECKBOX_CHECKED_ICON: resPath += TRISTATE_TREE_ICONS_PATH + "tristate_checkbox_checked.png";
+ break;
+ case TRISTATE_CHECKBOX_PARTIAL_ICON: resPath += TRISTATE_TREE_ICONS_PATH + "tristate_checkbox_partial.png";
+ break;
+ case TRISTATE_CHECKBOX_UNCHECKED_ICON: resPath += TRISTATE_TREE_ICONS_PATH + "tristate_checkbox_unchecked.png";
+ break;
+ case UNCHECKED_ICON: resPath += "unchecked.png";
+ break;
+ case UNKNOWN_RESOURCE_TYPE_ICON: resPath += FAMFAMFAM_PATH + "grey_circle.png";
+ break;
+ case USER_ICON: resPath += FAMFAMFAM_PATH + "user.png";
+ break;
+ case REGISTRY_ICON: resPath += FAMFAMFAM_PATH + "remote_resource.png";
+ break;
+ case SERVICE_PROVIDER_ICON: resPath += FAMFAMFAM_PATH + "chart_organisation.png";
+ break;
+ case SERVICE_ICON: resPath += "favicon.png";
+ break;
+ case SOAP_OPERATION_ICON: resPath += FAMFAMFAM_PATH + "plugin.png";
+ break;
+ case REST_METHOD_ICON: resPath += FAMFAMFAM_PATH + "plugin.png";
+ break;
+ case SERVICE_CATEGORY_ICON: resPath += FAMFAMFAM_PATH + "text_list_numbers.png";
+ break;
+ case TAG_ICON: resPath += FAMFAMFAM_PATH + "tag_blue.png";
+ break;
+ case WSDL_DOCUMENT_ICON: resPath += FAMFAMFAM_PATH + "page_white_code.png";
+ break;
+ case OPEN_IN_BIOCATALOGUE_ICON: resPath += FAMFAMFAM_PATH + "magnifier.png";
+ break;
+ case SEARCH_ICON: resPath += FAMFAMFAM_PATH + "magnifier.png";
+ break;
+ case HISTORY_ICON: resPath += FAMFAMFAM_PATH + "folder_explore.png";
+ break;
+ case REFRESH_ICON: resPath += FAMFAMFAM_PATH + "arrow_refresh.png";
+ break;
+ case FAVOURITE_ICON: resPath += FAMFAMFAM_PATH + "star.png";
+ break;
+ case TICK_ICON: resPath += FAMFAMFAM_PATH + "tick.png";
+ break;
+ case CROSS_ICON: resPath += FAMFAMFAM_PATH + "cross.png";
+ break;
+ case WARNING_ICON: resPath += FAMFAMFAM_PATH + "error.png";
+ break;
+ case ERROR_ICON: resPath += FAMFAMFAM_PATH + "exclamation.png";
+ break;
+ case SAVE_ICON: resPath += FAMFAMFAM_PATH + "disk.png";
+ break;
+ case DELETE_ITEM_ICON: resPath += FAMFAMFAM_PATH + "cross.png";
+ break;
+ case CLEAR_ICON: resPath += "trash.png";
+ break;
+ case LOCKED_ICON: resPath += FAMFAMFAM_PATH + "lock.png";
+ break;
+ case UNLOCKED_ICON: resPath += FAMFAMFAM_PATH + "lock_open.png";
+ break;
+ case BACK_ICON: resPath += FAMFAMFAM_PATH + "arrow_left.png";
+ break;
+ case FORWARD_ICON: resPath += FAMFAMFAM_PATH + "arrow_right.png";
+ break;
+ case FILTER_ICON: resPath += FAMFAMFAM_PATH + "arrow_join (flipped vertically).png";
+ break;
+ case PREVIEW_ICON: resPath += FAMFAMFAM_PATH + "magnifier.png";
+ break;
+ case SUGGESTION_TO_USER_ICON: resPath += FAMFAMFAM_PATH + "lightbulb.png";
+ break;
+ case ADD_PROCESSOR_TO_WORKFLOW_ICON: resPath += "open_in_BioCatalogue.png";
+ break;
+ case ADD_PROCESSOR_AS_FAVOURITE_ICON: resPath += FAMFAMFAM_PATH + "star.png";
+ break;
+ case ADD_ALL_SERVICES_AS_FAVOURITE_ICON:resPath += FAMFAMFAM_PATH + "multiple_star.png";
+ break;
+ case EXECUTE_HEALTH_CHECK_ICON: resPath += FAMFAMFAM_PATH + "information.png";
+ break;
+ case SELECT_ALL_ICON: resPath += FAMFAMFAM_PATH + "tick.png";
+ break;
+ case DESELECT_ALL_ICON: resPath += FAMFAMFAM_PATH + "cross.png";
+ break;
+ case EXPAND_ALL_ICON: resPath += FAMFAMFAM_PATH + "text_linespacing.png";
+ break;
+ case COLLAPSE_ALL_ICON: resPath += FAMFAMFAM_PATH + "text_linespacing (collapse).png";
+ break;
+ case SORT_BY_NAME_ICON: resPath += FAMFAMFAM_PATH + "style.png";
+ break;
+ case SORT_BY_COUNTS_ICON: resPath += FAMFAMFAM_PATH + "sum.png";
+ break;
+ case STYLES_CSS: resPath += "styles.css";
+ break;
+ default: return (null);
+ }
+
+ return (resPath);
+ }
+
+
+ private static URL getResourceLocalURL(int resourceId) {
+ return (BioCataloguePerspective.class.getResource(getResourceRelPath(resourceId)));
+ }
+
+ private static HashMap<Integer, ImageIcon> iconMap = new HashMap<Integer, ImageIcon>();
+
+ public static ImageIcon getImageIcon(int iconId)
+ {
+ ImageIcon result = iconMap.get(iconId);
+ if (result == null) {
+ result = new ImageIcon(getResourceLocalURL(iconId));
+ iconMap.put(iconId, result);
+ }
+ return result;
+ }
+
+ public static ImageIcon getImageIcon(URL resourceLocalURL) {
+ return (new ImageIcon(resourceLocalURL));
+ }
+
+
+ public static Icon getIconFromTaverna(int iconId) {
+ switch (iconId) {
+ case SOAP_OPERATION_ICON: return (WSDLActivityIcon.getWSDLIcon());
+ case REST_METHOD_ICON: return (RESTActivityIcon.getRESTActivityIcon());
+ default: return (drawMissingIcon());
+ }
+ }
+
+
+ /**
+ * This method would be called by other methods in this class
+ * when they were unable to load requested icon.
+ *
+ * @return A 16x16 pixel icon that represents a missing icon -
+ * a red cross.
+ */
+ private static ImageIcon drawMissingIcon()
+ {
+ int w = 16;
+ int h = 16;
+ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ GraphicsDevice gd = ge.getDefaultScreenDevice();
+ GraphicsConfiguration gc = gd.getDefaultConfiguration();
+
+ BufferedImage image = gc.createCompatibleImage(w, h, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g = image.createGraphics();
+ g.setColor(Color.RED);
+ g.setStroke(new BasicStroke(3, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER));
+ g.drawLine(4, 4, 12, 12);
+ g.drawLine(12, 4, 4, 12);
+ g.dispose();
+
+ return new ImageIcon(image);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/ResourcePreviewContent.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/ResourcePreviewContent.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/ResourcePreviewContent.java
new file mode 100644
index 0000000..7dc1fce
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/ResourcePreviewContent.java
@@ -0,0 +1,38 @@
+package net.sf.taverna.biocatalogue.model;
+
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+
+import net.sf.taverna.biocatalogue.model.connectivity.BioCatalogueClient;
+
+/**
+ * Helper class to hold all data about the generated preview.
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class ResourcePreviewContent
+{
+ private Resource resource;
+ private JComponent jcContent;
+
+ public ResourcePreviewContent(Resource resource, JComponent content)
+ {
+ this.resource = resource;
+ this.jcContent = content;
+ }
+
+ public Resource getResource() {
+ return(this.resource);
+ }
+
+ public JComponent getContent() {
+ return(this.jcContent);
+ }
+
+
+ public static ResourcePreviewContent createDummyInstance()
+ {
+ Resource r = new Resource(BioCatalogueClient.API_USERS_URL + "/1", "Dummy user");
+ return (new ResourcePreviewContent(r, new JLabel("dummy content - JLabel")));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/SoapOperationIdentity.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/SoapOperationIdentity.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/SoapOperationIdentity.java
new file mode 100644
index 0000000..df16566
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/SoapOperationIdentity.java
@@ -0,0 +1,77 @@
+package net.sf.taverna.biocatalogue.model;
+
+/**
+ * Identifies a SOAP operation (or "processor" in Taverna terms)
+ * in the most straightforward way - by WSDL location and operation name.
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class SoapOperationIdentity extends SoapServiceIdentity
+{
+ public static final String ACTION_STRING_SEPARATOR = "===";
+
+ private final String operationName;
+ private final String description;
+
+ public SoapOperationIdentity(String wsdlLocation, String operationName, String description) {
+ super(wsdlLocation);
+ this.operationName = operationName;
+ this.description = description;
+ }
+
+ public SoapOperationIdentity(Object errorDetails) {
+ super(errorDetails);
+ this.operationName = null;
+ this.description = null;
+ }
+
+ public String getOperationName() {
+ return operationName;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+
+ /**
+ * @return String that can be placed into an action command (i.e. into JClickableLabel)
+ * to identify a SOAP operation - WSDL location and operation name are concatenated
+ * with <code>SoapOperationIdentity.ACTION_STRING_SEPARATOR</code>.
+ */
+ public String toActionString() {
+ return (getWsdlLocation() + ACTION_STRING_SEPARATOR + this.operationName);
+ }
+
+
+ /**
+ * @param actionString String that includes WSDL location appended by
+ * <code>SoapOperationIdentity.ACTION_STRING_SEPARATOR</code>
+ * and by the operation name of a SOAP operations.
+ * <br/>
+ * The action string may either contain only WSDL location and operation
+ * name (which are joined by a specified separator) OR the action string
+ * may start from <code>BioCataloguePluginConstants.ACTION_PREVIEW_SOAP_OPERATION_AFTER_LOOKUP</code>.
+ * @return Instance of this class initialised with the values from the <code>actionString</code>
+ * or <code>null</code> if an error occurred.
+ */
+ public static SoapOperationIdentity fromActionString(String actionString)
+ {
+ if (actionString == null) return (null);
+
+ // remove the prefix if it is present
+ if (actionString.startsWith(BioCataloguePluginConstants.ACTION_PREVIEW_SOAP_OPERATION_AFTER_LOOKUP)) {
+ actionString = actionString.substring(BioCataloguePluginConstants.ACTION_PREVIEW_SOAP_OPERATION_AFTER_LOOKUP.length());
+ }
+
+ String[] parts = actionString.split(ACTION_STRING_SEPARATOR);
+ if (parts == null || parts.length != 2 ||
+ parts[0].length() == 0 || parts[1].length() == 0)
+ {
+ return (null);
+ }
+
+ return (new SoapOperationIdentity(parts[0], parts[1], null));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/SoapOperationPortIdentity.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/SoapOperationPortIdentity.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/SoapOperationPortIdentity.java
new file mode 100644
index 0000000..6910e23
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/SoapOperationPortIdentity.java
@@ -0,0 +1,26 @@
+package net.sf.taverna.biocatalogue.model;
+
+public class SoapOperationPortIdentity extends SoapOperationIdentity
+{
+ private String portName;
+ private boolean isInput;
+
+ public SoapOperationPortIdentity(String wsdlLocation, String operationName, String portName, boolean isInput) {
+ super(wsdlLocation, operationName, null);
+ this.portName = portName;
+ this.isInput = isInput;
+ }
+
+ public SoapOperationPortIdentity(Object errorDetails) {
+ super(errorDetails);
+ }
+
+ public String getPortName() {
+ return portName;
+ }
+
+ public boolean isInput() {
+ return isInput;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/SoapProcessorIdentity.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/SoapProcessorIdentity.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/SoapProcessorIdentity.java
new file mode 100644
index 0000000..814a701
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/SoapProcessorIdentity.java
@@ -0,0 +1,27 @@
+package net.sf.taverna.biocatalogue.model;
+
+/**
+ * Identifies a SOAP Processor in Taverna terms. Adds a local name
+ * attribute to the details available in <code>SoapOperationIdentity</code>.
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class SoapProcessorIdentity extends SoapOperationIdentity
+{
+ private final String localName;
+
+ public SoapProcessorIdentity(String wsdlLocation, String operationName, String localName) {
+ super(wsdlLocation, operationName, null);
+ this.localName = localName;
+ }
+
+ public SoapProcessorIdentity(Object errorDetails) {
+ super(errorDetails);
+ this.localName = null;
+ }
+
+ public String getLocalName() {
+ return localName;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/SoapServiceIdentity.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/SoapServiceIdentity.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/SoapServiceIdentity.java
new file mode 100644
index 0000000..a015ad2
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/SoapServiceIdentity.java
@@ -0,0 +1,45 @@
+package net.sf.taverna.biocatalogue.model;
+
+/**
+ * Identifies a SOAP service in the most straightforward
+ * way - by WSDL location.
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class SoapServiceIdentity
+{
+ private final String wsdlLocation;
+
+ // this variable holds an object that will be displayable
+ private final Object errorDetails;
+
+ public SoapServiceIdentity(String wsdlLocation) {
+ this.wsdlLocation = wsdlLocation;
+ this.errorDetails = null;
+ }
+
+ public SoapServiceIdentity(Object errorDetails) {
+ this.errorDetails = errorDetails;
+ this.wsdlLocation = null;
+ }
+
+ public String getWsdlLocation() {
+ return (wsdlLocation);
+ }
+
+ public boolean hasError() {
+ return (errorDetails != null);
+ }
+
+ /**
+ * @return Returned object contains an object that may be displayed
+ * in a JOptionPane or printed (in other words defining a
+ * sensible way of displaying itself), which has details of
+ * an error that has occurred which prevented from populating
+ * this instance with the actual details of their SOAP service.
+ */
+ public Object getErrorDetails() {
+ return (errorDetails);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/Tag.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/Tag.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/Tag.java
new file mode 100644
index 0000000..e1ca6b9
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/Tag.java
@@ -0,0 +1,218 @@
+package net.sf.taverna.biocatalogue.model;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+import org.apache.commons.lang.StringEscapeUtils;
+
+
+/**
+ * @author Sergejs Aleksejevs
+ */
+public class Tag implements Serializable
+{
+ private static final long serialVersionUID = 784872111173271581L;
+
+ private String tagURI; // URI to use on BioCatalogue to fetch all tagged items
+ private String tagNamespace; // namespace where this tag is defined
+ private String tagDisplayName; // only the actual tag (for display within the tag cloud)
+ private String fullTagName; // full tag name - including namespace
+ private int itemCount; // count of tagged items
+
+
+ /**
+ * Constructs a Tag instance from primitive components.
+ * All values are set directly, no internal inference made.
+ *
+ * @param tagURI
+ * @param tagNamespace
+ * @param tagDisplayName
+ * @param fullTagName
+ * @param itemCount
+ */
+ public Tag(String tagURI, String tagNamespace, String tagDisplayName, String fullTagName, int itemCount)
+ {
+ this.tagURI = tagURI;
+ this.tagNamespace = tagNamespace;
+ this.tagDisplayName = tagDisplayName;
+ this.setFullTagName(fullTagName);
+ this.itemCount = itemCount;
+ }
+
+
+ /**
+ * Constructs Tag instance from an XML representation of the Tag from BioCatalogue API.
+ *
+ * @param xmlTag
+ */
+ public Tag(org.biocatalogue.x2009.xml.rest.Tag xmlTag)
+ {
+ // these values come directly from the XML data obtained via the API
+ this.tagURI = xmlTag.getHref();
+ this.fullTagName = xmlTag.getName();
+ this.itemCount = xmlTag.getTotalItemsCount().intValue();
+
+ // NB! Namespace and the display name need to be inferred 'manually'.
+ // First - set the namespace; it's value is taken from the 'namespace'
+ // attribute of the tag URI.
+ this.tagNamespace = Util.extractURLParameter(this.tagURI, "namespace");
+
+ // Now set the display name; if full tag name is not a part of any ontology,
+ // display name will be identical to the full name.
+ if (this.fullTagName.startsWith("<") && this.fullTagName.endsWith(">")) {
+ int iStart = this.fullTagName.lastIndexOf('#') + 1;
+ this.tagDisplayName = this.fullTagName.substring(iStart, this.fullTagName.length() - 1);
+ }
+ else {
+ this.tagDisplayName = this.fullTagName;
+ }
+ }
+
+
+ // *** Various getters and setters ***
+
+ public void setTagURI(String tagURI) {
+ this.tagURI = tagURI;
+ }
+
+ public String getTagURI() {
+ return tagURI;
+ }
+
+
+ public void setTagNamespace(String tagNamespace) {
+ this.tagNamespace = tagNamespace;
+ }
+
+ public String getTagNamespace() {
+ return tagNamespace;
+ }
+
+
+ public void setTagDisplayName(String tagDisplayName) {
+ this.tagDisplayName = tagDisplayName;
+ }
+
+ public String getTagDisplayName() {
+ return tagDisplayName;
+ }
+
+
+ public void setFullTagName(String fullTagName) {
+ this.fullTagName = fullTagName;
+ }
+
+ /**
+ * @return Unique and unambiguous name of this tag on BioCatalogue:<br/>
+ * <ul>
+ * <li>for tags with no namespaces, they it is just plain text names;</li>
+ * <li>for those with namespaces, it will have the following form:<br/>
+ * "<code>< http://www.mygrid.org.uk/ontology#retrieving ></code>" (without spaces, though), where
+ * the first part before the '#' symbol is the namespace and the second part
+ * is the actual tag within that namespace.</li></ul>
+ */
+ public String getFullTagName() {
+ return fullTagName;
+ }
+
+
+ public int getItemCount() {
+ return itemCount;
+ }
+
+ public void setItemCount(int itemCount) {
+ this.itemCount = itemCount;
+ }
+
+
+ // *** Tag Comparators ***
+
+ public static class ReversePopularityComparator implements Comparator<Tag>
+ {
+ public ReversePopularityComparator() {
+ super();
+ }
+
+ public int compare(Tag t1, Tag t2)
+ {
+ if (t1.getItemCount() == t2.getItemCount()) {
+ // in case of the same popularity, compare by full tag names (which are unique)
+ return (t1.getFullTagName().compareTo(t2.getFullTagName()));
+ }
+ else {
+ // popularity isn't the same; arrange by popularity (more popular first)
+ return (t2.getItemCount() - t1.getItemCount());
+ }
+ }
+ }
+
+
+ public static class AlphanumericComparator implements Comparator<Tag>
+ {
+ public AlphanumericComparator() {
+ super();
+ }
+
+ public int compare(Tag t1, Tag t2) {
+ // full tag names are unique on BioCatalogue
+ return (t1.getFullTagName().compareTo(t2.getFullTagName()));
+ }
+ }
+
+ public static class AlphabeticalIgnoreCaseComparator implements Comparator<Tag>
+ {
+ public AlphabeticalIgnoreCaseComparator() {
+ super();
+ }
+
+ public int compare(Tag t1, Tag t2) {
+ // full tag names are unique on BioCatalogue
+ return (t1.getTagDisplayName().compareToIgnoreCase(t2.getTagDisplayName()));
+ }
+ }
+
+ /**
+ * This makes sure that things like instanceOf() and remove() in List interface
+ * work properly - this way resources are treated to be the same if they store
+ * identical data, rather than they simply hold the same reference.
+ */
+ public boolean equals(Object other) {
+ // could only be equal to another Tag object, not anything else
+ if (! (other instanceof Tag)) return (false);
+
+ // 'other' object is a Tag; equality is based on the data stored
+ // in the current and 'other' Tag instances
+ Tag otherTag = (Tag)other;
+ return (this.itemCount == otherTag.itemCount && this.fullTagName.equals(otherTag.fullTagName));
+ }
+
+
+ public String toString()
+ {
+ return ("Tag (" + this.fullTagName + ", " + this.itemCount + ")");
+ }
+
+
+ /**
+ * This method is used to generate the tooltip to be shown over the tag
+ * in the tagcloud. Shown text will contain the full tag name, namespace
+ * and frequency.
+ *
+ * @return HTML encoded string ready to be put into the tooltip.
+ */
+ public String getTagCloudTooltip()
+ {
+ StringBuilder tooltip = new StringBuilder("<html>");
+
+ tooltip.append(" <b>" + (this.fullTagName.length() > this.tagDisplayName.length() ? "Full tag" : "Tag") + ": </b>" + StringEscapeUtils.escapeHtml(this.fullTagName));
+ if (this.tagNamespace != null && this.tagNamespace.length() > 0) {
+ tooltip.append("<br> <b>Namespace: </b>" + StringEscapeUtils.escapeHtml(this.tagNamespace));
+ }
+ tooltip.append("<br> <b>Frequency: </b>" + this.itemCount);
+ tooltip.append("</html>");
+
+ return tooltip.toString();
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/Util.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/Util.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/Util.java
new file mode 100644
index 0000000..06b30e3
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/Util.java
@@ -0,0 +1,793 @@
+package net.sf.taverna.biocatalogue.model;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Font;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.BorderFactory;
+import javax.swing.JLabel;
+
+import net.sf.taverna.raven.appconfig.ApplicationRuntime;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.BioCataloguePerspective;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.log4j.Logger;
+
+/**
+ * Class containing various reusable helper methods.
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class Util
+
+
+{
+
+ private static Logger logger = Logger.getLogger(Util.class);
+
+
+ /**
+ * Makes sure that one component (for example, a window) is centered horizontally and vertically
+ * relatively to the other component. This is achieved by aligning centers of the two components.
+ *
+ * This method can be used even if the 'dependentComponent' is larger than the 'mainComponent'. In
+ * this case it is probably only useful for centering windows against each other rather than
+ * components inside a container.
+ *
+ * Method also makes sure that the dependent component will not be placed above the screen's upper
+ * edge and to the left of the left edge.
+ */
+ public static void centerComponentWithinAnother(Component mainComponent, Component dependentComponent)
+ {
+ int iMainComponentCenterX = (int)Math.round(mainComponent.getLocationOnScreen().getX() + (mainComponent.getWidth() / 2));
+ int iPosX = iMainComponentCenterX - (dependentComponent.getWidth() / 2);
+ if (iPosX < 0) iPosX = 0;
+
+ int iMainComponentCenterY = (int)Math.round(mainComponent.getLocationOnScreen().getY() + (mainComponent.getHeight() / 2));
+ int iPosY = iMainComponentCenterY - (dependentComponent.getHeight() / 2);
+ if (iPosY < 0) iPosY = 0;
+
+ dependentComponent.setLocation(iPosX, iPosY);
+ }
+
+
+ /**
+ * The parameter is the class name to be processed; class name is likely to be in
+ * the form <class_name>$<integer_value>, where the trailing part starting with
+ * the $ sign indicates the anonymous inner class within the base class. This will
+ * strip out that part of the class name to get the base class name.
+ */
+ public static String getBaseClassName(String strClassName)
+ {
+ // strip out the class name part after the $ sign; return
+ // the original value if the dollar sign wasn't found
+ String strResult = strClassName;
+
+ int iDollarIdx = strResult.indexOf("$");
+ if (iDollarIdx != -1) strResult = strResult.substring(0, iDollarIdx);
+
+ return (strResult);
+ }
+
+
+ /**
+ * Makes sure that the supplied string is no longer than provided length.
+ */
+ public static String ensureStringLength(String str, int iLength) {
+ if (str.length() > iLength) str = str.substring(0, iLength) + " (...)";
+ return (str);
+ }
+
+ /**
+ * Makes sure that the supplied string doesn't have any lines (separated by HTML line break tag) longer
+ * than specified; assumes that there are no line breaks in the source line.
+ *
+ * @param str The string to work with.
+ * @param iLineLength Desired length of each line.
+ * @param bIgnoreBrokenWords True if line breaks are to be inserted exactly each <code>iLineLength</code>
+ * symbols (which will most likely cause broken words); false to insert line breaks
+ * at the first space after <code>iLineLength</code> symbols since last line break.
+ * @return New string with inserted HTML line breaks.
+ */
+ public static String ensureLineLengthWithinString(String str, int iLineLength, boolean bIgnoreBrokenWords)
+ {
+ StringBuilder out = new StringBuilder(str);
+
+ // keep inserting line breaks from end of the line till the beginning until all done
+ int iLineBreakPosition = 0;
+ while (iLineBreakPosition >= 0 && iLineBreakPosition < out.length())
+ {
+ // insert line break either exactly at calculated position or
+ iLineBreakPosition += iLineLength;
+ iLineBreakPosition = (bIgnoreBrokenWords ?
+ iLineBreakPosition :
+ out.indexOf(" ", iLineBreakPosition));
+
+ if (iLineBreakPosition > 0 && iLineBreakPosition < out.length()) {
+ out.insert(iLineBreakPosition, "<br>");
+ iLineBreakPosition += 4; // -- four is the length of "<br>"
+ }
+ }
+
+ return (out.toString());
+ }
+
+
+ /**
+ * This is a convenience method for calling
+ * {@link Util#pluraliseNoun(String, long, boolean)}
+ * with <code>false</code> as a value for third parameter.
+ */
+ public static String pluraliseNoun(String noun, long count) {
+ return (pluraliseNoun(noun, count, false));
+ }
+
+ /**
+ * Performs naive pluralisation of the supplied noun.
+ *
+ * @param noun Noun in a singular form.
+ * @param count Number of occurrences of the item, for which the noun is provided.
+ * @param forceAppendingSByDefault <code>true</code> to make sure that "y" -> "ies"
+ * substitution is <b>not made</b>, but instead "s" is appended
+ * to unmodified root of the noun.
+ * @return Pluralised <code>noun</code>: with appended -s or -y replaced with -ies.
+ */
+ public static String pluraliseNoun(String noun, long count, boolean forceAppendingSByDefault)
+ {
+ if (count % 10 != 1 || count == 11) {
+ if (!forceAppendingSByDefault && noun.endsWith("y")) {
+ return (noun.substring(0, noun.length() - 1) + "ies"); // e.g. ENTRY -> ENTRIES
+ }
+ else {
+ return (noun + "s"); // e.g. SHIP -> SHIPS
+ }
+ }
+ else {
+ // no need to pluralise - count is of the type 21, 31, etc..
+ return noun;
+ }
+ }
+
+
+ /**
+ * Calculates time difference between two {@link Calendar} instances.
+ *
+ * @param earlier The "earlier" date.
+ * @param later The "later" date.
+ * @param maxDifferenceMillis The maximum allowed time difference between the two
+ * {@link Calendar} instances, in milliseconds. If the calculated
+ * difference will exceed <code>maxDifferenceMillis</code>,
+ * <code>null</code> will be returned. If this parameter has
+ * a value <code>less or equal to zero</code>, any time difference
+ * between the {@link Calendar} instances will be permitted.
+ * @return String in the form "XX seconds|minutes|hours|days ago". Proper pluralisation will
+ * be performed on the name of the time unit. <code>null</code> will be returned in
+ * cases where one of the {@link Calendar} instances is <code>null</code>, time
+ * difference between the provided instances is greater than <code>maxDifferenceMillis</code>
+ * or <code>earlier</code> date is not really earlier than <code>later</code> one.
+ */
+ public static String getAgoString(Calendar earlier, Calendar later, long maxDifferenceMillis)
+ {
+ // one of the dates is missing
+ if (earlier == null || later == null) {
+ return null;
+ }
+
+ if (earlier.before(later)) {
+ long differenceMillis = later.getTimeInMillis() - earlier.getTimeInMillis();
+
+ if (maxDifferenceMillis <= 0 || (maxDifferenceMillis > 0 && differenceMillis <= maxDifferenceMillis))
+ {
+ long result = 0;
+ String unitName = "";
+
+ if (differenceMillis < 60 * 1000) {
+ result = differenceMillis / 1000;
+ unitName = "second";
+ }
+ else if (differenceMillis < 60 * 60 * 1000) {
+ result = differenceMillis / (60 * 1000);
+ unitName = "minute";
+ }
+ else if (differenceMillis < 24 * 60 * 60 * 1000) {
+ result = differenceMillis / (60 * 60 * 1000);
+ unitName = "hour";
+ }
+ else {
+ result = differenceMillis / (24 * 60 * 60 * 1000);
+ unitName = "day";
+ }
+
+ return (result + " " + Util.pluraliseNoun(unitName, result, true) + " ago");
+ }
+ else {
+ // the difference is too large - larger than the supplied threshold
+ return null;
+ }
+ }
+ else {
+ // the "later" date is not really later than the "earlier" one
+ return null;
+ }
+ }
+
+
+ /**
+ * Joins the set of tokens in the provided list into a single string.
+ * This method is a shorthand for {@link Util#join(List, String, String, String)}.
+ *
+ * @param tokens List of strings to join.
+ * @param separator Separator to insert between individual strings.
+ * @return String of the form <code>[token1][separator][token2][separator]...[tokenN]</code>
+ */
+ public static String join(List<String> tokens, String separator) {
+ return (join(tokens, null, null, separator));
+ }
+
+ /**
+ * Joins the set of tokens in the provided list into a single string.
+ *
+ * Any empty strings or <code>null</code> entries in the <code>tokens</code> list
+ * will be removed to achieve a better resulting joined string.
+ *
+ * @param tokens List of strings to join.
+ * @param prefix String to prepend to each token.
+ * @param suffix String to append to each token.
+ * @param separator Separator to insert between individual strings.
+ * @return String of the form <code>[prefix][token1][suffix][separator][prefix][token2][suffix][separator]...[prefix][tokenN][suffix]</code>
+ * <br/><br/>
+ * Example: call <code>join(["cat","sat","on","the","mat"], "[", "]", ", ")</code> results in the following output:
+ * <code>"[cat], [sat], [on], [the], [mat]"</code>
+ */
+ public static String join(List<String> tokens, String prefix, String suffix, String separator)
+ {
+ if (tokens == null) {
+ // nothing to join
+ return (null);
+ }
+
+ // list of strings is not empty, but some pre-processing is necessary
+ // to remove any empty strings that may be there
+ for (int i = tokens.size() - 1; i >= 0; i--) {
+ if (tokens.get(i) == null || tokens.get(i).length() == 0) {
+ tokens.remove(i);
+ }
+ }
+
+ // now start the actual processing, but it may be the case that all strings
+ // were empty and we now have an empty list
+ if (tokens.isEmpty()) {
+ // nothing to join - just return an empty string
+ return ("");
+ }
+ else {
+ // there are some tokens -- perform the joining
+ String effectivePrefix = (prefix == null ? "" : prefix);
+ String effectiveSuffix = (suffix == null ? "" : suffix);
+ String effectiveSeparator = (separator == null ? "" : separator);
+
+ StringBuilder result = new StringBuilder();
+ for (int i = 0; i < tokens.size(); i++) {
+ result.append(effectivePrefix + tokens.get(i) + effectiveSuffix);
+ result.append(i == tokens.size() - 1 ? "" : effectiveSeparator);
+ }
+
+ return (result.toString());
+ }
+ }
+
+ /**
+ * Determines whether the plugin is running as a standalone JFrame or inside Taverna Workbench.
+ * This is a naive test, based only on the fact that Taverna uses Raven ApplicationRuntime.
+ */
+ public static boolean isRunningInTaverna()
+ {
+ try {
+ // ApplicationRuntime class is defined within Taverna API. If this is available,
+ // it should mean that the plugin runs within Taverna.
+ ApplicationRuntime.getInstance();
+ return true;
+ }
+ catch (NoClassDefFoundError e) {
+ return false;
+ }
+ }
+
+
+ // === STRIPPING OUT HTML FROM STRINGS ===
+
+ public static String prepareStringForComponent(String source) {
+ return "<html>" + StringEscapeUtils.escapeHtml(source) + "</html>";
+ }
+
+
+ /*
+ * === The following section is providing URL handling methods. ===
+ */
+
+ /**
+ * See: {@link Util#appendStringBeforeParametersOfURL(String, String, boolean)}
+ *
+ * Assumes the last parameter as false, so that the URL encoding will be done.
+ */
+ public static String appendStringBeforeParametersOfURL(String url, String strToAppend) {
+ return (appendStringBeforeParametersOfURL(url, strToAppend, false));
+ }
+
+ /**
+ * Tiny helper to strip out all HTML tags. This will not leave any HTML tags
+ * at all (so that the content can be displayed in DialogTextArea - and the
+ * like - components. This helps to present HTML content inside JAVA easier.
+ */
+ public static String stripAllHTML(String source) {
+ // don't do anything if not string is provided
+ if (source == null)
+ return ("");
+
+ // need to preserve at least all line breaks
+ // (ending and starting paragraph also make a line break)
+ source = source.replaceAll("</p>[\r\n]*<p>", "<br/>");
+ source = source.replaceAll("[\\s]+", " ");
+ source = source.replaceAll("\\<br/?\\>", "\n");
+ source = source.replaceAll("\n ", "\n");
+
+ // strip all HTML
+ source = source.replaceAll("\\<.*?\\>", ""); // any HTML tags
+ source = source.replaceAll("&\\w{1,4};", ""); // this is for things like " ", ">", etc
+
+ return (source);
+ }
+
+
+ /**
+ * Appends given string at the end of the provided URL just before the list of parameters in the url.
+ *
+ * For example, appending ".xml" to URL "http://www.sandbox.biocatalogue.org/services?tag=blast" will
+ * yield "http://www.sandbox.biocatalogue.org/services.xml?tag=blast".
+ *
+ * No duplication checking is made - if the URL is already ending (before parameters) with the value of
+ * the string to append, that string will still be appended.
+ *
+ * @param url URL to append the string to.
+ * @param strToAppend The string to append. The value will be url-encode before appending.
+ * @return New string containing modified <code>url</code> with the <code>strToAppend</code> appended
+ * before the "query string" of the URL.
+ */
+ public static String appendStringBeforeParametersOfURL(String url, String strToAppend, boolean ignoreURLEncoding)
+ {
+ StringBuilder modifiedURL = new StringBuilder(url);
+
+ int iPositionToInsertProvidedString = modifiedURL.indexOf("?");
+ if (iPositionToInsertProvidedString == -1) iPositionToInsertProvidedString = modifiedURL.length();
+
+ String stringToInsert = (ignoreURLEncoding ? strToAppend : Util.urlEncodeQuery(strToAppend));
+ modifiedURL.insert(iPositionToInsertProvidedString, stringToInsert);
+
+ return (modifiedURL.toString());
+ }
+
+
+ /**
+ * This method takes a collection of name-value pairs in the form of a map.
+ * It then adds all parameters from this map to the provided URL.
+ *
+ * If any parameter has the same name as was already present in the URL, the new value
+ * will replace the existing one.
+ *
+ * The implementation of this method is not particularly efficient - it makes a
+ * lot of overhead, but it's fine for non-intensive usage.
+ *
+ * @param url The URL to add a new parameter to.
+ * @param Map of parameters to add to the URL. Keys and values of the map are the names and values for URL parameters.
+ * @return New string which is the original <code>url</code> with all provided
+ * parameters (in the form <code>name</code>=<code>value</code> pair) added to it.
+ */
+ public static String appendAllURLParameters(String url, Map<String,String> parameterMap)
+ {
+ if (parameterMap == null || parameterMap.size() == 0) {
+ // nothing to add, return the same URL
+ return (url);
+ }
+ else {
+ // just call an overloaded method which has the main logic
+ // to do this action for each name-value pair in the map
+ String out = url;
+ for (Map.Entry<String,String> anotherParameter : parameterMap.entrySet()) {
+ out = appendURLParameter(out, anotherParameter);
+ }
+ return (out);
+ }
+ }
+
+
+
+ /**
+ * This method takes a string representation of a URL and a name-value pair
+ * of strings - in the form of Map.Entry instance to add to the URL as a new parameter.
+ *
+ * If parameter with the same name was already present in the URL, the new value
+ * will replace the existing one.
+ *
+ * @param url The URL to add a new parameter to.
+ * @param Map.Entry instance containing the name & the value for the parameter to add.
+ * @return New string which is the original <code>url</code> with the desired
+ * parameter (<code>name</code>=<code>value</code> pair) added to it.
+ */
+ public static String appendURLParameter(String url, Map.Entry<String,String> parameter)
+ {
+ if (parameter == null) {
+ // nothing to add, return the same URL
+ return (url);
+ }
+ else {
+ // just call an overloaded method which has the main logic to do this action
+ return (appendURLParameter(url, parameter.getKey(), parameter.getValue()));
+ }
+ }
+
+
+ /**
+ * This method takes a string representation of a URL and a name-value pair
+ * of strings to add to the URL as a new parameter.
+ *
+ * If parameter with the same name was already present in the URL, the new value
+ * will replace the existing one.
+ *
+ * @param url The URL to add a new parameter to.
+ * @param parameter String array with 2 elements - first element is the name
+ * of the parameter to add, second - the value of the parameter.
+ * @return New string which is the original <code>url</code> with the desired
+ * parameter (<code>name</code>=<code>value</code> pair) added to it.
+ */
+ public static String appendURLParameter(String url, String[] parameter)
+ {
+ if (parameter == null || parameter.length != 2) {
+ // nothing to add, return the same URL
+ return (url);
+ }
+ else {
+ // just call an overloaded method which has the main logic to do this action
+ return (appendURLParameter(url, parameter[0], parameter[1]));
+ }
+ }
+
+
+ /**
+ * This method takes a string representation of a URL and a name-value pair
+ * of strings to add to the URL as a new parameter.
+ *
+ * If parameter with the same name was already present in the URL, the new value
+ * will replace the existing one.
+ *
+ * @param url The URL to add a new parameter to.
+ * @param name Name of the parameter to add.
+ * @param value Value of the parameter to add.
+ * @return New string which is the original <code>url</code> with the desired
+ * parameter (<code>name</code>=<code>value</code> pair) added to it.
+ */
+ public static String appendURLParameter(String url, String name, String value)
+ {
+ // if name of the parameter is not given, ignore this request
+ // (makes sense to return the same URL as the input in this case -
+ // as appending "nothing" wouldn't make it any different)
+ if (name == null || name.length() == 0) {
+ return (url);
+ }
+
+ // do everything in the protected block
+ try
+ {
+ // parse the parameters of the given URL
+ Map<String,String> urlParameters = extractURLParameters(url);
+ if (urlParameters == null) {
+ // there were no parameters in the original URL, create new map
+ urlParameters = new HashMap<String,String>();
+ }
+
+ // add the new parameter (this will replace a parameter with identical
+ // name if it was already present in the map)
+ urlParameters.put(name, value);
+
+ // parse the URL string into the URL object to extract original query string
+ URL theURL = new URL(url);
+ String originalQueryString = theURL.getQuery();
+
+ // prepare the basis for the new URL to return
+ String newUrl = null;
+ if (originalQueryString != null) {
+ // replace the original query string with empty space to
+ // give way for appending the new query string
+ newUrl = url.replace(originalQueryString, "");
+ }
+ else {
+ // there were no parameters in the original URL
+ newUrl = url + "?";
+ }
+
+ // append the new query string
+ newUrl += constructURLQueryString(urlParameters);
+
+ return (newUrl);
+ }
+ catch (Exception e)
+ {
+ logger.error("\nCouldn't append parameter ('" + name + "', '" + value + "') to the URL: " + url, e);
+ return (null);
+ }
+ }
+
+
+ /**
+ * Extracts a value of a specific parameter from the supplied URL.
+ *
+ * @param url The URL to extract the parameter from.
+ * @param parameterName Name of the URL parameter to extract the value for.
+ * @return Value of the parameter with <code>parameterName</code> in the given <code>url</code>.
+ * If the parameter with specified name is not found in the given <code>url</code>,
+ * <code>null</code> is returned instead.
+ */
+ public static String extractURLParameter(String url, String parameterName)
+ {
+ // both URL and the name of the required parameter must be supplied
+ if (url == null || url.length() == 0 || parameterName == null || parameterName.length() == 0) return null;
+
+ Map<String,String> urlParameters = extractURLParameters(url);
+ if (urlParameters != null) {
+ // the URL has some parameters; check what's the value of the desired parameter
+ return (urlParameters.get(parameterName));
+ }
+ else {
+ // the URL doesn't contain any parameters
+ return (null);
+ }
+ }
+
+
+ /**
+ * Extracts the query string from the provided URL. Parses this query string into
+ * a map of parameters.
+ *
+ * All parameters (both names and values) will have special characters unescaped
+ * (i.e. decoded from the standard url-encoding) and can be used directly.
+ *
+ * @param url The string representation of the URL to parse.
+ */
+ public static Map<String,String> extractURLParameters(String url)
+ {
+ try {
+ // extract the query part of the supplied URL
+ URL theURL = new URL(url);
+ String queryString = theURL.getQuery();
+
+ // prepare storage for output
+ Map<String,String> parameterMap = null;
+
+ // extract each name-value pair from query string (if any are specified in the URL)
+ if (queryString != null && queryString.length() > 0)
+ {
+ // only initialise if there are some parameters
+ parameterMap = new HashMap<String,String>();
+
+ for (String parameter : queryString.split("&")) {
+ String[] nameValueArr = parameter.split("=");
+
+ String name = nameValueArr[0]; // parameter name must always be present
+ String value = (nameValueArr.length == 2 ? nameValueArr[1] : null); // could be that parameter value is not set (e.g. "q=") - insert null then
+
+ // decode possible special characters
+ name = urlDecodeQuery(name);
+ if (value != null) value = urlDecodeQuery(value);
+
+ parameterMap.put(name, value);
+ }
+ }
+
+ return (parameterMap);
+ }
+ catch (MalformedURLException e)
+ {
+ // some problem occurred - report it; can't return any data in this case
+ logger.error("Couldn't parse parameters of a URL: " + url + "; details below:", e);
+ return null;
+ }
+ }
+
+
+ /**
+ * This method is the opposite for <code>extractURLParameters(String url)</code>.
+ * It takes a map of parameters, performs URL-encoding of each and assembles them
+ * into a query string.
+ *
+ * The query string then can be added to the <code>URL</code> object by using standard
+ * Java API.
+ *
+ * @param urlParameters Map of parameters to use in query string construction.
+ * @return URL-encoded query string.
+ */
+ public static String constructURLQueryString(Map<String,String> urlParameters)
+ {
+ if (urlParameters != null) {
+ StringBuilder queryString = new StringBuilder();
+
+ // iterate through all parameters and reconstruct the query string
+ for (Map.Entry<String,String> parameter : urlParameters.entrySet())
+ {
+ if (queryString.length() > 0) queryString.append("&"); // parameter separator
+ queryString.append(urlEncodeQuery(parameter.getKey()) + "=" + urlEncodeQuery(parameter.getValue()));
+ }
+
+ return (queryString.toString());
+ }
+ else {
+ return (null);
+ }
+ }
+
+
+ /**
+ * Prepares the string to serve as a part of url query to the server.
+ * @param query The string that needs URL encoding.
+ * @return URL encoded string that can be inserted into the request URL.
+ */
+ public static String urlEncodeQuery(String query)
+ {
+ // "fast exit" - if null supplied, just return an empty string;
+ // this is because in the URLs we have "q=", rather than "q=null" - this will cater for such cases
+ if (query == null) return ("");
+
+ // encode the query
+ String strRes = "";
+ try {
+ strRes = URLEncoder.encode(query, "UTF-8");
+ }
+ catch (UnsupportedEncodingException e) {
+ // do nothing
+ }
+
+ return (strRes);
+ }
+
+
+ /**
+ * Decodes a string which came as a part of of URL (e.g. a URL parameter). This converts
+ * codes of escaped special characters back into those special characters.
+ *
+ * @param query The string that needs URL decoded.
+ * @return Decoded string that will contain all the special characters.
+ */
+ public static String urlDecodeQuery(String query)
+ {
+ String strRes = "";
+
+ try {
+ strRes = URLDecoder.decode(query, "UTF-8");
+ }
+ catch (UnsupportedEncodingException e) {
+ // do nothing
+ }
+
+ return (strRes);
+ }
+
+
+ /**
+ * This method is "clones" an object supplied as an argument. It uses
+ * serialisation to achieve this (as opposed to manually implementing deep
+ * copying of all referenced objects in the graph of the provided object).
+ * This technique is used to make sure that the new object will be exact
+ * replica, but totally independent of the original one.
+ *
+ * Note that this code works ~100 times slower than it would do if deep copying
+ * was implemented. However, this will not be used in tight loops (and in loops
+ * at all), so for one-off tasks it is fine.
+ *
+ * @author Dave Miller<br/>
+ * Original version of the code in this method is taken from
+ * <a href="http://www.javaworld.com/javaworld/javatips/jw-javatip76.html?page=2">
+ * http://www.javaworld.com/javaworld/javatips/jw-javatip76.html?page=2
+ * </a> [accessed on 25/Feb/2010].
+ * <br/><br/>
+ *
+ * @author Subhajit Dasgupta<br/>
+ * Example of using an alternative class loader during object de-serialisation
+ * was taken from
+ * <a href="http://blogs.sun.com/adventures/entry/desrializing_objects_custom_class_loaders">
+ * http://blogs.sun.com/adventures/entry/desrializing_objects_custom_class_loaders
+ * </a> [accessed on 29/Mar/2010].
+ *
+ * @return Deep copy of the provided object. If deep copying doesn't succeed,
+ * <code>null</code> is returned.
+ */
+ public static Object deepCopy(Object objectToCopy)
+ {
+ // a "safety net" - a class loader of BioCatalogue perspective may be used in
+ // de-serialisation process to make sure that all classes are recognised
+ // (system class loader may not be able to "see" all BioCatalogue plugin's files,
+ // but just those in Taverna's /lib folder)
+ final ClassLoader[] customClassLoaders = new ClassLoader[] { BioCataloguePerspective.class.getClassLoader() };
+
+ try
+ {
+ ObjectOutputStream oos = null;
+ ObjectInputStream ois = null;
+ try
+ {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ oos = new ObjectOutputStream(bos);
+
+ // serialise and pass the object
+ oos.writeObject(objectToCopy);
+ oos.flush();
+
+ // read and return the new object
+ ByteArrayInputStream bin = new ByteArrayInputStream(bos.toByteArray());
+ ois = new ObjectInputStream(bin) {
+ /**
+ * <code>resolveClass()</code> method is overridden to make use of
+ * custom ClassLoader in the de-serialisation process.
+ * <br/>
+ * This is needed to make sure that the ClassLoader of the BioCatalogue
+ * perspective is used as opposed to the system ClassLoader which will
+ * only be able to see classes from Taverna's /lib folder.
+ */
+ protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException
+ {
+ String className = desc.getName();
+ try {
+ // attempt to use default class loader
+ return Class.forName(className);
+ }
+ catch (ClassNotFoundException exc)
+ {
+ // default class loader was unable to locate a required class -
+ // attempt to use one of the provided class loaders
+ for (ClassLoader cl : customClassLoaders) {
+ try {
+ return cl.loadClass(className);
+ }
+ catch (ClassNotFoundException e) {
+ /* do nothing here - there may be other class loaders to try */
+ }
+ }
+ // none of the class loaders was able to recognise the currently
+ // de-serialised class, so it's indeed an exception
+ throw new ClassNotFoundException(className +
+ " -- neither system, nor alternative class loaders were able to load this class");
+ }
+ }
+ };
+ return ois.readObject();
+ }
+ catch(Exception e)
+ {
+ logger.error("Could not perform deep copy of " + objectToCopy.getClass() + " instance", e);
+ }
+ finally
+ {
+ oos.close();
+ ois.close();
+ }
+ }
+ catch (Exception e) {
+ logger.error("Could not close object streams during deep copy of " + objectToCopy.getClass() + " instance");
+ }
+
+ // Error occurred - couldn't produce the deep copy...
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/connectivity/BeanForPOSTToFilteredIndex.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/connectivity/BeanForPOSTToFilteredIndex.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/connectivity/BeanForPOSTToFilteredIndex.java
new file mode 100644
index 0000000..d879377
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/connectivity/BeanForPOSTToFilteredIndex.java
@@ -0,0 +1,12 @@
+package net.sf.taverna.biocatalogue.model.connectivity;
+
+import java.util.Map;
+
+/**
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class BeanForPOSTToFilteredIndex
+{
+ public Map<String, String[]> filters;
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/connectivity/BeansForJSONLiteAPI.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/connectivity/BeansForJSONLiteAPI.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/connectivity/BeansForJSONLiteAPI.java
new file mode 100644
index 0000000..ea3b391
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/connectivity/BeansForJSONLiteAPI.java
@@ -0,0 +1,84 @@
+package net.sf.taverna.biocatalogue.model.connectivity;
+
+
+/**
+ * Binding beans for GSON library to instantiate objects
+ * from JSON data obtained from the 'Lite' version of the
+ * BioCatalogue JSON API.
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class BeansForJSONLiteAPI
+{
+
+ public static abstract class ResourceIndex
+ {
+ public ResourceIndex() { }
+ public abstract ResourceLinkWithName[] getResources();
+ }
+
+
+ public static class SOAPOperationsIndex extends ResourceIndex {
+ public SOAPOperationsIndex() { }
+ public ResourceLinkWithName[] soap_operations;
+
+ public ResourceLinkWithName[] getResources() {
+ return soap_operations;
+ }
+ }
+
+ public static class RESTMethodsIndex extends ResourceIndex {
+ public RESTMethodsIndex() { }
+ public ResourceLinkWithName[] rest_methods;
+
+ public ResourceLinkWithName[] getResources() {
+ return rest_methods;
+ }
+ }
+
+ public static class ServicesIndex extends ResourceIndex {
+ public ServicesIndex() { }
+ public ResourceLinkWithName[] services;
+
+ public ResourceLinkWithName[] getResources() {
+ return services;
+ }
+ }
+
+ public static class ServiceProvidersIndex extends ResourceIndex {
+ public ServiceProvidersIndex() { }
+ public ResourceLinkWithName[] service_providers;
+
+ public ResourceLinkWithName[] getResources() {
+ return service_providers;
+ }
+ }
+
+ public static class UsersIndex extends ResourceIndex {
+ public UsersIndex() { }
+ public ResourceLinkWithName[] users;
+
+ public ResourceLinkWithName[] getResources() {
+ return users;
+ }
+ }
+
+
+
+ public static class ResourceLinkWithName
+ {
+ private ResourceLinkWithName() { }
+
+ private String resource;
+ private String name;
+
+ public String getURL() {
+ return (this.resource);
+ }
+
+ public String getName() {
+ return (this.name);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/connectivity/BioCatalogueAPIRequest.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/connectivity/BioCatalogueAPIRequest.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/connectivity/BioCatalogueAPIRequest.java
new file mode 100644
index 0000000..ea55a77
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/connectivity/BioCatalogueAPIRequest.java
@@ -0,0 +1,47 @@
+package net.sf.taverna.biocatalogue.model.connectivity;
+
+/**
+ * A class to wrap BioCatalogue API requests - will include
+ * the type (GET, POST, etc), URL and the data to send
+ * if that's a POST / PUT request.
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class BioCatalogueAPIRequest
+{
+ public static enum TYPE {
+ GET,
+ POST,
+ PUT,
+ DELETE
+ }
+
+
+ private TYPE requestType;
+ private String url;
+ private String data;
+
+
+ public BioCatalogueAPIRequest(TYPE requestType, String url, String data) {
+ this.requestType = requestType;
+ this.url = url;
+ this.data = data;
+ }
+
+
+ public TYPE getRequestType() {
+ return requestType;
+ }
+
+ public String getURL(){
+ return url;
+ }
+ public void setURL(String url) {
+ this.url = url;
+ }
+
+ public String getData(){
+ return data;
+ }
+
+}