View | Details | Raw Unified | Return to bug 21525
Collapse All | Expand All

(-)src/main/org/apache/tools/ant/taskdefs/XSLTLiaison.java (+1 lines)
Lines 51-56 Link Here
51
     * @param name the parameter name.
51
     * @param name the parameter name.
52
     * @param expression the parameter value as an expression string.
52
     * @param expression the parameter value as an expression string.
53
     * @throws Exception thrown if any problems happens.
53
     * @throws Exception thrown if any problems happens.
54
     * @see XSLTLiaison4#addParam(java.lang.String, java.lang.Object) 
54
     * @since Ant 1.3
55
     * @since Ant 1.3
55
     */
56
     */
56
    void addParam(String name, String expression) throws Exception;
57
    void addParam(String name, String expression) throws Exception;
(-)src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java (-10 / +176 lines)
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.
(-)src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java (-4 / +13 lines)
Lines 47-53 Link Here
47
import javax.xml.transform.TransformerConfigurationException;
47
import javax.xml.transform.TransformerConfigurationException;
48
import org.apache.tools.ant.BuildException;
48
import org.apache.tools.ant.BuildException;
49
import org.apache.tools.ant.Project;
49
import org.apache.tools.ant.Project;
50
import org.apache.tools.ant.taskdefs.XSLTLiaison3;
50
import org.apache.tools.ant.taskdefs.XSLTLiaison4;
51
import org.apache.tools.ant.taskdefs.XSLTLogger;
51
import org.apache.tools.ant.taskdefs.XSLTLogger;
52
import org.apache.tools.ant.taskdefs.XSLTLoggerAware;
52
import org.apache.tools.ant.taskdefs.XSLTLoggerAware;
53
import org.apache.tools.ant.taskdefs.XSLTProcess;
53
import org.apache.tools.ant.taskdefs.XSLTProcess;
Lines 68-74 Link Here
68
 *
68
 *
69
 * @since Ant 1.3
69
 * @since Ant 1.3
70
 */
70
 */
71
public class TraXLiaison implements XSLTLiaison3, ErrorListener, XSLTLoggerAware {
71
public class TraXLiaison implements XSLTLiaison4, ErrorListener, XSLTLoggerAware {
72
72
73
    /**
73
    /**
74
     * Helper for transforming filenames to URIs.
74
     * Helper for transforming filenames to URIs.
Lines 118-124 Link Here
118
    private Vector outputProperties = new Vector();
118
    private Vector outputProperties = new Vector();
119
119
120
    /** stylesheet parameters */
120
    /** stylesheet parameters */
121
    private Hashtable params = new Hashtable();
121
    private Hashtable<String, Object> params = new Hashtable<String, Object>();
122
122
123
    /** factory attributes */
123
    /** factory attributes */
124
    private Vector attributes = new Vector();
124
    private Vector attributes = new Vector();
Lines 369-375 Link Here
369
        for (final Enumeration enumeration = params.keys();
369
        for (final Enumeration enumeration = params.keys();
370
             enumeration.hasMoreElements();) {
370
             enumeration.hasMoreElements();) {
371
            final String name = (String) enumeration.nextElement();
371
            final String name = (String) enumeration.nextElement();
372
            final String value = (String) params.get(name);
372
            final Object value = params.get(name);
373
            transformer.setParameter(name, value);
373
            transformer.setParameter(name, value);
374
        }
374
        }
375
    }
375
    }
Lines 505-510 Link Here
505
    public void addParam(String name, String value) {
505
    public void addParam(String name, String value) {
506
        params.put(name, value);
506
        params.put(name, value);
507
    }
507
    }
508
    
509
    /**
510
     * Add a parameter.
511
     * @param name the name of the parameter
512
     * @param value the value of the parameter
513
     */
514
    public void addParam(String name, Object value) {
515
        params.put(name, value);
516
    }
508
517
509
    /**
518
    /**
510
     * Set a logger.
519
     * Set a logger.
(-)src/main/org/apache/tools/ant/taskdefs/XSLTLiaison4.java (+40 lines)
Line 0 Link Here
1
/*
2
 *  Licensed to the Apache Software Foundation (ASF) under one or more
3
 *  contributor license agreements.  See the NOTICE file distributed with
4
 *  this work for additional information regarding copyright ownership.
5
 *  The ASF licenses this file to You under the Apache License, Version 2.0
6
 *  (the "License"); you may not use this file except in compliance with
7
 *  the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 *  Unless required by applicable law or agreed to in writing, software
12
 *  distributed under the License is distributed on an "AS IS" BASIS,
13
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 *  See the License for the specific language governing permissions and
15
 *  limitations under the License.
16
 *
17
 */
18
package org.apache.tools.ant.taskdefs;
19
20
/**
21
 * Extends Proxy interface for XSLT processors: adds support for XSLT parameters
22
 * of various types (not only String)
23
 *
24
 *
25
 * @see XSLTProcess
26
 * @since Ant 1.9.2
27
 */
28
public interface XSLTLiaison4 extends XSLTLiaison3 {
29
30
    /**
31
     * Add a parameter to be set during the XSL transformation.
32
     *
33
     * @param name the parameter name.
34
     * @param value the parameter value as String, Boolean, int, etc.
35
     * @throws Exception thrown if any problems happens.
36
     * @since Ant 1.9.2
37
     * @see Transformer#setParameter(java.lang.String, java.lang.Object)
38
     */
39
    void addParam(String name, Object value) throws Exception;
40
}

Return to bug 21525