diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java | 1689 |
1 files changed, 0 insertions, 1689 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java deleted file mode 100644 index 4fe31260..00000000 --- a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java +++ /dev/null @@ -1,1689 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.tools.ant.taskdefs; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.EnumMap; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; -import java.util.Vector; - -import javax.xml.namespace.QName; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; -import javax.xml.xpath.XPathVariableResolver; - -import org.apache.tools.ant.AntClassLoader; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.DirectoryScanner; -import org.apache.tools.ant.DynamicConfigurator; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.PropertyHelper; -import org.apache.tools.ant.types.CommandlineJava; -import org.apache.tools.ant.types.Environment; -import org.apache.tools.ant.types.Mapper; -import org.apache.tools.ant.types.Path; -import org.apache.tools.ant.types.PropertySet; -import org.apache.tools.ant.types.Reference; -import org.apache.tools.ant.types.Resource; -import org.apache.tools.ant.types.ResourceCollection; -import org.apache.tools.ant.types.XMLCatalog; -import org.apache.tools.ant.types.resources.FileProvider; -import org.apache.tools.ant.types.resources.FileResource; -import org.apache.tools.ant.types.resources.Resources; -import org.apache.tools.ant.types.resources.Union; -import org.apache.tools.ant.util.FileNameMapper; -import org.apache.tools.ant.util.FileUtils; -import org.apache.tools.ant.util.ResourceUtils; - -/** - * Processes a set of XML documents via XSLT. This is - * useful for building views of XML based documentation. - * - * - * @since Ant 1.1 - * - * @ant.task name="xslt" category="xml" - */ - -public class XSLTProcess extends MatchingTask implements XSLTLogger { - /** destination directory */ - private File destDir = null; - - /** where to find the source XML file, default is the project's basedir */ - private File baseDir = null; - - /** XSL stylesheet as a filename */ - private String xslFile = null; - - /** XSL stylesheet as a {@link org.apache.tools.ant.types.Resource} */ - private Resource xslResource = null; - - /** extension of the files produced by XSL processing */ - private String targetExtension = ".html"; - - /** name for XSL parameter containing the filename */ - private String fileNameParameter = null; - - /** name for XSL parameter containing the file directory */ - private String fileDirParameter = null; - - /** additional parameters to be passed to the stylesheets */ - private final List<Param> params = new ArrayList<Param>(); - - /** Input XML document to be used */ - private File inFile = null; - - /** Output file */ - private File outFile = null; - - /** The name of the XSL processor to use */ - private String processor; - - /** Classpath to use when trying to load the XSL processor */ - private Path classpath = null; - - /** The Liaison implementation to use to communicate with the XSL - * processor */ - private XSLTLiaison liaison; - - /** Flag which indicates if the stylesheet has been loaded into - * the processor */ - private boolean stylesheetLoaded = false; - - /** force output of target files even if they already exist */ - private boolean force = false; - - /** XSL output properties to be used */ - private final Vector outputProperties = new Vector(); - - /** for resolving entities such as dtds */ - private final XMLCatalog xmlCatalog = new XMLCatalog(); - - /** Utilities used for file operations */ - private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); - - /** - * Whether to style all files in the included directories as well. - * - * @since Ant 1.5 - */ - private boolean performDirectoryScan = true; - - /** - * factory element for TraX processors only - * @since Ant 1.6 - */ - private Factory factory = null; - - /** - * whether to reuse Transformer if transforming multiple files. - * @since 1.5.2 - */ - private boolean reuseLoadedStylesheet = true; - - /** - * AntClassLoader for the nested <classpath> - if set. - * - * <p>We keep this here in order to reset the context classloader - * in execute. We can't use liaison.getClass().getClassLoader() - * since the actual liaison class may have been loaded by a loader - * higher up (system classloader, for example).</p> - * - * @since Ant 1.6.2 - */ - private AntClassLoader loader = null; - - /** - * Mapper to use when a set of files gets processed. - * - * @since Ant 1.6.2 - */ - private Mapper mapperElement = null; - - /** - * Additional resource collections to process. - * - * @since Ant 1.7 - */ - private final Union resources = new Union(); - - /** - * Whether to use the implicit fileset. - * - * @since Ant 1.7 - */ - private boolean useImplicitFileset = true; - - /** - * The default processor is trax - * @since Ant 1.7 - */ - public static final String PROCESSOR_TRAX = "trax"; - - /** - * whether to suppress warnings. - * - * @since Ant 1.8.0 - */ - private boolean suppressWarnings = false; - - /** - * whether to fail the build if an error occurs during transformation. - * - * @since Ant 1.8.0 - */ - private boolean failOnTransformationError = true; - - /** - * whether to fail the build if an error occurs. - * - * @since Ant 1.8.0 - */ - private boolean failOnError = true; - - /** - * Whether the build should fail if the nested resource collection - * is empty. - * - * @since Ant 1.8.0 - */ - private boolean failOnNoResources = true; - - /** - * For evaluating template params - * - * @since Ant 1.9.3 - */ - private XPathFactory xpathFactory; - /** - * For evaluating template params - * - * @since Ant 1.9.3 - */ - private XPath xpath; - - /** - * System properties to set during transformation. - * - * @since Ant 1.8.0 - */ - private final CommandlineJava.SysProperties sysProperties = - new CommandlineJava.SysProperties(); - - /** - * Trace configuration for Xalan2. - * - * @since Ant 1.8.0 - */ - private TraceConfiguration traceConfiguration; - - /** - * Creates a new XSLTProcess Task. - */ - public XSLTProcess() { - } //-- XSLTProcess - - /** - * Whether to style all files in the included directories as well; - * optional, default is true. - * - * @param b true if files in included directories are processed. - * @since Ant 1.5 - */ - public void setScanIncludedDirectories(final boolean b) { - performDirectoryScan = b; - } - - /** - * Controls whether the stylesheet is reloaded for every transform. - * - * <p>Setting this to true may get around a bug in certain - * Xalan-J versions, default is false.</p> - * @param b a <code>boolean</code> value - * @since Ant 1.5.2 - */ - public void setReloadStylesheet(final boolean b) { - reuseLoadedStylesheet = !b; - } - - /** - * Defines the mapper to map source to destination files. - * @param mapper the mapper to use - * @exception BuildException if more than one mapper is defined - * @since Ant 1.6.2 - */ - public void addMapper(final Mapper mapper) { - if (mapperElement != null) { - handleError("Cannot define more than one mapper"); - } else { - mapperElement = mapper; - } - } - - /** - * Adds a collection of resources to style in addition to the - * given file or the implicit fileset. - * - * @param rc the collection of resources to style - * @since Ant 1.7 - */ - public void add(final ResourceCollection rc) { - resources.add(rc); - } - - /** - * Add a nested <style> element. - * @param rc the configured Resources object represented as <style>. - * @since Ant 1.7 - */ - public void addConfiguredStyle(final Resources rc) { - if (rc.size() != 1) { - handleError("The style element must be specified with exactly one" - + " nested resource."); - } else { - setXslResource(rc.iterator().next()); - } - } - - /** - * API method to set the XSL Resource. - * @param xslResource Resource to set as the stylesheet. - * @since Ant 1.7 - */ - public void setXslResource(final Resource xslResource) { - this.xslResource = xslResource; - } - - /** - * Adds a nested filenamemapper. - * @param fileNameMapper the mapper to add - * @exception BuildException if more than one mapper is defined - * @since Ant 1.7.0 - */ - public void add(final FileNameMapper fileNameMapper) throws BuildException { - final Mapper mapper = new Mapper(getProject()); - mapper.add(fileNameMapper); - addMapper(mapper); - } - - /** - * Executes the task. - * - * @exception BuildException if there is an execution problem. - * @todo validate that if either in or out is defined, then both are - */ - @Override - public void execute() throws BuildException { - if ("style".equals(getTaskType())) { - log("Warning: the task name <style> is deprecated. Use <xslt> instead.", - Project.MSG_WARN); - } - final File savedBaseDir = baseDir; - - DirectoryScanner scanner; - String[] list; - String[] dirs; - - final String baseMessage = - "specify the stylesheet either as a filename in style attribute " - + "or as a nested resource"; - - if (xslResource == null && xslFile == null) { - handleError(baseMessage); - return; - } - if (xslResource != null && xslFile != null) { - handleError(baseMessage + " but not as both"); - return; - } - if (inFile != null && !inFile.exists()) { - handleError("input file " + inFile + " does not exist"); - return; - } - try { - setupLoader(); - - if (sysProperties.size() > 0) { - sysProperties.setSystem(); - } - - Resource styleResource; - if (baseDir == null) { - baseDir = getProject().getBaseDir(); - } - liaison = getLiaison(); - - // check if liaison wants to log errors using us as logger - if (liaison instanceof XSLTLoggerAware) { - ((XSLTLoggerAware) liaison).setLogger(this); - } - log("Using " + liaison.getClass().toString(), Project.MSG_VERBOSE); - - if (xslFile != null) { - // If we enter here, it means that the stylesheet is supplied - // via style attribute - File stylesheet = getProject().resolveFile(xslFile); - if (!stylesheet.exists()) { - final File alternative = FILE_UTILS.resolveFile(baseDir, xslFile); - /* - * shouldn't throw out deprecation warnings before we know, - * the wrong version has been used. - */ - if (alternative.exists()) { - log("DEPRECATED - the 'style' attribute should be " - + "relative to the project's"); - log(" basedir, not the tasks's basedir."); - stylesheet = alternative; - } - } - final FileResource fr = new FileResource(); - fr.setProject(getProject()); - fr.setFile(stylesheet); - styleResource = fr; - } else { - styleResource = xslResource; - } - - if (!styleResource.isExists()) { - handleError("stylesheet " + styleResource + " doesn't exist."); - return; - } - - // if we have an in file and out then process them - if (inFile != null && outFile != null) { - process(inFile, outFile, styleResource); - return; - } - /* - * if we get here, in and out have not been specified, we are - * in batch processing mode. - */ - - //-- make sure destination directory exists... - checkDest(); - - if (useImplicitFileset) { - scanner = getDirectoryScanner(baseDir); - log("Transforming into " + destDir, Project.MSG_INFO); - - // Process all the files marked for styling - list = scanner.getIncludedFiles(); - for (int i = 0; i < list.length; ++i) { - process(baseDir, list[i], destDir, styleResource); - } - if (performDirectoryScan) { - // Process all the directories marked for styling - dirs = scanner.getIncludedDirectories(); - for (int j = 0; j < dirs.length; ++j) { - list = new File(baseDir, dirs[j]).list(); - for (int i = 0; i < list.length; ++i) { - process(baseDir, dirs[j] + File.separator + list[i], destDir, - styleResource); - } - } - } - } else { // only resource collections, there better be some - if (resources.size() == 0) { - if (failOnNoResources) { - handleError("no resources specified"); - } - return; - } - } - processResources(styleResource); - } finally { - if (loader != null) { - loader.resetThreadContextLoader(); - loader.cleanup(); - loader = null; - } - if (sysProperties.size() > 0) { - sysProperties.restoreSystem(); - } - liaison = null; - stylesheetLoaded = false; - baseDir = savedBaseDir; - } - } - - /** - * Set whether to check dependencies, or always generate; - * optional, default is false. - * - * @param force true if always generate. - */ - public void setForce(final boolean force) { - this.force = force; - } - - /** - * Set the base directory; - * optional, default is the project's basedir. - * - * @param dir the base directory - **/ - public void setBasedir(final File dir) { - baseDir = dir; - } - - /** - * Set the destination directory into which the XSL result - * files should be copied to; - * required, unless <tt>in</tt> and <tt>out</tt> are - * specified. - * @param dir the name of the destination directory - **/ - public void setDestdir(final File dir) { - destDir = dir; - } - - /** - * Set the desired file extension to be used for the target; - * optional, default is html. - * @param name the extension to use - **/ - public void setExtension(final String name) { - targetExtension = name; - } - - /** - * Name of the stylesheet to use - given either relative - * to the project's basedir or as an absolute path; required. - * - * @param xslFile the stylesheet to use - */ - public void setStyle(final String xslFile) { - this.xslFile = xslFile; - } - - /** - * Set the optional classpath to the XSL processor - * - * @param classpath the classpath to use when loading the XSL processor - */ - public void setClasspath(final Path classpath) { - createClasspath().append(classpath); - } - - /** - * Set the optional classpath to the XSL processor - * - * @return a path instance to be configured by the Ant core. - */ - public Path createClasspath() { - if (classpath == null) { - classpath = new Path(getProject()); - } - return classpath.createPath(); - } - - /** - * Set the reference to an optional classpath to the XSL processor - * - * @param r the id of the Ant path instance to act as the classpath - * for loading the XSL processor - */ - public void setClasspathRef(final Reference r) { - createClasspath().setRefid(r); - } - - /** - * Set the name of the XSL processor to use; optional, default trax. - * - * @param processor the name of the XSL processor - */ - public void setProcessor(final String processor) { - this.processor = processor; - } - - /** - * Whether to use the implicit fileset. - * - * <p>Set this to false if you want explicit control with nested - * resource collections.</p> - * @param useimplicitfileset set to true if you want to use implicit fileset - * @since Ant 1.7 - */ - public void setUseImplicitFileset(final boolean useimplicitfileset) { - useImplicitFileset = useimplicitfileset; - } - - /** - * Add the catalog to our internal catalog - * - * @param xmlCatalog the XMLCatalog instance to use to look up DTDs - */ - public void addConfiguredXMLCatalog(final XMLCatalog xmlCatalog) { - this.xmlCatalog.addConfiguredXMLCatalog(xmlCatalog); - } - - /** - * Pass the filename of the current processed file as a xsl parameter - * to the transformation. This value sets the name of that xsl parameter. - * - * @param fileNameParameter name of the xsl parameter retrieving the - * current file name - */ - public void setFileNameParameter(final String fileNameParameter) { - this.fileNameParameter = fileNameParameter; - } - - /** - * Pass the directory name of the current processed file as a xsl parameter - * to the transformation. This value sets the name of that xsl parameter. - * - * @param fileDirParameter name of the xsl parameter retrieving the - * current file directory - */ - public void setFileDirParameter(final String fileDirParameter) { - this.fileDirParameter = fileDirParameter; - } - - /** - * Whether to suppress warning messages of the processor. - * - * @since Ant 1.8.0 - */ - public void setSuppressWarnings(final boolean b) { - suppressWarnings = b; - } - - /** - * Whether to suppress warning messages of the processor. - * - * @since Ant 1.8.0 - */ - public boolean getSuppressWarnings() { - return suppressWarnings; - } - - /** - * Whether transformation errors should make the build fail. - * - * @since Ant 1.8.0 - */ - public void setFailOnTransformationError(final boolean b) { - failOnTransformationError = b; - } - - /** - * Whether any errors should make the build fail. - * - * @since Ant 1.8.0 - */ - public void setFailOnError(final boolean b) { - failOnError = b; - } - - /** - * Whether the build should fail if the nested resource collection is empty. - * - * @since Ant 1.8.0 - */ - public void setFailOnNoResources(final boolean b) { - failOnNoResources = b; - } - - /** - * A system property to set during transformation. - * - * @since Ant 1.8.0 - */ - public void addSysproperty(final Environment.Variable sysp) { - sysProperties.addVariable(sysp); - } - - /** - * A set of system properties to set during transformation. - * - * @since Ant 1.8.0 - */ - public void addSyspropertyset(final PropertySet sysp) { - sysProperties.addSyspropertyset(sysp); - } - - /** - * Enables Xalan2 traces and uses the given configuration. - * - * <p>Note that this element doesn't have any effect with a - * processor other than trax or if the Transformer is not Xalan2's - * transformer implementation.</p> - * - * @since Ant 1.8.0 - */ - public TraceConfiguration createTrace() { - if (traceConfiguration != null) { - throw new BuildException("can't have more than one trace" - + " configuration"); - } - traceConfiguration = new TraceConfiguration(); - return traceConfiguration; - } - - /** - * Configuration for Xalan2 traces. - * - * @since Ant 1.8.0 - */ - public TraceConfiguration getTraceConfiguration() { - return traceConfiguration; - } - - /** - * Load processor here instead of in setProcessor - this will be - * called from within execute, so we have access to the latest - * classpath. - * - * @param proc the name of the processor to load. - * @exception Exception if the processor cannot be loaded. - */ - private void resolveProcessor(final String proc) throws Exception { - if (proc.equals(PROCESSOR_TRAX)) { - liaison = new org.apache.tools.ant.taskdefs.optional.TraXLiaison(); - } else { - //anything else is a classname - final Class clazz = loadClass(proc); - liaison = (XSLTLiaison) clazz.newInstance(); - } - } - - /** - * Load named class either via the system classloader or a given - * custom classloader. - * - * As a side effect, the loader is set as the thread context classloader - * @param classname the name of the class to load. - * @return the requested class. - * @exception Exception if the class could not be loaded. - */ - private Class loadClass(final String classname) throws Exception { - setupLoader(); - if (loader == null) { - return Class.forName(classname); - } - return Class.forName(classname, true, loader); - } - - /** - * If a custom classpath has been defined but no loader created - * yet, create the classloader and set it as the context - * classloader. - */ - private void setupLoader() { - if (classpath != null && loader == null) { - loader = getProject().createClassLoader(classpath); - loader.setThreadContextLoader(); - } - } - - /** - * Specifies the output name for the styled result from the - * <tt>in</tt> attribute; required if <tt>in</tt> is set - * - * @param outFile the output File instance. - */ - public void setOut(final File outFile) { - this.outFile = outFile; - } - - /** - * specifies a single XML document to be styled. Should be used - * with the <tt>out</tt> attribute; ; required if <tt>out</tt> is set - * - * @param inFile the input file - */ - public void setIn(final File inFile) { - this.inFile = inFile; - } - - /** - * Throws a BuildException if the destination directory hasn't - * been specified. - * @since Ant 1.7 - */ - private void checkDest() { - if (destDir == null) { - handleError("destdir attributes must be set!"); - } - } - - /** - * Styles all existing resources. - * - * @param stylesheet style sheet to use - * @since Ant 1.7 - */ - private void processResources(final Resource stylesheet) { - for (final Resource r : resources) { - if (!r.isExists()) { - continue; - } - File base = baseDir; - String name = r.getName(); - final FileProvider fp = r.as(FileProvider.class); - if (fp != null) { - final FileResource f = ResourceUtils.asFileResource(fp); - base = f.getBaseDir(); - if (base == null) { - name = f.getFile().getAbsolutePath(); - } - } - process(base, name, destDir, stylesheet); - } - } - - /** - * Processes the given input XML file and stores the result - * in the given resultFile. - * - * @param baseDir the base directory for resolving files. - * @param xmlFile the input file - * @param destDir the destination directory - * @param stylesheet the stylesheet to use. - * @exception BuildException if the processing fails. - */ - private void process(final File baseDir, final String xmlFile, final File destDir, final Resource stylesheet) - throws BuildException { - - File outF = null; - File inF = null; - - try { - final long styleSheetLastModified = stylesheet.getLastModified(); - inF = new File(baseDir, xmlFile); - - if (inF.isDirectory()) { - log("Skipping " + inF + " it is a directory.", Project.MSG_VERBOSE); - return; - } - FileNameMapper mapper = null; - if (mapperElement != null) { - mapper = mapperElement.getImplementation(); - } else { - mapper = new StyleMapper(); - } - - final String[] outFileName = mapper.mapFileName(xmlFile); - if (outFileName == null || outFileName.length == 0) { - log("Skipping " + inFile + " it cannot get mapped to output.", Project.MSG_VERBOSE); - return; - } else if (outFileName == null || outFileName.length > 1) { - log("Skipping " + inFile + " its mapping is ambiguos.", Project.MSG_VERBOSE); - return; - } - outF = new File(destDir, outFileName[0]); - - if (force || inF.lastModified() > outF.lastModified() - || styleSheetLastModified > outF.lastModified()) { - ensureDirectoryFor(outF); - log("Processing " + inF + " to " + outF); - configureLiaison(stylesheet); - setLiaisonDynamicFileParameters(liaison, inF); - liaison.transform(inF, outF); - } - } catch (final Exception ex) { - // If failed to process document, must delete target document, - // or it will not attempt to process it the second time - log("Failed to process " + inFile, Project.MSG_INFO); - if (outF != null) { - outF.delete(); - } - handleTransformationError(ex); - } - - } //-- processXML - - /** - * Process the input file to the output file with the given stylesheet. - * - * @param inFile the input file to process. - * @param outFile the destination file. - * @param stylesheet the stylesheet to use. - * @exception BuildException if the processing fails. - */ - private void process(final File inFile, final File outFile, final Resource stylesheet) throws BuildException { - try { - final long styleSheetLastModified = stylesheet.getLastModified(); - log("In file " + inFile + " time: " + inFile.lastModified(), Project.MSG_DEBUG); - log("Out file " + outFile + " time: " + outFile.lastModified(), Project.MSG_DEBUG); - log("Style file " + xslFile + " time: " + styleSheetLastModified, Project.MSG_DEBUG); - if (force || inFile.lastModified() >= outFile.lastModified() - || styleSheetLastModified >= outFile.lastModified()) { - ensureDirectoryFor(outFile); - log("Processing " + inFile + " to " + outFile, Project.MSG_INFO); - configureLiaison(stylesheet); - setLiaisonDynamicFileParameters(liaison, inFile); - liaison.transform(inFile, outFile); - } else { - log("Skipping input file " + inFile + " because it is older than output file " - + outFile + " and so is the stylesheet " + stylesheet, Project.MSG_DEBUG); - } - } catch (final Exception ex) { - log("Failed to process " + inFile, Project.MSG_INFO); - if (outFile != null) { - outFile.delete(); - } - handleTransformationError(ex); - } - } - - /** - * Ensure the directory exists for a given file - * - * @param targetFile the file for which the directories are required. - * @exception BuildException if the directories cannot be created. - */ - private void ensureDirectoryFor(final File targetFile) throws BuildException { - final File directory = targetFile.getParentFile(); - if (!directory.exists()) { - if (!(directory.mkdirs() || directory.isDirectory())) { - handleError("Unable to create directory: " - + directory.getAbsolutePath()); - } - } - } - - /** - * Get the factory instance configured for this processor - * - * @return the factory instance in use - */ - public Factory getFactory() { - return factory; - } - - /** - * Get the XML catalog containing entity definitions - * - * @return the XML catalog for the task. - */ - public XMLCatalog getXMLCatalog() { - xmlCatalog.setProject(getProject()); - return xmlCatalog; - } - - /** - * Get an enumeration on the outputproperties. - * @return the outputproperties - */ - public Enumeration getOutputProperties() { - return outputProperties.elements(); - } - - /** - * Get the Liaison implementation to use in processing. - * - * @return an instance of the XSLTLiaison interface. - */ - protected XSLTLiaison getLiaison() { - // if processor wasn't specified, use TraX. - if (liaison == null) { - if (processor != null) { - try { - resolveProcessor(processor); - } catch (final Exception e) { - handleError(e); - } - } else { - try { - resolveProcessor(PROCESSOR_TRAX); - } catch (final Throwable e1) { - e1.printStackTrace(); - handleError(e1); - } - } - } - return liaison; - } - - /** - * Create an instance of an XSL parameter for configuration by Ant. - * - * @return an instance of the Param class to be configured. - */ - public Param createParam() { - final Param p = new Param(); - params.add(p); - return p; - } - - /** - * The Param inner class used to store XSL parameters - */ - public static class Param { - /** The parameter name */ - private String name = null; - - /** The parameter's value */ - private String expression = null; - - /** - * Type of the expression. - * @see ParamType - */ - private String type; - - private Object ifCond; - private Object unlessCond; - private Project project; - - /** - * Set the current project - * - * @param project the current project - */ - public void setProject(final Project project) { - this.project = project; - } - - /** - * Set the parameter name. - * - * @param name the name of the parameter. - */ - public void setName(final String name) { - this.name = name; - } - - /** - * The parameter value - - * can be a primitive type value or an XPath expression. - * @param expression the parameter's value/expression. - * @see #setType(java.lang.String) - */ - public void setExpression(final String expression) { - this.expression = expression; - } - - /** - * @see ParamType - * @since Ant 1.9.3 - */ - public void setType(final String type) { - this.type = type; - } - - /** - * Get the parameter name - * - * @return the parameter name - * @exception BuildException if the name is not set. - */ - public String getName() throws BuildException { - if (name == null) { - throw new BuildException("Name attribute is missing."); - } - return name; - } - - /** - * Get the parameter's value - * - * @return the parameter value - * @exception BuildException if the value is not set. - * @see #getType() - */ - public String getExpression() throws BuildException { - if (expression == null) { - throw new BuildException("Expression attribute is missing."); - } - return expression; - } - - /** - * @see ParamType - * @since Ant 1.9.3 - */ - public String getType() { - return type; - } - - /** - * Set whether this param should be used. It will be used if - * the expression evaluates to true or the name of a property - * which has been set, otherwise it won't. - * @param ifCond evaluated expression - * @since Ant 1.8.0 - */ - public void setIf(final Object ifCond) { - this.ifCond = ifCond; - } - - /** - * Set whether this param should be used. It will be used if - * the expression evaluates to true or the name of a property - * which has been set, otherwise it won't. - * @param ifProperty evaluated expression - */ - public void setIf(final String ifProperty) { - setIf((Object) ifProperty); - } - - /** - * Set whether this param should NOT be used. It will not be - * used if the expression evaluates to true or the name of a - * property which has been set, otherwise it will be used. - * @param unlessCond evaluated expression - * @since Ant 1.8.0 - */ - public void setUnless(final Object unlessCond) { - this.unlessCond = unlessCond; - } - - /** - * Set whether this param should NOT be used. It will not be - * used if the expression evaluates to true or the name of a - * property which has been set, otherwise it will be used. - * @param unlessProperty evaluated expression - */ - public void setUnless(final String unlessProperty) { - setUnless((Object) unlessProperty); - } - - /** - * Ensures that the param passes the conditions placed - * on it with <code>if</code> and <code>unless</code> properties. - * @return true if the task passes the "if" and "unless" parameters - */ - public boolean shouldUse() { - final PropertyHelper ph = PropertyHelper.getPropertyHelper(project); - return ph.testIfCondition(ifCond) - && ph.testUnlessCondition(unlessCond); - } - } // Param - - /** - * Enum for types of the parameter expression. - * - * <p>The expression can be:</p> - * <ul> - * <li>primitive type that will be parsed from the string value e.g. - * {@linkplain Integer#parseInt(java.lang.String)}</li> - * <li>XPath expression that will be evaluated (outside of the transformed - * document - on empty one) and casted to given type. Inside XPath - * expressions the Ant variables (properties) can be used (as XPath - * variables - e.g. $variable123). n.b. placeholders in form of - * ${variable123} will be substituted with their values before evaluating the - * XPath expression (so it can be used for dynamic XPath function names and - * other hacks).</li> - * </ul> - * <p>The parameter will be then passed to the XSLT template.</p> - * - * <p>Default type (if omitted) is primitive String. So if the expression is e.g - * "true" with no type, in XSLT it will be only a text string, not true - * boolean.</p> - * - * @see Param#setType(java.lang.String) - * @see Param#setExpression(java.lang.String) - * @since Ant 1.9.3 - */ - public enum ParamType { - - STRING, - BOOLEAN, - INT, - LONG, - DOUBLE, - XPATH_STRING, - XPATH_BOOLEAN, - XPATH_NUMBER, - XPATH_NODE, - XPATH_NODESET; - - public static final Map<ParamType, QName> XPATH_TYPES; - - static { - final Map<ParamType, QName> m = new EnumMap<ParamType, QName>(ParamType.class); - m.put(XPATH_STRING, XPathConstants.STRING); - m.put(XPATH_BOOLEAN, XPathConstants.BOOLEAN); - m.put(XPATH_NUMBER, XPathConstants.NUMBER); - m.put(XPATH_NODE, XPathConstants.NODE); - m.put(XPATH_NODESET, XPathConstants.NODESET); - XPATH_TYPES = Collections.unmodifiableMap(m); - } - } - - /** - * Create an instance of an output property to be configured. - * @return the newly created output property. - * @since Ant 1.5 - */ - public OutputProperty createOutputProperty() { - final OutputProperty p = new OutputProperty(); - outputProperties.addElement(p); - return p; - } - - /** - * Specify how the result tree should be output as specified - * in the <a href="http://www.w3.org/TR/xslt#output"> - * specification</a>. - * @since Ant 1.5 - */ - public static class OutputProperty { - /** output property name */ - private String name; - - /** output property value */ - private String value; - - /** - * @return the output property name. - */ - public String getName() { - return name; - } - - /** - * set the name for this property - * @param name A non-null String that specifies an - * output property name, which may be namespace qualified. - */ - public void setName(final String name) { - this.name = name; - } - - /** - * @return the output property value. - */ - public String getValue() { - return value; - } - - /** - * set the value for this property - * @param value The non-null string value of the output property. - */ - public void setValue(final String value) { - this.value = value; - } - } - - /** - * Initialize internal instance of XMLCatalog. - * Initialize XPath for parameter evaluation. - * @throws BuildException on error - */ - @Override - public void init() throws BuildException { - super.init(); - xmlCatalog.setProject(getProject()); - - xpathFactory = XPathFactory.newInstance(); - xpath = xpathFactory.newXPath(); - xpath.setXPathVariableResolver(new XPathVariableResolver() { - public Object resolveVariable(final QName variableName) { - return getProject().getProperty(variableName.toString()); - } - }); - } - - /** - * Loads the stylesheet and set xsl:param parameters. - * - * @param stylesheet the file from which to load the stylesheet. - * @exception BuildException if the stylesheet cannot be loaded. - * @deprecated since Ant 1.7 - */ - @Deprecated - protected void configureLiaison(final File stylesheet) throws BuildException { - final FileResource fr = new FileResource(); - fr.setProject(getProject()); - fr.setFile(stylesheet); - configureLiaison(fr); - } - - /** - * Loads the stylesheet and set xsl:param parameters. - * - * @param stylesheet the resource from which to load the stylesheet. - * @exception BuildException if the stylesheet cannot be loaded. - * @since Ant 1.7 - */ - protected void configureLiaison(final Resource stylesheet) throws BuildException { - if (stylesheetLoaded && reuseLoadedStylesheet) { - return; - } - stylesheetLoaded = true; - - try { - log("Loading stylesheet " + stylesheet, Project.MSG_INFO); - // We call liaison.configure() and then liaison.setStylesheet() - // so that the internal variables of liaison can be set up - if (liaison instanceof XSLTLiaison2) { - ((XSLTLiaison2) liaison).configure(this); - } - if (liaison instanceof XSLTLiaison3) { - // If we are here we can set the stylesheet as a - // resource - ((XSLTLiaison3) liaison).setStylesheet(stylesheet); - } else { - // If we are here we cannot set the stylesheet as - // a resource, but we can set it as a file. So, - // we make an attempt to get it as a file - final FileProvider fp = - stylesheet.as(FileProvider.class); - if (fp != null) { - liaison.setStylesheet(fp.getFile()); - } else { - handleError(liaison.getClass().toString() - + " accepts the stylesheet only as a file"); - return; - } - } - for (final Param p : params) { - if (p.shouldUse()) { - final Object evaluatedParam = evaluateParam(p); - if (liaison instanceof XSLTLiaison4) { - ((XSLTLiaison4)liaison).addParam(p.getName(), evaluatedParam); - } else { - if (evaluatedParam == null || evaluatedParam instanceof String) { - liaison.addParam(p.getName(), (String)evaluatedParam); - } else { - log("XSLTLiaison '" + liaison.getClass().getName() - + "' supports only String parameters. Converting parameter '" + p.getName() - + "' to its String value '" + evaluatedParam, Project.MSG_WARN); - liaison.addParam(p.getName(), String.valueOf(evaluatedParam)); - } - } - } - } - } catch (final Exception ex) { - log("Failed to transform using stylesheet " + stylesheet, Project.MSG_INFO); - handleTransformationError(ex); - } - } - - /** - * Evaluates parameter expression according to its type. - * - * @param param parameter from Ant build file - * @return value to be passed to XSLT as parameter - * @throws IllegalArgumentException if param type is unsupported - * @throws NumberFormatException if expression of numeric type is not - * desired numeric type - * @throws XPathExpressionException if XPath expression can not be compiled - * @since Ant 1.9.3 - */ - private Object evaluateParam(final Param param) throws XPathExpressionException { - final String typeName = param.getType(); - final String expression = param.getExpression(); - - ParamType type; - - if (typeName == null || "".equals(typeName)) { - type = ParamType.STRING; // String is default - } else { - try { - type = ParamType.valueOf(typeName); - } catch (final IllegalArgumentException e) { - throw new IllegalArgumentException("Invalid XSLT parameter type: " + typeName, e); - } - } - - switch (type) { - case STRING: - return expression; - case BOOLEAN: - return Boolean.parseBoolean(expression); - case DOUBLE: - return Double.parseDouble(expression); - case INT: - return Integer.parseInt(expression); - case LONG: - return Long.parseLong(expression); - default: // XPath expression - final QName xpathType = ParamType.XPATH_TYPES.get(type); - if (xpathType == null) { - throw new IllegalArgumentException("Invalid XSLT parameter type: " + typeName); - } else { - final XPathExpression xpe = xpath.compile(expression); - // null = evaluate XPath on empty XML document - return xpe.evaluate((Object) null, xpathType); - } - } - } - - /** - * Sets file parameter(s) for directory and filename if the attribute - * 'filenameparameter' or 'filedirparameter' are set in the task. - * - * @param liaison to change parameters for - * @param inFile to get the additional file information from - * @throws Exception if an exception occurs on filename lookup - * - * @since Ant 1.7 - */ - private void setLiaisonDynamicFileParameters( - final XSLTLiaison liaison, final File inFile) throws Exception { - if (fileNameParameter != null) { - liaison.addParam(fileNameParameter, inFile.getName()); - } - if (fileDirParameter != null) { - final String fileName = FileUtils.getRelativePath(baseDir, inFile); - final File file = new File(fileName); - // Give always a slash as file separator, so the stylesheet could be sure about that - // Use '.' so a dir+"/"+name would not result in an absolute path - liaison.addParam(fileDirParameter, file.getParent() != null ? file.getParent().replace( - '\\', '/') : "."); - } - } - - /** - * Create the factory element to configure a trax liaison. - * @return the newly created factory element. - * @throws BuildException if the element is created more than one time. - */ - public Factory createFactory() throws BuildException { - if (factory != null) { - handleError("'factory' element must be unique"); - } else { - factory = new Factory(); - } - return factory; - } - - /** - * Throws an exception with the given message if failOnError is - * true, otherwise logs the message using the WARN level. - * - * @since Ant 1.8.0 - */ - protected void handleError(final String msg) { - if (failOnError) { - throw new BuildException(msg, getLocation()); - } - log(msg, Project.MSG_WARN); - } - - - /** - * Throws an exception with the given nested exception if - * failOnError is true, otherwise logs the message using the WARN - * level. - * - * @since Ant 1.8.0 - */ - protected void handleError(final Throwable ex) { - if (failOnError) { - throw new BuildException(ex); - } else { - log("Caught an exception: " + ex, Project.MSG_WARN); - } - } - - /** - * Throws an exception with the given nested exception if - * failOnError and failOnTransformationError are true, otherwise - * logs the message using the WARN level. - * - * @since Ant 1.8.0 - */ - protected void handleTransformationError(final Exception ex) { - if (failOnError && failOnTransformationError) { - throw new BuildException(ex); - } else { - log("Caught an error during transformation: " + ex, - Project.MSG_WARN); - } - } - - /** - * The factory element to configure a transformer factory - * @since Ant 1.6 - */ - public static class Factory { - - /** the factory class name to use for TraXLiaison */ - private String name; - - /** - * the list of factory attributes to use for TraXLiaison - */ - private final Vector attributes = new Vector(); - - /** - * @return the name of the factory. - */ - public String getName() { - return name; - } - - /** - * Set the name of the factory - * @param name the name of the factory. - */ - public void setName(final String name) { - this.name = name; - } - - /** - * Create an instance of a factory attribute. - * @param attr the newly created factory attribute - */ - public void addAttribute(final Attribute attr) { - attributes.addElement(attr); - } - - /** - * return the attribute elements. - * @return the enumeration of attributes - */ - public Enumeration getAttributes() { - return attributes.elements(); - } - - /** - * A JAXP factory attribute. This is mostly processor specific, for - * example for Xalan 2.3+, the following attributes could be set: - * <ul> - * <li>http://xml.apache.org/xalan/features/optimize (true|false) </li> - * <li>http://xml.apache.org/xalan/features/incremental (true|false) </li> - * </ul> - */ - public static class Attribute implements DynamicConfigurator { - - /** attribute name, mostly processor specific */ - private String name; - - /** attribute value, often a boolean string */ - private Object value; - - /** - * @return the attribute name. - */ - public String getName() { - return name; - } - - /** - * @return the output property value. - */ - public Object getValue() { - return value; - } - - /** - * Not used. - * @param name not used - * @return null - * @throws BuildException never - */ - public Object createDynamicElement(final String name) throws BuildException { - return null; - } - - /** - * Set an attribute. - * Only "name" and "value" are supported as names. - * @param name the name of the attribute - * @param value the value of the attribute - * @throws BuildException on error - */ - public void setDynamicAttribute(final String name, final String value) throws BuildException { - // only 'name' and 'value' exist. - if ("name".equalsIgnoreCase(name)) { - this.name = value; - } else if ("value".equalsIgnoreCase(name)) { - // a value must be of a given type - // say boolean|integer|string that are mostly used. - if ("true".equalsIgnoreCase(value)) { - this.value = Boolean.TRUE; - } else if ("false".equalsIgnoreCase(value)) { - this.value = Boolean.FALSE; - } else { - try { - this.value = new Integer(value); - } catch (final NumberFormatException e) { - this.value = value; - } - } - } else { - throw new BuildException("Unsupported attribute: " + name); - } - } - } // -- class Attribute - } // -- class Factory - - /** - * Mapper implementation of the "traditional" way <xslt> - * mapped filenames. - * - * <p>If the file has an extension, chop it off. Append whatever - * the user has specified as extension or ".html".</p> - * - * @since Ant 1.6.2 - */ - private class StyleMapper implements FileNameMapper { - public void setFrom(final String from) { - } - public void setTo(final String to) { - } - public String[] mapFileName(String xmlFile) { - final int dotPos = xmlFile.lastIndexOf('.'); - if (dotPos > 0) { - xmlFile = xmlFile.substring(0, dotPos); - } - return new String[] {xmlFile + targetExtension}; - } - } - - /** - * Configuration for Xalan2 traces. - * - * @since Ant 1.8.0 - */ - public final class TraceConfiguration { - private boolean elements, extension, generation, selection, templates; - - /** - * Set to true if the listener is to print events that occur - * as each node is 'executed' in the stylesheet. - */ - public void setElements(final boolean b) { - elements = b; - } - - /** - * True if the listener is to print events that occur as each - * node is 'executed' in the stylesheet. - */ - public boolean getElements() { - return elements; - } - - /** - * Set to true if the listener is to print information after - * each extension event. - */ - public void setExtension(final boolean b) { - extension = b; - } - - /** - * True if the listener is to print information after each - * extension event. - */ - public boolean getExtension() { - return extension; - } - - /** - * Set to true if the listener is to print information after - * each result-tree generation event. - */ - public void setGeneration(final boolean b) { - generation = b; - } - - /** - * True if the listener is to print information after each - * result-tree generation event. - */ - public boolean getGeneration() { - return generation; - } - - /** - * Set to true if the listener is to print information after - * each selection event. - */ - public void setSelection(final boolean b) { - selection = b; - } - - /** - * True if the listener is to print information after each - * selection event. - */ - public boolean getSelection() { - return selection; - } - - /** - * Set to true if the listener is to print an event whenever a - * template is invoked. - */ - public void setTemplates(final boolean b) { - templates = b; - } - - /** - * True if the listener is to print an event whenever a - * template is invoked. - */ - public boolean getTemplates() { - return templates; - } - - /** - * The stream to write traces to. - */ - public java.io.OutputStream getOutputStream() { - return new LogOutputStream(XSLTProcess.this); - } - } - -} |