001: /*
002: * Geotools2 - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package org.geotools.xml;
018:
019: import java.net.URI;
020: import java.util.Stack;
021: import java.util.logging.Level;
022: import java.util.logging.Logger;
023:
024: import org.geotools.xml.handlers.xsi.IgnoreHandler;
025: import org.geotools.xml.handlers.xsi.RootHandler;
026: import org.geotools.xml.schema.Schema;
027: import org.xml.sax.Attributes;
028: import org.xml.sax.Locator;
029: import org.xml.sax.SAXException;
030: import org.xml.sax.SAXParseException;
031: import org.xml.sax.helpers.DefaultHandler;
032:
033: /**
034: * XSISAXHandler purpose.
035: *
036: * <p>
037: * This is a schema handler. Code here has been modified from code written by
038: * Ian Schneider.
039: * </p>
040: *
041: * <p>
042: * This class contains one stack used to store part of the parse tree. The
043: * ElementHandlers found on the stack have direct next handlers placed on the
044: * stack. So here's the warning, be careful to read how you may be affecting
045: * (or forgetting to affect) the stack.
046: * </p>
047: *
048: * @author dzwiers, Refractions Research, Inc. http://www.refractions.net
049: * @author $Author:$ (last modification)
050: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/xml/src/main/java/org/geotools/xml/XSISAXHandler.java $
051: * @version $Id: XSISAXHandler.java 27862 2007-11-12 19:51:19Z desruisseaux $
052: *
053: * @see XSIElementHandler
054: */
055: public class XSISAXHandler extends DefaultHandler {
056: // the logger -- should be used for debugging (assuming there are bugs LOL)
057: protected final static Logger logger = org.geotools.util.logging.Logging
058: .getLogger("net.refractions.xsi.sax");
059:
060: // the stack of handers representing a portion of the parse tree
061: private Stack handlers = new Stack();
062:
063: // The schema being used to parse into
064: private Schema schema = null;
065:
066: // The root parsing element
067: protected RootHandler rootHandler = null;
068:
069: // the Locator is used for end-user debugging
070: private Locator locator;
071:
072: /** Collects string chunks in {@link #characters(char[], int, int)}
073: * callback to be handled at the beggining of {@link #endElement(String, String, String)}
074: */
075: private StringBuffer characters = new StringBuffer();
076:
077: // the schema uri being parsed. This is important to resolve relative uris
078: // private URI uri;
079:
080: /**
081: * should never be called
082: */
083: private XSISAXHandler() {
084: /* not used*/
085: }
086:
087: /**
088: * Stores the uri being parsed to help resolve relative uris within the
089: * document.
090: *
091: * @param uri
092: */
093: public XSISAXHandler(URI uri) {
094: // this.uri = uri;
095: rootHandler = new RootHandler(uri);
096: }
097:
098: /**
099: * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String,
100: * java.lang.String)
101: */
102: public void startPrefixMapping(String arg0, String arg1) {
103: rootHandler.startPrefixMapping(arg0, arg1);
104: }
105:
106: /**
107: * Implementation of endDocument.
108: *
109: * @see org.xml.sax.ContentHandler#endDocument()
110: */
111: public void endDocument() {
112: handlers.pop();
113: }
114:
115: /**
116: * Implementation of startDocument.
117: *
118: * @see org.xml.sax.ContentHandler#startDocument()
119: */
120: public void startDocument() {
121: try {
122: handlers.push(rootHandler);
123: } catch (RuntimeException e) {
124: logger.warning(e.toString());
125: throw e;
126: }
127: }
128:
129: /**
130: * Implementation of characters. push String
131: *
132: * @param ch
133: * @param start
134: * @param length
135: *
136: * @throws SAXException
137: *
138: * @see org.xml.sax.ContentHandler#characters(char[], int, int)
139: */
140: public void characters(char[] ch, int start, int length)
141: throws SAXException {
142: characters.append(ch, start, length);
143: }
144:
145: /**
146: * Handles the string chunks collected in {@link #characters}.
147: */
148: private void handleCharacters() throws SAXException {
149: final String text = characters.toString();
150: characters.setLength(0);
151: if (text.length() == 0) {
152: return;
153: }
154: XSIElementHandler peek = null;
155: try {
156: if ((text != null) && !"".equals(text.trim())) {
157: peek = (XSIElementHandler) handlers.peek();
158: peek.characters(text);
159: }
160: } catch (SAXException e) {
161: logger.warning(e.toString());
162: throw e;
163: }
164: }
165:
166: /**
167: * Implementation of endElement. push NS,Name
168: *
169: * @param namespaceURI
170: * @param localName
171: * @param qName
172: *
173: * @throws SAXException
174: *
175: * @see org.xml.sax.ContentHandler#endElement(java.lang.String,
176: * java.lang.String, java.lang.String)
177: */
178: public void endElement(String namespaceURI, String localName,
179: String qName) throws SAXException {
180: handleCharacters();
181: logger.fine("END: " + qName);
182:
183: try {
184: XSIElementHandler element = (XSIElementHandler) handlers
185: .pop();
186: element.endElement(namespaceURI, localName);
187: } catch (SAXException e) {
188: logger.warning(e.toString());
189: throw e;
190: }
191: }
192:
193: /**
194: * Implementation of startElement.
195: *
196: * @param namespaceURI
197: * @param localName
198: * @param qName
199: * @param atts
200: *
201: * @throws SAXException
202: *
203: * @see org.xml.sax.ContentHandler#startElement(java.lang.String,
204: * java.lang.String, java.lang.String, org.xml.sax.Attributes)
205: */
206: public void startElement(String namespaceURI, String localName,
207: String qName, Attributes atts) throws SAXException {
208: characters.setLength(0);
209: logger.fine("START: " + qName);
210:
211: try {
212: XSIElementHandler eh = ((XSIElementHandler) handlers.peek())
213: .getHandler(namespaceURI, localName);
214: logger.finest("Parent Node = "
215: + ((XSIElementHandler) handlers.peek()).getClass()
216: .getName());
217:
218: if (eh == null) {
219: eh = new IgnoreHandler();
220: }
221:
222: logger.finest("This Node = " + eh.getClass().getName());
223: logger.finest("This Node = " + localName + " :: "
224: + namespaceURI);
225:
226: handlers.push(eh);
227: eh.startElement(namespaceURI, localName, atts);
228: } catch (SAXException e) {
229: logger.warning(e.toString());
230: throw e;
231: }
232: }
233:
234: /**
235: * <p>
236: * Sets the logging level for all the XSISAXHandlers.
237: * </p>
238: *
239: * @param l
240: */
241: public static void setLogLevel(Level l) {
242: logger.setLevel(l);
243: XSIElementHandler.setLogLevel(l);
244: }
245:
246: /**
247: * getSchema purpose.
248: *
249: * <p>
250: * This method should be called only after the parse has been completed.
251: * This method will then return a compressed schema instance.
252: * </p>
253: *
254: * @return schema
255: *
256: * @throws SAXException
257: */
258: public Schema getSchema() throws SAXException {
259: if (schema == null) {
260: schema = rootHandler.getSchema();
261: }
262:
263: return schema;
264: }
265:
266: /**
267: * Implementation of error.
268: *
269: * @param exception
270: *
271: * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
272: */
273: public void error(SAXParseException exception) {
274: logger.severe("ERROR " + exception.getMessage());
275: logger.severe("col " + locator.getColumnNumber() + ", line "
276: + locator.getLineNumber());
277: }
278:
279: /**
280: * Implementation of fatalError.
281: *
282: * @param exception
283: *
284: * @throws SAXException
285: *
286: * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
287: */
288: public void fatalError(SAXParseException exception)
289: throws SAXException {
290: logger.severe("FATAL " + exception.getMessage());
291: logger.severe("col " + locator.getColumnNumber() + ", line "
292: + locator.getLineNumber());
293: throw exception;
294: }
295:
296: /**
297: * Implementation of warning.
298: *
299: * @param exception
300: *
301: * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
302: */
303: public void warning(SAXParseException exception) {
304: logger.warning("WARN " + exception.getMessage());
305: logger.severe("col " + locator.getColumnNumber() + ", line "
306: + locator.getLineNumber());
307: }
308:
309: /**
310: * @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
311: */
312: public void setDocumentLocator(Locator locator) {
313: super.setDocumentLocator(locator);
314: this.locator = locator;
315: }
316: }
|