001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2003-2006, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
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.collection;
017:
018: import java.io.IOException;
019: import java.util.NoSuchElementException;
020:
021: import org.geotools.data.DataTestCase;
022: import org.geotools.data.DataUtilities;
023: import org.geotools.data.DefaultQuery;
024: import org.geotools.data.DefaultTransaction;
025: import org.geotools.data.DiffFeatureReader;
026: import org.geotools.data.EmptyFeatureReader;
027: import org.geotools.data.FeatureReader;
028: import org.geotools.data.FeatureSource;
029: import org.geotools.data.FeatureWriter;
030: import org.geotools.data.FilteringFeatureReader;
031: import org.geotools.data.Query;
032: import org.geotools.data.Transaction;
033: import org.geotools.data.TransactionStateDiff;
034: import org.geotools.feature.Feature;
035: import org.geotools.feature.FeatureCollection;
036: import org.geotools.feature.FeatureIterator;
037: import org.geotools.feature.FeatureType;
038: import org.geotools.feature.IllegalAttributeException;
039: import org.opengis.filter.Filter;
040:
041: import com.vividsolutions.jts.geom.Envelope;
042: import com.vividsolutions.jts.geom.Geometry;
043:
044: /**
045: * DOCUMENT ME!
046: *
047: * @author Jody Garnett, Refractions Research
048: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/test/java/org/geotools/data/collection/CollectionDataStoreTest.java $
049: */
050: public class CollectionDataStoreTest extends DataTestCase {
051: CollectionDataStore data;
052:
053: /**
054: * Constructor for MemoryDataStoreTest.
055: *
056: * @param arg0
057: */
058: public CollectionDataStoreTest(String arg0) {
059: super (arg0);
060: }
061:
062: /*
063: * @see TestCase#setUp()
064: */
065: protected void setUp() throws Exception {
066: super .setUp();
067: data = new CollectionDataStore(DataUtilities
068: .collection(roadFeatures));
069: }
070:
071: /*
072: * @see TestCase#tearDown()
073: */
074: protected void tearDown() throws Exception {
075: data = null;
076: }
077:
078: public void testGetFeatureTypes() {
079: String[] names = data.getTypeNames();
080: assertEquals(1, names.length);
081: assertTrue(contains(names, "road"));
082: }
083:
084: boolean contains(Object[] array, Object expected) {
085: if ((array == null) || (array.length == 0)) {
086: return false;
087: }
088:
089: for (int i = 0; i < array.length; i++) {
090: if (array[i].equals(expected)) {
091: return true;
092: }
093: }
094:
095: return false;
096: }
097:
098: /**
099: * Like contain but based on match rather than equals
100: *
101: * @param array DOCUMENT ME!
102: * @param expected DOCUMENT ME!
103: *
104: * @return DOCUMENT ME!
105: */
106: boolean containsLax(Feature[] array, Feature expected) {
107: if ((array == null) || (array.length == 0)) {
108: return false;
109: }
110:
111: FeatureType type = expected.getFeatureType();
112:
113: for (int i = 0; i < array.length; i++) {
114: if (match(array[i], expected)) {
115: return true;
116: }
117: }
118:
119: return false;
120: }
121:
122: /**
123: * Compare based on attributes not getID allows comparison of Diff contents
124: *
125: * @param expected DOCUMENT ME!
126: * @param actual DOCUMENT ME!
127: *
128: * @return DOCUMENT ME!
129: */
130: boolean match(Feature expected, Feature actual) {
131: FeatureType type = expected.getFeatureType();
132:
133: for (int i = 0; i < type.getAttributeCount(); i++) {
134: Object av = actual.getAttribute(i);
135: Object ev = expected.getAttribute(i);
136:
137: if ((av == null) && (ev != null)) {
138: return false;
139: } else if ((ev == null) && (av != null)) {
140: return false;
141: } else if (av instanceof Geometry && ev instanceof Geometry) {
142: Geometry ag = (Geometry) av;
143: Geometry eg = (Geometry) ev;
144:
145: if (!ag.equals(eg)) {
146: return false;
147: }
148: } else if (!av.equals(ev)) {
149: return false;
150: }
151: }
152:
153: return true;
154: }
155:
156: public void testGetSchema() throws IOException {
157: assertSame(roadType, data.getSchema("road"));
158: }
159:
160: void assertCovers(String msg, FeatureCollection c1,
161: FeatureCollection c2) {
162: if (c1 == c2) {
163: return;
164: }
165:
166: assertNotNull(msg, c1);
167: assertNotNull(msg, c2);
168: assertEquals(msg + " size", c1.size(), c2.size());
169:
170: Feature f;
171:
172: for (FeatureIterator i = c1.features(); i.hasNext();) {
173: f = i.next();
174: assertTrue(msg + " " + f.getID(), c2.contains(f));
175: }
176: }
177:
178: public void testGetFeatureReader() throws IOException,
179: IllegalAttributeException {
180: FeatureReader reader = data.getFeatureReader("road");
181: assertCovered(roadFeatures, reader);
182: assertEquals(false, reader.hasNext());
183: }
184:
185: // public void testGetFeatureReaderMutability() throws IOException, IllegalAttributeException {
186: // FeatureReader reader = data.getFeatureReader("road");
187: // Feature feature;
188: //
189: // while (reader.hasNext()) {
190: // feature = (Feature) reader.next();
191: // feature.setAttribute("name", null);
192: // }
193: //
194: // reader.close();
195: //
196: // reader = data.getFeatureReader("road");
197: //
198: // while (reader.hasNext()) {
199: // feature = (Feature) reader.next();
200: // assertNotNull(feature.getAttribute("name"));
201: // }
202: //
203: // reader.close();
204: //
205: // try {
206: // reader.next();
207: // fail("next should fail with an IOException");
208: // } catch (IOException expected) {
209: // }
210: // }
211:
212: public void testGetFeatureReaderConcurancy()
213: throws NoSuchElementException, IOException,
214: IllegalAttributeException {
215: FeatureReader reader1 = data.getFeatureReader("road");
216: FeatureReader reader2 = data.getFeatureReader("road");
217:
218: Feature feature1;
219: Feature feature2;
220:
221: while (reader1.hasNext() || reader2.hasNext()) {
222: assertTrue(contains(roadFeatures, reader1.next()));
223: assertTrue(contains(roadFeatures, reader2.next()));
224: }
225:
226: try {
227: reader1.next();
228: fail("next should fail with an IOException");
229: } catch (IOException expected) {
230: }
231:
232: try {
233: reader2.next();
234: fail("next should fail with an IOException");
235: } catch (IOException expected) {
236: }
237:
238: reader1.close();
239: reader2.close();
240: }
241:
242: public void testGetFeatureReaderFilterAutoCommit()
243: throws NoSuchElementException, IOException,
244: IllegalAttributeException {
245: FeatureType type = data.getSchema("road");
246: FeatureReader reader;
247:
248: reader = data.getFeatureReader(new DefaultQuery("road"),
249: Transaction.AUTO_COMMIT);
250: assertFalse(reader instanceof FilteringFeatureReader);
251: assertEquals(type, reader.getFeatureType());
252: assertEquals(roadFeatures.length, count(reader));
253:
254: reader = data.getFeatureReader(new DefaultQuery("road",
255: Filter.EXCLUDE), Transaction.AUTO_COMMIT);
256: assertTrue(reader instanceof EmptyFeatureReader);
257:
258: assertEquals(type, reader.getFeatureType());
259: assertEquals(0, count(reader));
260:
261: reader = data.getFeatureReader(new DefaultQuery("road",
262: rd1Filter), Transaction.AUTO_COMMIT);
263: assertTrue(reader instanceof FilteringFeatureReader);
264: assertEquals(type, reader.getFeatureType());
265: assertEquals(1, count(reader));
266: }
267:
268: public void testGetFeatureReaderFilterTransaction()
269: throws NoSuchElementException, IOException,
270: IllegalAttributeException {
271: Transaction t = new DefaultTransaction();
272: FeatureType type = data.getSchema("road");
273: FeatureReader reader;
274:
275: reader = data.getFeatureReader(new DefaultQuery("road",
276: Filter.EXCLUDE), t);
277: assertTrue(reader instanceof EmptyFeatureReader);
278: assertEquals(type, reader.getFeatureType());
279: assertEquals(0, count(reader));
280:
281: reader = data.getFeatureReader(new DefaultQuery("road"), t);
282: assertTrue(reader instanceof DiffFeatureReader);
283: assertEquals(type, reader.getFeatureType());
284: assertEquals(roadFeatures.length, count(reader));
285:
286: reader = data.getFeatureReader(new DefaultQuery("road",
287: rd1Filter), t);
288: //assertTrue(reader instanceof DiffFeatureReader); //currently it is being wraped by a FilteringFeatureReader
289: assertEquals(type, reader.getFeatureType());
290: assertEquals(1, count(reader));
291:
292: TransactionStateDiff state = (TransactionStateDiff) t
293: .getState(data);
294: FeatureWriter writer = state.writer("road", Filter.INCLUDE);
295: Feature feature;
296:
297: while (writer.hasNext()) {
298: feature = writer.next();
299:
300: if (feature.getID().equals("road.rd1")) {
301: writer.remove();
302: }
303: }
304:
305: reader = data.getFeatureReader(new DefaultQuery("road",
306: Filter.EXCLUDE), t);
307: assertEquals(0, count(reader));
308:
309: reader = data.getFeatureReader(new DefaultQuery("road"), t);
310: assertEquals(roadFeatures.length - 1, count(reader));
311:
312: reader = data.getFeatureReader(new DefaultQuery("road",
313: rd1Filter), t);
314: assertEquals(0, count(reader));
315:
316: t.rollback();
317: reader = data.getFeatureReader(new DefaultQuery("road",
318: Filter.EXCLUDE), t);
319: assertEquals(0, count(reader));
320:
321: reader = data.getFeatureReader(new DefaultQuery("road"), t);
322: assertEquals(roadFeatures.length, count(reader));
323:
324: reader = data.getFeatureReader(new DefaultQuery("road",
325: rd1Filter), t);
326: assertEquals(1, count(reader));
327: }
328:
329: void assertCovered(Feature[] features, FeatureReader reader)
330: throws NoSuchElementException, IOException,
331: IllegalAttributeException {
332: int count = 0;
333:
334: try {
335: while (reader.hasNext()) {
336: assertTrue(contains(features, reader.next()));
337: count++;
338: }
339: } finally {
340: reader.close();
341: }
342:
343: assertEquals(features.length, count);
344: }
345:
346: /**
347: * Ensure that FeatureReader reader contains extactly the contents of array.
348: *
349: * @param reader DOCUMENT ME!
350: * @param array DOCUMENT ME!
351: *
352: * @return DOCUMENT ME!
353: *
354: * @throws NoSuchElementException DOCUMENT ME!
355: * @throws IOException DOCUMENT ME!
356: * @throws IllegalAttributeException DOCUMENT ME!
357: */
358: boolean covers(FeatureReader reader, Feature[] array)
359: throws NoSuchElementException, IOException,
360: IllegalAttributeException {
361: Feature feature;
362: int count = 0;
363:
364: try {
365: while (reader.hasNext()) {
366: feature = reader.next();
367:
368: if (!contains(array, feature)) {
369: return false;
370: }
371:
372: count++;
373: }
374: } finally {
375: reader.close();
376: }
377:
378: return count == array.length;
379: }
380:
381: boolean coversLax(FeatureReader reader, Feature[] array)
382: throws NoSuchElementException, IOException,
383: IllegalAttributeException {
384: Feature feature;
385: int count = 0;
386:
387: try {
388: while (reader.hasNext()) {
389: feature = reader.next();
390:
391: if (!containsLax(array, feature)) {
392: return false;
393: }
394:
395: count++;
396: }
397: } finally {
398: reader.close();
399: }
400:
401: return count == array.length;
402: }
403:
404: void dump(FeatureReader reader) throws NoSuchElementException,
405: IOException, IllegalAttributeException {
406: Feature feature;
407: int count = 0;
408:
409: try {
410: while (reader.hasNext()) {
411: feature = reader.next();
412: System.out.println(count + " feature:" + feature);
413: count++;
414: }
415: } finally {
416: reader.close();
417: }
418: }
419:
420: void dump(Object[] array) {
421: for (int i = 0; i < array.length; i++) {
422: System.out.println(i + " feature:" + array[i]);
423: }
424: }
425:
426: // Feature Source Testing
427: public void testGetFeatureSourceRoad() throws IOException {
428: FeatureSource road = data.getFeatureSource("road");
429:
430: assertSame(roadType, road.getSchema());
431: assertSame(data, road.getDataStore());
432: assertEquals(3, road.getCount(Query.ALL));
433: assertEquals(new Envelope(1, 5, 0, 4), road
434: .getBounds(Query.ALL));
435:
436: FeatureCollection all = road.getFeatures();
437: assertEquals(3, all.size());
438: assertEquals(roadBounds, all.getBounds());
439:
440: FeatureCollection expected = DataUtilities
441: .collection(roadFeatures);
442:
443: assertCovers("all", expected, all);
444: assertEquals(roadBounds, all.getBounds());
445:
446: FeatureCollection some = road.getFeatures(rd12Filter);
447: assertEquals(2, some.size());
448: assertEquals(rd12Bounds, some.getBounds());
449: assertEquals(some.getSchema(), road.getSchema());
450:
451: DefaultQuery query = new DefaultQuery(road.getSchema()
452: .getTypeName(), rd12Filter, new String[] { "name" });
453:
454: FeatureCollection half = road.getFeatures(query);
455: assertEquals(2, half.size());
456: assertEquals(1, half.getSchema().getAttributeCount());
457:
458: FeatureIterator reader = half.features();
459: FeatureType type = half.getSchema();
460: reader.close();
461:
462: FeatureType actual = half.getSchema();
463: String name = type.getTypeName();
464: assertEquals(name, actual.getTypeName());
465: assertEquals(type.getNamespace(), actual.getNamespace());
466: assertEquals(type.getAttributeCount(), actual
467: .getAttributeCount());
468:
469: for (int i = 0; i < type.getAttributeCount(); i++) {
470: assertEquals(type.getAttributeType(i), actual
471: .getAttributeType(i));
472: }
473:
474: assertNull(type.getDefaultGeometry());
475: assertEquals(type.getDefaultGeometry(), actual
476: .getDefaultGeometry());
477: assertEquals(type, actual);
478:
479: Envelope b = half.getBounds();
480: assertEquals(new Envelope(1, 5, 0, 4), b);
481: }
482:
483: }
|