001: package com.rimfaxe.xml.xmlreader;
002:
003: import java.io.*;
004: import java.net.URL;
005: import java.util.Enumeration;
006: import java.util.Iterator;
007:
008: import org.xml.sax.*;
009: import org.xml.sax.helpers.AttributesImpl;
010: import org.xml.sax.helpers.DefaultHandler;
011:
012: /** JAXP compatible XMLReader wrapper for Sparta.
013:
014: <blockquote><small> Copyright (C) 2002 Hewlett-Packard Company.
015: This file is part of Sparta, an XML Parser, DOM, and XPath library.
016: This library is free software; you can redistribute it and/or
017: modify it under the terms of the <a href="doc-files/LGPL.txt">GNU
018: Lesser General Public License</a> as published by the Free Software
019: Foundation; either version 2.1 of the License, or (at your option)
020: any later version. This library is distributed in the hope that it
021: will be useful, but WITHOUT ANY WARRANTY; without even the implied
022: warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
023: PURPOSE. </small></blockquote>
024: @version $Date: 2003/01/27 23:30:59 $ $Revision: 1.4 $
025: @author Sergio Marti
026: */
027:
028: public class XMLReaderImpl implements XMLReader, ParseHandler {
029:
030: private ParseSource parseSource_ = null;
031:
032: private ContentHandler contentHandler_ = null;
033: private DTDHandler dtdHandler_ = null;
034: private EntityResolver entityResolver_ = null;
035: private ErrorHandler errorHandler_ = null;
036:
037: /* Prototype namespace support */
038: private final boolean nsAware_;
039: private NamespaceSupport nsSupport_ = null;
040: private String[] nameInfo_ = new String[3];
041:
042: XMLReaderImpl(boolean nsAware) {
043: nsAware_ = nsAware;
044: if (nsAware) {
045: nsSupport_ = new NamespaceSupport();
046:
047: }
048: }
049:
050: void init(DefaultHandler dh) {
051: setContentHandler(dh);
052: setDTDHandler(dh);
053: setEntityResolver(dh);
054: setErrorHandler(dh);
055: }
056:
057: // XMLReader methods
058:
059: // Return the current content handler.
060: public ContentHandler getContentHandler() {
061: return contentHandler_;
062: }
063:
064: // Return the current DTD handle.
065: public DTDHandler getDTDHandler() {
066: return dtdHandler_;
067: }
068:
069: // Return the current entity resolver.
070: public EntityResolver getEntityResolver() {
071: return entityResolver_;
072: }
073:
074: // Return the current error handler.
075: public ErrorHandler getErrorHandler() {
076: return errorHandler_;
077: }
078:
079: // Look up the value of a feature.
080: public boolean getFeature(java.lang.String name) {
081: return false;
082: }
083:
084: // Look up the value of a property.
085: public java.lang.Object getProperty(java.lang.String name) {
086: return null;
087: }
088:
089: // Parse an XML document.
090: public void parse(InputSource input) throws SAXException,
091: IOException {
092: String sysID = "file:unknown";
093: try {
094: String uri = input.getSystemId();
095: if (uri != null)
096: sysID = uri;
097:
098: Reader reader = input.getCharacterStream();
099: InputStream stream = input.getByteStream();
100: String encoding = input.getEncoding();
101: if (reader != null) {
102: Parser.parse(sysID, reader, null, encoding, this );
103: } else if (stream != null) {
104: Parser.parse(sysID, stream, null, encoding, this );
105: } else if (uri != null) {
106: URL url = new URL(uri);
107: InputStream istream = url.openStream();
108: if (istream == null) {
109: String msg = "Cannot open " + uri;
110: if (errorHandler_ != null)
111: errorHandler_.fatalError(new SAXParseException(
112: msg, "", sysID, -1, -1));
113: throw new IOException(msg);
114: }
115: Parser.parse(uri, istream, null, encoding, this );
116: } else {
117: if (errorHandler_ != null)
118: errorHandler_.fatalError(new SAXParseException(
119: "Nothing in InputSource", "", sysID, 0, 0));
120: }
121: } catch (EncodingMismatchException eme) {
122: if (errorHandler_ != null)
123: errorHandler_.fatalError(new SAXParseException(eme
124: .getMessage(), "", sysID, -1, -1, eme));
125: } catch (ParseException pe) {
126: if (errorHandler_ != null)
127: errorHandler_.fatalError(new SAXParseException(pe
128: .getMessage(), "", sysID, -1, -1, pe));
129: }
130: }
131:
132: // Parse an XML document from a system identifier (URI).
133: public void parse(java.lang.String systemId) throws SAXException,
134: IOException {
135: parse(new InputSource(systemId));
136: }
137:
138: // Allow an application to register a content event handler.
139: public void setContentHandler(ContentHandler handler) {
140: contentHandler_ = handler;
141: if (contentHandler_ != null)
142: contentHandler_.setDocumentLocator(new LocatorImpl());
143: }
144:
145: // Allow an application to register a DTD event handler.
146: public void setDTDHandler(DTDHandler handler) {
147: dtdHandler_ = handler;
148: }
149:
150: // Allow an application to register an entity resolver.
151: public void setEntityResolver(EntityResolver resolver) {
152: entityResolver_ = resolver;
153: }
154:
155: // Allow an application to register an error event handler.
156: public void setErrorHandler(ErrorHandler handler) {
157: errorHandler_ = handler;
158: }
159:
160: // Set the state of a feature.
161: public void setFeature(java.lang.String name, boolean value) {
162: }
163:
164: // Set the value of a property.
165: public void setProperty(java.lang.String name,
166: java.lang.Object value) {
167: }
168:
169: // ParseHandler methods
170:
171: public void setParseSource(ParseSource ps) {
172: parseSource_ = ps;
173: }
174:
175: public ParseSource getParseSource() {
176: return parseSource_;
177: }
178:
179: public void startDocument() throws ParseException {
180:
181: if (contentHandler_ != null) {
182: try {
183: contentHandler_.startDocument();
184: } catch (SAXException se) {
185: throw new ParseException("Exception in startDocument",
186: se);
187: }
188: }
189: }
190:
191: public void endDocument() throws ParseException {
192: if (contentHandler_ != null) {
193: try {
194: contentHandler_.endDocument();
195: } catch (SAXException se) {
196: throw new ParseException("Exception in endDocument", se);
197: }
198: }
199: }
200:
201: public void startElement(Element element)
202: throws ParseException {
203:
204: if (nsAware_)
205: {
206: nsSupport_.pushContext();
207: }
208:
209: if (contentHandler_ != null) {
210:
211: nameInfo_[0] = "";
212: nameInfo_[1] = "";
213:
214: String[] res;
215:
216: String aName, aValue;
217: AttributesImpl attrs = new AttributesImpl();
218: Enumeration enum = element.getAttributeNames();
219: while (enum.hasMoreElements()) {
220: aName = (String)enum.nextElement();
221: aValue = element.getAttribute(aName);
222: if (nsAware_) {
223: if (aName.startsWith("xmlns:")) {
224: String prefix = aName.substring(6);
225: //nsSupport_.declarePrefix(prefix, aValue);
226: try {
227: contentHandler_.startPrefixMapping(prefix, aValue);
228: } catch (SAXException se) {
229: throw new ParseException("Exception in startPrefixMapping", se);
230: }
231: continue;
232: }
233:
234:
235: res = nsSupport_.processName(aName, nameInfo_, true);
236: if (res == null)
237: throw new ParseException("Unknown prefix: " + aName);
238: }
239:
240: /*
241: System.out.println("Attr: namespace: " + nameInfo_[0] +
242: ". lName: " + nameInfo_[1] + ". fullName: "
243: + nameInfo_[2] + ". value: " + aValue);
244: */
245:
246: attrs.addAttribute(nameInfo_[0], nameInfo_[1], aName, "",
247: aValue);
248: }
249:
250: nameInfo_[0] = "";
251: nameInfo_[1] = "";
252:
253: String fullName = element.getTagName();
254: if (nsAware_) {
255: res = nsSupport_.processName(fullName, nameInfo_, false);
256: if (res == null)
257: throw new ParseException("Unknown prefix: " +
258: fullName);
259: }
260:
261: /*
262: System.out.println("Start Elem: namespace: " + nameInfo_[0] +
263: ". localName: " + nameInfo_[1] +
264: ". fullName: " + fullName);
265: */
266:
267: try {
268: contentHandler_.startElement(nameInfo_[0], nameInfo_[1],
269: fullName, attrs);
270: } catch (SAXException se) {
271: throw new ParseException("Exception in startElement", se);
272: }
273: }
274: }
275:
276: public void endElement(Element element) throws ParseException {
277: if (contentHandler_ != null) {
278: nameInfo_[0] = "";
279: nameInfo_[1] = "";
280:
281: String fullName = element.getTagName();
282: if (nsAware_) {
283: /*String[] res =*/nsSupport_.processName(fullName,
284: nameInfo_, false);
285: }
286:
287: /*
288: System.out.println("End Elem: namespace: " + nameInfo_[0] +
289: ". localName: " + nameInfo_[1] +
290: ". fullName: " + fullName);
291: */
292:
293: try {
294: contentHandler_.endElement(nameInfo_[0], nameInfo_[1],
295: fullName);
296: } catch (SAXException se) {
297: throw new ParseException("Exception in endElement", se);
298: }
299: }
300: if (nsAware_) {
301: Iterator prefixSet = nsSupport_.popContext();
302: if (contentHandler_ != null) {
303: try {
304: while (prefixSet.hasNext())
305: contentHandler_
306: .endPrefixMapping((String) prefixSet
307: .next());
308: } catch (SAXException se) {
309: throw new ParseException("Exception in endElement",
310: se);
311: }
312: }
313: }
314: }
315:
316: public void characters(char[] buf, int offset, int len)
317: throws ParseException {
318: if (contentHandler_ != null) {
319: boolean whitespace = true;
320: for (int i = 0; i < len; i++) {
321: if (buf[i] > ' ')
322: whitespace = false;
323: }
324: if (whitespace) {
325: try {
326: contentHandler_.ignorableWhitespace(buf, offset,
327: len);
328: } catch (SAXException se) {
329: throw new ParseException("Exception in characters",
330: se);
331: }
332: } else {
333: try {
334: contentHandler_.characters(buf, offset, len);
335: } catch (SAXException se) {
336: throw new ParseException("Exception in characters",
337: se);
338: }
339: }
340: }
341: }
342:
343: class LocatorImpl implements Locator {
344:
345: public int getColumnNumber() {
346: return -1;
347: }
348:
349: public int getLineNumber() {
350: if (parseSource_ != null)
351: return parseSource_.getLineNumber();
352: else
353: return -1;
354: }
355:
356: public String getPublicId() {
357: return null;
358: }
359:
360: public String getSystemId() {
361: if (parseSource_ != null)
362: return parseSource_.getSystemId();
363: else
364: return null;
365: }
366: }
367: }
368:
369: // $Log: XMLReaderImpl.java,v $
370: // Revision 1.4 2003/01/27 23:30:59 yuhongx
371: // Replaced Hashtable with HashMap.
372: //
373: // Revision 1.3 2002/11/06 02:59:55 eobrain
374: // Organize imputs to removed unused imports. Remove some unused local variables.
375: //
376: // Revision 1.2 2002/09/18 05:31:07 eobrain
377: // Improved error handling when cannot open URI.
378: //
379: // Revision 1.1.1.1 2002/08/19 05:04:13 eobrain
380: // import from HP Labs internal CVS
381: //
382: // Revision 1.9 2002/08/19 00:41:23 eob
383: // Tweak javadoc comment -- add period (full stop) so that Javadoc knows
384: // where is end of summary.
385: //
386: // Revision 1.8 2002/08/18 05:46:30 eob
387: // Add copyright and other formatting and commenting in preparation for
388: // release to SourceForge.
389: //
390: // Revision 1.7 2002/08/17 00:54:14 sermarti
391: //
392: // Revision 1.6 2002/08/17 00:38:24 sermarti
393: //
394: // Revision 1.5 2002/08/15 23:40:23 sermarti
395: //
396: // Revision 1.4 2002/08/09 22:36:49 sermarti
397: //
398: // Revision 1.3 2002/08/05 20:04:32 sermarti
399: //
400: // Revision 1.2 2002/08/01 23:29:17 sermarti
401: // Much faster Sparta parsing.
402: // Has debug features enabled by default. Currently toggled
403: // in ParseCharStream.java and recompiled.
404: //
405: // Revision 1.1 2002/07/24 23:55:43 sermarti
406: // SAX parser wrapper for Sparta that is JAXP compliant.
|