Source Code Cross Referenced for DefaultView.java in  » GIS » GeoTools-2.4.1 » org » geotools » data » view » 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.data.view 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2004-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.data.view;
017:
018:        import java.io.IOException;
019:        import java.net.URI;
020:        import java.util.LinkedList;
021:        import java.util.List;
022:        import java.util.Set;
023:        import java.util.logging.Logger;
024:
025:        import org.geotools.data.DataSourceException;
026:        import org.geotools.data.DataStore;
027:        import org.geotools.data.DataUtilities;
028:        import org.geotools.data.DefaultQuery;
029:        import org.geotools.data.FeatureListener;
030:        import org.geotools.data.FeatureLocking;
031:        import org.geotools.data.FeatureSource;
032:        import org.geotools.data.FeatureStore;
033:        import org.geotools.data.Query;
034:        import org.geotools.data.crs.ForceCoordinateSystemFeatureResults;
035:        import org.geotools.data.crs.ReprojectFeatureResults;
036:        import org.geotools.factory.CommonFactoryFinder;
037:        import org.geotools.feature.FeatureCollection;
038:        import org.geotools.feature.FeatureType;
039:        import org.geotools.feature.SchemaException;
040:        import org.geotools.filter.FilterFactoryFinder;
041:        import org.opengis.filter.Filter;
042:        import org.opengis.filter.FilterFactory;
043:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
044:
045:        import com.vividsolutions.jts.geom.Envelope;
046:
047:        /**
048:         * Wrapper for FeatureSource constrained by a Query.
049:         * 
050:         * <p>
051:         * Support FeatureSource decorator that takes care of mapping a Query &
052:         * FeatureSource with the schema and definition query configured for it.
053:         * </p>
054:         * 
055:         * <p>
056:         * Because GeoServer requires that attributes always be returned in the same
057:         * order we need a way to smoothly inforce this. Could we use this class to do
058:         * so?
059:         * </p>
060:         * <p>
061:         * WARNING: this class is a placeholder for ideas right now - it may not always
062:         * impement FeatureSource.
063:         * </p>
064:         * 
065:         * @author Gabriel Rold�n
066:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/data/view/DefaultView.java $
067:         */
068:        public class DefaultView implements  FeatureSource {
069:
070:            /** Shared package logger */
071:            private static final Logger LOGGER = org.geotools.util.logging.Logging
072:                    .getLogger("org.geotools.data.view");
073:
074:            /** FeatureSource being served up */
075:            protected FeatureSource source;
076:
077:            /**
078:             * Schema generated by provided constraintQuery
079:             */
080:            private FeatureType schema;
081:
082:            /** Query provided as a constraint */
083:            private Query constraintQuery;
084:
085:            /**
086:             * Creates a new GeoServerFeatureSource object.
087:             * <p>
088:             * Grabs the following from query:
089:             * <ul>
090:             * <li>typeName - only used if client does not supply
091:             * <li>cs - only used if client does not supply
092:             * <li>csForce - only used if client does not supply
093:             * <li>filter - combined with client filter
094:             * <li>propertyNames - combined with client filter (indicate property names
095:             * that *must* be included)
096:             * </ul>
097:             * </p>
098:             * Schema is generated based on this information.
099:             * </p>
100:             * 
101:             * @param source
102:             *            a FeatureSource
103:             * @param query
104:             *            Filter used to limit results
105:             * @throws SchemaException
106:             */
107:            public DefaultView(FeatureSource source, Query query)
108:                    throws SchemaException {
109:                this .source = source;
110:                this .constraintQuery = query;
111:
112:                FeatureType origionalType = source.getSchema();
113:
114:                CoordinateReferenceSystem cs = null;
115:                if (query.getCoordinateSystemReproject() != null) {
116:                    cs = query.getCoordinateSystemReproject();
117:                } else if (query.getCoordinateSystem() != null) {
118:                    cs = query.getCoordinateSystem();
119:                }
120:                schema = DataUtilities.createSubType(origionalType, query
121:                        .getPropertyNames(), cs, query.getTypeName(), null);
122:            }
123:
124:            /**
125:             * Factory that make the correct decorator for the provided featureSource.
126:             * 
127:             * <p>
128:             * This factory method is public and will be used to create all required
129:             * subclasses. By comparison the constructors for this class have package
130:             * visibiliy.
131:             * </p>
132:             * 
133:             * TODO: revisit this - I am not sure I want write access to views
134:             * (especially if they do reprojection).
135:             * 
136:             * @param source
137:             * @param query
138:             * 
139:             * @return @throws
140:             *         SchemaException
141:             */
142:            public static FeatureSource create(FeatureSource source, Query query)
143:                    throws SchemaException {
144:                if (source instanceof  FeatureLocking) {
145:                    //  return new GeoServerFeatureLocking((FeatureLocking) source,
146:                    // schema, definitionQuery);
147:                } else if (source instanceof  FeatureStore) {
148:                    //return new GeoServerFeatureStore((FeatureStore) source, schema,
149:                    // definitionQuery);
150:                }
151:                return new DefaultView(source, query);
152:            }
153:
154:            /**
155:             * Takes a query and adapts it to match re definitionQuery filter configured
156:             * for a feature type. It won't handle coordinate system changes
157:             * <p>
158:             * Grabs the following from query:
159:             * <ul>
160:             * <li>typeName - only used if client does not supply
161:             * <li>filter - combined with client filter
162:             * <li>propertyNames - combined with client filter (indicate property names
163:             * that *must* be included)
164:             * </ul>
165:             * </p>
166:             * 
167:             * @param query
168:             *            Query against this DataStore
169:             * 
170:             * @return Query restricted to the limits of definitionQuery
171:             * 
172:             * @throws IOException
173:             *             See DataSourceException
174:             * @throws DataSourceException
175:             *             If query could not meet the restrictions of definitionQuery
176:             */
177:            protected DefaultQuery makeDefinitionQuery(Query query)
178:                    throws IOException {
179:                if ((query == Query.ALL) || query.equals(Query.ALL)) {
180:                    return new DefaultQuery(constraintQuery);
181:                }
182:
183:                try {
184:                    String[] propNames = extractAllowedAttributes(query);
185:
186:                    String typeName = query.getTypeName();
187:                    if (typeName == null) {
188:                        typeName = constraintQuery.getTypeName();
189:                    }
190:
191:                    URI namespace = query.getNamespace();
192:                    if (namespace == null || namespace == Query.NO_NAMESPACE) {
193:                        namespace = constraintQuery.getNamespace();
194:                    }
195:                    Filter filter = makeDefinitionFilter(query.getFilter());
196:
197:                    int maxFeatures = Math.min(query.getMaxFeatures(),
198:                            constraintQuery.getMaxFeatures());
199:
200:                    String handle = query.getHandle();
201:                    if (handle == null) {
202:                        handle = constraintQuery.getHandle();
203:                    } else if (constraintQuery.getHandle() != null) {
204:                        handle = handle + "(" + constraintQuery.getHandle()
205:                                + ")";
206:                    }
207:
208:                    DefaultQuery defaultQuery = new DefaultQuery(typeName,
209:                            namespace, filter, maxFeatures, propNames, handle);
210:                    defaultQuery.setSortBy(query.getSortBy());
211:                    return defaultQuery;
212:                } catch (Exception ex) {
213:                    throw new DataSourceException(
214:                            "Could not restrict the query to the definition criteria: "
215:                                    + ex.getMessage(), ex);
216:                }
217:            }
218:
219:            /**
220:             * List of allowed attributes.
221:             * 
222:             * <p>
223:             * Creates a list of FeatureTypeInfo's attribute names based on the
224:             * attributes requested by <code>query</code> and making sure they not
225:             * contain any non exposed attribute.
226:             * </p>
227:             * 
228:             * <p>
229:             * Exposed attributes are those configured in the "attributes" element of
230:             * the FeatureTypeInfo's configuration
231:             * </p>
232:             * 
233:             * @param query
234:             *            User's origional query
235:             * 
236:             * @return List of allowed attribute types
237:             */
238:            private String[] extractAllowedAttributes(Query query) {
239:                String[] propNames = null;
240:
241:                if (query.retrieveAllProperties()) {
242:                    propNames = new String[schema.getAttributeCount()];
243:
244:                    for (int i = 0; i < schema.getAttributeCount(); i++) {
245:                        propNames[i] = schema.getAttributeType(i).getName();
246:                    }
247:                } else {
248:                    String[] queriedAtts = query.getPropertyNames();
249:                    int queriedAttCount = queriedAtts.length;
250:                    List allowedAtts = new LinkedList();
251:
252:                    for (int i = 0; i < queriedAttCount; i++) {
253:                        if (schema.getAttributeType(queriedAtts[i]) != null) {
254:                            allowedAtts.add(queriedAtts[i]);
255:                        } else {
256:                            LOGGER.info("queried a not allowed property: "
257:                                    + queriedAtts[i]
258:                                    + ". Ommitting it from query");
259:                        }
260:                    }
261:
262:                    propNames = (String[]) allowedAtts
263:                            .toArray(new String[allowedAtts.size()]);
264:                }
265:
266:                return propNames;
267:            }
268:
269:            /**
270:             * If a definition query has been configured for the FeatureTypeInfo, makes
271:             * and return a new Filter that contains both the query's filter and the
272:             * layer's definition one, by logic AND'ing them.
273:             * 
274:             * @param filter
275:             *            Origional user supplied Filter
276:             * 
277:             * @return Filter adjusted to the limitations of definitionQuery
278:             * 
279:             * @throws DataSourceException
280:             *             If the filter could not meet the limitations of
281:             *             definitionQuery
282:             */
283:            protected Filter makeDefinitionFilter(Filter filter)
284:                    throws DataSourceException {
285:                Filter newFilter = filter;
286:                Filter constraintFilter = constraintQuery.getFilter();
287:                try {
288:                    if (constraintFilter != Filter.INCLUDE) {
289:                        FilterFactory ff = CommonFactoryFinder
290:                                .getFilterFactory(null);
291:                        newFilter = ff.and(constraintFilter, filter);
292:                    }
293:                } catch (Exception ex) {
294:                    throw new DataSourceException(
295:                            "Can't create the constraint filter", ex);
296:                }
297:                return newFilter;
298:            }
299:
300:            /**
301:             * Implement getDataStore.
302:             * 
303:             * <p>
304:             * Description ...
305:             * </p>
306:             * 
307:             * @return @see org.geotools.data.FeatureSource#getDataStore()
308:             */
309:            public DataStore getDataStore() {
310:                return source.getDataStore();
311:            }
312:
313:            /**
314:             * Implement addFeatureListener.
315:             * 
316:             * <p>
317:             * Description ...
318:             * </p>
319:             * 
320:             * @param listener
321:             * 
322:             * @see org.geotools.data.FeatureSource#addFeatureListener(org.geotools.data.FeatureListener)
323:             */
324:            public void addFeatureListener(FeatureListener listener) {
325:                source.addFeatureListener(listener);
326:            }
327:
328:            /**
329:             * Implement removeFeatureListener.
330:             * 
331:             * <p>
332:             * Description ...
333:             * </p>
334:             * 
335:             * @param listener
336:             * 
337:             * @see org.geotools.data.FeatureSource#removeFeatureListener(org.geotools.data.FeatureListener)
338:             */
339:            public void removeFeatureListener(FeatureListener listener) {
340:                source.removeFeatureListener(listener);
341:            }
342:
343:            /**
344:             * Implement getFeatures.
345:             * 
346:             * <p>
347:             * Description ...
348:             * </p>
349:             * 
350:             * @param query
351:             * 
352:             * @return @throws
353:             *         IOException
354:             * 
355:             * @see org.geotools.data.FeatureSource#getFeatures(org.geotools.data.Query)
356:             */
357:            public FeatureCollection getFeatures(Query query)
358:                    throws IOException {
359:                DefaultQuery mergedQuery = makeDefinitionQuery(query);
360:                FeatureCollection results = source.getFeatures(mergedQuery);
361:
362:                // Get all the coordinate systems involved in the two queries
363:                CoordinateReferenceSystem cCs = constraintQuery
364:                        .getCoordinateSystem();
365:                CoordinateReferenceSystem cCsr = constraintQuery
366:                        .getCoordinateSystemReproject();
367:                CoordinateReferenceSystem qCs = query.getCoordinateSystem();
368:                CoordinateReferenceSystem qCsr = query
369:                        .getCoordinateSystemReproject();
370:
371:                /*
372:                 * Here we create all the needed transformations. We assume for the
373:                 * moment that the data stores are incapable of any kind of cs
374:                 * transformation and neither capable of forcing cs. We also assume that
375:                 * concatenating multiple forced and reprojected wrappers is inexpensive
376:                 * since they are optimized to recognize each other and to avoid useless
377:                 * object creation
378:                 */
379:                try {
380:                    if (qCsr != null && cCsr != null) {
381:                        if (cCs != null)
382:                            results = new ForceCoordinateSystemFeatureResults(
383:                                    results, cCs);
384:                        results = new ReprojectFeatureResults(results, cCsr);
385:                        if (qCs != null)
386:                            results = new ForceCoordinateSystemFeatureResults(
387:                                    results, qCs);
388:                        results = new ReprojectFeatureResults(results, qCsr);
389:                    } else if (qCs != null && cCsr != null) {
390:                        // complex case 2, reprojected then forced
391:                        // mergedQuery.setCoordinateSystem(cCs);
392:                        // mergedQuery.setCoordinateSystemReproject(cCsr);
393:                        try {
394:                            if (cCs != null)
395:                                results = new ForceCoordinateSystemFeatureResults(
396:                                        results, cCs);
397:                            results = new ReprojectFeatureResults(source
398:                                    .getFeatures(mergedQuery), cCsr);
399:
400:                            results = new ForceCoordinateSystemFeatureResults(
401:                                    results, qCs);
402:                        } catch (SchemaException e) {
403:                            throw new DataSourceException(
404:                                    "This should not happen", e);
405:                        }
406:                    } else {
407:                        // easy case, we can just put toghether one forced cs and one
408:                        // reprojection cs
409:                        // in the mixed query and let it go
410:
411:                        // mergedQuery.setCoordinateSystem(qCs != null ? qCs : cCs);
412:                        // mergedQuery.setCoordinateSystemReproject(qCsr != null ? qCsr
413:                        // : cCsr);
414:                        CoordinateReferenceSystem forcedCS = qCs != null ? qCs
415:                                : cCs;
416:                        CoordinateReferenceSystem reprojectCS = qCsr != null ? qCsr
417:                                : cCsr;
418:
419:                        if (forcedCS != null)
420:                            results = new ForceCoordinateSystemFeatureResults(
421:                                    results, forcedCS);
422:                        if (reprojectCS != null)
423:                            results = new ReprojectFeatureResults(results,
424:                                    reprojectCS);
425:                    }
426:                } catch (IOException e) {
427:                    throw e;
428:                } catch (Exception e) {
429:                    throw new DataSourceException(
430:                            "A problem occurred while handling forced "
431:                                    + "coordinate systems and reprojection", e);
432:                }
433:
434:                return results;
435:            }
436:
437:            /**
438:             * Implement getFeatures.
439:             * 
440:             * <p>
441:             * Description ...
442:             * </p>
443:             * 
444:             * @param filter
445:             * 
446:             * @return @throws
447:             *         IOException
448:             */
449:            public FeatureCollection getFeatures(Filter filter)
450:                    throws IOException {
451:                return getFeatures(new DefaultQuery(schema.getTypeName(),
452:                        filter));
453:            }
454:
455:            /**
456:             * Implement getFeatures.
457:             * 
458:             * <p>
459:             * Description ...
460:             * </p>
461:             * 
462:             * @return @throws
463:             *         IOException
464:             * 
465:             * @see org.geotools.data.FeatureSource#getFeatures()
466:             */
467:            public FeatureCollection getFeatures() throws IOException {
468:                return getFeatures(Query.ALL);
469:            }
470:
471:            /**
472:             * Implement getSchema.
473:             * 
474:             * <p>
475:             * Description ...
476:             * </p>
477:             * 
478:             * @return @see org.geotools.data.FeatureSource#getSchema()
479:             */
480:            public FeatureType getSchema() {
481:                return schema;
482:            }
483:
484:            /**
485:             * Retrieves the total extent of this FeatureSource.
486:             * 
487:             * <p>
488:             * Please note this extent will reflect the provided definitionQuery.
489:             * </p>
490:             * 
491:             * @return Extent of this FeatureSource, or <code>null</code> if no
492:             *         optimizations exist.
493:             * 
494:             * @throws IOException
495:             *             If bounds of definitionQuery
496:             */
497:            public Envelope getBounds() throws IOException {
498:                if (constraintQuery.getCoordinateSystemReproject() == null) {
499:                    if (constraintQuery.getFilter() == null
500:                            || constraintQuery.getFilter() == Filter.INCLUDE
501:                            || Filter.INCLUDE.equals(constraintQuery
502:                                    .getFilter())) {
503:                        return source.getBounds();
504:                    }
505:                    return source.getBounds(constraintQuery);
506:
507:                }
508:                // this will create a feature results that can reproject the
509:                // features, and will
510:                // properly compute the bouds
511:                return getFeatures().getBounds();
512:
513:            }
514:
515:            /**
516:             * Retrive the extent of the Query.
517:             * 
518:             * <p>
519:             * This method provides access to an optimized getBounds opperation. If no
520:             * optimized opperation is available <code>null</code> will be returned.
521:             * </p>
522:             * 
523:             * <p>
524:             * You may still make use of getFeatures( Query ).getCount() which will
525:             * return the correct answer (even if it has to itterate through all the
526:             * results to do so.
527:             * </p>
528:             * 
529:             * @param query
530:             *            User's query
531:             * 
532:             * @return Extend of Query or <code>null</code> if no optimization is
533:             *         available
534:             * 
535:             * @throws IOException
536:             *             If a problem is encountered with source
537:             */
538:            public Envelope getBounds(Query query) throws IOException {
539:                if (constraintQuery.getCoordinateSystemReproject() == null) {
540:                    try {
541:                        query = makeDefinitionQuery(query);
542:                    } catch (IOException ex) {
543:                        return null;
544:                    }
545:
546:                    return source.getBounds(query);
547:                }
548:                // this will create a feature results that can reproject the
549:                // features, and will
550:                // properly compute the bouds
551:                return getFeatures(query).getBounds();
552:            }
553:
554:            /**
555:             * Adjust query and forward to source.
556:             * 
557:             * <p>
558:             * This method provides access to an optimized getCount opperation. If no
559:             * optimized opperation is available <code>-1</code> will be returned.
560:             * </p>
561:             * 
562:             * <p>
563:             * You may still make use of getFeatures( Query ).getCount() which will
564:             * return the correct answer (even if it has to itterate through all the
565:             * results to do so).
566:             * </p>
567:             * 
568:             * @param query
569:             *            User's query.
570:             * 
571:             * @return Number of Features for Query, or -1 if no optimization is
572:             *         available.
573:             */
574:            public int getCount(Query query) {
575:                try {
576:                    query = makeDefinitionQuery(query);
577:                } catch (IOException ex) {
578:                    return -1;
579:                }
580:                try {
581:                    return source.getCount(query);
582:                } catch (IOException e) {
583:                    return 0;
584:                }
585:            }
586:
587:            public Set getSupportedHints() {
588:                return source.getSupportedHints();
589:            }
590:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.