package com.thaiopensource.relaxng.util;

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.taskdefs.LogOutputStream;
import org.apache.tools.ant.types.FileSet;
import org.xml.sax.SAXException;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Vector;


/**
 * Ant task to validate XML files using RELAX NG.
 */

public class JingTask extends Task {

  private File schemaFile;
  private File src;
  private final Vector filesets = new Vector();
  private int flags = ValidationEngine.CHECK_ID_IDREF;

  public void execute() throws BuildException {
    if (schemaFile == null)
      throw new BuildException("There must be an rngFile or schemaFile attribute", 
			       location);
    if (src == null && filesets.size() == 0)
      throw new BuildException("There must be a file attribute or a fileset child element",
			       location);

    ErrorHandlerImpl eh = new ErrorHandlerImpl(new PrintStream(new LogOutputStream(this, Project.MSG_WARN)));

    boolean hadError = false;

    try {
      ValidationEngine engine = new ValidationEngine(new Jaxp11XMLReaderCreator(), eh, flags);
      if (!engine.loadSchema(ValidationEngine.fileInputSource(schemaFile)))
	hadError = true;
      else {
	if (src != null) {
	  if (!engine.validate(ValidationEngine.fileInputSource(src)))
	    hadError = true;
	}
	for (int i = 0; i < filesets.size(); i++) {
	  FileSet fs = (FileSet)filesets.elementAt(i);
	  DirectoryScanner ds = fs.getDirectoryScanner(project);
	  File dir = fs.getDir(project);
	  String[] srcs = ds.getIncludedFiles();
	  for (int j = 0; j < srcs.length; j++) {
	    if (!engine.validate(ValidationEngine.fileInputSource(new File(dir, srcs[j]))))
	      hadError = true;
	  }
	}
      }
    }
    catch (SAXException e) {
      hadError = true;
      eh.printException(e);
    }
    catch (IOException e) {
      hadError = true;
      eh.printException(e);
    }
    if (hadError)
      throw new BuildException("Validation failed, messages should have been provided.", location);
  }

  /**
   * Handles the <code>rngfile</code> attribute.
   *
   * @param rngFilename the attribute value
   */
  public void setRngfile(String rngFilename) {
    schemaFile = project.resolveFile(rngFilename);
  }

  /**
   * Handles the <code>schemafile</code> attribute.
   *
   * @param schemaFilename the attribute value
   */
  public void setSchemafile(String schemaFilename) {
    schemaFile = project.resolveFile(schemaFilename);
  }

  public void setFile(File file) {
    this.src = file;
  }

  /**
   * Handles the <code>checkid</code> attribute.
   *
   * @param checkid the attribute value converted to a boolean
   */
  public void setCheckid(boolean checkid) {
    if (checkid)
      flags |= ValidationEngine.CHECK_ID_IDREF;
    else
      flags &= ~ValidationEngine.CHECK_ID_IDREF;
  }

  /**
   * Handles the <code>compactsyntax</code> attribute.
   *
   * @param compactsyntax the attribute value converted to a boolean
   */
  public void setCompactsyntax(boolean compactsyntax) {
    if (compactsyntax)
      flags |= ValidationEngine.COMPACT_SYNTAX;
    else
      flags &= ~ValidationEngine.COMPACT_SYNTAX;
  }

  /**
   * Handles the <code>feasible</code> attribute.
   *
   * @param feasible the attribute value converted to a boolean
   */
  public void setFeasible(boolean feasible) {
    if (feasible)
      flags |= ValidationEngine.FEASIBLE;
    else
      flags &= ~ValidationEngine.FEASIBLE;
  }

  public void addFileset(FileSet set) {
    filesets.addElement(set);
  }

}

@@ -229,74 +229,53 @@
 nt.t
-askdefs.LogOutputStream;%0Aimport org.apache.tools.ant.types.FileSet
+ypes.FileSet;%0Aimport org.xml.sax.SAXException
 ;%0Aim
@@ -286,32 +286,37 @@
  org.xml.sax.SAX
+Parse
 Exception;%0A%0Aimpo
@@ -364,36 +364,8 @@
 on;%0A
-import java.io.PrintStream;%0A
 impo
@@ -633,16 +633,595 @@
 D_IDREF;
+%0A  private boolean failOnError = true;%0A%0A  private class LogErrorHandler extends ErrorHandlerImpl %7B%0A    int logLevel = Project.MSG_ERR;%0A%0A    public void warning(SAXParseException e) throws SAXParseException %7B%0A      logLevel = Project.MSG_WARN;%0A      super.warning(e);%0A    %7D%0A%0A    public void error(SAXParseException e) %7B%0A      logLevel = Project.MSG_ERR;%0A      super.error(e);%0A    %7D%0A%0A    public void printException(Throwable e) %7B%0A      logLevel = Project.MSG_ERR;%0A      super.printException(e);%0A    %7D%0A%0A    public void print(String message) %7B%0A      log(message, logLevel);%0A    %7D%0A  %7D
 %0A%0A  publ
@@ -1372,17 +1372,16 @@
 ribute%22,
- 
 %0A%09%09%09    
@@ -1583,16 +1583,19 @@
 h = new 
+Log
 ErrorHan
@@ -1602,73 +1602,9 @@
 dler
-Impl(new PrintStream(new LogOutputStream(this, Project.MSG_WARN))
+(
 );%0A%0A
@@ -2543,16 +2543,31 @@
 hadError
+ && failOnError
 )%0A      
@@ -4089,24 +4089,254 @@
 SIBLE;%0A  %7D%0A%0A
+  /**%0A   * Handles the %3Ccode%3Efailonerror%3C/code%3E attribute.%0A   *%0A   * @param failOnError the attribute value converted to a boolean%0A   */%0A  public void setFailonerror(boolean failOnError) %7B%0A    this.failOnError = failOnError;%0A  %7D%0A%0A
   public voi

Implement failonerror attribute. Better approach to logging.