001: /*
002: * (C) Copyright 2002-2003, Andy Clark. All rights reserved.
003: *
004: * This file is distributed under an Apache style license. Please
005: * refer to the LICENSE file for specific details.
006: */
007:
008: package org.cyberneko.pull.parsers;
009:
010: import org.cyberneko.pull.XMLEvent;
011: import org.cyberneko.pull.XMLPullParser;
012: import org.cyberneko.pull.util.EventCollector;
013: import org.cyberneko.pull.util.EventQueue;
014:
015: import java.io.IOException;
016: import java.util.Locale;
017:
018: import org.apache.xerces.xni.Augmentations;
019: import org.apache.xerces.xni.XNIException;
020: import org.apache.xerces.xni.parser.XMLConfigurationException;
021: import org.apache.xerces.xni.parser.XMLEntityResolver;
022: import org.apache.xerces.xni.parser.XMLErrorHandler;
023: import org.apache.xerces.xni.parser.XMLInputSource;
024: import org.apache.xerces.xni.parser.XMLPullParserConfiguration;
025:
026: /**
027: * An implementation of a pull parser that can use any standard
028: * XNI parser configuration as a driver.
029: * <p>
030: * <strong>Note:</strong>
031: * This class is provided for convenience. However, for the best
032: * performance, a parser should be implemented directly to the
033: * NekoPull interfaces to provide pull parsing functionality.
034: *
035: * @author Andy Clark
036: *
037: * @version $Id$
038: */
039: public class Xerces2 implements XMLPullParser {
040:
041: //
042: // Constants
043: //
044:
045: // features
046:
047: /** Feature identifer: reuse buffers. */
048: protected static final String REUSE_BUFFERS = "http://apache.org/xml/features/scanner/reuse-buffers";
049:
050: // private
051:
052: /** Standard configuration. */
053: private static final String CONFIG = "org.apache.xerces.parsers.StandardParserConfiguration";
054:
055: //
056: // Data
057: //
058:
059: /** Finished parsing. */
060: protected boolean fDone;
061:
062: /** XNI pull parser configuration. */
063: protected XMLPullParserConfiguration fConfiguration;
064:
065: /** Event collector. */
066: protected EventCollector fEventCollector = new EventCollector();
067:
068: //
069: // Constructors
070: //
071:
072: /** Constructs a pull parser with the standard configuration. */
073: public Xerces2() {
074: this ((XMLPullParserConfiguration) ObjectFactory.createObject(
075: CONFIG, CONFIG));
076: } // <init>()
077:
078: /** Constructs a pull parser with the specified configuration. */
079: public Xerces2(XMLPullParserConfiguration config) {
080: fConfiguration = config;
081: // REVISIT: This functionality is not implemented in the Xerces2
082: // reference implementation of XNI, yet. -Ac
083: try {
084: fConfiguration.setFeature(REUSE_BUFFERS, false);
085: } catch (Exception e) {
086: // ignore
087: //System.err.println(">>> "+e.getClass().getName()+":"+e.getMessage());
088: }
089: fConfiguration.setDocumentHandler(fEventCollector);
090: } // <init>(XMLParserConfiguration)
091:
092: //
093: // XMLPullParser methods
094: //
095:
096: // parsing
097:
098: /**
099: * Sets the input source for the document to parse.
100: *
101: * @param inputSource The document's input source.
102: *
103: * @exception XMLConfigurationException Thrown if there is a
104: * configuration error when initializing the
105: * parser.
106: * @exception IOException Thrown on I/O error.
107: *
108: * @see #nextEvent
109: */
110: public void setInputSource(XMLInputSource inputSource)
111: throws XMLConfigurationException, IOException {
112: fDone = false;
113: fEventCollector.reset(fConfiguration);
114: fConfiguration.setInputSource(inputSource);
115: } // setInputSource(inputSource)
116:
117: /**
118: * If the application decides to terminate parsing before the xml document
119: * is fully parsed, the application should call this method to free any
120: * resource allocated during parsing. For example, close all opened streams.
121: */
122: public void cleanup() {
123: fConfiguration.cleanup();
124: } // cleanup()
125:
126: // generic configuration
127:
128: /**
129: * Sets the state of a feature. This method is called by the parser
130: * and gets propagated to components in this parser configuration.
131: *
132: * @param featureId The feature identifier.
133: * @param state The state of the feature.
134: *
135: * @throws XMLConfigurationException Thrown if there is a configuration
136: * error.
137: */
138: public void setFeature(String featureId, boolean state)
139: throws XMLConfigurationException {
140: fConfiguration.setFeature(featureId, state);
141: } // setFeature(String,boolean)
142:
143: /**
144: * Sets the value of a property. This method is called by the parser
145: * and gets propagated to components in this parser configuration.
146: *
147: * @param propertyId The property identifier.
148: * @param value The value of the property.
149: *
150: * @throws XMLConfigurationException Thrown if there is a configuration
151: * error.
152: */
153: public void setProperty(String propertyId, Object value)
154: throws XMLConfigurationException {
155: fConfiguration.setProperty(propertyId, value);
156: } // setProperty(String,Object)
157:
158: //
159: // XMLEventIterator methods
160: //
161:
162: /**
163: * Returns the next event in the document or null if there are
164: * no more events. This method will return one and only one event
165: * if it is available; it will never return an event chain (i.e.
166: * an event with a non-null <code>next</code> field).
167: *
168: * @exception XNIException Any XNI exception, possibly wrapping
169: * another exception.
170: * @exception IOException An IO exception from the parser, possibly
171: * from a byte stream or character stream
172: * supplied by the parser.
173: *
174: * @see #setInputSource
175: */
176: public XMLEvent nextEvent() throws XNIException, IOException {
177: while (!fDone && fEventCollector.isEmpty()) {
178: fDone = !fConfiguration.parse(false);
179: }
180: return fEventCollector.dequeue();
181: } // nextEvent():XMLEvent
182:
183: //
184: // XMLComponentManager methods
185: //
186:
187: /**
188: * Returns the state of a feature.
189: *
190: * @param featureId The feature identifier.
191: *
192: * @throws XMLConfigurationException Thrown if there is a configuration
193: * error.
194: */
195: public boolean getFeature(String featureId)
196: throws XMLConfigurationException {
197: return fConfiguration.getFeature(featureId);
198: } // getFeature(String):boolean
199:
200: /**
201: * Returns the value of a property.
202: *
203: * @param propertyId The property identifier.
204: *
205: * @throws XMLConfigurationException Thrown if there is a configuration
206: * error.
207: */
208: public Object getProperty(String propertyId)
209: throws XMLConfigurationException {
210: return fConfiguration.getProperty(propertyId);
211: } // getProperty(String):Object
212:
213: // handlers
214:
215: /**
216: * Sets the error handler.
217: *
218: * @param errorHandler The error resolver.
219: */
220: public void setErrorHandler(XMLErrorHandler errorHandler) {
221: fConfiguration.setErrorHandler(errorHandler);
222: } // setErrorHandler(XMLErrorHandler)
223:
224: /** Returns the registered error handler. */
225: public XMLErrorHandler getErrorHandler() {
226: return fConfiguration.getErrorHandler();
227: } // getErrorHandler():XMLErrorHandler
228:
229: // other settings
230:
231: /**
232: * Sets the entity resolver.
233: *
234: * @param entityResolver The new entity resolver.
235: */
236: public void setEntityResolver(XMLEntityResolver entityResolver) {
237: fConfiguration.setEntityResolver(entityResolver);
238: } // setEntityResolver(XMLEntityResolver)
239:
240: /** Returns the registered entity resolver. */
241: public XMLEntityResolver getEntityResolver() {
242: return fConfiguration.getEntityResolver();
243: } // getEntityResolver():XMLEntityResolver
244:
245: /**
246: * Set the locale to use for messages.
247: *
248: * @param locale The locale object to use for localization of messages.
249: *
250: * @exception XNIException Thrown if the parser does not support the
251: * specified locale.
252: */
253: public void setLocale(Locale locale) throws XNIException {
254: fConfiguration.setLocale(locale);
255: } // setLocale(Locale)
256:
257: /** Returns the locale. */
258: public Locale getLocale() {
259: return fConfiguration.getLocale();
260: } // getLocale():Locale
261:
262: } // class Xerces2
|