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/17 12:48:45 UTC
[26/50] [abbrv] incubator-taverna-workbench-common-activities git
commit: taverna-xpath-activity-ui/
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTree.java
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTree.java b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTree.java
new file mode 100644
index 0000000..4f98851
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTree.java
@@ -0,0 +1,572 @@
+package net.sf.taverna.t2.activities.xpath.ui.config.xmltree;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.JLabel;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.JTree;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.text.Position;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreePath;
+
+import net.sf.taverna.t2.activities.xpath.ui.config.XPathActivityConfigurationPanel;
+import net.sf.taverna.t2.activities.xpath.ui.servicedescription.XPathActivityIcon;
+
+import org.dom4j.Attribute;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.dom4j.Namespace;
+import org.dom4j.QName;
+import org.dom4j.XPath;
+
+
+/**
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class XPathActivityXMLTree extends JTree
+{
+ private XPathActivityXMLTree instanceOfSelf;
+ private XPathActivityXMLTreeRenderer treeRenderer;
+
+ private JPopupMenu contextualMenu;
+
+ private TreeSelectionListener[] allSelectionListeners;
+ private XPathActivityXMLTreeSelectionHandler xmlTreeSelectionHandler;
+
+ /**
+ *
+ */
+ private XPathActivityConfigurationPanel parentConfigPanel;
+
+ private Document documentUsedToPopulateTree;
+
+ /**
+ * holds value of the current XPath expression obtained from
+ * the combination of nodes selected in the XML tree
+ */
+ private XPath currentXPathExpression;
+
+ private Map<String,String> currentXPathNamespaces;
+
+
+
+ private XPathActivityXMLTree(XPathActivityXMLTreeNode root, Document documentUsedToPopulateTree,
+ boolean bIncludeElementValues, boolean bIncludeElementNamespaces, XPathActivityConfigurationPanel parentConfigPanel)
+ {
+ super(root);
+
+ this.instanceOfSelf = this;
+ this.allSelectionListeners = new TreeSelectionListener[0];
+
+ this.parentConfigPanel = parentConfigPanel;
+
+ this.documentUsedToPopulateTree = documentUsedToPopulateTree;
+ this.currentXPathExpression = null;
+ this.currentXPathNamespaces = new HashMap<String,String>();
+ this.prepopulateNamespaceMap();
+
+
+ // custom renderer of the nodes in the XML tree
+ this.treeRenderer = new XPathActivityXMLTreeRenderer(bIncludeElementValues, bIncludeElementNamespaces);
+ this.setCellRenderer(treeRenderer);
+
+
+ // add listener to handle various selections of nodes in the tree
+ this.xmlTreeSelectionHandler = new XPathActivityXMLTreeSelectionHandler(parentConfigPanel, this);
+ this.addTreeSelectionListener(xmlTreeSelectionHandler);
+
+
+ // --- CONTEXTUAL MENU FOR EXPANDING / COLLAPSING THE TREE ---
+
+ // create popup menu for expanding / collapsing all nodes in the tree
+ JMenuItem miExpandAll = new JMenuItem("Expand all", XPathActivityIcon.getIconById(XPathActivityIcon.XML_TREE_EXPAND_ALL_ICON));
+ miExpandAll.setToolTipText("Expand all nodes in the filtering tree");
+ miExpandAll.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ for (int i = 0; i < getRowCount(); i++) {
+ instanceOfSelf.expandRow(i);
+ }
+ }
+ });
+ JMenuItem miCollapseAll = new JMenuItem("Collapse all", XPathActivityIcon.getIconById(XPathActivityIcon.XML_TREE_COLLAPSE_ALL_ICON));
+ miCollapseAll.setToolTipText("Collapse all expanded nodes in the filtering tree");
+ miCollapseAll.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ for (int i = getRowCount() - 1; i >= 0; i--) {
+ instanceOfSelf.collapseRow(i);
+ }
+ }
+ });
+
+ // populate the popup menu with created menu items
+ contextualMenu = new JPopupMenu();
+ contextualMenu.add(miExpandAll);
+ contextualMenu.add(miCollapseAll);
+
+ // mouse events may cause the contextual menu to be shown - adding a listener
+ this.addMouseListener(new MouseAdapter()
+ {
+ public void mousePressed(MouseEvent e) {
+ if (e.isPopupTrigger()) {
+ contextualMenu.show(instanceOfSelf, e.getX(), e.getY());
+ }
+ }
+ public void mouseReleased(MouseEvent e) {
+ if (e.isPopupTrigger()) {
+ // another way a popup menu may be called on different systems
+ contextualMenu.show(instanceOfSelf, e.getX(), e.getY());
+ }
+ }
+ });
+
+ }
+
+
+ /**
+ * Pre-populates namespace map with the namespaced declared in the root
+ * node of the XML document, which was used to populate the tree.
+ */
+ private void prepopulateNamespaceMap()
+ {
+ Document doc = this.getDocumentUsedToPopulateTree();
+ Element root = doc.getRootElement();
+
+ // get opening tag of the root node
+ String rootAsXML = root.asXML().substring(0, root.asXML().indexOf(">"));
+
+ // split the opening tag into tokens (all attributes are separated by a space)
+ String[] rootTokens = rootAsXML.split(" ");
+
+ // for each attribute check if that's a namespace declaration
+ for (String token : rootTokens) {
+ if (token.startsWith("xmlns"))
+ {
+ String[] namespacePrefixAndURI = token.split("=");
+
+ // a prefix is either given explicitly, or an empty one will be used
+ String prefix = namespacePrefixAndURI[0].indexOf(":") == -1 ?
+ "" :
+ namespacePrefixAndURI[0].split(":")[1];
+
+ // URI is the value of the XML attribute, so need to strip out surrounding quotes
+ String URI = namespacePrefixAndURI[1].replaceAll("\"", "");
+
+ // now add the details of the current namespace to the map
+ this.addNamespaceToXPathMap(new Namespace(prefix, URI));
+ }
+ }
+ }
+
+
+ protected XPathActivityConfigurationPanel getParentConfigPanel() {
+ return parentConfigPanel;
+ }
+
+ public XPathActivityXMLTreeSelectionHandler getXMLTreeSelectionHandler() {
+ return xmlTreeSelectionHandler;
+ }
+
+ public Document getDocumentUsedToPopulateTree() {
+ return documentUsedToPopulateTree;
+ }
+
+ public XPath getCurrentXPathExpression() {
+ return currentXPathExpression;
+ }
+ protected void setCurrentXPathExpression(XPath xpathExpression) {
+ this.currentXPathExpression = xpathExpression;
+ }
+
+
+ public Map<String,String> getCurrentXPathNamespaces() {
+ return currentXPathNamespaces;
+ }
+
+
+
+ protected void removeAllSelectionListeners()
+ {
+ this.allSelectionListeners = this.getTreeSelectionListeners();
+ for (TreeSelectionListener listener : this.allSelectionListeners) {
+ this.removeTreeSelectionListener(listener);
+ }
+ }
+
+ protected void restoreAllSelectionListeners()
+ {
+ for (TreeSelectionListener listener : this.allSelectionListeners) {
+ this.addTreeSelectionListener(listener);
+ }
+ }
+
+
+
+ /**
+ * Creates an instance of the XML tree from provided XML data.
+ *
+ * @param xmlData XML document in the form of a <code>String</code> to
+ * derive the tree from.
+ * @param bIncludeAttributesIntoTree
+ * @param bIncludeValuesIntoTree
+ * @param bIncludeElementNamespacesIntoTree
+ * @param parentConfigPanel
+ * @return
+ * @throws DocumentException if <code>xmlData</code> does not
+ * contain a valid XML document.
+ *
+ */
+ public static XPathActivityXMLTree createFromXMLData(String xmlData, boolean bIncludeAttributesIntoTree,
+ boolean bIncludeValuesIntoTree, boolean bIncludeElementNamespacesIntoTree,
+ XPathActivityConfigurationPanel parentConfigPanel) throws DocumentException
+ {
+ // ----- XML DOCUMENT PARSING -----
+ // try to parse the XML document - the next line will throw an exception if
+ // the document is not well-formed; proceed otherwise
+ Document doc = DocumentHelper.parseText(xmlData);
+ Element rootElement = doc.getRootElement();
+
+
+ // ----- POPULATE XML TREE -----
+ XPathActivityXMLTreeElementNode rootNode = new XPathActivityXMLTreeElementNode(rootElement);
+ populate(rootNode, rootElement, bIncludeAttributesIntoTree);
+
+ return (new XPathActivityXMLTree(rootNode, doc, bIncludeValuesIntoTree, bIncludeElementNamespacesIntoTree, parentConfigPanel));
+ }
+
+
+ /**
+ * Worker method for populating the tree recursively from a list of Elements.
+ *
+ * @param node
+ * @param element
+ */
+ private static void populate(DefaultMutableTreeNode node, Element element,
+ boolean bIncludeAttributesIntoTree)
+ {
+ Iterator<Element> elementIterator = element.elements().iterator();
+ while (elementIterator.hasNext()) {
+ Element childElement = elementIterator.next();
+ XPathActivityXMLTreeElementNode childNode = new XPathActivityXMLTreeElementNode(childElement);
+ node.add(childNode);
+
+ // recursively repeat for all children of the current child element
+ populate(childNode, childElement, bIncludeAttributesIntoTree);
+ }
+
+
+ // add attributes of the element as its children, if necessary
+ if (bIncludeAttributesIntoTree) {
+ List<Attribute> attributes = element.attributes();
+ for (Attribute attribute : attributes) {
+ node.add(new XPathActivityXMLTreeAttributeNode(attribute));
+ }
+ }
+ }
+
+
+ // ---------------- RESPONDING TO REQUESTS TO CHANGE APPEARANCE OF EXISTING TREE -----------------
+
+ /**
+ * NB! May be inefficient, as this solution re-generates the whole tree from
+ * stored XML document and replaces the root node of itself with a newly
+ * generated root node (that will be populated with updated children,
+ * according to the new values of options).
+ *
+ * However, this is a simple solution that will work for now.
+ *
+ * @param bIncludeAttributes
+ * @param bIncludeValues
+ * @param bIncludeNamespaces
+ */
+ public void refreshFromExistingDocument(boolean bIncludeAttributes, boolean bIncludeValues, boolean bIncludeNamespaces)
+ {
+ this.setEnabled(false);
+ removeAllSelectionListeners();
+
+ // store expansion and selection state of the XML tree
+ // see documentation for restoreExpandedPaths() for more details
+ //
+ // stored paths to expanded nodes are quite reliable, as paths are recorded;
+ // stored selected rows are less reliable, as only indices are kept -- however,
+ // the tree is re-created from the same document, so ordering/number of nodes
+ // cannot change (apart from attributes that may be added / removed - the attributes
+ // appear after other child nodes of some node in the tree, therefore only their
+ // selection could be affected)
+ HashMap<String,ArrayList<String>> toExpand = new HashMap<String,ArrayList<String>>();
+ ArrayList<Integer> toSelect = new ArrayList<Integer>();
+ for( int i = 1; i < this.getRowCount(); i++) {
+ if( this.isExpanded(i) ) {
+ TreePath path = this.getPathForRow(i);
+ String parentPath = path.getParentPath().toString();
+ ArrayList<String> values = toExpand.get(parentPath);
+ if(values == null) {
+ values = new ArrayList<String>();
+ }
+ values.add(path.getLastPathComponent().toString());
+ toExpand.put(parentPath, values);
+ }
+ if (this.isRowSelected(i)) {
+ toSelect.add(i);
+ }
+ }
+
+
+ // update presentation options
+ this.treeRenderer.setIncludeElementValues(bIncludeValues);
+ this.treeRenderer.setIncludeElementNamespaces(bIncludeNamespaces);
+
+ // re-create the root node of the tree and replace the old one with it
+ Element rootElement = this.documentUsedToPopulateTree.getRootElement();
+ XPathActivityXMLTreeNode newRootNode = new XPathActivityXMLTreeElementNode(rootElement);
+ populate(newRootNode, rootElement, bIncludeAttributes);
+ ((DefaultTreeModel)this.getModel()).setRoot(newRootNode);
+
+
+ // restore previous state of the tree from saved values
+ restoreExpandedPaths(toExpand, this.getPathForRow(0));
+ restoreSelectedPaths(toSelect);
+
+ this.restoreAllSelectionListeners();
+ this.setEnabled(true);
+ }
+
+
+ /**
+ * This method can only reliably work when the tree is re-generated from the same
+ * XML document, so that number / order of nodes would not change.
+ *
+ * @param toSelect List of indices of rows to re-select after tree was re-generated.
+ */
+ private void restoreSelectedPaths(ArrayList<Integer> toSelect)
+ {
+ if (toSelect == null || toSelect.isEmpty()) return;
+
+ // something definitely needs to be selected, so include root element into selection
+ this.addSelectionRow(0);
+
+ // select all stored rows
+ for (Integer value : toSelect) {
+ this.addSelectionRow(value);
+ }
+ }
+
+
+
+ /**
+ * Taken from: <a href="http://java.itags.org/java-core-gui-apis/58504/">http://java.itags.org/java-core-gui-apis/58504/</a>
+ *
+ * This method recursively expands all previously stored paths.
+ * Works under assumption that the name of the root node did not change.
+ * Otherwise, it can handle changed structure of the tree.
+ *
+ * To achieve its goal, it cannot simply use stored TreePath from your the original tree,
+ * since the paths are invalid after the tree is refreshed. Instead, a HashMap which links
+ * a String representation of the parent tree path to all expanded child node names is used.
+ *
+ * @param toExpand Map which links a String representation of the parent tree path to all
+ * expanded child node names is used.
+ * @param rootPath Path to root node.
+ */
+ void restoreExpandedPaths(HashMap<String,ArrayList<String>> toExpand, TreePath rootPath)
+ {
+ ArrayList<String> values = toExpand.remove(rootPath.toString());
+ if (values == null) return;
+
+ int row = this.getRowForPath(rootPath);
+ for (String value : values)
+ {
+ TreePath nextMatch = this.getNextMatch(value, row, Position.Bias.Forward);
+ this.expandPath(nextMatch);
+ if (toExpand.containsKey(nextMatch.toString())) {
+ restoreExpandedPaths(toExpand, nextMatch);
+ }
+ }
+ }
+
+
+
+ // ---------------- TREE SELECTION MODEL + XPath GENERATION -----------------
+
+
+ protected String generateXPathFromTreePath(TreePath path)
+ {
+ StringBuilder xpath = new StringBuilder();
+
+ for (String leg : generateXPathFromTreePathAsLegList(path)) {
+ xpath.append(leg);
+ }
+
+ return (xpath.toString());
+ }
+
+
+ protected List<String> generateXPathFromTreePathAsLegList(TreePath path)
+ {
+ List<String> pathLegs = new LinkedList<String>();
+
+ TreePath parentPath = path;
+ for (int i = 0; i < path.getPathCount(); i++)
+ {
+ XPathActivityXMLTreeNode lastXMLTreeNodeInThisPath = (XPathActivityXMLTreeNode)parentPath.getLastPathComponent();
+ pathLegs.add(0, this.getXMLTreeNodeEffectiveQualifiedNameAsXPathLeg(lastXMLTreeNodeInThisPath));
+
+ parentPath = parentPath.getParentPath();
+ }
+
+ return (pathLegs);
+ }
+
+
+ protected String getXMLTreeNodeEffectiveQualifiedNameAsXPathLeg(XPathActivityXMLTreeNode node)
+ {
+ QName qname = node.getNodeQName();
+ String effectiveNamespacePrefix = addNamespaceToXPathMap(qname.getNamespace());
+
+ return("/" +
+ (node.isAttribute() ? "@" : "") +
+ (effectiveNamespacePrefix.length() > 0 ? (effectiveNamespacePrefix + ":") : "") +
+ qname.getName());
+ }
+
+
+
+ private String addNamespaceToXPathMap(Namespace namespace)
+ {
+ // EMTPY PREFIX
+ if (namespace.getPrefix().length() == 0) {
+ if (namespace.getURI().length() == 0) {
+ // DEFAULT NAMESPACE with no URI - nothing to worry about
+ return "";
+ }
+ else {
+ // DEFAULT NAMESPACE WITH NO PREFIX, BUT URI IS KNOWN
+ return (addNamespaceToXPathMap(new Namespace("default", namespace.getURI())));
+ }
+ }
+
+ // NEW NON-EMPTY PREFIX
+ if (!this.currentXPathNamespaces.containsKey(namespace.getPrefix())) {
+ this.currentXPathNamespaces.put(namespace.getPrefix(), namespace.getURI());
+ return (namespace.getPrefix());
+ }
+
+ // EXISTING NON-EMPTY PREFIX AND THE SAME URI - NO NEED TO ADD AGAIN
+ else if (this.currentXPathNamespaces.get(namespace.getPrefix()).equals(namespace.getURI())) {
+ return (namespace.getPrefix());
+ }
+
+ // EXISTING NON-EMPTY PREFIX, BUT DIFFERENT URI
+ else {
+ String repeatedPrefix = namespace.getPrefix();
+
+ int i = 0;
+ while (this.currentXPathNamespaces.containsKey(repeatedPrefix + i)) {
+ // check if current alternative prefix wasn't yet applied to current URI
+ if (this.currentXPathNamespaces.get(repeatedPrefix + i).equals(namespace.getURI())) {
+ return (repeatedPrefix + i);
+ }
+ else {
+ // still another URI for the same prefix, keep trying to increase the ID in the prefix
+ i++;
+ }
+ }
+
+ String modifiedPrefix = repeatedPrefix + i;
+ this.currentXPathNamespaces.put(modifiedPrefix, namespace.getURI());
+ return (modifiedPrefix);
+ }
+ }
+
+
+ // ----------------------- Tree Cell Renderer --------------------------
+
+ /**
+ *
+ * @author Sergejs Aleksejevs
+ */
+ private class XPathActivityXMLTreeRenderer extends DefaultTreeCellRenderer
+ {
+ private boolean bIncludeElementValues;
+ private boolean bIncludeElementNamespaces;
+
+ public XPathActivityXMLTreeRenderer(boolean bIncludeElementValues, boolean bIncludeElementNamespaces) {
+ super();
+ this.bIncludeElementValues = bIncludeElementValues;
+ this.bIncludeElementNamespaces = bIncludeElementNamespaces;
+ }
+
+
+ public boolean getIncludeElementValues() {
+ return bIncludeElementValues;
+ }
+ public void setIncludeElementValues(boolean bIncludeElementValues) {
+ this.bIncludeElementValues = bIncludeElementValues;
+ }
+
+ public boolean getIncludeElementNamespaces() {
+ return bIncludeElementNamespaces;
+ }
+ public void setIncludeElementNamespaces(boolean bIncludeElementNamespaces) {
+ this.bIncludeElementNamespaces = bIncludeElementNamespaces;
+ }
+
+
+ public Component getTreeCellRendererComponent(JTree tree, Object value,
+ boolean selected, boolean expanded, boolean leaf, int row,
+ boolean hasFocus)
+ {
+ // obtain the default rendering, we'll then customize it
+ Component defaultRendering = super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
+
+ // it is most likely that the default rendering will be a JLabel, check just to be safe
+ if (defaultRendering instanceof JLabel)
+ {
+ JLabel defaultRenderedLabel = ((JLabel)defaultRendering);
+
+ // ---------- CHOOSE APPROPRIATE ICON FOR THE NODE ------------
+ if (row == 0) {
+ // set the icon for the XML tree root node
+ defaultRenderedLabel.setIcon(XPathActivityIcon.getIconById(XPathActivityIcon.XML_TREE_ROOT_ICON));
+ }
+ else {
+ // set the icon for the XML tree node
+ if (value instanceof XPathActivityXMLTreeNode &&
+ ((XPathActivityXMLTreeNode)value).isAttribute())
+ {
+ defaultRenderedLabel.setIcon(XPathActivityIcon.getIconById(XPathActivityIcon.XML_TREE_ATTRIBUTE_ICON));
+ }
+ else {
+ defaultRenderedLabel.setIcon(XPathActivityIcon.getIconById(XPathActivityIcon.XML_TREE_NODE_ICON));
+ }
+ }
+
+
+ // ----------- CHOOSE THE DISPLAY TITLE FOR THE NODE ------------
+ if (value instanceof XPathActivityXMLTreeNode) {
+ defaultRenderedLabel.setText(((XPathActivityXMLTreeNode)value).getTreeNodeDisplayLabel(
+ this.bIncludeElementValues, this.bIncludeElementNamespaces, true));
+ }
+ }
+
+ return (defaultRendering);
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeAttributeNode.java
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeAttributeNode.java b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeAttributeNode.java
new file mode 100644
index 0000000..d22623f
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeAttributeNode.java
@@ -0,0 +1,50 @@
+package net.sf.taverna.t2.activities.xpath.ui.config.xmltree;
+
+import org.dom4j.Attribute;
+
+/**
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class XPathActivityXMLTreeAttributeNode extends XPathActivityXMLTreeNode
+{
+ private Attribute associatedAttribute;
+
+ public XPathActivityXMLTreeAttributeNode(Attribute associatedAttribute) {
+ super(associatedAttribute, true);
+ this.associatedAttribute = associatedAttribute;
+ }
+
+ public Attribute getAssociatedAttribute() {
+ return associatedAttribute;
+ }
+
+ public String getTreeNodeDisplayLabel(boolean bIncludeValue, boolean bUseStyling)
+ {
+ StringBuilder label = new StringBuilder();
+
+ // add qualified attribute name (possibly) with styling
+ label.append((bUseStyling ? "<font color=\"purple\">" : "") +
+ this.associatedAttribute.getQualifiedName() +
+ (bUseStyling ? "</font>" : ""));
+
+ // add attribute value
+ if (bIncludeValue)
+ {
+ String attributeTextValue = this.associatedAttribute.getText();
+
+ if (attributeTextValue != null && attributeTextValue.length() > 0) {
+ label.append((bUseStyling ? "<font color=\"gray\"> - </font><font color=\"green\">" : "") +
+ truncateElementTextValue(stripAllHTML(attributeTextValue)) +
+ (bUseStyling ? "</font>" : ""));
+ }
+ }
+
+ if (bUseStyling) {
+ label.insert(0, "<html>");
+ label.append("</html>");
+ }
+
+ return (label.toString());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeElementNode.java
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeElementNode.java b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeElementNode.java
new file mode 100644
index 0000000..a151753
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeElementNode.java
@@ -0,0 +1,62 @@
+package net.sf.taverna.t2.activities.xpath.ui.config.xmltree;
+
+import org.dom4j.Element;
+import org.dom4j.Namespace;
+
+
+/**
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class XPathActivityXMLTreeElementNode extends XPathActivityXMLTreeNode
+{
+ private Element associatedElement;
+
+ public XPathActivityXMLTreeElementNode(Element associatedElement) {
+ super(associatedElement, false);
+ this.associatedElement = associatedElement;
+ }
+
+ public Element getAssociatedElement() {
+ return associatedElement;
+ }
+
+ public String getTreeNodeDisplayLabel(boolean bIncludeValue, boolean bIncludeNamespace, boolean bUseStyling)
+ {
+ StringBuilder label = new StringBuilder();
+
+ // add qualified element name
+ label.append(this.associatedElement.getQualifiedName());
+
+ // add element namespace
+ if (bIncludeNamespace)
+ {
+ Namespace ns = this.associatedElement.getNamespace();
+
+ label.append((bUseStyling ? "<font color=\"gray\">" : "") +
+ " - xmlns" + (ns.getPrefix().length() > 0 ? (":" + ns.getPrefix()) : "") + "=\"" +
+ this.associatedElement.getNamespaceURI() +
+ (bUseStyling ? "\"</font>" : ""));
+ }
+
+ // add element value
+ if (bIncludeValue)
+ {
+ String elementTextValue = this.associatedElement.getTextTrim();
+
+ if (elementTextValue != null && elementTextValue.length() > 0) {
+ label.append((bUseStyling ? "<font color=\"gray\"> - </font><font color=\"blue\">" : "") +
+ truncateElementTextValue(stripAllHTML(elementTextValue)) +
+ (bUseStyling ? "</font>" : ""));
+ }
+ }
+
+ if (bUseStyling) {
+ label.insert(0, "<html>");
+ label.append("</html>");
+ }
+
+ return (label.toString());
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeNode.java
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeNode.java b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeNode.java
new file mode 100644
index 0000000..d1e98f7
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeNode.java
@@ -0,0 +1,81 @@
+package net.sf.taverna.t2.activities.xpath.ui.config.xmltree;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+
+import org.dom4j.QName;
+
+
+/**
+ *
+ * @author Sergejs Aleksejevs
+ */
+public abstract class XPathActivityXMLTreeNode extends DefaultMutableTreeNode
+{
+ protected static final int DISPLAY_LABEL_MAX_LENGTH = 200;
+
+ private final boolean isAttribute;
+
+ public XPathActivityXMLTreeNode(Object userObject, boolean isAttribute)
+ {
+ super(userObject);
+ this.isAttribute = isAttribute;
+ }
+
+ public boolean isAttribute() {
+ return (isAttribute);
+ }
+
+
+ public QName getNodeQName() {
+ if (this.isAttribute()) {
+ return (((XPathActivityXMLTreeAttributeNode)this).getAssociatedAttribute().getQName());
+ }
+ else {
+ return (((XPathActivityXMLTreeElementNode)this).getAssociatedElement().getQName());
+ }
+ }
+
+
+ public String getTreeNodeDisplayLabel(boolean bIncludeValue, boolean bIncludeElementNamespace, boolean bUseStyling)
+ {
+ if (this.isAttribute()) {
+ return (((XPathActivityXMLTreeAttributeNode)this).getTreeNodeDisplayLabel(bIncludeValue, bUseStyling));
+ }
+ else {
+ return (((XPathActivityXMLTreeElementNode)this).getTreeNodeDisplayLabel(bIncludeValue, bIncludeElementNamespace, bUseStyling));
+ }
+ }
+
+
+ protected String truncateElementTextValue(String textValue)
+ {
+ if (textValue != null && textValue.length() > DISPLAY_LABEL_MAX_LENGTH) {
+ textValue = textValue.substring(0, DISPLAY_LABEL_MAX_LENGTH) + "(...)";
+ }
+ return (textValue);
+ }
+
+
+ /**
+ * 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("\\<br/?\\>", "\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);
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeSelectionHandler.java
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeSelectionHandler.java b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeSelectionHandler.java
new file mode 100644
index 0000000..389bf1a
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeSelectionHandler.java
@@ -0,0 +1,251 @@
+package net.sf.taverna.t2.activities.xpath.ui.config.xmltree;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.swing.JOptionPane;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+
+import net.sf.taverna.t2.activities.xpath.ui.config.XPathActivityConfigurationPanel;
+
+import org.dom4j.DocumentHelper;
+
+
+/**
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class XPathActivityXMLTreeSelectionHandler implements TreeSelectionListener
+{
+ private final XPathActivityXMLTree theTree;
+ private final XPathActivityConfigurationPanel parentConfigPanel;
+
+
+ public XPathActivityXMLTreeSelectionHandler(XPathActivityConfigurationPanel parentConfigPanel,
+ XPathActivityXMLTree tree)
+ {
+ this.parentConfigPanel = parentConfigPanel;
+ this.theTree = tree;
+ }
+
+
+ public void valueChanged(TreeSelectionEvent e)
+ {
+ // get the newly made selection
+ TreePath newSelectedPath = e.getNewLeadSelectionPath();
+
+ // NB! Safety check - sometimes the container of the XML tree will remove all selections,
+ // in such case this listener is not supposed to perform any action -> terminate
+ if (newSelectedPath == null) return;
+
+
+ // --- XPath GENERATION ---
+
+ // get the XPath expression for the new selection + taking into consideration all previous ones
+ List<String> wildcardedXPath = generateWildcardedXPathExpression(newSelectedPath);
+
+ // assemble the xpath expression as one string
+ StringBuilder xpath = new StringBuilder();
+ for (String leg : wildcardedXPath) {
+ xpath.append(leg);
+ }
+ theTree.setCurrentXPathExpression(DocumentHelper.createXPath(xpath.toString()));
+ theTree.getCurrentXPathExpression().setNamespaceURIs(theTree.getCurrentXPathNamespaces());
+
+
+ // --- UPDATE CONFIG PANEL ---
+ // (with new values for XPath expression and namespace mappings)
+
+ // inform the parent activity configuration panel to update the XPath expression in the UI
+ /* We do not update the XPath expression after changes in selection in the XML tree - we
+ * now have a button to explicitly do that.
+ * theTree.getParentConfigPanel().updateXPathEditingPanelValues();
+ */
+
+ // --- SELECTION ---
+ selectAllNodesThatMatchTheCurrentXPath(wildcardedXPath, newSelectedPath);
+ }
+
+
+ /**
+ * Selects all nodes that match the <code>wildcardedXPath</code> expression.
+ *
+ * Keyboard focus is set to remain on the "deepest" (e.g. furthest from root)
+ * element of the <code>lastSelectedPath</code>.
+ *
+ * @param wildcardedXPath List of strings, where each string contains one "leg" of the XPath expression
+ * (e.g. a string starting with a "/" and containing the name of one node of the tree).
+ *
+ * @param lastSelectedPath The path that was last selected in the tree (normally,
+ * because of this selection {@link XPathActivityXMLTreeSelectionHandler#valueChanged(TreeSelectionEvent)}
+ * was executed and this method was started as a part of that.
+ */
+ public void selectAllNodesThatMatchTheCurrentXPath(List<String> wildcardedXPath, TreePath lastSelectedPath)
+ {
+ // first of all - calculate the number of nodes that match this XPath
+ // expression in the XML tree
+ int numberOfMatchingNodes = parentConfigPanel.runXPath(false);
+
+
+ // store all tree selection listeners in order to temporarily remove them;
+ // this is necessary as selection modifications will be made here -- don't
+ // want any listeners to respond to these new events
+ theTree.removeAllSelectionListeners();
+
+
+ // remove all previous selections - safest way to get the new ones correctly
+ theTree.clearSelection();
+
+
+ if (numberOfMatchingNodes <= XPathActivityConfigurationPanel.MAX_NUMBER_OF_MATCHING_NODES_TO_HIGHLIGHT_IN_THE_TREE)
+ {
+ // find all nodes that match the XPath expression
+ List<XPathActivityXMLTreeNode> matchingNodes = new ArrayList<XPathActivityXMLTreeNode>();
+ findAllNodesThatMatchWildcardedXPath(
+ (XPathActivityXMLTreeNode)theTree.getModel().getRoot(),
+ wildcardedXPath.subList(1, wildcardedXPath.size()),
+ matchingNodes);
+
+ // obtain and select TreePaths for each of the matching nodes
+ for (XPathActivityXMLTreeNode matchingNode : matchingNodes) {
+ TreeNode[] pathAsObjects = ((DefaultTreeModel)theTree.getModel()).getPathToRoot(matchingNode);
+ TreePath path = new TreePath(pathAsObjects);
+ selectTreePathAndAllItsAncestors(path);
+ }
+ }
+ else {
+ JOptionPane.showMessageDialog(parentConfigPanel,
+ "Current XPath expression matches " + numberOfMatchingNodes + " nodes in the XML tree.\n" +
+ "The XPath Activity is unable to highlight all these nodes in the tree due to\n" +
+ "performance reasons.\n\n" +
+ "The XPath Activity will still work correctly - both during the workflow execution\n" +
+ "and if 'Run XPath' button is clicked to run this expression against the example XML.",
+ "XPath Activity", JOptionPane.INFORMATION_MESSAGE);
+ }
+
+
+ // make sure the keyboard focus stays on the actual node that was clicked on -
+ // no direct way to do this, so simply de-select and re-select again
+ if (lastSelectedPath != null) {
+ theTree.removeSelectionPath(lastSelectedPath);
+ theTree.addSelectionPath(lastSelectedPath);
+ }
+
+ // restore all previously stored selection listeners
+ theTree.restoreAllSelectionListeners();
+ }
+
+
+
+ /**
+ * This cannot work for XPath expressions that were modified manually -
+ * only works for the type generated by the click in the XML tree.
+ *
+ * @param nodeToStartAt
+ * @param xpathLegs From <code>nodeToStartAt</code>.
+ * @param matchingNodes
+ */
+ private void findAllNodesThatMatchWildcardedXPath(XPathActivityXMLTreeNode nodeToStartAt,
+ List<String> xpathLegs, List<XPathActivityXMLTreeNode> matchingNodes)
+ {
+ // some of the input data is missing, just return...
+ if (nodeToStartAt == null || xpathLegs == null || matchingNodes == null) {
+ return;
+ }
+
+ // no XPath expression to match against the 'nodeToStartAt', therefore
+ // we've "found" the macthing node: 'nodeToStartAt'
+ if (xpathLegs.size() == 0) {
+ matchingNodes.add(nodeToStartAt);
+ return;
+ }
+
+ // standard case - there is something to match, proceed as normal
+ Enumeration<XPathActivityXMLTreeNode> startNodeChildren = nodeToStartAt.children();
+ while (startNodeChildren.hasMoreElements()) {
+ XPathActivityXMLTreeNode child = startNodeChildren.nextElement();
+
+ if (xpathLegs.get(0).equals("/*") ||
+ xpathLegs.get(0).equals(this.theTree.getXMLTreeNodeEffectiveQualifiedNameAsXPathLeg(child)))
+ {
+ // this node matches current section of the XPath expression
+ if (xpathLegs.size() == 1) {
+ // no more sections in the XPath leg list to match, so this child
+ // node is the one we were looking for - add to the result
+ matchingNodes.add(child);
+ }
+ else {
+ // ...or process its children recursively
+ findAllNodesThatMatchWildcardedXPath(child, xpathLegs.subList(1, xpathLegs.size()), matchingNodes);
+ }
+ }
+ }
+ }
+
+
+ private List<String> generateWildcardedXPathExpression(TreePath newSelectedPath)
+ {
+ // look through previous selection to find paths of the same length, as the newly selected one
+ List<TreePath> pathsOfSameLength = new ArrayList<TreePath>();
+ TreePath[] previouslySelectedPaths = theTree.getSelectionPaths();
+ for (TreePath path : previouslySelectedPaths) {
+ if (path.getPathCount() == newSelectedPath.getPathCount()) {
+ pathsOfSameLength.add(path);
+ }
+ }
+
+ // if there were found any paths of the same length, we have a "wildcard" situation
+ List<String> wildcardXPathLegs = theTree.generateXPathFromTreePathAsLegList(newSelectedPath);
+
+ if (pathsOfSameLength.size() > 0)
+ {
+ // it's okay to use just the first path - TODO: explain that this is because of previous comparisons
+ List<String> firstMatchingLengthPathLegs = theTree.generateXPathFromTreePathAsLegList(pathsOfSameLength.get(0));
+
+ int pathLength = wildcardXPathLegs.size();
+
+ // only use wildcards if the last segments of both paths are identical
+ if (wildcardXPathLegs.get(pathLength - 1).equals(firstMatchingLengthPathLegs.get(pathLength - 1)))
+ {
+ // continue all the way to the last segment, but don't touch it
+ for (int i = 0; i < wildcardXPathLegs.size() - 1; i++)
+ {
+ if (!wildcardXPathLegs.get(i).equals(firstMatchingLengthPathLegs.get(i))) {
+ // set wildcard
+ // TODO - make wildcard a constant
+ // TODO - may need to make the wildcard to have a namespace? (e.g. "/default:*" instead of simply "/*")
+ wildcardXPathLegs.set(i, "/*"); // definitely an element, not an attribute (as not the last segment in the path)
+ }
+ }
+ }
+ }
+
+ return (wildcardXPathLegs);
+ }
+
+
+
+ private void selectTreePathAndAllItsAncestors(TreePath path)
+ {
+ // select all ancestors of that path
+ TreePath pathToSelect = path;
+ for (int i = 0; i < path.getPathCount(); i++)
+ {
+ pathToSelect = pathToSelect.getParentPath();
+ theTree.addSelectionPath(pathToSelect);
+ }
+
+ // select the specified path itself
+ //
+ // NB! important to do this after the ancestors, so that the supplied
+ // path is the one that retains the keyboard focus after this method terminates
+ theTree.addSelectionPath(path);
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/contextualview/ConfigureXPathActivityMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/contextualview/ConfigureXPathActivityMenuAction.java b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/contextualview/ConfigureXPathActivityMenuAction.java
new file mode 100644
index 0000000..6695dc9
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/contextualview/ConfigureXPathActivityMenuAction.java
@@ -0,0 +1,65 @@
+package net.sf.taverna.t2.activities.xpath.ui.contextualview;
+
+import javax.swing.Action;
+
+import net.sf.taverna.t2.activities.xpath.ui.config.XPathActivityConfigureAction;
+import net.sf.taverna.t2.activities.xpath.ui.servicedescription.XPathTemplateService;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
+import net.sf.taverna.t2.workbench.activitytools.AbstractConfigureActivityMenuAction;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import uk.org.taverna.commons.services.ServiceRegistry;
+
+/**
+ * This action is responsible for enabling the contextual menu entry on processors that perform
+ * XPathActivity'ies.
+ * NB! As a side-effect this also enables the pop-up with for configuration of the processor when it
+ * is added to the workflow from the Service Panel.
+ *
+ * @author Sergejs Aleksejevs
+ * @author David Withers
+ */
+public class ConfigureXPathActivityMenuAction extends AbstractConfigureActivityMenuAction {
+
+ private EditManager editManager;
+ private FileManager fileManager;
+ private ActivityIconManager activityIconManager;
+ private ServiceDescriptionRegistry serviceDescriptionRegistry;
+ private ServiceRegistry serviceRegistry;
+
+ public ConfigureXPathActivityMenuAction() {
+ super(XPathTemplateService.ACTIVITY_TYPE);
+ }
+
+ @Override
+ protected Action createAction() {
+ XPathActivityConfigureAction configAction = new XPathActivityConfigureAction(
+ findActivity(), getParentFrame(), editManager, fileManager, activityIconManager,
+ serviceDescriptionRegistry, serviceRegistry);
+ configAction.putValue(Action.NAME, "Configure XPath service");
+ addMenuDots(configAction);
+ return configAction;
+ }
+
+ public void setEditManager(EditManager editManager) {
+ this.editManager = editManager;
+ }
+
+ public void setFileManager(FileManager fileManager) {
+ this.fileManager = fileManager;
+ }
+
+ public void setActivityIconManager(ActivityIconManager activityIconManager) {
+ this.activityIconManager = activityIconManager;
+ }
+
+ public void setServiceDescriptionRegistry(ServiceDescriptionRegistry serviceDescriptionRegistry) {
+ this.serviceDescriptionRegistry = serviceDescriptionRegistry;
+ }
+
+ public void setServiceRegistry(ServiceRegistry serviceRegistry) {
+ this.serviceRegistry = serviceRegistry;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/contextualview/XPathActivityMainContextViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/contextualview/XPathActivityMainContextViewFactory.java b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/contextualview/XPathActivityMainContextViewFactory.java
new file mode 100644
index 0000000..355ab8d
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/contextualview/XPathActivityMainContextViewFactory.java
@@ -0,0 +1,59 @@
+package net.sf.taverna.t2.activities.xpath.ui.contextualview;
+
+import java.util.Arrays;
+import java.util.List;
+
+import net.sf.taverna.t2.activities.xpath.ui.servicedescription.XPathTemplateService;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
+import uk.org.taverna.commons.services.ServiceRegistry;
+import uk.org.taverna.scufl2.api.activity.Activity;
+
+/**
+ * @author Sergejs Aleksejevs
+ */
+public class XPathActivityMainContextViewFactory implements ContextualViewFactory<Activity> {
+
+ private EditManager editManager;
+ private FileManager fileManager;
+ private ActivityIconManager activityIconManager;
+ private ServiceDescriptionRegistry serviceDescriptionRegistry;
+ private ServiceRegistry serviceRegistry;
+
+ public boolean canHandle(Object selection) {
+ return selection instanceof Activity
+ && ((Activity) selection).getType()
+ .equals(XPathTemplateService.ACTIVITY_TYPE);
+ }
+
+ public List<ContextualView> getViews(Activity selection) {
+ return Arrays.<ContextualView> asList(new XPathActivityMainContextualView(selection,
+ editManager, fileManager, activityIconManager, serviceDescriptionRegistry,
+ serviceRegistry));
+ }
+
+ public void setEditManager(EditManager editManager) {
+ this.editManager = editManager;
+ }
+
+ public void setFileManager(FileManager fileManager) {
+ this.fileManager = fileManager;
+ }
+
+ public void setActivityIconManager(ActivityIconManager activityIconManager) {
+ this.activityIconManager = activityIconManager;
+ }
+
+ public void setServiceDescriptionRegistry(ServiceDescriptionRegistry serviceDescriptionRegistry) {
+ this.serviceDescriptionRegistry = serviceDescriptionRegistry;
+ }
+
+ public void setServiceRegistry(ServiceRegistry serviceRegistry) {
+ this.serviceRegistry = serviceRegistry;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/contextualview/XPathActivityMainContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/contextualview/XPathActivityMainContextualView.java b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/contextualview/XPathActivityMainContextualView.java
new file mode 100644
index 0000000..d872228
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/contextualview/XPathActivityMainContextualView.java
@@ -0,0 +1,209 @@
+package net.sf.taverna.t2.activities.xpath.ui.contextualview;
+
+import java.awt.Color;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Frame;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+import javax.swing.Action;
+import javax.swing.BorderFactory;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.table.DefaultTableModel;
+
+import net.sf.taverna.t2.activities.xpath.ui.config.XPathActivityConfigureAction;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import uk.org.taverna.commons.services.ServiceRegistry;
+import uk.org.taverna.scufl2.api.activity.Activity;
+import uk.org.taverna.scufl2.api.common.Scufl2Tools;
+import uk.org.taverna.scufl2.api.configurations.Configuration;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ *
+ * @author Sergejs Aleksejevs
+ * @author David Withers
+ */
+@SuppressWarnings("serial")
+public class XPathActivityMainContextualView extends ContextualView {
+
+ private final Scufl2Tools scufl2Tools = new Scufl2Tools();
+
+ private XPathActivityMainContextualView thisContextualView;
+
+ private final Activity activity;
+
+ private JPanel jpMainPanel;
+ private JTextField tfXPathExpression;
+
+ private DefaultTableModel xpathNamespaceMappingsTableModel;
+ private JTable jtXPathNamespaceMappings;
+ private JScrollPane spXPathNamespaceMappings;
+ private final EditManager editManager;
+ private final FileManager fileManager;
+ private final ActivityIconManager activityIconManager;
+ private final ServiceDescriptionRegistry serviceDescriptionRegistry;
+ private final ServiceRegistry serviceRegistry;
+
+ public XPathActivityMainContextualView(Activity activity, EditManager editManager,
+ FileManager fileManager, ActivityIconManager activityIconManager,
+ ServiceDescriptionRegistry serviceDescriptionRegistry, ServiceRegistry serviceRegistry) {
+ this.editManager = editManager;
+ this.fileManager = fileManager;
+ this.activityIconManager = activityIconManager;
+ this.serviceDescriptionRegistry = serviceDescriptionRegistry;
+ this.serviceRegistry = serviceRegistry;
+ this.thisContextualView = this;
+ this.activity = activity;
+ initView();
+ }
+
+ @Override
+ public JComponent getMainFrame() {
+ jpMainPanel = new JPanel(new GridBagLayout());
+ jpMainPanel.setBorder(BorderFactory.createCompoundBorder(
+ BorderFactory.createEmptyBorder(4, 2, 4, 2), BorderFactory.createEmptyBorder()));
+
+ GridBagConstraints c = new GridBagConstraints();
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.anchor = GridBagConstraints.WEST;
+ c.weighty = 0;
+
+ // --- XPath Expression ---
+
+ c.gridx = 0;
+ c.gridy = 0;
+ c.insets = new Insets(5, 5, 5, 5);
+ JLabel jlXPathExpression = new JLabel("XPath Expression:");
+ jlXPathExpression.setFont(jlXPathExpression.getFont().deriveFont(Font.BOLD));
+ jpMainPanel.add(jlXPathExpression, c);
+
+ c.gridx++;
+ c.weightx = 1.0;
+ tfXPathExpression = new JTextField();
+ tfXPathExpression.setEditable(false);
+ jpMainPanel.add(tfXPathExpression, c);
+
+ // --- Label to Show/Hide Mapping Table ---
+
+ final JLabel jlShowHideNamespaceMappings = new JLabel("Show namespace mappings...");
+ jlShowHideNamespaceMappings.setForeground(Color.BLUE);
+ jlShowHideNamespaceMappings.setCursor(new Cursor(Cursor.HAND_CURSOR));
+ jlShowHideNamespaceMappings.addMouseListener(new MouseAdapter() {
+ public void mouseClicked(MouseEvent e) {
+ spXPathNamespaceMappings.setVisible(!spXPathNamespaceMappings.isVisible());
+ jlShowHideNamespaceMappings.setText((spXPathNamespaceMappings.isVisible() ? "Hide"
+ : "Show") + " namespace mappings...");
+ thisContextualView.revalidate();
+ }
+ });
+
+ c.gridx = 0;
+ c.gridy++;
+ c.gridwidth = 2;
+ c.weightx = 1.0;
+ c.weighty = 0;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ jpMainPanel.add(jlShowHideNamespaceMappings, c);
+
+ // --- Namespace Mapping Table ---
+
+ xpathNamespaceMappingsTableModel = new DefaultTableModel() {
+ /**
+ * No cells should be editable
+ */
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return (false);
+ }
+ };
+ xpathNamespaceMappingsTableModel.addColumn("Namespace Prefix");
+ xpathNamespaceMappingsTableModel.addColumn("Namespace URI");
+
+ jtXPathNamespaceMappings = new JTable();
+ jtXPathNamespaceMappings.setModel(xpathNamespaceMappingsTableModel);
+ jtXPathNamespaceMappings.setPreferredScrollableViewportSize(new Dimension(200, 90));
+ // TODO - next line is to be enabled when Taverna is migrated to Java
+ // 1.6; for now it's fine to run without this
+ // jtXPathNamespaceMappings.setFillsViewportHeight(true); // makes sure
+ // that when the dedicated area is larger than the table, the latter is
+ // stretched vertically to fill the empty space
+
+ jtXPathNamespaceMappings.getColumnModel().getColumn(0).setPreferredWidth(20); // set
+ // relative
+ // sizes of
+ // columns
+ jtXPathNamespaceMappings.getColumnModel().getColumn(1).setPreferredWidth(300);
+
+ c.gridy++;
+ spXPathNamespaceMappings = new JScrollPane(jtXPathNamespaceMappings);
+ spXPathNamespaceMappings.setVisible(false);
+ jpMainPanel.add(spXPathNamespaceMappings, c);
+
+ // populate the view with values
+ refreshView();
+
+ return jpMainPanel;
+ }
+
+ @Override
+ /**
+ * This is the title of the contextual view - shown in the list of other available
+ * views (even when this contextual view is collapsed).
+ */
+ public String getViewTitle() {
+ return "XPath Service Details";
+ }
+
+ /**
+ * Typically called when the activity configuration has changed.
+ */
+ @Override
+ public void refreshView() {
+ Configuration configuration = scufl2Tools.configurationFor(activity, activity.getParent());
+ JsonNode json = configuration.getJson();
+
+ // Set XPath Expression
+ tfXPathExpression.setText(json.get("xpathExpression").asText());
+
+ // Populate Namespace Mappings
+ xpathNamespaceMappingsTableModel.getDataVector().removeAllElements();
+ if (json.has("xpathNamespaceMap")) {
+ for (JsonNode mapping : json.get("xpathNamespaceMap")) {
+ xpathNamespaceMappingsTableModel.addRow(new Object[] {
+ mapping.get("prefix").asText(), mapping.get("uri").asText() });
+ }
+ }
+ }
+
+ /**
+ * View position hint
+ */
+ @Override
+ public int getPreferredPosition() {
+ // want to be on top, as it's the main contextual view for this activity
+ return 100;
+ }
+
+ @Override
+ public Action getConfigureAction(final Frame owner) {
+ // "Configure" button appears because of this action being returned
+ return new XPathActivityConfigureAction(activity, owner, editManager, fileManager,
+ activityIconManager, serviceDescriptionRegistry, serviceRegistry);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/menu/AddXPathTemplateAction.java
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/menu/AddXPathTemplateAction.java b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/menu/AddXPathTemplateAction.java
new file mode 100644
index 0000000..a80696d
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/menu/AddXPathTemplateAction.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (C) 2007-2009 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.activities.xpath.ui.menu;
+
+import java.awt.event.ActionEvent;
+import java.net.URI;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+
+import net.sf.taverna.t2.activities.xpath.ui.servicedescription.XPathTemplateService;
+import net.sf.taverna.t2.ui.menu.AbstractContextualMenuAction;
+import net.sf.taverna.t2.ui.menu.MenuManager;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.selection.SelectionManager;
+import net.sf.taverna.t2.workbench.ui.workflowview.WorkflowView;
+import uk.org.taverna.commons.services.ServiceRegistry;
+import uk.org.taverna.scufl2.api.core.Workflow;
+
+/**
+ * An action to add a REST activity + a wrapping processor to the workflow.
+ *
+ * @author Alex Nenadic
+ */
+@SuppressWarnings("serial")
+public class AddXPathTemplateAction extends AbstractContextualMenuAction {
+
+ private static final String ADD_XPATH = "XPath";
+
+ private static final URI insertSection = URI
+ .create("http://taverna.sf.net/2009/contextMenu/insert");
+
+ private EditManager editManager;
+
+ private MenuManager menuManager;
+
+ private SelectionManager selectionManager;
+
+ private ActivityIconManager activityIconManager;
+
+ private ServiceRegistry serviceRegistry;
+
+ public AddXPathTemplateAction() {
+ super(insertSection, 1000);
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return super.isEnabled() && getContextualSelection().getSelection() instanceof Workflow;
+ }
+
+ @Override
+ protected Action createAction() {
+
+ return new AddXPathAction();
+ }
+
+ protected class AddXPathAction extends AbstractAction {
+ AddXPathAction() {
+ super(ADD_XPATH, activityIconManager
+ .iconForActivity(XPathTemplateService.ACTIVITY_TYPE));
+ }
+
+ public void actionPerformed(ActionEvent e) {
+
+ WorkflowView.importServiceDescription(XPathTemplateService.getServiceDescription(),
+ false, editManager, menuManager, selectionManager, serviceRegistry);
+ }
+ }
+
+ public void setEditManager(EditManager editManager) {
+ this.editManager = editManager;
+ }
+
+ public void setMenuManager(MenuManager menuManager) {
+ this.menuManager = menuManager;
+ }
+
+ public void setSelectionManager(SelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ }
+
+ public void setActivityIconManager(ActivityIconManager activityIconManager) {
+ this.activityIconManager = activityIconManager;
+ }
+
+ public void setServiceRegistry(ServiceRegistry serviceRegistry) {
+ this.serviceRegistry = serviceRegistry;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/menu/AddXPathTemplateMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/menu/AddXPathTemplateMenuAction.java b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/menu/AddXPathTemplateMenuAction.java
new file mode 100644
index 0000000..9132110
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/menu/AddXPathTemplateMenuAction.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (C) 2007-2009 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.activities.xpath.ui.menu;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.net.URI;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.KeyStroke;
+
+import net.sf.taverna.t2.activities.xpath.ui.servicedescription.XPathTemplateService;
+import net.sf.taverna.t2.ui.menu.AbstractMenuAction;
+import net.sf.taverna.t2.ui.menu.DesignOnlyAction;
+import net.sf.taverna.t2.ui.menu.MenuManager;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.selection.SelectionManager;
+import net.sf.taverna.t2.workbench.ui.workflowview.WorkflowView;
+import uk.org.taverna.commons.services.ServiceRegistry;
+
+/**
+ * An action to add a REST activity + a wrapping processor to the workflow.
+ *
+ * @author Alex Nenadic
+ * @author alanrw
+ */
+@SuppressWarnings("serial")
+public class AddXPathTemplateMenuAction extends AbstractMenuAction {
+
+ private static final String ADD_XPATH = "XPath";
+
+ private static final URI INSERT = URI
+ .create("http://taverna.sf.net/2008/t2workbench/menu#insert");
+
+ private static final URI ADD_XPATH_URI = URI
+ .create("http://taverna.sf.net/2008/t2workbench/menu#graphMenuAddXPath");
+
+ private EditManager editManager;
+
+ private MenuManager menuManager;
+
+ private SelectionManager selectionManager;
+
+ private ActivityIconManager activityIconManager;
+
+ private ServiceRegistry serviceRegistry;
+
+ public AddXPathTemplateMenuAction() {
+ super(INSERT, 1000, ADD_XPATH_URI);
+ }
+
+ @Override
+ protected Action createAction() {
+ return new AddXPathMenuAction();
+ }
+
+ protected class AddXPathMenuAction extends AbstractAction implements DesignOnlyAction {
+ AddXPathMenuAction() {
+ super();
+ putValue(SMALL_ICON,
+ activityIconManager.iconForActivity(XPathTemplateService.ACTIVITY_TYPE));
+ putValue(NAME, ADD_XPATH);
+ putValue(SHORT_DESCRIPTION, "XPath service");
+ putValue(
+ Action.ACCELERATOR_KEY,
+ KeyStroke.getKeyStroke(KeyEvent.VK_P, InputEvent.SHIFT_DOWN_MASK
+ | InputEvent.ALT_DOWN_MASK));
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ WorkflowView.importServiceDescription(XPathTemplateService.getServiceDescription(),
+ false, editManager, menuManager, selectionManager, serviceRegistry);
+ }
+ }
+
+ public void setEditManager(EditManager editManager) {
+ this.editManager = editManager;
+ }
+
+ public void setMenuManager(MenuManager menuManager) {
+ this.menuManager = menuManager;
+ }
+
+ public void setSelectionManager(SelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ }
+
+ public void setActivityIconManager(ActivityIconManager activityIconManager) {
+ this.activityIconManager = activityIconManager;
+ }
+
+ public void setServiceRegistry(ServiceRegistry serviceRegistry) {
+ this.serviceRegistry = serviceRegistry;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/servicedescription/XPathActivityIcon.java
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/servicedescription/XPathActivityIcon.java b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/servicedescription/XPathActivityIcon.java
new file mode 100644
index 0000000..2251efb
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/servicedescription/XPathActivityIcon.java
@@ -0,0 +1,86 @@
+package net.sf.taverna.t2.activities.xpath.ui.servicedescription;
+
+import java.awt.Color;
+import java.net.URI;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI;
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+
+/**
+ * @author Sergejs Aleksejevs
+ */
+public class XPathActivityIcon implements ActivityIconSPI {
+ private static final Color PROCESSOR_COLOUR = Color.decode("#E6FF5E");
+
+ // --- LOCATIONS OF ICONS USED IN THE XPath ACTIVITY ---
+
+ private static final String FAMFAMFAM_SILK_PATH = "famfamfam_silk/";
+ private static final String FOLDS_PATH = "folds/";
+
+ public static final String XPATH_ACTIVITY_ICON = FAMFAMFAM_SILK_PATH + "page_white_code.png";
+ public static final String XPATH_ACTIVITY_CONFIGURATION_PARSE_XML_ICON = "arrow_right.png";
+
+ public static final String XML_TREE_ROOT_ICON = FAMFAMFAM_SILK_PATH + "page_white_code.png";
+ public static final String XML_TREE_NODE_ICON = FAMFAMFAM_SILK_PATH + "tag.png";
+ public static final String XML_TREE_ATTRIBUTE_ICON = "xpath_attribute.png";
+
+ public static final String XML_TREE_EXPAND_ALL_ICON = FAMFAMFAM_SILK_PATH
+ + "text_linespacing.png";
+ public static final String XML_TREE_COLLAPSE_ALL_ICON = FAMFAMFAM_SILK_PATH
+ + "text_linespacing (collapse).png";
+
+ public static final String XPATH_STATUS_OK_ICON = FAMFAMFAM_SILK_PATH + "accept.png";
+ public static final String XPATH_STATUS_ERROR_ICON = FAMFAMFAM_SILK_PATH + "exclamation.png";
+ public static final String XPATH_STATUS_UNKNOWN_ICON = FAMFAMFAM_SILK_PATH + "help.png";
+
+ public static final String FOLD_ICON = FOLDS_PATH + "fold.png";
+ public static final String UNFOLD_ICON = FOLDS_PATH + "unfold.png";
+
+ // ------
+
+ private static ImageIcon icon;
+
+ public int canProvideIconScore(URI activityType) {
+ if (XPathTemplateService.ACTIVITY_TYPE.equals(activityType))
+ return DEFAULT_ICON + 1;
+ else
+ return NO_ICON;
+ }
+
+ public Icon getIcon(URI activityType) {
+ return getXPathActivityIcon();
+ }
+
+ public static Icon getXPathActivityIcon() {
+ if (icon == null) {
+ synchronized (XPathActivityIcon.class) {
+ if (icon == null) {
+ try {
+ icon = new ImageIcon(
+ XPathActivityIcon.class.getResource(XPATH_ACTIVITY_ICON));
+ } catch (NullPointerException e) {
+ /* icon wasn't found - do nothing, but no icon will be available */
+ }
+ }
+ }
+ }
+ return (icon);
+ }
+
+ public static Icon getIconById(String iconID) {
+ try {
+ return (new ImageIcon(XPathActivityIcon.class.getResource(iconID)));
+ } catch (NullPointerException e) {
+ // requested icon wasn't found - just return null
+ return (null);
+ }
+ }
+
+ public void setColourManager(ColourManager colourManager) {
+ colourManager.setPreferredColour(XPathTemplateService.ACTIVITY_TYPE.toString(), PROCESSOR_COLOUR);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/servicedescription/XPathTemplateService.java
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/servicedescription/XPathTemplateService.java b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/servicedescription/XPathTemplateService.java
new file mode 100644
index 0000000..d55235d
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/servicedescription/XPathTemplateService.java
@@ -0,0 +1,57 @@
+package net.sf.taverna.t2.activities.xpath.ui.servicedescription;
+
+import java.net.URI;
+
+import javax.swing.Icon;
+
+import net.sf.taverna.t2.servicedescriptions.AbstractTemplateService;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescription;
+import uk.org.taverna.scufl2.api.configurations.Configuration;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * @author Sergejs Aleksejevs
+ * @author David Withers
+ */
+public class XPathTemplateService extends AbstractTemplateService {
+
+ public static final URI ACTIVITY_TYPE = URI.create("http://ns.taverna.org.uk/2010/activity/xpath");
+
+ @Override
+ public URI getActivityType() {
+ return ACTIVITY_TYPE;
+ }
+
+ @Override
+ public Configuration getActivityConfiguration() {
+ Configuration configuration = new Configuration();
+ configuration.setType(ACTIVITY_TYPE.resolve("#Config"));
+ ObjectNode json = (ObjectNode) configuration.getJson();
+ json.put("xpathExpression", "/");
+ return configuration;
+ }
+
+ @Override
+ public Icon getIcon() {
+ return XPathActivityIcon.getXPathActivityIcon();
+ }
+
+ public String getName() {
+ return "XPath";
+ }
+
+ public String getDescription() {
+ return "Service for point-and-click creation of XPath expressions for XML data";
+ }
+
+ public static ServiceDescription getServiceDescription() {
+ XPathTemplateService gts = new XPathTemplateService();
+ return gts.templateService;
+ }
+
+ public String getId() {
+ return "http://www.taverna.org.uk/2010/services/xpath";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider b/taverna-xpath-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider
new file mode 100644
index 0000000..be7da5f
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider
@@ -0,0 +1 @@
+net.sf.taverna.t2.activities.xpath.ui.servicedescription.XPathTemplateService
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent b/taverna-xpath-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
new file mode 100644
index 0000000..7700abb
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
@@ -0,0 +1,3 @@
+net.sf.taverna.t2.activities.xpath.ui.contextualview.ConfigureXPathActivityMenuAction
+net.sf.taverna.t2.activities.xpath.ui.menu.AddXPathTemplateAction
+net.sf.taverna.t2.activities.xpath.ui.menu.AddXPathTemplateMenuAction
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI b/taverna-xpath-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI
new file mode 100644
index 0000000..b759c2e
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI
@@ -0,0 +1 @@
+net.sf.taverna.t2.activities.xpath.ui.servicedescription.XPathActivityIcon
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory b/taverna-xpath-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory
new file mode 100644
index 0000000..e248981
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory
@@ -0,0 +1 @@
+ net.sf.taverna.t2.activities.xpath.ui.contextualview.XPathActivityMainContextViewFactory
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/META-INF/spring/xpath-activity-ui-context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/META-INF/spring/xpath-activity-ui-context-osgi.xml b/taverna-xpath-activity-ui/src/main/resources/META-INF/spring/xpath-activity-ui-context-osgi.xml
new file mode 100644
index 0000000..1e53ea6
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/resources/META-INF/spring/xpath-activity-ui-context-osgi.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans:beans xmlns="http://www.springframework.org/schema/osgi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:beans="http://www.springframework.org/schema/beans"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/osgi
+ http://www.springframework.org/schema/osgi/spring-osgi.xsd">
+
+ <service ref="XPathActivityIcon" interface="net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI" />
+
+ <service ref="XPathTemplateService" interface="net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider" />
+
+ <service ref="ConfigureXPathActivityMenuAction" auto-export="interfaces" />
+ <service ref="AddXPathTemplateAction" auto-export="interfaces" />
+ <service ref="AddXPathTemplateMenuAction" auto-export="interfaces" />
+
+ <service ref="XPathActivityMainContextViewFactory" interface="net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory" />
+
+ <reference id="editManager" interface="net.sf.taverna.t2.workbench.edits.EditManager" />
+ <reference id="fileManager" interface="net.sf.taverna.t2.workbench.file.FileManager" />
+ <reference id="menuManager" interface="net.sf.taverna.t2.ui.menu.MenuManager" />
+ <reference id="selectionManager" interface="net.sf.taverna.t2.workbench.selection.SelectionManager" />
+ <reference id="activityIconManager" interface="net.sf.taverna.t2.workbench.activityicons.ActivityIconManager" />
+ <reference id="colourManager" interface="net.sf.taverna.t2.workbench.configuration.colour.ColourManager" />
+ <reference id="serviceDescriptionRegistry" interface="net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry" />
+ <reference id="serviceRegistry" interface="uk.org.taverna.commons.services.ServiceRegistry" />
+
+</beans:beans>
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/META-INF/spring/xpath-activity-ui-context.xml
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/META-INF/spring/xpath-activity-ui-context.xml b/taverna-xpath-activity-ui/src/main/resources/META-INF/spring/xpath-activity-ui-context.xml
new file mode 100644
index 0000000..0116b2e
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/resources/META-INF/spring/xpath-activity-ui-context.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <bean id="XPathActivityIcon"
+ class="net.sf.taverna.t2.activities.xpath.ui.servicedescription.XPathActivityIcon">
+ <property name="colourManager" ref="colourManager" />
+ </bean>
+
+ <bean id="XPathTemplateService"
+ class="net.sf.taverna.t2.activities.xpath.ui.servicedescription.XPathTemplateService" />
+
+ <bean id="ConfigureXPathActivityMenuAction"
+ class="net.sf.taverna.t2.activities.xpath.ui.contextualview.ConfigureXPathActivityMenuAction">
+ <property name="editManager" ref="editManager" />
+ <property name="fileManager" ref="fileManager" />
+ <property name="activityIconManager" ref="activityIconManager" />
+ <property name="serviceDescriptionRegistry" ref="serviceDescriptionRegistry" />
+ <property name="serviceRegistry" ref="serviceRegistry" />
+ </bean>
+ <bean id="AddXPathTemplateAction"
+ class="net.sf.taverna.t2.activities.xpath.ui.menu.AddXPathTemplateAction">
+ <property name="editManager" ref="editManager" />
+ <property name="menuManager" ref="menuManager" />
+ <property name="selectionManager" ref="selectionManager" />
+ <property name="activityIconManager" ref="activityIconManager" />
+ <property name="serviceRegistry" ref="serviceRegistry" />
+ </bean>
+ <bean id="AddXPathTemplateMenuAction"
+ class="net.sf.taverna.t2.activities.xpath.ui.menu.AddXPathTemplateMenuAction">
+ <property name="editManager" ref="editManager" />
+ <property name="menuManager" ref="menuManager" />
+ <property name="selectionManager" ref="selectionManager" />
+ <property name="activityIconManager" ref="activityIconManager" />
+ <property name="serviceRegistry" ref="serviceRegistry" />
+ </bean>
+
+ <bean id="XPathActivityMainContextViewFactory"
+ class="net.sf.taverna.t2.activities.xpath.ui.contextualview.XPathActivityMainContextViewFactory">
+ <property name="editManager" ref="editManager" />
+ <property name="fileManager" ref="fileManager" />
+ <property name="activityIconManager" ref="activityIconManager" />
+ <property name="serviceDescriptionRegistry" ref="serviceDescriptionRegistry" />
+ <property name="serviceRegistry" ref="serviceRegistry" />
+ </bean>
+
+</beans>
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/arrow_right.png
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/arrow_right.png b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/arrow_right.png
new file mode 100644
index 0000000..2cf15f1
Binary files /dev/null and b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/arrow_right.png differ
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/accept.png
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/accept.png b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/accept.png
new file mode 100644
index 0000000..89c8129
Binary files /dev/null and b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/accept.png differ
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/exclamation.png
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/exclamation.png b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/exclamation.png
new file mode 100644
index 0000000..c37bd06
Binary files /dev/null and b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/exclamation.png differ
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/help.png
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/help.png b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/help.png
new file mode 100644
index 0000000..5c87017
Binary files /dev/null and b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/help.png differ
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/page_white_code.png
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/page_white_code.png b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/page_white_code.png
new file mode 100644
index 0000000..0c76bd1
Binary files /dev/null and b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/page_white_code.png differ
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/tag.png
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/tag.png b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/tag.png
new file mode 100644
index 0000000..e093032
Binary files /dev/null and b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/tag.png differ
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/text_linespacing (collapse).png
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/text_linespacing (collapse).png b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/text_linespacing (collapse).png
new file mode 100644
index 0000000..ff09e31
Binary files /dev/null and b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/text_linespacing (collapse).png differ
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/text_linespacing.png
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/text_linespacing.png b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/text_linespacing.png
new file mode 100644
index 0000000..1a91cbd
Binary files /dev/null and b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/famfamfam_silk/text_linespacing.png differ
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/folds/fold.png
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/folds/fold.png b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/folds/fold.png
new file mode 100644
index 0000000..a13d280
Binary files /dev/null and b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/folds/fold.png differ
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/folds/unfold.png
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/folds/unfold.png b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/folds/unfold.png
new file mode 100644
index 0000000..589e2c9
Binary files /dev/null and b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/folds/unfold.png differ
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/90ee9c45/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/xpath_attribute.png
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/xpath_attribute.png b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/xpath_attribute.png
new file mode 100644
index 0000000..3fa7811
Binary files /dev/null and b/taverna-xpath-activity-ui/src/main/resources/net/sf/taverna/t2/activities/xpath/ui/servicedescription/xpath_attribute.png differ