antoine 2004/06/02 13:32:11 Modified: . WHATSNEW CONTRIBUTORS src/main/org/apache/tools/ant/taskdefs/optional XMLValidateTask.java src/testcases/org/apache/tools/ant/taskdefs/optional XmlValidateTest.java src/etc/testcases/taskdefs/optional xmlvalidate.xml Added: src/etc/testcases/taskdefs/optional/xml endpiece-noSchema-invalid.xml endpiece-noSchema.xml Log: 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) Revision Changes Path 1.1 ant/src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema-invalid.xml Index: endpiece-noSchema-invalid.xml =================================================================== <?xml version="1.0" encoding="UTF-8"?> <!-- Invalid test XML file without any schema refeferences --> <doc> <section title="endpiece"> With a little luck, the network will pick me up. This is Ripley - last survivor of The Nostromo - signing off. </section> <invalidelement/> </doc> 1.1 ant/src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema.xml Index: endpiece-noSchema.xml =================================================================== <?xml version="1.0" encoding="UTF-8"?> <!-- Test XML file without any schema refeferences --> <doc> <section title="endpiece"> With a little luck, the network will pick me up. This is Ripley - last survivor of The Nostromo - signing off. </section> </doc> 1.611 +3 -0 ant/WHATSNEW Index: WHATSNEW =================================================================== RCS file: /home/cvs/ant/WHATSNEW,v retrieving revision 1.610 retrieving revision 1.611 diff -u -r1.610 -r1.611 --- WHATSNEW 2 Jun 2004 12:09:45 -0000 1.610 +++ WHATSNEW 2 Jun 2004 20:32:11 -0000 1.611 @@ -128,6 +128,9 @@ Other changes: -------------- +* <xmlvalidate> 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. 1.17 +3 -3 ant/CONTRIBUTORS Index: CONTRIBUTORS =================================================================== RCS file: /home/cvs/ant/CONTRIBUTORS,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- CONTRIBUTORS 7 May 2004 18:10:34 -0000 1.16 +++ CONTRIBUTORS 2 Jun 2004 20:32:11 -0000 1.17 @@ -9,7 +9,7 @@ Anton Mazkovoi Arnaud Vandyck Arnout J. Kuiper -Aslak Hellesøy +Aslak Helles?y Avik Sengupta Balazs Fejes 2 Benoit Moussaud @@ -17,7 +17,6 @@ Brian Deitte Brian Felder Bruce Atherton -chanezon Charles Hudak Charlie Hubbard Chris Povirk @@ -72,7 +71,7 @@ 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 Foemmel Matt Humphrey Matt Small +Matthew Hawthorne Matthew Inger Matthew Kuperus Heun Matthew Watson 1.41 +193 -44 ant/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java Index: XMLValidateTask.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java,v retrieving revision 1.40 retrieving revision 1.41 diff -u -r1.40 -r1.41 --- XMLValidateTask.java 9 Mar 2004 16:48:15 -0000 1.40 +++ XMLValidateTask.java 2 Jun 2004 20:32:11 -0000 1.41 @@ -35,6 +35,7 @@ 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 @@ 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 @@ 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 @@ * <p> * If set to <code>true</code> (default), throw a buildException if the * parser yields an error. + * @param fail if set to <code>false</code> do not fail on error */ public void setFailOnError(boolean fail) { failOnError = fail; @@ -108,6 +114,7 @@ * Specify how parser error are to be handled. * <p> * If set to <code>true</true> (default), log a warn message for each SAX warn event. + * @param bool if set to <code>false</code> do not send warnings */ public void setWarn(boolean bool) { warn = bool; @@ -122,6 +129,7 @@ * <p> * this option is ignored if the specified class * with [EMAIL PROTECTED] #setClassName(String)} is not a SAX2 XMLReader. + * @param bool if set to <code>false</code> only fail on malformed XML */ public void setLenient(boolean bool) { lenient = bool; @@ -142,9 +150,9 @@ 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 @@ /** * @see #setClasspath + * @return the classpath created */ public Path createClasspath() { if (this.classpath == null) { @@ -167,6 +176,7 @@ /** * 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 @@ /** * 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 @@ /** * 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 @@ /** * 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 @@ * features of the SAX parser. * Valid attributes * <a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description">include</a> + * @return attribute created * @since ant1.6 */ public Attribute createAttribute() { @@ -206,6 +220,23 @@ 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 @@ * 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 <code>failonerror</code> 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ * 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } /** * 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 @@ return attributeValue; } } + + /** + * A Parser property. + * See <a href="http://xml.apache.org/xerces-j/properties.html"> + * XML parser properties</a> 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 + } 1.17 +33 -27 ant/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java Index: XmlValidateTest.java =================================================================== RCS file: /home/cvs/ant/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- XmlValidateTest.java 9 Mar 2004 16:49:01 -0000 1.16 +++ XmlValidateTest.java 2 Jun 2004 20:32:11 -0000 1.17 @@ -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 @@ /** * 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 @@ super(name); } - /** * The JUnit setup method */ @@ -55,28 +51,23 @@ 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 @@ 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 @@ 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); } } } @@ -177,6 +171,18 @@ */ public void testUtf8() { 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."); } } 1.13 +47 -0 ant/src/etc/testcases/taskdefs/optional/xmlvalidate.xml Index: xmlvalidate.xml =================================================================== RCS file: /home/cvs/ant/src/etc/testcases/taskdefs/optional/xmlvalidate.xml,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- xmlvalidate.xml 23 Sep 2003 14:33:43 -0000 1.12 +++ xmlvalidate.xml 2 Jun 2004 20:32:11 -0000 1.13 @@ -129,4 +129,51 @@ <xmlvalidate warn="false" file="xml/utf-8.xml"/> </target> + + <!-- Tests property element with XML file that satisfies schema --> + <target name="testProperty.validXML"> + + <!-- Converts path to URL format --> + <pathconvert dirsep="/" property="xsd.file"> + <path> + <pathelement location="xml/doc.xsd"/> + </path> + </pathconvert> + + <xmlvalidate file="xml/endpiece-noSchema.xml" lenient="false" + failonerror="true" warn="true"> + + <attribute name="http://apache.org/xml/features/validation/schema" + value="true"/> + + <property + name="http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation" + value="${xsd.file}"/> + </xmlvalidate> + </target> + + + <!-- Tests property element with XML file that fails schema validation --> + <target name="testProperty.invalidXML"> + + <!-- Converts path to URL format --> + <pathconvert dirsep="/" property="xsd.file"> + <path> + <pathelement location="xml/doc.xsd"/> + </path> + </pathconvert> + + <xmlvalidate file="xml/endpiece-noSchema-invalid.xml" lenient="false" + failonerror="true" warn="true"> + + <attribute name="http://apache.org/xml/features/validation/schema" + value="true"/> + + <property + name="http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation" + value="${xsd.file}"/> + </xmlvalidate> + </target> + </project> +
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]