
import java.io.File;
import java.io.IOException;
import org.w3c.dom.Document;
import org.apache.xerces.parsers.DOMParser;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.ErrorHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;

public class Validator implements ErrorHandler, EntityResolver
  {
  protected int warnings_ = 0;
  protected int errors_ = 0;
  protected int fatalErrors_ = 0;
  
  protected void reportException
    (
    String serverity,
    SAXParseException exception
    )
    {
    String msg = "[" + serverity + "] " + exception.getSystemId() +
      " " + exception.getLineNumber() + ":" + exception.getColumnNumber() +
      " " + exception.getMessage();
    System.out.println( msg );
    //exception.printStackTrace();
    }
    
  public void warning(SAXParseException exception)
    throws SAXException
    {
    reportException("warning", exception);
    ++warnings_;
    }
    
  public void error(SAXParseException exception)
    throws SAXException
    {
    reportException("error", exception);
    ++errors_;
    }
    
  public void fatalError(SAXParseException exception)
    throws SAXException
    {
    reportException("fatalError", exception);
    ++fatalErrors_;
    }
    
  public boolean isValid()
    {
    boolean valid = errors_ == 0 && fatalErrors_ == 0;
    return valid;
    }
   
  public void report()
    {
    System.out.println("warnings:    " + warnings_);
    System.out.println("errors:      " + errors_);
    System.out.println("fatalErrors: " + fatalErrors_);
    if (isValid())
      System.out.println("document is valid");
    else
      System.out.println("document is invalid");
    }
    
  public static void usage()
    {
    System.out.println("usage: Validator filename");
    }

  public InputSource resolveEntity
    (
    String publicId,
    String systemId
    )
    throws SAXException,java.io.IOException
    {
    String msg = new String("Entity: ");
    
    if (publicId != null)
      {
      msg += "publicId=" + publicId + " ";
      }
      
    if (systemId != null)
      {
      msg += "systemId=" + systemId;
      }
     
    System.out.println( msg );
    
    // use the default behaviour
    return null;
    }

  public static void main
    (
    String[] args
    )
    throws Exception
    {
    int exitCode = 1;
    
    if (args.length != 1)
      {
      usage();
      System.exit(1);
      }
      
    String filename = args[0];
    
    Validator validator = new Validator();
    DOMParser parser = new DOMParser();
    parser.setErrorHandler(  validator );
    parser.setEntityResolver( validator );
    
    try 
      {
      parser.setFeature("http://xml.org/sax/features/validation", true);
      parser.setFeature("http://xml.org/sax/features/namespaces", true);
      parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
      }
    catch(  org.xml.sax.SAXNotRecognizedException e ) 
      {
      e.printStackTrace();
      }
    catch( org.xml.sax.SAXNotSupportedException e ) 
      {
      e.printStackTrace();
      }

    Document doc = null;
    try 
      {
      parser.parse( filename );
      doc = parser.getDocument();
      }
    catch( IOException e ) 
      {
      e.printStackTrace();
      System.exit(1);
      }
    catch( SAXException e ) 
      {
      e.printStackTrace();
      System.exit(1);
      }

    validator.report();
    if (validator.isValid())
      {
      exitCode = 0;
      }
      
    System.exit(exitCode);
    }
  }  

