001: /*
002: * The JTS Topology Suite is a collection of Java classes that
003: * implement the fundamental operations required to validate a given
004: * geo-spatial data set to a known topological specification.
005: *
006: * Copyright (C) 2001 Vivid Solutions
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Lesser General Public
010: * License as published by the Free Software Foundation; either
011: * version 2.1 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public
019: * License along with this library; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021: *
022: * For more information, contact:
023: *
024: * Vivid Solutions
025: * Suite #1A
026: * 2328 Government Street
027: * Victoria BC V8T 5G5
028: * Canada
029: *
030: * (250)385-6040
031: * www.vividsolutions.com
032: */
033: package com.vividsolutions.jts.io.gml2;
034:
035: import java.util.*;
036:
037: import org.xml.sax.*;
038: import org.xml.sax.helpers.AttributesImpl;
039: import org.xml.sax.helpers.DefaultHandler;
040:
041: import com.vividsolutions.jts.geom.Geometry;
042: import com.vividsolutions.jts.geom.GeometryFactory;
043: import com.vividsolutions.jts.io.gml2.GeometryStrategies.ParseStrategy;
044:
045: /**
046: * When you encounter some GML Geometry elements, you may either delegate the events to this handler.
047: *
048: * This handler ignores both namespaces and prefixes. These mappings may be included at a later date, but for the moment are left as an exercise for the reader.
049: *
050: * Hints:
051: * If your parent handler is a DefaultHandler register the parent handler to receive the errors and locator calls.
052: * Use the @see com.vividsolutions.jts.io.gml2.GeometryStrategies#findStrategy(String, String) to help check for applicability
053: *
054: * @see DefaultHandler
055: *
056: * @author David Zwiers, Vivid Solutions.
057: */
058: public class GMLHandler extends DefaultHandler {
059:
060: /**
061: * This class is intended to log the SAX acitivity within a given element until it's termination.
062: *
063: * At this time, a new object of value is created and passed to the parent. An object of value is typically either java.lang.* or a JTS Geometry
064: *
065: * This class is not intended for use outside this distribution, and may change in subsequent versions.
066: *
067: * @author David Zwiers, Vivid Solutions.
068: */
069: static class Handler {
070: protected Attributes attrs = null;
071: protected ParseStrategy strategy;
072:
073: /**
074: * @param strategy
075: * @param attributes Nullable
076: */
077: public Handler(ParseStrategy strategy, Attributes attributes) {
078: if (attributes != null)
079: this .attrs = new AttributesImpl(attributes);
080: this .strategy = strategy;
081: }
082:
083: protected StringBuffer text = null;
084:
085: /**
086: * Caches text for the future
087: * @param str
088: */
089: public void addText(String str) {
090: if (text == null)
091: text = new StringBuffer();
092: text.append(str);
093: }
094:
095: protected List children = null;
096:
097: /**
098: * Store param for the future
099: *
100: * @param obj
101: */
102: public void keep(Object obj) {
103: if (children == null)
104: children = new LinkedList();
105: children.add(obj);
106:
107: }
108:
109: /**
110: * @param gf GeometryFactory
111: * @return Parsed Object
112: * @throws SAXException
113: */
114: public Object create(GeometryFactory gf) throws SAXException {
115: return strategy.parse(this , gf);
116: }
117: }
118:
119: private Stack stack = new Stack();
120: private ErrorHandler delegate = null;
121: private GeometryFactory gf = null;
122:
123: /**
124: * Allows the user to specify a delegate object for error / warning messages.
125: *
126: * If the delegate also implements ContentHandler then the document Locator will be passed on.
127: * @param gf Geometry Factory
128: *
129: * @see ErrorHandler
130: * @see ContentHandler
131: * @see ContentHandler#setDocumentLocator(org.xml.sax.Locator)
132: * @see org.xml.sax.Locator
133: *
134: * @param delegate Nullable
135: */
136: public GMLHandler(GeometryFactory gf, ErrorHandler delegate) {
137: this .delegate = delegate;
138: this .gf = gf;
139: stack.push(new Handler(null, null));
140: }
141:
142: /**
143: * This method should only be called AFTER the parser has completed execution
144: *
145: * @return Last Geometry Parsed, or a collection when there is morethan one geometry
146: */
147: public Geometry getGeometry() {
148: if (stack.size() == 1) {
149: Handler h = (Handler) stack.peek();
150: if (h.children.size() == 1)
151: return (Geometry) h.children.get(0);
152: return gf.createGeometryCollection((Geometry[]) h.children
153: .toArray(new Geometry[stack.size()]));
154: }
155: throw new IllegalStateException(
156: "Parse did not complete as expected, there are "
157: + stack.size() + " elements on the Stack");
158: }
159:
160: //////////////////////////////////////////////
161: // Parsing Methods
162:
163: /**
164: * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
165: */
166: public void characters(char[] ch, int start, int length)
167: throws SAXException {
168: if (!stack.isEmpty())
169: ((Handler) stack.peek()).addText(new String(ch, start,
170: length));
171: }
172:
173: /**
174: * @see org.xml.sax.helpers.DefaultHandler#ignorableWhitespace(char[], int, int)
175: */
176: public void ignorableWhitespace(char[] ch, int start, int length)
177: throws SAXException {
178: if (!stack.isEmpty())
179: ((Handler) stack.peek()).addText(" ");
180: }
181:
182: /**
183: * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
184: */
185: public void endElement(String uri, String localName, String qName)
186: throws SAXException {
187: Handler this Action = (Handler) stack.pop();
188: ((Handler) stack.peek()).keep(this Action.create(gf));
189: }
190:
191: /**
192: * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
193: */
194: public void startElement(String uri, String localName,
195: String qName, Attributes attributes) throws SAXException {
196: // create a handler
197: ParseStrategy ps = GeometryStrategies.findStrategy(uri,
198: localName);
199: if (ps == null) {
200: String qn = qName.substring(qName.indexOf(':') + 1, qName
201: .length());
202: ps = GeometryStrategies.findStrategy(null, qn);
203: }
204: Handler h = new Handler(ps, attributes);
205: // and add it to the stack
206: stack.push(h);
207: }
208:
209: //////////////////////////////////////////////
210: // Logging Methods
211:
212: /**
213: * @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
214: */
215: public void setDocumentLocator(Locator locator) {
216: this .locator = locator;
217: if (delegate != null && delegate instanceof ContentHandler)
218: ((ContentHandler) delegate).setDocumentLocator(locator);
219:
220: }
221:
222: private Locator locator = null;
223:
224: protected Locator getDocumentLocator() {
225: return locator;
226: }
227:
228: //////////////////////////////////////////////
229: // ERROR Methods
230:
231: /**
232: * @see org.xml.sax.helpers.DefaultHandler#fatalError(org.xml.sax.SAXParseException)
233: */
234: public void fatalError(SAXParseException e) throws SAXException {
235: if (delegate != null)
236: delegate.fatalError(e);
237: else
238: super .fatalError(e);
239: }
240:
241: /**
242: * @see org.xml.sax.helpers.DefaultHandler#error(org.xml.sax.SAXParseException)
243: */
244: public void error(SAXParseException e) throws SAXException {
245: if (delegate != null)
246: delegate.error(e);
247: else
248: super .error(e);
249: }
250:
251: /**
252: * @see org.xml.sax.helpers.DefaultHandler#warning(org.xml.sax.SAXParseException)
253: */
254: public void warning(SAXParseException e) throws SAXException {
255: if (delegate != null)
256: delegate.warning(e);
257: else
258: super.warning(e);
259: }
260:
261: }
|