KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > Validate


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: Validate.java,v 1.5 2004/02/17 19:11:45 minchau Exp $
18  */

19
20 import java.io.File JavaDoc;
21 import java.io.FileInputStream JavaDoc;
22 import java.io.FileNotFoundException JavaDoc;
23 import java.io.FileWriter JavaDoc;
24 import java.io.FilenameFilter JavaDoc;
25 import java.io.IOException JavaDoc;
26
27 import javax.xml.parsers.ParserConfigurationException JavaDoc;
28 import javax.xml.parsers.SAXParser JavaDoc;
29 import javax.xml.parsers.SAXParserFactory JavaDoc;
30
31 import org.xml.sax.InputSource JavaDoc;
32 import org.xml.sax.SAXException JavaDoc;
33 import org.xml.sax.SAXParseException JavaDoc;
34 import org.xml.sax.XMLReader JavaDoc;
35 import org.xml.sax.ext.LexicalHandler JavaDoc;
36 import org.xml.sax.helpers.DefaultHandler JavaDoc;
37
38 /* Use JAXP SAXParser to parse 1 .xml file or all the .xml files in a directory.
39  * Takes 1 or 2 command-line arguments:
40  * Argument 1 (required) is a file name or directory name.
41  * Argument 2 (optional) is a log file name. If ommitted, messages are written to screen.
42  */

43 public class Validate
44 {
45   static int numXMLFiles = 0;
46   static int numValidFiles = 0;
47   static int numInvalidFiles = 0;
48   static int numFilesMissingDoctype = 0;
49   static int numMalformedFiles = 0;
50   static boolean useLogFile = false;
51   static StringBuffer JavaDoc buff = new StringBuffer JavaDoc();
52
53   public static void main(String JavaDoc[] args)
54     throws FileNotFoundException JavaDoc, IOException JavaDoc, ParserConfigurationException JavaDoc, SAXException JavaDoc
55   {
56     if (args.length == 0 || args.length > 2)
57     {
58       System.out.println("\nEnter 'java validate -help' for information about running Validate");
59       return;
60     }
61     if (args[0].toLowerCase().equals("-help"))
62     {
63       String JavaDoc sep = "\n====================================================\n";
64       String JavaDoc a = "Validate uses Xerces to parse the xml files in the directory you specify or the individual xml file you specify. The parser validates each document (checks that it conforms to its DOCTYPE).\n";
65       String JavaDoc b = "Each xml file should contain a DOCTYPE declaration.\n\n";
66       String JavaDoc c = "Validate takes 1 or 2 arguments:\n";
67       String JavaDoc d = " Argument 1 specifies a directory or an individual xml file.\n";
68       String JavaDoc e = " Argument 2 specifies a log file. If you include this argument, Validate appends messages to this file. If you do not, Validate writes messages to the screen.\n";
69       System.out.println(sep+a+b+c+d+e+sep);
70       return;
71     }
72     try
73     {
74       Validate v = new Validate();
75       v.validate(args);
76     }
77     catch (Exception JavaDoc e)
78     {
79       e.printStackTrace();
80     }
81   }
82   
83   void validate(String JavaDoc[] args)
84     throws FileNotFoundException JavaDoc, IOException JavaDoc, ParserConfigurationException JavaDoc, SAXException JavaDoc
85   {
86     File JavaDoc dir = new File JavaDoc(args[0]);
87    
88     // User may include a 2nd argument for the log file.
89
useLogFile = (args.length == 2);
90    
91     if (dir.isFile()) // Just checking one file.
92
{
93       parse(null,args[0]);
94     }
95     else if (dir.isDirectory()) // Checking the contents of a directory.
96
{
97       // Only interested in .xml files.
98
XMLFileFilter filter = new XMLFileFilter();
99       String JavaDoc [] files = dir.list(filter);
100       for (int i = 0; i <files.length; i++)
101       {
102         parse(dir.toString(),files[i]); // All the work is done here.
103

104         if (!useLogFile)
105         // Write messages to screen after parsing each file.
106
{
107           System.out.print(buff.toString());
108           buff = new StringBuffer JavaDoc();
109         }
110       }
111     }
112     else // Command-line argument is no good!
113
{
114       System.out.println(args[0] + " not found!");
115       return;
116     }
117     // Provide user with a summary.
118
buff.append("================SUMMARY=============================\n");
119     if (numXMLFiles > 1)
120       buff.append("Parsed " + numXMLFiles + " .xml files in " + args[0] + ".\n");
121     if (numValidFiles > 1)
122       buff.append( numValidFiles + " files are valid.\n");
123     else if (numValidFiles == 1)
124       buff.append( numValidFiles + " file is valid.\n");
125     if (numInvalidFiles > 1)
126       buff.append(numInvalidFiles + " files are not valid.\n");
127     else if (numInvalidFiles == 1)
128       buff.append( numInvalidFiles + " file is not valid.\n");
129     if (numMalformedFiles > 1)
130       buff.append(numMalformedFiles + " files are not well-formed.\n");
131     else if (numMalformedFiles == 1)
132       buff.append( numMalformedFiles + " file is not well-formed.\n");
133     if (numFilesMissingDoctype > 1)
134       buff.append(numFilesMissingDoctype + " files do not contain a DOCTYPE declaration.\n");
135     else if (numFilesMissingDoctype == 1)
136       buff.append(numFilesMissingDoctype + " file does not contain a DOCTYPE declaration.\n");
137      
138     if (!useLogFile)
139       System.out.print(buff.toString());
140     else
141     {
142       // If log file exists, append.
143
FileWriter JavaDoc writer = new FileWriter JavaDoc(args[1], true);
144       writer.write(new java.util.Date JavaDoc().toString()+ "\n");
145       writer.write(buff.toString());
146       writer.close();
147       System.out.println("Done with validation. See " + args[1] + ".");
148     }
149   }
150   
151   // Parse each XML file.
152
void parse(String JavaDoc dir, String JavaDoc filename)
153      throws FileNotFoundException JavaDoc, IOException JavaDoc, ParserConfigurationException JavaDoc, SAXException JavaDoc
154   {
155     try
156     {
157       File JavaDoc f = new File JavaDoc(dir, filename);
158       StringBuffer JavaDoc errorBuff = new StringBuffer JavaDoc();
159       InputSource JavaDoc input = new InputSource JavaDoc(new FileInputStream JavaDoc(f));
160       // Set systemID so parser can find the dtd with a relative URL in the source document.
161
input.setSystemId(f.toString());
162       SAXParserFactory JavaDoc spfact = SAXParserFactory.newInstance();
163        
164       spfact.setValidating(true);
165       spfact.setNamespaceAware(true);
166             
167       SAXParser JavaDoc parser = spfact.newSAXParser();
168       XMLReader JavaDoc reader = parser.getXMLReader();
169       
170       //Instantiate inner-class error and lexical handler.
171
Handler JavaDoc handler = new Handler JavaDoc(filename, errorBuff);
172       reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler);
173       parser.parse(input, handler);
174
175       if (handler.containsDTD && !handler.errorOrWarning) // valid
176
{
177         buff.append("VALID " + filename +"\n");
178         numValidFiles++;
179       }
180       else if (handler.containsDTD) // not valid
181
{
182         buff.append ("NOT VALID " + filename + "\n");
183         buff.append(errorBuff.toString());
184         numInvalidFiles++;
185       }
186       else // no DOCTYPE to use for validation
187
{
188         buff.append("NO DOCTYPE DECLARATION " + filename + "\n");
189         numFilesMissingDoctype++;
190       }
191     }
192     catch (Exception JavaDoc e) // Serious problem!
193
{
194       buff.append("NOT WELL-FORMED " + filename + ". " + e.getMessage() + "\n");
195       numMalformedFiles++;
196     }
197     finally
198     {
199       numXMLFiles++;
200     }
201   }
202   // Inner classes
203

204   // Only interested in parsing .xml files.
205
class XMLFileFilter implements FilenameFilter JavaDoc
206   {
207     public boolean accept(File JavaDoc dir, String JavaDoc fileName)
208     {
209       return fileName.toLowerCase().endsWith(".xml") && new File JavaDoc(dir.toString(),fileName).isFile();
210     }
211   }
212   
213   // Catch any errors or warnings, and verify presence of doctype statement.
214
class Handler extends DefaultHandler JavaDoc implements LexicalHandler JavaDoc
215   {
216     boolean errorOrWarning;
217     boolean containsDTD;
218     String JavaDoc sourceFile;
219     StringBuffer JavaDoc errorBuff;
220   
221     Handler(String JavaDoc sourceFile, StringBuffer JavaDoc errorBuff)
222     {
223       super();
224       this.sourceFile = sourceFile;
225       this.errorBuff = errorBuff;
226       errorOrWarning = false;
227       containsDTD = false;
228     }
229     
230     public void error(SAXParseException JavaDoc exc)
231     {
232       errorBuff.append(sourceFile + " Error: " + exc.getMessage()+ "\n");
233       errorOrWarning = true;
234     }
235     public void warning(SAXParseException JavaDoc exc)
236     {
237       errorBuff.append(sourceFile + " Warning:" + exc.getMessage()+ "\n");
238       errorOrWarning = true;
239     }
240
241     // LexicalHandler methods; all no-op except startDTD().
242

243     // Set containsDTD to true when startDTD event occurs.
244
public void startDTD (String JavaDoc name, String JavaDoc publicId, String JavaDoc systemId)
245         throws SAXException JavaDoc
246     {
247       containsDTD = true;
248     }
249  
250     public void endDTD () throws SAXException JavaDoc
251     {}
252   
253     public void startEntity (String JavaDoc name) throws SAXException JavaDoc
254     {}
255   
256     public void endEntity (String JavaDoc name) throws SAXException JavaDoc
257     {}
258   
259     public void startCDATA () throws SAXException JavaDoc
260     {}
261   
262     public void endCDATA () throws SAXException JavaDoc
263     {}
264   
265     public void comment (char ch[], int start, int length) throws SAXException JavaDoc
266     {}
267   }
268 }
269
Popular Tags