diff --git a/docs/manual/OptionalTasks/xmlvalidate.html b/docs/manual/OptionalTasks/xmlvalidate.html
index 8b8052a36..099f209fd 100644
--- a/docs/manual/OptionalTasks/xmlvalidate.html
+++ b/docs/manual/OptionalTasks/xmlvalidate.html
@@ -8,9 +8,11 @@
Description
-
- 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
-
+
+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.
Parameters
@@ -34,7 +36,7 @@
classname |
- the parser to use. (default: crimson). |
+ the parser to use. |
No |
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java
index 08b44c423..22cd3dcdb 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java
@@ -64,6 +64,10 @@ import java.net.URL;
import java.util.Vector;
import java.util.Hashtable;
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.BuildException;
import org.apache.tools.ant.DirectoryScanner;
@@ -93,21 +97,20 @@ import org.xml.sax.helpers.ParserAdapter;
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
// defaults
protected boolean failOnError = true;
protected boolean warn = true;
protected boolean lenient = false;
- protected String readerClassName = DEFAULT_XML_READER_CLASSNAME;
+ protected String readerClassName = null;
protected File file = null; // 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() {
- 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());
@@ -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.
* TODO: find a way to set any feature from build.xml