Reorganize the SAX event pipeline, this fixes the problem of slow parsing when the namespace is not correct
git-svn-id: https://svn.apache.org/repos/asf/maven/maven-1/plugins/trunk@350057 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
cbd121a8be
commit
8158ed0a6a
@ -66,6 +66,7 @@ public class JaxpMsvBean
|
|||||||
private static final int MSV_FATAL_ERROR = 2;
|
private static final int MSV_FATAL_ERROR = 2;
|
||||||
|
|
||||||
private boolean isValid = true;
|
private boolean isValid = true;
|
||||||
|
private boolean validNamespace = true;
|
||||||
private XPathLocationTracker tracker;
|
private XPathLocationTracker tracker;
|
||||||
|
|
||||||
//~ Methods --------------------------------------------------------------
|
//~ Methods --------------------------------------------------------------
|
||||||
@ -82,18 +83,20 @@ public class JaxpMsvBean
|
|||||||
verifier.setErrorHandler( new ErrorHandlerImpl() );
|
verifier.setErrorHandler( new ErrorHandlerImpl() );
|
||||||
|
|
||||||
VerifierHandler handler = verifier.getVerifierHandler();
|
VerifierHandler handler = verifier.getVerifierHandler();
|
||||||
tracker = new XPathLocationTracker( handler );
|
|
||||||
|
|
||||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||||
factory.setNamespaceAware( true );
|
factory.setNamespaceAware( true );
|
||||||
factory.setValidating( false );
|
factory.setValidating( false );
|
||||||
|
|
||||||
|
|
||||||
XMLReader reader = factory.newSAXParser().getXMLReader();
|
XMLReader reader = factory.newSAXParser().getXMLReader();
|
||||||
reader.setContentHandler( tracker );
|
|
||||||
reader.setEntityResolver( new EntityResolverImpl() );
|
|
||||||
|
|
||||||
reader.parse( new InputSource( new FileInputStream( file ) ) );
|
tracker = new XPathLocationTracker();
|
||||||
|
tracker.setParent( reader );
|
||||||
|
tracker.setContentHandler( handler );
|
||||||
|
tracker.setEntityResolver( new EntityResolverImpl() );
|
||||||
|
|
||||||
|
tracker.parse( new InputSource( new FileInputStream( file ) ) );
|
||||||
|
|
||||||
endMessage();
|
endMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +104,7 @@ public class JaxpMsvBean
|
|||||||
* Sets the schema.
|
* Sets the schema.
|
||||||
* @param newSchema The schema to set
|
* @param newSchema The schema to set
|
||||||
*/
|
*/
|
||||||
public void setSchema(String newSchema)
|
public void setSchema( String newSchema )
|
||||||
{
|
{
|
||||||
this.schema = newSchema;
|
this.schema = newSchema;
|
||||||
}
|
}
|
||||||
@ -110,7 +113,7 @@ public class JaxpMsvBean
|
|||||||
* Sets the file.
|
* Sets the file.
|
||||||
* @param newFile The file to set
|
* @param newFile The file to set
|
||||||
*/
|
*/
|
||||||
public void setFile(String newFile)
|
public void setFile( String newFile )
|
||||||
{
|
{
|
||||||
this.file = newFile;
|
this.file = newFile;
|
||||||
}
|
}
|
||||||
@ -138,33 +141,36 @@ public class JaxpMsvBean
|
|||||||
if ( isValid )
|
if ( isValid )
|
||||||
{
|
{
|
||||||
log.info( file + " verified: OK" );
|
log.info( file + " verified: OK" );
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
log.info( file + " is NOT valid!" );
|
log.info( file + " is NOT valid!" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setValid(boolean valid)
|
private void errorMessage( SAXParseException e, int type )
|
||||||
{
|
|
||||||
this.isValid = valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void errorMessage(SAXParseException e, int type)
|
|
||||||
{
|
{
|
||||||
File xmlFile = new File( file );
|
File xmlFile = new File( file );
|
||||||
|
|
||||||
if ( type == MSV_ERROR )
|
if ( type == MSV_ERROR )
|
||||||
{
|
{
|
||||||
log.error( " ERROR on line " + e.getLineNumber()
|
// if namespace is not correct, error messages are crap
|
||||||
+ " of file " + xmlFile.getName() + "," );
|
if ( validNamespace )
|
||||||
log.error( " XPath location " + tracker.getXPath() + ":" );
|
{
|
||||||
log.error( " " + e.getMessage() );
|
log.error( " ERROR on line " + e.getLineNumber()
|
||||||
} else if ( type == MSV_FATAL_ERROR )
|
+ " of file " + xmlFile.getName() + "," );
|
||||||
|
log.error( " XPath location " + tracker.getXPath() + ":" );
|
||||||
|
log.error( " " + e.getMessage() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( type == MSV_FATAL_ERROR )
|
||||||
{
|
{
|
||||||
log.error( " Non-recoverable parsing error on line "
|
log.error( " Non-recoverable parsing error on line "
|
||||||
+ e.getLineNumber() + " of file " + xmlFile.getName() + "," );
|
+ e.getLineNumber() + " of file " + xmlFile.getName() + "," );
|
||||||
log.error( " XPath location " + tracker.getXPath() + ":" );
|
log.error( " XPath location " + tracker.getXPath() + ":" );
|
||||||
log.error( " " + e.getMessage() );
|
log.error( " " + e.getMessage() );
|
||||||
} else if ( type == MSV_WARNING )
|
}
|
||||||
|
else if ( type == MSV_WARNING )
|
||||||
{
|
{
|
||||||
log.warn( " WARNING on line " + e.getLineNumber()
|
log.warn( " WARNING on line " + e.getLineNumber()
|
||||||
+ " of file " + xmlFile.getName() + "," );
|
+ " of file " + xmlFile.getName() + "," );
|
||||||
@ -175,45 +181,36 @@ public class JaxpMsvBean
|
|||||||
|
|
||||||
private class ErrorHandlerImpl implements ErrorHandler
|
private class ErrorHandlerImpl implements ErrorHandler
|
||||||
{
|
{
|
||||||
public void warning(SAXParseException e) throws SAXException
|
public void warning( SAXParseException e ) throws SAXException
|
||||||
{
|
{
|
||||||
errorMessage( e, MSV_WARNING );
|
errorMessage( e, MSV_WARNING );
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void error(SAXParseException e) throws SAXException
|
public void error( SAXParseException e ) throws SAXException
|
||||||
{
|
{
|
||||||
/*if (e.getMessage() != null && e.getMessage().indexOf("xsi:schemaLocation") > -1)
|
errorMessage( e, MSV_ERROR);
|
||||||
{
|
isValid = false;
|
||||||
// unexpected attribute "xsi:schemaLocation"
|
|
||||||
// ignore, this is due to a valid xsd declaration
|
|
||||||
// Jaxp ignores additionals namespaces declared in the xml file (xmlns:xsi) and it can't validate
|
|
||||||
// using multiple schema at once
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
errorMessage( e, MSV_ERROR) ;
|
|
||||||
setValid( false );
|
|
||||||
|
|
||||||
if ( e.getMessage() != null
|
if ( e.getMessage() != null
|
||||||
&& e.getMessage().startsWith("namespace URI of tag") )
|
&& e.getMessage().startsWith("namespace URI of tag") )
|
||||||
{
|
{
|
||||||
// Fail the build if namespace declaration is wrong.
|
validNamespace = false;
|
||||||
// Otherwise parsing seems to hang after the first element.
|
|
||||||
throw new SAXException( e );
|
|
||||||
}
|
}
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fatalError(SAXParseException e) throws SAXException
|
public void fatalError( SAXParseException e ) throws SAXException
|
||||||
{
|
{
|
||||||
errorMessage( e, MSV_FATAL_ERROR );
|
errorMessage( e, MSV_FATAL_ERROR );
|
||||||
setValid( false );
|
isValid = false;
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class EntityResolverImpl implements EntityResolver
|
private class EntityResolverImpl implements EntityResolver
|
||||||
{
|
{
|
||||||
public InputSource resolveEntity(String publicId,
|
public InputSource resolveEntity( String publicId,
|
||||||
String systemId) throws SAXException
|
String systemId ) throws SAXException
|
||||||
{
|
{
|
||||||
log.warn( " WARNING: External entity " + systemId
|
log.warn( " WARNING: External entity " + systemId
|
||||||
+ " won't be resolved" );
|
+ " won't be resolved" );
|
||||||
|
|||||||
@ -21,8 +21,8 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.xml.sax.Attributes;
|
import org.xml.sax.Attributes;
|
||||||
import org.xml.sax.ContentHandler;
|
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.SAXParseException;
|
||||||
import org.xml.sax.helpers.XMLFilterImpl;
|
import org.xml.sax.helpers.XMLFilterImpl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,36 +31,26 @@ import org.xml.sax.helpers.XMLFilterImpl;
|
|||||||
*
|
*
|
||||||
* @author <a href="mailto:ltheussl@apache.org">Lukas Theussl</a>
|
* @author <a href="mailto:ltheussl@apache.org">Lukas Theussl</a>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class XPathLocationTracker extends XMLFilterImpl
|
public class XPathLocationTracker extends XMLFilterImpl
|
||||||
{
|
{
|
||||||
|
|
||||||
private State state;
|
private State state;
|
||||||
private static final Integer[] ints = new Integer[]
|
private static final Integer[] ints = new Integer[]
|
||||||
{
|
{
|
||||||
new Integer(0),
|
new Integer( 0 ),
|
||||||
new Integer(1),
|
new Integer( 1 ),
|
||||||
new Integer(2),
|
new Integer( 2 ),
|
||||||
new Integer(3),
|
new Integer( 3 ),
|
||||||
new Integer(4)
|
new Integer( 4 )
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor: sets the ContentHandler.
|
|
||||||
* @param handler The ContentHandler
|
|
||||||
*/
|
|
||||||
public XPathLocationTracker( ContentHandler handler )
|
|
||||||
{
|
|
||||||
setContentHandler(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overriding ContentHandler.
|
* Overriding ContentHandler.
|
||||||
* @throws SAXException SAXException
|
* @throws SAXException SAXException
|
||||||
*/
|
*/
|
||||||
public void startDocument() throws SAXException
|
public void startDocument() throws SAXException
|
||||||
{
|
{
|
||||||
state = new State(null);
|
state = new State( null );
|
||||||
super.startDocument();
|
super.startDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,11 +72,19 @@ public class XPathLocationTracker extends XMLFilterImpl
|
|||||||
* @param atts atts
|
* @param atts atts
|
||||||
* @throws SAXException SAXException
|
* @throws SAXException SAXException
|
||||||
*/
|
*/
|
||||||
public void startElement(String uri, String localName,
|
public void startElement( String uri, String localName,
|
||||||
String qName, Attributes atts) throws SAXException
|
String qName, Attributes atts ) throws SAXException
|
||||||
{
|
{
|
||||||
state = state.push(qName);
|
state = state.push( qName );
|
||||||
super.startElement(uri, localName, qName, atts);
|
try
|
||||||
|
{
|
||||||
|
super.startElement( uri, localName, qName, atts );
|
||||||
|
}
|
||||||
|
catch ( SAXParseException e )
|
||||||
|
{
|
||||||
|
// ignored on purpose: just avoid to throw an exception here
|
||||||
|
// it is thrown by the ErrorHandler in JaxpMsvBean instead
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -96,10 +94,18 @@ public class XPathLocationTracker extends XMLFilterImpl
|
|||||||
* @param qName qName
|
* @param qName qName
|
||||||
* @throws SAXException SAXException
|
* @throws SAXException SAXException
|
||||||
*/
|
*/
|
||||||
public void endElement(String uri, String localName, String qName)
|
public void endElement( String uri, String localName, String qName )
|
||||||
throws SAXException
|
throws SAXException
|
||||||
{
|
{
|
||||||
super.endElement(uri, localName, qName);
|
try
|
||||||
|
{
|
||||||
|
super.endElement( uri, localName, qName );
|
||||||
|
}
|
||||||
|
catch ( SAXParseException e )
|
||||||
|
{
|
||||||
|
// ignored on purpose: just avoid to throw an exception here
|
||||||
|
// it is thrown by the ErrorHandler in JaxpMsvBean instead
|
||||||
|
}
|
||||||
state = state.pop();
|
state = state.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,17 +120,19 @@ public class XPathLocationTracker extends XMLFilterImpl
|
|||||||
if ( state == null )
|
if ( state == null )
|
||||||
{
|
{
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"startDocument event is not invoked");
|
"startDocument event is not invoked" );
|
||||||
}
|
}
|
||||||
return state.getXPath();
|
return state.getXPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Integer getInt(int i)
|
private static Integer getInt( int i )
|
||||||
{
|
{
|
||||||
if ( i < ints.length )
|
if ( i < ints.length )
|
||||||
{
|
{
|
||||||
return ints[i];
|
return ints[i];
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return new Integer(i);
|
return new Integer(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,8 +156,10 @@ public class XPathLocationTracker extends XMLFilterImpl
|
|||||||
currentName = rawName;
|
currentName = rawName;
|
||||||
if ( child == null )
|
if ( child == null )
|
||||||
{
|
{
|
||||||
child = new State(this);
|
child = new State( this );
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
child.reset();
|
child.reset();
|
||||||
}
|
}
|
||||||
return child;
|
return child;
|
||||||
@ -163,14 +173,16 @@ public class XPathLocationTracker extends XMLFilterImpl
|
|||||||
|
|
||||||
private void count( String rawName )
|
private void count( String rawName )
|
||||||
{
|
{
|
||||||
Integer i = (Integer) counter.get(rawName);
|
Integer i = (Integer) counter.get( rawName );
|
||||||
if ( i == null )
|
if ( i == null )
|
||||||
{
|
{
|
||||||
i = getInt(1);
|
i = getInt( 1 );
|
||||||
} else {
|
|
||||||
i = getInt(i.intValue() + 1);
|
|
||||||
}
|
}
|
||||||
counter.put(rawName, i);
|
else
|
||||||
|
{
|
||||||
|
i = getInt( i.intValue() + 1 );
|
||||||
|
}
|
||||||
|
counter.put( rawName, i );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reset()
|
private void reset()
|
||||||
@ -185,16 +197,18 @@ public class XPathLocationTracker extends XMLFilterImpl
|
|||||||
if ( parent == null ) // root
|
if ( parent == null ) // root
|
||||||
{
|
{
|
||||||
xPath = "/";
|
xPath = "/";
|
||||||
if ( currentName != null)
|
if ( currentName != null )
|
||||||
{
|
{
|
||||||
xPath += currentName;
|
xPath += currentName;
|
||||||
}
|
}
|
||||||
} else { // child node
|
}
|
||||||
|
else // child node
|
||||||
|
{
|
||||||
xPath = parent.getXPath();
|
xPath = parent.getXPath();
|
||||||
if ( currentName != null )
|
if ( currentName != null )
|
||||||
{
|
{
|
||||||
xPath += '/' + currentName;
|
xPath += '/' + currentName;
|
||||||
Integer i = (Integer) counter.get(currentName);
|
Integer i = (Integer) counter.get( currentName );
|
||||||
xPath += '[' + i.toString() + ']';
|
xPath += '[' + i.toString() + ']';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user