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

XMLValidate

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 @@ - + 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
classnamethe parser to use. (default: crimson).the parser to use. No