diff --git a/docs/manual/OptionalTasks/schemavalidate.html b/docs/manual/OptionalTasks/schemavalidate.html new file mode 100644 index 000000000..344ca0d0a --- /dev/null +++ b/docs/manual/OptionalTasks/schemavalidate.html @@ -0,0 +1,310 @@ + + + +SchemaValidate Task + + + + +

SchemaValidate

+

Description

+ +

This task validates XML files described by an XML Schema. +The task extends the XmlValidate task with XSD-specific features.

+
    +
  1. The parser is created validating and namespace aware +
  2. +
  3. Validation is turned on.
  4. +
  5. and Schema validation is turned on.
  6. +
  7. Any default schema supplied is used as the no-namespace schema +
  8. All nested schema declarations are turned into the list of namespace-url +bindings for schema lookup. +
+ +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. + +

This task supports the use of nested +

  • <xmlcatalog> elements
  • +
  • <schema> elements, that bind a namespace URI to a URL or a + local filename. +
  • <dtd> elements which are used to resolve DTDs and entities.
  • +
  • <attribute> elements which are used to set features on the parser. + These can be any number of + http://xml.org/sax/features/ + or other features that your parser may support.
  • +
  • <property> elements, containing string properties +

    + +

    +The task only supports SAX2 or later parsers: it is an error to specify a SAX1 +parser. + + +

    Parameters

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionRequired
    filethe file(s) you want to check. (optionally can use an embedded fileset)No
    defaultSchemaFile + filename of a no-namespace XSD file to provide the + schema for no-namespace XML content. + No
    noNamespaceURL + URL of a no-namespace XSD file to provide the + schema for no-namespace XML content. + No
    noNamespaceFile + filename of a no-namespace XSD file to provide the + schema for no-namespace XML content. + No
    fullchecking + enable full schema checking. Slow but strict. + No - default true
    lenient + if true, only check the XML document is well formed + No
    classnamethe parser to use.No
    classpathrefwhere to find the parser class. + Optionally can use an embedded <classpath> element.No
    failonerrorfails on a error if set to true (defaults to true).No
    warnlog parser warn events.No
    + +

    Nested Elements

    + + +

    schema

    +

    +Identify the name and location of a schema that may be used in validating +the document(s). +

    + + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionRequired
    namespaceURI of the schema namespaceYes
    urlURL of the schemaOne of url or file is required
    filefile of the schemaOne of url or file is required
    + +

    dtd

    +

    +<dtd> is used to specify different locations for DTD resolution. +

    + + + + + + + + + + + + + + + + +
    AttributeDescriptionRequired
    publicIdPublic ID of the DTD to resolveYes
    locationLocation of the DTD to use, which can be a file, + a resource, or a URLYes
    +

    xmlcatalog

    +

    The <xmlcatalog> +element is used to perform entity resolution.

    +

    attribute

    +

    The <attribute> element is used to set parser features.
    +Features usable with the xerces parser are defined here : + Setting features
    + +SAX features are defined here: + http://xml.org/sax/features/
    +

    + + + + + + + + + + + + + + + + +
    AttributeDescriptionRequired
    nameThe name of the featureYes
    valueThe boolean value of the featureYes
    +

    + +

    property

    +

    The <property> element is used to set properties. +These properties are defined here for the xerces XML parser implementation : + XML Parser properties +Properties can be used to set the schema used to validate the XML file. +

    + + + + + + + + + + + + + + + + +
    AttributeDescriptionRequired
    nameThe name of the featureYes
    valueThe string value of the propertyYes
    +

    + + +

    Examples

    +
    +<xmlvalidate file="toto.xml"/>
    +
    +Validate toto.xml +
    +<xmlvalidate failonerror="no" lenient="yes" warn="yes"
    +             classname="org.apache.xerces.parsers.SAXParser">
    +             classpath="lib/xerces.jar">
    +  <fileset dir="src" includes="style/*.xsl"/>
    +</xmlvalidate>
    +
    +Validate all .xsl files in src/style, but only warn if there is an error, rather than +halt the build. +
    +
    +<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>
    +
    + +Validate a struts configuration, using a local copy of the DTD. +
     
    +<xmlvalidate failonerror="no">
    +  <fileset dir="${project.dir}" includes="**/*.xml"/>
    +  <xmlcatalog refid="mycatalog"/>
    +</xmlvalidate>
    +
    + +Scan all XML files in the project, using a predefined catalog to map URIs to local files. +
    +<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>
    +
    +Scan all XML files in the project, using the catalog defined inline. + +
    +<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>
    +
    +Validate all .xml files in xml directory with the parser configured to perform schema validation. Note: The parser must support the +
    http://apache.org/xml/features/validation/schema
    feature. + +
    +
    +
    +<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>
    +
    +
    +Validate the file xml/endpiece-noSchema.xml against the schema xml/doc.xsd. +
    +
    +

    Copyright © 2001-2002,2004 The Apache Software Foundation. All rights +Reserved.

    + + + + diff --git a/docs/manual/optionaltasklist.html b/docs/manual/optionaltasklist.html index bcf3339ee..9e4a3082c 100644 --- a/docs/manual/optionaltasklist.html +++ b/docs/manual/optionaltasklist.html @@ -56,11 +56,12 @@ ReplaceRegExp
    RExec
    Rpm
    -ServerDeploy
    -Setproxy
    +SchemaValidate
    Scp
    Script
    Scriptdef
    +ServerDeploy
    +Setproxy
    Sound
    SourceOffSite
    Splash
    diff --git a/src/etc/testcases/taskdefs/optional/schemavalidate.xml b/src/etc/testcases/taskdefs/optional/schemavalidate.xml new file mode 100644 index 000000000..3c7dac684 --- /dev/null +++ b/src/etc/testcases/taskdefs/optional/schemavalidate.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/etc/testcases/taskdefs/optional/xml/doc-in-ns.xsd b/src/etc/testcases/taskdefs/optional/xml/doc-in-ns.xsd new file mode 100644 index 000000000..3d4449050 --- /dev/null +++ b/src/etc/testcases/taskdefs/optional/xml/doc-in-ns.xsd @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/etc/testcases/taskdefs/optional/xml/endpiece-ns-no-location.xml b/src/etc/testcases/taskdefs/optional/xml/endpiece-ns-no-location.xml new file mode 100644 index 000000000..a566662ad --- /dev/null +++ b/src/etc/testcases/taskdefs/optional/xml/endpiece-ns-no-location.xml @@ -0,0 +1,7 @@ + + +
    + 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.xml b/src/etc/testcases/taskdefs/optional/xml/endpiece.xml index e00470f30..a566662ad 100644 --- a/src/etc/testcases/taskdefs/optional/xml/endpiece.xml +++ b/src/etc/testcases/taskdefs/optional/xml/endpiece.xml @@ -1,8 +1,6 @@ - -
    + +
    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 985a20aa3..b2ec73eba 100644 --- a/src/etc/testcases/taskdefs/optional/xmlvalidate.xml +++ b/src/etc/testcases/taskdefs/optional/xmlvalidate.xml @@ -175,5 +175,18 @@ + + + + + + + + + diff --git a/src/main/org/apache/tools/ant/taskdefs/defaults.properties b/src/main/org/apache/tools/ant/taskdefs/defaults.properties index c1f7aa797..fc41144f6 100644 --- a/src/main/org/apache/tools/ant/taskdefs/defaults.properties +++ b/src/main/org/apache/tools/ant/taskdefs/defaults.properties @@ -206,6 +206,7 @@ rexec=org.apache.tools.ant.taskdefs.optional.net.RExecTask 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 diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/SchemaValidate.java b/src/main/org/apache/tools/ant/taskdefs/optional/SchemaValidate.java new file mode 100644 index 000000000..ca8477a63 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/SchemaValidate.java @@ -0,0 +1,361 @@ +/* + * 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, {@link 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 + * JAXP 1.2 Approved CHANGES + * @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 {@link 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 +} 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 bdf57de24..d1f8d4a76 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java @@ -33,6 +33,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.apache.tools.ant.util.XmlConstants; import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; @@ -258,6 +259,19 @@ public class XMLValidateTask extends Task { protected EntityResolver getEntityResolver() { return xmlCatalog; } + + /** + * get the XML reader. Non-null only after {@link #initValidator()}. + * If the reader is an instance of {@link ParserAdapter} then + * the parser is a SAX1 parser, and you cannot call + * {@link #setFeature(String, boolean)} or {@link #setProperty(String, String)} + * on it. + * @return the XML reader or null. + */ + protected XMLReader getXmlReader() { + return xmlReader; + } + /** * execute the task * @throws BuildException if failonerror is true and an error happens @@ -304,16 +318,56 @@ public class XMLValidateTask extends Task { /** * 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 {@link #readerClassName}, + * falling back to a default reader if not. + * If the returned reader is an instance of {@link 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 @@ public class XMLValidateTask extends Task { } // 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 @@ public class XMLValidateTask extends Task { // 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 @@ public class XMLValidateTask extends Task { + " 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 @@ public class XMLValidateTask extends Task { * @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 @@ public class XMLValidateTask extends Task { /** * 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 @@ public class XMLValidateTask extends Task { } // Property + + } diff --git a/src/main/org/apache/tools/ant/util/XmlConstants.java b/src/main/org/apache/tools/ant/util/XmlConstants.java new file mode 100644 index 000000000..39f060a06 --- /dev/null +++ b/src/main/org/apache/tools/ant/util/XmlConstants.java @@ -0,0 +1,47 @@ +/* + * 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 Xerces features + * @see Xerces properties + * @see SAX. + */ + +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"; +} diff --git a/src/testcases/org/apache/tools/ant/taskdefs/optional/SchemaValidateTest.java b/src/testcases/org/apache/tools/ant/taskdefs/optional/SchemaValidateTest.java new file mode 100644 index 000000000..1fe811d9b --- /dev/null +++ b/src/testcases/org/apache/tools/ant/taskdefs/optional/SchemaValidateTest.java @@ -0,0 +1,63 @@ +/* + * 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"); + } + +}