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:36 UTC
[13/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/search/ServiceFilteringSettings.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/search/ServiceFilteringSettings.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/search/ServiceFilteringSettings.java
new file mode 100644
index 0000000..76d4eca
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/model/search/ServiceFilteringSettings.java
@@ -0,0 +1,184 @@
+package net.sf.taverna.biocatalogue.model.search;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.tree.TreePath;
+
+import net.sf.taverna.biocatalogue.model.Util;
+import net.sf.taverna.biocatalogue.ui.filtertree.FilterTreeNode;
+import net.sf.taverna.biocatalogue.ui.tristatetree.JTriStateTree;
+
+/**
+ * This class provides functionality to deal with service filtering settings.
+ * Particularly used to save the current state of the filtering tree as a
+ * favourite filter.
+ *
+ * Instances of this class hold all necessary information to restore the
+ * filtering state at a later point.
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class ServiceFilteringSettings implements Comparable<ServiceFilteringSettings>, Serializable
+{
+ private static final long serialVersionUID = -5706169924295062628L;
+
+ private String filterName;
+ private int filteringCriteriaNumber;
+ private List<TreePath> filterTreeRootsOfCheckedPaths;
+
+
+
+ /**
+ * Stores current filtering selection in the provided JTriStateTree
+ * instance into the instance of this class.
+ *
+ * @param filterTree The JTriStateTree instance to get the current selection from.
+ */
+ public ServiceFilteringSettings(JTriStateTree filterTree)
+ {
+ this(null, filterTree);
+ }
+
+
+ /**
+ * Stores current filtering selection in the provided JTriStateTree
+ * instance into the instance of this class.
+ *
+ * @param filterName The name to associate with this filter.
+ * @param filterTree The JTriStateTree instance to get the current selection from.
+ */
+ @SuppressWarnings("unchecked")
+ public ServiceFilteringSettings(String filterName, JTriStateTree filterTree)
+ {
+ this.filterName = filterName;
+
+ this.filteringCriteriaNumber = filterTree.getLeavesOfCheckedPaths().size();
+
+ // a deep copy of the data from the filter tree is created, so that the data stored in this instance
+ // is fully independent of the filter tree itself; therefore local copy of this data may be modified
+ // as needed and will not affect the main filter (and vice versa)
+ this.filterTreeRootsOfCheckedPaths = (List<TreePath>)Util.deepCopy(filterTree.getRootsOfCheckedPaths());
+ }
+
+
+ /**
+ * Analyses the filter tree and produces part of the request URL containing settings regarding filters.
+ */
+ @SuppressWarnings("unchecked")
+ public Map<String,String[]> getFilteringURLParameters()
+ {
+ // analyse filter tree to get checked elements
+ Map<String,HashSet<String>> selections = new HashMap<String,HashSet<String>>();
+
+ // cycle through the deepest selected nodes;
+ // NB! the CheckboxTree acts in a way that if A contains B,C --
+ // 1) if only B is checked, tp.getLastPathComponent() will be B;
+ // 2) if both B,C are checked, tp.getLastPathComponent() will be A;
+ for (TreePath selectedRootNodePath : getFilterTreeRootsOfCheckedPaths()) {
+ FilterTreeNode selectedNode = (FilterTreeNode)selectedRootNodePath.getLastPathComponent();
+
+ // identify affected nodes
+ HashSet<FilterTreeNode> affectedNodes = new HashSet<FilterTreeNode>();
+ if (selectedNode.isFilterCategory()) {
+ // case as in example 2) -- need to "extract" nodes that are one level deeper
+ for (Enumeration children = selectedNode.children(); children.hasMoreElements(); ) {
+ affectedNodes.add((FilterTreeNode)children.nextElement());
+ }
+ }
+ else {
+ // case as in example 1)
+ affectedNodes.add(selectedNode);
+ }
+
+ // walk through the identified collection of nodes and build the data structure with URL values
+ for (FilterTreeNode node : affectedNodes) {
+ if (selections.containsKey(node.getType())) {
+ selections.get(node.getType()).add(node.getUrlValue());
+ }
+ else {
+ HashSet<String> newSet = new HashSet<String>();
+ newSet.add(node.getUrlValue());
+
+ selections.put(node.getType(), newSet);
+ }
+ }
+ }
+
+
+ // now use the constructed set of data to build the map of filtering URL parameters
+ Map<String,String[]> filterUrlParameters = new HashMap<String,String[]>();
+ for(String key : selections.keySet())
+ {
+ List<String> categoryValues = new ArrayList<String>();
+ for (String value : selections.get(key)) {
+ categoryValues.add(value);
+ }
+
+ filterUrlParameters.put(key, categoryValues.toArray(new String[0]));
+ }
+
+ return (filterUrlParameters);
+ }
+
+
+ // *** Getters ***
+
+ public String getFilterName() {
+ return (this.filterName == null || filterName.length() == 0 ? "untitled filter" : this.filterName);
+ }
+
+ public List<TreePath> getFilterTreeRootsOfCheckedPaths() {
+ return filterTreeRootsOfCheckedPaths;
+ }
+
+ /**
+ * @return Number of filtering criteria within the current filter.
+ */
+ public int getNumberOfFilteringCriteria() {
+ return filteringCriteriaNumber;
+ }
+
+ // *** End of getters ***
+
+
+ public boolean equals(Object other)
+ {
+ if (other instanceof ServiceFilteringSettings)
+ {
+ ServiceFilteringSettings o = (ServiceFilteringSettings)other;
+ return (this.filterName.equals(o.filterName) &&
+ this.filterTreeRootsOfCheckedPaths.equals(o.filterTreeRootsOfCheckedPaths));
+ }
+ else {
+ return false;
+ }
+ }
+
+
+ public int compareTo(ServiceFilteringSettings other)
+ {
+ int iOrdering = this.filterName.compareTo(other.filterName);
+ if (iOrdering == 0) {
+ iOrdering = this.getNumberOfFilteringCriteria() - other.getNumberOfFilteringCriteria();
+ }
+
+ // inverse order, as the traversal of lists in the favourite filters panel is
+ // done this way round
+ return (-1 * iOrdering);
+ }
+
+
+ public String toString() {
+ return ("Filter: '" + getFilterName() + "' [" + detailsAsString() + "]");
+ }
+
+ public String detailsAsString() {
+ return (getNumberOfFilteringCriteria() + " filtering criteria");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/AnnotationBean.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/AnnotationBean.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/AnnotationBean.java
new file mode 100644
index 0000000..81ce849
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/AnnotationBean.java
@@ -0,0 +1,52 @@
+package net.sf.taverna.biocatalogue.test;
+
+
+public class AnnotationBean
+{
+ public AnnotationBean() { }
+
+ public String self;
+ private int version;
+ private String created;
+ public Annotatable annotatable;
+ private Source source;
+ private Attribute attribute;
+ private Value value;
+
+
+ public static class Annotatable
+ {
+ private Annotatable() { }
+
+ private String name;
+ public String resource;
+ private String type;
+ }
+
+ public static class Source
+ {
+ private Source() { }
+
+ private String name;
+ private String resource;
+ private String type;
+ }
+
+ public static class Attribute
+ {
+ private Attribute() { }
+
+ private String name;
+ private String resource;
+ private String identifier;
+ }
+
+ public static class Value
+ {
+ private Value() { }
+
+ private String resource;
+ private String type;
+ private String content;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/DrawDefaultIconTest.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/DrawDefaultIconTest.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/DrawDefaultIconTest.java
new file mode 100644
index 0000000..1bec9e6
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/DrawDefaultIconTest.java
@@ -0,0 +1,38 @@
+package net.sf.taverna.biocatalogue.test;
+
+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 javax.swing.ImageIcon;
+import javax.swing.JOptionPane;
+
+public class DrawDefaultIconTest {
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args)
+ {
+ 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();
+
+ JOptionPane.showMessageDialog(null, 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/test/GSONTest.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/GSONTest.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/GSONTest.java
new file mode 100644
index 0000000..eba01d6
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/GSONTest.java
@@ -0,0 +1,19 @@
+package net.sf.taverna.biocatalogue.test;
+
+import com.google.gson.Gson;
+
+public class GSONTest
+{
+
+ public static void main(String[] args) throws Exception
+ {
+ String json = "[{\"annotatable\":{\"name\":\"IndexerService\",\"resource\":\"http://sandbox.biocatalogue.org/services/2158\",\"type\":\"Service\"},\"self\":\"http://sandbox.biocatalogue.org/annotations/47473\",\"value\":{\"resource\":\"http://sandbox.biocatalogue.org/tags/indexing\",\"type\":\"Tag\",\"content\":\"indexing\"},\"version\":1,\"created\":\"2010-01-13T09:24:04Z\",\"source\":{\"name\":\"Marco Roos\",\"resource\":\"http://sandbox.biocatalogue.org/users/48\",\"type\":\"User\"},\"attribute\":{\"name\":\"Tag\",\"resource\":\"http://sandbox.biocatalogue.org/annotation_attributes/2\",\"identifier\":\"http://www.biocatalogue.org/attribute#Category\"}}]";
+
+ Gson gson = new Gson();
+ AnnotationBean[] a = gson.fromJson(json, AnnotationBean[].class);
+
+ System.out.println("Self URL: " + a[0].self);
+ System.out.println("Annotatable resource: " + a[0].annotatable.resource);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/GSONTest_exportingJSON.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/GSONTest_exportingJSON.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/GSONTest_exportingJSON.java
new file mode 100644
index 0000000..6e63ebb
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/GSONTest_exportingJSON.java
@@ -0,0 +1,30 @@
+package net.sf.taverna.biocatalogue.test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.taverna.biocatalogue.model.connectivity.BeanForPOSTToFilteredIndex;
+
+import com.google.gson.Gson;
+
+public class GSONTest_exportingJSON
+{
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args)
+ {
+ Map<String, String[]> m = new HashMap<String, String[]>();
+ m.put("a", new String[] {"b","c"});
+ m.put("d", new String[] {"e","f"});
+
+ BeanForPOSTToFilteredIndex b = new BeanForPOSTToFilteredIndex();
+ b.filters = m;
+
+ Gson gson = new Gson();
+ System.out.println(gson.toJson(b));
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/GSONTest_forSoapOperationsIndex.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/GSONTest_forSoapOperationsIndex.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/GSONTest_forSoapOperationsIndex.java
new file mode 100644
index 0000000..30035f7
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/GSONTest_forSoapOperationsIndex.java
@@ -0,0 +1,27 @@
+package net.sf.taverna.biocatalogue.test;
+
+import net.sf.taverna.biocatalogue.model.Resource;
+import net.sf.taverna.biocatalogue.model.connectivity.BeansForJSONLiteAPI;
+import net.sf.taverna.biocatalogue.model.connectivity.BioCatalogueClient;
+
+public class GSONTest_forSoapOperationsIndex
+{
+
+ /**
+ * @param args
+ * @throws Exception
+ */
+ public static void main(String[] args) throws Exception
+ {
+ BioCatalogueClient client = BioCatalogueClient.getInstance();
+
+ String url = BioCatalogueClient.API_SOAP_OPERATIONS_URL;
+// url = Util.appendURLParameter(url, "q", "blast");
+ BeansForJSONLiteAPI.ResourceIndex soapOpIndex = client.getBioCatalogueResourceLiteIndex(Resource.TYPE.SOAPOperation, url);
+
+ System.out.println("result count: " + soapOpIndex.getResources().length + "\n\n");
+// System.out.println(soapOpIndex.soap_operations[1].getName() + "\n" + soapOpIndex.soap_operations[1].getURL() + "\n\n");
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/JWaitDialogTest.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/JWaitDialogTest.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/JWaitDialogTest.java
new file mode 100644
index 0000000..2aed586
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/JWaitDialogTest.java
@@ -0,0 +1,36 @@
+package net.sf.taverna.biocatalogue.test;
+
+import net.sf.taverna.biocatalogue.ui.JWaitDialog;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.MainComponent;
+
+public class JWaitDialogTest
+{
+
+ public static void main(String[] args)
+ {
+ System.out.println("start test");
+
+ final JWaitDialog jwd = new JWaitDialog(MainComponent.dummyOwnerJFrame, "Old title", "Please wait... Please wait... Please wait... Please wait...");
+
+ // NB! Background process must be started before the modal dialog box
+ // is made visible - otherwise processing freezes.
+ new Thread("testing delayed update of JWaitDialog")
+ {
+ public void run()
+ {
+ // wait for some time
+ try { Thread.sleep(3000); }
+ catch (InterruptedException e) { /* do nothing */ }
+
+ // update the dialog
+ jwd.setTitle("New title");
+ jwd.waitFinished("Great, all done!");
+
+ System.out.println("end test");
+ }
+ }.start();
+
+ jwd.setVisible(true);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/LinkedListEqualsTest.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/LinkedListEqualsTest.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/LinkedListEqualsTest.java
new file mode 100644
index 0000000..6f252bd
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/LinkedListEqualsTest.java
@@ -0,0 +1,25 @@
+package net.sf.taverna.biocatalogue.test;
+
+import java.util.LinkedList;
+
+public class LinkedListEqualsTest
+{
+ public static void main(String[] args)
+ {
+ LinkedList l = new LinkedList();
+
+ String a = new String("test1");
+ String b = new String("test2");
+
+ System.out.println(a == b);
+ System.out.println(a.equals(b));
+
+ l.add(a);
+ l.add(b);
+
+ System.out.println(l);
+ System.out.println(l.indexOf(a));
+ System.out.println(l.indexOf(b));
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/TestAPICaller.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/TestAPICaller.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/TestAPICaller.java
new file mode 100644
index 0000000..a48a996
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/TestAPICaller.java
@@ -0,0 +1,241 @@
+package net.sf.taverna.biocatalogue.test;
+
+import javax.swing.JFrame;
+import java.awt.Dimension;
+import javax.swing.JPanel;
+import java.awt.BorderLayout;
+import javax.swing.JTextField;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JOptionPane;
+import javax.swing.JTextPane;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+
+import net.sf.taverna.biocatalogue.model.connectivity.BioCatalogueClient;
+
+import java.awt.GridBagLayout;
+import java.awt.GridBagConstraints;
+import java.awt.Insets;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * @author Sergejs Aleksejevs
+ */
+public class TestAPICaller extends JFrame implements ActionListener {
+
+ private JPanel jContentPane = null;
+ private JTextField tfURL = null;
+ private JButton bSubmitRequest = null;
+ private JButton bClear = null;
+ private JScrollPane spOutputPane = null;
+ private JTextPane tpOutputPane = null;
+
+ /**
+ * This method initializes
+ *
+ */
+ public TestAPICaller() {
+ super();
+ initialize();
+ }
+
+ /**
+ * This method initializes this
+ *
+ */
+ private void initialize() {
+ this.setSize(new Dimension(515, 321));
+ this.setTitle("Test Service Catalogue API Caller");
+ this.setContentPane(getJContentPane());
+
+ this.bSubmitRequest.setDefaultCapable(true);
+ this.getRootPane().setDefaultButton(bSubmitRequest);
+ }
+
+ /**
+ * This method initializes jContentPane
+ *
+ * @return javax.swing.JPanel
+ */
+ private JPanel getJContentPane() {
+ if (jContentPane == null) {
+ GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
+ gridBagConstraints3.fill = GridBagConstraints.BOTH;
+ gridBagConstraints3.gridwidth = 2;
+ gridBagConstraints3.gridx = 0;
+ gridBagConstraints3.gridy = 2;
+ gridBagConstraints3.ipadx = 459;
+ gridBagConstraints3.ipady = 182;
+ gridBagConstraints3.weightx = 1.0;
+ gridBagConstraints3.weighty = 1.0;
+ gridBagConstraints3.insets = new Insets(4, 12, 9, 12);
+ GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
+ gridBagConstraints2.fill = GridBagConstraints.HORIZONTAL;
+ gridBagConstraints2.gridy = 1;
+ gridBagConstraints2.ipadx = 0;
+ gridBagConstraints2.ipady = 0;
+ gridBagConstraints2.insets = new Insets(0, 5, 7, 12);
+ gridBagConstraints2.weightx = 0.5;
+ gridBagConstraints2.gridx = 1;
+ GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
+ gridBagConstraints1.fill = GridBagConstraints.HORIZONTAL;
+ gridBagConstraints1.gridy = 1;
+ gridBagConstraints1.ipadx = 0;
+ gridBagConstraints1.ipady = 0;
+ gridBagConstraints1.insets = new Insets(0, 12, 7, 5);
+ gridBagConstraints1.weightx = 0.5;
+ gridBagConstraints1.gridx = 0;
+ GridBagConstraints gridBagConstraints = new GridBagConstraints();
+ gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.gridwidth = 2;
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.ipadx = 466;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.ipady = 3;
+ gridBagConstraints.insets = new Insets(13, 12, 8, 12);
+ jContentPane = new JPanel();
+ jContentPane.setLayout(new GridBagLayout());
+ jContentPane.add(getTfURL(), gridBagConstraints);
+ jContentPane.add(getBSubmitRequest(), gridBagConstraints1);
+ jContentPane.add(getBClear(), gridBagConstraints2);
+ jContentPane.add(getSpOutputPane(), gridBagConstraints3);
+ }
+ return jContentPane;
+ }
+
+ /**
+ * This method initializes tfURL
+ *
+ * @return javax.swing.JTextField
+ */
+ private JTextField getTfURL() {
+ if (tfURL == null) {
+ tfURL = new JTextField();
+ tfURL.setText(BioCatalogueClient.DEFAULT_API_SANDBOX_BASE_URL);
+ }
+ return tfURL;
+ }
+
+ /**
+ * This method initializes tfSubmitRequest
+ *
+ * @return javax.swing.JButton
+ */
+ private JButton getBSubmitRequest() {
+ if (bSubmitRequest == null) {
+ bSubmitRequest = new JButton();
+ bSubmitRequest.setText("Submit Request");
+ bSubmitRequest.addActionListener(this);
+ }
+ return bSubmitRequest;
+ }
+
+
+ /**
+ * This method initializes bClear
+ *
+ * @return javax.swing.JButton
+ */
+ private JButton getBClear() {
+ if (bClear == null) {
+ bClear = new JButton();
+ bClear.setText("Clear Output");
+ bClear.addActionListener(this);
+ }
+ return bClear;
+ }
+
+
+ /**
+ * This method initializes tpOutputPane
+ *
+ * @return javax.swing.JTextPane
+ */
+ private JTextPane getTpOutputPane() {
+ if (tpOutputPane == null) {
+ tpOutputPane = new JTextPane();
+ tpOutputPane.setContentType("text/plain");
+ }
+ return tpOutputPane;
+ }
+
+
+ /**
+ * This method initializes spOutputPane
+ *
+ * @return javax.swing.JScrollPane
+ */
+ private JScrollPane getSpOutputPane() {
+ if (spOutputPane == null) {
+ spOutputPane = new JScrollPane();
+ spOutputPane.setViewportView(getTpOutputPane());
+ }
+ return spOutputPane;
+ }
+
+
+ // ACTION LISTENER
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(bSubmitRequest)) {
+ tfURL.selectAll();
+
+ // call the actual test method
+ runBioCatalogueAPITest(tfURL.getText());
+ }
+ else if (e.getSource().equals(bClear)) {
+ this.tpOutputPane.setText("");
+ }
+
+ }
+
+
+ // ACTUAL TEST CLASS
+
+ private void runBioCatalogueAPITest(String url) {
+ final String urlFinal = url;
+ new Thread("making request") {
+ public void run() {
+ tpOutputPane.setText("Initialising Service Catalogue client...");
+ BioCatalogueClient client = null;
+ try {
+ client = BioCatalogueClient.getInstance();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ final StringBuilder text = new StringBuilder();
+ try {
+ tpOutputPane.setText("Sending request...");
+ BufferedReader br = new BufferedReader(new InputStreamReader(client.doBioCatalogueGET(urlFinal).getResponseStream()));
+ String str = "";
+
+ while ((str = br.readLine()) != null) {
+ text.append(str + "\n");
+ }
+
+ br.close();
+ }
+ catch (Exception e) {
+ text.append(e);
+ }
+
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ tpOutputPane.setText(text.toString());
+ }
+ });
+ }
+ }.start();
+
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/TestDoubleUsageOfSameSwingElement.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/TestDoubleUsageOfSameSwingElement.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/TestDoubleUsageOfSameSwingElement.java
new file mode 100644
index 0000000..e5ad39c
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/TestDoubleUsageOfSameSwingElement.java
@@ -0,0 +1,32 @@
+package net.sf.taverna.biocatalogue.test;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JFrame;
+
+public class TestDoubleUsageOfSameSwingElement extends JFrame
+{
+ private String text = "abc";
+ boolean bLowerCase = true;
+
+ public TestDoubleUsageOfSameSwingElement()
+ {
+ final JButton bBtn = new JButton(text);
+ bBtn.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ bLowerCase = !bLowerCase;
+ bBtn.setText(bLowerCase ? text.toLowerCase() : text.toUpperCase());
+ }
+ });
+
+ this.setLayout(new BorderLayout());
+ this.add(bBtn, BorderLayout.WEST);
+ this.add(bBtn, BorderLayout.EAST);
+
+ this.pack();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/TestUtilURLHandling.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/TestUtilURLHandling.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/TestUtilURLHandling.java
new file mode 100644
index 0000000..71a6ca7
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/TestUtilURLHandling.java
@@ -0,0 +1,87 @@
+package net.sf.taverna.biocatalogue.test;
+
+import net.sf.taverna.biocatalogue.model.Util;
+
+public class TestUtilURLHandling
+{
+ public static void main(String[] args)
+ {
+ String url1 = "http://sandbox.biocatalogue.org/search";
+ String url2 = "http://sandbox.biocatalogue.org/search?";
+ String url3 = "http://sandbox.biocatalogue.org/search?q=";
+ String url4 = "http://sandbox.biocatalogue.org/search?q=franck";
+ String url5 = "http://sandbox.biocatalogue.org/services?tag=%5Bbiology%5D";
+ String url6 = "http://sandbox.biocatalogue.org/services?tag=%5B%3Chttp%3A%2F%2Fwww.mygrid.org.uk%2Fontology%23DDBJ%3E%5D";
+
+
+ System.out.println("----------------------------");
+ System.out.println("Extracting URL parameters:\n");
+
+
+ System.out.println(url1 + "\nParameter map:\n" + Util.extractURLParameters(url1));
+ System.out.println("Reconstructed query string from parameter map: " + Util.constructURLQueryString(Util.extractURLParameters(url1)) + "\n");
+
+
+ System.out.println(url2 + "\nParameter map:\n" + Util.extractURLParameters(url2));
+ System.out.println("Reconstructed query string from parameter map: " + Util.constructURLQueryString(Util.extractURLParameters(url2)) + "\n");
+
+
+ System.out.println(url3 + "\nParameter map:\n" + Util.extractURLParameters(url3));
+ System.out.println("Reconstructed query string from parameter map: " + Util.constructURLQueryString(Util.extractURLParameters(url3)) + "\n");
+
+
+ System.out.println(url4 + "\nParameter map:\n" + Util.extractURLParameters(url4));
+ System.out.println("Reconstructed query string from parameter map: " + Util.constructURLQueryString(Util.extractURLParameters(url4)) + "\n");
+
+
+ System.out.println(url5 + "\nParameter map:\n" + Util.extractURLParameters(url5));
+ System.out.println("Reconstructed query string from parameter map: " + Util.constructURLQueryString(Util.extractURLParameters(url5)) + "\n");
+
+
+ System.out.println("\n\n----------------------------");
+ System.out.println("Adding parameters:\n");
+
+ String newUrl = Util.appendURLParameter(url1, "testParam", "testValue");
+ System.out.println(url1 + "\n" + newUrl + "\n");
+
+ newUrl = Util.appendURLParameter(url2, "testParam", "testValue");
+ System.out.println(url2 + "\n" + newUrl + "\n");
+
+ newUrl = Util.appendURLParameter(url3, "testParam", "testValue");
+ System.out.println(url3 + "\n" + newUrl + "\n");
+
+ newUrl = Util.appendURLParameter(url4, "testParam", "testValue");
+ System.out.println(url4 + "\n" + newUrl + "\n");
+
+ newUrl = Util.appendURLParameter(url5, "testParam", "testValue");
+ System.out.println(url5 + "\n" + newUrl + "\n");
+
+
+ System.out.println("\n\n----------------------------");
+ System.out.println("Getting parameter values:\n");
+
+ System.out.println("Value of '" + "testParam" + "' in the URL: " + url1 + " -- " + Util.extractURLParameter(url1, "testParam"));
+ System.out.println("Value of '" + "testParam" + "' in the URL: " + url2 + " -- " + Util.extractURLParameter(url2, "testParam"));
+ System.out.println("Value of '" + "q" + "' in the URL: " + url3 + " -- " + Util.extractURLParameter(url3, "q"));
+ System.out.println("Value of '" + "q" + "' in the URL: " + url4 + " -- " + Util.extractURLParameter(url4, "q"));
+ System.out.println("Value of '" + "tag" + "' in the URL: " + url5 + " -- " + Util.extractURLParameter(url5, "tag"));
+
+
+ System.out.println("\n\n----------------------------");
+ System.out.println("URL decoding:\n");
+
+ System.out.println("Original URL: " + url6 + "\nDecoded URL: " + Util.urlDecodeQuery(url6));
+
+
+ System.out.println("\n\n----------------------------");
+ System.out.println("Appending a string before URL parameters:\n");
+
+ String strToAppend = ".xml";
+ System.out.println("Appending '" + strToAppend + "' in the URL: " + url1 + " -- " + Util.appendStringBeforeParametersOfURL(url1, strToAppend));
+ System.out.println("Appending '" + strToAppend + "' in the URL: " + url2 + " -- " + Util.appendStringBeforeParametersOfURL(url2, strToAppend));
+ System.out.println("Appending '" + strToAppend + "' in the URL: " + url3 + " -- " + Util.appendStringBeforeParametersOfURL(url3, strToAppend));
+ System.out.println("Appending '" + strToAppend + "' in the URL: " + url4 + " -- " + Util.appendStringBeforeParametersOfURL(url4, strToAppend));
+ System.out.println("Appending '" + strToAppend + "' in the URL: " + url5 + " -- " + Util.appendStringBeforeParametersOfURL(url5, strToAppend));
+ System.out.println("Appending '" + strToAppend + "' in the URL: " + url6 + " -- " + Util.appendStringBeforeParametersOfURL(url6, strToAppend));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/TestXHTMLRenderer.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/TestXHTMLRenderer.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/TestXHTMLRenderer.java
new file mode 100644
index 0000000..a50254e
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/TestXHTMLRenderer.java
@@ -0,0 +1,42 @@
+package net.sf.taverna.biocatalogue.test;
+
+import java.awt.Container;
+import java.io.File;
+
+import javax.swing.JFrame;
+
+import org.xhtmlrenderer.simple.FSScrollPane;
+import org.xhtmlrenderer.simple.XHTMLPanel;
+
+public class TestXHTMLRenderer extends JFrame {
+ public TestXHTMLRenderer() {
+ try {
+ init();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void init() throws Exception {
+ Container contentPane = this.getContentPane();
+
+ XHTMLPanel panel = new XHTMLPanel();
+ panel.getSharedContext().getTextRenderer().setSmoothingThreshold(0); // Anti-aliasing for all font sizes
+ panel.setDocument(new File("c:\\Temp\\MyExperiment\\T2 BioCatalogue Plugin\\BioCatalogue Plugin\\resources\\test.html"));
+
+ FSScrollPane scroll = new FSScrollPane(panel);
+ contentPane.add(scroll);
+
+ this.setTitle("XHTML rendered test");
+ this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ this.pack();
+ this.setSize(1024, 768);
+ }
+
+
+ public static void main(String[] args) {
+ JFrame f = new TestXHTMLRenderer();
+ f.setVisible(true);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/WrappableJLabelTest.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/WrappableJLabelTest.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/WrappableJLabelTest.java
new file mode 100644
index 0000000..22afbd4
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/WrappableJLabelTest.java
@@ -0,0 +1,35 @@
+package net.sf.taverna.biocatalogue.test;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+public class WrappableJLabelTest extends JFrame
+{
+ public WrappableJLabelTest() {
+
+ // depending on the LayoutManager of the container, JLabel may
+ // be resized or simply "cut off" on the edges - e.g. FlowLayout
+ // cuts it off, BorderLayout does the resizing
+ JPanel jpTestPanel = new JPanel(new BorderLayout());
+ jpTestPanel.add(new JLabel("<html><span color=\"red\">a very long</span> text that <b>is just</b> " +
+ "showing how the whole thing looks - will it wrap text or not; this " +
+ "is the question</html>"), BorderLayout.CENTER);
+
+ this.getContentPane().add(jpTestPanel);
+
+ this.pack();
+ }
+
+ public static void main(String[] args)
+ {
+ WrappableJLabelTest f = new WrappableJLabelTest();
+ f.setLocationRelativeTo(null);
+ f.setPreferredSize(new Dimension(400, 300));
+ f.setVisible(true);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/XStreamTest.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/XStreamTest.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/XStreamTest.java
new file mode 100644
index 0000000..edc1d5a
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/test/XStreamTest.java
@@ -0,0 +1,32 @@
+package net.sf.taverna.biocatalogue.test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+
+import net.sf.taverna.biocatalogue.model.SoapOperationIdentity;
+
+
+public class XStreamTest
+{
+
+ public static void main(String[] args)
+ {
+ List<SoapOperationIdentity> processors = new ArrayList<SoapOperationIdentity>();
+ processors.add(new SoapOperationIdentity("http://www.test.com/test.wsdl", "aa", null));
+ processors.add(new SoapOperationIdentity("http://www.example.com/example.wsdl", "bb", null));
+
+ XStream xstream = new XStream(new DomDriver());
+ String xml = xstream.toXML(processors);
+
+ System.out.println(xml);
+
+ List<SoapOperationIdentity> processorsFromXML = (List<SoapOperationIdentity>)xstream.fromXML(xml);
+ System.out.println("\n\n");
+ System.out.println(processorsFromXML.get(0).getWsdlLocation() + " - " + processorsFromXML.get(0).getOperationName());
+ System.out.println(processorsFromXML.get(1).getWsdlLocation() + " - " + processorsFromXML.get(1).getOperationName());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/BioCatalogueExplorationTab.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/BioCatalogueExplorationTab.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/BioCatalogueExplorationTab.java
new file mode 100644
index 0000000..d3f452d
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/BioCatalogueExplorationTab.java
@@ -0,0 +1,131 @@
+package net.sf.taverna.biocatalogue.ui;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+
+import javax.swing.BorderFactory;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.LayoutFocusTraversalPolicy;
+
+import net.sf.taverna.biocatalogue.model.connectivity.BioCatalogueClient;
+import net.sf.taverna.biocatalogue.ui.search_results.SearchResultsMainPanel;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.MainComponent;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.MainComponentFactory;
+
+import org.apache.log4j.Logger;
+
+
+/**
+ *
+ * @author Sergejs Aleksejevs
+ */
+@SuppressWarnings("serial")
+public class BioCatalogueExplorationTab extends JPanel implements HasDefaultFocusCapability
+{
+ private final MainComponent pluginPerspectiveMainComponent;
+ private final BioCatalogueClient client;
+ private final Logger logger;
+
+
+ // COMPONENTS
+ private BioCatalogueExplorationTab thisPanel;
+
+ private SearchOptionsPanel searchOptionsPanel;
+ private SearchResultsMainPanel tabbedSearchResultsPanel;
+
+
+ public BioCatalogueExplorationTab()
+ {
+ this.thisPanel = this;
+
+ this.pluginPerspectiveMainComponent = MainComponentFactory.getSharedInstance();
+ this.client = BioCatalogueClient.getInstance();
+ this.logger = Logger.getLogger(this.getClass());
+
+ initialiseUI();
+
+ // this is to make sure that search will get focused when this tab is opened
+ // -- is a workaround to a bug in JVM
+ setFocusCycleRoot(true);
+ setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
+ public Component getDefaultComponent(Container cont) {
+ return (thisPanel.getDefaultComponent());
+ }
+ });
+ }
+
+
+ private void initialiseUI()
+ {
+ this.tabbedSearchResultsPanel = new SearchResultsMainPanel();
+ this.searchOptionsPanel = new SearchOptionsPanel(tabbedSearchResultsPanel);
+
+
+ this.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weightx = 0.0;
+ c.anchor = GridBagConstraints.WEST;
+ c.insets = new Insets(3,10,3,10);
+ String baseString= "<html><b>Using service catalogue at </b>" + client.getBaseURL() + "</html>";
+ this.add(new JLabel(baseString), c);
+
+
+ c.gridx = 1;
+ c.gridy = 0;
+ c.weightx = 0.1;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.anchor = GridBagConstraints.EAST;
+ c.insets = new Insets(3,30,3,10);
+
+ this.add(searchOptionsPanel, c);
+
+ c.insets = new Insets(0,0,0,0);
+ c.gridy++;
+ c.gridx = 0;
+ c.gridwidth = 2;
+ c.weightx = c.weighty = 1.0;
+ c.fill = GridBagConstraints.BOTH;
+ c.anchor = GridBagConstraints.CENTER;
+ this.add(tabbedSearchResultsPanel, c);
+
+ this.setBorder(BorderFactory.createEmptyBorder(20, 10, 10, 10));
+ }
+
+
+ public SearchResultsMainPanel getTabbedSearchResultsPanel() {
+ return tabbedSearchResultsPanel;
+ }
+
+
+
+ // *** Callbacks for HasDefaultFocusCapability interface ***
+
+ public void focusDefaultComponent() {
+ this.searchOptionsPanel.focusDefaultComponent();
+ }
+
+ public Component getDefaultComponent() {
+ return (this.searchOptionsPanel.getDefaultComponent());
+ }
+
+ // *********************************************************
+
+
+ public static void main(String[] args) {
+ JFrame f = new JFrame();
+ f.getContentPane().add(new BioCatalogueExplorationTab());
+ f.setSize(1000, 800);
+ f.setLocationRelativeTo(null);
+
+ f.setVisible(true);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/HasDefaultFocusCapability.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/HasDefaultFocusCapability.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/HasDefaultFocusCapability.java
new file mode 100644
index 0000000..d8915d5
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/HasDefaultFocusCapability.java
@@ -0,0 +1,15 @@
+package net.sf.taverna.biocatalogue.ui;
+
+import java.awt.Component;
+
+/**
+ * Indicates that the class which implements this interface will focus default
+ * component (as if the component represented by that class was activated).
+ *
+ * @author Sergejs Aleksejevs
+ */
+public interface HasDefaultFocusCapability
+{
+ public void focusDefaultComponent();
+ public Component getDefaultComponent();
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/JClickableLabel.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/JClickableLabel.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/JClickableLabel.java
new file mode 100644
index 0000000..0cc9246
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/JClickableLabel.java
@@ -0,0 +1,172 @@
+package net.sf.taverna.biocatalogue.ui;
+
+import java.awt.Color;
+import java.awt.Cursor;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.util.EventListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.Icon;
+import javax.swing.JLabel;
+import javax.swing.SwingUtilities;
+
+/**
+ * @author Sergejs Aleksejevs
+ */
+@SuppressWarnings("serial")
+public class JClickableLabel extends JLabel implements MouseListener
+{
+ /**
+ * Default height of the JClickableLabel - calculated based on 16-pixel
+ * standard square icon and 3-pixel thick padding on top / bottom of element.
+ */
+ public static final int DEFAULT_HEIGHT = 22;
+
+ public static final Color DEFAULT_REGULAR_FOREGROUND_COLOR = Color.BLUE;
+ public static final Color DEFAULT_HOVER_FOREGROUND_COLOR = new Color(133, 53, 53);
+
+
+ // This will hold the data which is relevant to processing the 'click' event on this label
+ private final String strData;
+
+ // This will hold a reference to ResourcePreviewBrowser instance that is supposed to process the clicks
+ // on JClickableLabels
+ private ActionListener clickHandler;
+
+
+ private Color REGULAR_FOREGROUND_COLOR = DEFAULT_REGULAR_FOREGROUND_COLOR;
+ private Color HOVER_FOREGROUND_COLOR = DEFAULT_HOVER_FOREGROUND_COLOR;
+
+
+ public JClickableLabel(String strLabel, String strDataForAction, EventListener eventHandler)
+ {
+ this(strLabel, strDataForAction, eventHandler, null);
+ }
+
+ public JClickableLabel(String strLabel, String strDataForAction, EventListener eventHandler, Icon icon)
+ {
+ this(strLabel, strDataForAction, eventHandler, icon, SwingUtilities.LEFT);
+ }
+
+ public JClickableLabel(String strLabel, String strDataForAction, EventListener eventHandler, Icon icon, int horizontalAlignment)
+ {
+ this(strLabel, strDataForAction, eventHandler, icon, horizontalAlignment, null);
+ }
+
+ /**
+ *
+ * @param strLabel Textual label that will be visible in the UI.
+ * @param strDataForAction Data that will be passed to eventHandler when click on the label is made.
+ * @param eventHandler ActionListener that will process clicks on this label.
+ * @param icon Icon to display in the label.
+ * @param horizontalAlignment This is one of SwingConstants: LEFT, CENTER, RIGHT, LEADING or TRAILING
+ * @param strTooltip Tooltip to show over the label - if none is provided (e.g. null value), the strLabel will be used as a tooltip.
+ */
+ public JClickableLabel(String strLabel, String strDataForAction, EventListener eventHandler, Icon icon, int horizontalAlignment, String strTooltip)
+ {
+ super(strLabel, icon, horizontalAlignment);
+
+ this.strData = strDataForAction;
+ this.clickHandler = (ActionListener)eventHandler;
+
+ // empty border at the top and bottom will simulate "line-spacing"
+ // (this is only needed when an icon is displayed)
+ if (icon != null) {
+ this.setBorder(BorderFactory.createEmptyBorder(3, 0, 3, 0));
+ }
+
+ // the tooltip for now only shows the full label text
+ this.setToolTipText(strTooltip == null ? strLabel : strTooltip);
+ this.setForeground(REGULAR_FOREGROUND_COLOR);
+ this.addMouseListener(this);
+ }
+
+
+ public void setRegularForegroundColor(Color regularForegroundColor)
+ {
+ REGULAR_FOREGROUND_COLOR = regularForegroundColor;
+
+ // apply the new foreground color immediately
+ this.setForeground(REGULAR_FOREGROUND_COLOR);
+ }
+
+ public Color getRegularForegroundColor() {
+ return REGULAR_FOREGROUND_COLOR;
+ }
+
+
+ public void setHoverForegroundColor(Color hoverForegroundColor)
+ {
+ // will be applied the next time mouse hovers over this label
+ HOVER_FOREGROUND_COLOR = hoverForegroundColor;
+ }
+
+ public Color getHoverForegroundColor() {
+ return HOVER_FOREGROUND_COLOR;
+ }
+
+
+ /**
+ * @return The "hidden" string value that is normally sent as an <code>ActionCommand</code>
+ * within <code>ActionEvent</code> when JClickableLabel is clicked.
+ */
+ public String getData() {
+ return (this.strData);
+ }
+
+
+ /**
+ * @return String value of the label that this JClickableLabel would have in the UI.
+ */
+ public String toString() {
+ return (this.getText());
+ }
+
+
+ /* This class extends JLabel, so it can't extend MouseAdapter;
+ * therefore, empty methods will be added for not useful callbacks
+ * from the MouseListener interface.
+ */
+ public void mouseClicked(MouseEvent e)
+ {
+ // call 'actionPerformed' method on the clickHandler instance that was supplied
+ // on creation of the JClickableLabel instance
+ this.clickHandler.actionPerformed(new ActionEvent(this, e.getID(), this.strData));
+ }
+
+ public void mouseEntered(MouseEvent e)
+ {
+ this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)) ;
+ this.setForeground(HOVER_FOREGROUND_COLOR);
+ }
+
+ public void mouseExited(MouseEvent e)
+ {
+ this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)) ;
+ this.setForeground(REGULAR_FOREGROUND_COLOR);
+ }
+
+ public void mousePressed(MouseEvent e)
+ {
+ // do nothing
+ }
+
+ public void mouseReleased(MouseEvent e)
+ {
+ // do nothing
+ }
+
+
+ /**
+ * @return A dummy instance of JClickable label - only intended to
+ * represent an object of this class; doesn't have a click handler,
+ * so a click on it will result in a <code>NullPointerException</code>.
+ */
+ public static JClickableLabel getDummyInstance() {
+ return (new JClickableLabel("dummy", "", 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/ui/JWaitDialog.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/JWaitDialog.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/JWaitDialog.java
new file mode 100644
index 0000000..526066b
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/JWaitDialog.java
@@ -0,0 +1,234 @@
+package net.sf.taverna.biocatalogue.ui;
+
+import java.awt.BorderLayout;
+//import java.awt.Dimension;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import javax.swing.BorderFactory;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.UIManager;
+
+import net.sf.taverna.biocatalogue.model.ResourceManager;
+import net.sf.taverna.t2.workbench.MainWindow;
+
+/**
+ * Creates a modal non-resizable dialog window.
+ *
+ * Intended to be used for operations that consume some
+ * time, but the user must wait for them to complete before
+ * proceeding.
+ *
+ * Initially the dialog shows a specified string message or
+ * component and a "loader" bar - dynamic GIF image that
+ * displays "activity" going on. At this stage the window
+ * cannot be closed.
+ *
+ * When the operation completes, the caller notifies the dialog
+ * that it has finished, provides a new message / component to
+ * display and allows the dialog to be closed.
+ *
+ * If the operation doesn't complete within the specified time,
+ * a timeout occurs and the dialog windows lets to close itself.
+ *
+ * @author Sergejs Aleksejevs
+ */
+@SuppressWarnings("serial")
+public class JWaitDialog extends JDialog
+{
+ private static final int DEFAULT_TIMEOUT = 10000;
+ private static final ImageIcon LOADER_ICON = ResourceManager.getImageIcon(ResourceManager.BAR_LOADER_ORANGE);
+
+ private JPanel jpInformationPanel;
+ private JLabel jlLoaderIcon;
+
+ private JButton bOK;
+ private JPanel jpOKButton;
+
+ private Timer timeoutTimer;
+ private boolean hasTimedOut;
+
+
+ /**
+ * Creates a new Wait Dialog with no parent and default timeout on
+ * operation - <code>JWaitDialog.DEFAULT_TIMEOUT</code>.
+ *
+ * @param dialogTitle Title to set for the dialog window.
+ * @param waitMessage Text to be displayed in the body of this dialog while
+ * the user waits.
+ */
+ public JWaitDialog(String dialogTitle, String waitMessage) {
+ this(null, dialogTitle, new JLabel(waitMessage, JLabel.CENTER), DEFAULT_TIMEOUT);
+ }
+
+
+ /**
+ * Creates a new Wait Dialog with specified parent and default timeout on
+ * operation - <code>JWaitDialog.DEFAULT_TIMEOUT</code>.
+ *
+ * @param owner Specified JFrame is set as an owner for this Wait Dialog.
+ * @param dialogTitle Title to set for the dialog window.
+ * @param waitMessage Text to be displayed in the body of this dialog while
+ * the user waits.
+ */
+ public JWaitDialog(JFrame owner, String dialogTitle, String waitMessage) {
+ this(owner, dialogTitle, new JLabel(waitMessage, JLabel.CENTER), DEFAULT_TIMEOUT);
+ }
+
+
+ /**
+ * Creates a new Wait Dialog with specified parent and timeout on
+ * operation.
+ *
+ * @param owner Specified JFrame is set as an owner for this Wait Dialog.
+ * @param dialogTitle Title to set for the dialog window.
+ * @param waitMessage Text to be displayed in the body of this dialog while
+ * the user waits.
+ * @param timeoutMillis Duration of the timeout on the operation - after this
+ * time has passed the window will notify of the timeout
+ * and allow to close itself. Value of 0 indicates that the timeout will never occur.
+ */
+ public JWaitDialog(JFrame owner, String dialogTitle, String waitMessage, int timeoutMillis) {
+ this(owner, dialogTitle, new JLabel(waitMessage, JLabel.CENTER), timeoutMillis);
+ }
+
+
+ /**
+ * Creates a new Wait Dialog with parent JFrame.
+ *
+ * @param owner Specified JFrame is set as an owner for this Wait Dialog.
+ * @param dialogTitle Title to set for the dialog window.
+ * @param waitInformationComponent Component to be shown in the body of this
+ * dialog windows while the user waits for an operation to complete.
+ * @param timeoutMillis Duration of the timeout on the operation - after this
+ * time has passed the window will notify of the timeout
+ * and allow to close itself. Value of 0 indicates that the timeout will never occur.
+ */
+ public JWaitDialog(JFrame owner, String dialogTitle, JComponent waitInformationComponent, int timeoutMillis)
+ {
+ super(owner);
+ this.setModal(true);
+ this.setTitle(dialogTitle);
+
+ // this will show the wait message to the user
+ jpInformationPanel = new JPanel(new GridLayout());
+ jpInformationPanel.add(waitInformationComponent);
+ jpInformationPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 10, 20));
+
+ // some graphical indication that the loading activity is going on
+ jlLoaderIcon = new JLabel(LOADER_ICON);
+ jlLoaderIcon.setBorder(BorderFactory.createEmptyBorder(0, 20, 20, 20));
+
+ // put components into the dialog box
+ this.getContentPane().setLayout(new BorderLayout());
+ this.getContentPane().add(jpInformationPanel, BorderLayout.CENTER);
+ this.getContentPane().add(jlLoaderIcon, BorderLayout.SOUTH);
+
+ this.pack();
+ // Set the height of the dialog not to be more than 500; the message is in the scroll pane so that should be OK
+ this.setSize(new Dimension(this.getPreferredSize().width, this.getPreferredSize().height > 500 ? 500 : this.getPreferredSize().height));
+ // this.setResizable(false);
+ this.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
+
+ // center this window within the main Taverna Workbench window
+ this.setLocationRelativeTo(MainWindow.getMainWindow());
+
+
+ // start the timer - on timeout it will produce the
+ // timeout message and allow to close the window
+ hasTimedOut = false;
+ if (timeoutMillis > 0)
+ {
+ timeoutTimer = new Timer();
+ timeoutTimer.schedule(
+ new TimerTask() {
+ public void run() {
+ waitFinished(new JLabel("<html><center>The operation did not complete within the " +
+ "allocated time.</center></html>",
+ UIManager.getIcon("OptionPane.warningIcon"), JLabel.CENTER));
+ hasTimedOut = true;
+ }
+ },
+ timeoutMillis);
+ }
+ }
+
+
+ public void waitFinished(String resultMessage) {
+ waitFinished(new JLabel(resultMessage, JLabel.CENTER));
+ }
+
+ public void waitFinished(JComponent resultInformationComponent)
+ {
+ // this prevents the real response to be set after the
+ // timeout message was already displayed
+ if (!hasTimedOut)
+ {
+ // first of all stop the timeout timer: if this
+ // method was called by the application explicitly, not on
+ // timeout, we don't want the timeout message to appear after that
+ if (timeoutTimer != null) { timeoutTimer.cancel(); }
+
+ // change the information component
+ jpInformationPanel.removeAll();
+ jpInformationPanel.add(resultInformationComponent);
+
+ // the OK button will allow closing the window
+ bOK = new JButton("OK");
+ //bOK.setPreferredSize(new Dimension(LOADER_ICON.getIconWidth(), (int) (1.5 * LOADER_ICON.getIconHeight())));
+ bOK.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ // just remove the window
+ dispose();
+ }
+ });
+ bOK.addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent e) {
+ if (e.getKeyCode() == KeyEvent.VK_ENTER) {
+ // a fallback mechanism - default button doesn't work for some reason
+ // when the button is added into the dialog not in the constructor
+ bOK.doClick();
+ }
+ }
+ });
+ bOK.setDefaultCapable(true);
+ this.getRootPane().setDefaultButton(bOK);
+
+ // wrap OK button into a panel to add empty borders
+ jpOKButton = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
+ jpOKButton.add(bOK);
+ jpOKButton.setBorder(BorderFactory.createEmptyBorder(0, 20, 20 - (bOK.getPreferredSize().height - LOADER_ICON.getIconHeight()), 20));
+
+
+ // add OK button instead of the loader icon
+ this.getContentPane().remove(jlLoaderIcon);
+ this.getContentPane().add(jpOKButton, BorderLayout.SOUTH);
+ this.bOK.requestFocusInWindow();
+
+ // re-enable (X) button in the title bar
+ this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+
+ // update the size of this window - as the inner sizes of components have
+ // been likely to change; then center the dialog box within its parent
+ this.pack();
+ // Set the height of the dialog not to be more than 500; the message is in the scroll pane so that should be OK
+ this.setSize(new Dimension(this.getPreferredSize().width, this.getPreferredSize().height > 500 ? 500 : this.getPreferredSize().height));
+ this.setLocationRelativeTo(MainWindow.getMainWindow());
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/SearchOptionsPanel.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/SearchOptionsPanel.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/SearchOptionsPanel.java
new file mode 100644
index 0000000..b0d9d26
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/SearchOptionsPanel.java
@@ -0,0 +1,167 @@
+package net.sf.taverna.biocatalogue.ui;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.util.Arrays;
+
+import javax.swing.AbstractAction;
+import javax.swing.JButton;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.event.CaretEvent;
+import javax.swing.event.CaretListener;
+
+import net.sf.taverna.biocatalogue.model.BioCataloguePluginConstants;
+import net.sf.taverna.biocatalogue.model.ResourceManager;
+import net.sf.taverna.biocatalogue.model.Resource.TYPE;
+import net.sf.taverna.biocatalogue.model.search.SearchOptions;
+import net.sf.taverna.biocatalogue.ui.search_results.SearchResultsMainPanel;
+import net.sf.taverna.t2.lang.ui.DeselectingButton;
+
+
+/**
+ *
+ * @author Sergejs Aleksejevs
+ */
+@SuppressWarnings("serial")
+public class SearchOptionsPanel extends JPanel implements HasDefaultFocusCapability
+{
+ // COMPONENTS
+ private SearchOptionsPanel thisPanel;
+
+private JTextField tfSearchQuery;
+ private JButton bSearch;
+
+ private final SearchResultsMainPanel tabbedSearchResultsPanel;
+
+
+ public SearchOptionsPanel(SearchResultsMainPanel tabbedSearchResultsPanel)
+ {
+ super();
+ this.thisPanel = this;
+ this.tabbedSearchResultsPanel = tabbedSearchResultsPanel;
+
+ this.initialiseUI();
+ }
+
+
+ private void initialiseUI()
+ {
+ this.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weightx = 0.0;
+ c.fill = GridBagConstraints.NONE;
+
+
+ this.tfSearchQuery = new JTextField(30);
+ this.tfSearchQuery.setToolTipText(
+ "<html> Tips for creating search queries:<br>" +
+ " 1) Use wildcards to make more flexible queries. Asterisk (<b>*</b>) matches any zero or more<br>" +
+ " characters (e.g. <b><i>Seq*</i></b> would match <b><i>Sequence</i></b>), question mark (<b>?</b>) matches any single<br>" +
+ " character (e.g. <b><i>Bla?t</i></b> would match <b><i>Blast</i></b>).<br>" +
+ " 2) Enclose the <b><i>\"search query\"</i></b> in double quotes to make exact phrase matching, otherwise<br>" +
+ " items that contain any (or all) words in the <b><i>search query</i></b> will be found.</html>");
+
+ this.tfSearchQuery.addFocusListener(new FocusListener() {
+ public void focusGained(FocusEvent e) {
+ tfSearchQuery.selectAll();
+ }
+ public void focusLost(FocusEvent e) { /* do nothing */ }
+ });
+ this.tfSearchQuery.addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent e) {
+ // ENTER pressed - start search by simulating "search" button click
+ // (only do this if the "search" button was active at that moment)
+ if (e.getKeyCode() == KeyEvent.VK_ENTER && bSearch.isEnabled()) {
+ bSearch.doClick();
+ }
+ }
+ });
+ JButton jbClearSearch = new DeselectingButton(new AbstractAction("Clear") {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ tfSearchQuery.setText("");
+ clearSearch();
+ }}, "");
+ jbClearSearch.setIcon(ResourceManager.getImageIcon(ResourceManager.CLEAR_ICON));
+
+ this.add(jbClearSearch, c);
+
+ c.gridx++;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.weightx = 0.1;
+ this.add(tfSearchQuery, c);
+
+
+ // --- Search button ---
+
+ c.gridx++;
+ c.weightx = 0;
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.EAST;
+ this.bSearch = new DeselectingButton("Search",
+ new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if (getSearchQuery().length() == 0) {
+ clearSearch();
+ }
+ else {
+ // search query available - collect data about the current search and execute it
+ tabbedSearchResultsPanel.startNewSearch(thisPanel.getState());
+ }
+ }
+ },
+ tfSearchQuery.getToolTipText());
+ this.bSearch.setIcon(ResourceManager.getImageIcon(ResourceManager.SEARCH_ICON));
+ this.add(bSearch, c);
+
+}
+
+ private void clearSearch() {
+ tabbedSearchResultsPanel.clearSearch();
+ thisPanel.focusDefaultComponent();
+ }
+
+ /**
+ * Saves the current state of the search options into a single {@link SearchOptions} object.
+ */
+ public SearchOptions getState() {
+ return (new SearchOptions(getSearchQuery(), Arrays.asList(TYPE.values())));
+ }
+
+
+ // *** GETTERS AND SETTERS ***
+
+ public String getSearchQuery() {
+ return (this.tfSearchQuery.getText().trim());
+ }
+ public void setSearchQuery(String strSearchQuery) {
+ this.tfSearchQuery.setText(strSearchQuery);
+ }
+
+
+ // *** Callbacks for HasDefaultFocusCapability interface ***
+
+ public void focusDefaultComponent() {
+ this.tfSearchQuery.selectAll();
+ this.tfSearchQuery.requestFocusInWindow();
+ }
+
+ public Component getDefaultComponent() {
+ return(this.tfSearchQuery);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/filtertree/FilterTreeNode.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/filtertree/FilterTreeNode.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/filtertree/FilterTreeNode.java
new file mode 100644
index 0000000..fedd553
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/filtertree/FilterTreeNode.java
@@ -0,0 +1,91 @@
+package net.sf.taverna.biocatalogue.ui.filtertree;
+
+import net.sf.taverna.biocatalogue.ui.tristatetree.TriStateTreeNode;
+
+/**
+ * This class allows storing two pieces of data relevant to content filtering
+ * within the node of a tree. These values are kept hidden from the user and
+ * are only used when the filtering is about to happen.
+ *
+ * @author Sergejs Aleksejevs
+ */
+@SuppressWarnings("serial")
+public class FilterTreeNode extends TriStateTreeNode
+{
+ private String type;
+ private String urlValue;
+ final private boolean isFilterCategory;
+
+
+ /**
+ * This constructor is useful for root nodes, which need not have filter type / value.
+ */
+ public FilterTreeNode(Object userObject) {
+ super(userObject);
+
+ this.isFilterCategory = true;
+ }
+
+
+ /**
+ * @param userObject As in the superclass (DefaultMutableTreeNode) - the object which represents the node in the UI
+ * @param filterType Type of the filter - e.g. 'Service Categories' --> "cat"; 'Service Types' --> "t"
+ * @param filterUrlValue Value that should be added to the URL to perform the filtering operation
+ */
+ public FilterTreeNode(Object userObject, String filterType, String filterUrlValue) {
+ super(userObject);
+
+ this.setType(filterType);
+ this.setUrlValue(filterUrlValue);
+ this.isFilterCategory = false;
+ }
+
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setUrlValue(String urlValue) {
+ this.urlValue = urlValue;
+ }
+
+
+ public String getUrlValue() {
+ return urlValue;
+ }
+
+ /**
+ * @return True if and only if this node is one of the "root" filter categories (not to be mixed with root of the filter tree).
+ */
+ public boolean isFilterCategory() {
+ return isFilterCategory;
+ }
+
+
+ /**
+ * @return <code>true</code> if the current {@link FilterTreeNode} represents a tag with a namespace
+ * (i.e. an ontological term), whose full tag name looks like:
+ * <code>< http://example.namespace.com#tag_display_name ></code>
+ */
+ public boolean isTagWithNamespaceNode() {
+ return (this.getType() != null && this.getType().contains("tag") && this.getUrlValue().contains("#") &&
+ this.getUrlValue().startsWith("<") && this.getUrlValue().endsWith(">"));
+ }
+
+
+ /**
+ * Static wrapper for {@link FilterTreeNode#isTagWithNamespaceNode()}
+ *
+ * @param filterType
+ * @param filterUrlValue
+ * @return
+ */
+ public static boolean isTagWithNamespaceNode(String filterType, String filterUrlValue) {
+ return (new FilterTreeNode("test_user_object", filterType, filterUrlValue).isTagWithNamespaceNode());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/filtertree/FilterTreePane.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/filtertree/FilterTreePane.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/filtertree/FilterTreePane.java
new file mode 100644
index 0000000..75a80ea
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/filtertree/FilterTreePane.java
@@ -0,0 +1,348 @@
+package net.sf.taverna.biocatalogue.ui.filtertree;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.BorderFactory;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+import javax.swing.JToolBar;
+import javax.swing.SwingUtilities;
+
+import net.sf.taverna.biocatalogue.model.BioCataloguePluginConstants;
+import net.sf.taverna.biocatalogue.model.Resource.TYPE;
+import net.sf.taverna.biocatalogue.model.ResourceManager;
+import net.sf.taverna.biocatalogue.model.connectivity.BioCatalogueClient;
+import net.sf.taverna.biocatalogue.model.search.SearchInstance;
+import net.sf.taverna.biocatalogue.model.search.ServiceFilteringSettings;
+import net.sf.taverna.biocatalogue.ui.tristatetree.JTriStateTree;
+import net.sf.taverna.biocatalogue.ui.tristatetree.TriStateTreeCheckingListener;
+import net.sf.taverna.t2.ui.perspectives.biocatalogue.MainComponentFactory;
+import net.sf.taverna.t2.workbench.icons.WorkbenchIcons;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.log4j.Logger;
+
+import org.biocatalogue.x2009.xml.rest.Filter;
+import org.biocatalogue.x2009.xml.rest.FilterGroup;
+import org.biocatalogue.x2009.xml.rest.FilterType;
+import org.biocatalogue.x2009.xml.rest.Filters;
+
+/**
+ *
+ * @author Sergejs Aleksejevs
+ */
+@SuppressWarnings("serial")
+public class FilterTreePane extends JPanel implements TriStateTreeCheckingListener
+{
+ private TYPE resourceType;
+ private String filtersURL;
+ private BioCatalogueClient client;
+ private Logger logger;
+
+ private FilterTreePane thisPanel;
+
+ private JToolBar tbFilterTreeToolbar;
+
+ private JPanel jpFilters = null;
+ private JFilterTree filterTree; // tree component to display filter selections
+ private Filters filtersRoot; // last filters element which was received from the API
+
+
+
+ public FilterTreePane(TYPE resourceType)
+ {
+ this.thisPanel = this;
+
+ this.resourceType = resourceType;
+ this.filtersURL = resourceType.getAPIResourceCollectionFiltersURL();
+ this.client = BioCatalogueClient.getInstance();
+ this.logger = Logger.getLogger(this.getClass());
+
+ initialiseUI();
+ loadFiltersAndBuildTheTree();
+ }
+
+
+ private void initialiseUI()
+ {
+ jpFilters = new JPanel();
+ jpFilters.setBackground(Color.WHITE);
+
+ JScrollPane spFilters = new JScrollPane(jpFilters);
+ spFilters.setMinimumSize(new Dimension(235,0));
+ spFilters.setPreferredSize(new Dimension(300,0));
+ spFilters.getVerticalScrollBar().setUnitIncrement(BioCataloguePluginConstants.DEFAULT_SCROLL);
+
+
+ tbFilterTreeToolbar = createTreeActionToolbar();
+ resetTreeActionToolbar();
+
+ this.setLayout(new BorderLayout());
+ this.add(tbFilterTreeToolbar, BorderLayout.NORTH);
+ this.add(spFilters, BorderLayout.CENTER);
+ }
+
+
+ /**
+ * @return A toolbar that replicates all actions available in the contextual menu of
+ * the filtering tree - mainly: saving current filter, reloading filter tree,
+ * expanding/collapsing and selecting/deselecting everything in the tree.
+ */
+private JToolBar createTreeActionToolbar()
+ {
+
+
+ // the actual toolbar - no actions are added to it yet: done in a separate method
+ JToolBar tbTreeActions = new JToolBar(JToolBar.HORIZONTAL);
+ tbTreeActions.setAlignmentX(RIGHT_ALIGNMENT);
+ tbTreeActions.setBorderPainted(true);
+ tbTreeActions.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+ tbTreeActions.setFloatable(false);
+ return (tbTreeActions);
+ }
+
+
+ /**
+ * Resets the action toolbar to the original state.
+ */
+ public void resetTreeActionToolbar()
+ {
+
+ tbFilterTreeToolbar.removeAll();
+ tbFilterTreeToolbar.repaint();
+ }
+
+
+ /**
+ * This method loads filter data from API and populates the view.
+ */
+ private void loadFiltersAndBuildTheTree()
+ {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run()
+ {
+ resetTreeActionToolbar();
+
+ jpFilters.removeAll();
+ jpFilters.setLayout(new BorderLayout());
+ jpFilters.add(new JLabel(" Loading filters..."), BorderLayout.NORTH);
+ jpFilters.add(new JLabel(ResourceManager.getImageIcon(ResourceManager.BAR_LOADER_ORANGE)), BorderLayout.CENTER);
+ thisPanel.validate();
+ thisPanel.repaint(); // validate and repaint this component to make sure that
+ // scroll bar around the filter tree placeholder panel disappears
+ }
+ });
+
+ new Thread("Load filters") {
+ public void run() {
+ try {
+ // load filter data
+ filtersRoot = client.getBioCatalogueFilters(filtersURL);
+
+ // Create root of the filter tree component
+ FilterTreeNode root = new FilterTreeNode("root");
+
+ // populate the tree via its root element
+ for (FilterGroup fgroup : filtersRoot.getGroupList())
+ {
+ // attach filter group directly to the root node
+ FilterTreeNode fgroupNode = new FilterTreeNode("<html><span style=\"color: black; font-weight: bold;\">" + StringEscapeUtils.escapeHtml(fgroup.getName().toString()) + "</span></html>");
+ root.add(fgroupNode);
+
+
+ // go through all filter types in this group and add them to the tree
+ for (FilterType ftype : fgroup.getTypeList())
+ {
+ // if there's more than one filter type in the group, add the type node as another level of nesting
+ // (otherwise, attach filters inside the single type directly to the group node)
+ FilterTreeNode filterTypeNode = fgroupNode;
+ if (fgroup.getTypeList().size() > 1) {
+ filterTypeNode = new FilterTreeNode("<html><span style=\"color: black; font-weight: bold;\">" + StringEscapeUtils.escapeHtml(ftype.getName().toString()) + "</span></html>");
+ fgroupNode.add(filterTypeNode);
+ }
+
+ // For some reason sorting the list of filters before inserting into tree
+ // messes up the tree nodes
+// Collections.sort(ftype.getFilterList(), new Comparator<Filter>(){
+// @Override
+// public int compare(Filter f1, Filter f2) {
+// return (f1.getName().compareToIgnoreCase(f2.getName()));
+// }
+// });
+ addFilterChildren(filterTypeNode, ftype.getUrlKey().toString(), ftype.getFilterList());
+ }
+ }
+
+ // Create the tree view with the populated root
+ filterTree = new JFilterTree(root);
+ filterTree.setRootVisible(false); // don't want the root to be visible; not a standard thing, so not implemented within JTriStateTree
+ filterTree.setLargeModel(true); // potentially can have many filters!
+ filterTree.addCheckingListener(thisPanel);
+
+
+ // insert the created tree view into the filters panel
+ jpFilters.removeAll();
+ jpFilters.setLayout(new GridLayout(0,1));
+ jpFilters.add(filterTree);
+ jpFilters.validate();
+
+
+ // add actions from the contextual menu of the filter tree into the toolbar
+ // that replicates those plus adds additional ones in this panel
+ tbFilterTreeToolbar.removeAll();
+ for (Action a : filterTree.getContextualMenuActions()) {
+ tbFilterTreeToolbar.add(a);
+ }
+
+
+ // enable all actions
+ filterTree.enableAllContextualMenuAction(true);
+ }
+ catch (Exception e) {
+ logger.error("Failed to load filter tree from the following URL: " + filtersURL, e);
+ }
+ }
+
+
+ /**
+ * Recursive method to populate a node of the filter tree with all
+ * sub-filters.
+ *
+ * Ontological terms will be underlined.
+ *
+ * @param root Tree node to add children to.
+ * @param filterList A list of Filters to add to "root" as children.
+ */
+ private void addFilterChildren(FilterTreeNode root, String filterCategory, List<Filter> filterList) {
+ for (Filter f : filterList) {
+
+ // Is this an ontological term?
+ String ontology = null;
+ if (FilterTreeNode.isTagWithNamespaceNode(filterCategory, f
+ .getUrlValue())) {
+ String nameAndNamespace = f.getUrlValue().substring(1,
+ f.getUrlValue().length() - 1);
+ String[] namePlusNamespace = nameAndNamespace
+ .split("#");
+ ontology = JFilterTree
+ .getOntologyFromNamespace(namePlusNamespace[0]);
+ }
+
+ FilterTreeNode fNode = new FilterTreeNode("<html><span color=\"black\"" /*(FilterTreeNode.isTagWithNamespaceNode(filterCategory, f.getUrlValue()) ? " style=\"text-decoration: underline;\"" : "") */ + ">" +
+ StringEscapeUtils.escapeHtml(f.getName()) + " (" + f.getCount() + ")" + "</span>" +
+ /*(FilterTreeNode.isTagWithNamespaceNode(filterCategory, f.getUrlValue()) ? "<span color=\"gray\"> ("+f.getCount().intValue()+")</span></html>" : "</html>"),*/
+ (ontology != null ? "<span color=\"#3090C7\"> <"+ ontology +"></span></html>" : "</html>"),
+ filterCategory, f.getUrlValue());
+ addFilterChildren(fNode, filterCategory, f.getFilterList());
+
+ // Insert the node into the (alphabetically) sorted children nodes
+ List<FilterTreeNode> children = Collections.list(root.children());
+ // Search for the index the new node should be inserted at
+ int index = Collections.binarySearch(children, fNode,
+ new Comparator<FilterTreeNode>() {
+ @Override
+ public int compare(FilterTreeNode o1,
+ FilterTreeNode o2) {
+ String str1 = ((String) o1.getUserObject())
+ .toString();
+ String str2 = ((String) o2.getUserObject())
+ .toString();
+ return (str1.compareToIgnoreCase(str2));
+ }
+ });
+
+ if (index < 0){ // not found - index will be equal to -insertion-point -1
+ index = -index - 1;
+ }// else node with the same name found in the array - insert it at that position
+ root.insert(fNode, index);
+
+ //root.add(fNode);
+ }
+ }
+ }.start();
+ }
+
+
+ /**
+ * @param si Uses this SearchInstance to restore the checking
+ * state of filtering criteria in the filter tree.
+ */
+ public void restoreFilteringSettings(SearchInstance si) {
+ this.filterTree.restoreFilterCheckingSettings(si.getFilteringSettings().getFilterTreeRootsOfCheckedPaths());
+ }
+
+
+ /**
+ * Clears any selections made in the filter tree -
+ * i.e. both clears checked nodes and removes all tree path selections.
+ */
+ public void clearSelection() {
+ // filter tree may not have been initialised yet, so perform a check
+ if (this.filterTree != null)
+ {
+ // remove, then restore self as a listener - this is to avoid
+ // receiving checking state change event
+ this.filterTree.removeCheckingListener(thisPanel);
+ this.filterTree.selectAllNodes(false);
+ this.filterTree.clearSelection();
+ this.filterTree.addCheckingListener(thisPanel);
+ }
+ }
+
+
+ /**
+ * Collapses all expanded nodes in the filter tree.
+ */
+ public void collapseAll() {
+ // filter tree may not have been initialised yet, so perform a check
+ if (this.filterTree != null) {
+ this.filterTree.collapseAll();
+ }
+ }
+
+ public void applyQueryString(final String queryString) {
+ this.filtersURL = resourceType.getAPIResourceCollectionFiltersURL() + "?q=" + queryString;
+ loadFiltersAndBuildTheTree();
+ }
+
+ /**
+ * Used for making preferred height of the search status label
+ * the same as the height of this toolbar.
+ *
+ * @return
+ */
+ public Dimension getTreeToolbarPreferredSize() {
+ return this.tbFilterTreeToolbar.getPreferredSize();
+ }
+
+
+ // *** Callback for TriStateTreeCheckingListener ***
+
+ /**
+ * We start a new search as soon as checking state of the filter tree changes.
+ */
+ public void triStateTreeCheckingChanged(JTriStateTree source)
+ {
+ MainComponentFactory.getSharedInstance().getBioCatalogueExplorationTab().getTabbedSearchResultsPanel().
+ startNewFiltering(resourceType, new ServiceFilteringSettings(filterTree));
+ }
+
+
+public void reset() {
+ this.filtersURL = resourceType.getAPIResourceCollectionFiltersURL();
+ loadFiltersAndBuildTheTree();
+}
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/filtertree/JFilterTree.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/filtertree/JFilterTree.java b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/filtertree/JFilterTree.java
new file mode 100644
index 0000000..a6cc111
--- /dev/null
+++ b/taverna-workbench-perspective-biocatalogue/src/main/java/net/sf/taverna/biocatalogue/ui/filtertree/JFilterTree.java
@@ -0,0 +1,69 @@
+package net.sf.taverna.biocatalogue.ui.filtertree;
+
+import java.awt.event.MouseEvent;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.taverna.biocatalogue.ui.tristatetree.JTriStateTree;
+import net.sf.taverna.biocatalogue.ui.tristatetree.TriStateTreeNode;
+
+/**
+ * This subclass of {@link JTriStateTree} provides custom behaviour
+ * for tooltips: ontological terms will now always get a tooltip that
+ * displays the namespace for the tag, but plain text tags will still
+ * behave as before - the way it is defined in the superclass (so that
+ * the tooltip will only be shown if the tag does not fully fit into
+ * the visible part of the {@link FilterTreePane}.
+ *
+ * @author Sergejs Aleksejevs
+ */
+@SuppressWarnings("serial")
+public class JFilterTree extends JTriStateTree
+{
+
+ private static Map<String, String> nameSpaceToOntologyMap = new HashMap<String, String>(){
+ {
+ put("http://www.mygrid.org.uk/ontology", "mygrid-domain-ontology");
+ put("http://www.mygrid.org.uk/mygrid-moby-service", "mygrid-service-ontology");
+ }
+ };
+
+
+ public JFilterTree(TriStateTreeNode root) {
+ super(root);
+ }
+
+
+ public String getToolTipText(MouseEvent e)
+ {
+ Object correspondingObject = super.getTreeNodeObject(e);
+ if (correspondingObject != null && correspondingObject instanceof FilterTreeNode) {
+ FilterTreeNode filterNode = (FilterTreeNode) correspondingObject;
+
+ if (filterNode.isTagWithNamespaceNode())
+ {
+ String nameAndNamespace = filterNode.getUrlValue().substring(1, filterNode.getUrlValue().length() - 1);
+ String[] namePlusNamespace = nameAndNamespace.split("#");
+
+ return ("<html>" + namePlusNamespace[1] + " (<b>Namespace: </b>" + namePlusNamespace[0] + ")</html>");
+ }
+ }
+
+ return super.getToolTipText(e);
+ }
+
+ public static String getOntologyFromNamespace(String namespace){
+ if (namespace == null){
+ return null;
+ }
+ else{
+ if (nameSpaceToOntologyMap.containsKey(namespace)){
+ return nameSpaceToOntologyMap.get(namespace);
+ }
+ else{
+ return null;
+ }
+ }
+ }
+
+}