out-xpath: optional variable resolver for environment variables – can be used together with those from command line
3 * Copyright © 2014 František Kučera (frantovo.cz)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 package cz.frantovo.alt2xml.out.xpath;
20 import cz.frantovo.alt2xml.out.AbstractDOMAction;
21 import cz.frantovo.alt2xml.out.ActionContext;
22 import cz.frantovo.alt2xml.out.OutputActionException;
23 import java.io.PrintWriter;
24 import java.util.Arrays;
25 import java.util.HashMap;
26 import java.util.List;
28 import javax.xml.transform.dom.DOMResult;
29 import javax.xml.xpath.XPath;
30 import javax.xml.xpath.XPathExpression;
31 import javax.xml.xpath.XPathExpressionException;
32 import javax.xml.xpath.XPathFactory;
33 import javax.xml.xpath.XPathVariableResolver;
37 * @author Ing. František Kučera (frantovo.cz)
39 public class XPathAction extends AbstractDOMAction {
41 public static final String PARAMETER_TYPED_PARAMETERS = "typed-parameters";
42 public static final String PARAMETER_LINE_BREAK = "line-break";
43 public static final String PARAMETER_ENVIRONMENT_VARIABLES = "environment-variables";
44 private final boolean typedParameters;
45 private final boolean lineBreak;
46 private final boolean environmentVariables;
47 private final XPathFactory xpathFactory;
48 private final XPath xpath;
49 private final String expressionString;
50 private final XPathExpression xpathExpression;
52 public XPathAction(ActionContext actionContext) throws OutputActionException {
54 xpathFactory = XPathFactory.newInstance();
55 xpath = xpathFactory.newXPath();
57 final List<String> actionData = getActionContext().getActionData();
59 if (actionData.size() < 1) {
60 throw new OutputActionException("Please specify the XPath expression as action data");
63 typedParameters = Boolean.parseBoolean(actionContext.getActionProperties().getProperty(PARAMETER_TYPED_PARAMETERS));
64 lineBreak = Boolean.parseBoolean(actionContext.getActionProperties().getProperty(PARAMETER_LINE_BREAK, Boolean.TRUE.toString()));
65 environmentVariables = Boolean.parseBoolean(actionContext.getActionProperties().getProperty(PARAMETER_ENVIRONMENT_VARIABLES, Boolean.FALSE.toString()));
67 Map<String, Object> xpathParameters = new HashMap<>();
69 for (int i = 1; i < actionData.size(); i++) {
70 String parameterName = actionData.get(i++);
71 String parameterType = typedParameters ? actionData.get(i++) : PARAMETER_TYPE.STRING.name();
72 Object parameterValue = parseParameterValue(parameterType, actionData.get(i));
73 xpathParameters.put(parameterName, parameterValue);
76 XPathVariableResolver cliVariableResolver = new PropertiesVariableResolver(xpathParameters);
77 XPathVariableResolver variableResolver = environmentVariables ? new CompoundVariableResolver(cliVariableResolver, new EnvironmentVariableResolver()) : cliVariableResolver;
79 xpath.setXPathVariableResolver(variableResolver);
81 expressionString = actionData.get(0);
83 xpathExpression = xpath.compile(expressionString);
84 } catch (XPathExpressionException e) {
85 throw new OutputActionException("Unable to compile XPath: " + expressionString, e);
91 private enum PARAMETER_TYPE {
93 // TODO: wait for Java 8 widespread and rewrite with lambdas :-)
96 public Object parse(String value) {
102 public Object parse(String value) {
103 return Boolean.valueOf(value);
108 public Object parse(String value) {
109 return Integer.parseInt(value);
114 public Object parse(String value) {
115 return Long.parseLong(value);
120 public Object parse(String value) {
121 return Double.parseDouble(value);
125 public abstract Object parse(String value);
129 private static Object parseParameterValue(String type, String value) throws OutputActionException {
132 PARAMETER_TYPE parameterType = PARAMETER_TYPE.valueOf(type.toUpperCase());
135 return parameterType.parse(value);
136 } catch (IllegalArgumentException e) {
137 throw new OutputActionException("Unable to parse value: „" + value + "“ as " + parameterType.name());
139 } catch (IllegalArgumentException e) {
140 throw new OutputActionException(
141 "Invalid XPath parameter type: „" + type
142 + "“. Possible values are: " + Arrays.toString(PARAMETER_TYPE.values())
143 + " and are case insensitive.",
149 public void run(DOMResult domResult) throws OutputActionException {
151 String result = xpathExpression.evaluate(domResult.getNode());
152 try (PrintWriter out = new PrintWriter(getActionContext().getOutputStream())) {
158 } catch (XPathExpressionException e) {
159 throw new OutputActionException("Unable to evaluate XPath: " + xpathExpression, e);