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


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2002-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.feature;
017:
018:        // J2SE interfaces
019:        import java.io.IOException;
020:        import java.util.ArrayList;
021:        import java.util.Collection;
022:        import java.util.Collections;
023:        import java.util.Iterator;
024:        import java.util.LinkedList;
025:        import java.util.List;
026:        import java.util.NoSuchElementException;
027:        import java.util.Set;
028:        import java.util.SortedMap;
029:        import java.util.TreeMap;
030:
031:        import org.geotools.data.DataSourceException;
032:        import org.geotools.data.FeatureReader;
033:        import org.geotools.feature.collection.FeatureState;
034:        import org.geotools.feature.collection.FeatureIteratorImpl;
035:        import org.geotools.feature.collection.SubFeatureCollection;
036:        import org.geotools.feature.type.FeatureAttributeType;
037:        import org.geotools.feature.visitor.FeatureVisitor;
038:        import org.opengis.filter.Filter;
039:        import org.opengis.filter.sort.SortBy;
040:        import org.geotools.filter.SortBy2;
041:        import org.geotools.geometry.jts.ReferencedEnvelope;
042:        import org.geotools.util.NullProgressListener;
043:        import org.geotools.util.ProgressListener;
044:        import org.geotools.util.logging.Logging;
045:
046:        import com.vividsolutions.jts.geom.Envelope;
047:        import com.vividsolutions.jts.geom.Geometry;
048:
049:        /**
050:         * A basic implementation of FeatureCollection which use a {@link TreeMap} for
051:         * its internal storage.
052:         * <p>
053:         * This should be considered a MemoryFeatureCollection.
054:         * </p>
055:         * 
056:         * @author Ian Schneider
057:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/feature/DefaultFeatureCollection.java $
058:         * @version $Id: DefaultFeatureCollection.java 27905 2007-11-15 08:51:13Z desruisseaux $
059:         */
060:        public class DefaultFeatureCollection implements  FeatureCollection {
061:
062:            /**
063:             * Contents of collection, referenced by FeatureID.
064:             * <p>
065:             * This use will result in collections that are sorted by FID, in keeping
066:             * with shapefile etc...
067:             * </p>
068:             */
069:            private SortedMap contents = new TreeMap();
070:
071:            /** Internal listener storage list */
072:            private List listeners = new ArrayList(2);
073:
074:            /** Internal envelope of bounds. */
075:            private Envelope bounds = null;
076:
077:            private String id; /// fid
078:
079:            /**
080:             * This contructor should not be used by client code.
081:             * <p>
082:             * Opportunistic reuse is encouraged, but only for the purposes
083:             * of testing or other specialized uses. Normal creation should
084:             * occur through <code>org.geotools.core.FeatureCollections.newCollection()</code>
085:             * allowing applications to customize any generated collections.
086:             * </p>
087:             * 
088:             * </p>
089:             * @param id may be null ... feature id
090:             * @param featureType optional, may be null
091:             */
092:            public DefaultFeatureCollection(String id, FeatureType featureType) {
093:                this .id = id;
094:                if (featureType == null) {
095:                    List ats = new LinkedList();
096:                    ats.add(new FeatureAttributeType("_Feature",
097:                            new DefaultFeatureType("AbstractFeatureType",
098:                                    FeatureTypes.DEFAULT_NAMESPACE,
099:                                    new LinkedList(), new LinkedList(), null),
100:                            false));
101:                    featureType = new DefaultFeatureType(
102:                            "AbstractFeatureCollectionType",
103:                            FeatureTypes.DEFAULT_NAMESPACE, ats,
104:                            new LinkedList(), null);
105:                }
106:                this .featureType = featureType;
107:                this .childType = null; // no children yet
108:            }
109:
110:            private FeatureType featureType;
111:            private FeatureType childType;
112:
113:            public FeatureType getSchema() {
114:                if (childType == null) {
115:                    // no children guess Features are okay then
116:                    new DefaultFeatureType("AbstractFeatureType",
117:                            FeatureTypes.DEFAULT_NAMESPACE, new LinkedList(),
118:                            new LinkedList(), null);
119:                }
120:                return childType;
121:            }
122:
123:            /**
124:             * Gets the bounding box for the features in this feature collection.
125:             * 
126:             * @return the envelope of the geometries contained by this feature
127:             *         collection.
128:             */
129:            public ReferencedEnvelope getBounds() {
130:                if (bounds == null) {
131:                    bounds = new Envelope();
132:
133:                    for (Iterator i = contents.values().iterator(); i.hasNext();) {
134:                        Envelope geomBounds = ((Feature) i.next()).getBounds();
135:                        // IanS - as of 1.3, JTS expandToInclude ignores "null" Envelope
136:                        // and simply adds the new bounds...
137:                        // This check ensures this behavior does not occur.
138:                        if (!geomBounds.isNull()) {
139:                            bounds.expandToInclude(geomBounds);
140:                        }
141:                    }
142:                }
143:                return ReferencedEnvelope.reference(bounds);
144:            }
145:
146:            /**
147:             * Adds a listener for collection events.
148:             *
149:             * @param listener The listener to add
150:             */
151:            public void addListener(CollectionListener listener) {
152:                listeners.add(listener);
153:            }
154:
155:            /**
156:             * Removes a listener for collection events.
157:             *
158:             * @param listener The listener to remove
159:             */
160:            public void removeListener(CollectionListener listener) {
161:                listeners.remove(listener);
162:            }
163:
164:            /**
165:             * To let listeners know that something has changed.
166:             */
167:            protected void fireChange(Feature[] features, int type) {
168:                bounds = null;
169:
170:                CollectionEvent cEvent = new CollectionEvent(this , features,
171:                        type);
172:
173:                for (int i = 0, ii = listeners.size(); i < ii; i++) {
174:                    ((CollectionListener) listeners.get(i))
175:                            .collectionChanged(cEvent);
176:                }
177:            }
178:
179:            protected void fireChange(Feature feature, int type) {
180:                fireChange(new Feature[] { feature }, type);
181:            }
182:
183:            protected void fireChange(Collection coll, int type) {
184:                Feature[] features = new Feature[coll.size()];
185:                features = (Feature[]) coll.toArray(features);
186:                fireChange(features, type);
187:            }
188:
189:            /**
190:             * Ensures that this collection contains the specified element (optional
191:             * operation).  Returns <tt>true</tt> if this collection changed as a
192:             * result of the call.  (Returns <tt>false</tt> if this collection does
193:             * not permit duplicates and already contains the specified element.)
194:             * 
195:             * <p>
196:             * Collections that support this operation may place limitations on what
197:             * elements may be added to this collection.  In particular, some
198:             * collections will refuse to add <tt>null</tt> elements, and others will
199:             * impose restrictions on the type of elements that may be added.
200:             * Collection classes should clearly specify in their documentation any
201:             * restrictions on what elements may be added.
202:             * </p>
203:             * 
204:             * <p>
205:             * If a collection refuses to add a particular element for any reason other
206:             * than that it already contains the element, it <i>must</i> throw an
207:             * exception (rather than returning <tt>false</tt>).  This preserves the
208:             * invariant that a collection always contains the specified element after
209:             * this call returns.
210:             * </p>
211:             *
212:             * @param o element whose presence in this collection is to be ensured.
213:             *
214:             * @return <tt>true</tt> if this collection changed as a result of the call
215:             */
216:            public boolean add(Object o) {
217:                return add((Feature) o, true);
218:            }
219:
220:            protected boolean add(Feature feature, boolean fire) {
221:
222:                // This cast is neccessary to keep with the contract of Set!
223:                if (feature == null)
224:                    return false; // cannot add null!
225:                final String ID = feature.getID();
226:                if (ID == null)
227:                    return false; // ID is required!
228:                if (contents.containsKey(ID))
229:                    return false; // feature all ready present
230:
231:                if (childType == null) {
232:                    childType = feature.getFeatureType();
233:                } else {
234:                    if (!feature.getFeatureType().equals(childType))
235:                        Logging.getLogger("org.geotools.feature.collections")
236:                                .warning(
237:                                        "Feature Collection contains a heterogeneous"
238:                                                + " mix of features");
239:                }
240:                //TODO check inheritance with FeatureType here!!!
241:                contents.put(ID, feature);
242:                if (fire) {
243:                    fireChange(feature, CollectionEvent.FEATURES_ADDED);
244:                }
245:                return true;
246:            }
247:
248:            /**
249:             * Adds all of the elements in the specified collection to this collection
250:             * (optional operation).  The behavior of this operation is undefined if
251:             * the specified collection is modified while the operation is in
252:             * progress. (This implies that the behavior of this call is undefined if
253:             * the specified collection is this collection, and this collection is
254:             * nonempty.)
255:             *
256:             * @param collection elements to be inserted into this collection.
257:             *
258:             * @return <tt>true</tt> if this collection changed as a result of the call
259:             *
260:             * @see #add(Object)
261:             */
262:            public boolean addAll(Collection collection) {
263:                //TODO check inheritance with FeatureType here!!!
264:                boolean changed = false;
265:
266:                Iterator iterator = collection.iterator();
267:                try {
268:                    List featuresAdded = new ArrayList(collection.size());
269:                    while (iterator.hasNext()) {
270:                        Feature f = (Feature) iterator.next();
271:                        boolean added = add(f, false);
272:                        changed |= added;
273:
274:                        if (added)
275:                            featuresAdded.add(f);
276:                    }
277:
278:                    if (changed) {
279:                        fireChange(featuresAdded,
280:                                CollectionEvent.FEATURES_ADDED);
281:                    }
282:
283:                    return changed;
284:                } finally {
285:                    if (collection instanceof  FeatureCollection) {
286:                        ((FeatureCollection) collection).close(iterator);
287:                    }
288:                }
289:            }
290:
291:            /**
292:             * Removes all of the elements from this collection (optional operation).
293:             * This collection will be empty after this method returns unless it
294:             * throws an exception.
295:             */
296:            public void clear() {
297:                if (contents.isEmpty())
298:                    return;
299:
300:                Feature[] oldFeatures = new Feature[contents.size()];
301:                oldFeatures = (Feature[]) contents.values()
302:                        .toArray(oldFeatures);
303:
304:                contents.clear();
305:                fireChange(oldFeatures, CollectionEvent.FEATURES_REMOVED);
306:            }
307:
308:            /**
309:             * Returns <tt>true</tt> if this collection contains the specified element.
310:             * More formally, returns <tt>true</tt> if and only if this collection
311:             * contains at least one element <tt>e</tt> such that <tt>(o==null ?
312:             * e==null : o.equals(e))</tt>.
313:             *
314:             * @param o element whose presence in this collection is to be tested.
315:             *
316:             * @return <tt>true</tt> if this collection contains the specified element
317:             */
318:            public boolean contains(Object o) {
319:                // The contract of Set doesn't say we have to cast here, but I think its
320:                // useful for client sanity to get a ClassCastException and not just a
321:                // false.
322:                if (!(o instanceof  Feature))
323:                    return false;
324:
325:                Feature feature = (Feature) o;
326:                final String ID = feature.getID();
327:
328:                return contents.containsKey(ID); // || contents.containsValue( feature );        
329:            }
330:
331:            /**
332:             * Test for collection membership.
333:             * 
334:             * @param collection
335:             * @return true if collection is completly covered
336:             */
337:            public boolean containsAll(Collection collection) {
338:                Iterator iterator = collection.iterator();
339:                try {
340:                    while (iterator.hasNext()) {
341:                        Feature feature = (Feature) iterator.next();
342:                        if (!contents.containsKey(feature.getID())) {
343:                            return false;
344:                        }
345:                    }
346:                    return true;
347:                } finally {
348:                    if (collection instanceof  FeatureCollection) {
349:                        ((FeatureCollection) collection).close(iterator);
350:                    }
351:                }
352:            }
353:
354:            /**
355:             * Returns <tt>true</tt> if this collection contains no elements.
356:             *
357:             * @return <tt>true</tt> if this collection contains no elements
358:             */
359:            public boolean isEmpty() {
360:                return contents.isEmpty();
361:            }
362:
363:            /**
364:             * Returns an iterator over the elements in this collection.  There are no
365:             * guarantees concerning the order in which the elements are returned
366:             * (unless this collection is an instance of some class that provides a
367:             * guarantee).
368:             *
369:             * @return an <tt>Iterator</tt> over the elements in this collection
370:             */
371:            public Iterator iterator() {
372:                final Iterator iterator = contents.values().iterator();
373:
374:                return new Iterator() {
375:                    Feature currFeature = null;
376:
377:                    public boolean hasNext() {
378:                        return iterator.hasNext();
379:                    }
380:
381:                    public Object next() {
382:                        currFeature = (Feature) iterator.next();
383:                        return currFeature;
384:                    }
385:
386:                    public void remove() {
387:                        iterator.remove();
388:                        fireChange(currFeature,
389:                                CollectionEvent.FEATURES_REMOVED);
390:                    }
391:                };
392:            }
393:
394:            /**
395:             * Gets a FeatureIterator of this feature collection.  This allows
396:             * iteration without having to cast.
397:             *
398:             * @return the FeatureIterator for this collection.
399:             */
400:            public FeatureIterator features() {
401:                return new FeatureIteratorImpl(this );
402:            }
403:
404:            /**
405:             * Removes a single instance of the specified element from this collection,
406:             * if it is present (optional operation).  More formally, removes an
407:             * element <tt>e</tt> such that <tt>(o==null ?  e==null :
408:             * o.equals(e))</tt>, if this collection contains one or more such
409:             * elements.  Returns true if this collection contained the specified
410:             * element (or equivalently, if this collection changed as a result of the
411:             * call).
412:             *
413:             * @param o element to be removed from this collection, if present.
414:             *
415:             * @return <tt>true</tt> if this collection changed as a result of the call
416:             */
417:            public boolean remove(Object o) {
418:                if (!(o instanceof  Feature))
419:                    return false;
420:
421:                Feature f = (Feature) o;
422:                boolean changed = contents.values().remove(f);
423:
424:                if (changed) {
425:                    fireChange(f, CollectionEvent.FEATURES_REMOVED);
426:                }
427:                return changed;
428:            }
429:
430:            /**
431:             * Removes all this collection's elements that are also contained in the
432:             * specified collection (optional operation).  After this call returns,
433:             * this collection will contain no elements in common with the specified
434:             * collection.
435:             *
436:             * @param collection elements to be removed from this collection.
437:             *
438:             * @return <tt>true</tt> if this collection changed as a result of the call
439:             *
440:             * @see #remove(Object)
441:             * @see #contains(Object)
442:             */
443:            public boolean removeAll(Collection collection) {
444:                boolean changed = false;
445:                Iterator iterator = collection.iterator();
446:                try {
447:                    List removedFeatures = new ArrayList(collection.size());
448:                    while (iterator.hasNext()) {
449:                        Feature f = (Feature) iterator.next();
450:                        boolean removed = contents.values().remove(f);
451:
452:                        if (removed) {
453:                            changed = true;
454:                            removedFeatures.add(f);
455:                        }
456:                    }
457:
458:                    if (changed) {
459:                        fireChange(removedFeatures,
460:                                CollectionEvent.FEATURES_REMOVED);
461:                    }
462:
463:                    return changed;
464:                } finally {
465:                    if (collection instanceof  FeatureCollection) {
466:                        ((FeatureCollection) collection).close(iterator);
467:                    }
468:                }
469:            }
470:
471:            /**
472:             * Retains only the elements in this collection that are contained in the
473:             * specified collection (optional operation).  In other words, removes
474:             * from this collection all of its elements that are not contained in the
475:             * specified collection.
476:             *
477:             * @param collection elements to be retained in this collection.
478:             *
479:             * @return <tt>true</tt> if this collection changed as a result of the call
480:             *
481:             * @see #remove(Object)
482:             * @see #contains(Object)
483:             */
484:            public boolean retainAll(Collection collection) {
485:                List removedFeatures = new ArrayList(contents.size()
486:                        - collection.size());
487:                boolean modified = false;
488:
489:                for (Iterator it = contents.values().iterator(); it.hasNext();) {
490:                    Feature f = (Feature) it.next();
491:                    if (!collection.contains(f)) {
492:                        it.remove();
493:                        modified = true;
494:                        removedFeatures.add(f);
495:                    }
496:                }
497:
498:                if (modified) {
499:                    fireChange(removedFeatures,
500:                            CollectionEvent.FEATURES_REMOVED);
501:                }
502:
503:                return modified;
504:            }
505:
506:            /**
507:             * Returns the number of elements in this collection.  If this collection
508:             * contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
509:             * <tt>Integer.MAX_VALUE</tt>.
510:             *
511:             * @return the number of elements in this collection
512:             */
513:            public int size() {
514:                return contents.size();
515:            }
516:
517:            /**
518:             * Returns an array containing all of the elements in this collection.  If
519:             * the collection makes any guarantees as to what order its elements are
520:             * returned by its iterator, this method must return the elements in the
521:             * same order.
522:             * 
523:             * <p>
524:             * The returned array will be "safe" in that no references to it are
525:             * maintained by this collection.  (In other words, this method must
526:             * allocate a new array even if this collection is backed by an array).
527:             * The caller is thus free to modify the returned array.
528:             * </p>
529:             * 
530:             * <p>
531:             * This method acts as bridge between array-based and collection-based
532:             * APIs.
533:             * </p>
534:             *
535:             * @return an array containing all of the elements in this collection
536:             */
537:            public Object[] toArray() {
538:                return contents.values().toArray();
539:            }
540:
541:            /**
542:             * Returns an array containing all of the elements in this collection; the
543:             * runtime type of the returned array is that of the specified array. If
544:             * the collection fits in the specified array, it is returned therein.
545:             * Otherwise, a new array is allocated with the runtime type of the
546:             * specified array and the size of this collection.
547:             * 
548:             * <p>
549:             * If this collection fits in the specified array with room to spare (i.e.,
550:             * the array has more elements than this collection), the element in the
551:             * array immediately following the end of the collection is set to
552:             * <tt>null</tt>.  This is useful in determining the length of this
553:             * collection <i>only</i> if the caller knows that this collection does
554:             * not contain any <tt>null</tt> elements.)
555:             * </p>
556:             * 
557:             * <p>
558:             * If this collection makes any guarantees as to what order its elements
559:             * are returned by its iterator, this method must return the elements in
560:             * the same order.
561:             * </p>
562:             * 
563:             * <p>
564:             * Like the <tt>toArray</tt> method, this method acts as bridge between
565:             * array-based and collection-based APIs.  Further, this method allows
566:             * precise control over the runtime type of the output array, and may,
567:             * under certain circumstances, be used to save allocation costs
568:             * </p>
569:             * 
570:             * <p>
571:             * Suppose <tt>l</tt> is a <tt>List</tt> known to contain only strings. The
572:             * following code can be used to dump the list into a newly allocated
573:             * array of <tt>String</tt>:
574:             * <pre>
575:             *     String[] x = (String[]) v.toArray(new String[0]);
576:             * </pre>
577:             * </p>
578:             * 
579:             * <p>
580:             * Note that <tt>toArray(new Object[0])</tt> is identical in function to
581:             * <tt>toArray()</tt>.
582:             * </p>
583:             *
584:             * @param a the array into which the elements of this collection are to be
585:             *        stored, if it is big enough; otherwise, a new array of the same
586:             *        runtime type is allocated for this purpose.
587:             *
588:             * @return an array containing the elements of this collection
589:             */
590:            public Object[] toArray(Object[] a) {
591:                return contents.values().toArray(a);
592:            }
593:
594:            /* (non-Javadoc)
595:             * @see org.geotools.feature.FeatureCollection#getFeatureType()
596:             */
597:            public FeatureType getFeatureType() {
598:                return featureType;
599:            }
600:
601:            private FeatureCollection parent;
602:
603:            /* (non-Javadoc)
604:             * @see org.geotools.feature.Feature#getParent()
605:             */
606:            public FeatureCollection getParent() {
607:                // TODO deal with listeners?
608:                return parent;
609:            }
610:
611:            /* (non-Javadoc)
612:             * @see org.geotools.feature.Feature#setParent(org.geotools.feature.FeatureCollection)
613:             */
614:            public void setParent(FeatureCollection collection) {
615:                parent = collection;
616:            }
617:
618:            /* (non-Javadoc)
619:             * @see org.geotools.feature.Feature#getID()
620:             */
621:            public String getID() {
622:                return id;
623:            }
624:
625:            /* (non-Javadoc)
626:             * @see org.geotools.feature.Feature#getAttributes(java.lang.Object[])
627:             */
628:            public Object[] getAttributes(Object[] attributes) {
629:                return toArray(attributes);
630:            }
631:
632:            /* (non-Javadoc)
633:             * @see org.geotools.feature.Feature#getAttribute(java.lang.String)
634:             */
635:            public Object getAttribute(String xPath) {
636:                if (xPath.indexOf(featureType.getTypeName()) > -1)
637:                    if (xPath.endsWith("]")) {
638:                        return contents.values(); // TODO get index and grab it                
639:                    } else {
640:                        return contents.values();
641:                    }
642:                return null;
643:            }
644:
645:            /* (non-Javadoc)
646:             * @see org.geotools.feature.Feature#getAttribute(int)
647:             */
648:            public Object getAttribute(int index) {
649:                if (index == 0) {
650:                    return contents.values();
651:                }
652:                return null;
653:            }
654:
655:            /* (non-Javadoc)
656:             * @see org.geotools.feature.Feature#setAttribute(int, java.lang.Object)
657:             */
658:            public void setAttribute(int position, Object val)
659:                    throws IllegalAttributeException,
660:                    ArrayIndexOutOfBoundsException {
661:                if (position == 0 && val instanceof  List) {
662:                    List nw = (List) val;
663:                    if (!FeatureState.isFeatures(nw))
664:                        return;
665:
666:                    contents.clear();
667:                    for (Iterator i = nw.iterator(); i.hasNext();) {
668:                        Feature feature = (Feature) i.next();
669:                        contents.put(feature.getID(), feature);
670:                    }
671:                    fireChange(nw, 0);
672:                }
673:            }
674:
675:            /* (non-Javadoc)
676:             * @see org.geotools.feature.Feature#getNumberOfAttributes()
677:             */
678:            public int getNumberOfAttributes() {
679:                return featureType == null ? 1 : featureType
680:                        .getAttributeCount();
681:            }
682:
683:            /* (non-Javadoc)
684:             * @see org.geotools.feature.Feature#setAttribute(java.lang.String, java.lang.Object)
685:             */
686:            public void setAttribute(String xPath, Object attribute)
687:                    throws IllegalAttributeException {
688:                if (xPath.indexOf(featureType.getTypeName()) > -1) {
689:                    if (xPath.endsWith("]")) {
690:                        // TODO get index and grab it
691:                    } else {
692:                        setAttribute(0, attribute);
693:                    }
694:                }
695:            }
696:
697:            /* (non-Javadoc)
698:             * @see org.geotools.feature.Feature#getDefaultGeometry()
699:             */
700:            public Geometry getDefaultGeometry() {
701:                return null;
702:            }
703:
704:            /* (non-Javadoc)
705:             * @see org.geotools.feature.Feature#setDefaultGeometry(com.vividsolutions.jts.geom.Geometry)
706:             */
707:            public void setDefaultGeometry(Geometry geometry)
708:                    throws IllegalAttributeException {
709:                throw new IllegalAttributeException("Not Supported");
710:            }
711:
712:            public void close(FeatureIterator close) {
713:                if (close instanceof  FeatureIteratorImpl) {
714:                    FeatureIteratorImpl wrapper = (FeatureIteratorImpl) close;
715:                    wrapper.close();
716:                }
717:            }
718:
719:            public void close(Iterator close) {
720:                // nop
721:            }
722:
723:            public FeatureReader reader() throws IOException {
724:                final FeatureIterator iterator = features();
725:                return new FeatureReader() {
726:                    public FeatureType getFeatureType() {
727:                        return getSchema();
728:                    }
729:
730:                    public Feature next() throws IOException,
731:                            IllegalAttributeException, NoSuchElementException {
732:                        return iterator.next();
733:                    }
734:
735:                    public boolean hasNext() throws IOException {
736:                        return iterator.hasNext();
737:                    }
738:
739:                    public void close() throws IOException {
740:                        DefaultFeatureCollection.this .close(iterator);
741:                    }
742:                };
743:            }
744:
745:            public int getCount() throws IOException {
746:                return contents.size();
747:            }
748:
749:            public FeatureCollection collection() throws IOException {
750:                FeatureCollection copy = new DefaultFeatureCollection(null,
751:                        featureType);
752:                List list = new ArrayList(contents.size());
753:                for (FeatureIterator iterator = features(); iterator.hasNext();) {
754:                    Feature feature = iterator.next();
755:                    Feature duplicate;
756:                    try {
757:                        duplicate = feature.getFeatureType().duplicate(feature);
758:                    } catch (IllegalAttributeException e) {
759:                        throw new DataSourceException("Unable to copy "
760:                                + feature.getID(), e);
761:                    }
762:                    list.add(duplicate);
763:                }
764:                copy.addAll(list);
765:                return copy;
766:            }
767:
768:            /**
769:             * Optimization time ... grab the fid set so other can quickly test membership
770:             * during removeAll/retainAll implementations.
771:             * 
772:             * @return Set of fids.
773:             */
774:            public Set fids() {
775:                return Collections.unmodifiableSet(contents.keySet());
776:            }
777:
778:            /**
779:             * Accepts a visitor, which then visits each feature in the collection.
780:             * @throws IOException 
781:             */
782:            public void accepts(FeatureVisitor visitor,
783:                    ProgressListener progress) throws IOException {
784:                Iterator iterator = null;
785:                if (progress == null)
786:                    progress = new NullProgressListener();
787:                try {
788:                    float size = size();
789:                    float position = 0;
790:                    progress.started();
791:                    for (iterator = iterator(); !progress.isCanceled()
792:                            && iterator.hasNext(); progress.progress(position++
793:                            / size)) {
794:                        try {
795:                            Feature feature = (Feature) iterator.next();
796:                            visitor.visit(feature);
797:                        } catch (Exception erp) {
798:                            progress.exceptionOccurred(erp);
799:                        }
800:                    }
801:                } finally {
802:                    progress.complete();
803:                    close(iterator);
804:                }
805:            }
806:
807:            /**
808:             * Will return an optimized subCollection based on access
809:             * to the origional MemoryFeatureCollection.
810:             * <p>
811:             * This method is intended in a manner similar to subList,
812:             * example use:
813:             * <code>
814:             * collection.subCollection( myFilter ).clear()
815:             * </code>
816:             * </p>    
817:             * @param filter Filter used to determine sub collection.
818:             * @since GeoTools 2.2, Filter 1.1
819:             */
820:            public FeatureCollection subCollection(Filter filter) {
821:                if (filter == Filter.INCLUDE) {
822:                    return this ;
823:                }
824:                return new SubFeatureCollection(this , filter);
825:            }
826:
827:            /**
828:             * Construct a sorted view of this content.
829:             * <p>
830:             * Sorts may be combined togther in a stable fashion, in congruence
831:             * with the Filter 1.1 specification.
832:             * </p>
833:             * <p>
834:             * This method should also be able to handle GeoTools specific
835:             * sorting through detecting order as a SortBy2 instance.
836:             * </p>
837:             * 
838:             * @since GeoTools 2.2, Filter 1.1
839:             * @param order Filter 1.1 SortBy Construction of a Sort
840:             * 
841:             * @return FeatureList sorted according to provided order
842:             * 
843:             */
844:            public FeatureList sort(SortBy order) {
845:                if (order == SortBy.NATURAL_ORDER) {
846:                    // return new FeatureListImpl( this );
847:                }
848:                if (order instanceof  SortBy2) {
849:                    SortBy2 advanced = (SortBy2) order;
850:                    return sort(advanced);
851:                }
852:                return null;
853:            }
854:
855:            /**
856:             * Allows for "Advanced" sort capabilities specific to the
857:             * GeoTools platform!
858:             * <p>
859:             * Advanced in this case really means making use of a generic
860:             * Expression, rather then being limited to PropertyName.
861:             * </p>
862:             * @param order GeoTools SortBy
863:             * @return FeatureList sorted according to provided order
864:             */
865:            public FeatureList sort(SortBy2 order) {
866:                if (order == SortBy.NATURAL_ORDER) {
867:                    // forward
868:                } else if (order == SortBy.REVERSE_ORDER) {
869:                    // backwards
870:                }
871:                // custom
872:                return null; // new OrderedFeatureList( order, compare );
873:            }
874:
875:            public void purge() {
876:                // no resources were harmed in the making of this FeatureCollection
877:            }
878:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.