KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > fractal > adl > xml > XMLParser


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

23
24 package org.objectweb.fractal.adl.xml;
25
26 import org.objectweb.fractal.adl.Node;
27 import org.objectweb.fractal.adl.Parser;
28 import org.objectweb.fractal.adl.ParserException;
29 import org.objectweb.fractal.adl.xml.XMLNodeClassLoader;
30 import org.objectweb.fractal.adl.xml.DTDHandler;
31 import org.objectweb.fractal.adl.xml.XMLNode;
32
33 import java.io.InputStream JavaDoc;
34 import java.io.IOException JavaDoc;
35 import java.util.List JavaDoc;
36 import java.util.ArrayList JavaDoc;
37 import java.util.Map JavaDoc;
38 import java.util.HashMap JavaDoc;
39 import java.net.URL JavaDoc;
40 import java.net.MalformedURLException JavaDoc;
41
42 import javax.xml.parsers.ParserConfigurationException JavaDoc;
43 import javax.xml.parsers.SAXParser JavaDoc;
44 import javax.xml.parsers.SAXParserFactory JavaDoc;
45
46 import org.xml.sax.helpers.DefaultHandler JavaDoc;
47 import org.xml.sax.SAXException JavaDoc;
48 import org.xml.sax.InputSource JavaDoc;
49 import org.xml.sax.Attributes JavaDoc;
50 import org.xml.sax.SAXNotRecognizedException JavaDoc;
51 import org.xml.sax.Locator JavaDoc;
52 import org.xml.sax.SAXParseException JavaDoc;
53
54 /**
55  * An extensible XML parser that constructs strongly typed abstract syntax trees.
56  */

57
58 public class XMLParser extends DefaultHandler JavaDoc implements Parser {
59
60   /**
61    * The parser factory used to create new parsers.
62    */

63   
64   SAXParserFactory JavaDoc spf;
65   
66   /**
67    * Associates an ASTClassLoader to each DTD.
68    * Keys are DTD names, values are ASTClassLoader objects.
69    */

70
71   Map JavaDoc loaders;
72
73   /**
74    * Name of the file that is currently being parsed.
75    */

76
77   String JavaDoc file;
78
79   /**
80    * Loader used for the elements that are currently being parsed.
81    */

82
83   XMLNodeClassLoader loader;
84
85   /**
86    * Stack of the elements that are currently being parsed.
87    */

88
89   List JavaDoc stack;
90
91   /**
92    * Top level element of the elements that are currently being parsed.
93    */

94
95   XMLNode result;
96
97   /**
98    * The locator used to keep track of line numbers.
99    */

100   
101   Locator JavaDoc locator;
102
103   int line;
104   
105   // --------------------------------------------------------------------------
106
// Constructor
107
// --------------------------------------------------------------------------
108

109   public XMLParser () {
110     this(true);
111   }
112   
113   public XMLParser (boolean validate) {
114     loaders = new HashMap JavaDoc();
115     stack = new ArrayList JavaDoc();
116     spf = SAXParserFactory.newInstance();
117     spf.setValidating(validate);
118   }
119
120   // --------------------------------------------------------------------------
121
// Implementation of the Parser interface
122
// --------------------------------------------------------------------------
123

124   public Node parse (final InputStream JavaDoc is, final String JavaDoc name)
125     throws ParserException
126   {
127     file = name;
128     try {
129       SAXParser JavaDoc sp = spf.newSAXParser();
130       sp.parse(new InputSource JavaDoc(is), this);
131       return result;
132     } catch (IOException JavaDoc e) {
133       throw new ParserException("Parser error (" + file + ":" + line + ")", e);
134     } catch (ParserConfigurationException JavaDoc e) {
135       throw new ParserException("Parser error (" + file + ":" + line + ")", e);
136     } catch (SAXException JavaDoc e) {
137       throw new ParserException("Parser error (" + file + ":" + line + ")", e);
138     }
139   }
140
141   // --------------------------------------------------------------------------
142
// Overriden DefaultHandler methods
143
// --------------------------------------------------------------------------
144

145   public void setDocumentLocator (final Locator JavaDoc locator) {
146     super.setDocumentLocator(locator);
147     this.locator = locator;
148   }
149
150   public InputSource JavaDoc resolveEntity (
151     final String JavaDoc publicId,
152     final String JavaDoc systemId) throws SAXException JavaDoc
153   {
154     // finds the AST class loader for the "systemID" DTD
155
loader = (XMLNodeClassLoader)loaders.get(systemId);
156     if (loader == null) {
157       loader = new XMLNodeClassLoader(getClass().getClassLoader());
158       loaders.put(systemId, loader);
159
160       try {
161         InputStream JavaDoc is;
162         // gets an InputStream to read the DTD
163
if (systemId.startsWith("classpath://")) {
164           is = getClass().getClassLoader().getResourceAsStream(
165             systemId.substring("classpath://".length()));
166         } else if (systemId.startsWith("file:")) {
167           is = new URL JavaDoc(systemId).openStream();
168         } else {
169           throw new SAXNotRecognizedException JavaDoc(
170             "Unrecognized system identifier: " + systemId);
171         }
172         // verifies the DTD and initializes the AST class loader
173
new DTDHandler().checkDTD(is, loader);
174       } catch (MalformedURLException JavaDoc e) {
175         throw new SAXException JavaDoc("Cannot find the DTD", e);
176       } catch (IOException JavaDoc e) {
177         throw new SAXException JavaDoc("Cannot read the DTD", e);
178       } catch (ClassNotFoundException JavaDoc e) {
179         throw new SAXException JavaDoc("Cannot check the DTD", e);
180       }
181     }
182
183     if (systemId.startsWith("classpath://")) {
184       return new InputSource JavaDoc(getClass().getClassLoader().getResourceAsStream(
185         systemId.substring("classpath://".length())));
186     } else {
187       return null;
188     }
189   }
190
191   public void startElement (
192     final String JavaDoc uri,
193     final String JavaDoc localName,
194     final String JavaDoc qualifiedName,
195     final Attributes JavaDoc attributes) throws SAXException JavaDoc
196   {
197     String JavaDoc xmlNodeClassName = loader.getASTClassName(qualifiedName);
198     XMLNode o;
199     try {
200       o = (XMLNode)loader.loadClass(xmlNodeClassName).newInstance();
201     } catch (Exception JavaDoc e) {
202       throw new SAXException JavaDoc("Internal error", e);
203     }
204     o.astSetSource(file + ":" + locator.getLineNumber());
205     o.xmlSetAttributes(attributes);
206     if (stack.size() == 0) {
207       result = o;
208     } else {
209       Object JavaDoc p = stack.get(stack.size() - 1);
210       ((XMLNode)p).xmlAddNode(qualifiedName, o);
211     }
212     stack.add(o);
213   }
214
215   public void endElement (
216     final String JavaDoc uri,
217     final String JavaDoc localName,
218     final String JavaDoc qualifiedName) throws SAXException JavaDoc
219   {
220     stack.remove(stack.size() - 1);
221   }
222
223   public void error (final SAXParseException JavaDoc e) throws SAXException JavaDoc {
224     line = locator.getLineNumber();
225     throw e;
226   }
227
228   public void fatalError (final SAXParseException JavaDoc e) throws SAXException JavaDoc {
229     line = locator.getLineNumber();
230     throw e;
231   }
232 }
233
Popular Tags