git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@270227 13f79535-47bb-0310-9956-ffa450edef68master
@@ -5,7 +5,7 @@ | |||||
* version 1.1, a copy of which has been included with this distribution in | * version 1.1, a copy of which has been included with this distribution in | ||||
* the LICENSE file. | * the LICENSE file. | ||||
*/ | */ | ||||
package org.apache.tools.ant.taskdefs.optional; | |||||
package org.apache.antlib.xml; | |||||
import java.io.File; | import java.io.File; | ||||
import java.io.FileInputStream; | import java.io.FileInputStream; | ||||
@@ -19,9 +19,8 @@ import javax.xml.transform.TransformerException; | |||||
import javax.xml.transform.TransformerFactory; | import javax.xml.transform.TransformerFactory; | ||||
import javax.xml.transform.stream.StreamResult; | import javax.xml.transform.stream.StreamResult; | ||||
import javax.xml.transform.stream.StreamSource; | import javax.xml.transform.stream.StreamSource; | ||||
import org.apache.tools.ant.taskdefs.XSLTLiaison; | |||||
import org.apache.tools.ant.taskdefs.XSLTLogger; | |||||
import org.apache.tools.ant.taskdefs.XSLTLoggerAware; | |||||
import org.apache.avalon.framework.logger.AbstractLogEnabled; | |||||
import org.apache.avalon.framework.logger.LogEnabled; | |||||
/** | /** | ||||
* Concrete liaison for XSLT processor implementing TraX. (ie JAXP 1.1) | * Concrete liaison for XSLT processor implementing TraX. (ie JAXP 1.1) | ||||
@@ -30,30 +29,29 @@ import org.apache.tools.ant.taskdefs.XSLTLoggerAware; | |||||
* @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a> | * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a> | ||||
* @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a> | * @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a> | ||||
*/ | */ | ||||
public class TraXLiaison implements XSLTLiaison, ErrorListener, XSLTLoggerAware | |||||
public class TraXLiaison | |||||
extends AbstractLogEnabled | |||||
implements XSLTLiaison, ErrorListener | |||||
{ | { | ||||
/** | /** | ||||
* The trax TransformerFactory | * The trax TransformerFactory | ||||
*/ | */ | ||||
private TransformerFactory tfactory = null; | |||||
private TransformerFactory tfactory; | |||||
/** | /** | ||||
* stylesheet stream, close it asap | * stylesheet stream, close it asap | ||||
*/ | */ | ||||
private FileInputStream xslStream = null; | |||||
private FileInputStream xslStream; | |||||
/** | /** | ||||
* Stylesheet template | * Stylesheet template | ||||
*/ | */ | ||||
private Templates templates = null; | |||||
private Templates templates; | |||||
/** | /** | ||||
* transformer | * transformer | ||||
*/ | */ | ||||
private Transformer transformer = null; | |||||
private XSLTLogger logger; | |||||
private Transformer transformer; | |||||
public TraXLiaison() | public TraXLiaison() | ||||
throws Exception | throws Exception | ||||
@@ -62,11 +60,6 @@ public class TraXLiaison implements XSLTLiaison, ErrorListener, XSLTLoggerAware | |||||
tfactory.setErrorListener( this ); | tfactory.setErrorListener( this ); | ||||
} | } | ||||
public void setLogger( XSLTLogger l ) | |||||
{ | |||||
logger = l; | |||||
} | |||||
public void setOutputtype( String type ) | public void setOutputtype( String type ) | ||||
throws Exception | throws Exception | ||||
{ | { | ||||
@@ -214,7 +207,7 @@ public class TraXLiaison implements XSLTLiaison, ErrorListener, XSLTLoggerAware | |||||
msg.append( " Cause: " + e.getCause() ); | msg.append( " Cause: " + e.getCause() ); | ||||
} | } | ||||
logger.log( msg.toString() ); | |||||
getLogger().info( msg.toString() ); | |||||
} | } | ||||
}//-- TraXLiaison | }//-- TraXLiaison |
@@ -5,7 +5,7 @@ | |||||
* version 1.1, a copy of which has been included with this distribution in | * version 1.1, a copy of which has been included with this distribution in | ||||
* the LICENSE file. | * the LICENSE file. | ||||
*/ | */ | ||||
package org.apache.tools.ant.taskdefs.optional; | |||||
package org.apache.antlib.xml; | |||||
import java.io.File; | import java.io.File; | ||||
import java.io.FileInputStream; | import java.io.FileInputStream; | ||||
@@ -44,9 +44,9 @@ import org.xml.sax.helpers.ParserAdapter; | |||||
* @author Raphael Pierquin <a href="mailto:raphael.pierquin@agisphere.com"> | * @author Raphael Pierquin <a href="mailto:raphael.pierquin@agisphere.com"> | ||||
* raphael.pierquin@agisphere.com</a> | * raphael.pierquin@agisphere.com</a> | ||||
*/ | */ | ||||
public class XMLValidateTask extends Task | |||||
public class XMLValidateTask | |||||
extends Task | |||||
{ | { | ||||
/** | /** | ||||
* The default implementation parser classname used by the task to process | * The default implementation parser classname used by the task to process | ||||
* validation. | * validation. | ||||
@@ -591,7 +591,7 @@ public class XMLValidateTask extends Task | |||||
urlDTDs.put( publicId, urldtd ); | urlDTDs.put( publicId, urldtd ); | ||||
} | } | ||||
} | } | ||||
catch( java.net.MalformedURLException e ) | |||||
catch( MalformedURLException e ) | |||||
{ | { | ||||
//ignored | //ignored | ||||
} | } |
@@ -5,7 +5,7 @@ | |||||
* version 1.1, a copy of which has been included with this distribution in | * version 1.1, a copy of which has been included with this distribution in | ||||
* the LICENSE file. | * the LICENSE file. | ||||
*/ | */ | ||||
package org.apache.tools.ant.taskdefs; | |||||
package org.apache.antlib.xml; | |||||
import java.io.File; | import java.io.File; | ||||
@@ -18,7 +18,6 @@ import java.io.File; | |||||
*/ | */ | ||||
public interface XSLTLiaison | public interface XSLTLiaison | ||||
{ | { | ||||
/** | /** | ||||
* the file protocol prefix for systemid. This file protocol must be | * the file protocol prefix for systemid. This file protocol must be | ||||
* appended to an absolute path. Typically: <tt>FILE_PROTOCOL_PREFIX + | * appended to an absolute path. Typically: <tt>FILE_PROTOCOL_PREFIX + |
@@ -0,0 +1,46 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE.txt file. | |||||
*/ | |||||
package org.apache.antlib.xml; | |||||
import org.apache.myrmidon.api.TaskException; | |||||
public class XSLTParam | |||||
{ | |||||
private String m_name; | |||||
private String m_expression; | |||||
public void setExpression( String expression ) | |||||
{ | |||||
m_expression = expression; | |||||
} | |||||
public void setName( String name ) | |||||
{ | |||||
m_name = name; | |||||
} | |||||
public String getExpression() | |||||
throws TaskException | |||||
{ | |||||
if( m_expression == null ) | |||||
{ | |||||
throw new TaskException( "Expression attribute is missing." ); | |||||
} | |||||
return m_expression; | |||||
} | |||||
public String getName() | |||||
throws TaskException | |||||
{ | |||||
if( m_name == null ) | |||||
{ | |||||
throw new TaskException( "Name attribute is missing." ); | |||||
} | |||||
return m_name; | |||||
} | |||||
} |
@@ -5,15 +5,18 @@ | |||||
* version 1.1, a copy of which has been included with this distribution in | * version 1.1, a copy of which has been included with this distribution in | ||||
* the LICENSE file. | * the LICENSE file. | ||||
*/ | */ | ||||
package org.apache.tools.ant.taskdefs; | |||||
package org.apache.antlib.xml; | |||||
import java.io.File; | import java.io.File; | ||||
import java.util.Enumeration; | import java.util.Enumeration; | ||||
import java.util.Vector; | import java.util.Vector; | ||||
import java.util.ArrayList; | |||||
import java.util.Iterator; | |||||
import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
import org.apache.tools.ant.AntClassLoader; | import org.apache.tools.ant.AntClassLoader; | ||||
import org.apache.tools.ant.DirectoryScanner; | import org.apache.tools.ant.DirectoryScanner; | ||||
import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
import org.apache.tools.ant.taskdefs.MatchingTask; | |||||
import org.apache.tools.ant.types.Path; | import org.apache.tools.ant.types.Path; | ||||
import org.apache.tools.ant.types.Reference; | import org.apache.tools.ant.types.Reference; | ||||
import org.apache.tools.ant.util.FileUtils; | import org.apache.tools.ant.util.FileUtils; | ||||
@@ -41,44 +44,28 @@ import org.apache.tools.ant.util.FileUtils; | |||||
*/ | */ | ||||
public class XSLTProcess | public class XSLTProcess | ||||
extends MatchingTask | extends MatchingTask | ||||
implements XSLTLogger | |||||
{ | { | ||||
private File destDir = null; | |||||
private File baseDir = null; | |||||
private String xslFile = null; | |||||
private String targetExtension = ".html"; | |||||
private Vector params = new Vector(); | |||||
private File inFile = null; | |||||
private File outFile = null; | |||||
private Path classpath = null; | |||||
private boolean stylesheetLoaded = false; | |||||
private boolean force = false; | |||||
private String outputtype = null; | |||||
private FileUtils fileUtils; | |||||
private XSLTLiaison liaison; | |||||
private String processor; | |||||
public void log( String msg ) | |||||
{ | |||||
getLogger().info( msg ); | |||||
} | |||||
private File m_destDir; | |||||
private File m_baseDir; | |||||
private String m_xslFile; | |||||
private String m_targetExtension = ".html"; | |||||
private ArrayList m_params = new ArrayList(); | |||||
private File m_inFile; | |||||
private File m_outFile; | |||||
private Path m_classpath; | |||||
private boolean m_stylesheetLoaded; | |||||
private boolean m_force; | |||||
private String m_outputtype; | |||||
private FileUtils m_fileUtils; | |||||
private XSLTLiaison m_liaison; | |||||
private String m_processor; | |||||
/** | /** | ||||
* Creates a new XSLTProcess Task. | * Creates a new XSLTProcess Task. | ||||
*/ | */ | ||||
public XSLTProcess() | public XSLTProcess() | ||||
{ | { | ||||
fileUtils = FileUtils.newFileUtils(); | |||||
m_fileUtils = FileUtils.newFileUtils(); | |||||
}//-- setForce | }//-- setForce | ||||
/** | /** | ||||
@@ -88,7 +75,7 @@ public class XSLTProcess | |||||
*/ | */ | ||||
public void setBasedir( File dir ) | public void setBasedir( File dir ) | ||||
{ | { | ||||
baseDir = dir; | |||||
m_baseDir = dir; | |||||
} | } | ||||
/** | /** | ||||
@@ -112,7 +99,7 @@ public class XSLTProcess | |||||
throws TaskException | throws TaskException | ||||
{ | { | ||||
createClasspath().setRefid( r ); | createClasspath().setRefid( r ); | ||||
}//-- setSourceDir | |||||
} | |||||
/** | /** | ||||
* Set the destination directory into which the XSL result files should be | * Set the destination directory into which the XSL result files should be | ||||
@@ -122,8 +109,8 @@ public class XSLTProcess | |||||
*/ | */ | ||||
public void setDestdir( File dir ) | public void setDestdir( File dir ) | ||||
{ | { | ||||
destDir = dir; | |||||
}//-- setDestDir | |||||
m_destDir = dir; | |||||
} | |||||
/** | /** | ||||
* Set the desired file extension to be used for the target | * Set the desired file extension to be used for the target | ||||
@@ -132,8 +119,8 @@ public class XSLTProcess | |||||
*/ | */ | ||||
public void setExtension( String name ) | public void setExtension( String name ) | ||||
{ | { | ||||
targetExtension = name; | |||||
}//-- execute | |||||
m_targetExtension = name; | |||||
} | |||||
/** | /** | ||||
* Set whether to check dependencies, or always generate. | * Set whether to check dependencies, or always generate. | ||||
@@ -142,7 +129,7 @@ public class XSLTProcess | |||||
*/ | */ | ||||
public void setForce( boolean force ) | public void setForce( boolean force ) | ||||
{ | { | ||||
this.force = force; | |||||
this.m_force = force; | |||||
} | } | ||||
/** | /** | ||||
@@ -152,7 +139,7 @@ public class XSLTProcess | |||||
*/ | */ | ||||
public void setIn( File inFile ) | public void setIn( File inFile ) | ||||
{ | { | ||||
this.inFile = inFile; | |||||
this.m_inFile = inFile; | |||||
} | } | ||||
/** | /** | ||||
@@ -162,7 +149,7 @@ public class XSLTProcess | |||||
*/ | */ | ||||
public void setOut( File outFile ) | public void setOut( File outFile ) | ||||
{ | { | ||||
this.outFile = outFile; | |||||
this.m_outFile = outFile; | |||||
} | } | ||||
/** | /** | ||||
@@ -174,12 +161,12 @@ public class XSLTProcess | |||||
*/ | */ | ||||
public void setOutputtype( String type ) | public void setOutputtype( String type ) | ||||
{ | { | ||||
this.outputtype = type; | |||||
this.m_outputtype = type; | |||||
} | } | ||||
public void setProcessor( String processor ) | public void setProcessor( String processor ) | ||||
{ | { | ||||
this.processor = processor; | |||||
this.m_processor = processor; | |||||
}//-- setDestDir | }//-- setDestDir | ||||
/** | /** | ||||
@@ -190,7 +177,7 @@ public class XSLTProcess | |||||
*/ | */ | ||||
public void setStyle( String xslFile ) | public void setStyle( String xslFile ) | ||||
{ | { | ||||
this.xslFile = xslFile; | |||||
this.m_xslFile = xslFile; | |||||
} | } | ||||
/** | /** | ||||
@@ -201,17 +188,17 @@ public class XSLTProcess | |||||
public Path createClasspath() | public Path createClasspath() | ||||
throws TaskException | throws TaskException | ||||
{ | { | ||||
if( classpath == null ) | |||||
if( m_classpath == null ) | |||||
{ | { | ||||
classpath = new Path( project ); | |||||
m_classpath = new Path( project ); | |||||
} | } | ||||
return classpath.createPath(); | |||||
return m_classpath.createPath(); | |||||
} | } | ||||
public Param createParam() | |||||
public XSLTParam createParam() | |||||
{ | { | ||||
Param p = new Param(); | |||||
params.addElement( p ); | |||||
XSLTParam p = new XSLTParam(); | |||||
m_params.add( p ); | |||||
return p; | return p; | ||||
}//-- XSLTProcess | }//-- XSLTProcess | ||||
@@ -228,32 +215,28 @@ public class XSLTProcess | |||||
String[] list; | String[] list; | ||||
String[] dirs; | String[] dirs; | ||||
if( xslFile == null ) | |||||
if( m_xslFile == null ) | |||||
{ | { | ||||
throw new TaskException( "no stylesheet specified" ); | throw new TaskException( "no stylesheet specified" ); | ||||
} | } | ||||
if( baseDir == null ) | |||||
if( m_baseDir == null ) | |||||
{ | { | ||||
baseDir = getBaseDirectory(); | |||||
m_baseDir = getBaseDirectory(); | |||||
} | } | ||||
liaison = getLiaison(); | |||||
m_liaison = getLiaison(); | |||||
// check if liaison wants to log errors using us as logger | // 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 ); | |||||
setupLogger( m_liaison ); | |||||
File stylesheet = resolveFile( xslFile ); | |||||
log( "Using " + m_liaison.getClass().toString(), Project.MSG_VERBOSE ); | |||||
File stylesheet = resolveFile( m_xslFile ); | |||||
// 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( m_inFile != null && m_outFile != null ) | |||||
{ | { | ||||
process( inFile, outFile, stylesheet ); | |||||
process( m_inFile, m_outFile, stylesheet ); | |||||
return; | return; | ||||
} | } | ||||
@@ -262,28 +245,28 @@ public class XSLTProcess | |||||
* in batch processing mode. | * in batch processing mode. | ||||
*/ | */ | ||||
//-- make sure Source directory exists... | //-- make sure Source directory exists... | ||||
if( destDir == null ) | |||||
if( m_destDir == null ) | |||||
{ | { | ||||
String msg = "destdir attributes must be set!"; | String msg = "destdir attributes must be set!"; | ||||
throw new TaskException( msg ); | throw new TaskException( msg ); | ||||
} | } | ||||
scanner = getDirectoryScanner( baseDir ); | |||||
log( "Transforming into " + destDir, Project.MSG_INFO ); | |||||
scanner = getDirectoryScanner( m_baseDir ); | |||||
log( "Transforming into " + m_destDir, Project.MSG_INFO ); | |||||
// Process all the files marked for styling | // Process all the files marked for styling | ||||
list = scanner.getIncludedFiles(); | list = scanner.getIncludedFiles(); | ||||
for( int i = 0; i < list.length; ++i ) | for( int i = 0; i < list.length; ++i ) | ||||
{ | { | ||||
process( baseDir, list[ i ], destDir, stylesheet ); | |||||
process( m_baseDir, list[ i ], m_destDir, stylesheet ); | |||||
} | } | ||||
// Process all the directoried marked for styling | // Process all the directoried marked for styling | ||||
dirs = scanner.getIncludedDirectories(); | dirs = scanner.getIncludedDirectories(); | ||||
for( int j = 0; j < dirs.length; ++j ) | for( int j = 0; j < dirs.length; ++j ) | ||||
{ | { | ||||
list = new File( baseDir, dirs[ j ] ).list(); | |||||
list = new File( m_baseDir, dirs[ j ] ).list(); | |||||
for( int i = 0; i < list.length; ++i ) | for( int i = 0; i < list.length; ++i ) | ||||
process( baseDir, list[ i ], destDir, stylesheet ); | |||||
process( m_baseDir, list[ i ], m_destDir, stylesheet ); | |||||
} | } | ||||
} | } | ||||
@@ -292,13 +275,13 @@ public class XSLTProcess | |||||
{ | { | ||||
// if processor wasn't specified, see if TraX is available. If not, | // 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 | // default it to xslp or xalan, depending on which is in the classpath | ||||
if( liaison == null ) | |||||
if( m_liaison == null ) | |||||
{ | { | ||||
if( processor != null ) | |||||
if( m_processor != null ) | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
resolveProcessor( processor ); | |||||
resolveProcessor( m_processor ); | |||||
} | } | ||||
catch( Exception e ) | catch( Exception e ) | ||||
{ | { | ||||
@@ -341,7 +324,7 @@ public class XSLTProcess | |||||
} | } | ||||
} | } | ||||
} | } | ||||
return liaison; | |||||
return m_liaison; | |||||
} | } | ||||
/** | /** | ||||
@@ -353,26 +336,27 @@ public class XSLTProcess | |||||
protected void configureLiaison( File stylesheet ) | protected void configureLiaison( File stylesheet ) | ||||
throws TaskException | throws TaskException | ||||
{ | { | ||||
if( stylesheetLoaded ) | |||||
if( m_stylesheetLoaded ) | |||||
{ | { | ||||
return; | return; | ||||
} | } | ||||
stylesheetLoaded = true; | |||||
m_stylesheetLoaded = true; | |||||
try | try | ||||
{ | { | ||||
log( "Loading stylesheet " + stylesheet, Project.MSG_INFO ); | |||||
liaison.setStylesheet( stylesheet ); | |||||
for( Enumeration e = params.elements(); e.hasMoreElements(); ) | |||||
getLogger().info( "Loading stylesheet " + stylesheet ); | |||||
m_liaison.setStylesheet( stylesheet ); | |||||
final Iterator params = m_params.iterator(); | |||||
while( params.hasNext() ) | |||||
{ | { | ||||
Param p = (Param)e.nextElement(); | |||||
liaison.addParam( p.getName(), p.getExpression() ); | |||||
final XSLTParam param = (XSLTParam)params.next(); | |||||
m_liaison.addParam( param.getName(), param.getExpression() ); | |||||
} | } | ||||
} | } | ||||
catch( Exception ex ) | |||||
catch( final Exception e ) | |||||
{ | { | ||||
log( "Failed to read stylesheet " + stylesheet, Project.MSG_INFO ); | |||||
throw new TaskException( "Error", ex ); | |||||
getLogger().info( "Failed to read stylesheet " + stylesheet ); | |||||
throw new TaskException( "Error", e ); | |||||
} | } | ||||
} | } | ||||
@@ -401,13 +385,13 @@ public class XSLTProcess | |||||
private Class loadClass( String classname ) | private Class loadClass( String classname ) | ||||
throws Exception | throws Exception | ||||
{ | { | ||||
if( classpath == null ) | |||||
if( m_classpath == null ) | |||||
{ | { | ||||
return Class.forName( classname ); | return Class.forName( classname ); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
AntClassLoader al = new AntClassLoader( project, classpath ); | |||||
AntClassLoader al = new AntClassLoader( project, m_classpath ); | |||||
Class c = al.loadClass( classname ); | Class c = al.loadClass( classname ); | ||||
AntClassLoader.initializeClass( c ); | AntClassLoader.initializeClass( c ); | ||||
return c; | return c; | ||||
@@ -429,7 +413,7 @@ public class XSLTProcess | |||||
throws TaskException | throws TaskException | ||||
{ | { | ||||
String fileExt = targetExtension; | |||||
String fileExt = m_targetExtension; | |||||
File outFile = null; | File outFile = null; | ||||
File inFile = null; | File inFile = null; | ||||
@@ -446,7 +430,7 @@ public class XSLTProcess | |||||
{ | { | ||||
outFile = new File( destDir, xmlFile + fileExt ); | outFile = new File( destDir, xmlFile + fileExt ); | ||||
} | } | ||||
if( force || | |||||
if( m_force || | |||||
inFile.lastModified() > outFile.lastModified() || | inFile.lastModified() > outFile.lastModified() || | ||||
styleSheetLastModified > outFile.lastModified() ) | styleSheetLastModified > outFile.lastModified() ) | ||||
{ | { | ||||
@@ -454,14 +438,14 @@ public class XSLTProcess | |||||
getLogger().info( "Processing " + inFile + " to " + outFile ); | getLogger().info( "Processing " + inFile + " to " + outFile ); | ||||
configureLiaison( stylesheet ); | configureLiaison( stylesheet ); | ||||
liaison.transform( inFile, outFile ); | |||||
m_liaison.transform( inFile, outFile ); | |||||
} | } | ||||
} | } | ||||
catch( Exception ex ) | catch( Exception ex ) | ||||
{ | { | ||||
// If failed to process document, must delete target document, | // If failed to process document, must delete target document, | ||||
// or it will not attempt to process it the second time | // or it will not attempt to process it the second time | ||||
log( "Failed to process " + inFile, Project.MSG_INFO ); | |||||
getLogger().info( "Failed to process " + inFile ); | |||||
if( outFile != null ) | if( outFile != null ) | ||||
{ | { | ||||
outFile.delete(); | outFile.delete(); | ||||
@@ -477,23 +461,24 @@ public class XSLTProcess | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
long styleSheetLastModified = stylesheet.lastModified(); | |||||
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 || | |||||
final long styleSheetLastModified = stylesheet.lastModified(); | |||||
getLogger().debug( "In file " + inFile + " time: " + inFile.lastModified() ); | |||||
getLogger().debug( "Out file " + outFile + " time: " + outFile.lastModified() ); | |||||
getLogger().debug( "Style file " + m_xslFile + " time: " + styleSheetLastModified ); | |||||
if( m_force || | |||||
inFile.lastModified() > outFile.lastModified() || | inFile.lastModified() > outFile.lastModified() || | ||||
styleSheetLastModified > outFile.lastModified() ) | styleSheetLastModified > outFile.lastModified() ) | ||||
{ | { | ||||
ensureDirectoryFor( outFile ); | ensureDirectoryFor( outFile ); | ||||
log( "Processing " + inFile + " to " + outFile, Project.MSG_INFO ); | |||||
getLogger().info( "Processing " + inFile + " to " + outFile ); | |||||
configureLiaison( stylesheet ); | configureLiaison( stylesheet ); | ||||
liaison.transform( inFile, outFile ); | |||||
m_liaison.transform( inFile, outFile ); | |||||
} | } | ||||
} | } | ||||
catch( Exception ex ) | catch( Exception ex ) | ||||
{ | { | ||||
log( "Failed to process " + inFile, Project.MSG_INFO ); | |||||
getLogger().info( "Failed to process " + inFile ); | |||||
if( outFile != null ) | if( outFile != null ) | ||||
outFile.delete(); | outFile.delete(); | ||||
throw new TaskException( "Error", ex ); | throw new TaskException( "Error", ex ); | ||||
@@ -514,50 +499,18 @@ public class XSLTProcess | |||||
{ | { | ||||
final Class clazz = | final Class clazz = | ||||
loadClass( "org.apache.tools.ant.taskdefs.optional.TraXLiaison" ); | loadClass( "org.apache.tools.ant.taskdefs.optional.TraXLiaison" ); | ||||
liaison = (XSLTLiaison)clazz.newInstance(); | |||||
m_liaison = (XSLTLiaison)clazz.newInstance(); | |||||
} | } | ||||
else if( proc.equals( "xalan" ) ) | else if( proc.equals( "xalan" ) ) | ||||
{ | { | ||||
final Class clazz = | final Class clazz = | ||||
loadClass( "org.apache.tools.ant.taskdefs.optional.XalanLiaison" ); | loadClass( "org.apache.tools.ant.taskdefs.optional.XalanLiaison" ); | ||||
liaison = (XSLTLiaison)clazz.newInstance(); | |||||
m_liaison = (XSLTLiaison)clazz.newInstance(); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
liaison = (XSLTLiaison)loadClass( proc ).newInstance(); | |||||
} | |||||
} | |||||
public class Param | |||||
{ | |||||
private String name = null; | |||||
private String expression = null; | |||||
public void setExpression( String expression ) | |||||
{ | |||||
this.expression = expression; | |||||
} | |||||
public void setName( String name ) | |||||
{ | |||||
this.name = name; | |||||
} | |||||
public String getExpression() | |||||
throws TaskException | |||||
{ | |||||
if( expression == null ) | |||||
throw new TaskException( "Expression attribute is missing." ); | |||||
return expression; | |||||
} | |||||
public String getName() | |||||
throws TaskException | |||||
{ | |||||
if( name == null ) | |||||
throw new TaskException( "Name attribute is missing." ); | |||||
return name; | |||||
m_liaison = (XSLTLiaison)loadClass( proc ).newInstance(); | |||||
} | } | ||||
} | } | ||||
}//-- XSLTProcess | |||||
} |
@@ -5,14 +5,13 @@ | |||||
* version 1.1, a copy of which has been included with this distribution in | * version 1.1, a copy of which has been included with this distribution in | ||||
* the LICENSE file. | * the LICENSE file. | ||||
*/ | */ | ||||
package org.apache.tools.ant.taskdefs.optional; | |||||
package org.apache.antlib.xml; | |||||
import java.io.File; | import java.io.File; | ||||
import java.io.FileInputStream; | import java.io.FileInputStream; | ||||
import java.io.FileOutputStream; | import java.io.FileOutputStream; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
import org.apache.tools.ant.taskdefs.XSLTLiaison; | |||||
import org.apache.xalan.xslt.XSLTInputSource; | import org.apache.xalan.xslt.XSLTInputSource; | ||||
import org.apache.xalan.xslt.XSLTProcessor; | import org.apache.xalan.xslt.XSLTProcessor; | ||||
import org.apache.xalan.xslt.XSLTProcessorFactory; | import org.apache.xalan.xslt.XSLTProcessorFactory; | ||||
@@ -24,11 +23,11 @@ import org.apache.xalan.xslt.XSLTResultTarget; | |||||
* @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a> | * @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a> | ||||
* @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a> | * @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a> | ||||
*/ | */ | ||||
public class XalanLiaison implements XSLTLiaison | |||||
public class XalanLiaison | |||||
implements XSLTLiaison | |||||
{ | { | ||||
protected XSLTProcessor processor; | |||||
protected File stylesheet; | |||||
private XSLTProcessor processor; | |||||
private File stylesheet; | |||||
public XalanLiaison() | public XalanLiaison() | ||||
throws Exception | throws Exception |
@@ -1,18 +0,0 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE file. | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs; | |||||
public interface XSLTLogger | |||||
{ | |||||
/** | |||||
* Log a message. | |||||
* | |||||
* @param msg Description of Parameter | |||||
*/ | |||||
void log( String msg ); | |||||
} |
@@ -1,13 +0,0 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE file. | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs; | |||||
public interface XSLTLoggerAware | |||||
{ | |||||
void setLogger( XSLTLogger l ); | |||||
} |
@@ -1,563 +0,0 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE file. | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs; | |||||
import java.io.File; | |||||
import java.util.Enumeration; | |||||
import java.util.Vector; | |||||
import org.apache.myrmidon.api.TaskException; | |||||
import org.apache.tools.ant.AntClassLoader; | |||||
import org.apache.tools.ant.DirectoryScanner; | |||||
import org.apache.tools.ant.Project; | |||||
import org.apache.tools.ant.types.Path; | |||||
import org.apache.tools.ant.types.Reference; | |||||
import org.apache.tools.ant.util.FileUtils; | |||||
/** | |||||
* A Task to process via XSLT a set of XML documents. This is useful for | |||||
* building views of XML based documentation. arguments: | |||||
* <ul> | |||||
* <li> basedir | |||||
* <li> destdir | |||||
* <li> style | |||||
* <li> includes | |||||
* <li> excludes | |||||
* </ul> | |||||
* Of these arguments, the <b>sourcedir</b> and <b>destdir</b> are required. <p> | |||||
* | |||||
* This task will recursively scan the sourcedir and destdir looking for XML | |||||
* documents to process via XSLT. Any other files, such as images, or html files | |||||
* in the source directory will be copied into the destination directory. | |||||
* | |||||
* @author <a href="mailto:kvisco@exoffice.com">Keith Visco</a> | |||||
* @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a> | |||||
* @author <a href="mailto:russgold@acm.org">Russell Gold</a> | |||||
* @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
*/ | |||||
public class XSLTProcess | |||||
extends MatchingTask | |||||
implements XSLTLogger | |||||
{ | |||||
private File destDir = null; | |||||
private File baseDir = null; | |||||
private String xslFile = null; | |||||
private String targetExtension = ".html"; | |||||
private Vector params = new Vector(); | |||||
private File inFile = null; | |||||
private File outFile = null; | |||||
private Path classpath = null; | |||||
private boolean stylesheetLoaded = false; | |||||
private boolean force = false; | |||||
private String outputtype = null; | |||||
private FileUtils fileUtils; | |||||
private XSLTLiaison liaison; | |||||
private String processor; | |||||
public void log( String msg ) | |||||
{ | |||||
getLogger().info( msg ); | |||||
} | |||||
/** | |||||
* Creates a new XSLTProcess Task. | |||||
*/ | |||||
public XSLTProcess() | |||||
{ | |||||
fileUtils = FileUtils.newFileUtils(); | |||||
}//-- setForce | |||||
/** | |||||
* Set the base directory. | |||||
* | |||||
* @param dir The new Basedir value | |||||
*/ | |||||
public void setBasedir( File dir ) | |||||
{ | |||||
baseDir = dir; | |||||
} | |||||
/** | |||||
* Set the classpath to load the Processor through (attribute). | |||||
* | |||||
* @param classpath The new Classpath value | |||||
*/ | |||||
public void setClasspath( Path classpath ) | |||||
throws TaskException | |||||
{ | |||||
createClasspath().append( classpath ); | |||||
} | |||||
/** | |||||
* Set the classpath to load the Processor through via reference | |||||
* (attribute). | |||||
* | |||||
* @param r The new ClasspathRef value | |||||
*/ | |||||
public void setClasspathRef( Reference r ) | |||||
throws TaskException | |||||
{ | |||||
createClasspath().setRefid( r ); | |||||
}//-- setSourceDir | |||||
/** | |||||
* Set the destination directory into which the XSL result files should be | |||||
* copied to | |||||
* | |||||
* @param dir The new Destdir value | |||||
*/ | |||||
public void setDestdir( File dir ) | |||||
{ | |||||
destDir = dir; | |||||
}//-- setDestDir | |||||
/** | |||||
* Set the desired file extension to be used for the target | |||||
* | |||||
* @param name the extension to use | |||||
*/ | |||||
public void setExtension( String name ) | |||||
{ | |||||
targetExtension = name; | |||||
}//-- execute | |||||
/** | |||||
* Set whether to check dependencies, or always generate. | |||||
* | |||||
* @param force The new Force value | |||||
*/ | |||||
public void setForce( boolean force ) | |||||
{ | |||||
this.force = force; | |||||
} | |||||
/** | |||||
* Sets an input xml file to be styled | |||||
* | |||||
* @param inFile The new In value | |||||
*/ | |||||
public void setIn( File inFile ) | |||||
{ | |||||
this.inFile = inFile; | |||||
} | |||||
/** | |||||
* Sets an out file | |||||
* | |||||
* @param outFile The new Out value | |||||
*/ | |||||
public void setOut( File outFile ) | |||||
{ | |||||
this.outFile = outFile; | |||||
} | |||||
/** | |||||
* Set the output type to use for the transformation. Only "xml" (the | |||||
* default) is guaranteed to work for all parsers. Xalan2 also supports | |||||
* "html" and "text". | |||||
* | |||||
* @param type the output method to use | |||||
*/ | |||||
public void setOutputtype( String type ) | |||||
{ | |||||
this.outputtype = type; | |||||
} | |||||
public void setProcessor( String processor ) | |||||
{ | |||||
this.processor = processor; | |||||
}//-- setDestDir | |||||
/** | |||||
* Sets the file to use for styling relative to the base directory of this | |||||
* task. | |||||
* | |||||
* @param xslFile The new Style value | |||||
*/ | |||||
public void setStyle( String xslFile ) | |||||
{ | |||||
this.xslFile = xslFile; | |||||
} | |||||
/** | |||||
* Set the classpath to load the Processor through (nested element). | |||||
* | |||||
* @return Description of the Returned Value | |||||
*/ | |||||
public Path createClasspath() | |||||
throws TaskException | |||||
{ | |||||
if( classpath == null ) | |||||
{ | |||||
classpath = new Path( project ); | |||||
} | |||||
return classpath.createPath(); | |||||
} | |||||
public Param createParam() | |||||
{ | |||||
Param p = new Param(); | |||||
params.addElement( p ); | |||||
return p; | |||||
}//-- XSLTProcess | |||||
/** | |||||
* Executes the task. | |||||
* | |||||
* @exception TaskException Description of Exception | |||||
*/ | |||||
public void execute() | |||||
throws TaskException | |||||
{ | |||||
DirectoryScanner scanner; | |||||
String[] list; | |||||
String[] dirs; | |||||
if( xslFile == null ) | |||||
{ | |||||
throw new TaskException( "no stylesheet specified" ); | |||||
} | |||||
if( baseDir == null ) | |||||
{ | |||||
baseDir = getBaseDirectory(); | |||||
} | |||||
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 ); | |||||
File stylesheet = resolveFile( xslFile ); | |||||
// if we have an in file and out then process them | |||||
if( inFile != null && outFile != null ) | |||||
{ | |||||
process( inFile, outFile, stylesheet ); | |||||
return; | |||||
} | |||||
/* | |||||
* if we get here, in and out have not been specified, we are | |||||
* in batch processing mode. | |||||
*/ | |||||
//-- make sure Source directory exists... | |||||
if( destDir == null ) | |||||
{ | |||||
String msg = "destdir attributes must be set!"; | |||||
throw new TaskException( msg ); | |||||
} | |||||
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 ); | |||||
} | |||||
// Process all the directoried 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, list[ i ], destDir, stylesheet ); | |||||
} | |||||
} | |||||
protected XSLTLiaison getLiaison() | |||||
throws TaskException | |||||
{ | |||||
// 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 | |||||
if( liaison == null ) | |||||
{ | |||||
if( processor != null ) | |||||
{ | |||||
try | |||||
{ | |||||
resolveProcessor( processor ); | |||||
} | |||||
catch( Exception e ) | |||||
{ | |||||
throw new TaskException( "Error", e ); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
try | |||||
{ | |||||
resolveProcessor( "trax" ); | |||||
} | |||||
catch( Throwable e1 ) | |||||
{ | |||||
try | |||||
{ | |||||
resolveProcessor( "xalan" ); | |||||
} | |||||
catch( Throwable e2 ) | |||||
{ | |||||
try | |||||
{ | |||||
resolveProcessor( "adaptx" ); | |||||
} | |||||
catch( Throwable e3 ) | |||||
{ | |||||
try | |||||
{ | |||||
resolveProcessor( "xslp" ); | |||||
} | |||||
catch( Throwable e4 ) | |||||
{ | |||||
e4.printStackTrace(); | |||||
e3.printStackTrace(); | |||||
e2.printStackTrace(); | |||||
throw new TaskException( "Error", e1 ); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return liaison; | |||||
} | |||||
/** | |||||
* Loads the stylesheet and set xsl:param parameters. | |||||
* | |||||
* @param stylesheet Description of Parameter | |||||
* @exception TaskException Description of Exception | |||||
*/ | |||||
protected void configureLiaison( File stylesheet ) | |||||
throws TaskException | |||||
{ | |||||
if( stylesheetLoaded ) | |||||
{ | |||||
return; | |||||
} | |||||
stylesheetLoaded = true; | |||||
try | |||||
{ | |||||
log( "Loading stylesheet " + stylesheet, Project.MSG_INFO ); | |||||
liaison.setStylesheet( stylesheet ); | |||||
for( Enumeration e = params.elements(); e.hasMoreElements(); ) | |||||
{ | |||||
Param p = (Param)e.nextElement(); | |||||
liaison.addParam( p.getName(), p.getExpression() ); | |||||
} | |||||
} | |||||
catch( Exception ex ) | |||||
{ | |||||
log( "Failed to read stylesheet " + stylesheet, Project.MSG_INFO ); | |||||
throw new TaskException( "Error", ex ); | |||||
} | |||||
} | |||||
private void ensureDirectoryFor( File targetFile ) | |||||
throws TaskException | |||||
{ | |||||
File directory = new File( targetFile.getParent() ); | |||||
if( !directory.exists() ) | |||||
{ | |||||
if( !directory.mkdirs() ) | |||||
{ | |||||
throw new TaskException( "Unable to create directory: " | |||||
+ directory.getAbsolutePath() ); | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Load named class either via the system classloader or a given custom | |||||
* classloader. | |||||
* | |||||
* @param classname Description of Parameter | |||||
* @return Description of the Returned Value | |||||
* @exception Exception Description of Exception | |||||
*/ | |||||
private Class loadClass( String classname ) | |||||
throws Exception | |||||
{ | |||||
if( classpath == null ) | |||||
{ | |||||
return Class.forName( classname ); | |||||
} | |||||
else | |||||
{ | |||||
AntClassLoader al = new AntClassLoader( project, classpath ); | |||||
Class c = al.loadClass( classname ); | |||||
AntClassLoader.initializeClass( c ); | |||||
return c; | |||||
} | |||||
} | |||||
/** | |||||
* Processes the given input XML file and stores the result in the given | |||||
* resultFile. | |||||
* | |||||
* @param baseDir Description of Parameter | |||||
* @param xmlFile Description of Parameter | |||||
* @param destDir Description of Parameter | |||||
* @param stylesheet Description of Parameter | |||||
* @exception TaskException Description of Exception | |||||
*/ | |||||
private void process( File baseDir, String xmlFile, File destDir, | |||||
File stylesheet ) | |||||
throws TaskException | |||||
{ | |||||
String fileExt = targetExtension; | |||||
File outFile = null; | |||||
File inFile = null; | |||||
try | |||||
{ | |||||
long styleSheetLastModified = stylesheet.lastModified(); | |||||
inFile = new File( baseDir, xmlFile ); | |||||
int dotPos = xmlFile.lastIndexOf( '.' ); | |||||
if( dotPos > 0 ) | |||||
{ | |||||
outFile = new File( destDir, xmlFile.substring( 0, xmlFile.lastIndexOf( '.' ) ) + fileExt ); | |||||
} | |||||
else | |||||
{ | |||||
outFile = new File( destDir, xmlFile + fileExt ); | |||||
} | |||||
if( force || | |||||
inFile.lastModified() > outFile.lastModified() || | |||||
styleSheetLastModified > outFile.lastModified() ) | |||||
{ | |||||
ensureDirectoryFor( outFile ); | |||||
getLogger().info( "Processing " + inFile + " to " + outFile ); | |||||
configureLiaison( stylesheet ); | |||||
liaison.transform( inFile, outFile ); | |||||
} | |||||
} | |||||
catch( 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( outFile != null ) | |||||
{ | |||||
outFile.delete(); | |||||
} | |||||
throw new TaskException( "Error", ex ); | |||||
} | |||||
}//-- processXML | |||||
private void process( File inFile, File outFile, File stylesheet ) | |||||
throws TaskException | |||||
{ | |||||
try | |||||
{ | |||||
long styleSheetLastModified = stylesheet.lastModified(); | |||||
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 ); | |||||
liaison.transform( inFile, outFile ); | |||||
} | |||||
} | |||||
catch( Exception ex ) | |||||
{ | |||||
log( "Failed to process " + inFile, Project.MSG_INFO ); | |||||
if( outFile != null ) | |||||
outFile.delete(); | |||||
throw new TaskException( "Error", ex ); | |||||
} | |||||
} | |||||
/** | |||||
* Load processor here instead of in setProcessor - this will be called from | |||||
* within execute, so we have access to the latest classpath. | |||||
* | |||||
* @param proc Description of Parameter | |||||
* @exception Exception Description of Exception | |||||
*/ | |||||
private void resolveProcessor( String proc ) | |||||
throws Exception | |||||
{ | |||||
if( proc.equals( "trax" ) ) | |||||
{ | |||||
final Class clazz = | |||||
loadClass( "org.apache.tools.ant.taskdefs.optional.TraXLiaison" ); | |||||
liaison = (XSLTLiaison)clazz.newInstance(); | |||||
} | |||||
else if( proc.equals( "xalan" ) ) | |||||
{ | |||||
final Class clazz = | |||||
loadClass( "org.apache.tools.ant.taskdefs.optional.XalanLiaison" ); | |||||
liaison = (XSLTLiaison)clazz.newInstance(); | |||||
} | |||||
else | |||||
{ | |||||
liaison = (XSLTLiaison)loadClass( proc ).newInstance(); | |||||
} | |||||
} | |||||
public class Param | |||||
{ | |||||
private String name = null; | |||||
private String expression = null; | |||||
public void setExpression( String expression ) | |||||
{ | |||||
this.expression = expression; | |||||
} | |||||
public void setName( String name ) | |||||
{ | |||||
this.name = name; | |||||
} | |||||
public String getExpression() | |||||
throws TaskException | |||||
{ | |||||
if( expression == null ) | |||||
throw new TaskException( "Expression attribute is missing." ); | |||||
return expression; | |||||
} | |||||
public String getName() | |||||
throws TaskException | |||||
{ | |||||
if( name == null ) | |||||
throw new TaskException( "Name attribute is missing." ); | |||||
return name; | |||||
} | |||||
} | |||||
}//-- XSLTProcess |
@@ -1,75 +0,0 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE file. | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs; | |||||
import java.io.File; | |||||
/** | |||||
* Proxy interface for XSLT processors. | |||||
* | |||||
* @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a> | |||||
* @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a> | |||||
* @see XSLTProcess | |||||
*/ | |||||
public interface XSLTLiaison | |||||
{ | |||||
/** | |||||
* 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 :) | |||||
*/ | |||||
String FILE_PROTOCOL_PREFIX = "file:///"; | |||||
/** | |||||
* set the stylesheet to use for the transformation. | |||||
* | |||||
* @param stylesheet the stylesheet to be used for transformation. | |||||
* @exception Exception Description of Exception | |||||
*/ | |||||
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. | |||||
*/ | |||||
void addParam( String name, String expression ) | |||||
throws Exception; | |||||
/** | |||||
* set the output type to use for the transformation. Only "xml" (the | |||||
* default) is guaranteed to work for all parsers. Xalan2 also supports | |||||
* "html" and "text". | |||||
* | |||||
* @param type the output method to use | |||||
* @exception Exception Description of Exception | |||||
*/ | |||||
void setOutputtype( String type ) | |||||
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 | |||||
* @see #setStylesheet(File) | |||||
* @throws Exception thrown if any problems happens. | |||||
*/ | |||||
void transform( File infile, File outfile ) | |||||
throws Exception; | |||||
}//-- XSLTLiaison |
@@ -1,18 +0,0 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE file. | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs; | |||||
public interface XSLTLogger | |||||
{ | |||||
/** | |||||
* Log a message. | |||||
* | |||||
* @param msg Description of Parameter | |||||
*/ | |||||
void log( String msg ); | |||||
} |
@@ -1,13 +0,0 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE file. | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs; | |||||
public interface XSLTLoggerAware | |||||
{ | |||||
void setLogger( XSLTLogger l ); | |||||
} |
@@ -1,220 +0,0 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE file. | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs.optional; | |||||
import java.io.File; | |||||
import java.io.FileInputStream; | |||||
import java.io.FileOutputStream; | |||||
import java.io.IOException; | |||||
import javax.xml.transform.ErrorListener; | |||||
import javax.xml.transform.OutputKeys; | |||||
import javax.xml.transform.Templates; | |||||
import javax.xml.transform.Transformer; | |||||
import javax.xml.transform.TransformerException; | |||||
import javax.xml.transform.TransformerFactory; | |||||
import javax.xml.transform.stream.StreamResult; | |||||
import javax.xml.transform.stream.StreamSource; | |||||
import org.apache.tools.ant.taskdefs.XSLTLiaison; | |||||
import org.apache.tools.ant.taskdefs.XSLTLogger; | |||||
import org.apache.tools.ant.taskdefs.XSLTLoggerAware; | |||||
/** | |||||
* Concrete liaison for XSLT processor implementing TraX. (ie JAXP 1.1) | |||||
* | |||||
* @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a> | |||||
* @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a> | |||||
* @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a> | |||||
*/ | |||||
public class TraXLiaison implements XSLTLiaison, ErrorListener, XSLTLoggerAware | |||||
{ | |||||
/** | |||||
* The trax TransformerFactory | |||||
*/ | |||||
private TransformerFactory tfactory = null; | |||||
/** | |||||
* stylesheet stream, close it asap | |||||
*/ | |||||
private FileInputStream xslStream = null; | |||||
/** | |||||
* Stylesheet template | |||||
*/ | |||||
private Templates templates = null; | |||||
/** | |||||
* transformer | |||||
*/ | |||||
private Transformer transformer = null; | |||||
private XSLTLogger logger; | |||||
public TraXLiaison() | |||||
throws Exception | |||||
{ | |||||
tfactory = TransformerFactory.newInstance(); | |||||
tfactory.setErrorListener( this ); | |||||
} | |||||
public void setLogger( XSLTLogger l ) | |||||
{ | |||||
logger = l; | |||||
} | |||||
public void setOutputtype( String type ) | |||||
throws Exception | |||||
{ | |||||
transformer.setOutputProperty( OutputKeys.METHOD, type ); | |||||
} | |||||
//------------------- 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( getSystemId( stylesheet ) ); | |||||
templates = tfactory.newTemplates( src ); | |||||
transformer = templates.newTransformer(); | |||||
transformer.setErrorListener( this ); | |||||
} | |||||
public void addParam( String name, String value ) | |||||
{ | |||||
transformer.setParameter( name, value ); | |||||
} | |||||
public void error( TransformerException e ) | |||||
{ | |||||
logError( e, "Error" ); | |||||
} | |||||
public void fatalError( TransformerException e ) | |||||
{ | |||||
logError( e, "Fatal Error" ); | |||||
} | |||||
public void transform( File infile, File outfile ) | |||||
throws Exception | |||||
{ | |||||
FileInputStream fis = null; | |||||
FileOutputStream fos = null; | |||||
try | |||||
{ | |||||
fis = new FileInputStream( infile ); | |||||
fos = new FileOutputStream( outfile ); | |||||
StreamSource src = new StreamSource( fis ); | |||||
src.setSystemId( getSystemId( infile ) ); | |||||
StreamResult res = new StreamResult( fos ); | |||||
// not sure what could be the need of this... | |||||
res.setSystemId( getSystemId( outfile ) ); | |||||
transformer.transform( src, 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 ) | |||||
{ | |||||
} | |||||
} | |||||
} | |||||
public void warning( TransformerException e ) | |||||
{ | |||||
logError( e, "Warning" ); | |||||
} | |||||
// make sure that the systemid is made of '/' and not '\' otherwise | |||||
// crimson will complain that it cannot resolve relative entities | |||||
// because it grabs the base uri via lastIndexOf('/') without | |||||
// making sure it is really a /'ed path | |||||
protected String getSystemId( File file ) | |||||
{ | |||||
String path = file.getAbsolutePath(); | |||||
path = path.replace( '\\', '/' ); | |||||
return FILE_PROTOCOL_PREFIX + path; | |||||
} | |||||
private void logError( TransformerException e, String type ) | |||||
{ | |||||
StringBuffer msg = new StringBuffer(); | |||||
if( e.getLocator() != null ) | |||||
{ | |||||
if( e.getLocator().getSystemId() != null ) | |||||
{ | |||||
String url = e.getLocator().getSystemId(); | |||||
if( url.startsWith( "file:///" ) ) | |||||
url = url.substring( 8 ); | |||||
msg.append( url ); | |||||
} | |||||
else | |||||
{ | |||||
msg.append( "Unknown file" ); | |||||
} | |||||
if( e.getLocator().getLineNumber() != -1 ) | |||||
{ | |||||
msg.append( ":" + e.getLocator().getLineNumber() ); | |||||
if( e.getLocator().getColumnNumber() != -1 ) | |||||
{ | |||||
msg.append( ":" + e.getLocator().getColumnNumber() ); | |||||
} | |||||
} | |||||
} | |||||
msg.append( ": " + type + "! " ); | |||||
msg.append( e.getMessage() ); | |||||
if( e.getCause() != null ) | |||||
{ | |||||
msg.append( " Cause: " + e.getCause() ); | |||||
} | |||||
logger.log( msg.toString() ); | |||||
} | |||||
}//-- TraXLiaison |
@@ -1,654 +0,0 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE file. | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs.optional; | |||||
import java.io.File; | |||||
import java.io.FileInputStream; | |||||
import java.io.FileNotFoundException; | |||||
import java.io.FileReader; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import java.net.MalformedURLException; | |||||
import java.net.URL; | |||||
import java.util.Enumeration; | |||||
import java.util.Hashtable; | |||||
import java.util.Vector; | |||||
import org.apache.myrmidon.api.TaskException; | |||||
import org.apache.tools.ant.AntClassLoader; | |||||
import org.apache.tools.ant.DirectoryScanner; | |||||
import org.apache.tools.ant.Project; | |||||
import org.apache.tools.ant.Task; | |||||
import org.apache.tools.ant.types.FileSet; | |||||
import org.apache.tools.ant.types.Path; | |||||
import org.apache.tools.ant.types.Reference; | |||||
import org.xml.sax.EntityResolver; | |||||
import org.xml.sax.ErrorHandler; | |||||
import org.xml.sax.InputSource; | |||||
import org.xml.sax.Parser; | |||||
import org.xml.sax.SAXException; | |||||
import org.xml.sax.SAXNotRecognizedException; | |||||
import org.xml.sax.SAXNotSupportedException; | |||||
import org.xml.sax.SAXParseException; | |||||
import org.xml.sax.XMLReader; | |||||
import org.xml.sax.helpers.ParserAdapter; | |||||
/** | |||||
* The <code>XMLValidateTask</code> checks that an XML document is valid, with a | |||||
* SAX validating parser. | |||||
* | |||||
* @author Raphael Pierquin <a href="mailto:raphael.pierquin@agisphere.com"> | |||||
* raphael.pierquin@agisphere.com</a> | |||||
*/ | |||||
public class XMLValidateTask extends Task | |||||
{ | |||||
/** | |||||
* The default implementation parser classname used by the task to process | |||||
* validation. | |||||
*/ | |||||
// The crimson implementation is shipped with ant. | |||||
public static String DEFAULT_XML_READER_CLASSNAME = "org.apache.crimson.parser.XMLReaderImpl"; | |||||
protected static String INIT_FAILED_MSG = "Could not start xml validation: "; | |||||
// ant task properties | |||||
// defaults | |||||
protected boolean failOnError = true; | |||||
protected boolean warn = true; | |||||
protected boolean lenient = false; | |||||
protected String readerClassName = DEFAULT_XML_READER_CLASSNAME; | |||||
protected File file = null;// file to be validated | |||||
protected Vector filesets = new Vector(); | |||||
/** | |||||
* the parser is viewed as a SAX2 XMLReader. If a SAX1 parser is specified, | |||||
* it's wrapped in an adapter that make it behave as a XMLReader. a more | |||||
* 'standard' way of doing this would be to use the JAXP1.1 SAXParser | |||||
* interface. | |||||
*/ | |||||
protected XMLReader xmlReader = null;// XMLReader used to validation process | |||||
protected ValidatorErrorHandler errorHandler | |||||
= new ValidatorErrorHandler();// to report sax parsing errors | |||||
protected Hashtable features = new Hashtable(); | |||||
/** | |||||
* The list of configured DTD locations | |||||
*/ | |||||
public Vector dtdLocations = new Vector();// sets of file to be validated | |||||
protected Path classpath; | |||||
/** | |||||
* Specify the class name of the SAX parser to be used. (optional) | |||||
* | |||||
* @param className should be an implementation of SAX2 <code>org.xml.sax.XMLReader</code> | |||||
* or SAX2 <code>org.xml.sax.Parser</code>. <p> | |||||
* | |||||
* if className is an implementation of <code>org.xml.sax.Parser</code> | |||||
* , {@link #setLenient(boolean)}, will be ignored. <p> | |||||
* | |||||
* if not set, the default {@link #DEFAULT_XML_READER_CLASSNAME} will | |||||
* be used. | |||||
* @see org.xml.sax.XMLReader | |||||
* @see org.xml.sax.Parser | |||||
*/ | |||||
public void setClassName( String className ) | |||||
{ | |||||
readerClassName = className; | |||||
} | |||||
/** | |||||
* Specify the classpath to be searched to load the parser (optional) | |||||
* | |||||
* @param classpath The new Classpath value | |||||
*/ | |||||
public void setClasspath( Path classpath ) | |||||
throws TaskException | |||||
{ | |||||
if( this.classpath == null ) | |||||
{ | |||||
this.classpath = classpath; | |||||
} | |||||
else | |||||
{ | |||||
this.classpath.append( classpath ); | |||||
} | |||||
} | |||||
/** | |||||
* @param r The new ClasspathRef value | |||||
* @see #setClasspath | |||||
*/ | |||||
public void setClasspathRef( Reference r ) | |||||
throws TaskException | |||||
{ | |||||
createClasspath().setRefid( r ); | |||||
} | |||||
/** | |||||
* Specify how parser error are to be handled. <p> | |||||
* | |||||
* If set to <code>true</code> (default), throw a TaskException if the | |||||
* parser yields an error. | |||||
* | |||||
* @param fail The new FailOnError value | |||||
*/ | |||||
public void setFailOnError( boolean fail ) | |||||
{ | |||||
failOnError = fail; | |||||
} | |||||
/** | |||||
* specifify the file to be checked | |||||
* | |||||
* @param file The new File value | |||||
*/ | |||||
public void setFile( File file ) | |||||
{ | |||||
this.file = file; | |||||
} | |||||
/** | |||||
* Specify whether the parser should be validating. Default is <code>true</code> | |||||
* . <p> | |||||
* | |||||
* If set to false, the validation will fail only if the parsed document is | |||||
* not well formed XML. <p> | |||||
* | |||||
* this option is ignored if the specified class with {@link | |||||
* #setClassName(String)} is not a SAX2 XMLReader. | |||||
* | |||||
* @param bool The new Lenient value | |||||
*/ | |||||
public void setLenient( boolean bool ) | |||||
{ | |||||
lenient = bool; | |||||
} | |||||
/** | |||||
* Specify how parser error are to be handled. <p> | |||||
* | |||||
* If set to <code>true | |||||
*</true> | |||||
*(default), log a warn message for each SAX warn event. | |||||
* | |||||
* @param bool The new Warn value | |||||
*/ | |||||
public void setWarn( boolean bool ) | |||||
{ | |||||
warn = bool; | |||||
} | |||||
/** | |||||
* specifify a set of file to be checked | |||||
* | |||||
* @param set The feature to be added to the Fileset attribute | |||||
*/ | |||||
public void addFileset( FileSet set ) | |||||
{ | |||||
filesets.addElement( set ); | |||||
} | |||||
/** | |||||
* @return Description of the Returned Value | |||||
* @see #setClasspath | |||||
*/ | |||||
public Path createClasspath() | |||||
throws TaskException | |||||
{ | |||||
if( this.classpath == null ) | |||||
{ | |||||
this.classpath = new Path( project ); | |||||
} | |||||
return this.classpath.createPath(); | |||||
} | |||||
/** | |||||
* Create a DTD location record. This stores the location of a DTD. The DTD | |||||
* is identified by its public Id. The location may either be a file | |||||
* location or a resource location. | |||||
* | |||||
* @return Description of the Returned Value | |||||
*/ | |||||
public DTDLocation createDTD() | |||||
{ | |||||
DTDLocation dtdLocation = new DTDLocation(); | |||||
dtdLocations.addElement( dtdLocation ); | |||||
return dtdLocation; | |||||
} | |||||
public void execute() | |||||
throws TaskException | |||||
{ | |||||
int fileProcessed = 0; | |||||
if( file == null && ( filesets.size() == 0 ) ) | |||||
{ | |||||
throw new TaskException( "Specify at least one source - a file or a fileset." ); | |||||
} | |||||
initValidator(); | |||||
if( file != null ) | |||||
{ | |||||
if( file.exists() && file.canRead() && file.isFile() ) | |||||
{ | |||||
doValidate( file ); | |||||
fileProcessed++; | |||||
} | |||||
else | |||||
{ | |||||
String errorMsg = "File " + file + " cannot be read"; | |||||
if( failOnError ) | |||||
throw new TaskException( errorMsg ); | |||||
else | |||||
log( errorMsg, Project.MSG_ERR ); | |||||
} | |||||
} | |||||
for( int i = 0; i < filesets.size(); i++ ) | |||||
{ | |||||
FileSet fs = (FileSet)filesets.elementAt( i ); | |||||
DirectoryScanner ds = fs.getDirectoryScanner( project ); | |||||
String[] files = ds.getIncludedFiles(); | |||||
for( int j = 0; j < files.length; j++ ) | |||||
{ | |||||
File srcFile = new File( fs.getDir( project ), files[ j ] ); | |||||
doValidate( srcFile ); | |||||
fileProcessed++; | |||||
} | |||||
} | |||||
getLogger().info( fileProcessed + " file(s) have been successfully validated." ); | |||||
} | |||||
protected EntityResolver getEntityResolver() | |||||
{ | |||||
LocalResolver resolver = new LocalResolver(); | |||||
for( Enumeration i = dtdLocations.elements(); i.hasMoreElements(); ) | |||||
{ | |||||
DTDLocation location = (DTDLocation)i.nextElement(); | |||||
resolver.registerDTD( location ); | |||||
} | |||||
return resolver; | |||||
} | |||||
/* | |||||
* set a feature on the parser. | |||||
* TODO: find a way to set any feature from build.xml | |||||
*/ | |||||
private boolean setFeature( String feature, boolean value, boolean warn ) | |||||
{ | |||||
boolean toReturn = false; | |||||
try | |||||
{ | |||||
xmlReader.setFeature( feature, value ); | |||||
toReturn = true; | |||||
} | |||||
catch( SAXNotRecognizedException e ) | |||||
{ | |||||
if( warn ) | |||||
log( "Could not set feature '" | |||||
+ feature | |||||
+ "' because the parser doesn't recognize it", | |||||
Project.MSG_WARN ); | |||||
} | |||||
catch( SAXNotSupportedException e ) | |||||
{ | |||||
if( warn ) | |||||
log( "Could not set feature '" | |||||
+ feature | |||||
+ "' because the parser doesn't support it", | |||||
Project.MSG_WARN ); | |||||
} | |||||
return toReturn; | |||||
} | |||||
/* | |||||
* parse the file | |||||
*/ | |||||
private void doValidate( File afile ) | |||||
throws TaskException | |||||
{ | |||||
try | |||||
{ | |||||
log( "Validating " + afile.getName() + "... ", Project.MSG_VERBOSE ); | |||||
errorHandler.init( afile ); | |||||
InputSource is = new InputSource( new FileReader( afile ) ); | |||||
String uri = "file:" + afile.getAbsolutePath().replace( '\\', '/' ); | |||||
for( int index = uri.indexOf( '#' ); index != -1; | |||||
index = uri.indexOf( '#' ) ) | |||||
{ | |||||
uri = uri.substring( 0, index ) + "%23" + uri.substring( index + 1 ); | |||||
} | |||||
is.setSystemId( uri ); | |||||
xmlReader.parse( is ); | |||||
} | |||||
catch( SAXException ex ) | |||||
{ | |||||
if( failOnError ) | |||||
throw new TaskException( "Could not validate document " + afile ); | |||||
} | |||||
catch( IOException ex ) | |||||
{ | |||||
throw new TaskException( "Could not validate document " + afile, ex ); | |||||
} | |||||
if( errorHandler.getFailure() ) | |||||
{ | |||||
if( failOnError ) | |||||
throw new TaskException( afile + " is not a valid XML document." ); | |||||
else | |||||
log( afile + " is not a valid XML document", Project.MSG_ERR ); | |||||
} | |||||
} | |||||
/** | |||||
* init the parser : load the parser class, and set features if necessary | |||||
*/ | |||||
private void initValidator() | |||||
throws TaskException | |||||
{ | |||||
try | |||||
{ | |||||
// load the parser class | |||||
// with JAXP, we would use a SAXParser factory | |||||
Class readerClass = null; | |||||
//Class readerImpl = null; | |||||
//Class parserImpl = null; | |||||
if( classpath != null ) | |||||
{ | |||||
AntClassLoader loader = new AntClassLoader( project, classpath ); | |||||
// loader.addSystemPackageRoot("org.xml"); // needed to avoid conflict | |||||
readerClass = loader.loadClass( readerClassName ); | |||||
AntClassLoader.initializeClass( readerClass ); | |||||
} | |||||
else | |||||
readerClass = Class.forName( readerClassName ); | |||||
// then check it implements XMLReader | |||||
if( XMLReader.class.isAssignableFrom( readerClass ) ) | |||||
{ | |||||
xmlReader = (XMLReader)readerClass.newInstance(); | |||||
log( "Using SAX2 reader " + readerClassName, Project.MSG_VERBOSE ); | |||||
} | |||||
else | |||||
{ | |||||
// see if it is a SAX1 Parser | |||||
if( Parser.class.isAssignableFrom( readerClass ) ) | |||||
{ | |||||
Parser parser = (Parser)readerClass.newInstance(); | |||||
xmlReader = new ParserAdapter( parser ); | |||||
log( "Using SAX1 parser " + readerClassName, Project.MSG_VERBOSE ); | |||||
} | |||||
else | |||||
{ | |||||
throw new TaskException( INIT_FAILED_MSG | |||||
+ readerClassName | |||||
+ " implements nor SAX1 Parser nor SAX2 XMLReader." ); | |||||
} | |||||
} | |||||
} | |||||
catch( ClassNotFoundException e ) | |||||
{ | |||||
throw new TaskException( INIT_FAILED_MSG + readerClassName, e ); | |||||
} | |||||
catch( InstantiationException e ) | |||||
{ | |||||
throw new TaskException( INIT_FAILED_MSG + readerClassName, e ); | |||||
} | |||||
catch( IllegalAccessException e ) | |||||
{ | |||||
throw new TaskException( INIT_FAILED_MSG + readerClassName, e ); | |||||
} | |||||
xmlReader.setEntityResolver( getEntityResolver() ); | |||||
xmlReader.setErrorHandler( errorHandler ); | |||||
if( !( xmlReader instanceof ParserAdapter ) ) | |||||
{ | |||||
// turn validation on | |||||
if( !lenient ) | |||||
{ | |||||
boolean ok = setFeature( "http://xml.org/sax/features/validation", true, true ); | |||||
if( !ok ) | |||||
{ | |||||
throw new TaskException( INIT_FAILED_MSG | |||||
+ readerClassName | |||||
+ " doesn't provide validation" ); | |||||
} | |||||
} | |||||
// set other features | |||||
Enumeration enum = features.keys(); | |||||
while( enum.hasMoreElements() ) | |||||
{ | |||||
String featureId = (String)enum.nextElement(); | |||||
setFeature( featureId, ( (Boolean)features.get( featureId ) ).booleanValue(), true ); | |||||
} | |||||
} | |||||
} | |||||
public static class DTDLocation | |||||
{ | |||||
private String publicId = null; | |||||
private String location = null; | |||||
public void setLocation( String location ) | |||||
{ | |||||
this.location = location; | |||||
} | |||||
public void setPublicId( String publicId ) | |||||
{ | |||||
this.publicId = publicId; | |||||
} | |||||
public String getLocation() | |||||
{ | |||||
return location; | |||||
} | |||||
public String getPublicId() | |||||
{ | |||||
return publicId; | |||||
} | |||||
} | |||||
/* | |||||
* ValidatorErrorHandler role : | |||||
* <ul> | |||||
* <li> log SAX parse exceptions, | |||||
* <li> remember if an error occured | |||||
* </ul> | |||||
*/ | |||||
protected class ValidatorErrorHandler implements ErrorHandler | |||||
{ | |||||
protected File currentFile = null; | |||||
protected String lastErrorMessage = null; | |||||
protected boolean failed = false; | |||||
// did an error happen during last parsing ? | |||||
public boolean getFailure() | |||||
{ | |||||
return failed; | |||||
} | |||||
public void error( SAXParseException exception ) | |||||
{ | |||||
failed = true; | |||||
doLog( exception, Project.MSG_ERR ); | |||||
} | |||||
public void fatalError( SAXParseException exception ) | |||||
{ | |||||
failed = true; | |||||
doLog( exception, Project.MSG_ERR ); | |||||
} | |||||
public void init( File file ) | |||||
{ | |||||
currentFile = file; | |||||
failed = false; | |||||
} | |||||
public void warning( SAXParseException exception ) | |||||
{ | |||||
// depending on implementation, XMLReader can yield hips of warning, | |||||
// only output then if user explicitely asked for it | |||||
if( warn ) | |||||
doLog( exception, Project.MSG_WARN ); | |||||
} | |||||
private String getMessage( SAXParseException e ) | |||||
{ | |||||
String sysID = e.getSystemId(); | |||||
if( sysID != null ) | |||||
{ | |||||
try | |||||
{ | |||||
int line = e.getLineNumber(); | |||||
int col = e.getColumnNumber(); | |||||
return new URL( sysID ).getFile() + | |||||
( line == -1 ? "" : ( ":" + line + | |||||
( col == -1 ? "" : ( ":" + col ) ) ) ) + | |||||
": " + e.getMessage(); | |||||
} | |||||
catch( MalformedURLException mfue ) | |||||
{ | |||||
} | |||||
} | |||||
return e.getMessage(); | |||||
} | |||||
private void doLog( SAXParseException e, int logLevel ) | |||||
{ | |||||
log( getMessage( e ), logLevel ); | |||||
} | |||||
} | |||||
private class LocalResolver | |||||
implements EntityResolver | |||||
{ | |||||
private Hashtable fileDTDs = new Hashtable(); | |||||
private Hashtable resourceDTDs = new Hashtable(); | |||||
private Hashtable urlDTDs = new Hashtable(); | |||||
public LocalResolver() | |||||
{ | |||||
} | |||||
public void registerDTD( String publicId, String location ) | |||||
{ | |||||
if( location == null ) | |||||
{ | |||||
return; | |||||
} | |||||
File fileDTD = new File( location ); | |||||
if( fileDTD.exists() ) | |||||
{ | |||||
if( publicId != null ) | |||||
{ | |||||
fileDTDs.put( publicId, fileDTD ); | |||||
log( "Mapped publicId " + publicId + " to file " + fileDTD, Project.MSG_VERBOSE ); | |||||
} | |||||
return; | |||||
} | |||||
if( LocalResolver.this.getClass().getResource( location ) != null ) | |||||
{ | |||||
if( publicId != null ) | |||||
{ | |||||
resourceDTDs.put( publicId, location ); | |||||
log( "Mapped publicId " + publicId + " to resource " + location, Project.MSG_VERBOSE ); | |||||
} | |||||
} | |||||
try | |||||
{ | |||||
if( publicId != null ) | |||||
{ | |||||
URL urldtd = new URL( location ); | |||||
urlDTDs.put( publicId, urldtd ); | |||||
} | |||||
} | |||||
catch( java.net.MalformedURLException e ) | |||||
{ | |||||
//ignored | |||||
} | |||||
} | |||||
public void registerDTD( DTDLocation location ) | |||||
{ | |||||
registerDTD( location.getPublicId(), location.getLocation() ); | |||||
} | |||||
public InputSource resolveEntity( String publicId, String systemId ) | |||||
throws SAXException | |||||
{ | |||||
File dtdFile = (File)fileDTDs.get( publicId ); | |||||
if( dtdFile != null ) | |||||
{ | |||||
try | |||||
{ | |||||
log( "Resolved " + publicId + " to local file " + dtdFile, Project.MSG_VERBOSE ); | |||||
return new InputSource( new FileInputStream( dtdFile ) ); | |||||
} | |||||
catch( FileNotFoundException ex ) | |||||
{ | |||||
// ignore | |||||
} | |||||
} | |||||
String dtdResourceName = (String)resourceDTDs.get( publicId ); | |||||
if( dtdResourceName != null ) | |||||
{ | |||||
InputStream is = this.getClass().getResourceAsStream( dtdResourceName ); | |||||
if( is != null ) | |||||
{ | |||||
log( "Resolved " + publicId + " to local resource " + dtdResourceName, Project.MSG_VERBOSE ); | |||||
return new InputSource( is ); | |||||
} | |||||
} | |||||
URL dtdUrl = (URL)urlDTDs.get( publicId ); | |||||
if( dtdUrl != null ) | |||||
{ | |||||
try | |||||
{ | |||||
InputStream is = dtdUrl.openStream(); | |||||
log( "Resolved " + publicId + " to url " + dtdUrl, Project.MSG_VERBOSE ); | |||||
return new InputSource( is ); | |||||
} | |||||
catch( IOException ioe ) | |||||
{ | |||||
//ignore | |||||
} | |||||
} | |||||
log( "Could not resolve ( publicId: " + publicId + ", systemId: " + systemId + ") to a local entity", | |||||
Project.MSG_INFO ); | |||||
return null; | |||||
} | |||||
} | |||||
} |
@@ -1,114 +0,0 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE file. | |||||
*/ | |||||
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.myrmidon.api.TaskException; | |||||
import org.apache.tools.ant.taskdefs.XSLTLiaison; | |||||
import org.apache.xalan.xslt.XSLTInputSource; | |||||
import org.apache.xalan.xslt.XSLTProcessor; | |||||
import org.apache.xalan.xslt.XSLTProcessorFactory; | |||||
import org.apache.xalan.xslt.XSLTResultTarget; | |||||
/** | |||||
* Concrete liaison for Xalan 1.x API. | |||||
* | |||||
* @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a> | |||||
* @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a> | |||||
*/ | |||||
public class XalanLiaison implements XSLTLiaison | |||||
{ | |||||
protected XSLTProcessor processor; | |||||
protected File stylesheet; | |||||
public XalanLiaison() | |||||
throws Exception | |||||
{ | |||||
processor = XSLTProcessorFactory.getProcessor(); | |||||
} | |||||
public void setOutputtype( String type ) | |||||
throws Exception | |||||
{ | |||||
if( !type.equals( "xml" ) ) | |||||
throw new TaskException( "Unsupported output type: " + type ); | |||||
} | |||||
public void setStylesheet( File stylesheet ) | |||||
throws Exception | |||||
{ | |||||
this.stylesheet = stylesheet; | |||||
} | |||||
public void addParam( String name, String value ) | |||||
{ | |||||
processor.setStylesheetParam( name, value ); | |||||
} | |||||
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 ) | |||||
{ | |||||
} | |||||
} | |||||
} | |||||
}//-- XalanLiaison |