Lines 18-25
Link Here
|
18 |
package org.apache.tools.ant.taskdefs; |
18 |
package org.apache.tools.ant.taskdefs; |
19 |
|
19 |
|
20 |
import java.io.File; |
20 |
import java.io.File; |
|
|
21 |
import java.util.ArrayList; |
22 |
import java.util.Collections; |
21 |
import java.util.Enumeration; |
23 |
import java.util.Enumeration; |
|
|
24 |
import java.util.HashMap; |
25 |
import java.util.List; |
26 |
import java.util.Map; |
22 |
import java.util.Vector; |
27 |
import java.util.Vector; |
|
|
28 |
import javax.xml.namespace.QName; |
29 |
import javax.xml.xpath.XPath; |
30 |
import javax.xml.xpath.XPathConstants; |
31 |
import javax.xml.xpath.XPathExpression; |
32 |
import javax.xml.xpath.XPathExpressionException; |
33 |
import javax.xml.xpath.XPathFactory; |
34 |
import javax.xml.xpath.XPathVariableResolver; |
23 |
import org.apache.tools.ant.AntClassLoader; |
35 |
import org.apache.tools.ant.AntClassLoader; |
24 |
import org.apache.tools.ant.BuildException; |
36 |
import org.apache.tools.ant.BuildException; |
25 |
import org.apache.tools.ant.DirectoryScanner; |
37 |
import org.apache.tools.ant.DirectoryScanner; |
Lines 76-82
Link Here
|
76 |
private String fileDirParameter = null; |
88 |
private String fileDirParameter = null; |
77 |
|
89 |
|
78 |
/** additional parameters to be passed to the stylesheets */ |
90 |
/** additional parameters to be passed to the stylesheets */ |
79 |
private Vector params = new Vector(); |
91 |
private List<Param> params = new ArrayList<Param>(); |
80 |
|
92 |
|
81 |
/** Input XML document to be used */ |
93 |
/** Input XML document to be used */ |
82 |
private File inFile = null; |
94 |
private File inFile = null; |
Lines 196-201
Link Here
|
196 |
* @since Ant 1.8.0 |
208 |
* @since Ant 1.8.0 |
197 |
*/ |
209 |
*/ |
198 |
private boolean failOnNoResources = true; |
210 |
private boolean failOnNoResources = true; |
|
|
211 |
|
212 |
/** |
213 |
* For evaluating template params |
214 |
* |
215 |
* @since Ant 1.9.2 |
216 |
*/ |
217 |
private XPathFactory xpathFactory; |
218 |
/** |
219 |
* For evaluating template params |
220 |
* |
221 |
* @since Ant 1.9.2 |
222 |
*/ |
223 |
private XPath xpath; |
199 |
|
224 |
|
200 |
/** |
225 |
/** |
201 |
* System properties to set during transformation. |
226 |
* System properties to set during transformation. |
Lines 305-312
Link Here
|
305 |
* Executes the task. |
330 |
* Executes the task. |
306 |
* |
331 |
* |
307 |
* @exception BuildException if there is an execution problem. |
332 |
* @exception BuildException if there is an execution problem. |
308 |
* @todo validate that if either in or our is defined, then both are |
333 |
* @todo validate that if either in or out is defined, then both are |
309 |
*/ |
334 |
*/ |
|
|
335 |
@Override |
310 |
public void execute() throws BuildException { |
336 |
public void execute() throws BuildException { |
311 |
if ("style".equals(getTaskType())) { |
337 |
if ("style".equals(getTaskType())) { |
312 |
log("Warning: the task name <style> is deprecated. Use <xslt> instead.", |
338 |
log("Warning: the task name <style> is deprecated. Use <xslt> instead.", |
Lines 937-943
Link Here
|
937 |
*/ |
963 |
*/ |
938 |
public Param createParam() { |
964 |
public Param createParam() { |
939 |
Param p = new Param(); |
965 |
Param p = new Param(); |
940 |
params.addElement(p); |
966 |
params.add(p); |
941 |
return p; |
967 |
return p; |
942 |
} |
968 |
} |
943 |
|
969 |
|
Lines 950-955
Link Here
|
950 |
|
976 |
|
951 |
/** The parameter's value */ |
977 |
/** The parameter's value */ |
952 |
private String expression = null; |
978 |
private String expression = null; |
|
|
979 |
|
980 |
/** |
981 |
* Type of the expression. |
982 |
* @see ParamType |
983 |
*/ |
984 |
private String type; |
953 |
|
985 |
|
954 |
private Object ifCond; |
986 |
private Object ifCond; |
955 |
private Object unlessCond; |
987 |
private Object unlessCond; |
Lines 974-988
Link Here
|
974 |
} |
1006 |
} |
975 |
|
1007 |
|
976 |
/** |
1008 |
/** |
977 |
* The parameter value |
1009 |
* The parameter value - can be a primitive value or XPath expression. |
978 |
* NOTE : was intended to be an XSL expression. |
1010 |
* @param expression the parameter's value/expression. |
979 |
* @param expression the parameter's value. |
1011 |
* @see #setType(java.lang.String) |
980 |
*/ |
1012 |
*/ |
981 |
public void setExpression(String expression) { |
1013 |
public void setExpression(String expression) { |
982 |
this.expression = expression; |
1014 |
this.expression = expression; |
983 |
} |
1015 |
} |
984 |
|
1016 |
|
985 |
/** |
1017 |
/** |
|
|
1018 |
* @see ParamType |
1019 |
* @since Ant 1.9.2 |
1020 |
*/ |
1021 |
public void setType(String type) { |
1022 |
this.type = type; |
1023 |
} |
1024 |
|
1025 |
/** |
986 |
* Get the parameter name |
1026 |
* Get the parameter name |
987 |
* |
1027 |
* |
988 |
* @return the parameter name |
1028 |
* @return the parameter name |
Lines 1000-1005
Link Here
|
1000 |
* |
1040 |
* |
1001 |
* @return the parameter value |
1041 |
* @return the parameter value |
1002 |
* @exception BuildException if the value is not set. |
1042 |
* @exception BuildException if the value is not set. |
|
|
1043 |
* @see #getType() |
1003 |
*/ |
1044 |
*/ |
1004 |
public String getExpression() throws BuildException { |
1045 |
public String getExpression() throws BuildException { |
1005 |
if (expression == null) { |
1046 |
if (expression == null) { |
Lines 1009-1014
Link Here
|
1009 |
} |
1050 |
} |
1010 |
|
1051 |
|
1011 |
/** |
1052 |
/** |
|
|
1053 |
* @see ParamType |
1054 |
* @since Ant 1.9.2 |
1055 |
*/ |
1056 |
public String getType() { |
1057 |
return type; |
1058 |
} |
1059 |
|
1060 |
/** |
1012 |
* Set whether this param should be used. It will be used if |
1061 |
* Set whether this param should be used. It will be used if |
1013 |
* the expression evaluates to true or the name of a property |
1062 |
* the expression evaluates to true or the name of a property |
1014 |
* which has been set, otherwise it won't. |
1063 |
* which has been set, otherwise it won't. |
Lines 1061-1067
Link Here
|
1061 |
&& ph.testUnlessCondition(unlessCond); |
1110 |
&& ph.testUnlessCondition(unlessCond); |
1062 |
} |
1111 |
} |
1063 |
} // Param |
1112 |
} // Param |
|
|
1113 |
|
1114 |
/** |
1115 |
* Constants for types of the parameter expression. |
1116 |
* |
1117 |
* The expression can be: |
1118 |
* <ul> |
1119 |
* <li>primitive type that will be parsed from the string value e.g. |
1120 |
* {@linkplain Integer#parseInt(java.lang.String)}</li> |
1121 |
* <li>XPath expression that will be evaluated (outside of the transformed |
1122 |
* document - on empty one) and casted to given type. Inside XPath |
1123 |
* expressions the Ant variables (properties) can be used (as XPath |
1124 |
* variables - e.g. $variable123). n.b. placeholders in form of |
1125 |
* ${variable123} will be replaced with their values before evaluating the |
1126 |
* XPath expression (so it can be used for dynamic XPath function names and |
1127 |
* other hacks).</li> |
1128 |
* </ul> |
1129 |
* The parameter will be then passed to the XSLT template. |
1130 |
* |
1131 |
* Default type (if omited) is primitive String. So if the expression is e.g |
1132 |
* "true" with no type, in XSLT it will be only a text string, not true |
1133 |
* boolean. |
1134 |
* |
1135 |
* @see Param#setType(java.lang.String) |
1136 |
* @see Param#setExpression(java.lang.String) |
1137 |
* @since Ant 1.9.2 |
1138 |
*/ |
1139 |
public static class ParamType { |
1064 |
|
1140 |
|
|
|
1141 |
public static final String STRING = "string"; |
1142 |
public static final String BOOLEAN = "boolean"; |
1143 |
public static final String INT = "int"; |
1144 |
public static final String LONG = "long"; |
1145 |
public static final String DOUBLE = "double"; |
1146 |
|
1147 |
|
1148 |
private static final String XPATH_PREFIX = "xpath:"; |
1149 |
|
1150 |
public static final String XPATH_STRING = "xpath:string"; |
1151 |
public static final String XPATH_BOOLEAN = "xpath:boolean"; |
1152 |
public static final String XPATH_NUMBER = "xpath:number"; |
1153 |
public static final String XPATH_NODE = "xpath:node"; |
1154 |
public static final String XPATH_NODESET = "xpath:nodeset"; |
1155 |
|
1156 |
private static final Map<String,QName> XPATH_TYPES; |
1157 |
|
1158 |
static { |
1159 |
Map<String, QName> m = new HashMap<String, QName>(); |
1160 |
m.put(XPATH_STRING, XPathConstants.STRING); |
1161 |
m.put(XPATH_BOOLEAN, XPathConstants.BOOLEAN); |
1162 |
m.put(XPATH_NUMBER, XPathConstants.NUMBER); |
1163 |
m.put(XPATH_NODE, XPathConstants.NODE); |
1164 |
m.put(XPATH_NODESET, XPathConstants.NODESET); |
1165 |
XPATH_TYPES = Collections.unmodifiableMap(m); |
1166 |
} |
1167 |
|
1168 |
private ParamType() { } |
1169 |
} |
1170 |
|
1065 |
/** |
1171 |
/** |
1066 |
* Create an instance of an output property to be configured. |
1172 |
* Create an instance of an output property to be configured. |
1067 |
* @return the newly created output property. |
1173 |
* @return the newly created output property. |
Lines 1119-1130
Link Here
|
1119 |
} |
1225 |
} |
1120 |
|
1226 |
|
1121 |
/** |
1227 |
/** |
1122 |
* Initialize internal instance of XMLCatalog |
1228 |
* Initialize internal instance of XMLCatalog. |
|
|
1229 |
* Initialize XPath for parameter evaluation. |
1123 |
* @throws BuildException on error |
1230 |
* @throws BuildException on error |
1124 |
*/ |
1231 |
*/ |
|
|
1232 |
@Override |
1125 |
public void init() throws BuildException { |
1233 |
public void init() throws BuildException { |
1126 |
super.init(); |
1234 |
super.init(); |
1127 |
xmlCatalog.setProject(getProject()); |
1235 |
xmlCatalog.setProject(getProject()); |
|
|
1236 |
|
1237 |
xpathFactory = XPathFactory.newInstance(); |
1238 |
xpath = xpathFactory.newXPath(); |
1239 |
xpath.setXPathVariableResolver(new XPathVariableResolver() { |
1240 |
public Object resolveVariable(QName variableName) { |
1241 |
return getProject().getProperty(variableName.toString()); |
1242 |
} |
1243 |
}); |
1128 |
} |
1244 |
} |
1129 |
|
1245 |
|
1130 |
/** |
1246 |
/** |
Lines 1179-1188
Link Here
|
1179 |
return; |
1295 |
return; |
1180 |
} |
1296 |
} |
1181 |
} |
1297 |
} |
1182 |
for (Enumeration e = params.elements(); e.hasMoreElements();) { |
1298 |
for (Param p : params) { |
1183 |
Param p = (Param) e.nextElement(); |
|
|
1184 |
if (p.shouldUse()) { |
1299 |
if (p.shouldUse()) { |
1185 |
liaison.addParam(p.getName(), p.getExpression()); |
1300 |
Object evaluatedParam = evaluateParam(p); |
|
|
1301 |
if (liaison instanceof XSLTLiaison4) { |
1302 |
((XSLTLiaison4)liaison).addParam(p.getName(), evaluatedParam); |
1303 |
} else { |
1304 |
if (evaluatedParam == null || evaluatedParam instanceof String) { |
1305 |
liaison.addParam(p.getName(), (String)evaluatedParam); |
1306 |
} else { |
1307 |
log("XSLTLiaison '" + liaison.getClass().getName() |
1308 |
+ "' supports only String parameters. Converting parameter '" + p.getName() |
1309 |
+ "' to its String value '" + evaluatedParam, Project.MSG_WARN); |
1310 |
liaison.addParam(p.getName(), String.valueOf(evaluatedParam)); |
1311 |
} |
1312 |
} |
1186 |
} |
1313 |
} |
1187 |
} |
1314 |
} |
1188 |
} catch (Exception ex) { |
1315 |
} catch (Exception ex) { |
Lines 1190-1196
Link Here
|
1190 |
handleTransformationError(ex); |
1317 |
handleTransformationError(ex); |
1191 |
} |
1318 |
} |
1192 |
} |
1319 |
} |
|
|
1320 |
|
1321 |
/** |
1322 |
* Evaluates parameter expression according to its type. |
1323 |
* |
1324 |
* @param param parameter from Ant build file |
1325 |
* @return value to be passed to XSLT as parameter |
1326 |
* @throws IllegalArgumentException if param type is unsupported |
1327 |
* @throws NumberFormatException if expression of numeric type is not |
1328 |
* desired numeric type |
1329 |
* @throws XPathExpressionException if XPath expression can not be compiled |
1330 |
* @since Ant 1.9.2 |
1331 |
*/ |
1332 |
private Object evaluateParam(Param param) throws XPathExpressionException { |
1333 |
String type = param.getType(); |
1334 |
String expression = param.getExpression(); |
1193 |
|
1335 |
|
|
|
1336 |
if (type == null || ParamType.STRING.equals(type)) { |
1337 |
return expression; |
1338 |
} else if (ParamType.BOOLEAN.equals(type)) { |
1339 |
return Boolean.parseBoolean(expression); |
1340 |
} else if (ParamType.DOUBLE.equals(type)) { |
1341 |
return Double.parseDouble(expression); |
1342 |
} else if (ParamType.INT.equals(type)) { |
1343 |
return Integer.parseInt(expression); |
1344 |
} else if (ParamType.LONG.equals(type)) { |
1345 |
return Long.parseLong(expression); |
1346 |
} else if (type.startsWith(ParamType.XPATH_PREFIX)) { |
1347 |
XPathExpression xpe = xpath.compile(expression); |
1348 |
QName xpathType = ParamType.XPATH_TYPES.get(type); |
1349 |
if (xpathType == null) { |
1350 |
throw new IllegalArgumentException("Invalid XSLT parameter XPath type: " + type); |
1351 |
} else { |
1352 |
// null = evaluate XPath on empty XML document |
1353 |
return xpe.evaluate((Object) null, xpathType); |
1354 |
} |
1355 |
} else { |
1356 |
throw new IllegalArgumentException("Invalid XSLT parameter type: " + type); |
1357 |
} |
1358 |
} |
1359 |
|
1194 |
/** |
1360 |
/** |
1195 |
* Sets file parameter(s) for directory and filename if the attribute |
1361 |
* Sets file parameter(s) for directory and filename if the attribute |
1196 |
* 'filenameparameter' or 'filedirparameter' are set in the task. |
1362 |
* 'filenameparameter' or 'filedirparameter' are set in the task. |