001: package net.myvietnam.mvncore.configuration;
002:
003: /* ====================================================================
004: * The Apache Software License, Version 1.1
005: *
006: * Copyright (c) 1999-2003 The Apache Software Foundation. All rights
007: * reserved.
008: *
009: * Redistribution and use in source and binary forms, with or without
010: * modification, are permitted provided that the following conditions
011: * are met:
012: *
013: * 1. Redistributions of source code must retain the above copyright
014: * notice, this list of conditions and the following disclaimer.
015: *
016: * 2. Redistributions in binary form must reproduce the above copyright
017: * notice, this list of conditions and the following disclaimer in
018: * the documentation and/or other materials provided with the
019: * distribution.
020: *
021: * 3. The end-user documentation included with the redistribution, if
022: * any, must include the following acknowledgement:
023: * "This product includes software developed by the
024: * Apache Software Foundation (http://www.apache.org/)."
025: * Alternately, this acknowledgement may appear in the software itself,
026: * if and wherever such third-party acknowledgements normally appear.
027: *
028: * 4. The names "The Jakarta Project", "Commons", and "Apache Software
029: * Foundation" must not be used to endorse or promote products derived
030: * from this software without prior written permission. For written
031: * permission, please contact apache@apache.org.
032: *
033: * 5. Products derived from this software may not be called "Apache"
034: * nor may "Apache" appear in their names without prior written
035: * permission of the Apache Software Foundation.
036: *
037: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
038: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
039: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
040: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
041: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
042: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
043: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
044: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
045: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
046: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
047: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
048: * SUCH DAMAGE.
049: * ====================================================================
050: *
051: * This software consists of voluntary contributions made by many
052: * individuals on behalf of the Apache Software Foundation. For more
053: * information on the Apache Software Foundation, please see
054: * <http://www.apache.org/>.
055: */
056:
057: import java.io.IOException;
058:
059: import org.xml.sax.Attributes;
060: import org.xml.sax.ContentHandler;
061: import org.xml.sax.DTDHandler;
062: import org.xml.sax.EntityResolver;
063: import org.xml.sax.ErrorHandler;
064: import org.xml.sax.InputSource;
065: import org.xml.sax.SAXException;
066: import org.xml.sax.XMLReader;
067: import org.xml.sax.helpers.AttributesImpl;
068:
069: /**
070: * <p>A base class for "faked" <code>XMLReader</code> classes
071: * that transform a configuration object in a set of SAX parsing events.</p>
072: * <p>This class provides dummy implementations for most of the methods
073: * defined in the <code>XMLReader</code> interface that are not used for this
074: * special purpose. There will be concrete sub classes that process specific
075: * configuration classes.</p>
076: *
077: * @author <a href="mailto:oliver.heger@t-online.de">Oliver Heger</a>
078: * @version $Id: ConfigurationXMLReader.java,v 1.1 2003/12/09 08:25:30 huumai Exp $
079: */
080: public abstract class ConfigurationXMLReader implements XMLReader {
081: /** Constant for the namespace URI.*/
082: protected static final String NS_URI = "";
083:
084: /** Constant for the default name of the root element.*/
085: private static final String DEFAULT_ROOT_NAME = "config";
086:
087: /** An empty attributes object.*/
088: private static final Attributes EMPTY_ATTRS = new AttributesImpl();
089:
090: /** Stores the content handler.*/
091: private ContentHandler contentHandler;
092:
093: /** Stores an exception that occurred during parsing.*/
094: private SAXException exception;
095:
096: /** Stores the name for the root element.*/
097: private String rootName;
098:
099: /**
100: * Creates a new instance of <code>ConfigurationXMLReader</code>.
101: */
102: protected ConfigurationXMLReader() {
103: super ();
104: setRootName(DEFAULT_ROOT_NAME);
105: }
106:
107: /**
108: * Parses the acutal configuration object. The passed system ID will be
109: * ignored.
110: * @param systemId the system ID (ignored)
111: * @throws IOException if no configuration was specified
112: * @throws SAXException if an error occurs during parsing
113: */
114: public void parse(String systemId) throws IOException, SAXException {
115: parseConfiguration();
116: }
117:
118: /**
119: * Parses the acutal configuration object. The passed input source will be
120: * ignored.
121: * @param input the input source (ignored)
122: * @throws IOException if no configuration was specified
123: * @throws SAXException if an error occurs during parsing
124: */
125: public void parse(InputSource input) throws IOException,
126: SAXException {
127: parseConfiguration();
128: }
129:
130: /**
131: * Dummy implementation of the interface method.
132: * @param name the name of the feature
133: * @return always <b>false</b> (no features are supported)
134: */
135: public boolean getFeature(String name) {
136: return false;
137: }
138:
139: /**
140: * Dummy implementation of the interface method.
141: * @param name the name of the feature to be set
142: * @param value the value of the feature
143: */
144: public void setFeature(String name, boolean value) {
145: }
146:
147: /**
148: * Returns the actually set content handler.
149: * @return the content handler
150: */
151: public ContentHandler getContentHandler() {
152: return contentHandler;
153: }
154:
155: /**
156: * Sets the content handler. The object specified here will receive SAX
157: * events during parsing.
158: * @param handler the content handler
159: */
160: public void setContentHandler(ContentHandler handler) {
161: contentHandler = handler;
162: }
163:
164: /**
165: * Returns the DTD handler. This class does not support DTD handlers,
166: * so this method always returns <b>null</b>.
167: * @return the DTD handler
168: */
169: public DTDHandler getDTDHandler() {
170: return null;
171: }
172:
173: /**
174: * Sets the DTD handler. The passed value is ignored.
175: * @param handler the handler to be set
176: */
177: public void setDTDHandler(DTDHandler handler) {
178: }
179:
180: /**
181: * Returns the entity resolver. This class does not support an entity
182: * resolver, so this method always returns <b>null</b>.
183: * @return the entity resolver
184: */
185: public EntityResolver getEntityResolver() {
186: return null;
187: }
188:
189: /**
190: * Sets the entity resolver. The passed value is ignored.
191: * @param resolver the entity resolver
192: */
193: public void setEntityResolver(EntityResolver resolver) {
194: }
195:
196: /**
197: * Returns the error handler. This class does not support an error handler,
198: * so this method always returns <b>null</b>.
199: * @return the error handler
200: */
201: public ErrorHandler getErrorHandler() {
202: return null;
203: }
204:
205: /**
206: * Sets the error handler. The passed value is ignored.
207: * @param handler the error handler
208: */
209: public void setErrorHandler(ErrorHandler handler) {
210: }
211:
212: /**
213: * Dummy implementation of the interface method. No properties are
214: * supported, so this method always returns <b>null</b>.
215: * @param name the name of the requested property
216: * @return the property value
217: */
218: public Object getProperty(String name) {
219: return null;
220: }
221:
222: /**
223: * Dummy implementation of the interface method. No properties are
224: * supported, so a call of this method just has no effect.
225: * @param name the property name
226: * @param value the property value
227: */
228: public void setProperty(String name, Object value) {
229: }
230:
231: /**
232: * Returns the name to be used for the root element.
233: * @return the name for the root element
234: */
235: public String getRootName() {
236: return rootName;
237: }
238:
239: /**
240: * Sets the name for the root element.
241: * @param string the name for the root element.
242: */
243: public void setRootName(String string) {
244: rootName = string;
245: }
246:
247: /**
248: * Fires a SAX element start event.
249: * @param name the name of the actual element
250: * @param attribs the attributes of this element (can be <b>null</b>)
251: */
252: protected void fireElementStart(String name, Attributes attribs) {
253: if (getException() == null) {
254: try {
255: Attributes at = (attribs == null) ? EMPTY_ATTRS
256: : attribs;
257: getContentHandler()
258: .startElement(NS_URI, name, name, at);
259: } /* try */
260: catch (SAXException ex) {
261: exception = ex;
262: } /* catch */
263: } /* if */
264: }
265:
266: /**
267: * Fires a SAX element end event.
268: * @param name the name of the affected element
269: */
270: protected void fireElementEnd(String name) {
271: if (getException() == null) {
272: try {
273: getContentHandler().endElement(NS_URI, name, name);
274: } /* try */
275: catch (SAXException ex) {
276: exception = ex;
277: } /* catch */
278: } /* if */
279: }
280:
281: /**
282: * Fires a SAX characters event.
283: * @param text the text
284: */
285: protected void fireCharacters(String text) {
286: if (getException() == null) {
287: try {
288: char[] ch = text.toCharArray();
289: getContentHandler().characters(ch, 0, ch.length);
290: } /* try */
291: catch (SAXException ex) {
292: exception = ex;
293: } /* catch */
294: } /* if */
295: }
296:
297: /**
298: * Returns a reference to an exception that occurred during parsing.
299: * @return a SAXExcpetion or <b>null</b> if none occurred
300: */
301: public SAXException getException() {
302: return exception;
303: }
304:
305: /**
306: * Parses the configuration object and generates SAX events. This is the
307: * main processing method.
308: * @throws IOException if no configuration has been specified
309: * @throws SAXException if an error occurs during parsing
310: */
311: protected void parseConfiguration() throws IOException,
312: SAXException {
313: if (getParsedConfiguration() == null) {
314: throw new IOException("No configuration specified!");
315: } /* if */
316:
317: if (getContentHandler() != null) {
318: exception = null;
319: getContentHandler().startDocument();
320: processKeys();
321: if (getException() != null) {
322: throw getException();
323: } /* if */
324: getContentHandler().endDocument();
325: } /* if */
326: }
327:
328: /**
329: * Returns a reference to the configuration that is parsed by this object.
330: * @return the parsed configuration
331: */
332: public abstract Configuration getParsedConfiguration();
333:
334: /**
335: * Processes all keys stored in the actual configuration. This method is
336: * called by <code>parseConfiguration()</code> to start the main parsing
337: * process. <code>parseConfiguration()</code> calls the content handler's
338: * <code>startDocument()</code> and <code>endElement()</code> methods
339: * and cares for exception handling. The remaining actions are left to this
340: * method that must be implemented in a concrete sub class.
341: * @throws IOException if an IO error occurs
342: * @throws SAXException if a SAX error occurs
343: */
344: protected abstract void processKeys() throws IOException,
345: SAXException;
346: }
|