sbailliez 01/08/11 15:06:45
Modified: src/main/org/apache/tools/ant/taskdefs/optional Tag:
ANT_14_BRANCH TraXLiaison.java XalanLiaison.java
XslpLiaison.java
src/main/org/apache/tools/ant/taskdefs Tag: ANT_14_BRANCH
XSLTLiaison.java XSLTProcess.java
Log:
Great deal of modification around style tasks...
Mostly I wanted to unify the syntax and deal with systemid but it
unfortunately leads to problems because the URI specs are not
clearly defined and xsl processors do what they want....
Inconsistencies in Xalan 2 prevented the use of File objects
(bugs are currently being resolved), thus I switched to systemid
that are known to work fine and should work fine in later versions.
Fixed a bug in XslpLiaison that was producing a NPE.
(did someone use that task before ?)
Added testcases that are transforming an XML file via an XSL.
The point here is that the XML and the XSL do an include, this allow to check
that the resolution is working fine and thus the systemid is correctly setted.
Tescases also check for redirect behavior (xalan extension) end do a
mini-encoding test (an encoding attribute should probably be added as a
convenience to the style task)
Added Javadoc as well in the XSLTLiaison interface.
Related to bug 3087, 3088.
Revision Changes Path
No revision
No revision
1.3.2.1 +59 -21
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java
Index: TraXLiaison.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java,v
retrieving revision 1.3
retrieving revision 1.3.2.1
diff -u -r1.3 -r1.3.2.1
--- TraXLiaison.java 2001/08/07 23:39:49 1.3
+++ TraXLiaison.java 2001/08/11 22:06:45 1.3.2.1
@@ -54,61 +54,99 @@
package org.apache.tools.ant.taskdefs.optional;
+import java.io.File;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
+import java.io.IOException;
import org.apache.tools.ant.taskdefs.XSLTLiaison;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.Templates;
+import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
/**
+ * Concrete liaison for XSLT processor implementing TraX. (ie JAXP 1.1)
*
* @author <a href="mailto:[EMAIL PROTECTED]">Sam Ruby</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Davanum Srinivas</a>
- * @version $Revision: 1.3 $ $Date: 2001/08/07 23:39:49 $
+ * @author <a href="mailto:[EMAIL PROTECTED]">Stephane Bailliez</a>
*/
public class TraXLiaison implements XSLTLiaison {
- protected final static String FILEURL = "file:";
-
/** The trax TransformerFactory */
private TransformerFactory tfactory = null;
+ /** stylesheet stream, close it asap */
+ private FileInputStream xslStream = null;
+
/** Stylesheet template */
private Templates templates = null;
- /** The trax Transformer itself */
- private Transformer transformer;
+ /** transformer */
+ private Transformer transformer = null;
public TraXLiaison() throws Exception {
tfactory = TransformerFactory.newInstance();
}
-
- public void setStylesheet(String fileName) throws Exception {
- templates = tfactory.newTemplates(new
StreamSource(normalize(fileName)));
+//------------------- IMPORTANT
+ // 1) Don't use the StreamSource(File) ctor. It won't work with
+ // xalan prior to 2.2 because of systemid bugs.
+
+ // 2) Use a stream so that you can close it yourself quickly
+ // and avoid keeping the handle until the object is garbaged.
+ // (always keep control), otherwise you won't be able to delete
+ // the file quickly on windows.
+
+ // 3) Always set the systemid to the source for imports, includes...
+ // in xsl and xml...
+
+ public void setStylesheet(File stylesheet) throws Exception {
+ xslStream = new FileInputStream(stylesheet);
+ StreamSource src = new StreamSource(xslStream);
+ src.setSystemId(FILE_PROTOCOL_PREFIX + stylesheet.getAbsolutePath());
+ templates = tfactory.newTemplates(src);
transformer = templates.newTransformer();
- };
+ }
- public void transform(String infile, String outfile) throws Exception {
- FileOutputStream out = new FileOutputStream(outfile);
+ public void transform(File infile, File outfile) throws Exception {
+ FileInputStream fis = null;
+ FileOutputStream fos = null;
try {
- transformer.transform(new StreamSource(normalize(infile)),
- new StreamResult(out));
+ fis = new FileInputStream(infile);
+ fos = new FileOutputStream(outfile);
+ StreamSource src = new StreamSource(fis);
+ src.setSystemId(FILE_PROTOCOL_PREFIX + infile.getAbsolutePath());
+ StreamResult res = new StreamResult(fos);
+ // not sure what could be the need of this...
+ res.setSystemId(FILE_PROTOCOL_PREFIX +
outfile.getAbsolutePath());
+
+ transformer.transform(src, res);
} finally {
- out.close();
+ // make sure to close all handles, otherwise the garbage
+ // collector will close them...whenever possible and
+ // Windows may complain about not being able to delete files.
+ try {
+ if (xslStream != null){
+ xslStream.close();
+ }
+ } catch (IOException ignored){}
+ try {
+ if (fis != null){
+ fis.close();
+ }
+ } catch (IOException ignored){}
+ try {
+ if (fos != null){
+ fos.close();
+ }
+ } catch (IOException ignored){}
}
}
- protected String normalize(String fileName) {
- if(fileName != null && !fileName.startsWith(FILEURL)) {
- return FILEURL + "///" + fileName;
- }
- return fileName;
- }
-
public void addParam(String name, String value){
transformer.setParameter(name, value);
}
1.5.4.1 +48 -17
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/XalanLiaison.java
Index: XalanLiaison.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/XalanLiaison.java,v
retrieving revision 1.5
retrieving revision 1.5.4.1
diff -u -r1.5 -r1.5.4.1
--- XalanLiaison.java 2001/01/03 14:18:35 1.5
+++ XalanLiaison.java 2001/08/11 22:06:45 1.5.4.1
@@ -60,39 +60,70 @@
import org.apache.xalan.xslt.XSLTProcessor;
import org.apache.xalan.xslt.XSLTInputSource;
import org.apache.xalan.xslt.XSLTResultTarget;
+import org.xml.sax.InputSource;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
/**
+ * Concrete liaison for Xalan 1.x API.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Sam Ruby</a>
- * @version $Revision: 1.5 $ $Date: 2001/01/03 14:18:35 $
+ * @author <a href="mailto:[EMAIL PROTECTED]">Stephane Bailliez</a>
*/
public class XalanLiaison implements XSLTLiaison {
-
- protected final static String FILEURL = "file:";
- XSLTProcessor processor;
- XSLTInputSource xslSheet;
+ protected XSLTProcessor processor;
+ protected File stylesheet;
public XalanLiaison() throws Exception {
processor = XSLTProcessorFactory.getProcessor();
}
- public void setStylesheet(String fileName) throws Exception {
- xslSheet = new XSLTInputSource (normalize(fileName));
- };
-
- public void transform(String infile, String outfile) throws Exception {
- processor.process(new XSLTInputSource(normalize(infile)), xslSheet,
- new XSLTResultTarget(outfile));
+ public void setStylesheet(File stylesheet) throws Exception {
+ this.stylesheet = stylesheet;
}
- protected String normalize(String fileName) {
- if(fileName != null && !fileName.startsWith(FILEURL)) {
- return FILEURL + fileName;
+ public void transform(File infile, File outfile) throws Exception {
+ FileInputStream fis = null;
+ FileOutputStream fos = null;
+ FileInputStream xslStream = null;
+ try {
+ xslStream = new FileInputStream(stylesheet);
+ fis = new FileInputStream(infile);
+ fos = new FileOutputStream(outfile);
+ // systemid such as file:/// + getAbsolutePath() are considered
+ // invalid here...
+ XSLTInputSource xslSheet = new XSLTInputSource(xslStream);
+ xslSheet.setSystemId(stylesheet.getAbsolutePath());
+ XSLTInputSource src = new XSLTInputSource(fis);
+ src.setSystemId(infile.getAbsolutePath());
+ XSLTResultTarget res = new XSLTResultTarget(fos);
+ processor.process(src, xslSheet, res);
+ } finally {
+ // make sure to close all handles, otherwise the garbage
+ // collector will close them...whenever possible and
+ // Windows may complain about not being able to delete files.
+ try {
+ if (xslStream != null){
+ xslStream.close();
+ }
+ } catch (IOException ignored){}
+ try {
+ if (fis != null){
+ fis.close();
+ }
+ } catch (IOException ignored){}
+ try {
+ if (fos != null){
+ fos.close();
+ }
+ } catch (IOException ignored){}
}
- return fileName;
}
-
+
public void addParam(String name, String value){
processor.setStylesheetParam(name, value);
}
1.5.2.1 +22 -17
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/XslpLiaison.java
Index: XslpLiaison.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/XslpLiaison.java,v
retrieving revision 1.5
retrieving revision 1.5.2.1
diff -u -r1.5 -r1.5.2.1
--- XslpLiaison.java 2001/06/22 07:24:18 1.5
+++ XslpLiaison.java 2001/08/11 22:06:45 1.5.2.1
@@ -54,40 +54,45 @@
package org.apache.tools.ant.taskdefs.optional;
-import java.io.FileWriter;
+import java.io.*;
+import java.net.URL;
import org.apache.tools.ant.taskdefs.XSLTLiaison;
+import org.xml.sax.InputSource;
-import com.kvisco.xsl.XSLProcessor;
-import com.kvisco.xsl.XSLReader;
-import com.kvisco.xsl.XSLStylesheet;
+import com.kvisco.xsl.*;
/**
+ * Concrete liaison for XSLP
*
* @author <a href="mailto:[EMAIL PROTECTED]">Sam Ruby</a>
- * @version $Revision: 1.5 $ $Date: 2001/06/22 07:24:18 $
+ * @author <a href="mailto:[EMAIL PROTECTED]">Stephane Bailliez</a>
*/
public class XslpLiaison implements XSLTLiaison {
- XSLProcessor processor;
- XSLStylesheet xslSheet;
+ protected XSLProcessor processor;
+ protected XSLStylesheet xslSheet;
public XslpLiaison() {
processor = new XSLProcessor();
+ // uh ?! I'm forced to do that otherwise a setProperty crashes with
NPE !
+ // I don't understand why the property map is static though...
+ // how can we do multithreading w/ multiple identical parameters ?
+ processor.getProperty("dummy-to-init-properties-map");
}
- public void setStylesheet(String fileName) throws Exception {
+ public void setStylesheet(File fileName) throws Exception {
XSLReader xslReader = new XSLReader();
- xslSheet = xslReader.read( fileName );
- };
+ // a file:/// + getAbsolutePath() does not work here
+ // it is really the pathname
+ xslSheet = xslReader.read( fileName.getAbsolutePath() );
+ }
- public void transform(String infile, String outfile) throws Exception {
- FileWriter out = new FileWriter(outfile);
- try {
- processor.process(infile, xslSheet, out);
- } finally {
- out.close();
- }
+ public void transform(File infile, File outfile) throws Exception {
+ FileOutputStream fos = new FileOutputStream(outfile);
+ // XSLP does not support encoding...we're in hot water.
+ OutputStreamWriter out = new OutputStreamWriter(fos,"UTF8");
+ processor.process(infile.getAbsolutePath(), xslSheet, out);
}
public void addParam(String name, String expression){
No revision
No revision
1.3.4.1 +36 -4
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison.java
Index: XSLTLiaison.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison.java,v
retrieving revision 1.3
retrieving revision 1.3.4.1
diff -u -r1.3 -r1.3.4.1
--- XSLTLiaison.java 2001/01/03 14:18:31 1.3
+++ XSLTLiaison.java 2001/08/11 22:06:45 1.3.4.1
@@ -54,19 +54,51 @@
package org.apache.tools.ant.taskdefs;
-import org.apache.tools.ant.*;
+import java.io.File;
/**
+ * Proxy interface for XSLT processors.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Sam Ruby</a>
- * @version $Revision: 1.3 $ $Date: 2001/01/03 14:18:31 $
+ * @author <a href="mailto:[EMAIL PROTECTED]">Stephane Bailliez</a>
+ * @see #XSLTProcess
*/
public interface XSLTLiaison {
- public void setStylesheet(String fileName) throws Exception;
+ /**
+ * the file protocol prefix for systemid.
+ * This file protocol must be appended to an absolute path.
+ * Typically: <tt>FILE_PROTOCOL_PREFIX + file.getAbsolutePath()</tt>
+ * This is not correct in specification terms since an absolute
+ * url in Unix is file:// + file.getAbsolutePath() while it is
+ * file:/// + file.getAbsolutePath() under Windows.
+ * Whatever, it should not be a problem to put file:/// in every
+ * case since most parsers for now incorrectly makes no difference
+ * between it.. and users also have problem with that :)
+ */
+ public final static String FILE_PROTOCOL_PREFIX = "file:///";
+ /**
+ * set the stylesheet to use for the transformation.
+ * @param stylesheet the stylesheet to be used for transformation.
+ */
+ public void setStylesheet(File stylesheet) throws Exception;
+
+ /**
+ * Add a parameter to be set during the XSL transformation.
+ * @param name the parameter name.
+ * @param expression the parameter value as an expression string.
+ * @throws Exception thrown if any problems happens.
+ */
public void addParam(String name, String expression) throws Exception;
- public void transform(String infile, String outfile) throws Exception;
+ /**
+ * Perform the transformation of a file into another.
+ * @param infile the input file, probably an XML one. :-)
+ * @param outfile the output file resulting from the transformation
+ * @throws Exception thrown if any problems happens.
+ * @see #setStylesheet(File)
+ */
+ public void transform(File infile, File outfile) throws Exception;
} //-- XSLTLiaison
1.23.2.1 +20 -20
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java
Index: XSLTProcess.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java,v
retrieving revision 1.23
retrieving revision 1.23.2.1
diff -u -r1.23 -r1.23.2.1
--- XSLTProcess.java 2001/08/08 16:13:08 1.23
+++ XSLTProcess.java 2001/08/11 22:06:45 1.23.2.1
@@ -88,7 +88,7 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Sam Ruby</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Russell Gold</a>
* @author <a href="[EMAIL PROTECTED]">Stefan Bodewig</a>
- * @version $Revision: 1.23 $ $Date: 2001/08/08 16:13:08 $
+ * @version $Revision: 1.23.2.1 $ $Date: 2001/08/11 22:06:45 $
*/
public class XSLTProcess extends MatchingTask {
@@ -100,9 +100,9 @@
private String targetExtension = ".html";
private Vector params = new Vector();
-
+
private File inFile = null;
-
+
private File outFile = null;
private String processor;
@@ -137,7 +137,7 @@
if (baseDir == null) {
baseDir = project.resolveFile(".");
}
-
+
liaison = getLiaison();
log("Using "+liaison.getClass().toString(), Project.MSG_VERBOSE);
@@ -178,7 +178,7 @@
for (int i = 0;i < list.length; ++i) {
process( baseDir, list[i], destDir, stylesheet );
}
-
+
// Process all the directoried marked for styling
dirs = scanner.getIncludedDirectories();
for (int j = 0;j < dirs.length;++j){
@@ -264,15 +264,15 @@
*/
private void resolveProcessor(String proc) throws Exception {
if (proc.equals("trax")) {
- final Class clazz =
+ final Class clazz =
loadClass("org.apache.tools.ant.taskdefs.optional.TraXLiaison");
liaison = (XSLTLiaison)clazz.newInstance();
} else if (proc.equals("xslp")) {
- final Class clazz =
+ final Class clazz =
loadClass("org.apache.tools.ant.taskdefs.optional.XslpLiaison");
liaison = (XSLTLiaison) clazz.newInstance();
} else if (proc.equals("xalan")) {
- final Class clazz =
+ final Class clazz =
loadClass("org.apache.tools.ant.taskdefs.optional.XalanLiaison");
liaison = (XSLTLiaison)clazz.newInstance();
} else {
@@ -313,14 +313,14 @@
* Processes the given input XML file and stores the result
* in the given resultFile.
**/
- private void process(File baseDir, String xmlFile, File destDir,
+ private void process(File baseDir, String xmlFile, File destDir,
File stylesheet)
throws BuildException {
String fileExt=targetExtension;
File outFile=null;
File inFile=null;
-
+
try {
long styleSheetLastModified = stylesheet.lastModified();
inFile = new File(baseDir,xmlFile);
@@ -337,7 +337,7 @@
log("Transforming into "+destDir);
configureLiaison(stylesheet);
- liaison.transform(inFile.toString(), outFile.toString());
+ liaison.transform(inFile, outFile);
}
}
catch (Exception ex) {
@@ -347,7 +347,7 @@
if (outFile != null) {
outFile.delete();
}
-
+
throw new BuildException(ex);
}
@@ -365,7 +365,7 @@
ensureDirectoryFor( outFile );
log("Processing " + inFile + " to " + outFile,
Project.MSG_INFO);
configureLiaison(stylesheet);
- liaison.transform(inFile.toString(), outFile.toString());
+ liaison.transform(inFile, outFile);
}
}catch (Exception ex) {
log("Failed to process " + inFile, Project.MSG_INFO);
@@ -378,12 +378,12 @@
File directory = new File( targetFile.getParent() );
if (!directory.exists()) {
if (!directory.mkdirs()) {
- throw new BuildException("Unable to create directory: "
+ throw new BuildException("Unable to create directory: "
+ directory.getAbsolutePath() );
}
}
}
-
+
protected XSLTLiaison getLiaison() {
// if processor wasn't specified, see if TraX is available. If not,
// default it to xslp or xalan, depending on which is in the
classpath
@@ -424,20 +424,20 @@
public class Param {
private String name=null;
private String expression=null;
-
+
public void setName(String name){
this.name = name;
}
-
+
public void setExpression(String expression){
this.expression = expression;
}
-
+
public String getName() throws BuildException{
if(name==null)throw new BuildException("Name attribute is
missing.");
return name;
}
-
+
public String getExpression() throws BuildException{
if(expression==null)throw new BuildException("Expression
attribute is missing.");
return expression;
@@ -455,7 +455,7 @@
try {
log( "Loading stylesheet " + stylesheet, Project.MSG_INFO);
- liaison.setStylesheet( stylesheet.toString() );
+ liaison.setStylesheet( stylesheet );
for(Enumeration e = params.elements();e.hasMoreElements();) {
Param p = (Param)e.nextElement();
liaison.addParam( p.getName(), p.getExpression() );