ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dona...@apache.org
Subject cvs commit: jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional XMLValidateTask.java
Date Tue, 10 Apr 2001 04:47:00 GMT
donaldp     01/04/09 21:47:00

  Modified:    docs/manual optionaltasklist.html
               src/main/org/apache/tools/ant/taskdefs defaults.properties
  Added:       docs/manual/OptionalTasks xmlvalidate.html
               src/main/org/apache/tools/ant/taskdefs/optional
                        XMLValidateTask.java
  Log:
  Added in xmlvalidate task
  
  Submitted By: Raphael PIERQUIN <pierquin@agisphere.com>
  
  Revision  Changes    Path
  1.11      +1 -0      jakarta-ant/docs/manual/optionaltasklist.html
  
  Index: optionaltasklist.html
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/docs/manual/optionaltasklist.html,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- optionaltasklist.html	2001/04/10 04:29:05	1.10
  +++ optionaltasklist.html	2001/04/10 04:47:00	1.11
  @@ -43,6 +43,7 @@
   <a href="OptionalTasks/vssget.html">VssGet</a><br>
   <a href="OptionalTasks/vsshistory.html">VssHistory</a><br>
   <a href="OptionalTasks/vsslabel.html">VssLabel</a><br>
  +<a href="OptionalTasks/xmlvalidate.html">XmlValidate</a><br>
   
   </body>
   </html>
  
  
  
  1.1                  jakarta-ant/docs/manual/OptionalTasks/xmlvalidate.html
  
  Index: xmlvalidate.html
  ===================================================================
  <html>
  
  <head>
  <title>XMLValidate Task</title>
  </head>
  
  <body>
  
  <h2><a name="xmlvalidate">XMLValidate</a></h2>
  <h3>Description</h3>
  <p>
    This task checks xml files are valid (or only well formed). The task uses crimson SAX2
parser implementation by default, but one can specify any SAX1/2 parser if needed
  </p>
  
  <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">lenient</td>
      <td valign="top">
        if true, only check the xml document is well formed
  	    (ignored if the specified parser is as SAX1 parser)
      </td>
      <td valign="top" align="center">No</td>
    </tr>
    <tr>
      <td valign="top">classname</td>
      <td valign="top">the parser to use. (default: crimson).</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
classpath 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>Examples</h3>
  <blockquote><pre>
  &lt;xmlvalidate file="toto.xml"/&gt;
  
      &lt;xmlvalidate failonerror="no" lenient="yes" warn="yes"
  	         classname="org.apache.xerces.parsers.SAXParser" &gt;
  	         classpath="lib/xerces.jar"&gt;
          &lt;fileset dir="src" includes="style/*.xsl"/&gt;  
      &lt;/xmlvalidate&gt;
  </pre></blockquote>
  <hr>
  
  <p align="center">Copyright &copy; 2000,2001 Apache Software Foundation. All rights
  Reserved.</p>
  
  </body>
  </html>
  
  
  
  
  1.70      +1 -0      jakarta-ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties
  
  Index: defaults.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties,v
  retrieving revision 1.69
  retrieving revision 1.70
  diff -u -r1.69 -r1.70
  --- defaults.properties	2001/04/10 04:29:06	1.69
  +++ defaults.properties	2001/04/10 04:47:00	1.70
  @@ -96,6 +96,7 @@
   vsshistory=org.apache.tools.ant.taskdefs.optional.vss.MSVSSHISTORY
   blgenclient=org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient
   rpm=org.apache.tools.ant.taskdefs.optional.Rpm
  +xmlvalidate=org.apache.tools.ant.taskdefs.optional.XMLValidateTask
   
   # deprecated ant tasks (kept for back compatibility)
   javadoc2=org.apache.tools.ant.taskdefs.Javadoc
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java
  
  Index: XMLValidateTask.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.tools.ant.taskdefs.optional;
  
  import java.io.File;
  import java.io.FileReader;
  import java.io.IOException;
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.Vector;
  import org.apache.tools.ant.AntClassLoader;
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.DirectoryScanner;
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.Task;
  import org.apache.tools.ant.types.FileSet;
  import org.apache.tools.ant.types.Path;
  import org.apache.tools.ant.types.Reference;
  import org.xml.sax.ErrorHandler;
  import org.xml.sax.InputSource;
  import org.xml.sax.Parser;
  import org.xml.sax.SAXException;
  import org.xml.sax.SAXNotRecognizedException;
  import org.xml.sax.SAXNotSupportedException;
  import org.xml.sax.SAXParseException;
  import org.xml.sax.XMLReader;
  import org.xml.sax.helpers.ParserAdapter;
  
  /** 
   * The <code>XMLValidateTask</code> checks that an XML document is valid,
   * with a SAX validating parser.
   * @author Raphael Pierquin <a href="mailto:raphael.pierquin@agisphere.com">raphael.pierquin@agisphere.com</a>
   */
  public class XMLValidateTask extends Task {
  
      /**
       * The default implementation parser classname used by the task to process
       * validation.
       */
      // The crimson implementation is shipped with ant.
      public static String DEFAULT_XML_READER_CLASSNAME= "org.apache.crimson.parser.XMLReaderImpl";
  
      protected static String INIT_FAILED_MSG = "Could'nt start xml validation: ";
  
      // ant task properties
      // defaults
      protected boolean failOnError = true;
      protected boolean warn = true;
      protected boolean lenient = false;
      protected String  readerClassName = DEFAULT_XML_READER_CLASSNAME;
      
      protected File file = null; // file to be validated
      protected Vector filesets = new Vector(); // sets of file to be validated
      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 Hashtable features = new Hashtable();
  
  
      /**
       * Specify how parser error are to be handled.
       * <p>
       * If set to <code>true</code> (default), throw a buildException if the
parser yields an error.
       */
      public void setFailOnError(boolean fail) {
          
          failOnError = fail;
      }
  
      /**
       * 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.
       */
      public void setWarn(boolean bool) {
          
          warn = bool;
      }
  
      /**
       * Specify whether the parser should be validating. Default is <code>true</code>.
       * <p>
       * If set to false, the validation will fail only if the parsed document is not well
formed XML.
       * <p>
       * this option is ignored if the specified class with {@link #setClassName(String)}
is not a SAX2
       * XMLReader.
       */
      public void setLenient(boolean bool) {
  
          lenient = bool;
      }
      
      /**
       * Specify the class name of the SAX parser to be used. (optional)
       * @param className should be an implementation of SAX2 <code>org.xml.sax.XMLReader</code>
       * or SAX2 <code>org.xml.sax.Parser</code>.
       * <p> if className is an implementation of <code>org.xml.sax.Parser</code>,
{@link #setLenient(boolean)},
       * will be ignored.
       * <p> if not set, the default {@link #DEFAULT_XML_READER_CLASSNAME} will be used.
       * @see org.xml.sax.XMLReader;
       * @see org.xml.sax.Parser;
       */
      public void setClassName(String className) {
          
          readerClassName = className;
      }
  
  
      /**
       * Specify the classpath to be searched to load the parser (optional)
       */
      public void setClasspath(Path classpath) {
  
          if (this.classpath == null) {
              this.classpath = classpath;
          } else {
              this.classpath.append(classpath);
          }
      }
  
      /**
       * @see #setClassPath
       */
      public Path createClasspath() {
          if (this.classpath == null) {
              this.classpath = new Path(project);
          }
          return this.classpath.createPath();
      }
  
      /**
       * @see #setClassPath
       */
      public void setClasspathRef(Reference r) {
          createClasspath().setRefid(r);
      }
  
      /**
       * specifify the file to be checked
       */
      public void setFile(File file) {
          this.file = file;
      }
  
      /**
       * specifify a set of file to be checked
       */
      public void addFileset(FileSet set) {
          filesets.addElement(set);
      }
  
      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.");
          }
  
          initValidator();
  
          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(project);
              String[] files = ds.getIncludedFiles();
              
              for (int j=0; j < files.length ; j++)  {
                  File srcFile = new File(fs.getDir(project), files[j]);
                  doValidate(srcFile);
                  fileProcessed++;
              }
          }
          log(fileProcessed + " file(s) have been successfully validated.");
      }
  
      /**
       * init the parser :
       * load the parser class, and set features if necessary
       */
      private void initValidator() {
  
          try {
              // load the parser class
              // with JAXP, we would use a SAXParser factory
              Class readerClass= null;
              //Class readerImpl = null;
              //Class parserImpl = null;
              if (classpath != null) {
                  AntClassLoader loader = new AntClassLoader(project, classpath, false);
                  loader.addSystemPackageRoot("org.xml"); // needed to avoid conflict
                  readerClass = loader.loadClass(readerClassName);
                  //readerImpl  = loader.loadClass(
              } else 
                  readerClass = Class.forName(readerClassName);
              
              // then check it implements XMLReader
              if (XMLReader.class.isAssignableFrom(readerClass)) {
  
                  xmlReader = (XMLReader) readerClass.newInstance();
                  log("Using SAX2 reader " + readerClassName, Project.MSG_VERBOSE);
              } else {
                  
                  // see if it is a SAX1 Parser
                  if (Parser.class.isAssignableFrom(readerClass)) {
                      Parser parser = (Parser) readerClass.newInstance();
                      xmlReader = new ParserAdapter(parser);
                      log("Using SAX1 parser " + readerClassName, Project.MSG_VERBOSE);
                  }  else {
                      throw new BuildException(INIT_FAILED_MSG
                                               + readerClassName
                                               + " implements nor SAX1 Parser nor SAX2 XMLReader.");
                  }
              }
          } 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);
          }
  
          xmlReader.setErrorHandler(errorHandler);
          
          if (! (xmlReader instanceof ParserAdapter)) {
              // turn validation on
              if (! lenient) {
                  boolean ok = setFeature("http://xml.org/sax/features/validation",true,true);
                  if (! ok) {
                      throw new BuildException(INIT_FAILED_MSG
                                               + readerClassName
                                               + " doesn't provide validation");
                  }
              }
              // set other features
              Enumeration enum = features.keys();
              while(enum.hasMoreElements()) {
                  String featureId = (String) enum.nextElement();
                  setFeature(featureId, ((Boolean) features.get(featureId)).booleanValue(),
true);
              }
          }
      }
  
      /*
       * set a feature on the parser.
       * TODO: find a way to set any feature from build.xml
       */
      private boolean setFeature(String feature, boolean value, boolean warn) {
  
          boolean  toReturn = false;
          try {
              xmlReader.setFeature(feature,value);
              toReturn = true;
          } catch (SAXNotRecognizedException e) {
              if (warn)
                  log("Could'nt set feature '"
                      + feature
                      + "' because the parser doesn't recognize it", 
                      Project.MSG_WARN);
          } catch (SAXNotSupportedException  e) {
              if (warn)
                  log("Could'nt set feature '"
                      + feature 
                      + "' because the parser doesn't support it",
                      Project.MSG_WARN);
          }
          return toReturn;
      }
      /*
       * parse the file
       */
      private void doValidate(File afile) {
          try {
              log("Validating " + afile.getName() + "... ", Project.MSG_VERBOSE);
              errorHandler.init(afile);
              xmlReader.parse(new InputSource(new FileReader(afile)));
          } catch (SAXException ex) {
              if (failOnError)
                  throw new BuildException("Could'nt validate document " + afile);
          } catch (IOException ex) {
              throw new BuildException("Could'nt validate document " + afile, ex);
          }
          
          if (errorHandler.getFailure()) {
              if (failOnError)
                  throw new BuildException(afile + " is not a valid XML document.");
              else
                  log(afile + " is not a valid XML document",Project.MSG_ERR);
          }        
      }
  
      /*
       * ValidatorErrorHandler role : 
       * <ul>
       * <li> log SAX parse exceptions,
       * <li> remember if an error occured
       * </ul>
       */
      protected class ValidatorErrorHandler implements ErrorHandler {
          
          protected File currentFile = null;
          protected String lastErrorMessage = null;
          protected boolean failed = false;
          
          public void init(File file) {
              currentFile = file;
              failed = false;
          }
          
          // did an error happen during last parsing ?
          public boolean getFailure() {
              
              return failed;
          }
  
          public void fatalError(SAXParseException exception) {
  
              failed = true;
              doLog(exception,Project.MSG_ERR);
          }
  
          public void error(SAXParseException exception) {
  
              failed = true;
              doLog(exception,Project.MSG_ERR);
          }
          
          public void warning(SAXParseException exception) {
              // depending on implementation, XMLReader can yield hips of warning, 
              // only output then if user explicitely asked for it
              if (warn)
                  doLog(exception,Project.MSG_WARN);
          }
          
          private void doLog(SAXParseException e, int logLevel) {
              
              log(getMessage(e), logLevel);
          }
  
          private String getMessage(SAXParseException e) {
  
              return currentFile + ":" + e.getLineNumber() + ": " + e.getMessage();
          }
      }
  }
  
  
  

Mime
View raw message