Bugzilla Report 39407 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@409378 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -419,6 +419,9 @@ Other changes: | |||||
| * <scp> now optionally supports the sftp protocol. Bugzilla Report 39373. | * <scp> now optionally supports the sftp protocol. Bugzilla Report 39373. | ||||
| * resources can now be used to indicate the location of the stylesheet to use | |||||
| in <xslt>. Bugzilla Report 39407. | |||||
| Changes from Ant 1.6.4 to Ant 1.6.5 | Changes from Ant 1.6.4 to Ant 1.6.5 | ||||
| =================================== | =================================== | ||||
| @@ -82,12 +82,15 @@ element which is used to perform Entity and URI resolution.</p> | |||||
| <td valign="top">name of the stylesheet to use - given either relative | <td valign="top">name of the stylesheet to use - given either relative | ||||
| to the project's basedir or as an absolute path.<br/> | to the project's basedir or as an absolute path.<br/> | ||||
| <br/> | <br/> | ||||
| Alternatively, a nested element which ant can interpret as a resource | |||||
| can be used to indicate where to find the stylesheet<br/> | |||||
| <em>deprecated variation :</em> <br/> | <em>deprecated variation :</em> <br/> | ||||
| If the stylesheet cannot be found, and if you have specified the | If the stylesheet cannot be found, and if you have specified the | ||||
| attribute basedir for the task, ant will assume that the style | attribute basedir for the task, ant will assume that the style | ||||
| attribute is relative to the basedir of the task. | attribute is relative to the basedir of the task. | ||||
| </td> | </td> | ||||
| <td align="center" valign="top">Yes</td> | |||||
| <td align="center" valign="top">No, if you specify the location of | |||||
| the stylesheet as a nested resource element</td> | |||||
| </tr> | </tr> | ||||
| <tr> | <tr> | ||||
| <td valign="top">classpath</td> | <td valign="top">classpath</td> | ||||
| @@ -348,6 +351,13 @@ used by <code><xslt></code> removes the file extension from the | |||||
| source file and adds the extension specified via the extension | source file and adds the extension specified via the extension | ||||
| attribute.</p> | attribute.</p> | ||||
| <h4>nested element of type resource to indicate the stylesheet</h4> | |||||
| <p><em>Since Ant 1.7</em></p> | |||||
| <p>You can use nested elements which extend resource to indicate the stylesheet. | |||||
| See <a href="../CoreTypes/resources.html">resources</a> to see the concrete syntax you can use</p> | |||||
| <h3>Examples</h3> | <h3>Examples</h3> | ||||
| <blockquote> | <blockquote> | ||||
| <pre> | <pre> | ||||
| @@ -407,6 +417,14 @@ attribute.</p> | |||||
| style="style/apache.xsl"> | style="style/apache.xsl"> | ||||
| <mapper type="glob" from="*.xml.en" to="*.html.en"/> | <mapper type="glob" from="*.xml.en" to="*.html.en"/> | ||||
| </xslt></pre> | </xslt></pre> | ||||
| <h4>Using a nested resource to define the stylesheet</h4> | |||||
| <pre> | |||||
| <xslt in="data.xml" out="${out.dir}/out.xml"> | |||||
| <url url="${printParams.xsl.url}"/> | |||||
| <param name="set" expression="value"/> | |||||
| </xslt></pre> | |||||
| </blockquote> | </blockquote> | ||||
| <hr> | <hr> | ||||
| <p align="center">Copyright © 2000-2006 The Apache Software Foundation. All rights | <p align="center">Copyright © 2000-2006 The Apache Software Foundation. All rights | ||||
| @@ -107,4 +107,26 @@ | |||||
| </copy> | </copy> | ||||
| </target> | </target> | ||||
| <target name="testWithStyleAttrAndResource"> | |||||
| <property name="value" value="myvalue"/> | |||||
| <xslt in="data.xml" out="${out.dir}/out.xml" style="printParams.xsl"> | |||||
| <file file="printParams.xsl"/> | |||||
| </xslt> | |||||
| </target> | |||||
| <target name="testWithFileResource"> | |||||
| <xslt in="data.xml" out="${out.dir}/out.xml"> | |||||
| <file file="printParams.xsl"/> | |||||
| <param name="set" expression="value"/> | |||||
| </xslt> | |||||
| </target> | |||||
| <target name="testWithUrlResource"> | |||||
| <makeurl file="printParams.xsl" property="printParams.xsl.url"/> | |||||
| <xslt in="data.xml" out="${out.dir}/out.xml"> | |||||
| <url url="${printParams.xsl.url}"/> | |||||
| <param name="set" expression="value"/> | |||||
| </xslt> | |||||
| </target> | |||||
| </project> | </project> | ||||
| @@ -0,0 +1,34 @@ | |||||
| /* | |||||
| * Copyright 2006 The Apache Software Foundation | |||||
| * | |||||
| * Licensed 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 org.apache.tools.ant.types.Resource; | |||||
| /** | |||||
| * Extends Proxy interface for XSLT processors. | |||||
| * | |||||
| * @see XSLTProcess | |||||
| * @since Ant 1.7 | |||||
| */ | |||||
| public interface XSLTLiaison3 extends XSLTLiaison2 { | |||||
| /** | |||||
| * sets the stylesheet to use as a resource | |||||
| * @param stylesheet the stylesheet to use as a resource | |||||
| * @throws Exception if the stylesheet cannot be loaded | |||||
| */ | |||||
| void setStylesheet(Resource stylesheet) throws Exception; | |||||
| } | |||||
| @@ -54,9 +54,12 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { | |||||
| /** where to find the source XML file, default is the project's basedir */ | /** where to find the source XML file, default is the project's basedir */ | ||||
| private File baseDir = null; | private File baseDir = null; | ||||
| /** XSL stylesheet */ | |||||
| /** XSL stylesheet as a filename */ | |||||
| private String xslFile = null; | 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 */ | /** extension of the files produced by XSL processing */ | ||||
| private String targetExtension = ".html"; | private String targetExtension = ".html"; | ||||
| @@ -217,7 +220,17 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { | |||||
| * @since Ant 1.7 | * @since Ant 1.7 | ||||
| */ | */ | ||||
| public void add(ResourceCollection rc) { | public void add(ResourceCollection rc) { | ||||
| resources.add(rc); | |||||
| resources.add(rc); | |||||
| } | |||||
| /** | |||||
| * Adds the XSLT stylesheet as a resource | |||||
| * @param xslResource the stylesheet as a | |||||
| * {@link org.apache.tools.ant.types.Resource} | |||||
| * @since Ant 1.7 | |||||
| */ | |||||
| public void addConfigured(Resource xslResource) { | |||||
| this.xslResource = xslResource; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -231,7 +244,7 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { | |||||
| mapper.add(fileNameMapper); | mapper.add(fileNameMapper); | ||||
| addMapper(mapper); | addMapper(mapper); | ||||
| } | } | ||||
| /** | /** | ||||
| * Executes the task. | * Executes the task. | ||||
| * | * | ||||
| @@ -240,7 +253,8 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { | |||||
| */ | */ | ||||
| public void execute() throws BuildException { | public void execute() throws BuildException { | ||||
| if ("style".equals(getTaskType())) { | if ("style".equals(getTaskType())) { | ||||
| log("Warning: the task name <style> is deprecated. Use <xslt> instead.", Project.MSG_WARN); | |||||
| log("Warning: the task name <style> is deprecated. Use <xslt> instead.", | |||||
| Project.MSG_WARN); | |||||
| } | } | ||||
| File savedBaseDir = baseDir; | File savedBaseDir = baseDir; | ||||
| @@ -249,8 +263,17 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { | |||||
| String[] list; | String[] list; | ||||
| String[] dirs; | String[] dirs; | ||||
| if (xslFile == null) { | |||||
| throw new BuildException("no stylesheet specified", getLocation()); | |||||
| if (xslResource == null && xslFile == null) { | |||||
| throw new BuildException("specify the " | |||||
| + "stylesheet either as a filename in style " | |||||
| + "attribute or as a nested resource", getLocation()); | |||||
| } | |||||
| if (xslResource != null && xslFile != null) { | |||||
| throw new BuildException("specify the " | |||||
| + "stylesheet either as a filename in style " | |||||
| + "attribute or as a nested resource but not " | |||||
| + "as both", getLocation()); | |||||
| } | } | ||||
| if (inFile != null && !inFile.exists()) { | if (inFile != null && !inFile.exists()) { | ||||
| @@ -272,23 +295,31 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { | |||||
| log("Using " + liaison.getClass().toString(), Project.MSG_VERBOSE); | log("Using " + liaison.getClass().toString(), Project.MSG_VERBOSE); | ||||
| File stylesheet = getProject().resolveFile(xslFile); | |||||
| if (!stylesheet.exists()) { | |||||
| stylesheet = FILE_UTILS.resolveFile(baseDir, xslFile); | |||||
| /* | |||||
| * shouldn't throw out deprecation warnings before we know, | |||||
| * the wrong version has been used. | |||||
| */ | |||||
| if (stylesheet.exists()) { | |||||
| log("DEPRECATED - the 'style' attribute should be relative " | |||||
| + "to the project's"); | |||||
| log(" basedir, not the tasks's basedir."); | |||||
| if (xslFile != null) { | |||||
| // If we enter here, it means that the stylesheet is supplied | |||||
| // via style attribute | |||||
| File stylesheet = FILE_UTILS.resolveFile(getProject().getBaseDir(), xslFile); | |||||
| if (!stylesheet.exists()) { | |||||
| stylesheet = FILE_UTILS.resolveFile(baseDir, xslFile); | |||||
| /* | |||||
| * shouldn't throw out deprecation warnings before we know, | |||||
| * the wrong version has been used. | |||||
| */ | |||||
| if (stylesheet.exists()) { | |||||
| log("DEPRECATED - the 'style' attribute should be relative " | |||||
| + "to the project's"); | |||||
| log(" basedir, not the tasks's basedir."); | |||||
| } | |||||
| } | } | ||||
| FileResource fr = new FileResource(); | |||||
| fr.setProject(getProject()); | |||||
| fr.setFile(stylesheet); | |||||
| xslResource = fr; | |||||
| } | } | ||||
| // if we have an in file and out then process them | // if we have an in file and out then process them | ||||
| if (inFile != null && outFile != null) { | if (inFile != null && outFile != null) { | ||||
| process(inFile, outFile, stylesheet); | |||||
| process(inFile, outFile, xslResource); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -298,34 +329,34 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { | |||||
| */ | */ | ||||
| //-- make sure destination directory exists... | //-- make sure destination directory exists... | ||||
| checkDest(); | |||||
| checkDest(); | |||||
| if (useImplicitFileset) { | |||||
| scanner = getDirectoryScanner(baseDir); | |||||
| log("Transforming into " + destDir, Project.MSG_INFO); | |||||
| 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, stylesheet); | |||||
| } | |||||
| 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, stylesheet); | |||||
| // Process all the files marked for styling | |||||
| list = scanner.getIncludedFiles(); | |||||
| for (int i = 0; i < list.length; ++i) { | |||||
| process(baseDir, list[i], destDir, xslResource); | |||||
| } | |||||
| 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, xslResource); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } else { // only resource collections, there better be some | |||||
| if (resources.size() == 0) { | |||||
| throw new BuildException("no resources specified"); | |||||
| } | |||||
| } | } | ||||
| } else { // only resource collections, there better be some | |||||
| if (resources.size() == 0) { | |||||
| throw new BuildException("no resources specified"); | |||||
| } | |||||
| } | |||||
| processResources(stylesheet); | |||||
| processResources(xslResource); | |||||
| } finally { | } finally { | ||||
| if (loader != null) { | if (loader != null) { | ||||
| loader.resetThreadContextLoader(); | loader.resetThreadContextLoader(); | ||||
| @@ -337,7 +368,7 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { | |||||
| baseDir = savedBaseDir; | baseDir = savedBaseDir; | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * Set whether to check dependencies, or always generate; | * Set whether to check dependencies, or always generate; | ||||
| * optional, default is false. | * optional, default is false. | ||||
| @@ -434,11 +465,11 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { | |||||
| * | * | ||||
| * <p>Set this to false if you want explicit control with nested | * <p>Set this to false if you want explicit control with nested | ||||
| * resource collections.</p> | * resource collections.</p> | ||||
| * | |||||
| * @param useimplicitfileset set to true if you want to use implicit fileset | |||||
| * @since Ant 1.7 | * @since Ant 1.7 | ||||
| */ | */ | ||||
| public void setUseImplicitFileset(boolean b) { | |||||
| useImplicitFileset = b; | |||||
| public void setUseImplicitFileset(boolean useimplicitfileset) { | |||||
| useImplicitFileset = useimplicitfileset; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -461,7 +492,7 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { | |||||
| private void resolveProcessor(String proc) throws Exception { | private void resolveProcessor(String proc) throws Exception { | ||||
| String classname; | String classname; | ||||
| if (proc.equals(PROCESSOR_TRAX)) { | if (proc.equals(PROCESSOR_TRAX)) { | ||||
| classname= TRAX_LIAISON_CLASS; | |||||
| classname = TRAX_LIAISON_CLASS; | |||||
| } else if (proc.equals(PROCESSOR_XALAN1)) { | } else if (proc.equals(PROCESSOR_XALAN1)) { | ||||
| log("DEPRECATED - xalan processor is deprecated. Use trax " | log("DEPRECATED - xalan processor is deprecated. Use trax " | ||||
| + "instead."); | + "instead."); | ||||
| @@ -531,24 +562,24 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { | |||||
| * | * | ||||
| * @since Ant 1.7 | * @since Ant 1.7 | ||||
| */ | */ | ||||
| private void processResources(File stylesheet) { | |||||
| Iterator iter = resources.iterator(); | |||||
| while (iter.hasNext()) { | |||||
| Resource r = (Resource) iter.next(); | |||||
| if (!r.isExists()) { | |||||
| continue; | |||||
| } | |||||
| File base = baseDir; | |||||
| String name = r.getName(); | |||||
| if (r instanceof FileResource) { | |||||
| FileResource f = (FileResource) r; | |||||
| base = f.getBaseDir(); | |||||
| if (base == null) { | |||||
| name = f.getFile().getAbsolutePath(); | |||||
| } | |||||
| } | |||||
| process(base, name, destDir, stylesheet); | |||||
| } | |||||
| private void processResources(Resource stylesheet) { | |||||
| Iterator iter = resources.iterator(); | |||||
| while (iter.hasNext()) { | |||||
| Resource r = (Resource) iter.next(); | |||||
| if (!r.isExists()) { | |||||
| continue; | |||||
| } | |||||
| File base = baseDir; | |||||
| String name = r.getName(); | |||||
| if (r instanceof FileResource) { | |||||
| FileResource f = (FileResource) r; | |||||
| base = f.getBaseDir(); | |||||
| if (base == null) { | |||||
| name = f.getFile().getAbsolutePath(); | |||||
| } | |||||
| } | |||||
| process(base, name, destDir, stylesheet); | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -562,14 +593,14 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { | |||||
| * @exception BuildException if the processing fails. | * @exception BuildException if the processing fails. | ||||
| */ | */ | ||||
| private void process(File baseDir, String xmlFile, File destDir, | private void process(File baseDir, String xmlFile, File destDir, | ||||
| File stylesheet) | |||||
| Resource stylesheet) | |||||
| throws BuildException { | throws BuildException { | ||||
| File outF = null; | File outF = null; | ||||
| File inF = null; | File inF = null; | ||||
| try { | try { | ||||
| long styleSheetLastModified = stylesheet.lastModified(); | |||||
| long styleSheetLastModified = stylesheet.getLastModified(); | |||||
| inF = new File(baseDir, xmlFile); | inF = new File(baseDir, xmlFile); | ||||
| if (inF.isDirectory()) { | if (inF.isDirectory()) { | ||||
| @@ -628,10 +659,10 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { | |||||
| * @param stylesheet the stylesheet to use. | * @param stylesheet the stylesheet to use. | ||||
| * @exception BuildException if the processing fails. | * @exception BuildException if the processing fails. | ||||
| */ | */ | ||||
| private void process(File inFile, File outFile, File stylesheet) | |||||
| private void process(File inFile, File outFile, Resource stylesheet) | |||||
| throws BuildException { | throws BuildException { | ||||
| try { | try { | ||||
| long styleSheetLastModified = stylesheet.lastModified(); | |||||
| long styleSheetLastModified = stylesheet.getLastModified(); | |||||
| log("In file " + inFile + " time: " + inFile.lastModified(), | log("In file " + inFile + " time: " + inFile.lastModified(), | ||||
| Project.MSG_DEBUG); | Project.MSG_DEBUG); | ||||
| log("Out file " + outFile + " time: " + outFile.lastModified(), | log("Out file " + outFile + " time: " + outFile.lastModified(), | ||||
| @@ -917,10 +948,24 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { | |||||
| /** | /** | ||||
| * Loads the stylesheet and set xsl:param parameters. | * Loads the stylesheet and set xsl:param parameters. | ||||
| * | * | ||||
| * @param stylesheet the file form which to load the stylesheet. | |||||
| * @param stylesheet the file from which to load the stylesheet. | |||||
| * @exception BuildException if the stylesheet cannot be loaded. | * @exception BuildException if the stylesheet cannot be loaded. | ||||
| * @deprecated since Ant 1.7 | |||||
| */ | */ | ||||
| protected void configureLiaison(File stylesheet) throws BuildException { | protected void configureLiaison(File stylesheet) throws BuildException { | ||||
| 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(Resource stylesheet) throws BuildException { | |||||
| if (stylesheetLoaded && reuseLoadedStylesheet) { | if (stylesheetLoaded && reuseLoadedStylesheet) { | ||||
| return; | return; | ||||
| } | } | ||||
| @@ -928,16 +973,35 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { | |||||
| try { | try { | ||||
| log("Loading stylesheet " + stylesheet, Project.MSG_INFO); | log("Loading stylesheet " + stylesheet, Project.MSG_INFO); | ||||
| liaison.setStylesheet(stylesheet); | |||||
| // We call liason.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 | |||||
| if (stylesheet instanceof FileResource) { | |||||
| liaison.setStylesheet( | |||||
| ((FileResource) stylesheet).getFile()); | |||||
| } else { | |||||
| throw new BuildException(liaison.getClass().toString() | |||||
| + " accepts the stylesheet only as a file", | |||||
| getLocation()); | |||||
| } | |||||
| } | |||||
| for (Enumeration e = params.elements(); e.hasMoreElements();) { | for (Enumeration e = params.elements(); e.hasMoreElements();) { | ||||
| Param p = (Param) e.nextElement(); | Param p = (Param) e.nextElement(); | ||||
| if (p.shouldUse()) { | if (p.shouldUse()) { | ||||
| liaison.addParam(p.getName(), p.getExpression()); | liaison.addParam(p.getName(), p.getExpression()); | ||||
| } | } | ||||
| } | } | ||||
| if (liaison instanceof XSLTLiaison2) { | |||||
| ((XSLTLiaison2) liaison).configure(this); | |||||
| } | |||||
| } catch (Exception ex) { | } catch (Exception ex) { | ||||
| log("Failed to transform using stylesheet " + stylesheet, | log("Failed to transform using stylesheet " + stylesheet, | ||||
| Project.MSG_INFO); | Project.MSG_INFO); | ||||
| @@ -42,11 +42,14 @@ import javax.xml.transform.stream.StreamResult; | |||||
| import javax.xml.transform.stream.StreamSource; | import javax.xml.transform.stream.StreamSource; | ||||
| import javax.xml.transform.TransformerConfigurationException; | import javax.xml.transform.TransformerConfigurationException; | ||||
| import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
| import org.apache.tools.ant.taskdefs.XSLTLiaison2; | |||||
| import org.apache.tools.ant.taskdefs.XSLTProcess; | |||||
| import org.apache.tools.ant.Project; | |||||
| import org.apache.tools.ant.taskdefs.XSLTLiaison3; | |||||
| import org.apache.tools.ant.taskdefs.XSLTLogger; | import org.apache.tools.ant.taskdefs.XSLTLogger; | ||||
| import org.apache.tools.ant.taskdefs.XSLTLoggerAware; | import org.apache.tools.ant.taskdefs.XSLTLoggerAware; | ||||
| import org.apache.tools.ant.taskdefs.XSLTProcess; | |||||
| import org.apache.tools.ant.types.XMLCatalog; | import org.apache.tools.ant.types.XMLCatalog; | ||||
| import org.apache.tools.ant.types.Resource; | |||||
| import org.apache.tools.ant.types.resources.FileResource; | |||||
| import org.apache.tools.ant.util.FileUtils; | import org.apache.tools.ant.util.FileUtils; | ||||
| import org.apache.tools.ant.util.JAXPUtils; | import org.apache.tools.ant.util.JAXPUtils; | ||||
| import org.xml.sax.EntityResolver; | import org.xml.sax.EntityResolver; | ||||
| @@ -59,7 +62,12 @@ import org.xml.sax.XMLReader; | |||||
| * | * | ||||
| * @since Ant 1.3 | * @since Ant 1.3 | ||||
| */ | */ | ||||
| public class TraXLiaison implements XSLTLiaison2, ErrorListener, XSLTLoggerAware { | |||||
| public class TraXLiaison implements XSLTLiaison3, ErrorListener, XSLTLoggerAware { | |||||
| /** | |||||
| * The current <code>Project</code> | |||||
| */ | |||||
| private Project project; | |||||
| /** | /** | ||||
| * the name of the factory implementation class to use | * the name of the factory implementation class to use | ||||
| @@ -71,7 +79,7 @@ public class TraXLiaison implements XSLTLiaison2, ErrorListener, XSLTLoggerAware | |||||
| private TransformerFactory tfactory = null; | private TransformerFactory tfactory = null; | ||||
| /** stylesheet to use for transformation */ | /** stylesheet to use for transformation */ | ||||
| private File stylesheet; | |||||
| private Resource stylesheet; | |||||
| private XSLTLogger logger; | private XSLTLogger logger; | ||||
| @@ -115,13 +123,24 @@ public class TraXLiaison implements XSLTLiaison2, ErrorListener, XSLTLoggerAware | |||||
| * @throws Exception on error | * @throws Exception on error | ||||
| */ | */ | ||||
| public void setStylesheet(File stylesheet) throws Exception { | public void setStylesheet(File stylesheet) throws Exception { | ||||
| FileResource fr = new FileResource(); | |||||
| fr.setProject(project); | |||||
| fr.setFile(stylesheet); | |||||
| } | |||||
| /** | |||||
| * Set the stylesheet file. | |||||
| * @param stylesheet a {@link org.apache.tools.ant.types.Resource} value | |||||
| * @throws Exception on error | |||||
| */ | |||||
| public void setStylesheet(Resource stylesheet) throws Exception { | |||||
| if (this.stylesheet != null) { | if (this.stylesheet != null) { | ||||
| // resetting the stylesheet - reset transformer | // resetting the stylesheet - reset transformer | ||||
| transformer = null; | transformer = null; | ||||
| // do we need to reset templates as well | // do we need to reset templates as well | ||||
| if (!this.stylesheet.equals(stylesheet) | if (!this.stylesheet.equals(stylesheet) | ||||
| || (stylesheet.lastModified() != templatesModTime)) { | |||||
| || (stylesheet.getLastModified() != templatesModTime)) { | |||||
| templates = null; | templates = null; | ||||
| } | } | ||||
| } | } | ||||
| @@ -205,6 +224,35 @@ public class TraXLiaison implements XSLTLiaison2, ErrorListener, XSLTLoggerAware | |||||
| return src; | return src; | ||||
| } | } | ||||
| private Source getSource(InputStream is, Resource resource) | |||||
| throws ParserConfigurationException, SAXException { | |||||
| // todo: is this comment still relevant ?? | |||||
| // FIXME: need to use a SAXSource as the source for the transform | |||||
| // so we can plug in our own entity resolver | |||||
| Source src = null; | |||||
| if (entityResolver != null) { | |||||
| if (getFactory().getFeature(SAXSource.FEATURE)) { | |||||
| SAXParserFactory spFactory = SAXParserFactory.newInstance(); | |||||
| spFactory.setNamespaceAware(true); | |||||
| XMLReader reader = spFactory.newSAXParser().getXMLReader(); | |||||
| reader.setEntityResolver(entityResolver); | |||||
| src = new SAXSource(reader, new InputSource(is)); | |||||
| } else { | |||||
| throw new IllegalStateException("xcatalog specified, but " | |||||
| + "parser doesn't support SAX"); | |||||
| } | |||||
| } else { | |||||
| // WARN: Don't use the StreamSource(File) ctor. It won't work with | |||||
| // xalan prior to 2.2 because of systemid bugs. | |||||
| src = new StreamSource(is); | |||||
| } | |||||
| // The line below is a hack: the system id must an URI, but it is not | |||||
| // cleat to get the URI of an resource, so just set the name of the | |||||
| // resource as a system id | |||||
| src.setSystemId(resource.getName()); | |||||
| return src; | |||||
| } | |||||
| /** | /** | ||||
| * Read in templates from the stylesheet | * Read in templates from the stylesheet | ||||
| */ | */ | ||||
| @@ -219,8 +267,8 @@ public class TraXLiaison implements XSLTLiaison2, ErrorListener, XSLTLoggerAware | |||||
| InputStream xslStream = null; | InputStream xslStream = null; | ||||
| try { | try { | ||||
| xslStream | xslStream | ||||
| = new BufferedInputStream(new FileInputStream(stylesheet)); | |||||
| templatesModTime = stylesheet.lastModified(); | |||||
| = new BufferedInputStream(stylesheet.getInputStream()); | |||||
| templatesModTime = stylesheet.getLastModified(); | |||||
| Source src = getSource(xslStream, stylesheet); | Source src = getSource(xslStream, stylesheet); | ||||
| templates = getFactory().newTemplates(src); | templates = getFactory().newTemplates(src); | ||||
| } finally { | } finally { | ||||
| @@ -437,7 +485,7 @@ public class TraXLiaison implements XSLTLiaison2, ErrorListener, XSLTLoggerAware | |||||
| /** | /** | ||||
| * @param file the filename to use for the systemid | * @param file the filename to use for the systemid | ||||
| * @return the systemid | * @return the systemid | ||||
| * @deprecated since 1.5.x. | |||||
| * @deprecated since 1.5.x. | |||||
| * Use org.apache.tools.ant.util.JAXPUtils#getSystemId instead. | * Use org.apache.tools.ant.util.JAXPUtils#getSystemId instead. | ||||
| */ | */ | ||||
| protected String getSystemId(File file) { | protected String getSystemId(File file) { | ||||
| @@ -451,6 +499,7 @@ public class TraXLiaison implements XSLTLiaison2, ErrorListener, XSLTLoggerAware | |||||
| * is to be configured. | * is to be configured. | ||||
| */ | */ | ||||
| public void configure(XSLTProcess xsltTask) { | public void configure(XSLTProcess xsltTask) { | ||||
| project = xsltTask.getProject(); | |||||
| XSLTProcess.Factory factory = xsltTask.getFactory(); | XSLTProcess.Factory factory = xsltTask.getFactory(); | ||||
| if (factory != null) { | if (factory != null) { | ||||
| setFactory(factory.getName()); | setFactory(factory.getName()); | ||||
| @@ -33,6 +33,8 @@ import org.apache.tools.ant.util.FileUtils; | |||||
| */ | */ | ||||
| public class StyleTest extends BuildFileTest { | public class StyleTest extends BuildFileTest { | ||||
| private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | |||||
| public StyleTest(String s) { | public StyleTest(String s) { | ||||
| super(s); | super(s); | ||||
| } | } | ||||
| @@ -48,7 +50,10 @@ public class StyleTest extends BuildFileTest { | |||||
| } | } | ||||
| public void testStyleIsSet() throws Exception { | public void testStyleIsSet() throws Exception { | ||||
| expectBuildException("testStyleIsSet", "no stylesheet specified"); | |||||
| expectSpecificBuildException("testStyleIsSet", | |||||
| "no stylesheet specified", "specify the " + | |||||
| "stylesheet either as a filename in style " + | |||||
| "attribute or as a nested resource"); | |||||
| } | } | ||||
| public void testTransferParameterSet() throws Exception { | public void testTransferParameterSet() throws Exception { | ||||
| @@ -91,21 +96,24 @@ public class StyleTest extends BuildFileTest { | |||||
| } | } | ||||
| public void testDefaultMapper(String target) throws Exception { | public void testDefaultMapper(String target) throws Exception { | ||||
| assertTrue(!getProject().resolveFile("out/data.html").exists()); | |||||
| assertTrue(!(FileUtils.getFileUtils().resolveFile( | |||||
| getProject().getBaseDir(),"out/data.html")).exists()); | |||||
| expectFileContains(target, | expectFileContains(target, | ||||
| "out/data.html", | "out/data.html", | ||||
| "set='myvalue'"); | "set='myvalue'"); | ||||
| } | } | ||||
| public void testCustomMapper() throws Exception { | public void testCustomMapper() throws Exception { | ||||
| assertTrue(!getProject().resolveFile("out/out.xml").exists()); | |||||
| assertTrue(!FILE_UTILS.resolveFile( | |||||
| getProject().getBaseDir(), "out/out.xml").exists()); | |||||
| expectFileContains("testCustomMapper", | expectFileContains("testCustomMapper", | ||||
| "out/out.xml", | "out/out.xml", | ||||
| "set='myvalue'"); | "set='myvalue'"); | ||||
| } | } | ||||
| public void testTypedMapper() throws Exception { | public void testTypedMapper() throws Exception { | ||||
| assertTrue(!getProject().resolveFile("out/out.xml").exists()); | |||||
| assertTrue(!FILE_UTILS.resolveFile( | |||||
| getProject().getBaseDir(), "out/out.xml").exists()); | |||||
| expectFileContains("testTypedMapper", | expectFileContains("testTypedMapper", | ||||
| "out/out.xml", | "out/out.xml", | ||||
| "set='myvalue'"); | "set='myvalue'"); | ||||
| @@ -113,16 +121,34 @@ public class StyleTest extends BuildFileTest { | |||||
| public void testDirectoryHierarchyWithDirMatching() throws Exception { | public void testDirectoryHierarchyWithDirMatching() throws Exception { | ||||
| executeTarget("testDirectoryHierarchyWithDirMatching"); | executeTarget("testDirectoryHierarchyWithDirMatching"); | ||||
| assertTrue(getProject().resolveFile("out/dest/level1/data.html") | |||||
| assertTrue(FILE_UTILS.resolveFile( | |||||
| getProject().getBaseDir(), "out/dest/level1/data.html") | |||||
| .exists()); | .exists()); | ||||
| } | } | ||||
| public void testDirsWithSpaces() throws Exception { | public void testDirsWithSpaces() throws Exception { | ||||
| executeTarget("testDirsWithSpaces"); | executeTarget("testDirsWithSpaces"); | ||||
| assertTrue(getProject().resolveFile("out/d est/data.html") | |||||
| assertTrue(FILE_UTILS.resolveFile( | |||||
| getProject().getBaseDir(), "out/d est/data.html") | |||||
| .exists()); | .exists()); | ||||
| } | } | ||||
| public void testWithStyleAttrAndResource() throws Exception { | |||||
| expectSpecificBuildException("testWithStyleAttrAndResource", | |||||
| "Must throws a BuildException", "specify the " + | |||||
| "stylesheet either as a filename in style " + | |||||
| "attribute or as a nested resource but not " + | |||||
| "as both"); | |||||
| } | |||||
| public void testWithFileResource() throws Exception { | |||||
| expectFileContains("testWithFileResource", "out/out.xml", "set='value'"); | |||||
| } | |||||
| public void testWithUrlResource() throws Exception { | |||||
| expectFileContains("testWithUrlResource", "out/out.xml", "set='value'"); | |||||
| } | |||||
| // ************* copied from ConcatTest ************* | // ************* copied from ConcatTest ************* | ||||
| // ------------------------------------------------------ | // ------------------------------------------------------ | ||||