001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
003: * for visualizing and manipulating spatial features with geometry and attributes.
004: *
005: * Copyright (C) 2003 Vivid Solutions
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: *
021: * For more information, contact:
022: *
023: * Vivid Solutions
024: * Suite #1A
025: * 2328 Government Street
026: * Victoria BC V8T 5G5
027: * Canada
028: *
029: * (250)385-6040
030: * www.vividsolutions.com
031: */
032:
033: package com.vividsolutions.jump.feature;
034:
035: import java.util.*;
036:
037: import com.vividsolutions.jts.geom.Envelope;
038: import com.vividsolutions.jts.util.Assert;
039:
040: /**
041: * Delegates to another instance of FeatureCollection. A useful means of
042: * overriding the behaviour of a FeatureCollection dynamically, at run-time
043: * (i.e. without subclassing).
044: */
045: public abstract class FeatureCollectionWrapper implements
046: FeatureCollection {
047: private FeatureCollection fc;
048:
049: /**
050: * Constructs a FeatureCollectionWrapper that delegates to the given
051: * FeatureCollection.
052: */
053: public FeatureCollectionWrapper(FeatureCollection fc) {
054: this .fc = fc;
055: }
056:
057: /**
058: * Returns the non-wrapper FeatureCollection wrapped by this wrapper and
059: * possibly by other wrappers in-between. Intended to get at the "real"
060: * FeatureCollection underneath several layers of FeatureCollectionWrappers.
061: *
062: * @see #getWrappee()
063: */
064: public FeatureCollection getUltimateWrappee() {
065: FeatureCollection currentWrappee = fc;
066: while (currentWrappee instanceof FeatureCollectionWrapper) {
067: currentWrappee = ((FeatureCollectionWrapper) currentWrappee).fc;
068: }
069: return currentWrappee;
070: }
071:
072: /**
073: * Throws an AssertionFailedException if this FeatureCollectionWrapper wraps
074: * (directly or indirectly) another FeatureCollectionWrapper having the same
075: * class (or descendant class thereof). A consistency check that is useful
076: * for some FeatureCollectionWrapper implementations.
077: */
078: public void checkNotWrappingSameClass() {
079: Assert
080: .isTrue(!(fc instanceof FeatureCollectionWrapper && ((FeatureCollectionWrapper) fc)
081: .hasWrapper(getClass())));
082: }
083:
084: public Collection remove(Envelope env) {
085: return fc.remove(env);
086: }
087:
088: /**
089: * Returns whether this FeatureCollectionWrapper (or a
090: * FeatureCollectionWrapper that it wraps, directly or indirectly) is an
091: * instance of the given class (or one of its descendants).
092: */
093: public boolean hasWrapper(Class c) {
094: Assert.isTrue(FeatureCollectionWrapper.class
095: .isAssignableFrom(c));
096:
097: if (c.isInstance(this )) {
098: return true;
099: }
100:
101: return fc instanceof FeatureCollectionWrapper
102: && ((FeatureCollectionWrapper) fc).hasWrapper(c);
103: }
104:
105: /**
106: * Returns the FeatureCollection that this wrapper delegates to (possibly
107: * another FeatureCollectionWrapper).
108: *
109: * @see #getUltimateWrappee()
110: */
111: public FeatureCollection getWrappee() {
112: return fc;
113: }
114:
115: public FeatureSchema getFeatureSchema() {
116: return fc.getFeatureSchema();
117: }
118:
119: public Envelope getEnvelope() {
120: return fc.getEnvelope();
121: }
122:
123: public int size() {
124: return fc.size();
125: }
126:
127: public boolean isEmpty() {
128: return fc.isEmpty();
129: }
130:
131: public List getFeatures() {
132: return fc.getFeatures();
133: }
134:
135: public Iterator iterator() {
136: return fc.iterator();
137: }
138:
139: public List query(Envelope envelope) {
140: return fc.query(envelope);
141: }
142:
143: public void add(Feature feature) {
144: fc.add(feature);
145: }
146:
147: public void remove(Feature feature) {
148: fc.remove(feature);
149: }
150:
151: public void addAll(Collection features) {
152: fc.addAll(features);
153: }
154:
155: public void removeAll(Collection features) {
156: fc.removeAll(features);
157: }
158:
159: public void clear() {
160: //Create a new ArrayList to avoid a ConcurrentModificationException.
161: // [Jon Aquino]
162: removeAll(new ArrayList(getFeatures()));
163: }
164:
165: protected FeatureCollection getFeatureCollection() {
166: return fc;
167: }
168:
169: protected void setFeatureCollection(
170: FeatureCollection featureCollection) {
171: this.fc = featureCollection;
172: }
173: }
|