Source Code Cross Referenced for FeatureTransformer.java in  » GIS » GeoTools-2.4.1 » org » geotools » gml » producer » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » org.geotools.gml.producer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2003-2006, 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:        package org.geotools.gml.producer;
017:
018:        import com.vividsolutions.jts.geom.Envelope;
019:        import com.vividsolutions.jts.geom.Geometry;
020:        import org.geotools.data.FeatureReader;
021:        import org.geotools.feature.AttributeType;
022:        import org.geotools.feature.Feature;
023:        import org.geotools.feature.FeatureCollection;
024:        import org.geotools.feature.FeatureCollectionIteration;
025:        import org.geotools.feature.FeatureIterator;
026:        import org.geotools.feature.FeatureType;
027:        import org.geotools.feature.GeometryAttributeType;
028:        import org.geotools.feature.type.DateUtil;
029:        import org.geotools.gml.producer.GeometryTransformer.GeometryTranslator;
030:        import org.geotools.xml.transform.TransformerBase;
031:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
032:        import org.xml.sax.Attributes;
033:        import org.xml.sax.ContentHandler;
034:        import org.xml.sax.SAXException;
035:        import org.xml.sax.helpers.AttributesImpl;
036:        import org.xml.sax.helpers.NamespaceSupport;
037:        import java.io.IOException;
038:        import java.text.SimpleDateFormat;
039:        import java.util.Date;
040:        import java.util.HashMap;
041:        import java.util.HashSet;
042:        import java.util.Map;
043:        import java.util.Set;
044:        import java.util.logging.Logger;
045:
046:        /**
047:         * FeatureTransformer provides a mechanism for converting Feature objects into
048:         * (hopefully) valid gml. This is a work in progress, so please be patient. A
049:         * simple example of how to use this class follows:
050:         * <pre>
051:         *    FeatureCollection collection; // can also use FeatureReader!!
052:         *   OutputStream out;
053:         *    FeatureTransformer ft = new FeatureTransformer();
054:         *    // set the indentation to 4 spaces
055:         *   ft.setIndentation(4);
056:         *    // this will allow Features with the FeatureType which has the namespace
057:         *   // "http://somewhere.org" to be prefixed with xxx...
058:         *   ft.getFeatureNamespaces().declarePrefix("xxx","http://somewhere.org");
059:         *    // transform
060:         *   ft.transform(collection,out);
061:         * </pre>
062:         * <b>The above example assumes a homogenous collection of Features whose
063:         * FeatureType has the namespace "http://somewhere.org"</b> but note that not
064:         * all DataSources currently provide FeatureTypes with a namespace... There
065:         * are two other mechanisms for prefixing your Features.<br>
066:         * 1) Map a specific FeatureType <b>by identity</b> to prefix and nsURI
067:         * <pre>
068:         *   FeatureType fc;
069:         *   FeatureTransformer ft = new FeatureTransformer();
070:         *   ft.getFeatureTypeNamespaces().declareNamespace(fc,"xxx","http://somewhere.org");
071:         * </pre>
072:         * 2) Provide a default namespace for any Features whose FeatureType either has
073:         * an empty namespace, OR, has not been mapped using the previous method. This
074:         * is basically a catch-all mechanism.
075:         * <pre>
076:         *   FeatureTransformer ft = new FeatureTransformer();
077:         *   ft.getFeatureTypeNamespaces().declareDefaultNamespace("xxx","http://somewhere.org");
078:         * </pre>
079:         * <br/> The collectionNamespace and prefix property refers to the prefix and
080:         * namespace given to the document root and defualts to
081:         * wfs,http://www.opengis.wfs.
082:         *
083:         * @author Ian Schneider
084:         * @author Chris Holmes, TOPP
085:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/gml/producer/FeatureTransformer.java $
086:         * @version $Id: FeatureTransformer.java 29502 2008-02-28 09:06:25Z jgarnett $
087:         *
088:         * @todo Add support for schemaLocation
089:         */
090:        public class FeatureTransformer extends TransformerBase {
091:            /** The logger for the filter module. */
092:            private static final Logger LOGGER = org.geotools.util.logging.Logging
093:                    .getLogger("org.geotools.gml");
094:            private static Set gmlAtts;
095:            private String collectionPrefix = "wfs";
096:            private String collectionNamespace = "http://www.opengis.net/wfs";
097:            private NamespaceSupport nsLookup = new NamespaceSupport();
098:            private FeatureTypeNamespaces featureTypeNamespaces = new FeatureTypeNamespaces(
099:                    nsLookup);
100:            private SchemaLocationSupport schemaLocation = new SchemaLocationSupport();
101:            private int maxFeatures = -1;
102:            private boolean prefixGml = false;
103:            private boolean featureBounding = false;
104:            private String srsName;
105:            private String lockId;
106:            private int numDecimals = 4;
107:
108:            public void setCollectionNamespace(String nsURI) {
109:                collectionNamespace = nsURI;
110:            }
111:
112:            public String getCollectionNamespace() {
113:                return collectionNamespace;
114:            }
115:
116:            public void setCollectionPrefix(String prefix) {
117:                this .collectionPrefix = prefix;
118:            }
119:
120:            public String getCollectionPrefix() {
121:                return collectionPrefix;
122:            }
123:
124:            /**
125:             * Sets the number of decimals to be used in the geometry coordinates of
126:             * the response.  This allows for more efficient results, since often the
127:             * storage format itself won't specify as many decimal places as the
128:             * response might want.  The default is 4, but should generally be set by
129:             * the user of this class.
130:             *
131:             * @param numDecimals the number of significant digits past the decimal to
132:             *        include in the response.
133:             */
134:            public void setNumDecimals(int numDecimals) {
135:                this .numDecimals = numDecimals;
136:            }
137:
138:            public NamespaceSupport getFeatureNamespaces() {
139:                return nsLookup;
140:            }
141:
142:            public FeatureTypeNamespaces getFeatureTypeNamespaces() {
143:                return featureTypeNamespaces;
144:            }
145:
146:            public void addSchemaLocation(String nsURI, String uri) {
147:                schemaLocation.setLocation(nsURI, uri);
148:            }
149:
150:            /**
151:             * Used to set the srsName attribute of the Geometries to be turned to xml.
152:             * For now we can only have all with the same srsName.
153:             *
154:             * @param srsName This SRS names hould agree with the GML specification; example "EPSG:4326"
155:             * @task REVISIT: once we have better srs support in our feature model this
156:             *       should be rethought, as it's a rather blunt approach.
157:             */
158:            public void setSrsName(String srsName) {
159:                this .srsName = srsName;
160:            }
161:
162:            /**
163:             * Used to set a lockId attribute after a getFeatureWithLock.
164:             *
165:             * @param lockId The lockId of the lock on the WFS.
166:             *
167:             * @task REVISIT: Ian, this is probably the most wfs specific addition. If
168:             *       you'd like I can subclass and add it there.  It has to be added
169:             *       as an attribute to FeatureCollection, to report a
170:             *       GetFeatureWithLock
171:             */
172:            public void setLockId(String lockId) {
173:                this .lockId = lockId;
174:            }
175:
176:            /**
177:             * If Gml Prefixing is enabled then attributes with names that could be
178:             * prefixed with gml, such as description, pointProperty, and name, will
179:             * be.  So if an attribute called name is encountered, instead of
180:             * prepending the default prefix (say gt2:name), it will turn out as
181:             * gml:name.  Right now this is fairly hacky, as the gml:name,
182:             * gml:description, ect., should be in the first attributes by default.
183:             * The actualy geometry encodings will always be prefixed with the proper
184:             * gml, like gml:coordinates. This only applies to attributes, that could
185:             * also be part of the features normal schema (for example a pointProperty
186:             * could be declared in the gt2  namespace, instead of a gml:pointProperty
187:             * it would be a gt2:pointProperty.
188:             *
189:             * @param prefixGml <tt>true</tt> if prefixing gml should be enabled.
190:             *        Default is disabled, no gml prefixing.
191:             *
192:             * @task REVISIT: only prefix name, description, and boundedBy if they
193:             *       occur in their proper places.  Right now names always get gml
194:             *       prefixed if the gmlPrefixing is on, which is less than ideal.
195:             * @task REVISIT: The other approach is to allow for generic mapping, users
196:             *       would set which attributes they wanted to have different
197:             *       prefixes.
198:             */
199:            public void setGmlPrefixing(boolean prefixGml) {
200:                this .prefixGml = prefixGml;
201:
202:                if (prefixGml && (gmlAtts == null)) {
203:                    gmlAtts = new HashSet();
204:                    loadGmlAttributes(gmlAtts);
205:                }
206:            }
207:
208:            /**
209:             * Template method for determining which attributes to prefix with gml.
210:             * @param gmlAtts Set of strings corresponding to element names on a type.
211:             */
212:            protected void loadGmlAttributes(Set gmlAtts) {
213:                gmlAtts.add("pointProperty");
214:                gmlAtts.add("geometryProperty");
215:                gmlAtts.add("polygonProperty");
216:                gmlAtts.add("lineStringProperty");
217:                gmlAtts.add("multiPointProperty");
218:                gmlAtts.add("multiLineStringProperty");
219:                gmlAtts.add("multiPolygonProperty");
220:                gmlAtts.add("description");
221:                gmlAtts.add("name");
222:
223:                //boundedBy is done in handleAttribute to make use of the writeBounds
224:                //code.
225:            }
226:
227:            /**
228:             * Sets whether a gml:boundedBy element should automatically be generated
229:             * and included.  The element will not be updateable, and is simply
230:             * derived from the geometries present in the feature.
231:             * 
232:             * <p>
233:             * Note that the <tt>setGmlPrefixing()</tt> interacts with this
234:             * occasionally, since it will hack in a gml prefix to a boundedBy
235:             * attribute included in the featureType.  If gml prefixing is on, and
236:             * featureBounding is on, then the bounds from the attribute will be used.
237:             * If gml prefixing is off, then that boundedBy attribute will
238:             * presumably be in its own namespace, and so the automatic gml boundedBy
239:             * will not conflict, so both will be printed, with the automatic one
240:             * deriving its bounds from the boundedBy attribute and any other
241:             * geometries in the feature
242:             * </p>
243:             *
244:             * @param featureBounding <tt>true</tt> if the bounds of the feature should
245:             *        be automatically calculated and included as a gml:boundedBy in
246:             *        the gml output.  Note this puts a good bit of bandwidth overhead
247:             *        on the  output.  Default is <tt>false</tt>
248:             */
249:            public void setFeatureBounding(boolean featureBounding) {
250:                this .featureBounding = featureBounding;
251:            }
252:
253:            public org.geotools.xml.transform.Translator createTranslator(
254:                    ContentHandler handler) {
255:                FeatureTranslator t = createTranslator(handler,
256:                        collectionPrefix, collectionNamespace,
257:                        featureTypeNamespaces, schemaLocation);
258:                java.util.Enumeration prefixes = nsLookup.getPrefixes();
259:
260:                //setGmlPrefixing(true);
261:                t.setNumDecimals(numDecimals);
262:                t.setGmlPrefixing(prefixGml);
263:                t.setSrsName(srsName);
264:                t.setLockId(lockId);
265:                t.setFeatureBounding(featureBounding);
266:
267:                while (prefixes.hasMoreElements()) {
268:                    String prefix = prefixes.nextElement().toString();
269:                    String uri = nsLookup.getURI(prefix);
270:                    t.getNamespaceSupport().declarePrefix(prefix, uri);
271:                }
272:
273:                return t;
274:            }
275:
276:            /**
277:             * Template method for creating the translator.
278:             */
279:            protected FeatureTranslator createTranslator(
280:                    ContentHandler handler, String prefix, String ns,
281:                    FeatureTypeNamespaces featureTypeNamespaces,
282:                    SchemaLocationSupport schemaLocationSupport) {
283:                return new FeatureTranslator(handler, prefix, ns,
284:                        featureTypeNamespaces, schemaLocationSupport);
285:            }
286:
287:            public static class FeatureTypeNamespaces {
288:                Map lookup = new HashMap();
289:                NamespaceSupport nsSupport;
290:                String defaultPrefix = null;
291:
292:                public FeatureTypeNamespaces(NamespaceSupport nsSupport) {
293:                    this .nsSupport = nsSupport;
294:                }
295:
296:                public void declareDefaultNamespace(String prefix, String nsURI) {
297:                    defaultPrefix = prefix;
298:                    nsSupport.declarePrefix(prefix, nsURI);
299:                }
300:
301:                public void declareNamespace(FeatureType type, String prefix,
302:                        String nsURI) {
303:                    lookup.put(type, prefix);
304:                    nsSupport.declarePrefix(prefix, nsURI);
305:                }
306:
307:                public String findPrefix(FeatureType type) {
308:                    String pre = (String) lookup.get(type);
309:
310:                    if (pre == null) {
311:                        pre = defaultPrefix;
312:                    }
313:
314:                    return pre;
315:                }
316:
317:                public String toString() {
318:                    return "FeatureTypeNamespaces[Default: " + defaultPrefix
319:                            + ", lookUp: " + lookup;
320:                }
321:            }
322:
323:            /**
324:             * Outputs gml without any fancy indents or newlines.
325:             */
326:            public static class FeatureTranslator extends TranslatorSupport
327:                    implements  FeatureCollectionIteration.Handler {
328:                String fc = "FeatureCollection";
329:                protected GeometryTransformer.GeometryTranslator geometryTranslator;
330:                String memberString;
331:                String currentPrefix;
332:                FeatureTypeNamespaces types;
333:                boolean prefixGml = false;
334:                boolean featureBounding = false;
335:                /**
336:                 * The string representing the Spatial Reference System of the data.
337:                 * <p>
338:                 * This value should be determined by looking at the first
339:                 * GeometryAttributeType encountered (but this way GeoServer can override
340:                 * everything and be divorced from the actual (lack of) abilities of the underlying
341:                 * DataStore).
342:                 */
343:                String srsName = null;
344:                /**
345:                 * Will be 0 - if unknown; 2 if normal and 3 if working with 3D coordinates.
346:                 * <p>
347:                 * This value will be set based on looking at the *first* GeometryAttributeType encountered,
348:                 * a similar approach should be taken for determining the SRID name.
349:                 * 
350:                 * @since 2.4.1
351:                 */
352:                int dimension = 0;
353:                String lockId = null;
354:                ContentHandler handler;
355:                private boolean running = true;
356:
357:                /**
358:                 * Constructor with handler.
359:                 *
360:                 * @param handler the handler to use.
361:                 * @param prefix DOCUMENT ME!
362:                 * @param ns DOCUMENT ME!
363:                 * @param types DOCUMENT ME!
364:                 * @param schemaLoc DOCUMENT ME!
365:                 */
366:                public FeatureTranslator(ContentHandler handler, String prefix,
367:                        String ns, FeatureTypeNamespaces types,
368:                        SchemaLocationSupport schemaLoc) {
369:                    super (handler, prefix, ns, schemaLoc);
370:                    geometryTranslator = createGeometryTranslator(handler);
371:                    this .types = types;
372:                    this .handler = handler;
373:                    getNamespaceSupport().declarePrefix(
374:                            geometryTranslator.getDefaultPrefix(),
375:                            geometryTranslator.getDefaultNamespace());
376:                    memberString = geometryTranslator.getDefaultPrefix()
377:                            + ":featureMember";
378:                }
379:
380:                /**
381:                 * Method to be subclassed to return a custom geometry translator, mostly for gml3 
382:                 * geometry support.
383:                 * @param handler
384:                 * @return
385:                 */
386:                protected GeometryTranslator createGeometryTranslator(
387:                        ContentHandler handler) {
388:                    return new GeometryTransformer.GeometryTranslator(handler);
389:                }
390:
391:                protected GeometryTranslator createGeometryTranslator(
392:                        ContentHandler handler, int numDecimals) {
393:                    return new GeometryTransformer.GeometryTranslator(handler,
394:                            numDecimals);
395:                }
396:
397:                /**
398:                 * @deprecated Use of DummyZ is not known
399:                 * @param handler
400:                 * @param numDecimals
401:                 * @param useDummyZ
402:                 * @return
403:                 */
404:                protected GeometryTranslator createGeometryTranslator(
405:                        ContentHandler handler, int numDecimals,
406:                        boolean useDummyZ) {
407:                    return new GeometryTransformer.GeometryTranslator(handler,
408:                            numDecimals, useDummyZ);
409:                }
410:
411:                /**
412:                 * @since 2.4.1
413:                 * @param handler
414:                 * @param numDecimals
415:                 * @param dimension
416:                 * @return GeometryTranslator that will delegate  a CoordinateWriter configured with the above parameters
417:                 */
418:                protected GeometryTranslator createGeometryTranslator(
419:                        ContentHandler handler, int numDecimals, int dimension) {
420:                    return new GeometryTranslator(handler, "gml",
421:                            GMLUtils.GML_URL, numDecimals, false, dimension);
422:                }
423:
424:                void setGmlPrefixing(boolean prefixGml) {
425:                    this .prefixGml = prefixGml;
426:                }
427:
428:                void setFeatureBounding(boolean bounding) {
429:                    this .featureBounding = bounding;
430:                }
431:
432:                void setSrsName(String srsName) {
433:                    this .srsName = srsName;
434:                    this .dimension = 0; // will be determined by the first GeometryAttributeType encountered
435:                }
436:
437:                void setNumDecimals(int numDecimals) {
438:                    geometryTranslator = createGeometryTranslator(handler,
439:                            numDecimals);
440:                }
441:
442:                void setUseDummyZ(boolean useDummyZ) {
443:                    geometryTranslator = createGeometryTranslator(handler,
444:                            geometryTranslator.getNumDecimals(), useDummyZ);
445:                }
446:
447:                /** If set to 3 the real z value from the coordinates will be used */
448:                void setDimension(int dimension) {
449:                    geometryTranslator = createGeometryTranslator(handler,
450:                            geometryTranslator.getNumDecimals(), dimension);
451:                }
452:
453:                public void setLockId(String lockId) {
454:                    this .lockId = lockId;
455:                }
456:
457:                public FeatureTypeNamespaces getFeatureTypeNamespaces() {
458:                    return types;
459:                }
460:
461:                public void encode(Object o) throws IllegalArgumentException {
462:                    try {
463:                        if (o instanceof  FeatureCollection) {
464:                            FeatureCollection fc = (FeatureCollection) o;
465:                            FeatureCollectionIteration.iteration(this , fc);
466:                        } else if (o instanceof  FeatureCollection[]) {
467:                            //Did FeatureResult[] so that we are sure they're all the same type.
468:                            //Could also consider collections here...  
469:                            FeatureCollection[] results = (FeatureCollection[]) o;
470:                            Envelope bounds = new Envelope();
471:
472:                            for (int i = 0; i < results.length; i++) {
473:                                bounds.expandToInclude(results[i].getBounds());
474:                            }
475:
476:                            startFeatureCollection();
477:                            writeBounds(bounds);
478:
479:                            for (int i = 0; i < results.length; i++) {
480:                                handleFeatureIterator(results[i].features());
481:                            }
482:                            endFeatureCollection();
483:                        } else if (o instanceof  FeatureReader) {
484:                            // THIS IS A HACK FOR QUICK USE
485:                            FeatureReader r = (FeatureReader) o;
486:
487:                            startFeatureCollection();
488:
489:                            handleFeatureReader(r);
490:
491:                            endFeatureCollection();
492:                            //                } else if (o instanceof FeatureResults) {
493:                            //                    FeatureResults fr = (FeatureResults) o;
494:                            //                    startFeatureCollection();
495:                            //                    writeBounds(fr.getBounds());
496:                            //                    handleFeatureReader(fr.reader());
497:                            //                    endFeatureCollection();
498:                            //                } else if (o instanceof FeatureResults[]) {
499:                            //                    //Did FeatureResult[] so that we are sure they're all the same type.
500:                            //                    //Could also consider collections here...  
501:                            //                    FeatureResults[] results = (FeatureResults[]) o;
502:                            //                    Envelope bounds = new Envelope();
503:                            //
504:                            //                    for (int i = 0; i < results.length; i++) {
505:                            //                        bounds.expandToInclude(results[i].getBounds());
506:                            //                    }
507:                            //
508:                            //                    startFeatureCollection();
509:                            //                    writeBounds(bounds);
510:                            //
511:                            //                    for (int i = 0; i < results.length; i++) {
512:                            //                        handleFeatureReader(results[i].reader());
513:                            //                    }
514:                            //
515:                            //                    endFeatureCollection();
516:                        } else {
517:                            throw new IllegalArgumentException("Cannot encode "
518:                                    + o);
519:                        }
520:                    } catch (IOException ioe) {
521:                        ioe.printStackTrace(System.out);
522:                        throw new RuntimeException(
523:                                "error reading FeatureResults", ioe);
524:                    }
525:                }
526:
527:                public void handleFeatureIterator(FeatureIterator iterator)
528:                        throws IOException {
529:                    try {
530:                        while (iterator.hasNext() && running) {
531:                            Feature f = iterator.next();
532:                            handleFeature(f);
533:
534:                            FeatureType t = f.getFeatureType();
535:
536:                            for (int i = 0, ii = f.getNumberOfAttributes(); i < ii; i++) {
537:                                handleAttribute(t.getAttributeType(i), f
538:                                        .getAttribute(i));
539:                            }
540:                            endFeature(f);
541:                        }
542:                    } catch (Exception ioe) {
543:                        throw new RuntimeException("Error reading Features",
544:                                ioe);
545:                    } finally {
546:                        if (iterator != null) {
547:                            LOGGER.finer("closing reader " + iterator);
548:                            iterator.close();
549:                        }
550:                    }
551:                }
552:
553:                public void handleFeatureReader(FeatureReader reader)
554:                        throws IOException {
555:                    try {
556:                        while (reader.hasNext() && running) {
557:                            Feature f = reader.next();
558:                            handleFeature(f);
559:
560:                            FeatureType t = f.getFeatureType();
561:
562:                            for (int i = 0, ii = f.getNumberOfAttributes(); i < ii; i++) {
563:                                handleAttribute(t.getAttributeType(i), f
564:                                        .getAttribute(i));
565:                            }
566:
567:                            endFeature(f);
568:                        }
569:                    } catch (Exception ioe) {
570:                        throw new RuntimeException("Error reading Features",
571:                                ioe);
572:                    } finally {
573:                        if (reader != null) {
574:                            LOGGER.finer("closing reader " + reader);
575:                            reader.close();
576:                        }
577:                    }
578:                }
579:
580:                public void startFeatureCollection() {
581:                    try {
582:                        String element = (getDefaultPrefix() == null) ? fc
583:                                : (getDefaultPrefix() + ":" + fc);
584:                        AttributesImpl atts = new AttributesImpl();
585:
586:                        if (lockId != null) {
587:                            atts.addAttribute("", "lockId", "lockId", "",
588:                                    lockId);
589:                        }
590:
591:                        contentHandler.startElement("", "", element, atts);
592:
593:                    } catch (SAXException se) {
594:                        throw new RuntimeException(se);
595:                    }
596:                }
597:
598:                public void endFeatureCollection() {
599:                    end(fc);
600:                }
601:
602:                /**
603:                 * Prints up the gml for a featurecollection.
604:                 *
605:                 * @param collection DOCUMENT ME!
606:                 */
607:                public void handleFeatureCollection(FeatureCollection collection) {
608:                    startFeatureCollection();
609:                    writeBounds(collection.getBounds());
610:                }
611:
612:                /**
613:                 * writes the <code>gml:boundedBy</code> element to output based on
614:                 * <code>fc.getBounds()</code>
615:                 *
616:                 * @param bounds
617:                 *
618:                 * @throws RuntimeException if it is thorwn while writing the element
619:                 *         or coordinates
620:                 */
621:                public void writeBounds(Envelope bounds) {
622:                    try {
623:                        String boundedBy = geometryTranslator
624:                                .getDefaultPrefix()
625:                                + ":" + "boundedBy";
626:
627:                        contentHandler.startElement("", "", boundedBy,
628:                                NULL_ATTS);
629:                        geometryTranslator.encode(bounds, srsName);
630:                        contentHandler.endElement("", "", boundedBy);
631:                    } catch (SAXException se) {
632:                        throw new RuntimeException(se);
633:                    }
634:                }
635:
636:                /**
637:                 * Sends sax for the ending of a feature collection.
638:                 *
639:                 * @param collection DOCUMENT ME!
640:                 */
641:                public void endFeatureCollection(FeatureCollection collection) {
642:                    endFeatureCollection();
643:                }
644:
645:                /**
646:                 * Sends sax for the ending of a feature.
647:                 *
648:                 * @param f DOCUMENT ME!
649:                 *
650:                 * @throws RuntimeException DOCUMENT ME!
651:                 */
652:                public void endFeature(Feature f) {
653:                    try {
654:                        String name = f.getFeatureType().getTypeName();
655:
656:                        if (currentPrefix != null) {
657:                            name = currentPrefix + ":" + name;
658:                        }
659:
660:                        contentHandler.endElement("", "", name);
661:                        contentHandler.endElement("", "", memberString);
662:                    } catch (Exception e) {
663:                        throw new RuntimeException(e);
664:                    }
665:                }
666:
667:                /**
668:                 * handles sax for an attribute.
669:                 *
670:                 * @param type DOCUMENT ME!
671:                 * @param value DOCUMENT ME!
672:                 *
673:                 * @throws RuntimeException DOCUMENT ME!
674:                 */
675:                public void handleAttribute(AttributeType type, Object value) {
676:                    try {
677:                        if (value != null) {
678:                            String name = type.getName();
679:
680:                            //HACK: this should be user configurable, along with the
681:
682:                            //other gml substitutions I shall add.
683:
684:                            if (prefixGml //adding this in since the extra boundedBy
685:                                    //hacking should only need to be done for the weird
686:                                    //cite tests, and having this check before the string
687:                                    //equals should get us better performance.  Albeit
688:                                    //very slightly, but this method gets called millions
689:                                    && (name.equals("boundedBy") && Geometry.class
690:                                            .isAssignableFrom(value.getClass()))) {
691:
692:                                writeBounds(((Geometry) value)
693:                                        .getEnvelopeInternal());
694:                            } else {
695:                                String this Prefix = currentPrefix;
696:
697:                                if (prefixGml && gmlAtts.contains(name)) {
698:                                    this Prefix = "gml";
699:                                }
700:
701:                                if (this Prefix != null) {
702:                                    name = this Prefix + ":" + name;
703:                                }
704:
705:                                contentHandler.startElement("", "", name,
706:                                        NULL_ATTS);
707:
708:                                if (Geometry.class.isAssignableFrom(value
709:                                        .getClass())) {
710:                                    if (dimension == 0) {
711:                                        // lets look at the CRS
712:                                        GeometryAttributeType geometryType = (GeometryAttributeType) type;
713:                                        CoordinateReferenceSystem crs = geometryType
714:                                                .getCoordinateSystem();
715:                                        if (crs == null) {
716:                                            // I won't even bother people with a warning
717:                                            // (until DataStore quality has improved
718:                                            dimension = 2; // the most sensible default
719:
720:                                        } else {
721:                                            dimension = crs
722:                                                    .getCoordinateSystem()
723:                                                    .getDimension();
724:                                            // note we could check the srsName here!
725:                                            if (dimension == 3) {
726:                                                setDimension(dimension);
727:                                            }
728:                                        }
729:                                    }
730:                                    geometryTranslator.encode((Geometry) value,
731:                                            srsName);
732:                                } else if (value instanceof  Date) {
733:                                    String text = null;
734:                                    if (value instanceof  java.sql.Date)
735:                                        text = DateUtil
736:                                                .serializeSqlDate((java.sql.Date) value);
737:                                    else if (value instanceof  java.sql.Time)
738:                                        text = DateUtil
739:                                                .serializeSqlTime((java.sql.Time) value);
740:                                    else
741:                                        text = DateUtil
742:                                                .serializeDateTime((Date) value);
743:                                    contentHandler.characters(text
744:                                            .toCharArray(), 0, text.length());
745:                                } else {
746:                                    String text = value.toString();
747:                                    contentHandler.characters(text
748:                                            .toCharArray(), 0, text.length());
749:                                }
750:
751:                                contentHandler.endElement("", "", name);
752:                            }
753:                        }
754:
755:                        //REVISIT: xsi:nillable is the proper xml way to handle nulls,
756:                        //but OGC people are fine with just leaving it out.       
757:                    } catch (Exception e) {
758:                        throw new RuntimeException(e);
759:                    }
760:                }
761:
762:                /**
763:                 * Handles sax for a feature.
764:                 *
765:                 * @param f DOCUMENT ME!
766:                 *
767:                 * @throws RuntimeException DOCUMENT ME!
768:                 */
769:                public void handleFeature(Feature f) {
770:                    try {
771:                        contentHandler.startElement("", "", memberString,
772:                                NULL_ATTS);
773:
774:                        FeatureType type = f.getFeatureType();
775:                        String name = type.getTypeName();
776:                        currentPrefix = getNamespaceSupport().getPrefix(
777:                                f.getFeatureType().getNamespace().toString());
778:
779:                        if (currentPrefix == null) {
780:                            currentPrefix = types
781:                                    .findPrefix(f.getFeatureType());
782:                        }
783:
784:                        if (currentPrefix == null) {
785:                            throw new RuntimeException(
786:                                    "Could not locate namespace for FeatureType : "
787:                                            + type.getTypeName() + ":"
788:                                            + type.getNamespace()
789:                                            + "look up in: " + types);
790:                        }
791:
792:                        if (currentPrefix != null) {
793:                            name = currentPrefix + ":" + name;
794:                        }
795:
796:                        Attributes fidAtts = encodeFeatureId(f);
797:
798:                        contentHandler.startElement("", "", name, fidAtts);
799:
800:                        if (featureBounding) {
801:                            //HACK pt.2 see line 511, if the cite stuff wanted to hack
802:                            //in a boundedBy geometry, we don't want to do it twice.
803:                            //So if 
804:                            if (prefixGml
805:                                    && (f.getAttribute("boundedBy") != null)) {
806:                                //do nothing, since our hack will handle it.
807:                            } else {
808:                                writeBounds(f.getBounds());
809:                            }
810:                        }
811:                    } catch (Exception e) {
812:                        throw new RuntimeException(e);
813:                    }
814:                }
815:
816:                protected Attributes encodeFeatureId(Feature f) {
817:                    AttributesImpl fidAtts = new org.xml.sax.helpers.AttributesImpl();
818:                    String fid = f.getID();
819:
820:                    if (fid != null) {
821:                        fidAtts.addAttribute("", "fid", "fid", "fids", fid);
822:                    }
823:
824:                    return fidAtts;
825:                }
826:
827:            }
828:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.