You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by re...@apache.org on 2015/03/27 17:22:16 UTC

[03/23] incubator-taverna-workbench-common-activities git commit:

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/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
deleted file mode 100644
index d1e98f7..0000000
--- a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeNode.java
+++ /dev/null
@@ -1,81 +0,0 @@
-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 "&nbsp;", "&gt;", etc
-
-        return (source);
-  }
-  
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/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
deleted file mode 100644
index 389bf1a..0000000
--- a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/config/xmltree/XPathActivityXMLTreeSelectionHandler.java
+++ /dev/null
@@ -1,251 +0,0 @@
-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/163747de/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
deleted file mode 100644
index caa15da..0000000
--- a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/contextualview/ConfigureXPathActivityMenuAction.java
+++ /dev/null
@@ -1,65 +0,0 @@
-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 org.apache.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/163747de/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
deleted file mode 100644
index a86a1ff..0000000
--- a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/contextualview/XPathActivityMainContextViewFactory.java
+++ /dev/null
@@ -1,59 +0,0 @@
-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 org.apache.taverna.commons.services.ServiceRegistry;
-import org.apache.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/163747de/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
deleted file mode 100644
index 54eee43..0000000
--- a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/contextualview/XPathActivityMainContextualView.java
+++ /dev/null
@@ -1,209 +0,0 @@
-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 org.apache.taverna.commons.services.ServiceRegistry;
-import org.apache.taverna.scufl2.api.activity.Activity;
-import org.apache.taverna.scufl2.api.common.Scufl2Tools;
-import org.apache.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/163747de/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
deleted file mode 100644
index e3ee445..0000000
--- a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/menu/AddXPathTemplateAction.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*******************************************************************************
- * 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 org.apache.taverna.commons.services.ServiceRegistry;
-import org.apache.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/163747de/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
deleted file mode 100644
index c2ec7ca..0000000
--- a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/menu/AddXPathTemplateMenuAction.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*******************************************************************************
- * 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 org.apache.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/163747de/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
deleted file mode 100644
index 2251efb..0000000
--- a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/servicedescription/XPathActivityIcon.java
+++ /dev/null
@@ -1,86 +0,0 @@
-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/163747de/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
deleted file mode 100644
index a1ebafc..0000000
--- a/taverna-xpath-activity-ui/src/main/java/net/sf/taverna/t2/activities/xpath/ui/servicedescription/XPathTemplateService.java
+++ /dev/null
@@ -1,63 +0,0 @@
-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 org.apache.taverna.scufl2.api.configurations.Configuration;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider;
-
-/**
- * @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";
-	}
-
-    @Override
-    public XPathTemplateService newInstance() {
-        return new XPathTemplateService();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-xpath-activity-ui/src/main/java/org/apache/taverna/activities/xpath/ui/config/TwoFieldQueryPanel.java
----------------------------------------------------------------------
diff --git a/taverna-xpath-activity-ui/src/main/java/org/apache/taverna/activities/xpath/ui/config/TwoFieldQueryPanel.java b/taverna-xpath-activity-ui/src/main/java/org/apache/taverna/activities/xpath/ui/config/TwoFieldQueryPanel.java
new file mode 100644
index 0000000..a63e465
--- /dev/null
+++ b/taverna-xpath-activity-ui/src/main/java/org/apache/taverna/activities/xpath/ui/config/TwoFieldQueryPanel.java
@@ -0,0 +1,110 @@
+package org.apache.taverna.activities.xpath.ui.config;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+
+import javax.swing.BorderFactory;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+/**
+ * Auxiliary class that creates a JPanel with two labels and two text fields.
+ *
+ * It can be used to be placed into a dialog made by JOptionPane to get two
+ * input values, not just one.
+ *
+ * @author Sergejs Aleksejevs
+ */
+public class TwoFieldQueryPanel extends JPanel {
+	private JTextField tfFirstValue;
+	private JTextField tfSecondValue;
+
+	public TwoFieldQueryPanel(String firstFieldName, String secondFieldName) {
+		this(null, firstFieldName, null, secondFieldName, null);
+	}
+
+	public TwoFieldQueryPanel(String message, String firstFieldName,
+			String secondFieldName) {
+		this(message, firstFieldName, null, secondFieldName, null);
+	}
+
+	public TwoFieldQueryPanel(String firstFieldName,
+			String firstFieldDefaultValue, String secondFieldName,
+			String secondFieldDefaultValue) {
+		this(null, firstFieldName, firstFieldDefaultValue, secondFieldName,
+				secondFieldDefaultValue);
+	}
+
+	public TwoFieldQueryPanel(String message, String firstFieldName,
+			String firstFieldDefaultValue, String secondFieldName,
+			String secondFieldDefaultValue) {
+		super();
+		this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+
+		this.setLayout(new GridBagLayout());
+		GridBagConstraints c = new GridBagConstraints();
+
+		c.gridx = 0;
+		c.gridy = 0;
+		c.weightx = 0;
+		c.fill = GridBagConstraints.HORIZONTAL;
+		c.anchor = GridBagConstraints.WEST;
+		c.insets = new Insets(3, 5, 3, 5);
+
+		if (message != null && message.length() > 0) {
+			c.gridwidth = 2;
+			c.insets = new Insets(5, 5, 15, 5);
+			this.add(new JLabel(message), c);
+
+			c.gridwidth = 1;
+			c.gridx = 0;
+			c.gridy++;
+			c.insets = new Insets(3, 5, 3, 5);
+		}
+
+		this.add(new JLabel(firstFieldName), c);
+
+		c.gridx++;
+		c.weightx = 1.0;
+		tfFirstValue = new JTextField(20);
+		if (firstFieldDefaultValue != null) {
+			tfFirstValue.setText(firstFieldDefaultValue);
+		}
+		tfFirstValue.selectAll();
+		tfFirstValue.requestFocusInWindow();
+		this.add(tfFirstValue, c);
+
+		c.gridx = 0;
+		c.gridy++;
+		c.weightx = 0;
+		this.add(new JLabel(secondFieldName), c);
+
+		c.gridx++;
+		c.weightx = 1.0;
+		tfSecondValue = new JTextField(20);
+		if (secondFieldDefaultValue != null) {
+			tfSecondValue.setText(secondFieldDefaultValue);
+		}
+		tfSecondValue.selectAll();
+		this.add(tfSecondValue, c);
+	}
+
+	/**
+	 * @return Trimmed value from the first text field. Guaranteed to be
+	 *         non-null.
+	 */
+	public String getFirstValue() {
+		return (tfFirstValue.getText().trim());
+	}
+
+	/**
+	 * @return Trimmed value from the second text field. Guaranteed to be
+	 *         non-null.
+	 */
+	public String getSecondValue() {
+		return (tfSecondValue.getText().trim());
+	}
+
+}