Browse Source

Make <xmlvalidate> use JAXP when the user didn't provide a classname.

This should make the tests work no matter which XML parser you used
(failed for me now as I still have Crimson on my CLASSPATH).


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272540 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 23 years ago
parent
commit
6de0aa0431
2 changed files with 82 additions and 44 deletions
  1. +6
    -4
      docs/manual/OptionalTasks/xmlvalidate.html
  2. +76
    -40
      src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java

+ 6
- 4
docs/manual/OptionalTasks/xmlvalidate.html View File

@@ -8,9 +8,11 @@


<h2><a name="xmlvalidate">XMLValidate</a></h2> <h2><a name="xmlvalidate">XMLValidate</a></h2>
<h3>Description</h3> <h3>Description</h3>
<p>
This task checks xml files are valid (or only well formed). The task uses crimson SAX2 parser implementation by default, but one can specify any SAX1/2 parser if needed
</p>

<p>This task checks xml files are valid (or only well formed). The
task uses the SAX2 parser implementation provided by JAXP by default
(probably the one that is used by Ant itself), but one can specify any
SAX1/2 parser if needed.</p>


<h3>Parameters</h3> <h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0"> <table border="1" cellpadding="2" cellspacing="0">
@@ -34,7 +36,7 @@
</tr> </tr>
<tr> <tr>
<td valign="top">classname</td> <td valign="top">classname</td>
<td valign="top">the parser to use. (default: crimson).</td>
<td valign="top">the parser to use.</td>
<td align="center" valign="top">No</td> <td align="center" valign="top">No</td>
</tr> </tr>
<tr> <tr>


+ 76
- 40
src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java View File

@@ -64,6 +64,10 @@ import java.net.URL;
import java.util.Vector; import java.util.Vector;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Enumeration; import java.util.Enumeration;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.FactoryConfigurationError;
import org.apache.tools.ant.AntClassLoader; import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.DirectoryScanner;
@@ -93,21 +97,20 @@ import org.xml.sax.helpers.ParserAdapter;
public class XMLValidateTask extends Task { public class XMLValidateTask extends Task {


/** /**
* The default implementation parser classname used by the task to process
* validation.
* Parser factory to use to create parsers.
* @see #getParserFactory
*/ */
// The Xerces implementation ships with Ant.
public static String DEFAULT_XML_READER_CLASSNAME
= "org.apache.xerces.parsers.SAXParser";
private static SAXParserFactory parserFactory = null;


protected static String INIT_FAILED_MSG = "Could not start xml validation: ";
protected static String INIT_FAILED_MSG =
"Could not start xml validation: ";


// ant task properties // ant task properties
// defaults // defaults
protected boolean failOnError = true; protected boolean failOnError = true;
protected boolean warn = true; protected boolean warn = true;
protected boolean lenient = false; protected boolean lenient = false;
protected String readerClassName = DEFAULT_XML_READER_CLASSNAME;
protected String readerClassName = null;


protected File file = null; // file to be validated protected File file = null; // file to be validated
protected Vector filesets = new Vector(); // sets of file to be validated protected Vector filesets = new Vector(); // sets of file to be validated
@@ -289,44 +292,62 @@ public class XMLValidateTask extends Task {
*/ */
private void initValidator() { private void initValidator() {


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);
Object reader = null;
if (readerClassName == null) {
// use JAXP
try {
SAXParser saxParser = getParserFactory().newSAXParser();
try {
reader = saxParser.getXMLReader();
} catch (SAXException exc) {
reader = saxParser.getParser();
}
} catch (ParserConfigurationException e) {
throw new BuildException(INIT_FAILED_MSG + e.getMessage(),
e, getLocation());
} catch (SAXException e) {
throw new BuildException(INIT_FAILED_MSG + e.getMessage(),
e, getLocation());
} }
} else {
Class readerClass = null;
try {
// load the parser class
if (classpath != null) {
AntClassLoader loader = new AntClassLoader(project, classpath);
readerClass = loader.loadClass(readerClassName);
AntClassLoader.initializeClass(readerClass);
} else {
readerClass = Class.forName(readerClassName);
}


// then check it implements XMLReader
if (XMLReader.class.isAssignableFrom(readerClass)) {
reader = readerClass.newInstance();
} catch (ClassNotFoundException e) {
throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
} catch (InstantiationException e) {
throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
} catch (IllegalAccessException e) {
throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
}
}


xmlReader = (XMLReader) readerClass.newInstance();
log("Using SAX2 reader " + readerClassName, Project.MSG_VERBOSE);
} else {
// then check it implements XMLReader
if (reader instanceof XMLReader) {
xmlReader = (XMLReader) reader;
log("Using SAX2 reader " + reader.getClass().getName(),
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 BuildException(INIT_FAILED_MSG + readerClassName
+ " implements nor SAX1 Parser nor SAX2 XMLReader.");
}
// see if it is a SAX1 Parser
if (reader instanceof Parser) {
xmlReader = new ParserAdapter((Parser) reader);
log("Using SAX1 parser " + reader.getClass().getName(),
Project.MSG_VERBOSE);
} else {
throw new BuildException(INIT_FAILED_MSG + readerClassName
+ " implements nor SAX1 Parser nor SAX2 XMLReader.");
} }
} catch (ClassNotFoundException e) {
throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
} catch (InstantiationException e) {
throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
} catch (IllegalAccessException e) {
throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
} }


xmlReader.setEntityResolver(getEntityResolver()); xmlReader.setEntityResolver(getEntityResolver());
@@ -351,6 +372,21 @@ public class XMLValidateTask extends Task {
} }
} }


/**
* Returns the parser factory to use. Only one parser
* factory is ever created by this method (multi-threading
* issues aside) and is then cached for future use.
*
* @return a SAXParserFactory to use within this class
*/
private static SAXParserFactory getParserFactory() {
if (parserFactory == null) {
parserFactory = SAXParserFactory.newInstance();
}

return parserFactory;
}

/* /*
* set a feature on the parser. * set a feature on the parser.
* TODO: find a way to set any feature from build.xml * TODO: find a way to set any feature from build.xml


Loading…
Cancel
Save