Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.geometry / org.gvsig.fmap.geometry.jts / src / main / java / org / gvsig / fmap / geom / jts / gml / GMLHandler.java @ 47646

History | View | Annotate | Download (8.29 KB)

1
/*
2
 * The JTS Topology Suite is a collection of Java classes that
3
 * implement the fundamental operations required to validate a given
4
 * geo-spatial data set to a known topological specification.
5
 *
6
 * Copyright (C) 2001 Vivid Solutions
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 *
22
 * For more information, contact:
23
 *
24
 *     Vivid Solutions
25
 *     Suite #1A
26
 *     2328 Government Street
27
 *     Victoria BC  V8T 5G5
28
 *     Canada
29
 *
30
 *     (250)385-6040
31
 *     www.vividsolutions.com
32
 */
33
package org.gvsig.fmap.geom.jts.gml;
34

    
35
import com.vividsolutions.jts.geom.Geometry;
36
import com.vividsolutions.jts.geom.GeometryFactory;
37
import java.util.*;
38
import org.gvsig.fmap.geom.jts.gml.GeometryStrategies.ParseStrategy;
39
import org.xml.sax.*;
40
import org.xml.sax.helpers.AttributesImpl;
41
import org.xml.sax.helpers.DefaultHandler;
42

    
43
/**
44
 * A SAX {@link DefaultHandler} which builds {@link Geometry}s 
45
 * from GML2-formatted geometries.
46
 * An XML parser can delegate SAX events to this handler
47
 * to parse and building Geometrys. 
48
 * <p>
49
 * This handler currently ignores both namespaces and prefixes. 
50
 * 
51
 * Hints: 
52
 * <ul>
53
 * <li>If your parent handler is a DefaultHandler register the parent handler to receive the errors and locator calls.
54
 * <li>Use {@link GeometryStrategies#findStrategy(String, String)} to help check for applicability
55
 * </ul>
56
 * 
57
 * @see DefaultHandler
58
 *
59
 * @author David Zwiers, Vivid Solutions. 
60
 */
61
public class GMLHandler extends DefaultHandler {
62

    
63
        /**
64
         * This class is intended to log the SAX acitivity within a given element until its termination. 
65
         * At this time, a new object of value is created and passed to the parent. 
66
         * An object of value is typically either java.lang.* or a JTS Geometry
67
         * This class is not intended for use outside this distribution, 
68
         * and may change in subsequent versions.
69
         *
70
         * @author David Zwiers, Vivid Solutions.
71
         */
72
        static class Handler {
73
                protected Attributes attrs = null;
74

    
75
                protected ParseStrategy strategy;
76

    
77
                /**
78
                 * @param strategy 
79
                 * @param attributes Nullable
80
                 */
81
                public Handler(ParseStrategy strategy, Attributes attributes) {
82
                        if (attributes != null)
83
                                this.attrs = new AttributesImpl(attributes);
84
                        this.strategy = strategy;
85
                }
86

    
87
                protected StringBuffer text = null;
88

    
89
                /**
90
                 * Caches text for the future
91
                 * @param str
92
                 */
93
                public void addText(String str) {
94
                        if (text == null)
95
                                text = new StringBuffer();
96
                        text.append(str);
97
                }
98

    
99
                protected List children = null;
100

    
101
                /**
102
                 * Store param for the future
103
                 * 
104
                 * @param obj
105
                 */
106
                public void keep(Object obj) {
107
                        if (children == null)
108
                                children = new LinkedList();
109
                        children.add(obj);
110

    
111
                }
112

    
113
                /**
114
                 * @param gf GeometryFactory
115
                 * @return Parsed Object
116
                 * @throws SAXException 
117
                 */
118
                public Object create(GeometryFactory gf) throws SAXException {
119
//                    System.out.println("create "+this.strategy.getClass().getSimpleName());
120
                    return strategy.parse(this, gf);
121
                }
122
        }
123

    
124
        private Stack stack = new Stack();
125

    
126
        private ErrorHandler delegate = null;
127

    
128
        private GeometryFactory gf = null;
129

    
130
        /**
131
         * Creates a new handler.
132
         * Allows the user to specify a delegate object for error / warning messages. 
133
         * If the delegate also implements ContentHandler then the document Locator will be passed on.
134
         * 
135
         * @param gf Geometry Factory
136
         * @param delegate Nullable
137
         * 
138
         * @see ErrorHandler
139
         * @see ContentHandler
140
         * @see ContentHandler#setDocumentLocator(org.xml.sax.Locator)
141
         * @see org.xml.sax.Locator
142
         * 
143
         */
144
        public GMLHandler(GeometryFactory gf, ErrorHandler delegate) {
145
                this.delegate = delegate;
146
                this.gf = gf;
147
                stack.push(new Handler(null, null));
148
        }
149

    
150
        /**
151
         * Tests whether this handler has completed parsing 
152
         * a geometry.
153
         * If this is the case, {@link #getGeometry()} can be called
154
         * to get the value of the parsed geometry.
155
         * 
156
         * @return if the parsing of the geometry is complete
157
         */
158
        public boolean isGeometryComplete()
159
        {
160
                if (stack.size() > 1)
161
                        return false;
162
                // top level node on stack needs to have at least one child 
163
                Handler h = (Handler) stack.peek();
164
                if (h.children.size() < 1)
165
                        return false;
166
                return true;
167
                
168
        }
169
        
170
        /**
171
         * Gets the geometry parsed by this handler.
172
         * This method should only be called AFTER the parser has completed execution
173
         * 
174
         * @return the parsed Geometry, or a GeometryCollection if more than one geometry was parsed
175
         * @throws IllegalStateException if called before the parse is complete
176
         */
177
        public Geometry getGeometry() {
178
                if (stack.size() == 1) {
179
                        Handler h = (Handler) stack.peek();
180
                        if (h.children.size() == 1)
181
                                return (Geometry) h.children.get(0);
182
                        return gf.createGeometryCollection(
183
                                        (Geometry[]) h.children.toArray(new Geometry[stack.size()]));
184
                }
185
                throw new IllegalStateException(
186
                                "Parse did not complete as expected, there are " + stack.size()
187
                                                + " elements on the Stack");
188
        }
189

    
190
        //////////////////////////////////////////////
191
        // Parsing Methods
192

    
193
        /**
194
         * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
195
         */
196
        public void characters(char[] ch, int start, int length) throws SAXException {
197
                if (!stack.isEmpty())
198
                        ((Handler) stack.peek()).addText(new String(ch, start, length));
199
        }
200

    
201
        /**
202
         * @see org.xml.sax.helpers.DefaultHandler#ignorableWhitespace(char[], int, int)
203
         */
204
        public void ignorableWhitespace(char[] ch, int start, int length)
205
                        throws SAXException {
206
                if (!stack.isEmpty())
207
                        ((Handler) stack.peek()).addText(" ");
208
        }
209

    
210
        /**
211
         * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
212
         */
213
        public void endElement(String uri, String localName, String qName)
214
                        throws SAXException {
215
//            System.out.println("endElement: "+localName +" , "+qName);
216
                Handler thisAction = (Handler) stack.pop();
217
                ((Handler) stack.peek()).keep(thisAction.create(gf));
218
        }
219

    
220
        /**
221
         * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
222
         */
223
        public void startElement(String uri, String localName, String qName,
224
                        Attributes attributes) throws SAXException {
225
//            System.out.println("startElement: "+localName +" , "+qName);
226
                // create a handler
227
                ParseStrategy ps = GeometryStrategies.findStrategy(uri, localName);
228
                if (ps == null) {
229
                        String qn = qName.substring(qName.indexOf(':') + 1, qName.length());
230
                        ps = GeometryStrategies.findStrategy(null, qn);
231
                }
232
                Handler h = new Handler(ps, attributes);
233
                // and add it to the stack
234
                stack.push(h);
235
        }
236

    
237
        //////////////////////////////////////////////
238
        // Logging Methods
239

    
240
        /**
241
         * @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
242
         */
243
        public void setDocumentLocator(Locator locator) {
244
                this.locator = locator;
245
                if (delegate != null && delegate instanceof ContentHandler)
246
                        ((ContentHandler) delegate).setDocumentLocator(locator);
247

    
248
        }
249

    
250
        private Locator locator = null;
251

    
252
        protected Locator getDocumentLocator() {
253
                return locator;
254
        }
255

    
256
        //////////////////////////////////////////////
257
        // ERROR Methods
258

    
259
        /**
260
         * @see org.xml.sax.helpers.DefaultHandler#fatalError(org.xml.sax.SAXParseException)
261
         */
262
        public void fatalError(SAXParseException e) throws SAXException {
263
                if (delegate != null)
264
                        delegate.fatalError(e);
265
                else
266
                        super.fatalError(e);
267
        }
268

    
269
        /**
270
         * @see org.xml.sax.helpers.DefaultHandler#error(org.xml.sax.SAXParseException)
271
         */
272
        public void error(SAXParseException e) throws SAXException {
273
                if (delegate != null)
274
                        delegate.error(e);
275
                else
276
                        super.error(e);
277
        }
278

    
279
        /**
280
         * @see org.xml.sax.helpers.DefaultHandler#warning(org.xml.sax.SAXParseException)
281
         */
282
        public void warning(SAXParseException e) throws SAXException {
283
                if (delegate != null)
284
                        delegate.warning(e);
285
                else
286
                        super.warning(e);
287
        }
288

    
289
}