// validating a JNLP document with an XSD schema

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import javax.xml.XMLConstants;
import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
  * Validate on JNLP file using the Vampqh JNLP XSD schema
  * Requires a copy of the Vampqh schema "jnlp1-xml-schema.xsd" version 1.0
  * or "jnlp6-xml-schema.xsd" version 6.0 in the current directory.
  */
public class ValidateJNLP
   {
   /**
    * validate one jnlp file
    *
    * @param args first name of xsd schema,
    * second name of name of the jnlp file to validate,
    * e.g. E:\com\mindprod\affirm\affirm.jnlp
    */
   public static void main ( String[] args )
      {
      try
         {
         // build an XSD-aware SchemaFactory
         SchemaFactory schemaFactory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI );

         // hook up mindless org.xml.sax.ErrorHandler implementation.
         schemaFactory.setErrorHandler( new JNLPErrorHandler() );

         // get the custom xsd schema describing the required format for my XML files.
         Schema schemaXSD = schemaFactory.newSchema( new File ( args[0] ) );

         // Create a Validator capable of validating JNLP files according to to the custom schema.
         Validator validator = schemaXSD.newValidator();

         // Create a generic XML parser.
         DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();

         // parse the JNLP file on the command line purely as XML and get a DOM tree represenation.
         Document document = parser.parse( new File( args[1] ));

         // Validate the JNLP tree against the stricter XSD schema
         validator.validate( new DOMSource( document ) );
         }
      catch ( Exception e )
         {
         e.printStackTrace();
         }
      } // end main

   } // end ValidateJNLP

class JNLPErrorHandler implements ErrorHandler
   {
   /**
    * default contstructor
    */
   public JNLPErrorHandler()
      {
      }

   /**
    * Receive notification of a warning.
    *
    * <p>SAX parsers will use this method to report conditions that
    * are not errors or fatal errors as defined by the XML
    * recommendation.  The default behaviour is to take no
    * action.</p>
    *
    * <p>The SAX parser must continue to provide normal parsing events
    * after invoking this method: it should still be possible for the
    * application to process the document through to the end.</p>
    *
    * <p>Filters may use this method to report other, non-XML warnings
    * as well.</p>
    *
    * @param exception The warning information encapsulated in a
    *                  SAX parse exception.
    * @exception org.xml.sax.SAXException Any SAX exception, possibly
    *            wrapping another exception.
    * @see org.xml.sax.SAXParseException
    */
   public void warning (SAXParseException exception)
   throws SAXException
   {
      System.err.println( exception );
   }

   /**
    * Receive notification of a recoverable error.
    *
    * <p>This corresponds to the definition of "error" in section 1.2
    * of the W3C XML 1.0 Recommendation.  For example, a validating
    * parser would use this callback to report the violation of a
    * validity constraint.  The default behaviour is to take no
    * action.</p>
    *
    * <p>The SAX parser must continue to provide normal parsing
    * events after invoking this method: it should still be possible
    * for the application to process the document through to the end.
    * If the application cannot do so, then the parser should report
    * a fatal error even if the XML recommendation does not require
    * it to do so.</p>
    *
    * <p>Filters may use this method to report other, non-XML errors
    * as well.</p>
    *
    * @param exception The error information encapsulated in a
    *                  SAX parse exception.
    * @exception org.xml.sax.SAXException Any SAX exception, possibly
    *            wrapping another exception.
    * @see org.xml.sax.SAXParseException
    */
   public  void error (SAXParseException exception)
   throws SAXException
   {
      System.err.println( exception );
   }

   /**
    * Receive notification of a non-recoverable error.
    *
    * <p><strong>There is an apparent contradiction between the
    * documentation for this method and the documentation for {@link
    * org.xml.sax.ContentHandler#endDocument}.  Until this ambiguity
    * is resolved in a future major release, clients should make no
    * assumptions about whether endDocument() will or will not be
    * invoked when the parser has reported a fatalError() or thrown
    * an exception.</strong></p>
    *
    * <p>This corresponds to the definition of "fatal error" in
    * section 1.2 of the W3C XML 1.0 Recommendation.  For example, a
    * parser would use this callback to report the violation of a
    * well-formedness constraint.</p>
    *
    * <p>The application must assume that the document is unusable
    * after the parser has invoked this method, and should continue
    * (if at all) only for the sake of collecting additional error
    * messages: in fact, SAX parsers are free to stop reporting any
    * other events once this method has been invoked.</p>
    *
    * @param exception The error information encapsulated in a
    *                  SAX parse exception.
    * @exception org.xml.sax.SAXException Any SAX exception, possibly
    *            wrapping another exception.
    * @see org.xml.sax.SAXParseException
    */
   public  void fatalError (SAXParseException exception)
   throws SAXException
   {
      System.err.println( exception );
   }

   } // end JNLPErrorHandler