FileDocCategorySizeDatePackage
XMLValidateTask.javaAPI DocApache Ant 1.7023740Wed Dec 13 06:16:18 GMT 2006org.apache.tools.ant.taskdefs.optional

XMLValidateTask

public class XMLValidateTask extends org.apache.tools.ant.Task
Checks XML files are valid (or only well formed). The task uses the SAX2 parser implementation provided by JAXP by default (probably the one that is used by Ant itself), but one can specify any SAX1/2 parser if needed.

Fields Summary
private static final org.apache.tools.ant.util.FileUtils
FILE_UTILS
helper for path -> URI and URI -> path conversions.
protected static final String
INIT_FAILED_MSG
protected boolean
failOnError
protected boolean
warn
protected boolean
lenient
protected String
readerClassName
protected File
file
file to be validated
protected Vector
filesets
sets of file to be validated
protected org.apache.tools.ant.types.Path
classpath
protected XMLReader
xmlReader
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 ValidatorErrorHandler
errorHandler
private Vector
attributeList
The vector to store all attributes (features) to be set on the parser.
private final Vector
propertyList
List of properties.
private org.apache.tools.ant.types.XMLCatalog
xmlCatalog
public static final String
MESSAGE_FILES_VALIDATED
Message for sucessfull validation
Constructors Summary
Methods Summary
public voidaddConfiguredXMLCatalog(org.apache.tools.ant.types.XMLCatalog catalog)
add an XMLCatalog as a nested element; optional.

param
catalog XMLCatalog to use

        xmlCatalog.addConfiguredXMLCatalog(catalog);
    
public voidaddFileset(org.apache.tools.ant.types.FileSet set)
specify a set of file to be checked

param
set the fileset to check

        filesets.addElement(set);
    
public org.apache.tools.ant.taskdefs.optional.XMLValidateTask$AttributecreateAttribute()
Add an attribute nested element. This is used for setting arbitrary features of the SAX parser. Valid attributes include

return
attribute created
since
ant1.6

        final Attribute feature = new Attribute();
        attributeList.addElement(feature);
        return feature;
    
public org.apache.tools.ant.types.PathcreateClasspath()

see
#setClasspath
return
the classpath created

        if (this.classpath == null) {
            this.classpath = new Path(getProject());
        }
        return this.classpath.createPath();
    
public org.apache.tools.ant.types.DTDLocationcreateDTD()
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

        DTDLocation dtdLocation = new DTDLocation();
        xmlCatalog.addDTD(dtdLocation);
        return dtdLocation;
    
protected org.xml.sax.XMLReadercreateDefaultReader()
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

        return JAXPUtils.getXMLReader();
    
private java.lang.ObjectcreateDefaultReaderOrParser()

return

        Object reader;
        try {
            reader = createDefaultReader();
        } catch (BuildException exc) {
            reader = JAXPUtils.getParser();
        }
        return reader;
    
public org.apache.tools.ant.taskdefs.optional.XMLValidateTask$PropertycreateProperty()
Creates a property.

return
a property.
since
ant 1.6.2

        final Property prop = new Property();
        propertyList.addElement(prop);
        return prop;
    
protected org.xml.sax.XMLReadercreateXmlReader()
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.

return
the new XMLReader.

        Object reader = null;
        if (readerClassName == null) {
            reader = createDefaultReaderOrParser();
        } else {

            Class readerClass = null;
            try {
                // load the parser class
                if (classpath != null) {
                    AntClassLoader loader =
                        getProject().createClassLoader(classpath);
                    readerClass = Class.forName(readerClassName, true, loader);
                } else {
                    readerClass = Class.forName(readerClassName);
                }

                reader = readerClass.newInstance();
            } catch (ClassNotFoundException e) {
                throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
            } catch (InstantiationException e) {
                throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
            } catch (IllegalAccessException e) {
                throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
            }
        }

        // then check it implements XMLReader
        XMLReader newReader;
        if (reader instanceof XMLReader) {
            newReader = (XMLReader) reader;
            log(
                "Using SAX2 reader " + reader.getClass().getName(),
                Project.MSG_VERBOSE);
        } else {

            // see if it is a SAX1 Parser
            if (reader instanceof Parser) {
                newReader = new ParserAdapter((Parser) reader);
                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.");
            }
        }
        return newReader;
    
protected booleandoValidate(java.io.File afile)
parse the file

param
afile the file to validate.
return
true if the file validates.

        //for every file, we have a new instance of the validator
        initValidator();
        boolean result = true;
        try {
            log("Validating " + afile.getName() + "... ", Project.MSG_VERBOSE);
            errorHandler.init(afile);
            InputSource is = new InputSource(new FileInputStream(afile));
            String uri = FILE_UTILS.toURI(afile.getAbsolutePath());
            is.setSystemId(uri);
            xmlReader.parse(is);
        } catch (SAXException ex) {
            log("Caught when validating: " + ex.toString(), Project.MSG_DEBUG);
            if (failOnError) {
                throw new BuildException(
                    "Could not validate document " + afile);
            }
            log("Could not validate document " + afile + ": " + ex.toString());
            result = false;
        } catch (IOException ex) {
            throw new BuildException(
                "Could not validate document " + afile,
                ex);
        }
        if (errorHandler.getFailure()) {
            if (failOnError) {
                throw new BuildException(
                    afile + " is not a valid XML document.");
            }
            result = false;
            log(afile + " is not a valid XML document", Project.MSG_ERR);
        }
        return result;
    
public voidexecute()
execute the task

throws
BuildException if failonerror is true and an error happens


        int fileProcessed = 0;
        if (file == null && (filesets.size() == 0)) {
            throw new BuildException(
                "Specify at least one source - " + "a file or a fileset.");
        }



        if (file != null) {
            if (file.exists() && file.canRead() && file.isFile()) {
                doValidate(file);
                fileProcessed++;
            } else {
                String errorMsg = "File " + file + " cannot be read";
                if (failOnError) {
                    throw new BuildException(errorMsg);
                } else {
                    log(errorMsg, Project.MSG_ERR);
                }
            }
        }

        for (int i = 0; i < filesets.size(); i++) {

            FileSet fs = (FileSet) filesets.elementAt(i);
            DirectoryScanner ds = fs.getDirectoryScanner(getProject());
            String[] files = ds.getIncludedFiles();

            for (int j = 0; j < files.length; j++) {
                File srcFile = new File(fs.getDir(getProject()), files[j]);
                doValidate(srcFile);
                fileProcessed++;
            }
        }
        onSuccessfulValidation(fileProcessed);
    
protected org.xml.sax.EntityResolvergetEntityResolver()
accessor to the xmlCatalog used in the task

return
xmlCatalog reference

        return xmlCatalog;
    
protected org.xml.sax.XMLReadergetXmlReader()
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.

        return xmlReader;
    
public voidinit()
Called by the project to let the task initialize properly.

exception
BuildException if something goes wrong with the build

        super.init();
        xmlCatalog.setProject(getProject());
    
protected voidinitValidator()
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


        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());
            }
        }
    
protected booleanisSax1Parser()
test that returns true if we are using a SAX1 parser.

return
true when a SAX1 parser is in use

        return (xmlReader instanceof ParserAdapter);
    
protected voidonSuccessfulValidation(int fileProcessed)
handler called on successful file validation.

param
fileProcessed number of files processed.

        log(fileProcessed + MESSAGE_FILES_VALIDATED);
    
public voidsetClassName(java.lang.String className)
Specify the class name of the SAX parser to be used. (optional)

param
className should be an implementation of SAX2 org.xml.sax.XMLReader or SAX2 org.xml.sax.Parser.

if className is an implementation of org.xml.sax.Parser, {@link #setLenient(boolean)}, will be ignored.

if not set, the default will be used.

see
org.xml.sax.XMLReader
see
org.xml.sax.Parser

        readerClassName = className;
    
public voidsetClasspath(org.apache.tools.ant.types.Path classpath)
Specify the classpath to be searched to load the parser (optional)

param
classpath the classpath to load the parser

        if (this.classpath == null) {
            this.classpath = classpath;
        } else {
            this.classpath.append(classpath);
        }
    
public voidsetClasspathRef(org.apache.tools.ant.types.Reference r)
Where to find the parser class; optional.

see
#setClasspath
param
r reference to a classpath defined elsewhere

        createClasspath().setRefid(r);
    
public voidsetFailOnError(boolean fail)
Specify how parser error are to be handled. Optional, default is true.

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


                                               
        
        failOnError = fail;
    
protected voidsetFeature(java.lang.String feature, boolean value)
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

        log("Setting feature " + feature + "=" + value, Project.MSG_DEBUG);
        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());
        }
    
public voidsetFile(java.io.File file)
specify the file to be checked; optional.

param
file the file to be checked

        this.file = file;
    
public voidsetLenient(boolean bool)
Specify whether the parser should be validating. Default is true.

If set to false, the validation will fail only if the parsed document is not well formed XML.

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

        lenient = bool;
    
protected voidsetProperty(java.lang.String name, java.lang.String value)
Sets a property.

param
name a property name
param
value a property value.
throws
BuildException if an error occurs.
throws
BuildException if the property was not supported

        // 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());
        }
    
public voidsetWarn(boolean bool)
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

        warn = bool;