Source Code Cross Referenced for GeoServerFeatureSource.java in  » GIS » GeoServer » org » vfny » geoserver » global » 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 » GeoServer » org.vfny.geoserver.global 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org.  All rights reserved.
002:         * This code is licensed under the GPL 2.0 license, available at the root
003:         * application directory.
004:         */
005:        package org.vfny.geoserver.global;
006:
007:        import java.io.IOException;
008:        import java.util.LinkedList;
009:        import java.util.List;
010:        import java.util.Set;
011:        import java.util.logging.Logger;
012:
013:        import org.geoserver.feature.DefaultCRSFilterVisitor;
014:        import org.geoserver.feature.ReprojectingFilterVisitor;
015:        import org.geotools.data.DataSourceException;
016:        import org.geotools.data.DataStore;
017:        import org.geotools.data.DefaultQuery;
018:        import org.geotools.data.FeatureListener;
019:        import org.geotools.data.FeatureLocking;
020:        import org.geotools.data.FeatureSource;
021:        import org.geotools.data.FeatureStore;
022:        import org.geotools.data.Query;
023:        import org.geotools.data.crs.ForceCoordinateSystemFeatureResults;
024:        import org.geotools.data.crs.ReprojectFeatureResults;
025:        import org.geotools.factory.CommonFactoryFinder;
026:        import org.geotools.feature.FeatureCollection;
027:        import org.geotools.feature.FeatureType;
028:        import org.geotools.feature.FeatureTypes;
029:        import org.geotools.feature.GeometryAttributeType;
030:        import org.geotools.feature.SchemaException;
031:        import org.geotools.referencing.CRS;
032:        import org.opengis.filter.Filter;
033:        import org.opengis.filter.FilterFactory;
034:        import org.opengis.filter.FilterFactory2;
035:        import org.opengis.referencing.FactoryException;
036:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
037:        import org.opengis.referencing.operation.OperationNotFoundException;
038:        import org.opengis.referencing.operation.TransformException;
039:
040:        import com.vividsolutions.jts.geom.Envelope;
041:
042:        /**
043:         * GeoServer wrapper for backend Geotools2 DataStore.
044:         *
045:         * <p>
046:         * Support FeatureSource decorator for FeatureTypeInfo that takes care of
047:         * mapping the FeatureTypeInfo's FeatureSource with the schema and definition
048:         * query configured for it.
049:         * </p>
050:         *
051:         * <p>
052:         * Because GeoServer requires that attributes always be returned in the same
053:         * order we need a way to smoothly inforce this. Could we use this class to do
054:         * so?
055:         * </p>
056:         *
057:         * @author Gabriel Rold�n
058:         * @version $Id: GeoServerFeatureSource.java 8449 2008-02-25 18:14:20Z aaime $
059:         */
060:        public class GeoServerFeatureSource implements  FeatureSource {
061:            /** Shared package logger */
062:            private static final Logger LOGGER = org.geotools.util.logging.Logging
063:                    .getLogger("org.vfny.geoserver.global");
064:
065:            /** FeatureSource being served up */
066:            protected FeatureSource source;
067:
068:            /**
069:             * GeoTools2 Schema information
070:             *
071:             * <p>
072:             * Is this the same as source.getSchema() or is it used supply the order
073:             * that GeoServer requires attributes to be returned in?
074:             * </p>
075:             */
076:            protected FeatureType schema;
077:
078:            /** Used to constrain the Feature made available to GeoServer. */
079:            private Filter definitionQuery = Filter.INCLUDE;
080:
081:            /** Geometries will be forced to this CRS (or null, if no forcing is needed) */
082:            private CoordinateReferenceSystem declaredCRS;
083:
084:            /** How to handle SRS   */
085:            private int srsHandling;
086:
087:            /**
088:             * Creates a new GeoServerFeatureSource object.
089:             *
090:             * @param source GeoTools2 FeatureSource
091:             * @param schema FeatureType returned by this FeatureSource
092:             * @param definitionQuery Filter used to limit results
093:             * @param declaredCRS Geometries will be forced or projected to this CRS
094:             */
095:            GeoServerFeatureSource(FeatureSource source, FeatureType schema,
096:                    Filter definitionQuery,
097:                    CoordinateReferenceSystem declaredCRS, int srsHandling) {
098:                this .source = source;
099:                this .schema = schema;
100:                this .definitionQuery = definitionQuery;
101:                this .declaredCRS = declaredCRS;
102:                this .srsHandling = srsHandling;
103:
104:                if (this .definitionQuery == null) {
105:                    this .definitionQuery = Filter.INCLUDE;
106:                }
107:            }
108:
109:            /**
110:             * Factory that make the correct decorator for the provided featureSource.
111:             *
112:             * <p>
113:             * This factory method is public and will be used to create all required
114:             * subclasses. By comparison the constructors for this class have package
115:             * visibiliy.
116:             * </p>
117:             *
118:             * @param featureSource
119:             * @param schema DOCUMENT ME!
120:             * @param definitionQuery DOCUMENT ME!
121:             * @param declaredCRS 
122:             *
123:             * @return
124:             */
125:            public static GeoServerFeatureSource create(
126:                    FeatureSource featureSource, FeatureType schema,
127:                    Filter definitionQuery,
128:                    CoordinateReferenceSystem declaredCRS, int srsHandling) {
129:                if (featureSource instanceof  FeatureLocking) {
130:                    return new GeoServerFeatureLocking(
131:                            (FeatureLocking) featureSource, schema,
132:                            definitionQuery, declaredCRS, srsHandling);
133:                } else if (featureSource instanceof  FeatureStore) {
134:                    return new GeoServerFeatureStore(
135:                            (FeatureStore) featureSource, schema,
136:                            definitionQuery, declaredCRS, srsHandling);
137:                }
138:
139:                return new GeoServerFeatureSource(featureSource, schema,
140:                        definitionQuery, declaredCRS, srsHandling);
141:            }
142:
143:            /**
144:             * Takes a query and adapts it to match re definitionQuery filter
145:             * configured for a feature type.
146:             *
147:             * @param query Query against this DataStore
148:             * @param schema TODO
149:             *
150:             * @return Query restricted to the limits of definitionQuery
151:             *
152:             * @throws IOException See DataSourceException
153:             * @throws DataSourceException If query could not meet the restrictions of
154:             *         definitionQuery
155:             */
156:            protected Query makeDefinitionQuery(Query query, FeatureType schema)
157:                    throws IOException {
158:                if ((query == Query.ALL) || query.equals(Query.ALL)) {
159:                    return query;
160:                }
161:
162:                try {
163:                    String[] propNames = extractAllowedAttributes(query, schema);
164:                    Filter filter = query.getFilter();
165:                    filter = makeDefinitionFilter(filter);
166:
167:                    DefaultQuery defQuery = new DefaultQuery(query);
168:                    defQuery.setFilter(filter);
169:                    defQuery.setPropertyNames(propNames);
170:
171:                    //set sort by
172:                    if (query.getSortBy() != null) {
173:                        defQuery.setSortBy(query.getSortBy());
174:                    }
175:
176:                    return defQuery;
177:                } catch (Exception ex) {
178:                    throw new DataSourceException(
179:                            "Could not restrict the query to the definition criteria: "
180:                                    + ex.getMessage(), ex);
181:                }
182:            }
183:
184:            /**
185:             * List of allowed attributes.
186:             *
187:             * <p>
188:             * Creates a list of FeatureTypeInfo's attribute names based on the
189:             * attributes requested by <code>query</code> and making sure they not
190:             * contain any non exposed attribute.
191:             * </p>
192:             *
193:             * <p>
194:             * Exposed attributes are those configured in the "attributes" element of
195:             * the FeatureTypeInfo's configuration
196:             * </p>
197:             *
198:             * @param query User's origional query
199:             * @param schema TODO
200:             *
201:             * @return List of allowed attribute types
202:             */
203:            private String[] extractAllowedAttributes(Query query,
204:                    FeatureType schema) {
205:                String[] propNames = null;
206:
207:                if (query.retrieveAllProperties()) {
208:                    propNames = new String[schema.getAttributeCount()];
209:
210:                    for (int i = 0; i < schema.getAttributeCount(); i++) {
211:                        propNames[i] = schema.getAttributeType(i).getName();
212:                    }
213:                } else {
214:                    String[] queriedAtts = query.getPropertyNames();
215:                    int queriedAttCount = queriedAtts.length;
216:                    List allowedAtts = new LinkedList();
217:
218:                    for (int i = 0; i < queriedAttCount; i++) {
219:                        if (schema.getAttributeType(queriedAtts[i]) != null) {
220:                            allowedAtts.add(queriedAtts[i]);
221:                        } else {
222:                            LOGGER.info("queried a not allowed property: "
223:                                    + queriedAtts[i]
224:                                    + ". Ommitting it from query");
225:                        }
226:                    }
227:
228:                    propNames = (String[]) allowedAtts
229:                            .toArray(new String[allowedAtts.size()]);
230:                }
231:
232:                return propNames;
233:            }
234:
235:            /**
236:             * If a definition query has been configured for the FeatureTypeInfo, makes
237:             * and return a new Filter that contains both the query's filter and the
238:             * layer's definition one, by logic AND'ing them.
239:             *
240:             * @param filter Origional user supplied Filter
241:             *
242:             * @return Filter adjusted to the limitations of definitionQuery
243:             *
244:             * @throws DataSourceException If the filter could not meet the limitations
245:             *         of definitionQuery
246:             */
247:            protected Filter makeDefinitionFilter(Filter filter)
248:                    throws DataSourceException {
249:                Filter newFilter = filter;
250:
251:                try {
252:                    if (definitionQuery != Filter.INCLUDE) {
253:                        FilterFactory ff = CommonFactoryFinder
254:                                .getFilterFactory(null);
255:                        newFilter = ff.and(definitionQuery, filter);
256:                    }
257:                } catch (Exception ex) {
258:                    throw new DataSourceException(
259:                            "Can't create the definition filter", ex);
260:                }
261:
262:                return newFilter;
263:            }
264:
265:            /**
266:             * Implement getDataStore.
267:             *
268:             * <p>
269:             * Description ...
270:             * </p>
271:             *
272:             * @return
273:             *
274:             * @see org.geotools.data.FeatureSource#getDataStore()
275:             */
276:            public DataStore getDataStore() {
277:                return source.getDataStore();
278:            }
279:
280:            /**
281:             * Implement addFeatureListener.
282:             *
283:             * <p>
284:             * Description ...
285:             * </p>
286:             *
287:             * @param listener
288:             *
289:             * @see org.geotools.data.FeatureSource#addFeatureListener(org.geotools.data.FeatureListener)
290:             */
291:            public void addFeatureListener(FeatureListener listener) {
292:                source.addFeatureListener(listener);
293:            }
294:
295:            /**
296:             * Implement removeFeatureListener.
297:             *
298:             * <p>
299:             * Description ...
300:             * </p>
301:             *
302:             * @param listener
303:             *
304:             * @see org.geotools.data.FeatureSource#removeFeatureListener(org.geotools.data.FeatureListener)
305:             */
306:            public void removeFeatureListener(FeatureListener listener) {
307:                source.removeFeatureListener(listener);
308:            }
309:
310:            /**
311:             * Implement getFeatures.
312:             *
313:             * <p>
314:             * Description ...
315:             * </p>
316:             *
317:             * @param query
318:             *
319:             * @return
320:             *
321:             * @throws IOException
322:             *
323:             * @see org.geotools.data.FeatureSource#getFeatures(org.geotools.data.Query)
324:             */
325:            public FeatureCollection getFeatures(Query query)
326:                    throws IOException {
327:                Query reprojected = reprojectFilter(query);
328:                Query newQuery = adaptQuery(reprojected, schema);
329:
330:                CoordinateReferenceSystem targetCRS = query
331:                        .getCoordinateSystemReproject();
332:                try {
333:                    //this is the raw "unprojected" feature collection
334:                    FeatureCollection fc = source.getFeatures(newQuery);
335:
336:                    return reprojectFeatureCollection(targetCRS, fc);
337:                } catch (Exception e) {
338:                    throw new DataSourceException(e);
339:                }
340:            }
341:
342:            private Query reprojectFilter(Query query) throws IOException {
343:                FeatureType nativeFeatureType = source.getSchema();
344:                final GeometryAttributeType geom = nativeFeatureType
345:                        .getDefaultGeometry();
346:                // handle the geometryless case
347:                if (geom == null)
348:                    return query;
349:                try {
350:                    // default CRS: the CRS we can assume geometry and bbox elements in filter are
351:                    // that is, usually the declared one, but the native one in the leave case
352:                    CoordinateReferenceSystem defaultCRS = null;
353:                    // we need to reproject all bbox and geometries to a target crs, which is
354:                    // the native one usually, but it's the declared on in the force case (since in
355:                    // that case we completely ignore the native one)
356:                    CoordinateReferenceSystem targetCRS = null;
357:                    CoordinateReferenceSystem nativeCRS = geom
358:                            .getCoordinateSystem();
359:                    if (srsHandling == FeatureTypeInfo.FORCE) {
360:                        defaultCRS = declaredCRS;
361:                        targetCRS = declaredCRS;
362:                        nativeFeatureType = FeatureTypes.transform(
363:                                nativeFeatureType, declaredCRS);
364:                    } else if (srsHandling == FeatureTypeInfo.REPROJECT) {
365:                        defaultCRS = declaredCRS;
366:                        targetCRS = nativeCRS;
367:                    } else { // FeatureTypeInfo.LEAVE
368:                        defaultCRS = nativeCRS;
369:                        targetCRS = nativeCRS;
370:                    }
371:
372:                    // now we apply a default to all geometries and bbox in the filter
373:                    FilterFactory2 ff = CommonFactoryFinder
374:                            .getFilterFactory2(null);
375:                    DefaultCRSFilterVisitor defaultCRSVisitor = new DefaultCRSFilterVisitor(
376:                            ff, defaultCRS);
377:                    Filter defaultedFilter = (Filter) query.getFilter().accept(
378:                            defaultCRSVisitor, null);
379:
380:                    // and then we reproject all geometries so that the datastore receives
381:                    // them in the native projection system (or the forced one, in case of force) 
382:                    ReprojectingFilterVisitor reprojectingVisitor = new ReprojectingFilterVisitor(
383:                            ff, nativeFeatureType);
384:                    Filter reprojectedFilter = (Filter) defaultedFilter.accept(
385:                            reprojectingVisitor, null);
386:
387:                    DefaultQuery reprojectedQuery = new DefaultQuery(query);
388:                    reprojectedQuery.setFilter(reprojectedFilter);
389:                    return reprojectedQuery;
390:                } catch (Exception e) {
391:                    throw new DataSourceException(
392:                            "Had troubles handling filter reprojection...", e);
393:                }
394:            }
395:
396:            /**
397:             * Wraps feature collection as needed in order to respect srs handling and reprojection
398:             * @param targetCRS
399:             * @param fc
400:             * @return
401:             * @throws IOException
402:             * @throws SchemaException
403:             * @throws TransformException
404:             * @throws OperationNotFoundException
405:             * @throws FactoryException
406:             */
407:            protected FeatureCollection reprojectFeatureCollection(
408:                    CoordinateReferenceSystem targetCRS, FeatureCollection fc)
409:                    throws IOException, SchemaException, TransformException,
410:                    OperationNotFoundException, FactoryException {
411:                if (fc.getSchema().getDefaultGeometry() == null) {
412:                    // reprojection and crs forcing do not make sense, bail out
413:                    return fc;
414:                }
415:                CoordinateReferenceSystem nativeCRS = fc.getSchema()
416:                        .getDefaultGeometry().getCoordinateSystem();
417:
418:                if (nativeCRS == null) {
419:                    fc = new ForceCoordinateSystemFeatureResults(fc,
420:                            declaredCRS);
421:                    nativeCRS = declaredCRS;
422:                } else if (srsHandling == FeatureTypeInfo.FORCE
423:                        && !nativeCRS.equals(declaredCRS)) {
424:                    fc = new ForceCoordinateSystemFeatureResults(fc,
425:                            declaredCRS);
426:                    nativeCRS = declaredCRS;
427:                } else if (srsHandling == FeatureTypeInfo.REPROJECT
428:                        && targetCRS == null && !nativeCRS.equals(declaredCRS)) {
429:                    fc = new ReprojectFeatureResults(fc, declaredCRS);
430:                }
431:
432:                //was reproject specified as part of the query?
433:                if (targetCRS != null) {
434:                    //reprojection is occuring
435:                    if (nativeCRS == null) {
436:                        //we do not know what the native crs which means we can 
437:                        // not be sure if we should reproject or not... so we go 
438:                        // ahead and reproject regardless
439:                        fc = new ReprojectFeatureResults(fc, targetCRS);
440:                    } else {
441:                        //only reproject if native != target
442:                        if (!CRS.equalsIgnoreMetadata(nativeCRS, targetCRS)) {
443:                            fc = new ReprojectFeatureResults(fc, targetCRS);
444:                        }
445:                    }
446:                }
447:                return fc;
448:            }
449:
450:            /**
451:             * Transforms the query applying the definition query in this layer, removes reprojection
452:             * since data stores cannot be trusted
453:             * @param query
454:             * @param schema TODO
455:             * @return
456:             * @throws IOException
457:             */
458:            protected Query adaptQuery(Query query, FeatureType schema)
459:                    throws IOException {
460:                // if needed, reproject the filter to the native srs
461:
462:                Query newQuery = makeDefinitionQuery(query, schema);
463:
464:                // see if the CRS got xfered over
465:                // a. old had a CRS, new doesnt
466:                boolean requireXferCRS = (newQuery.getCoordinateSystem() == null)
467:                        && (query.getCoordinateSystem() != null);
468:
469:                if ((newQuery.getCoordinateSystem() != null)
470:                        && (query.getCoordinateSystem() != null)) {
471:                    //b. both have CRS, but they're different
472:                    requireXferCRS = !(newQuery.getCoordinateSystem()
473:                            .equals(query.getCoordinateSystem()));
474:                }
475:
476:                if (requireXferCRS) {
477:                    //carry along the CRS
478:                    if (!(newQuery instanceof  DefaultQuery)) {
479:                        newQuery = new DefaultQuery(newQuery);
480:                    }
481:
482:                    ((DefaultQuery) newQuery).setCoordinateSystem(query
483:                            .getCoordinateSystem());
484:                }
485:
486:                //JD: this is a huge hack... but its the only way to ensure that we 
487:                // we get what we ask for ... which is not reprojection, since 
488:                // datastores are unreliable in this aspect we dont know if they will
489:                // reproject or not.
490:                if (newQuery.getCoordinateSystemReproject() != null) {
491:                    ((DefaultQuery) newQuery)
492:                            .setCoordinateSystemReproject(null);
493:                }
494:                return newQuery;
495:            }
496:
497:            public FeatureCollection getFeatures(Filter filter)
498:                    throws IOException {
499:                return getFeatures(new DefaultQuery(schema.getTypeName(),
500:                        filter));
501:            }
502:
503:            public FeatureCollection getFeatures() throws IOException {
504:                return getFeatures(Query.ALL);
505:            }
506:
507:            /**
508:             * Implement getSchema.
509:             *
510:             * <p>
511:             * Description ...
512:             * </p>
513:             *
514:             * @return
515:             *
516:             * @see org.geotools.data.FeatureSource#getSchema()
517:             */
518:            public FeatureType getSchema() {
519:                return schema;
520:            }
521:
522:            /**
523:             * Retrieves the total extent of this FeatureSource.
524:             *
525:             * <p>
526:             * Please note this extent will reflect the provided definitionQuery.
527:             * </p>
528:             *
529:             * @return Extent of this FeatureSource, or <code>null</code> if no
530:             *         optimizations exist.
531:             *
532:             * @throws IOException If bounds of definitionQuery
533:             */
534:            public Envelope getBounds() throws IOException {
535:                // since CRS is at most forced, we don't need to change this code
536:                if (definitionQuery == Filter.INCLUDE) {
537:                    return source.getBounds();
538:                } else {
539:                    Query query = new DefaultQuery(getSchema().getTypeName(),
540:                            definitionQuery);
541:
542:                    return source.getBounds(query);
543:                }
544:            }
545:
546:            /**
547:             * Retrive the extent of the Query.
548:             *
549:             * <p>
550:             * This method provides access to an optimized getBounds opperation. If no
551:             * optimized opperation is available <code>null</code> will be returned.
552:             * </p>
553:             *
554:             * <p>
555:             * You may still make use of getFeatures( Query ).getCount() which will
556:             * return the correct answer (even if it has to itterate through all the
557:             * results to do so.
558:             * </p>
559:             *
560:             * @param query User's query
561:             *
562:             * @return Extend of Query or <code>null</code> if no optimization is
563:             *         available
564:             *
565:             * @throws IOException If a problem is encountered with source
566:             */
567:            public Envelope getBounds(Query query) throws IOException {
568:                // since CRS is at most forced, we don't need to change this code
569:                try {
570:                    query = makeDefinitionQuery(query, schema);
571:                } catch (IOException ex) {
572:                    return null;
573:                }
574:
575:                return source.getBounds(query);
576:            }
577:
578:            /**
579:             * Adjust query and forward to source.
580:             *
581:             * <p>
582:             * This method provides access to an optimized getCount opperation. If no
583:             * optimized opperation is available <code>-1</code> will be returned.
584:             * </p>
585:             *
586:             * <p>
587:             * You may still make use of getFeatures( Query ).getCount() which will
588:             * return the correct answer (even if it has to itterate through all the
589:             * results to do so).
590:             * </p>
591:             *
592:             * @param query User's query.
593:             *
594:             * @return Number of Features for Query, or -1 if no optimization is
595:             *         available.
596:             */
597:            public int getCount(Query query) {
598:                try {
599:                    query = makeDefinitionQuery(query, schema);
600:                } catch (IOException ex) {
601:                    return -1;
602:                }
603:
604:                try {
605:                    return source.getCount(query);
606:                } catch (IOException e) {
607:                    return 0;
608:                }
609:            }
610:
611:            public Set getSupportedHints() {
612:                return source.getSupportedHints();
613:            }
614:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.