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 | |||||