stevel 2005/02/22 07:58:36 Modified: src/etc/testcases/taskdefs/optional xmlvalidate.xml src/etc/testcases/taskdefs/optional/xml endpiece.xml src/main/org/apache/tools/ant/taskdefs/optional XMLValidateTask.java src/main/org/apache/tools/ant/taskdefs defaults.properties docs/manual optionaltasklist.html Added: docs/manual/OptionalTasks schemavalidate.html src/etc/testcases/taskdefs/optional schemavalidate.xml src/etc/testcases/taskdefs/optional/xml doc-in-ns.xsd endpiece-ns-no-location.xml src/main/org/apache/tools/ant/taskdefs/optional SchemaValidate.java src/main/org/apache/tools/ant/util XmlConstants.java src/testcases/org/apache/tools/ant/taskdefs/optional SchemaValidateTest.java Log: <schemavalidate>. Because I can never get the settings right. Revision Changes Path 1.1 ant/docs/manual/OptionalTasks/schemavalidate.html Index: schemavalidate.html =================================================================== <html> <head> <title>SchemaValidate Task</title> </head> <body> <h2><a name="schemavalidate">SchemaValidate</a></h2> <h3>Description</h3> <p>This task validates XML files described by an XML Schema. The task extends the XmlValidate task with XSD-specific features.</p> <ol> <li>The parser is created validating and namespace aware </li> <li>Validation is turned on.</li> <li>and Schema validation is turned on.</li> <li>Any default schema supplied is used as the no-namespace schema <li>All nested schema declarations are turned into the list of namespace-url bindings for schema lookup. </ol> Note that nested catalogs are still used for lookup of the URLs given as the sources of schema documents, so you can still delegate lookup to a catalog, you just need to list all schema URIs and their URL equivalents. <p>This task supports the use of nested <li><a href="../CoreTypes/xmlcatalog.html"><tt><xmlcatalog></tt></a> elements</li> <li> <tt><schema></tt> elements, that bind a namespace URI to a URL or a local filename. <li><tt><dtd></tt> elements which are used to resolve DTDs and entities.</li> <li><tt><attribute></tt> elements which are used to set features on the parser. These can be any number of <a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description"><tt>http://xml.org/sax/features/</tt></a> or other features that your parser may support.</li> <li><tt><property></tt> elements, containing string properties </p> <p> The task only supports SAX2 or later parsers: it is an error to specify a SAX1 parser. <h3>Parameters</h3> <table border="1" cellpadding="2" cellspacing="0"> <tr> <td valign="top"><b>Attribute</b></td> <td valign="top"><b>Description</b></td> <td align="center" valign="top"><b>Required</b></td> </tr> <tr> <td valign="top">file</td> <td valign="top">the file(s) you want to check. (optionally can use an embedded fileset)</td> <td valign="top" align="center">No</td> </tr> <tr> <td valign="top">defaultSchemaFile</td> <td valign="top"> filename of a no-namespace XSD file to provide the schema for no-namespace XML content. </td> <td valign="top" align="center">No</td> </tr> <tr> <td valign="top">noNamespaceURL</td> <td valign="top"> URL of a no-namespace XSD file to provide the schema for no-namespace XML content. </td> <td valign="top" align="center">No</td> </tr> <tr> <td valign="top">noNamespaceFile</td> <td valign="top"> filename of a no-namespace XSD file to provide the schema for no-namespace XML content. </td> <td valign="top" align="center">No</td> </tr> <tr> <td valign="top">fullchecking</td> <td valign="top"> enable full schema checking. Slow but strict. </td> <td valign="top" align="center">No - default true</td> </tr> <tr> <td valign="top">lenient</td> <td valign="top"> if true, only check the XML document is well formed </td> <td valign="top" align="center">No</td> </tr> <tr> <td valign="top">classname</td> <td valign="top">the parser to use.</td> <td align="center" valign="top">No</td> </tr> <tr> <td valign="top">classpathref</td> <td valign="top">where to find the parser class. Optionally can use an embedded <tt><classpath></tt> element.</td> <td align="center" valign="top">No</td> </tr> <tr> <td valign="top">failonerror</td> <td valign="top">fails on a error if set to true (defaults to true).</td> <td align="center" valign="top">No</td> </tr> <tr> <td valign="top">warn</td> <td valign="top">log parser warn events.</td> <td align="center" valign="top">No</td> </tr> </table> <h3><a name="nested">Nested Elements</a></h3> <h4>schema</h4> <p> Identify the name and location of a schema that may be used in validating the document(s). </p> <table border="1" cellpadding="2" cellspacing="0"> <tr> <td width="12%" valign="top"><b>Attribute</b></td> <td width="78%" valign="top"><b>Description</b></td> <td width="10%" valign="top"><b>Required</b></td> </tr> <tr> <td valign="top">namespace</td> <td valign="top">URI of the schema namespace</td> <td align="center" valign="top">Yes</td> </tr> <tr> <td valign="top">url</td> <td valign="top">URL of the schema</td> <td align="center" valign="top">One of url or file is required</td> </tr> <tr> <td valign="top">file</td> <td valign="top">file of the schema</td> <td align="center" valign="top">One of url or file is required</td> </tr> </table> <h4>dtd</h4> <p> <tt><dtd></tt> is used to specify different locations for DTD resolution. </p> <table border="1" cellpadding="2" cellspacing="0"> <tr> <td width="12%" valign="top"><b>Attribute</b></td> <td width="78%" valign="top"><b>Description</b></td> <td width="10%" valign="top"><b>Required</b></td> </tr> <tr> <td valign="top">publicId</td> <td valign="top">Public ID of the DTD to resolve</td> <td align="center" valign="top">Yes</td> </tr> <tr> <td valign="top">location</td> <td valign="top">Location of the DTD to use, which can be a file, a resource, or a URL</td> <td align="center" valign="top">Yes</td> </tr> </table> <h4>xmlcatalog</h4> <p>The <a href="../CoreTypes/xmlcatalog.html"><tt><xmlcatalog></tt></a> element is used to perform entity resolution.</p> <h4>attribute</h4> <p>The <tt><attribute></tt> element is used to set parser features.<br> Features usable with the xerces parser are defined here : <a href="http://xml.apache.org/xerces-j/features.html">Setting features</a><br> SAX features are defined here: <a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description"><tt>http://xml.org/sax/features/</tt></a><br> </p> <table border="1" cellpadding="2" cellspacing="0"> <tr> <td width="12%" valign="top"><b>Attribute</b></td> <td width="78%" valign="top"><b>Description</b></td> <td width="10%" valign="top"><b>Required</b></td> </tr> <tr> <td valign="top">name</td> <td valign="top">The name of the feature</td> <td align="center" valign="top">Yes</td> </tr> <tr> <td valign="top">value</td> <td valign="top">The boolean value of the feature</td> <td align="center" valign="top">Yes</td> </tr> </table> </p> <h4>property</h4> <p>The <tt><property></tt> element is used to set properties. These properties are defined here for the xerces XML parser implementation : <a href="http://xml.apache.org/xerces-j/properties.html">XML Parser properties</a> Properties can be used to set the schema used to validate the XML file. </p> <table border="1" cellpadding="2" cellspacing="0"> <tr> <td width="12%" valign="top"><b>Attribute</b></td> <td width="78%" valign="top"><b>Description</b></td> <td width="10%" valign="top"><b>Required</b></td> </tr> <tr> <td valign="top">name</td> <td valign="top">The name of the feature</td> <td align="center" valign="top">Yes</td> </tr> <tr> <td valign="top">value</td> <td valign="top">The string value of the property</td> <td align="center" valign="top">Yes</td> </tr> </table> </p> <h3>Examples</h3> <pre> <xmlvalidate file="toto.xml"/> </pre> Validate toto.xml <pre> <xmlvalidate failonerror="no" lenient="yes" warn="yes" classname="org.apache.xerces.parsers.SAXParser"> classpath="lib/xerces.jar"> <fileset dir="src" includes="style/*.xsl"/> </xmlvalidate> </pre> Validate all .xsl files in src/style, but only warn if there is an error, rather than halt the build. <pre> <xmlvalidate file="struts-config.xml" warn="false"> <dtd publicId="-//Apache Software Foundation//DTD Struts Configuration 1.0//EN" location="struts-config_1_0.dtd"/> </xmlvalidate> </pre> Validate a struts configuration, using a local copy of the DTD. <pre> <xmlvalidate failonerror="no"> <fileset dir="${project.dir}" includes="**/*.xml"/> <xmlcatalog refid="mycatalog"/> </xmlvalidate> </pre> Scan all XML files in the project, using a predefined catalog to map URIs to local files. <pre> <xmlvalidate failonerror="no"> <fileset dir="${project.dir}" includes="**/*.xml"/> <xmlcatalog> <dtd publicId="-//ArielPartners//DTD XML Article V1.0//EN" location="com/arielpartners/knowledgebase/dtd/article.dtd"/> </xmlcatalog> </xmlvalidate> </pre> Scan all XML files in the project, using the catalog defined inline. <pre> <xmlvalidate failonerror="yes" lenient="no" warn="yes"> <fileset dir="xml" includes="**/*.xml"/> <attribute name="http://xml.org/sax/features/validation" value="true"/> <attribute name="http://apache.org/xml/features/validation/schema" value="true"/> <attribute name="http://xml.org/sax/features/namespaces" value="true"/> </xmlvalidate> </pre> Validate all .xml files in xml directory with the parser configured to perform schema validation. Note: The parser must support the <pre>http://apache.org/xml/features/validation/schema</pre> feature. <br> <pre> <!-- 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"/> <attribute name="http://xml.org/sax/features/namespaces" value="true"/> <property name="http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation" value="${xsd.file}"/> </xmlvalidate> </pre> <br> Validate the file xml/endpiece-noSchema.xml against the schema xml/doc.xsd. <br> <hr> <p align="center">Copyright © 2001-2002,2004 The Apache Software Foundation. All rights Reserved.</p> </body> </html> 1.14 +13 -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.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- xmlvalidate.xml 2 Jun 2004 20:32:11 -0000 1.13 +++ xmlvalidate.xml 22 Feb 2005 15:58:35 -0000 1.14 @@ -175,5 +175,18 @@ </xmlvalidate> </target> + <target name="testSchemaWithXSD"> + <xmlvalidate warn="false" lenient="false" + file="xml/endpiece-noSchema.xml"> + + <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> 1.1 ant/src/etc/testcases/taskdefs/optional/schemavalidate.xml Index: schemavalidate.xml =================================================================== <project name="validate" default="default" basedir="."> <property name="doc.xsd" location="xml/doc.xsd"/> <property name="doc-in-ns.xsd" location="xml/doc-in-ns.xsd"/> <property name="namespace" value="http://apache.org/ant/doc/" /> <property name="endpiece-ns-no-location.xml" location="xml/endpiece-ns-no-location.xml"/> <target name="testNoNamespace"> <schemavalidate defaultSchemaFile="${doc.xsd}" file="xml/endpiece-noSchema.xml"> </schemavalidate> </target> <target name="testNSMapping"> <schemavalidate file="${endpiece-ns-no-location.xml}"> <schema namespace="${namespace}" file="${doc-in-ns.xsd}" /> <schema namespace="http://apache.org/ant/2" url="http://ant.apache.org/" /> </schemavalidate> </target> <target name="default" depends="testNoNamespace,testNSMapping" /> </project> 1.3 +2 -4 ant/src/etc/testcases/taskdefs/optional/xml/endpiece.xml Index: endpiece.xml =================================================================== RCS file: /home/cvs/ant/src/etc/testcases/taskdefs/optional/xml/endpiece.xml,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- endpiece.xml 8 Nov 2002 09:06:20 -0000 1.2 +++ endpiece.xml 22 Feb 2005 15:58:36 -0000 1.3 @@ -1,8 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<doc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="doc.xsd" - xmlns="http://Massive/Attack+Mezzanine"> - <section title="endpiece"> +<doc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="doc-in-ns.xsd" xmlns="http://apache.org/ant/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> 1.1 ant/src/etc/testcases/taskdefs/optional/xml/doc-in-ns.xsd Index: doc-in-ns.xsd =================================================================== <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://apache.org/ant/doc/" xmlns:tns="http://apache.org/ant/doc/" elementFormDefault="qualified"> <xs:element name="doc"> <xs:complexType> <xs:sequence> <xs:element ref="tns:section"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="section"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="title" type="xs:string"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> </xs:schema> 1.1 ant/src/etc/testcases/taskdefs/optional/xml/endpiece-ns-no-location.xml Index: endpiece-ns-no-location.xml =================================================================== <?xml version="1.0" encoding="UTF-8"?> <doc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="doc-in-ns.xsd" xmlns="http://apache.org/ant/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.47 +94 -31 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.46 retrieving revision 1.47 diff -u -r1.46 -r1.47 --- XMLValidateTask.java 6 Jan 2005 12:05:08 -0000 1.46 +++ XMLValidateTask.java 22 Feb 2005 15:58:36 -0000 1.47 @@ -33,6 +33,7 @@ import org.apache.tools.ant.types.XMLCatalog; import org.apache.tools.ant.util.FileUtils; import org.apache.tools.ant.util.JAXPUtils; +import org.apache.tools.ant.util.XmlConstants; import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; @@ -258,6 +259,19 @@ protected EntityResolver getEntityResolver() { return xmlCatalog; } + + /** + * get the XML reader. Non-null only after [EMAIL PROTECTED] #initValidator()}. + * If the reader is an instance of [EMAIL PROTECTED] ParserAdapter} then + * the parser is a SAX1 parser, and you cannot call + * [EMAIL PROTECTED] #setFeature(String, boolean)} or [EMAIL PROTECTED] #setProperty(String, String)} + * on it. + * @return the XML reader or null. + */ + protected XMLReader getXmlReader() { + return xmlReader; + } + /** * execute the task * @throws BuildException if <code>failonerror</code> is true and an error happens @@ -304,16 +318,56 @@ /** * init the parser : * load the parser class, and set features if necessary + * It is only after this that the reader is valid + * @throws BuildException if something went wrong + */ + protected void initValidator() { + + xmlReader=createXmlReader(); + + xmlReader.setEntityResolver(getEntityResolver()); + xmlReader.setErrorHandler(errorHandler); + + if (!isSax1Parser()) { + // turn validation on + if (!lenient) { + setFeature(XmlConstants.FEATURE_VALIDATION, true); + } + // set the feature from the attribute list + for (int i = 0; i < attributeList.size(); i++) { + Attribute feature = (Attribute) attributeList.elementAt(i); + 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()); + } + } + } + + /** + * test that returns true if we are using a SAX1 parser. + * @return true when a SAX1 parser is in use */ - private void initValidator() { + protected boolean isSax1Parser() { + return (xmlReader instanceof ParserAdapter); + } + /** + * create the XML reader. + * This is one by instantiating anything specified by [EMAIL PROTECTED] #readerClassName}, + * falling back to a default reader if not. + * If the returned reader is an instance of [EMAIL PROTECTED] ParserAdapter} then + * we have created and wrapped a SAX1 parser. + * @returns the new XMLReader. + */ + protected XMLReader createXmlReader() { Object reader = null; if (readerClassName == null) { - try { - reader = JAXPUtils.getXMLReader(); - } catch (BuildException exc) { - reader = JAXPUtils.getParser(); - } + reader = createDefaultReaderOrParser(); } else { Class readerClass = null; @@ -338,8 +392,9 @@ } // then check it implements XMLReader + XMLReader newReader; if (reader instanceof XMLReader) { - xmlReader = (XMLReader) reader; + newReader = (XMLReader) reader; log( "Using SAX2 reader " + reader.getClass().getName(), Project.MSG_VERBOSE); @@ -347,7 +402,7 @@ // see if it is a SAX1 Parser if (reader instanceof Parser) { - xmlReader = new ParserAdapter((Parser) reader); + newReader = new ParserAdapter((Parser) reader); log( "Using SAX1 parser " + reader.getClass().getName(), Project.MSG_VERBOSE); @@ -358,36 +413,41 @@ + " implements nor SAX1 Parser nor SAX2 XMLReader."); } } + return newReader; + } - xmlReader.setEntityResolver(getEntityResolver()); - xmlReader.setErrorHandler(errorHandler); - - if (!(xmlReader instanceof ParserAdapter)) { - // turn validation on - if (!lenient) { - setFeature("http://xml.org/sax/features/validation", true); - } - // set the feature from the attribute list - for (int i = 0; i < attributeList.size(); i++) { - Attribute feature = (Attribute) attributeList.elementAt(i); - 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()); - } + /** + * + * @return + */ + private Object createDefaultReaderOrParser() { + Object reader; + try { + reader = createDefaultReader(); + } catch (BuildException exc) { + reader = JAXPUtils.getParser(); } + return reader; + } + + /** + * create a reader if the use of the class did not specify another one. + * If a BuildException is thrown, the caller may revert to an alternate + * reader. + * @return a new reader. + * @throws BuildException if something went wrong + */ + protected XMLReader createDefaultReader() { + return JAXPUtils.getXMLReader(); } /** * Set a feature on the parser. * @param feature the name of the feature to set * @param value the value of the feature + * @throws BuildException if the feature was not supported */ - private void setFeature(String feature, boolean value) + protected void setFeature(String feature, boolean value) throws BuildException { log("Setting feature " + feature + "=" + value, Project.MSG_DEBUG); try { @@ -417,8 +477,9 @@ * @param name a property name * @param value a property value. * @throws BuildException if an error occurs. + * @throws BuildException if the property was not supported */ - private void setProperty(String name, String value) throws BuildException { + protected 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."); @@ -448,7 +509,7 @@ /** * parse the file */ - private void doValidate(File afile) { + protected void doValidate(File afile) { try { log("Validating " + afile.getName() + "... ", Project.MSG_VERBOSE); errorHandler.init(afile); @@ -655,4 +716,6 @@ } // Property + + } 1.1 ant/src/main/org/apache/tools/ant/taskdefs/optional/SchemaValidate.java Index: SchemaValidate.java =================================================================== /* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.taskdefs.optional; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.DTDLocation; import org.apache.tools.ant.util.XmlConstants; import org.apache.tools.ant.util.JAXPUtils; import org.xml.sax.XMLReader; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; import org.xml.sax.SAXException; import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParser; import javax.xml.parsers.ParserConfigurationException; import java.util.List; import java.util.ArrayList; import java.util.Iterator; import java.io.File; import java.net.MalformedURLException; /** * Validate XML Schema documents. * This task validates XML schema documents. It requires an XML parser * that handles the relevant SAx, Xerces or JAXP options. * * To resolve remote referencies, Ant may need its proxy set up, using the * setproxy task. * * Hands off most of the work to its parent, [EMAIL PROTECTED] XMLValidateTask} * @since Ant1.7 */ public class SchemaValidate extends XMLValidateTask { private List schemaLocations= new ArrayList(); /** full checking of a schema */ private boolean fullChecking=true; /** * default URL for nonamespace schemas */ private SchemaLocation anonymousSchema; public static final String ERROR_SAX_1 = "SAX1 parsers are not supported"; public static final String ERROR_NO_XSD_SUPPORT = "Parser does not support Xerces or JAXP schema features"; public static final String ERROR_TOO_MANY_DEFAULT_SCHEMAS = "Only one of defaultSchemaFile and defaultSchemaURL allowed"; public static final String ERROR_PARSER_CREATION_FAILURE = "Could not create parser"; /** * Called by the project to let the task initialize properly. The default * implementation is a no-op. * * @throws BuildException if something goes wrong with the build */ public void init() throws BuildException { super.init(); //validating setLenient(false); } public boolean enableXercesSchemaValidation() { try { setFeature(XmlConstants.FEATURE_XSD,true); //set the schema source for the doc setNoNamespaceSchemaProperty( XmlConstants.PROPERTY_NO_NAMESPACE_SCHEMA_LOCATION); } catch (BuildException e) { log(e.toString(),Project.MSG_VERBOSE); return false; } return true; } private void setNoNamespaceSchemaProperty(String property) { String anonSchema = getNoNamespaceSchemaURL(); if (anonSchema != null) { setProperty(property, anonSchema); } } /** * JAXP12 schema attributes * @see <A href="http://java.sun.com/xml/jaxp/change-requests-11.html"> * JAXP 1.2 Approved CHANGES</A> * @return */ public boolean enableJAXP12SchemaValidation() { try { //enable XSD setProperty(XmlConstants.FEATURE_JAXP12_SCHEMA_LANGUAGE, XmlConstants.URI_XSD); //set the schema source for the doc setNoNamespaceSchemaProperty( XmlConstants.FEATURE_JAXP12_SCHEMA_SOURCE); } catch (BuildException e) { log(e.toString(), Project.MSG_VERBOSE); return false; } return true; } public void addSchema(SchemaLocation location) { schemaLocations.add(location); } /** * enable full schema checking. Slower but better. * @param fullChecking */ public void setFullChecking(boolean fullChecking) { this.fullChecking = fullChecking; } /** * create a schema location to hold the anonymous * schema */ protected void createAnonymousSchema() { if(anonymousSchema==null) { anonymousSchema=new SchemaLocation(); } anonymousSchema.setNamespace("(no namespace)"); } /** * identify the URL of the default schema * @param defaultSchemaURL */ public void setNoNamespaceURL(String defaultSchemaURL) { createAnonymousSchema(); this.anonymousSchema.setUrl(defaultSchemaURL); } /** * identify a file containing the default schema * @param defaultSchemaFile */ public void setNoNamespaceFile(File defaultSchemaFile) { createAnonymousSchema(); this.anonymousSchema.setFile(defaultSchemaFile); } /** * init the parser : load the parser class, and set features if necessary It * is only after this that the reader is valid * * @throws BuildException if something went wrong */ protected void initValidator() { super.initValidator(); XMLReader xmlReader = getXmlReader(); //validate the parser type if(isSax1Parser()) { throw new BuildException(ERROR_SAX_1); } //enable schema //setFeature(XmlConstants.FEATURE_VALIDATION,false); setFeature(XmlConstants.FEATURE_NAMESPACES,true); if(!enableXercesSchemaValidation() && !enableJAXP12SchemaValidation()) { //couldnt use the xerces or jaxp calls throw new BuildException(ERROR_NO_XSD_SUPPORT); } //enable schema checking setFeature(XmlConstants.FEATURE_XSD_FULL_VALIDATION,fullChecking); //turn off DTDs setFeatureIfSupported(XmlConstants.FEATURE_DISALLOW_DTD,true); //schema declarations go in next addSchemaLocations(); } /** * Create a reader if the use of the class did not specify another one. * The reason to not use [EMAIL PROTECTED] JAXPUtils#getXMLReader()} was to * create our own factory with our own options. * @return */ protected XMLReader createDefaultReader() { SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(true); factory.setNamespaceAware(true); XMLReader reader = null; try { SAXParser saxParser = factory.newSAXParser(); reader = saxParser.getXMLReader(); } catch (ParserConfigurationException e) { throw new BuildException(ERROR_PARSER_CREATION_FAILURE,e); } catch (SAXException e) { throw new BuildException(ERROR_PARSER_CREATION_FAILURE, e); } return reader; } /** * build a string list of all schema locations, then set the relevant * property. */ protected void addSchemaLocations() { Iterator it = schemaLocations.iterator(); StringBuffer buffer = new StringBuffer(); int count = 0; while (it.hasNext()) { if (count > 0) { buffer.append(' '); } SchemaLocation schemaLocation = (SchemaLocation) it.next(); String tuple = schemaLocation.getURIandLocation(); buffer.append(tuple); count++; } if (count > 0) { setProperty(XmlConstants.PROPERTY_SCHEMA_LOCATION, buffer.toString()); } } /** * get the URL of the no namespace schema * @return */ protected String getNoNamespaceSchemaURL() { if(anonymousSchema==null) { return null; } else { return anonymousSchema.getSchemaLocationURL(); } } /** * set a feature if it is supported, log at verbose level if * not * @param feature * @param value */ protected void setFeatureIfSupported(String feature,boolean value) { try { getXmlReader().setFeature(feature, value); } catch (SAXNotRecognizedException e) { log("Not recognizied: "+feature,Project.MSG_VERBOSE); } catch (SAXNotSupportedException e) { log("Not supported: " + feature, Project.MSG_VERBOSE); } } /** * representation of a schema location. This is a URI plus either a file or * a url */ public static class SchemaLocation { private String namespace; private File file; private String url; public static final String ERROR_NO_URI = "No URI"; private static final String ERROR_TWO_LOCATIONS = "Both URL and File were given for schema "; public static final String ERROR_NO_FILE = "File not found: "; public static final String ERROR_NO_URL_REPRESENTATION = "Cannot make a URL of "; public static final String ERROR_NO_LOCATION = "No file or URL supplied for the schema "; public SchemaLocation() { } public String getNamespace() { return namespace; } public void setNamespace(String namespace) { this.namespace = namespace; } public File getFile() { return file; } public void setFile(File file) { this.file = file; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getSchemaLocationURL() { boolean hasFile = file != null; boolean hasURL = isSet(url); //error if both are empty, or both are set if(!hasFile && !hasURL) { throw new BuildException( ERROR_NO_LOCATION+namespace); } if (hasFile && hasURL) { throw new BuildException(ERROR_TWO_LOCATIONS + namespace); } String schema = url; if (hasFile) { if (!file.exists()) { throw new BuildException(ERROR_NO_FILE + file); } try { schema = file.toURL().toString(); } catch (MalformedURLException e) { //this is almost implausible, but required handling throw new BuildException(ERROR_NO_URL_REPRESENTATION + file,e); } } return schema; } /** * validate the fields then create a "uri location" string * * @return string of uri and location * @throws BuildException */ public String getURIandLocation() throws BuildException { if (!isSet(getNamespace())) { throw new BuildException(ERROR_NO_URI); } StringBuffer buffer = new StringBuffer(); buffer.append(namespace); buffer.append(' '); buffer.append(getSchemaLocationURL()); return new String(buffer); } private boolean isSet(String property) { return property != null && property.length() != 0; } } //SchemaLocation } 1.1 ant/src/main/org/apache/tools/ant/util/XmlConstants.java Index: XmlConstants.java =================================================================== /* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.util; /** * XML Parser constants, all kept in one place for ease of reuse * @see <a href="http://xml.apache.org/xerces-j/features.html">Xerces features</a> * @see <a href="http://xml.apache.org/xerces-j/properties.html">Xerces properties</a> * @see <a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description">SAX.</a> */ public class XmlConstants { public static final String PROPERTY_SCHEMA_LOCATION = "http://apache.org/xml/properties/schema/external-schemaLocation"; public static final String PROPERTY_NO_NAMESPACE_SCHEMA_LOCATION = "http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation"; public static final String FEATURE_XSD_FULL_VALIDATION = "http://apache.org/xml/features/validation/schema-full-checking"; public static final String FEATURE_XSD = "http://apache.org/xml/features/validation/schema"; public static final String FEATURE_VALIDATION = "http://xml.org/sax/features/validation"; public static final String FEATURE_NAMESPACES = "http://xml.org/sax/features/namespaces"; public static final String FEATURE_JAXP12_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; public static final String FEATURE_JAXP12_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; public static final String URI_XSD = "http://www.w3.org/2001/XMLSchema"; public static final String FEATURE_EXTERNAL_ENTITIES = "http://xml.org/sax/features/external-general-entities"; public static final String FEATURE_DISALLOW_DTD = "http://apache.org/xml/features/disallow-doctype-decl"; } 1.1 ant/src/testcases/org/apache/tools/ant/taskdefs/optional/SchemaValidateTest.java Index: SchemaValidateTest.java =================================================================== /* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.taskdefs.optional; import org.apache.tools.ant.BuildFileTest; /** * Test schema validation */ public class SchemaValidateTest extends BuildFileTest { /** * where tasks run */ private final static String TASKDEFS_DIR = "src/etc/testcases/taskdefs/optional/"; /** * Constructor * * @param name testname */ public SchemaValidateTest(String name) { super(name); } /** * The JUnit setup method */ public void setUp() { configureProject(TASKDEFS_DIR + "schemavalidate.xml"); } /** * test with no namespace */ public void testNoNamespace() throws Exception { executeTarget("testNoNamespace"); } /** * add namespace awareness. */ public void testNSMapping() throws Exception { executeTarget("testNSMapping"); } } 1.165 +1 -0 ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties Index: defaults.properties =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties,v retrieving revision 1.164 retrieving revision 1.165 diff -u -r1.164 -r1.165 --- defaults.properties 7 Jan 2005 21:56:59 -0000 1.164 +++ defaults.properties 22 Feb 2005 15:58:36 -0000 1.165 @@ -206,6 +206,7 @@ scriptdef=org.apache.tools.ant.taskdefs.optional.script.ScriptDef ildasm=org.apache.tools.ant.taskdefs.optional.dotnet.Ildasm apt=org.apache.tools.ant.taskdefs.Apt +schemavalidate=org.apache.tools.ant.taskdefs.optional.SchemaValidate # deprecated ant tasks (kept for back compatibility) starteam=org.apache.tools.ant.taskdefs.optional.scm.AntStarTeamCheckOut 1.41 +3 -2 ant/docs/manual/optionaltasklist.html Index: optionaltasklist.html =================================================================== RCS file: /home/cvs/ant/docs/manual/optionaltasklist.html,v retrieving revision 1.40 retrieving revision 1.41 diff -u -r1.40 -r1.41 --- optionaltasklist.html 2 Oct 2003 00:04:55 -0000 1.40 +++ optionaltasklist.html 22 Feb 2005 15:58:36 -0000 1.41 @@ -56,11 +56,12 @@ <a href="OptionalTasks/replaceregexp.html">ReplaceRegExp</a><br> <a href="OptionalTasks/rexec.html">RExec</a><br> <a href="OptionalTasks/rpm.html">Rpm</a><br> -<a href="OptionalTasks/serverdeploy.html">ServerDeploy</a><br> -<a href="OptionalTasks/setproxy.html">Setproxy</a><br> +<a href="OptionalTasks/schemavalidate.html">SchemaValidate</a><br> <a href="OptionalTasks/scp.html">Scp</a><br> <a href="OptionalTasks/script.html">Script</a><br> <a href="OptionalTasks/scriptdef.html">Scriptdef</a><br> +<a href="OptionalTasks/serverdeploy.html">ServerDeploy</a><br> +<a href="OptionalTasks/setproxy.html">Setproxy</a><br> <a href="OptionalTasks/sound.html">Sound</a><br> <a href="OptionalTasks/sos.html">SourceOffSite</a><br> <a href="OptionalTasks/splash.html">Splash</a><br>
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]