View Javadoc

1   /*
2   * This program is licensed under Common Public License Version 0.5.
3   *
4   * For License Information and conditions of use, see "LICENSE" in packaged
5   * 
6   * Change History (based on CVS versions):
7   * 
8   * Version:      Date:       Author:         Description:
9   * 1.1           2002/09/02  yuquing_wang    Initial revision
10  * 1.2           2003/11/14  ckoelle         Validation works for Xerces1 and Xerces2
11  * 1.3           2003/11/    ckoelle         Bug Fix: property xmlutil.validation.dom can be null 
12  */
13  package net.wangs.xmlutil;
14  
15  import javax.xml.parsers.*;
16  import org.w3c.dom.*;
17  import org.xml.sax.*;
18  import java.util.Properties;
19  import java.io.*;
20  
21  /***
22  * This XMLValidator is a tool to validate an XML file against its refenrenced XML Schema.
23  *
24  * <pre>
25  * Command line usage: 
26  *    java [-classpath &lt;path&gt;/xerces.jar:&lt;path&gt;/xalan.jar:&lt;path&gt;/jtestcase.jar] 
27  *         jtestcase.XMLValidator &lt;xml-file-name&gt;
28  *
29  * API usage: 
30  *    boolean valid = XMLValidator.validate(String fileName);
31  * </pre>
32  * @author <a href="mailto:yuqingwang_99@yahoo.com">Yuqing Wang</a>
33  */
34  
35  public class XMLValidator {
36  
37      protected static Properties _props;
38      protected static String mParserVersion;
39  
40      public static void main(String[] args) {
41  
42          if (args.length < 1) {
43              System.out.println("---Usage: java [-classpath <path>/xerces.jar:<path>/xalan.jar:<path>/jtestcase.jar]");
44              System.out.println("               jtestcase.XMLValidator <xml-file-name>\n");
45              return;
46          }
47  
48          String fileName = args[0];
49  
50          String use_dom = System.getProperty("xmlutil.validate.dom");
51          if (use_dom.equals("") || use_dom.equals("false"))
52              System.out.println("Using SAXParsing validation...");
53          else
54              System.out.println("Using DOM parsing validation...");
55  
56          boolean result = false;
57          try {
58              result = XMLValidator.validate(fileName);
59          } catch (Exception e) {
60              e.printStackTrace();
61              return;
62          }
63  
64          System.out.println("");
65          if (result)
66              System.out.println("---File " + fileName + " is a valid one!");
67          else
68              System.out.println("***File " + fileName + " is NOT valid!");
69  
70      }
71  
72      /*** 
73      * Prepares validating features from property file 
74      */
75      public XMLValidator() {
76          try {
77              _props = _loadProperties();
78              mParserVersion = System.getProperty("xmlutil.parser.version");
79          } catch (Exception e) {
80              e.printStackTrace();
81          }
82      }
83  
84      /***
85      * Validates XML file using either DOMBuilder or SAXParser, based on property 
86      * "USE_DOMBUILDER".
87      */
88      public static boolean validate(String fileName) throws XMLUtilException {
89  
90          XMLValidator me = new XMLValidator();
91  
92          InputStream is = null; 
93          try {
94              is = new FileInputStream(fileName);
95          } catch (FileNotFoundException e) {
96              // fails absolute path, will try relative path based on classpath
97          }
98  
99          if (is == null) {
100             is = me.getClass().getResourceAsStream( fileName );
101                         
102             if ( is == null ) {
103                 String msg = "***Error: " + fileName + " is missing";
104                 throw new XMLUtilException(msg);
105             }
106         }
107 
108         String use_dom = System.getProperty("xmlutil.validate.dom");
109         if (use_dom== null || use_dom.equals("") || use_dom.equals("false"))  
110             return me.validateWithSAXParser(is);
111         else
112             return me.validateWithDOMBuilder(is);
113     }
114  
115     /***
116     * Validates XML file using DOMBuilder.
117     */
118     public boolean validateWithDOMBuilder(InputStream is) {
119 
120         try {
121             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
122             factory.setValidating(true);
123             factory.setNamespaceAware(true);
124             if (mParserVersion != null && mParserVersion.compareTo("Xerces2") == 0) {
125                 factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
126             }
127             DocumentBuilder domBuilder = factory.newDocumentBuilder();
128             SAXErrorHandlerImpl error = new SAXErrorHandlerImpl();
129             domBuilder.setErrorHandler(error);
130 
131             Document dom = domBuilder.parse(is);
132             is.close();
133 
134             if (!dom.isSupported("Traversal", "2.0")) {
135                 // This cannot happen with the DOMParser...
136                 throw new RuntimeException("This DOM Document does not support Traversal");
137             }
138 
139             if ((error.getErrors()).size() > 0) 
140                 return false;
141             else 
142                 return true;
143 
144         } catch (Exception e) {
145             e.printStackTrace();
146             return false;
147         }
148     }
149 
150     /***
151     * Validates XML file using SAXParser.
152     */
153     public boolean validateWithSAXParser(InputStream is) {
154 
155         try {
156             SAXParserFactory factory = SAXParserFactory.newInstance();
157             factory.setFeature((String)_props.get("NAMESPACES_FEATURE_ID"), true);
158             factory.setFeature((String)_props.get("VALIDATION_FEATURE_ID"), true);
159             factory.setFeature((String)_props.get("SCHEMA_VALIDATION_FEATURE_ID"), true);
160             String schemaFullChecking = (String)_props.get("DEFAULT_SCHEMA_FULL_CHECKING");
161             if (schemaFullChecking.equals("true"))
162                 factory.setFeature((String)_props.get("SCHEMA_FULL_CHECKING_FEATURE_ID"), true);
163             else
164                 factory.setFeature((String)_props.get("SCHEMA_FULL_CHECKING_FEATURE_ID"), false);
165 
166             SAXParser parser = factory.newSAXParser();
167 
168             InputSource source = new InputSource(is);         
169             SAXErrorHandlerImpl error = new SAXErrorHandlerImpl();
170             parser.parse(source, error);
171             is.close();
172 
173             if ((error.getErrors()).size() > 0) 
174                 return false;
175             else 
176                 return true;
177 
178         } catch (Exception e) {
179             e.printStackTrace();
180             return false;
181         }
182     }
183 
184 
185     private Properties _loadProperties() throws Exception {
186         String filename = "/net/wangs/xmlutil/util.properties";
187         try {
188             // read in the file
189             InputStream is = getClass().getResourceAsStream( filename );
190             if ( is == null ) {
191                 throw new Exception( filename + " missing" );
192             }
193 
194             // load properties
195             Properties props = new Properties();
196             props.load(is);
197             is.close();
198 
199             return props;
200         } catch(IOException e) {
201             throw new Exception("SFWK::***Error reading " + filename );
202         }
203     }
204     
205     /***
206      * Provides information about the used XML parser.
207      * @return A string with the fully qualified parser name
208      * @throws Exception 
209      */
210     public static String _getParserInformation() throws Exception{
211         XMLValidator me = new XMLValidator();
212         String use_dom = System.getProperty("xmlutil.validate.dom");
213         if (use_dom.equals("") || use_dom.equals("false")) {
214             SAXParserFactory factory = SAXParserFactory.newInstance();
215             SAXParser parser = factory.newSAXParser();
216             return parser.getClass().getName();
217         }
218         else {
219             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
220             DocumentBuilder domBuilder = factory.newDocumentBuilder();
221             return domBuilder.getClass().getName();
222         }
223     }
224 
225 }