From d8361ec47ac005b959a6a22b17fecf77d540e890 Mon Sep 17 00:00:00 2001 From: Antoine Levy-Lambert Date: Wed, 2 Jun 2004 20:32:11 +0000 Subject: [PATCH] Addition of a nested property element to the XMLValidateTask to support string parser properties PR: 23395 Submitted by: Matthew Hawthorne (mhawthorne at alumni dot pitt dot edu) git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@276506 13f79535-47bb-0310-9956-ffa450edef68 --- CONTRIBUTORS | 6 +- WHATSNEW | 3 + .../xml/endpiece-noSchema-invalid.xml | 14 ++ .../optional/xml/endpiece-noSchema.xml | 12 + .../taskdefs/optional/xmlvalidate.xml | 47 ++++ .../taskdefs/optional/XMLValidateTask.java | 237 ++++++++++++++---- .../taskdefs/optional/XmlValidateTest.java | 60 +++-- 7 files changed, 305 insertions(+), 74 deletions(-) create mode 100644 src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema-invalid.xml create mode 100644 src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema.xml diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 8022e4720..1088a88ff 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -9,7 +9,7 @@ Antoine Levy-Lambert Anton Mazkovoi Arnaud Vandyck Arnout J. Kuiper -Aslak Hellesøy +Aslak Helles?y Avik Sengupta Balazs Fejes 2 Benoit Moussaud @@ -17,7 +17,6 @@ Brad Clark Brian Deitte Brian Felder Bruce Atherton -chanezon Charles Hudak Charlie Hubbard Chris Povirk @@ -72,7 +71,7 @@ Ingmar Stein Irene Rusman Jack J. Woehr James Duncan Davidson -Jan Matèrne +Jan Mat?rne Jason Hunter Jason Pettiss Jason Salter @@ -122,6 +121,7 @@ Matt Bishop Matt Foemmel Matt Humphrey Matt Small +Matthew Hawthorne Matthew Inger Matthew Kuperus Heun Matthew Watson diff --git a/WHATSNEW b/WHATSNEW index 444cedc53..872c2c75e 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -128,6 +128,9 @@ Fixed bugs: Other changes: -------------- +* has now a property nested element, + allowing to set string properties for the parser + Bugzilla Report 23395. * Docs fixes for xmlvalidate.html, javadoc.html, starteam. Bugzilla Reports 27092, 27284, 27554. diff --git a/src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema-invalid.xml b/src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema-invalid.xml new file mode 100644 index 000000000..bb49c8219 --- /dev/null +++ b/src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema-invalid.xml @@ -0,0 +1,14 @@ + + + + +
+ With a little luck, the network will pick me up. + This is Ripley - last survivor of The Nostromo - signing off. +
+ + + +
diff --git a/src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema.xml b/src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema.xml new file mode 100644 index 000000000..a4944ea72 --- /dev/null +++ b/src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema.xml @@ -0,0 +1,12 @@ + + + + +
+ With a little luck, the network will pick me up. + This is Ripley - last survivor of The Nostromo - signing off. +
+ +
diff --git a/src/etc/testcases/taskdefs/optional/xmlvalidate.xml b/src/etc/testcases/taskdefs/optional/xmlvalidate.xml index 7dcd5af19..985a20aa3 100644 --- a/src/etc/testcases/taskdefs/optional/xmlvalidate.xml +++ b/src/etc/testcases/taskdefs/optional/xmlvalidate.xml @@ -129,4 +129,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 2ac355893..9c347de01 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java @@ -35,6 +35,7 @@ import org.apache.tools.ant.types.Reference; import org.apache.tools.ant.types.XMLCatalog; import org.apache.tools.ant.util.FileUtils; import org.apache.tools.ant.util.JAXPUtils; + import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; @@ -68,7 +69,7 @@ public class XMLValidateTask extends Task { protected boolean failOnError = true; protected boolean warn = true; protected boolean lenient = false; - protected String readerClassName = null; + protected String readerClassName = null; /** file to be validated */ protected File file = null; @@ -76,20 +77,24 @@ public class XMLValidateTask extends Task { protected Vector filesets = new Vector(); protected Path classpath; - /** * the parser is viewed as a SAX2 XMLReader. If a SAX1 parser is specified, * it's wrapped in an adapter that make it behave as a XMLReader. * a more 'standard' way of doing this would be to use the JAXP1.1 SAXParser * interface. */ - protected XMLReader xmlReader = null; // XMLReader used to validation process - protected ValidatorErrorHandler errorHandler - = new ValidatorErrorHandler(); // to report sax parsing errors + protected XMLReader xmlReader = null; + // XMLReader used to validation process + protected ValidatorErrorHandler errorHandler = new ValidatorErrorHandler(); + // to report sax parsing errors /** The vector to store all attributes (features) to be set on the parser. **/ private Vector attributeList = new Vector(); + /** + * List of properties. + */ + private final Vector propertyList = new Vector(); private XMLCatalog xmlCatalog = new XMLCatalog(); @@ -99,6 +104,7 @@ public class XMLValidateTask extends Task { *

* If set to true (default), throw a buildException if the * parser yields an error. + * @param fail if set to false do not fail on error */ public void setFailOnError(boolean fail) { failOnError = fail; @@ -108,6 +114,7 @@ public class XMLValidateTask extends Task { * Specify how parser error are to be handled. *

* If set to true (default), log a warn message for each SAX warn event. + * @param bool if set to false do not send warnings */ public void setWarn(boolean bool) { warn = bool; @@ -122,6 +129,7 @@ public class XMLValidateTask extends Task { *

* this option is ignored if the specified class * with {@link #setClassName(String)} is not a SAX2 XMLReader. + * @param bool if set to false only fail on malformed XML */ public void setLenient(boolean bool) { lenient = bool; @@ -142,9 +150,9 @@ public class XMLValidateTask extends Task { readerClassName = className; } - /** * Specify the classpath to be searched to load the parser (optional) + * @param classpath the classpath to load the parser */ public void setClasspath(Path classpath) { if (this.classpath == null) { @@ -156,6 +164,7 @@ public class XMLValidateTask extends Task { /** * @see #setClasspath + * @return the classpath created */ public Path createClasspath() { if (this.classpath == null) { @@ -167,6 +176,7 @@ public class XMLValidateTask extends Task { /** * Where to find the parser class; optional. * @see #setClasspath + * @param r reference to a classpath defined elsewhere */ public void setClasspathRef(Reference r) { createClasspath().setRefid(r); @@ -174,6 +184,7 @@ public class XMLValidateTask extends Task { /** * specify the file to be checked; optional. + * @param file the file to be checked */ public void setFile(File file) { this.file = file; @@ -181,6 +192,7 @@ public class XMLValidateTask extends Task { /** * add an XMLCatalog as a nested element; optional. + * @param catalog XMLCatalog to use */ public void addConfiguredXMLCatalog(XMLCatalog catalog) { xmlCatalog.addConfiguredXMLCatalog(catalog); @@ -188,6 +200,7 @@ public class XMLValidateTask extends Task { /** * specify a set of file to be checked + * @param set the fileset to check */ public void addFileset(FileSet set) { filesets.addElement(set); @@ -198,6 +211,7 @@ public class XMLValidateTask extends Task { * features of the SAX parser. * Valid attributes * include + * @return attribute created * @since ant1.6 */ public Attribute createAttribute() { @@ -206,6 +220,23 @@ public class XMLValidateTask extends Task { return feature; } + /** + * Creates a property. + * + * @return a property. + * @since ant 1.6.2 + */ + public Property createProperty() { + final Property prop = new Property(); + propertyList.addElement(prop); + return prop; + } + + /** + * Called by the project to let the task initialize properly. + * + * @exception BuildException if something goes wrong with the build + */ public void init() throws BuildException { super.init(); xmlCatalog.setProject(getProject()); @@ -215,29 +246,36 @@ public class XMLValidateTask extends Task { * Create a DTD location record; optional. * This stores the location of a DTD. The DTD is identified * by its public Id. + * @return created DTD location */ public DTDLocation createDTD() { DTDLocation dtdLocation = new DTDLocation(); xmlCatalog.addDTD(dtdLocation); return dtdLocation; } - + /** + * accessor to the xmlCatalog used in the task + * @return xmlCatalog reference + */ protected EntityResolver getEntityResolver() { return xmlCatalog; } - + /** + * execute the task + * @throws BuildException if failonerror is true and an error happens + */ public void execute() throws BuildException { int fileProcessed = 0; if (file == null && (filesets.size() == 0)) { - throw new BuildException("Specify at least one source - " - + "a file or a fileset."); + throw new BuildException( + "Specify at least one source - " + "a file or a fileset."); } initValidator(); if (file != null) { - if (file.exists() && file.canRead() && file.isFile()) { + if (file.exists() && file.canRead() && file.isFile()) { doValidate(file); fileProcessed++; } else { @@ -256,7 +294,7 @@ public class XMLValidateTask extends Task { DirectoryScanner ds = fs.getDirectoryScanner(getProject()); String[] files = ds.getIncludedFiles(); - for (int j = 0; j < files.length; j++) { + for (int j = 0; j < files.length; j++) { File srcFile = new File(fs.getDir(getProject()), files[j]); doValidate(srcFile); fileProcessed++; @@ -284,8 +322,8 @@ public class XMLValidateTask extends Task { try { // load the parser class if (classpath != null) { - AntClassLoader loader - = getProject().createClassLoader(classpath); + AntClassLoader loader = + getProject().createClassLoader(classpath); readerClass = Class.forName(readerClassName, true, loader); } else { readerClass = Class.forName(readerClassName); @@ -304,19 +342,22 @@ public class XMLValidateTask extends Task { // then check it implements XMLReader if (reader instanceof XMLReader) { xmlReader = (XMLReader) reader; - log("Using SAX2 reader " + reader.getClass().getName(), + log( + "Using SAX2 reader " + reader.getClass().getName(), Project.MSG_VERBOSE); } else { // see if it is a SAX1 Parser if (reader instanceof Parser) { xmlReader = new ParserAdapter((Parser) reader); - log("Using SAX1 parser " + reader.getClass().getName(), + log( + "Using SAX1 parser " + reader.getClass().getName(), Project.MSG_VERBOSE); - } else { - throw new BuildException(INIT_FAILED_MSG - + reader.getClass().getName() - + " implements nor SAX1 Parser nor SAX2 XMLReader."); + } else { + throw new BuildException( + INIT_FAILED_MSG + + reader.getClass().getName() + + " implements nor SAX1 Parser nor SAX2 XMLReader."); } } @@ -334,6 +375,12 @@ public class XMLValidateTask extends Task { setFeature(feature.getName(), feature.getValue()); } + + // Sets properties + for (int i = 0; i < propertyList.size(); i++) { + final Property prop = (Property) propertyList.elementAt(i); + setProperty(prop.getName(), prop.getValue()); + } } } @@ -341,8 +388,6 @@ public class XMLValidateTask extends Task { * Set a feature on the parser. * @param feature the name of the feature to set * @param value the value of the feature - * @param warn whether to war if the parser does not support the feature - */ private void setFeature(String feature, boolean value) throws BuildException { @@ -350,13 +395,55 @@ public class XMLValidateTask extends Task { try { xmlReader.setFeature(feature, value); } catch (SAXNotRecognizedException e) { - throw new BuildException("Parser " + xmlReader.getClass().getName() - + " doesn't recognize feature " - + feature, e, getLocation()); - } catch (SAXNotSupportedException e) { - throw new BuildException("Parser " + xmlReader.getClass().getName() - + " doesn't support feature " - + feature, e, getLocation()); + throw new BuildException( + "Parser " + + xmlReader.getClass().getName() + + " doesn't recognize feature " + + feature, + e, + getLocation()); + } catch (SAXNotSupportedException e) { + throw new BuildException( + "Parser " + + xmlReader.getClass().getName() + + " doesn't support feature " + + feature, + e, + getLocation()); + } + } + + /** + * Sets a property. + * + * @param name a property name + * @param value a property value. + * @throws BuildException if an error occurs. + */ + private void setProperty(String name, String value) throws BuildException { + // Validates property + if (name == null || value == null) { + throw new BuildException("Property name and value must be specified."); + } + + try { + xmlReader.setProperty(name, value); + } catch (SAXNotRecognizedException e) { + throw new BuildException( + "Parser " + + xmlReader.getClass().getName() + + " doesn't recognize property " + + name, + e, + getLocation()); + } catch (SAXNotSupportedException e) { + throw new BuildException( + "Parser " + + xmlReader.getClass().getName() + + " doesn't support property " + + name, + e, + getLocation()); } } @@ -373,18 +460,21 @@ public class XMLValidateTask extends Task { xmlReader.parse(is); } catch (SAXException ex) { if (failOnError) { - throw new BuildException("Could not validate document " - + afile); + throw new BuildException( + "Could not validate document " + afile); + } else { + log("Could not validate document " + afile + ": " + ex.toString()); } } catch (IOException ex) { - throw new BuildException("Could not validate document " + afile, + throw new BuildException( + "Could not validate document " + afile, ex); } if (errorHandler.getFailure()) { if (failOnError) { - throw new BuildException(afile - + " is not a valid XML document."); + throw new BuildException( + afile + " is not a valid XML document."); } else { log(afile + " is not a valid XML document", Project.MSG_ERR); } @@ -403,28 +493,42 @@ public class XMLValidateTask extends Task { protected File currentFile = null; protected String lastErrorMessage = null; protected boolean failed = false; - + /** + * initialises the class + * @param file file used + */ public void init(File file) { currentFile = file; failed = false; } - - // did an error happen during last parsing ? + /** + * did an error happen during last parsing ? + * @return did an error happen during last parsing ? + */ public boolean getFailure() { - return failed; } + /** + * record a fatal error + * @param exception the fatal error + */ public void fatalError(SAXParseException exception) { failed = true; doLog(exception, Project.MSG_ERR); } - + /** + * receive notification of a recoverable error + * @param exception the error + */ public void error(SAXParseException exception) { failed = true; doLog(exception, Project.MSG_ERR); } - + /** + * receive notification of a warning + * @param exception the warning + */ public void warning(SAXParseException exception) { // depending on implementation, XMLReader can yield hips of warning, // only output then if user explicitly asked for it @@ -445,9 +549,11 @@ public class XMLValidateTask extends Task { int line = e.getLineNumber(); int col = e.getColumnNumber(); return new URL(sysID).getFile() - + (line == -1 ? "" : (":" + line - + (col == -1 ? "" : (":" + col)))) - + ": " + e.getMessage(); + + (line == -1 + ? "" + : (":" + line + (col == -1 ? "" : (":" + col)))) + + ": " + + e.getMessage(); } catch (MalformedURLException mfue) { // ignore and just return exception message } @@ -481,7 +587,7 @@ public class XMLValidateTask extends Task { } /** * Set the feature value to true or false. - * @param value + * @param value feature value */ public void setValue(boolean value) { attributeValue = value; @@ -503,4 +609,47 @@ public class XMLValidateTask extends Task { return attributeValue; } } + + /** + * A Parser property. + * See + * XML parser properties for usable properties + * @since ant 1.6.2 + */ + public final class Property { + + private String name; + private String value; + /** + * accessor to the name of the property + * @return name of the property + */ + public String getName() { + return name; + } + /** + * setter for the name of the property + * @param name name of the property + */ + public void setName(String name) { + this.name = name; + } + + /** + * getter for the value of the property + * @return value of the property + */ + public String getValue() { + return value; + } + /** + * sets the value of the property + * @param value value of the property + */ + public void setValue(String value) { + this.value = value; + } + + } // Property + } diff --git a/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java b/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java index 98e44832e..04138deb0 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java @@ -16,9 +16,6 @@ */ package org.apache.tools.ant.taskdefs.optional; -import java.io.*; -import java.util.Properties; - import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildFileTest; @@ -35,8 +32,8 @@ public class XmlValidateTest extends BuildFileTest { /** * where tasks run */ - private final static String TASKDEFS_DIR = "src/etc/testcases/taskdefs/optional/"; - + private final static String TASKDEFS_DIR = + "src/etc/testcases/taskdefs/optional/"; /** * Constructor @@ -47,7 +44,6 @@ public class XmlValidateTest extends BuildFileTest { super(name); } - /** * The JUnit setup method */ @@ -55,28 +51,23 @@ public class XmlValidateTest extends BuildFileTest { configureProject(TASKDEFS_DIR + "xmlvalidate.xml"); } - /** * The teardown method for JUnit */ - public void tearDown() { - - } - + public void tearDown() {} /** * Basic inline 'dtd' element test. */ public void testValidate() throws Exception { - executeTarget("testValidate"); + executeTarget("testValidate"); } - /** * Test indirect validation. */ public void testDeepValidate() throws Exception { - executeTarget("testDeepValidate"); + executeTarget("testDeepValidate"); } /** @@ -124,10 +115,11 @@ public class XmlValidateTest extends BuildFileTest { try { executeTarget("testSchemaGood"); } catch (BuildException e) { - if (e.getMessage() - .endsWith(" doesn't recognize feature http://apache.org/xml/features/validation/schema") || - e.getMessage() - .endsWith(" doesn't support feature http://apache.org/xml/features/validation/schema")) { + if (e + .getMessage() + .endsWith(" doesn't recognize feature http://apache.org/xml/features/validation/schema") + || e.getMessage().endsWith( + " doesn't support feature http://apache.org/xml/features/validation/schema")) { System.err.println(" skipped, parser doesn't support schema"); } else { throw e; @@ -142,18 +134,20 @@ public class XmlValidateTest extends BuildFileTest { executeTarget("testSchemaBad"); fail("Should throw BuildException because 'Bad Schema Validation'"); - expectBuildExceptionContaining("testSchemaBad", - "Bad Schema Validation", - "not a valid XML document"); + expectBuildExceptionContaining( + "testSchemaBad", + "Bad Schema Validation", + "not a valid XML document"); } catch (BuildException e) { - if (e.getMessage() - .endsWith(" doesn't recognize feature http://apache.org/xml/features/validation/schema") || - e.getMessage() - .endsWith(" doesn't support feature http://apache.org/xml/features/validation/schema")) { + if (e + .getMessage() + .endsWith(" doesn't recognize feature http://apache.org/xml/features/validation/schema") + || e.getMessage().endsWith( + " doesn't support feature http://apache.org/xml/features/validation/schema")) { System.err.println(" skipped, parser doesn't support schema"); } else { - assertTrue(e.getMessage() - .indexOf("not a valid XML document") > -1); + assertTrue( + e.getMessage().indexOf("not a valid XML document") > -1); } } } @@ -179,4 +173,16 @@ public class XmlValidateTest extends BuildFileTest { expectBuildException("testUtf8", "invalid characters in file"); } + // Tests property element, using XML schema properties as an example. + + public void testPropertySchemaForValidXML() { + executeTarget("testProperty.validXML"); + } + + public void testPropertySchemaForInvalidXML() { + expectBuildException( + "testProperty.invalidXML", + "XML file does not satisfy schema."); + } + }