001 /* ========================================================================
002 * JCommon : a free general purpose class library for the Java(tm) platform
003 * ========================================================================
004 *
005 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
006 *
007 * Project Info: http://www.jfree.org/jcommon/index.html
008 *
009 * This library is free software; you can redistribute it and/or modify it
010 * under the terms of the GNU Lesser General Public License as published by
011 * the Free Software Foundation; either version 2.1 of the License, or
012 * (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful, but
015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017 * License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this library; if not, write to the Free Software
021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
022 * USA.
023 *
024 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025 * in the United States and other countries.]
026 *
027 * ------------
028 * FrontendDefaultHandler.java
029 * ------------
030 * (C) Copyright 2002-2005, by Object Refinery Limited.
031 *
032 * Original Author: David Gilbert (for Object Refinery Limited);
033 * Contributor(s): -;
034 *
035 * $Id: FrontendDefaultHandler.java,v 1.9 2008/09/10 09:20:49 mungady Exp $
036 *
037 * Changes
038 * -------
039 * 02-Feb-2005 : Initial version.
040 *
041 */
042 package org.jfree.xml;
043
044 import java.net.MalformedURLException;
045 import java.net.URL;
046 import java.util.Iterator;
047 import java.util.Enumeration;
048
049 import org.jfree.util.Configuration;
050 import org.jfree.util.DefaultConfiguration;
051 import org.xml.sax.Locator;
052 import org.xml.sax.SAXException;
053 import org.xml.sax.helpers.DefaultHandler;
054
055 /**
056 * The frontenddefault handler connects the SAX-backend with the handler implementations.
057 * It must be the base class for all parser implementations used by the ParserFrontEnd.
058 *
059 * @author Thomas Morgner
060 */
061 public abstract class FrontendDefaultHandler extends DefaultHandler implements Configuration {
062 /**
063 * A key for the content base.
064 */
065 public static final String CONTENTBASE_KEY = "content-base";
066
067 /**
068 * Storage for the parser configuration.
069 */
070 private DefaultConfiguration parserConfiguration;
071
072 /**
073 * The DocumentLocator can be used to resolve the current parse position.
074 */
075 private Locator locator;
076
077 /**
078 * The current comment handler used to receive xml comments.
079 */
080 private final CommentHandler commentHandler;
081
082 /**
083 * Default constructor.
084 */
085 protected FrontendDefaultHandler() {
086 this.parserConfiguration = new DefaultConfiguration();
087 this.commentHandler = new CommentHandler();
088 }
089
090 /**
091 * Returns the comment handler that is used to collect comments.
092 *
093 * @return the comment handler.
094 */
095 public CommentHandler getCommentHandler() {
096 return this.commentHandler;
097 }
098
099 /**
100 * Receive an object for locating the origin of SAX document events.
101 * <p/>
102 * The locator allows the application to determine the end position of
103 * any document-related event, even if the parser is not reporting an
104 * error. Typically, the application will use this information for
105 * reporting its own errors (such as character content that does not
106 * match an application's business rules). The information returned by
107 * the locator is probably not sufficient for use with a search engine.
108 *
109 * @param locator the locator.
110 */
111 public void setDocumentLocator(final Locator locator) {
112 this.locator = locator;
113 }
114
115 /**
116 * Returns the current locator.
117 *
118 * @return the locator.
119 */
120 public Locator getLocator() {
121 return this.locator;
122 }
123
124 /**
125 * Returns the configuration property with the specified key.
126 *
127 * @param key the property key.
128 * @return the property value.
129 */
130 public String getConfigProperty(final String key) {
131 return getConfigProperty(key, null);
132 }
133
134 /**
135 * Returns the configuration property with the specified key (or the specified default value
136 * if there is no such property).
137 * <p/>
138 * If the property is not defined in this configuration, the code will lookup the property in
139 * the parent configuration.
140 *
141 * @param key the property key.
142 * @param defaultValue the default value.
143 * @return the property value.
144 */
145 public String getConfigProperty(final String key, final String defaultValue) {
146 return this.parserConfiguration.getConfigProperty(key, defaultValue);
147 }
148
149 /**
150 * Sets a parser configuration value.
151 *
152 * @param key the key.
153 * @param value the value.
154 */
155 public void setConfigProperty(final String key, final String value) {
156 if (value == null) {
157 this.parserConfiguration.remove(key);
158 }
159 else {
160 this.parserConfiguration.setProperty(key, value);
161 }
162 }
163
164 /**
165 * Returns the configuration properties.
166 *
167 * @return An enumeration of the configuration properties.
168 */
169 public Enumeration getConfigProperties()
170 {
171 return this.parserConfiguration.getConfigProperties();
172 }
173
174 /**
175 * Returns a new instance of the parser.
176 *
177 * @return a new instance of the parser.
178 */
179 public abstract FrontendDefaultHandler newInstance();
180
181 /**
182 * Returns all keys with the given prefix.
183 *
184 * @param prefix the prefix
185 * @return the iterator containing all keys with that prefix
186 */
187 public Iterator findPropertyKeys(final String prefix) {
188 return this.parserConfiguration.findPropertyKeys(prefix);
189 }
190
191 /**
192 * Returns the parse result. This method is called at the end of the
193 * parsing process and expects the generated object.
194 *
195 * @return the object.
196 * @throws SAXException if something went wrong.
197 */
198 public abstract Object getResult() throws SAXException;
199
200 /**
201 * Gets the ContentBase used to resolve relative URLs.
202 *
203 * @return the current contentbase, or null if no contentBase is set.
204 */
205 public URL getContentBase() {
206 final String contentBase = getConfigProperty(Parser.CONTENTBASE_KEY);
207 if (contentBase == null) {
208 return null;
209 }
210 try {
211 return new URL(contentBase);
212 }
213 catch (MalformedURLException mfe) {
214 throw new IllegalStateException("Content Base is illegal." + contentBase);
215 }
216 }
217
218 /**
219 * Returns a clone of this instance.
220 *
221 * @return A clone.
222 *
223 * @throws CloneNotSupportedException if there is a problem cloning.
224 */
225 public Object clone () throws CloneNotSupportedException
226 {
227 final FrontendDefaultHandler o = (FrontendDefaultHandler) super.clone();
228 o.parserConfiguration = (DefaultConfiguration) this.parserConfiguration.clone();
229 return o;
230 }
231 }