KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jorm > xml2mi > lib > SAXParserHelper


1 /**
2  * Copyright (C) 2001-2005 France Telecom R&D
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  *
19  *
20  * Authors: S.Chassande-Barrioz.
21  * Created on 10 mars 2005
22  *
23  */

24 package org.objectweb.jorm.xml2mi.lib;
25
26 import java.io.FileInputStream JavaDoc;
27 import java.io.FileNotFoundException JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.InputStream JavaDoc;
30 import java.net.URL JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.Properties JavaDoc;
36 import java.util.jar.JarFile JavaDoc;
37 import java.util.zip.ZipEntry JavaDoc;
38
39 import javax.xml.parsers.DocumentBuilder JavaDoc;
40 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
41 import javax.xml.parsers.ParserConfigurationException JavaDoc;
42
43 import org.objectweb.util.monolog.api.BasicLevel;
44 import org.objectweb.util.monolog.api.Logger;
45 import org.w3c.dom.Document JavaDoc;
46 import org.xml.sax.EntityResolver JavaDoc;
47 import org.xml.sax.ErrorHandler JavaDoc;
48 import org.xml.sax.InputSource JavaDoc;
49 import org.xml.sax.SAXException JavaDoc;
50 import org.xml.sax.SAXParseException JavaDoc;
51
52 /**
53  * This class is an helper for the use of SAX Parser. It manages the entity
54  * resolving public id, and handling errors.
55  *
56  * @author S.Chassande-Barrioz
57  */

58 public class SAXParserHelper implements EntityResolver JavaDoc, ErrorHandler JavaDoc {
59
60     /**
61      * the entity location for each public id
62      */

63     private Properties JavaDoc publicid2location = null;
64     
65     /**
66      * The classLoader used to try to load entities and xml files
67      */

68     private ClassLoader JavaDoc classLoader;
69     
70     /**
71      * The list of errors occuring during the parsing
72      */

73     private List JavaDoc errors;
74     
75     /**
76      * the parser
77      */

78     private DocumentBuilder JavaDoc parser;
79     
80     private Logger logger;
81
82     /**
83      * Creates and initializes a SAX parser with the classLoader of the current
84      * class. The DTD checking is done.
85      * @param publicid2location contains the association between public id and
86      * location
87      */

88     public SAXParserHelper(Properties JavaDoc publicid2location,
89             Logger logger) throws SAXException JavaDoc {
90         this.publicid2location = publicid2location;
91         this.logger = logger;
92         this.classLoader = getClass().getClassLoader();
93         if (classLoader == null) {
94             classLoader = ClassLoader.getSystemClassLoader();
95         }
96         init(true);
97     }
98
99     /**
100      * Creates and initializes a SAX parser.
101      * @param publicid2location contains the association between public id and
102      * location
103      * @param cl is the classLoader used to try to load entities and xml files
104      * @param dtdverify indicates if the DTD checking must be done
105      */

106     public SAXParserHelper(Properties JavaDoc publicid2location,
107             Logger logger,
108             ClassLoader JavaDoc cl,
109             boolean dtdverify) throws SAXException JavaDoc {
110         this.publicid2location = publicid2location;
111         this.logger = logger;
112         this.classLoader = cl;
113         if (classLoader == null) {
114             classLoader = getClass().getClassLoader();
115             if (classLoader == null) {
116                 classLoader = ClassLoader.getSystemClassLoader();
117             }
118         }
119         init(dtdverify);
120     }
121
122     /**
123      * Parses a xml file. Firstly this method try to found the xml file from
124      * the file system or the classpath. Then the method delegates the parsing
125      * to the parse(InputStream) method.
126      *
127      * @param xmlFileName is the path to the xml file. This path can be valid
128      * from the file system or the classpath/classloader. The path can be an
129      * URL.
130      * @return the Document representing the XML file.
131      * @throws SAXException is thrown if the file cannot be found or if the
132      * file is malformed.
133      */

134     public Document JavaDoc parse(String JavaDoc xmlFileName) throws SAXException JavaDoc {
135         InputStream JavaDoc is = null;
136         try {
137             is = new FileInputStream JavaDoc(xmlFileName);
138         } catch (FileNotFoundException JavaDoc e) {
139             logger.log(BasicLevel.DEBUG, xmlFileName + " is not a local file ");
140         }
141
142         if (is == null) {
143             URL JavaDoc urldtd = null;
144             try {
145                 urldtd = new URL JavaDoc(xmlFileName);
146                 is = urldtd.openStream();
147             } catch (IOException JavaDoc e) {
148                 logger.log(BasicLevel.DEBUG, xmlFileName + " is not an URL ");
149             }
150         }
151
152         // Try in the classpath
153
if (is == null) {
154             is = classLoader.getResourceAsStream(xmlFileName);
155             if (is == null) {
156                 logger.log(BasicLevel.DEBUG, xmlFileName + " is not availlable in the classpath");
157             }
158         }
159
160         //the location can be a jar file
161
if (is == null) {
162             int idx = xmlFileName.indexOf(".jar!");
163             if (idx != -1) {
164                 try {
165                     JarFile JavaDoc jarfile = new JarFile JavaDoc(xmlFileName.substring(0, idx));
166                     // the path is the jar file, can continue
167
if (jarfile != null) {
168                         ZipEntry JavaDoc zipentry = jarfile.getEntry(
169                                 xmlFileName.substring(idx + 5, xmlFileName.length()));
170                         // if the entry (file) exists in the jar file
171
// extracts it and return an input stream from it
172
if (zipentry != null) {
173                             is = jarfile.getInputStream(zipentry);
174                         }
175                     }
176                 } catch (Exception JavaDoc e) {
177                     logger.log(BasicLevel.DEBUG, xmlFileName + " is not in a jar file");
178                 }
179             } else {
180                 logger.log(BasicLevel.DEBUG, xmlFileName + " is not in a jar file");
181             }
182         }
183         
184         if (is == null) {
185             throw new SAXException JavaDoc("No XML file '" + xmlFileName + "' found");
186         } else {
187             return parse(is);
188         }
189         
190     }
191     
192     /**
193      * Parses a stream as an xml file. Errors are logged.
194      * @param is an inputStream contains the XML xml content
195      * @return the Document representing the XML file.
196      * @throws SAXException is thrown if the file cannot be found or if the
197      * file is malformed.
198      */

199     public Document JavaDoc parse(InputStream JavaDoc is) throws SAXException JavaDoc {
200         if (errors != null) {
201             //forget errors of a previous parsing
202
errors.clear();
203         }
204         //Parsing
205
try {
206             Document JavaDoc d = parser.parse(is, ".");
207             if (d == null) {
208                 throw new SAXException JavaDoc("No document");
209             }
210             return d;
211         } catch (IOException JavaDoc e) {
212             throw new SAXException JavaDoc(e);
213         }
214     }
215
216     /**
217      * creates the real parser and initializes it.
218      * @param dtdverify indicates if the DTD checking must be done
219      * @throws SAXException
220      */

221     private void init(boolean dtdverify)throws SAXException JavaDoc {
222         //Parser initialisation
223
DocumentBuilderFactory JavaDoc domFactory = DocumentBuilderFactory.newInstance();
224         domFactory.setValidating(dtdverify);
225         try {
226             parser = domFactory.newDocumentBuilder();
227         } catch (ParserConfigurationException JavaDoc e) {
228             throw new SAXException JavaDoc(e);
229         }
230         parser.setEntityResolver(this);
231         parser.setErrorHandler(this);
232     }
233     
234     private List JavaDoc getErrorList() {
235         if (errors == null) {
236             errors = new ArrayList JavaDoc();
237         }
238         return errors;
239     }
240     
241     // IMPLEMENTATION OF METHODS FROM THE ErrorHandler INTERFACE //
242
//-----------------------------------------------------------//
243

244     public void error(SAXParseException JavaDoc e) throws SAXException JavaDoc {
245         logger.log(BasicLevel.ERROR, e.getMessage(), e);
246         getErrorList().add(e);
247     }
248     public void fatalError(SAXParseException JavaDoc e) throws SAXException JavaDoc {
249         logger.log(BasicLevel.FATAL, e.getMessage(), e);
250         getErrorList().add(e);
251     }
252     public void warning(SAXParseException JavaDoc e) throws SAXException JavaDoc {
253         logger.log(BasicLevel.WARN, e.getMessage(), e);
254         getErrorList().add(e);
255     }
256     
257     
258     // IMPLEMENTATION OF METHODS FROM THE EntityResolver INTERFACE //
259
//-------------------------------------------------------------//
260

261     /**
262      * Resolves the entity according to the associaition contained in
263      * #publicid2location. The entity are searched in the file system and in
264      * the classpath.
265      */

266     public InputSource JavaDoc resolveEntity (String JavaDoc publicId, String JavaDoc systemId)
267             throws SAXException JavaDoc {
268         String JavaDoc publicid = publicId;
269         String JavaDoc location = null;
270         if (publicid == null) {
271             location = systemId;
272         } else {
273             logger.log(BasicLevel.DEBUG, "Looking for the publicId: " + publicid);
274             for(Iterator JavaDoc it = publicid2location.entrySet().iterator(); it.hasNext();) {
275                 Map.Entry JavaDoc me = (Map.Entry JavaDoc) it.next();
276                 String JavaDoc current = (String JavaDoc) me.getKey();
277                 logger.log(BasicLevel.DEBUG, "Current public id: " + current);
278                 if (current.equals(publicid)) {
279                     location = (String JavaDoc) me.getValue();
280                     break;
281                 }
282             }
283         }
284         if (location == null) {
285             logger.log(BasicLevel.INFO,
286                     "No dtd location found for the publicId: " + publicid);
287             if (systemId == null)
288                 throw new SAXException JavaDoc("Could not resolve publicid: " + publicid);
289             logger.log(BasicLevel.INFO, "Try to resolve " + publicid
290                     + " with the default location " + systemId);
291             location = systemId;
292         }
293
294         InputStream JavaDoc is = null;
295
296         // try in the file system
297
try {
298             is = new FileInputStream JavaDoc(location);
299             logger.log(BasicLevel.DEBUG, "Resolved " + publicid
300                     + " to local file " + location);
301         } catch (FileNotFoundException JavaDoc e) {
302             logger.log(BasicLevel.DEBUG, location + " is not a local file ");
303         }
304
305         if (is == null) {
306             URL JavaDoc urldtd = null;
307             try {
308                 urldtd = new URL JavaDoc(location);
309                 is = urldtd.openStream();
310                 logger.log(BasicLevel.DEBUG, "Resolved " + publicid
311                         + " to url " + urldtd);
312             } catch (IOException JavaDoc e) {
313                 logger.log(BasicLevel.DEBUG, location + " is not an URL ");
314             }
315         }
316
317         // Try in the classpath
318
if (is == null) {
319             is = classLoader.getResourceAsStream(location);
320             if (is != null) {
321                 logger.log(BasicLevel.DEBUG, "Resolved " + publicid
322                         + " to resource " + location);
323             } else {
324                 logger.log(BasicLevel.DEBUG, location
325                         + " is not availlable in the classpath");
326             }
327         }
328
329         //the location can be a jar file
330
if (is == null) {
331             int idx = location.indexOf(".jar!");
332             if (idx != -1) {
333                 try {
334                     JarFile JavaDoc jarfile = new JarFile JavaDoc(location.substring(0, idx));
335                     // the path is the jar file, can continue
336
if (jarfile != null) {
337                         ZipEntry JavaDoc zipentry = jarfile.getEntry(
338                                 location.substring(idx + 5, location.length()));
339                         // if the entry (file) exists in the jar file
340
// extracts it and return an input stream from it
341
if (zipentry != null) {
342                             is = jarfile.getInputStream(zipentry);
343                         }
344                     }
345                 } catch (Exception JavaDoc e) {
346                     logger.log(BasicLevel.DEBUG, location + " is not an jar file");
347                 }
348             }
349         }
350
351         if (is != null)
352             return new InputSource JavaDoc(is);
353         else
354             throw new SAXException JavaDoc("Could not resolve publicid: ["
355                                   + publicid + "] location [" + location + "]");
356     }
357 }
358
Popular Tags