KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > continuent > sequoia > common > xml > XmlValidator


1 /**
2  * Sequoia: Database clustering technology.
3  * Copyright (C) 2002-2004 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: sequoia@continuent.org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * Initial developer(s): Nicolas Modrzyk.
20  * Contributor(s):
21  */

22
23 package org.continuent.sequoia.common.xml;
24
25 import java.io.BufferedReader JavaDoc;
26 import java.io.File JavaDoc;
27 import java.io.FileReader JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.InputStream JavaDoc;
30 import java.io.StringReader JavaDoc;
31 import java.util.ArrayList JavaDoc;
32
33 import org.continuent.sequoia.common.i18n.Translate;
34 import org.continuent.sequoia.controller.core.ControllerConstants;
35 import org.xml.sax.ErrorHandler JavaDoc;
36 import org.xml.sax.InputSource JavaDoc;
37 import org.xml.sax.SAXException JavaDoc;
38 import org.xml.sax.SAXParseException JavaDoc;
39 import org.xml.sax.XMLReader JavaDoc;
40 import org.xml.sax.ext.LexicalHandler JavaDoc;
41 import org.xml.sax.helpers.DefaultHandler JavaDoc;
42 import org.xml.sax.helpers.XMLReaderFactory JavaDoc;
43
44 /**
45  * Validate a document and its DTD.
46  *
47  * @author <a HREF="mailto:Nicolas.Modrzyk@inrialpes.fr">Nicolas Modrzyk </a>
48  */

49 public class XmlValidator extends DefaultHandler JavaDoc
50     implements
51       ErrorHandler JavaDoc,
52       LexicalHandler JavaDoc
53 {
54
55   /** XML parser. */
56   private XMLReader JavaDoc parser;
57   private String JavaDoc pathToDtd;
58   private boolean isXmlValid = false;
59   private boolean isDtdValid = false;
60   private String JavaDoc xmlContent;
61   private ArrayList JavaDoc errors;
62   private ArrayList JavaDoc warnings;
63
64   /**
65    * Allow to use the xml validator as an external program
66    *
67    * @param args the xmlfile and the dtd file
68    * @throws Exception if fails
69    */

70   public static void main(String JavaDoc[] args) throws Exception JavaDoc
71   {
72     if (args.length < 1 || args.length > 2)
73     {
74       System.out.println("usage: XmlValidator [xmlFile] ([dtd]) ");
75       System.exit(0);
76     }
77
78     String JavaDoc fileName = args[0];
79     String JavaDoc dtdName = ControllerConstants.SEQUOIA_DTD_FILE;
80     if (args.length == 2)
81       dtdName = args[1];
82     else
83       System.out.println("Using default DTD:" + ControllerConstants.SEQUOIA_DTD_FILE);
84
85     File JavaDoc dtd = null;
86     dtd = new File JavaDoc(ClassLoader.getSystemResource(dtdName).getFile());
87     File JavaDoc xmlFile = null;
88     try
89     {
90       xmlFile = new File JavaDoc(ClassLoader.getSystemResource(fileName).getFile());
91     }
92     catch (RuntimeException JavaDoc e)
93     {
94       xmlFile = new File JavaDoc(fileName);
95     }
96
97     if (!dtd.exists())
98     {
99       System.out.println("Cannot find specified dtd");
100       System.exit(1);
101     }
102     if (!xmlFile.exists())
103     {
104       System.out.println("Cannot find specified xml file");
105       System.exit(1);
106     }
107
108     System.out.println("Validating:\tFile:" + xmlFile.getName() + " with dtd:"
109         + dtd.getName());
110
111     // Validate xml and dtd
112
XmlValidator validator = new XmlValidator(dtd.getAbsolutePath(),
113         new FileReader JavaDoc(xmlFile));
114
115     // Display Results
116
if (!validator.isDtdValid())
117       System.out.println("[FAILED:Dtd is not valid]");
118     else if (!validator.isXmlValid())
119       System.out.println("[FAILED:xml is not valid]");
120     else if (validator.isXmlValid())
121       System.out.println("[OK]");
122
123     if (validator.getLastException() != null)
124     {
125       ArrayList JavaDoc errors = validator.getExceptions();
126       for (int i = 0; i < errors.size(); i++)
127         System.out.println("\t(parsing error):"
128             + ((Exception JavaDoc) errors.get(i)).getMessage());
129     }
130   }
131
132   /**
133    * Check the given dtd, and the given xml are valid.
134    *
135    * @param pathToDtd path to dtd
136    * @param xml source to parse as a string
137    */

138   public XmlValidator(String JavaDoc pathToDtd, String JavaDoc xml)
139   {
140     validate(pathToDtd, xml);
141   }
142
143   /**
144    * @see #XmlValidator(String pathToDtd,String xml)
145    */

146   public XmlValidator(String JavaDoc pathToDtd, FileReader JavaDoc file) throws IOException JavaDoc
147   {
148     // Read the file
149
BufferedReader JavaDoc in = new BufferedReader JavaDoc(file);
150     StringBuffer JavaDoc xml = new StringBuffer JavaDoc();
151     String JavaDoc line;
152     do
153     {
154       line = in.readLine();
155       if (line != null)
156         xml.append(line.trim());
157     }
158     while (line != null);
159     xmlContent = xml.toString();
160     validate(pathToDtd, xmlContent);
161   }
162
163   /**
164    * get the xml that was formatted
165    *
166    * @return xml
167    */

168   public String JavaDoc getXmlContent()
169   {
170     return xmlContent;
171   }
172
173   /**
174    * Starts the verification of the xml document AND the dtd
175    *
176    * @param pathToDtd path
177    * @param xml content
178    */

179   public void validate(String JavaDoc pathToDtd, String JavaDoc xml)
180   {
181     System.setProperty("org.xml.sax.driver",
182         "org.apache.crimson.parser.XMLReaderImpl");
183     errors = new ArrayList JavaDoc();
184     warnings = new ArrayList JavaDoc();
185     try
186     {
187       // Store dtd reference
188
this.pathToDtd = pathToDtd;
189       // Instantiate a new parser
190
parser = XMLReaderFactory.createXMLReader();
191       // Activate validation
192
parser.setFeature("http://xml.org/sax/features/validation", true);
193       // Install error handler
194
parser.setErrorHandler(this);
195       // Install document handler
196
parser.setContentHandler(this);
197       parser.setProperty("http://xml.org/sax/properties/lexical-handler", this);
198       // Install local entity resolver
199
parser.setEntityResolver(this);
200       InputSource JavaDoc input = new InputSource JavaDoc(new StringReader JavaDoc(xml));
201       parser.parse(input);
202     }
203     catch (Exception JavaDoc e)
204     {
205       //throw new Exception("Xml document can not be validated.");
206
//e.printStackTrace();
207
addError(e);
208       isXmlValid = false;
209     }
210   }
211
212   /**
213    * Allows to parse the document with a local copy of the DTD whatever the
214    * original <code>DOCTYPE</code> found. Warning, this method is called only
215    * if the XML document contains a <code>DOCTYPE</code>.
216    *
217    * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String,
218    * java.lang.String)
219    */

220   public InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId)
221       throws SAXException JavaDoc
222   {
223
224     File JavaDoc dtd = new File JavaDoc(pathToDtd);
225     if (dtd.exists())
226     {
227       try
228       {
229         FileReader JavaDoc reader = new FileReader JavaDoc(dtd);
230         return new InputSource JavaDoc(reader);
231       }
232       catch (Exception JavaDoc e)
233       { //impossible
234
}
235     }
236
237     InputStream JavaDoc stream = XmlValidator.class
238         .getResourceAsStream("/" + pathToDtd);
239     if (stream == null)
240     {
241       SAXException JavaDoc sax = new SAXException JavaDoc(Translate.get(
242           "virtualdatabase.xml.dtd.not.found", ControllerConstants.PRODUCT_NAME, pathToDtd)); //$NON-NLS-1$
243
addError(sax);
244       throw sax;
245     }
246
247     return new InputSource JavaDoc(stream);
248   }
249
250   /**
251    * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
252    */

253   public void error(SAXParseException JavaDoc exception) throws SAXException JavaDoc
254   {
255     addError(exception);
256   }
257
258   /**
259    * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
260    */

261   public void fatalError(SAXParseException JavaDoc exception) throws SAXException JavaDoc
262   {
263     addError(exception);
264   }
265
266   /**
267    * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
268    */

269   public void warning(SAXParseException JavaDoc exception) throws SAXException JavaDoc
270   {
271     warnings.add(exception);
272   }
273
274   /**
275    * @see org.xml.sax.ContentHandler#endDocument()
276    */

277   public void endDocument() throws SAXException JavaDoc
278   {
279     if (errors.size() == 0)
280       this.isXmlValid = true;
281   }
282
283   /**
284    * @return Returns the isXmlValid.
285    */

286   public boolean isValid()
287   {
288     return isXmlValid && isDtdValid;
289   }
290
291   /**
292    * Return the last cause of parsing failure
293    *
294    * @return exception, null if no exception
295    */

296   public Exception JavaDoc getLastException()
297   {
298     if (errors.size() == 0)
299       return null;
300     else
301       return (Exception JavaDoc) errors.get(errors.size() - 1);
302   }
303
304   /**
305    * Retrieve an <code>ArrayList</code> of all parsing exceptions
306    *
307    * @return an <code>ArrayList</code> of <code>Exception</code>
308    */

309   public ArrayList JavaDoc getExceptions()
310   {
311     return errors;
312   }
313
314   /**
315    * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int)
316    */

317   public void comment(char[] ch, int start, int length) throws SAXException JavaDoc
318   {
319   }
320
321   /**
322    * @see org.xml.sax.ext.LexicalHandler#endCDATA()
323    */

324   public void endCDATA() throws SAXException JavaDoc
325   {
326   }
327
328   /**
329    * @see org.xml.sax.ext.LexicalHandler#endDTD()
330    */

331   public void endDTD() throws SAXException JavaDoc
332   {
333     if (errors.size() == 0)
334     {
335       isDtdValid = true;
336     }
337     else
338     {
339       isDtdValid = false;
340     }
341   }
342
343   /**
344    * @see org.xml.sax.ext.LexicalHandler#endEntity(java.lang.String)
345    */

346   public void endEntity(String JavaDoc name) throws SAXException JavaDoc
347   {
348   }
349
350   /**
351    * @see org.xml.sax.ext.LexicalHandler#startCDATA()
352    */

353   public void startCDATA() throws SAXException JavaDoc
354   {
355   }
356
357   /**
358    * @see org.xml.sax.ext.LexicalHandler#startDTD(java.lang.String,
359    * java.lang.String, java.lang.String)
360    */

361   public void startDTD(String JavaDoc name, String JavaDoc publicId, String JavaDoc systemId)
362       throws SAXException JavaDoc
363   {
364   }
365
366   /**
367    * @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String)
368    */

369   public void startEntity(String JavaDoc name) throws SAXException JavaDoc
370   {
371   }
372
373   /**
374    * @return Returns the isDtdValid.
375    */

376   public boolean isDtdValid()
377   {
378     return isDtdValid;
379   }
380
381   /**
382    * @param isDtdValid The isDtdValid to set.
383    */

384   public void setDtdValid(boolean isDtdValid)
385   {
386     this.isDtdValid = isDtdValid;
387   }
388
389   /**
390    * @return Returns the isXmlValid.
391    */

392   public boolean isXmlValid()
393   {
394     return isXmlValid;
395   }
396
397   /**
398    * @param isXmlValid The isXmlValid to set.
399    */

400   public void setXmlValid(boolean isXmlValid)
401   {
402     this.isXmlValid = isXmlValid;
403   }
404
405   private void addError(Exception JavaDoc e)
406   {
407     errors.add(e);
408   }
409
410   /**
411    * @return Returns the warnings.
412    */

413   public ArrayList JavaDoc getWarnings()
414   {
415     return warnings;
416   }
417 }
Popular Tags