blob: 924f7f5d0e02ec1f1fb642758c48a93f01416249 [file] [log] [blame]
package org.apache.taverna.activities.xpath.ui.config;
import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.BorderFactory;
import javax.swing.JOptionPane;
import org.apache.taverna.activities.xpath.XPathActivityConfigurationBean;
import org.apache.taverna.workbench.ui.views.contextualviews.activity.ActivityConfigurationPanel;
import org.apache.taverna.services.ServiceRegistry;
import org.apache.taverna.scufl2.api.activity.Activity;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
/**
*
* @author Sergejs Aleksejevs
* @author David Withers
*/
@SuppressWarnings("serial")
public class XPathActivityConfigurationPanelProvider extends ActivityConfigurationPanel {
private XPathActivityConfigurationPanel configPanel;
private final ServiceRegistry serviceRegistry;
public XPathActivityConfigurationPanelProvider(Activity activity, ServiceRegistry serviceRegistry) {
super(activity);
this.serviceRegistry = serviceRegistry;
initialise();
}
@Override
protected void initialise() {
super.initialise();
removeAll();
setLayout(new BorderLayout());
// create actual contents of the config panel
this.configPanel = new XPathActivityConfigurationPanel();
add(configPanel, BorderLayout.CENTER);
// place the whole configuration panel into a raised area, so that
// automatically added 'Apply' / 'Close' buttons visually apply to
// the whole of the panel, not just part of it
this.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(12, 12, 2, 12),
BorderFactory.createRaisedBevelBorder()));
// Populate fields from activity configuration bean
refreshConfiguration();
}
/**
* Prepare a new configuration bean from the UI, to be returned with
* getConfiguration()
*/
@Override
public void noteConfiguration() {
if (configPanel.getCurrentXMLTree() != null) {
setProperty("exampleXmlDocument", configPanel.getCurrentXMLTree()
.getDocumentUsedToPopulateTree().asXML());
}
setProperty("xpathExpression", configPanel.getCurrentXPathExpression());
Map<String, String> xPathNamespaceMap = configPanel.getCurrentXPathNamespaceMap();
if (xPathNamespaceMap.isEmpty()) {
json.remove("xpathNamespaceMap");
} else {
ArrayNode namespaceMapNode = json.arrayNode();
for (Entry<String, String> namespaceMapping : xPathNamespaceMap.entrySet()) {
namespaceMapNode.addObject().put("prefix", namespaceMapping.getKey()).put("uri", namespaceMapping.getValue());
}
json.set("xpathNamespaceMap", namespaceMapNode);
}
configureInputPorts(serviceRegistry);
configureOutputPorts(serviceRegistry);
}
/**
* Check that user values in the UI are valid.
*/
@Override
public boolean checkValues() {
// the only validity condition is the correctness of the XPath
// expression -- so checking that
int xpathExpressionStatus = XPathActivityConfigurationBean.validateXPath(this.configPanel
.getCurrentXPathExpression());
// show an explicit warning message to explain the problem
if (xpathExpressionStatus == XPathActivityConfigurationBean.XPATH_EMPTY) {
JOptionPane.showMessageDialog(this, "XPath expression should not be empty",
"XPath Activity", JOptionPane.WARNING_MESSAGE);
} else if (xpathExpressionStatus == XPathActivityConfigurationBean.XPATH_INVALID) {
JOptionPane.showMessageDialog(this,
"<html><center>XPath expression is invalid - hover the mouse over the XPath status<br>"
+ "icon to get more information</center></html>", "XPath Activity",
JOptionPane.WARNING_MESSAGE);
}
return (xpathExpressionStatus == XPathActivityConfigurationBean.XPATH_VALID);
}
/**
* Update GUI from a changed configuration bean (perhaps by undo / redo).
*/
@Override
public void refreshConfiguration() {
if (json.has("exampleXmlDocument")) {
configPanel.setSourceXML(getProperty("exampleXmlDocument"));
configPanel.parseXML();
}
configPanel.setCurrentXPathExpression(getProperty("xpathExpression"));
Map<String, String> xpathNamespaceMap = new HashMap<>();
if (json.has("xpathNamespaceMap")) {
for (JsonNode namespaceMapping : json.get("xpathNamespaceMap")) {
xpathNamespaceMap.put(namespaceMapping.get("prefix").asText(), namespaceMapping.get("uri").asText());
}
}
configPanel.setCurrentXPathNamespaceMapValues(xpathNamespaceMap);
configPanel.reloadNamespaceMappingTableFromLocalMap();
// if the XML tree was populated, (re-)run the XPath expression
// and restore selection of nodes in the tree, if possible
if (configPanel.getCurrentXMLTree() != null) {
configPanel.runXPath(true);
// convert the XPath expression into the required list form;
// discard the first 'leg', as it's a side effect of
// "String.split()" -
// non-existent string to the left of the first "/"
String[] xpathLegs = getProperty("xpathExpression").split("/");
List<String> xpathLegList = new ArrayList<String>();
for (int i = 1; i < xpathLegs.length; i++) {
xpathLegList.add("/" + xpathLegs[i]);
}
// if nothing was obtained, we should be looking at the root node -
// but add the actual expression as it was, just in case
if (xpathLegList.size() == 0) {
xpathLegList.add(configPanel.getCurrentXPathExpression());
}
// invoke selection handler of the XML tree to do the job
configPanel.getCurrentXMLTree().getXMLTreeSelectionHandler()
.selectAllNodesThatMatchTheCurrentXPath(xpathLegList, null);
}
}
}