git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@270739 13f79535-47bb-0310-9956-ffa450edef68master
@@ -0,0 +1,131 @@ | |||
/* | |||
* 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 java.io.File; | |||
import java.io.FileInputStream; | |||
import java.io.FileNotFoundException; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.net.MalformedURLException; | |||
import java.net.URL; | |||
import java.util.Hashtable; | |||
import org.apache.avalon.framework.logger.AbstractLogEnabled; | |||
import org.xml.sax.EntityResolver; | |||
import org.xml.sax.InputSource; | |||
import org.xml.sax.SAXException; | |||
class LocalResolver | |||
extends AbstractLogEnabled | |||
implements EntityResolver | |||
{ | |||
private Hashtable m_fileDTDs = new Hashtable(); | |||
private Hashtable m_resourceDTDs = new Hashtable(); | |||
private Hashtable m_urlDTDs = new Hashtable(); | |||
public void registerDTD( String publicId, String location ) | |||
{ | |||
if( location == null ) | |||
{ | |||
return; | |||
} | |||
File fileDTD = new File( location ); | |||
if( fileDTD.exists() ) | |||
{ | |||
if( publicId != null ) | |||
{ | |||
m_fileDTDs.put( publicId, fileDTD ); | |||
final String message = "Mapped publicId " + publicId + " to file " + fileDTD; | |||
getLogger().debug( message ); | |||
} | |||
return; | |||
} | |||
if( LocalResolver.this.getClass().getResource( location ) != null ) | |||
{ | |||
if( publicId != null ) | |||
{ | |||
m_resourceDTDs.put( publicId, location ); | |||
final String message = "Mapped publicId " + publicId + | |||
" to resource " + location; | |||
getLogger().debug( message ); | |||
} | |||
} | |||
try | |||
{ | |||
if( publicId != null ) | |||
{ | |||
URL urldtd = new URL( location ); | |||
m_urlDTDs.put( publicId, urldtd ); | |||
} | |||
} | |||
catch( 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)m_fileDTDs.get( publicId ); | |||
if( dtdFile != null ) | |||
{ | |||
try | |||
{ | |||
final String message = "Resolved " + publicId + " to local file " + dtdFile; | |||
getLogger().debug( message ); | |||
return new InputSource( new FileInputStream( dtdFile ) ); | |||
} | |||
catch( FileNotFoundException ex ) | |||
{ | |||
// ignore | |||
} | |||
} | |||
String dtdResourceName = (String)m_resourceDTDs.get( publicId ); | |||
if( dtdResourceName != null ) | |||
{ | |||
InputStream is = getClass().getResourceAsStream( dtdResourceName ); | |||
if( is != null ) | |||
{ | |||
getLogger().debug( "Resolved " + publicId + " to local resource " + dtdResourceName ); | |||
return new InputSource( is ); | |||
} | |||
} | |||
URL dtdUrl = (URL)m_urlDTDs.get( publicId ); | |||
if( dtdUrl != null ) | |||
{ | |||
try | |||
{ | |||
InputStream is = dtdUrl.openStream(); | |||
final String message = "Resolved " + publicId + " to url " + dtdUrl; | |||
getLogger().debug( message ); | |||
return new InputSource( is ); | |||
} | |||
catch( IOException ioe ) | |||
{ | |||
//ignore | |||
} | |||
} | |||
final String message = "Could not resolve ( publicId: " + publicId + | |||
", systemId: " + systemId + ") to a local entity"; | |||
getLogger().info( message ); | |||
return null; | |||
} | |||
} |
@@ -208,5 +208,4 @@ public class TraXLiaison | |||
getLogger().info( msg.toString() ); | |||
} | |||
}//-- TraXLiaison | |||
} |
@@ -0,0 +1,92 @@ | |||
/* | |||
* 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 java.io.File; | |||
import java.net.MalformedURLException; | |||
import java.net.URL; | |||
import org.apache.avalon.framework.logger.AbstractLogEnabled; | |||
import org.xml.sax.ErrorHandler; | |||
import org.xml.sax.SAXParseException; | |||
/* | |||
* ValidatorErrorHandler role : | |||
* <ul> | |||
* <li> log SAX parse exceptions, | |||
* <li> remember if an error occured | |||
* </ul> | |||
*/ | |||
final class ValidatorErrorHandler | |||
extends AbstractLogEnabled | |||
implements ErrorHandler | |||
{ | |||
private File m_file; | |||
private String m_lastErrorMessage; | |||
private boolean m_failed; | |||
private final boolean m_warn; | |||
protected ValidatorErrorHandler( final boolean warn ) | |||
{ | |||
m_warn = warn; | |||
} | |||
public void error( final SAXParseException spe ) | |||
{ | |||
m_failed = true; | |||
getLogger().error( getMessage( spe ), spe ); | |||
} | |||
public void fatalError( final SAXParseException spe ) | |||
{ | |||
m_failed = true; | |||
getLogger().error( getMessage( spe ), spe ); | |||
} | |||
public void warning( final SAXParseException spe ) | |||
{ | |||
// depending on implementation, XMLReader can yield hips of warning, | |||
// only output then if user explicitely asked for it | |||
if( m_warn ) | |||
{ | |||
getLogger().warn( getMessage( spe ), spe ); | |||
} | |||
} | |||
protected void init( final File file ) | |||
{ | |||
m_file = file; | |||
m_failed = false; | |||
} | |||
// did an error happen during last parsing ? | |||
protected boolean getFailure() | |||
{ | |||
return m_failed; | |||
} | |||
private String getMessage( final SAXParseException spe ) | |||
{ | |||
final String sysID = spe.getSystemId(); | |||
if( sysID != null ) | |||
{ | |||
try | |||
{ | |||
final int line = spe.getLineNumber(); | |||
final int col = spe.getColumnNumber(); | |||
return new URL( sysID ).getFile() + | |||
( line == -1 ? "" : ( ":" + line + | |||
( col == -1 ? "" : ( ":" + col ) ) ) ) + | |||
": " + spe.getMessage(); | |||
} | |||
catch( MalformedURLException mfue ) | |||
{ | |||
} | |||
} | |||
return spe.getMessage(); | |||
} | |||
} |
@@ -59,7 +59,6 @@ public class XMLValidateTask | |||
private boolean m_warn = true; | |||
private boolean m_lenient; | |||
private String m_readerClassName = DEFAULT_XML_READER_CLASSNAME; | |||
private File m_file;// file to be validated | |||
private ArrayList m_filesets = new ArrayList(); | |||
@@ -74,7 +73,7 @@ public class XMLValidateTask | |||
/** | |||
* to report sax parsing errors | |||
*/ | |||
private ValidatorErrorHandler m_errorHandler = new ValidatorErrorHandler(); | |||
private ValidatorErrorHandler m_errorHandler; | |||
private Hashtable m_features = new Hashtable(); | |||
/** | |||
@@ -234,9 +233,10 @@ public class XMLValidateTask | |||
getLogger().info( message ); | |||
} | |||
private EntityResolver getEntityResolver() | |||
private EntityResolver buildEntityResolver() | |||
{ | |||
final LocalResolver resolver = new LocalResolver(); | |||
setupLogger( resolver ); | |||
for( int i = 0; i < m_dtdLocations.size(); i++ ) | |||
{ | |||
@@ -377,7 +377,10 @@ public class XMLValidateTask | |||
throw new TaskException( INIT_FAILED_MSG + m_readerClassName, e ); | |||
} | |||
m_xmlReader.setEntityResolver( getEntityResolver() ); | |||
m_xmlReader.setEntityResolver( buildEntityResolver() ); | |||
m_errorHandler = new ValidatorErrorHandler( m_warn ); | |||
setupLogger( m_errorHandler ); | |||
m_xmlReader.setErrorHandler( m_errorHandler ); | |||
if( !( m_xmlReader instanceof ParserAdapter ) ) | |||
@@ -403,175 +406,4 @@ public class XMLValidateTask | |||
} | |||
} | |||
/* | |||
* ValidatorErrorHandler role : | |||
* <ul> | |||
* <li> log SAX parse exceptions, | |||
* <li> remember if an error occured | |||
* </ul> | |||
*/ | |||
private class ValidatorErrorHandler | |||
implements ErrorHandler | |||
{ | |||
private File currentFile; | |||
private String lastErrorMessage; | |||
private boolean failed; | |||
// did an error happen during last parsing ? | |||
public boolean getFailure() | |||
{ | |||
return failed; | |||
} | |||
public void error( SAXParseException exception ) | |||
{ | |||
failed = true; | |||
getLogger().error( getMessage( exception ), exception ); | |||
} | |||
public void fatalError( SAXParseException exception ) | |||
{ | |||
failed = true; | |||
getLogger().error( getMessage( exception ), exception ); | |||
} | |||
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( m_warn ) | |||
{ | |||
getLogger().warn( getMessage( exception ), exception ); | |||
} | |||
} | |||
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 class LocalResolver | |||
implements EntityResolver | |||
{ | |||
private Hashtable fileDTDs = new Hashtable(); | |||
private Hashtable resourceDTDs = new Hashtable(); | |||
private Hashtable urlDTDs = new Hashtable(); | |||
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 ); | |||
getLogger().debug( "Mapped publicId " + publicId + " to file " + fileDTD ); | |||
} | |||
return; | |||
} | |||
if( LocalResolver.this.getClass().getResource( location ) != null ) | |||
{ | |||
if( publicId != null ) | |||
{ | |||
resourceDTDs.put( publicId, location ); | |||
getLogger().debug( "Mapped publicId " + publicId + " to resource " + location ); | |||
} | |||
} | |||
try | |||
{ | |||
if( publicId != null ) | |||
{ | |||
URL urldtd = new URL( location ); | |||
urlDTDs.put( publicId, urldtd ); | |||
} | |||
} | |||
catch( 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 | |||
{ | |||
getLogger().debug( "Resolved " + publicId + " to local file " + dtdFile ); | |||
return new InputSource( new FileInputStream( dtdFile ) ); | |||
} | |||
catch( FileNotFoundException ex ) | |||
{ | |||
// ignore | |||
} | |||
} | |||
String dtdResourceName = (String)resourceDTDs.get( publicId ); | |||
if( dtdResourceName != null ) | |||
{ | |||
InputStream is = getClass().getResourceAsStream( dtdResourceName ); | |||
if( is != null ) | |||
{ | |||
getLogger().debug( "Resolved " + publicId + " to local resource " + dtdResourceName ); | |||
return new InputSource( is ); | |||
} | |||
} | |||
URL dtdUrl = (URL)urlDTDs.get( publicId ); | |||
if( dtdUrl != null ) | |||
{ | |||
try | |||
{ | |||
InputStream is = dtdUrl.openStream(); | |||
getLogger().debug( "Resolved " + publicId + " to url " + dtdUrl ); | |||
return new InputSource( is ); | |||
} | |||
catch( IOException ioe ) | |||
{ | |||
//ignore | |||
} | |||
} | |||
getLogger().info( "Could not resolve ( publicId: " + publicId + ", systemId: " + systemId + ") to a local entity" ); | |||
return null; | |||
} | |||
} | |||
} |
@@ -9,7 +9,7 @@ package org.apache.antlib.xml; | |||
import org.apache.myrmidon.api.TaskException; | |||
public class XSLTParam | |||
public final class XSLTParam | |||
{ | |||
private String m_name; | |||
private String m_expression; | |||
@@ -24,23 +24,13 @@ public class XSLTParam | |||
m_name = name; | |||
} | |||
public String getExpression() | |||
throws TaskException | |||
protected String getExpression() | |||
{ | |||
if( m_expression == null ) | |||
{ | |||
throw new TaskException( "Expression attribute is missing." ); | |||
} | |||
return m_expression; | |||
} | |||
public String getName() | |||
throws TaskException | |||
protected String getName() | |||
{ | |||
if( m_name == null ) | |||
{ | |||
throw new TaskException( "Name attribute is missing." ); | |||
} | |||
return m_name; | |||
} | |||
} |
@@ -324,13 +324,26 @@ public class XSLTProcess | |||
while( params.hasNext() ) | |||
{ | |||
final XSLTParam param = (XSLTParam)params.next(); | |||
m_liaison.addParam( param.getName(), param.getExpression() ); | |||
final String expression = param.getExpression(); | |||
if( expression == null ) | |||
{ | |||
throw new TaskException( "Expression attribute is missing." ); | |||
} | |||
final String name = param.getName(); | |||
if( name == null ) | |||
{ | |||
throw new TaskException( "Name attribute is missing." ); | |||
} | |||
m_liaison.addParam( name, expression ); | |||
} | |||
} | |||
catch( final Exception e ) | |||
{ | |||
getLogger().info( "Failed to read stylesheet " + stylesheet ); | |||
throw new TaskException( "Error", e ); | |||
throw new TaskException( e.getMessage(), e ); | |||
} | |||
} | |||
@@ -342,8 +355,8 @@ public class XSLTProcess | |||
{ | |||
if( !directory.mkdirs() ) | |||
{ | |||
throw new TaskException( "Unable to create directory: " | |||
+ directory.getAbsolutePath() ); | |||
throw new TaskException( "Unable to create directory: " + | |||
directory.getAbsolutePath() ); | |||
} | |||
} | |||
} | |||