0001: /*
0002: * GeoTools - OpenSource mapping toolkit
0003: * http://geotools.org
0004: * (C) 2003-2006, Geotools Project Managment Committee (PMC)
0005: *
0006: * This library is free software; you can redistribute it and/or
0007: * modify it under the terms of the GNU Lesser General Public
0008: * License as published by the Free Software Foundation; either
0009: * version 2.1 of the License, or (at your option) any later version.
0010: *
0011: * This library is distributed in the hope that it will be useful,
0012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * Lesser General Public License for more details.
0015: */
0016: package org.geotools.data.feature.memory;
0017:
0018: import java.io.IOException;
0019: import java.net.URI;
0020: import java.util.ArrayList;
0021: import java.util.Collections;
0022: import java.util.List;
0023: import java.util.NoSuchElementException;
0024:
0025: import org.geotools.data.DataStore;
0026: import org.geotools.data.DataTestCase;
0027: import org.geotools.data.DataUtilities;
0028: import org.geotools.data.DefaultQuery;
0029: import org.geotools.data.DefaultTransaction;
0030: import org.geotools.data.DiffFeatureReader;
0031: import org.geotools.data.EmptyFeatureReader;
0032: import org.geotools.data.EmptyFeatureWriter;
0033: import org.geotools.data.FeatureEvent;
0034: import org.geotools.data.FeatureListener;
0035: import org.geotools.data.FeatureLock;
0036: import org.geotools.data.FeatureLockFactory;
0037: import org.geotools.data.FeatureLocking;
0038: import org.geotools.data.FeatureReader;
0039: import org.geotools.data.FeatureSource;
0040: import org.geotools.data.FeatureStore;
0041: import org.geotools.data.FeatureWriter;
0042: import org.geotools.data.FilteringFeatureReader;
0043: import org.geotools.data.FilteringFeatureWriter;
0044: import org.geotools.data.InProcessLockingManager;
0045: import org.geotools.data.Query;
0046: import org.geotools.data.Transaction;
0047: import org.geotools.data.TransactionStateDiff;
0048: import org.geotools.factory.CommonFactoryFinder;
0049: import org.geotools.feature.AttributeType;
0050: import org.geotools.feature.Feature;
0051: import org.geotools.feature.FeatureCollection;
0052: import org.geotools.feature.FeatureIterator;
0053: import org.geotools.feature.FeatureType;
0054: import org.geotools.feature.IllegalAttributeException;
0055: import org.geotools.feature.SimpleFeature;
0056: import org.opengis.filter.Filter;
0057: import org.opengis.filter.FilterFactory;
0058: import org.opengis.filter.Id;
0059:
0060: import com.vividsolutions.jts.geom.Coordinate;
0061: import com.vividsolutions.jts.geom.Envelope;
0062: import com.vividsolutions.jts.geom.Geometry;
0063: import com.vividsolutions.jts.geom.GeometryFactory;
0064: import com.vividsolutions.jts.geom.MultiLineString;
0065:
0066: /**
0067: * DOCUMENT ME!
0068: *
0069: * @author Jody Garnett, Refractions Research
0070: * @source $URL:
0071: * http://svn.geotools.org/geotools/trunk/gt/modules/library/main/src/test/java/org/geotools/data/memory/MemoryDataAccessTest.java $
0072: */
0073: public class MemoryDataAccess_GTAPI_Test extends DataTestCase {
0074: MemoryDataAccess data;
0075:
0076: /**
0077: * Constructor for MemoryDataAccessTest.
0078: *
0079: * @param arg0
0080: */
0081: public MemoryDataAccess_GTAPI_Test(String arg0) {
0082: super (arg0);
0083: }
0084:
0085: /*
0086: * @see TestCase#setUp()
0087: */
0088: protected void setUp() throws Exception {
0089: super .setUp();
0090: data = new MemoryDataAccess();
0091: data.addFeatures(roadFeatures);
0092: data.addFeatures(riverFeatures);
0093: }
0094:
0095: /*
0096: * @see TestCase#tearDown()
0097: */
0098: protected void tearDown() throws Exception {
0099: data = null;
0100: super .tearDown();
0101: }
0102:
0103: public void testFixture() throws Exception {
0104: FeatureType type = DataUtilities.createType(
0105: "namespace.typename",
0106: "name:String,id:0,geom:MultiLineString");
0107: assertEquals("namespace", new URI("namespace"), type
0108: .getNamespace());
0109: assertEquals("typename", "typename", type.getTypeName());
0110: assertEquals("attributes", 3, type.getAttributeCount());
0111:
0112: AttributeType[] a = type.getAttributeTypes();
0113: assertEquals("a1", "name", a[0].getName());
0114: assertEquals("a1", String.class, a[0].getType());
0115:
0116: assertEquals("a2", "id", a[1].getName());
0117: assertEquals("a2", Integer.class, a[1].getType());
0118:
0119: assertEquals("a3", "geom", a[2].getName());
0120: assertEquals("a3", MultiLineString.class, a[2].getType());
0121: }
0122:
0123: public void testMemoryDataAccess() throws Exception {
0124: DataStore store = new MemoryDataAccess();
0125: }
0126:
0127: /*
0128: * Test for void MemoryDataAccess(FeatureCollection)
0129: */
0130: public void testMemoryDataAccessFeatureCollection() {
0131: DataStore store = new MemoryDataAccess(DataUtilities
0132: .collection(roadFeatures));
0133: }
0134:
0135: /*
0136: * Test for void MemoryDataAccess(FeatureReader)
0137: */
0138: public void testMemoryDataAccessFeatureArray() throws IOException {
0139: DataStore store = new MemoryDataAccess(roadFeatures);
0140: }
0141:
0142: /*
0143: * Test for void MemoryDataAccess(FeatureReader)
0144: */
0145: public void testMemoryDataAccessFeatureReader() throws Exception {
0146: FeatureReader reader = DataUtilities.reader(roadFeatures);
0147: DataStore store = new MemoryDataAccess(reader);
0148: }
0149:
0150: public void testGetFeatureTypes() {
0151: String[] names = data.getTypeNames();
0152: assertEquals(2, names.length);
0153: assertTrue(contains(names, "road"));
0154: assertTrue(contains(names, "river"));
0155: }
0156:
0157: boolean contains(Object[] array, Object expected) {
0158: if ((array == null) || (array.length == 0)) {
0159: return false;
0160: }
0161:
0162: for (int i = 0; i < array.length; i++) {
0163: if (array[i].equals(expected)) {
0164: return true;
0165: }
0166: }
0167:
0168: return false;
0169: }
0170:
0171: /**
0172: * Like contain but based on match rather than equals
0173: *
0174: * @param array
0175: * DOCUMENT ME!
0176: * @param expected
0177: * DOCUMENT ME!
0178: * @return DOCUMENT ME!
0179: */
0180: boolean containsLax(Feature[] array, Feature expected) {
0181: if ((array == null) || (array.length == 0)) {
0182: return false;
0183: }
0184:
0185: FeatureType type = expected.getFeatureType();
0186:
0187: for (int i = 0; i < array.length; i++) {
0188: if (match(array[i], expected)) {
0189: return true;
0190: }
0191: }
0192:
0193: return false;
0194: }
0195:
0196: /**
0197: * Compare based on attributes not getID allows comparison of Diff contents
0198: *
0199: * @param expected
0200: * DOCUMENT ME!
0201: * @param actual
0202: * DOCUMENT ME!
0203: * @return DOCUMENT ME!
0204: */
0205: boolean match(Feature expected, Feature actual) {
0206: FeatureType type = expected.getFeatureType();
0207:
0208: for (int i = 0; i < type.getAttributeCount(); i++) {
0209: Object av = actual.getAttribute(i);
0210: Object ev = expected.getAttribute(i);
0211:
0212: if ((av == null) && (ev != null)) {
0213: return false;
0214: } else if ((ev == null) && (av != null)) {
0215: return false;
0216: } else if (av instanceof Geometry && ev instanceof Geometry) {
0217: Geometry ag = (Geometry) av;
0218: Geometry eg = (Geometry) ev;
0219:
0220: if (!ag.equals(eg)) {
0221: return false;
0222: }
0223: } else if (!av.equals(ev)) {
0224: return false;
0225: }
0226: }
0227:
0228: return true;
0229: }
0230:
0231: public void testGetSchema() throws IOException {
0232: assertSame(roadType, data.getSchema("road"));
0233: assertSame(riverType, data.getSchema("river"));
0234: }
0235:
0236: void assertCovers(String msg, FeatureCollection c1,
0237: FeatureCollection c2) {
0238: if (c1 == c2) {
0239: return;
0240: }
0241:
0242: assertNotNull(msg, c1);
0243: assertNotNull(msg, c2);
0244: assertEquals(msg + " size", c1.size(), c2.size());
0245:
0246: Feature f;
0247:
0248: for (FeatureIterator i = c1.features(); i.hasNext();) {
0249: f = i.next();
0250: assertTrue(msg + " " + f.getID(), c2.contains(f));
0251: }
0252: }
0253:
0254: public void testGetFeatureReader() throws IOException,
0255: IllegalAttributeException {
0256: FeatureReader reader = data.getFeatureReader("road");
0257: assertCovered(roadFeatures, reader);
0258: assertEquals(false, reader.hasNext());
0259: }
0260:
0261: public void testGetFeatureReaderMutability() throws IOException,
0262: IllegalAttributeException {
0263: FeatureReader reader = data.getFeatureReader("road");
0264: Feature feature;
0265:
0266: while (reader.hasNext()) {
0267: feature = (Feature) reader.next();
0268: feature.setAttribute("name", null);
0269: }
0270:
0271: reader.close();
0272:
0273: reader = data.getFeatureReader("road");
0274:
0275: while (reader.hasNext()) {
0276: feature = (Feature) reader.next();
0277: assertNotNull(feature.getAttribute("name"));
0278: }
0279:
0280: reader.close();
0281:
0282: try {
0283: reader.next();
0284: fail("next should fail with an IOException");
0285: } catch (IOException expected) {
0286: }
0287: }
0288:
0289: public void testGetFeatureReaderConcurancy()
0290: throws NoSuchElementException, IOException,
0291: IllegalAttributeException {
0292: FeatureReader reader1 = data.getFeatureReader("road");
0293: FeatureReader reader2 = data.getFeatureReader("road");
0294: FeatureReader reader3 = data.getFeatureReader("river");
0295:
0296: while (reader1.hasNext() || reader2.hasNext()
0297: || reader3.hasNext()) {
0298: assertTrue(contains(roadFeatures, reader1.next()));
0299: assertTrue(contains(roadFeatures, reader2.next()));
0300:
0301: if (reader3.hasNext()) {
0302: assertTrue(contains(riverFeatures, reader3.next()));
0303: }
0304: }
0305:
0306: try {
0307: reader1.next();
0308: fail("next should fail with an IOException");
0309: } catch (IOException expected) {
0310: }
0311:
0312: try {
0313: reader2.next();
0314: fail("next should fail with an IOException");
0315: } catch (IOException expected) {
0316: }
0317:
0318: try {
0319: reader3.next();
0320: fail("next should fail with an IOException");
0321: } catch (IOException expected) {
0322: }
0323:
0324: reader1.close();
0325: reader2.close();
0326: reader3.close();
0327: }
0328:
0329: public void testGetFeatureReaderFilterAutoCommit()
0330: throws NoSuchElementException, IOException,
0331: IllegalAttributeException {
0332: FeatureType type = data.getSchema("road");
0333: FeatureReader reader;
0334:
0335: reader = data.getFeatureReader(new DefaultQuery("road"),
0336: Transaction.AUTO_COMMIT);
0337: assertFalse(reader instanceof FilteringFeatureReader);
0338: assertEquals(type, reader.getFeatureType());
0339: assertEquals(roadFeatures.length, count(reader));
0340:
0341: reader = data.getFeatureReader(new DefaultQuery("road",
0342: Filter.EXCLUDE), Transaction.AUTO_COMMIT);
0343: assertTrue(reader instanceof EmptyFeatureReader);
0344:
0345: assertEquals(type, reader.getFeatureType());
0346: assertEquals(0, count(reader));
0347:
0348: reader = data.getFeatureReader(new DefaultQuery("road",
0349: rd1Filter), Transaction.AUTO_COMMIT);
0350: assertTrue(reader instanceof FilteringFeatureReader);
0351: assertEquals(type, reader.getFeatureType());
0352: assertEquals(1, count(reader));
0353: }
0354:
0355: public void testGetFeatureReaderFilterTransaction()
0356: throws NoSuchElementException, IOException,
0357: IllegalAttributeException {
0358: Transaction t = new DefaultTransaction();
0359: FeatureType type = data.getSchema("road");
0360: FeatureReader reader;
0361:
0362: reader = data.getFeatureReader(new DefaultQuery("road",
0363: Filter.EXCLUDE), t);
0364: assertTrue(reader instanceof EmptyFeatureReader);
0365: assertEquals(type, reader.getFeatureType());
0366: assertEquals(0, count(reader));
0367:
0368: reader = data.getFeatureReader(new DefaultQuery("road"), t);
0369: assertTrue(reader instanceof DiffFeatureReader);
0370: assertEquals(type, reader.getFeatureType());
0371: assertEquals(roadFeatures.length, count(reader));
0372:
0373: reader = data.getFeatureReader(new DefaultQuery("road",
0374: rd1Filter), t);
0375: // assertTrue(reader instanceof DiffFeatureReader);//Currently wrapped
0376: // by a filtering
0377: // feature reader
0378: assertEquals(type, reader.getFeatureType());
0379: assertEquals(1, count(reader));
0380:
0381: TransactionStateDiff state = (TransactionStateDiff) t
0382: .getState(data);
0383: FeatureWriter writer = state.writer("road", Filter.INCLUDE);
0384: Feature feature;
0385:
0386: while (writer.hasNext()) {
0387: feature = writer.next();
0388:
0389: if (feature.getID().equals("road.rd1")) {
0390: writer.remove();
0391: }
0392: }
0393:
0394: reader = data.getFeatureReader(new DefaultQuery("road",
0395: Filter.EXCLUDE), t);
0396: assertEquals(0, count(reader));
0397:
0398: reader = data.getFeatureReader(new DefaultQuery("road"), t);
0399: assertEquals(roadFeatures.length - 1, count(reader));
0400:
0401: reader = data.getFeatureReader(new DefaultQuery("road",
0402: rd1Filter), t);
0403: assertEquals(0, count(reader));
0404:
0405: t.rollback();
0406: reader = data.getFeatureReader(new DefaultQuery("road",
0407: Filter.EXCLUDE), t);
0408: assertEquals(0, count(reader));
0409:
0410: reader = data.getFeatureReader(new DefaultQuery("road"), t);
0411: assertEquals(roadFeatures.length, count(reader));
0412:
0413: reader = data.getFeatureReader(new DefaultQuery("road",
0414: rd1Filter), t);
0415: assertEquals(1, count(reader));
0416:
0417: t.close();
0418: }
0419:
0420: void assertCovered(Feature[] features, FeatureReader reader)
0421: throws NoSuchElementException, IOException,
0422: IllegalAttributeException {
0423: int count = 0;
0424:
0425: try {
0426: while (reader.hasNext()) {
0427: assertTrue(contains(features, reader.next()));
0428: count++;
0429: }
0430: } finally {
0431: reader.close();
0432: }
0433:
0434: assertEquals(features.length, count);
0435: }
0436:
0437: /**
0438: * Ensure that FeatureReader reader contains extactly the contents of array.
0439: *
0440: * @param reader
0441: * DOCUMENT ME!
0442: * @param array
0443: * DOCUMENT ME!
0444: * @return DOCUMENT ME!
0445: * @throws NoSuchElementException
0446: * DOCUMENT ME!
0447: * @throws IOException
0448: * DOCUMENT ME!
0449: * @throws IllegalAttributeException
0450: * DOCUMENT ME!
0451: */
0452: boolean covers(FeatureReader reader, Feature[] array)
0453: throws NoSuchElementException, IOException,
0454: IllegalAttributeException {
0455: Feature feature;
0456: int count = 0;
0457:
0458: try {
0459: while (reader.hasNext()) {
0460: feature = reader.next();
0461:
0462: if (!contains(array, feature)) {
0463: return false;
0464: }
0465:
0466: count++;
0467: }
0468: } finally {
0469: reader.close();
0470: }
0471:
0472: return count == array.length;
0473: }
0474:
0475: boolean covers(FeatureIterator reader, Feature[] array)
0476: throws NoSuchElementException, IOException,
0477: IllegalAttributeException {
0478: Feature feature;
0479: int count = 0;
0480:
0481: try {
0482: while (reader.hasNext()) {
0483: feature = reader.next();
0484:
0485: if (!contains(array, feature)) {
0486: return false;
0487: }
0488:
0489: count++;
0490: }
0491: } finally {
0492: reader.close();
0493: }
0494:
0495: return count == array.length;
0496: }
0497:
0498: boolean coversLax(FeatureReader reader, Feature[] array)
0499: throws NoSuchElementException, IOException,
0500: IllegalAttributeException {
0501: Feature feature;
0502: int count = 0;
0503:
0504: try {
0505: while (reader.hasNext()) {
0506: feature = reader.next();
0507:
0508: if (!containsLax(array, feature)) {
0509: return false;
0510: }
0511:
0512: count++;
0513: }
0514: } finally {
0515: reader.close();
0516: }
0517:
0518: return count == array.length;
0519: }
0520:
0521: boolean coversLax(FeatureIterator reader, Feature[] array)
0522: throws NoSuchElementException, IOException,
0523: IllegalAttributeException {
0524: Feature feature;
0525: int count = 0;
0526:
0527: try {
0528: while (reader.hasNext()) {
0529: feature = reader.next();
0530:
0531: if (!containsLax(array, feature)) {
0532: return false;
0533: }
0534:
0535: count++;
0536: }
0537: } finally {
0538: reader.close();
0539: }
0540:
0541: return count == array.length;
0542: }
0543:
0544: void dump(FeatureReader reader) throws NoSuchElementException,
0545: IOException, IllegalAttributeException {
0546: Feature feature;
0547: int count = 0;
0548:
0549: try {
0550: while (reader.hasNext()) {
0551: feature = reader.next();
0552: System.out.println(count + " feature:" + feature);
0553: count++;
0554: }
0555: } finally {
0556: reader.close();
0557: }
0558: }
0559:
0560: void dump(Object[] array) {
0561: for (int i = 0; i < array.length; i++) {
0562: System.out.println(i + " feature:" + array[i]);
0563: }
0564: }
0565:
0566: /*
0567: * Test for FeatureWriter getFeatureWriter(String, Filter, Transaction)
0568: */
0569: public void testGetFeatureWriter() throws NoSuchElementException,
0570: IOException, IllegalAttributeException {
0571: FeatureWriter writer = data.getFeatureWriter("road",
0572: Transaction.AUTO_COMMIT);
0573: assertEquals(roadFeatures.length, count(writer));
0574:
0575: try {
0576: writer.hasNext();
0577: fail("Should not be able to use a closed writer");
0578: } catch (IOException expected) {
0579: }
0580:
0581: try {
0582: writer.next();
0583: fail("Should not be able to use a closed writer");
0584: } catch (IOException expected) {
0585: }
0586: }
0587:
0588: public void testGetFeatureWriterRemove() throws IOException,
0589: IllegalAttributeException {
0590: FeatureWriter writer = data.getFeatureWriter("road",
0591: Transaction.AUTO_COMMIT);
0592: Feature feature;
0593:
0594: while (writer.hasNext()) {
0595: feature = writer.next();
0596:
0597: if (feature.getID().equals("road.rd1")) {
0598: writer.remove();
0599: }
0600: }
0601:
0602: assertEquals(roadFeatures.length - 1, data.features("road")
0603: .size());
0604: }
0605:
0606: public void testGetFeaturesWriterAdd() throws IOException,
0607: IllegalAttributeException {
0608: FeatureWriter writer = data.getFeatureWriter("road",
0609: Transaction.AUTO_COMMIT);
0610: SimpleFeature feature;
0611:
0612: while (writer.hasNext()) {
0613: feature = (SimpleFeature) writer.next();
0614: }
0615:
0616: assertFalse(writer.hasNext());
0617: feature = (SimpleFeature) writer.next();
0618: feature.setAttributes(newRoad.getAttributes(null));
0619: writer.write();
0620: assertFalse(writer.hasNext());
0621: assertEquals(roadFeatures.length + 1, data.features("road")
0622: .size());
0623: }
0624:
0625: public void testGetFeaturesWriterModify() throws IOException,
0626: IllegalAttributeException {
0627: FeatureWriter writer = data.getFeatureWriter("road",
0628: Transaction.AUTO_COMMIT);
0629: Feature feature;
0630:
0631: while (writer.hasNext()) {
0632: feature = writer.next();
0633:
0634: if (feature.getID().equals("road.rd1")) {
0635: feature.setAttribute("name", "changed");
0636: writer.write();
0637: }
0638: }
0639:
0640: org.opengis.feature.simple.SimpleFeature f;
0641: f = (org.opengis.feature.simple.SimpleFeature) data.features(
0642: "road").get("road.rd1");
0643: assertEquals("changed", f.getValue("name"));
0644: }
0645:
0646: public void testGetFeatureWriterTypeNameTransaction()
0647: throws NoSuchElementException, IOException,
0648: IllegalAttributeException {
0649: FeatureWriter writer;
0650:
0651: writer = data.getFeatureWriter("road", Transaction.AUTO_COMMIT);
0652: assertEquals(roadFeatures.length, count(writer));
0653: writer.close();
0654: }
0655:
0656: public void testGetFeatureWriterAppendTypeNameTransaction()
0657: throws Exception {
0658: FeatureWriter writer;
0659:
0660: writer = data.getFeatureWriterAppend("road",
0661: Transaction.AUTO_COMMIT);
0662: assertEquals(0, count(writer));
0663: writer.close();
0664: }
0665:
0666: /*
0667: * Test for FeatureWriter getFeatureWriter(String, boolean, Transaction)
0668: */
0669: public void testGetFeatureWriterFilter()
0670: throws NoSuchElementException, IOException,
0671: IllegalAttributeException {
0672: FeatureWriter writer;
0673:
0674: writer = data.getFeatureWriter("road", Filter.EXCLUDE,
0675: Transaction.AUTO_COMMIT);
0676: assertTrue(writer instanceof EmptyFeatureWriter);
0677: assertEquals(0, count(writer));
0678:
0679: writer = data.getFeatureWriter("road", Filter.INCLUDE,
0680: Transaction.AUTO_COMMIT);
0681: assertFalse(writer instanceof FilteringFeatureWriter);
0682: assertEquals(roadFeatures.length, count(writer));
0683:
0684: writer = data.getFeatureWriter("road", rd1Filter,
0685: Transaction.AUTO_COMMIT);
0686: assertTrue(writer instanceof FilteringFeatureWriter);
0687: assertEquals(1, count(writer));
0688: }
0689:
0690: /**
0691: * Test two transactions one removing feature, and one adding a feature.
0692: *
0693: * @throws Exception
0694: * DOCUMENT ME!
0695: */
0696: public void testGetFeatureWriterTransaction() throws Exception {
0697: Transaction t1 = new DefaultTransaction();
0698: Transaction t2 = new DefaultTransaction();
0699: FeatureWriter writer1 = data.getFeatureWriter("road",
0700: rd1Filter, t1);
0701: FeatureWriter writer2 = data.getFeatureWriterAppend("road", t2);
0702:
0703: FeatureReader reader;
0704: SimpleFeature feature;
0705: SimpleFeature[] ORIGIONAL = roadFeatures;
0706: Feature[] REMOVE = new Feature[ORIGIONAL.length - 1];
0707: Feature[] ADD = new Feature[ORIGIONAL.length + 1];
0708: Feature[] FINAL = new Feature[ORIGIONAL.length];
0709: int i;
0710: int index;
0711: index = 0;
0712:
0713: for (i = 0; i < ORIGIONAL.length; i++) {
0714: feature = ORIGIONAL[i];
0715:
0716: if (!feature.getID().equals("road.rd1")) {
0717: REMOVE[index++] = feature;
0718: }
0719: }
0720:
0721: for (i = 0; i < ORIGIONAL.length; i++) {
0722: ADD[i] = ORIGIONAL[i];
0723: }
0724:
0725: ADD[i] = newRoad;
0726:
0727: for (i = 0; i < REMOVE.length; i++) {
0728: FINAL[i] = REMOVE[i];
0729: }
0730:
0731: FINAL[i] = newRoad;
0732:
0733: // start of with ORIGINAL
0734: reader = data.getFeatureReader(new DefaultQuery("road"),
0735: Transaction.AUTO_COMMIT);
0736: assertTrue(covers(reader, ORIGIONAL));
0737:
0738: // writer 1 removes road.rd1 on t1
0739: // -------------------------------
0740: // - tests transaction independence from DataStore
0741: while (writer1.hasNext()) {
0742: feature = (SimpleFeature) writer1.next();
0743: assertEquals("road.rd1", feature.getID());
0744: writer1.remove();
0745: }
0746:
0747: // still have ORIGIONAL and t1 has REMOVE
0748: reader = data.getFeatureReader(new DefaultQuery("road"),
0749: Transaction.AUTO_COMMIT);
0750: assertTrue(covers(reader, ORIGIONAL));
0751: reader = data.getFeatureReader(new DefaultQuery("road"), t1);
0752: assertTrue(covers(reader, REMOVE));
0753:
0754: // close writer1
0755: // --------------
0756: // ensure that modification is left up to transaction commmit
0757: writer1.close();
0758:
0759: // We still have ORIGIONAL and t1 has REMOVE
0760: reader = data.getFeatureReader(new DefaultQuery("road"),
0761: Transaction.AUTO_COMMIT);
0762: assertTrue(covers(reader, ORIGIONAL));
0763: reader = data.getFeatureReader(new DefaultQuery("road"), t1);
0764: assertTrue(covers(reader, REMOVE));
0765:
0766: // writer 2 adds road.rd4 on t2
0767: // ----------------------------
0768: // - tests transaction independence from each other
0769: feature = (SimpleFeature) writer2.next();
0770: feature.setAttributes(newRoad.getAttributes(null));
0771: writer2.write();
0772:
0773: // We still have ORIGIONAL and t2 has ADD
0774: reader = data.getFeatureReader(new DefaultQuery("road"),
0775: Transaction.AUTO_COMMIT);
0776: assertTrue(covers(reader, ORIGIONAL));
0777: reader = data.getFeatureReader(new DefaultQuery("road"), t2);
0778: assertTrue(coversLax(reader, ADD));
0779:
0780: // close writer2
0781: // -------------
0782: // ensure that modification is left up to transaction commmit
0783: writer2.close();
0784:
0785: // Still have ORIGIONAL and t2 has ADD
0786: reader = data.getFeatureReader(new DefaultQuery("road"),
0787: Transaction.AUTO_COMMIT);
0788: assertTrue(covers(reader, ORIGIONAL));
0789: reader = data.getFeatureReader(new DefaultQuery("road"), t2);
0790: assertTrue(coversLax(reader, ADD));
0791:
0792: // commit t1
0793: // ---------
0794: // -ensure that delayed writing of transactions takes place
0795: //
0796: t1.commit();
0797:
0798: // We now have REMOVE, as does t1 (which has not additional diffs)
0799: // t2 will have FINAL
0800: reader = data.getFeatureReader(new DefaultQuery("road"),
0801: Transaction.AUTO_COMMIT);
0802: assertTrue(covers(reader, REMOVE));
0803: reader = data.getFeatureReader(new DefaultQuery("road"), t1);
0804: assertTrue(covers(reader, REMOVE));
0805: reader = data.getFeatureReader(new DefaultQuery("road"), t2);
0806: assertTrue(coversLax(reader, FINAL));
0807:
0808: // commit t2
0809: // ---------
0810: // -ensure that everyone is FINAL at the end of the day
0811: t2.commit();
0812:
0813: // We now have Number( remove one and add one)
0814: reader = data.getFeatureReader(new DefaultQuery("road"),
0815: Transaction.AUTO_COMMIT);
0816: reader = data.getFeatureReader(new DefaultQuery("road"),
0817: Transaction.AUTO_COMMIT);
0818: assertTrue(coversLax(reader, FINAL));
0819: reader = data.getFeatureReader(new DefaultQuery("road"), t1);
0820: assertTrue(coversLax(reader, FINAL));
0821: reader = data.getFeatureReader(new DefaultQuery("road"), t2);
0822: assertTrue(coversLax(reader, FINAL));
0823:
0824: t1.close();
0825: t2.close();
0826: }
0827:
0828: /**
0829: * Test the transaction when multiple edits occur using a transaction and a
0830: * fid filter.
0831: */
0832: public void testModifyInTransactionFidFilter() throws Exception {
0833: Transaction t1 = new DefaultTransaction();
0834:
0835: GeometryFactory fac = new GeometryFactory();
0836:
0837: FeatureWriter writer1 = data.getFeatureWriter("road",
0838: rd1Filter, t1);
0839: writer1.next().setDefaultGeometry(
0840: fac.createLineString(new Coordinate[] {
0841: new Coordinate(0, 0), new Coordinate(0, 1) }));
0842: writer1.write();
0843:
0844: writer1.close();
0845:
0846: FeatureReader reader = data.getFeatureReader(new DefaultQuery(
0847: "road", rd1Filter), t1);
0848: Geometry geom1 = reader.next().getDefaultGeometry();
0849: reader.close();
0850: assertEquals(new Coordinate(0, 0), geom1.getCoordinates()[0]);
0851: assertEquals(new Coordinate(0, 1), geom1.getCoordinates()[1]);
0852:
0853: writer1 = data.getFeatureWriter("road", rd1Filter, t1);
0854: writer1.next()
0855: .setDefaultGeometry(
0856: fac.createLineString(new Coordinate[] {
0857: new Coordinate(10, 0),
0858: new Coordinate(10, 1) }));
0859: writer1.write();
0860: writer1.close();
0861:
0862: reader = data.getFeatureReader(new DefaultQuery("road",
0863: rd1Filter), t1);
0864: geom1 = reader.next().getDefaultGeometry();
0865: reader.close();
0866: assertEquals(new Coordinate(10, 0), geom1.getCoordinates()[0]);
0867: assertEquals(new Coordinate(10, 1), geom1.getCoordinates()[1]);
0868:
0869: FeatureWriter writer = data.getFeatureWriterAppend("road", t1);
0870: Feature feature = writer.next();
0871: feature
0872: .setDefaultGeometry(fac
0873: .createLineString(new Coordinate[] {
0874: new Coordinate(20, 0),
0875: new Coordinate(20, 1) }));
0876: writer.write();
0877: writer.close();
0878: FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);
0879: Id filter = ff.id(Collections.singleton(ff.featureId(feature
0880: .getID())));
0881:
0882: reader = data.getFeatureReader(
0883: new DefaultQuery("road", filter), t1);
0884: geom1 = reader.next().getDefaultGeometry();
0885: reader.close();
0886: assertEquals(new Coordinate(20, 0), geom1.getCoordinates()[0]);
0887: assertEquals(new Coordinate(20, 1), geom1.getCoordinates()[1]);
0888:
0889: writer1 = data.getFeatureWriter("road", filter, t1);
0890: writer1.next()
0891: .setDefaultGeometry(
0892: fac.createLineString(new Coordinate[] {
0893: new Coordinate(30, 0),
0894: new Coordinate(30, 1) }));
0895: writer1.write();
0896: writer1.close();
0897:
0898: reader = data.getFeatureReader(
0899: new DefaultQuery("road", filter), t1);
0900: geom1 = reader.next().getDefaultGeometry();
0901: reader.close();
0902: assertEquals(new Coordinate(30, 0), geom1.getCoordinates()[0]);
0903: assertEquals(new Coordinate(30, 1), geom1.getCoordinates()[1]);
0904:
0905: t1.close();
0906: }
0907:
0908: // Feature Source Testing
0909: public void testGetFeatureSourceRoad() throws IOException {
0910: FeatureSource road = data.getFeatureSource("road");
0911:
0912: assertSame(roadType, road.getSchema());
0913: assertSame(data, road.getDataStore());
0914: assertEquals(3, road.getCount(Query.ALL));
0915: assertEquals(new Envelope(1, 5, 0, 4), road
0916: .getBounds(Query.ALL));
0917:
0918: FeatureCollection all = road.getFeatures();
0919: assertEquals(3, all.size());
0920: assertEquals(roadBounds, all.getBounds());
0921:
0922: FeatureCollection expected = DataUtilities
0923: .collection(roadFeatures);
0924:
0925: assertCovers("all", expected, all);
0926: assertEquals(roadBounds, all.getBounds());
0927:
0928: FeatureCollection some = road.getFeatures(rd12Filter);
0929: assertEquals(2, some.size());
0930: assertEquals(rd12Bounds, some.getBounds());
0931: assertEquals(some.getSchema(), road.getSchema());
0932:
0933: DefaultQuery query = new DefaultQuery("road", rd12Filter,
0934: new String[] { "name", });
0935:
0936: FeatureCollection half = road.getFeatures(query);
0937: assertEquals(2, half.size());
0938: assertEquals(1, half.getSchema().getAttributeCount());
0939: FeatureIterator reader = half.features();
0940: FeatureType type = half.getSchema();
0941: reader.close();
0942: FeatureType actual = half.getSchema();
0943:
0944: assertEquals(type.getTypeName(), actual.getTypeName());
0945: assertEquals(type.getNamespace(), actual.getNamespace());
0946: assertEquals(type.getAttributeCount(), actual
0947: .getAttributeCount());
0948: for (int i = 0; i < type.getAttributeCount(); i++) {
0949: assertEquals(type.getAttributeType(i), actual
0950: .getAttributeType(i));
0951: }
0952: assertNull(type.getDefaultGeometry());
0953: assertEquals(type.getDefaultGeometry(), actual
0954: .getDefaultGeometry());
0955: assertEquals(type, actual);
0956: Envelope b = half.getBounds();
0957: assertEquals(new Envelope(1, 5, 0, 4), b);
0958: }
0959:
0960: public void testGetFeatureSourceRiver()
0961: throws NoSuchElementException, IOException,
0962: IllegalAttributeException {
0963: FeatureSource river = data.getFeatureSource("river");
0964:
0965: assertSame(riverType, river.getSchema());
0966: assertSame(data, river.getDataStore());
0967:
0968: FeatureCollection all = river.getFeatures();
0969: assertEquals(2, all.size());
0970: assertEquals(riverBounds, all.getBounds());
0971: assertTrue("rivers", covers(all.features(), riverFeatures));
0972:
0973: FeatureCollection expected = DataUtilities
0974: .collection(riverFeatures);
0975: assertCovers("all", expected, all);
0976: assertEquals(riverBounds, all.getBounds());
0977: }
0978:
0979: //
0980: // Feature Store Testing
0981: //
0982: public void testGetFeatureStoreModifyFeatures1() throws IOException {
0983: FeatureStore road = (FeatureStore) data
0984: .getFeatureSource("road");
0985: AttributeType name = roadType.getAttributeType("name");
0986: road.modifyFeatures(name, "changed", rd1Filter);
0987:
0988: FeatureCollection results = road.getFeatures(rd1Filter);
0989: assertEquals("changed", results.features().next().getAttribute(
0990: "name"));
0991: }
0992:
0993: public void testGetFeatureStoreModifyFeatures2() throws IOException {
0994: FeatureStore road = (FeatureStore) data
0995: .getFeatureSource("road");
0996: AttributeType name = roadType.getAttributeType("name");
0997: road.modifyFeatures(new AttributeType[] { name, },
0998: new Object[] { "changed", }, rd1Filter);
0999:
1000: FeatureCollection results = road.getFeatures(rd1Filter);
1001: assertEquals("changed", results.features().next().getAttribute(
1002: "name"));
1003: }
1004:
1005: public void testGetFeatureStoreRemoveFeatures() throws IOException {
1006: FeatureStore road = (FeatureStore) data
1007: .getFeatureSource("road");
1008:
1009: road.removeFeatures(rd1Filter);
1010: assertEquals(0, road.getFeatures(rd1Filter).size());
1011: assertEquals(roadFeatures.length - 1, road.getFeatures().size());
1012: }
1013:
1014: public void testGetFeatureStoreAddFeatures() throws IOException {
1015: FeatureReader reader = DataUtilities
1016: .reader(new Feature[] { newRoad, });
1017: FeatureStore road = (FeatureStore) data
1018: .getFeatureSource("road");
1019:
1020: road.addFeatures(DataUtilities.collection(reader));
1021: assertEquals(roadFeatures.length + 1, road.getFeatures().size());
1022: }
1023:
1024: public void testGetFeatureStoreSetFeatures() throws IOException {
1025: FeatureReader reader = DataUtilities
1026: .reader(new Feature[] { newRoad, });
1027: FeatureStore road = (FeatureStore) data
1028: .getFeatureSource("road");
1029:
1030: road.setFeatures(reader);
1031: assertEquals(1, road.getFeatures().size());
1032: }
1033:
1034: public void testGetFeatureStoreTransactionSupport()
1035: throws Exception {
1036: Transaction t1 = new DefaultTransaction();
1037: Transaction t2 = new DefaultTransaction();
1038:
1039: FeatureStore road = (FeatureStore) data
1040: .getFeatureSource("road");
1041: FeatureStore road1 = (FeatureStore) data
1042: .getFeatureSource("road");
1043: FeatureStore road2 = (FeatureStore) data
1044: .getFeatureSource("road");
1045:
1046: road1.setTransaction(t1);
1047: road2.setTransaction(t2);
1048:
1049: Feature feature;
1050: Feature[] ORIGIONAL = roadFeatures;
1051: Feature[] REMOVE = new Feature[ORIGIONAL.length - 1];
1052: Feature[] ADD = new Feature[ORIGIONAL.length + 1];
1053: Feature[] FINAL = new Feature[ORIGIONAL.length];
1054: int i;
1055: int index;
1056: index = 0;
1057:
1058: for (i = 0; i < ORIGIONAL.length; i++) {
1059: feature = ORIGIONAL[i];
1060:
1061: if (!feature.getID().equals("road.rd1")) {
1062: REMOVE[index++] = feature;
1063: }
1064: }
1065:
1066: for (i = 0; i < ORIGIONAL.length; i++) {
1067: ADD[i] = ORIGIONAL[i];
1068: }
1069:
1070: ADD[i] = newRoad;
1071:
1072: for (i = 0; i < REMOVE.length; i++) {
1073: FINAL[i] = REMOVE[i];
1074: }
1075:
1076: FINAL[i] = newRoad;
1077:
1078: // start of with ORIGINAL
1079: assertTrue(covers(road.getFeatures().features(), ORIGIONAL));
1080:
1081: // road1 removes road.rd1 on t1
1082: // -------------------------------
1083: // - tests transaction independence from DataStore
1084: road1.removeFeatures(rd1Filter);
1085:
1086: // still have ORIGIONAL and t1 has REMOVE
1087: assertTrue(covers(road.getFeatures().features(), ORIGIONAL));
1088: assertTrue(covers(road1.getFeatures().features(), REMOVE));
1089:
1090: // road2 adds road.rd4 on t2
1091: // ----------------------------
1092: // - tests transaction independence from each other
1093: FeatureReader reader = DataUtilities
1094: .reader(new Feature[] { newRoad, });
1095: road2.addFeatures(DataUtilities.collection(reader));
1096:
1097: // We still have ORIGIONAL, t1 has REMOVE, and t2 has ADD
1098: assertTrue(covers(road.getFeatures().features(), ORIGIONAL));
1099: assertTrue(covers(road1.getFeatures().features(), REMOVE));
1100: assertTrue(coversLax(road2.getFeatures().features(), ADD));
1101:
1102: // commit t1
1103: // ---------
1104: // -ensure that delayed writing of transactions takes place
1105: //
1106: t1.commit();
1107:
1108: // We now have REMOVE, as does t1 (which has not additional diffs)
1109: // t2 will have FINAL
1110: assertTrue(covers(road.getFeatures().features(), REMOVE));
1111: assertTrue(covers(road1.getFeatures().features(), REMOVE));
1112: assertTrue(coversLax(road2.getFeatures().features(), FINAL));
1113:
1114: // commit t2
1115: // ---------
1116: // -ensure that everyone is FINAL at the end of the day
1117: t2.commit();
1118:
1119: // We now have Number( remove one and add one)
1120: assertTrue(coversLax(road.getFeatures().features(), FINAL));
1121: assertTrue(coversLax(road1.getFeatures().features(), FINAL));
1122: assertTrue(coversLax(road2.getFeatures().features(), FINAL));
1123:
1124: t1.close();
1125: t2.close();
1126: }
1127:
1128: boolean isLocked(String typeName, String fid) {
1129: InProcessLockingManager lockingManager = (InProcessLockingManager) data
1130: .getLockingManager();
1131: return lockingManager.isLocked(typeName, fid);
1132: }
1133:
1134: public void testFeatureEvents() throws Exception {
1135: FeatureStore store1 = (FeatureStore) data
1136: .getFeatureSource(roadFeatures[0].getFeatureType()
1137: .getTypeName());
1138: FeatureStore store2 = (FeatureStore) data
1139: .getFeatureSource(roadFeatures[0].getFeatureType()
1140: .getTypeName());
1141: Transaction t1 = new DefaultTransaction();
1142: store1.setTransaction(t1);
1143: class Listener implements FeatureListener {
1144:
1145: String name;
1146:
1147: List events = new ArrayList();
1148:
1149: public Listener(String name) {
1150: this .name = name;
1151: }
1152:
1153: public void changed(FeatureEvent featureEvent) {
1154: this .events.add(featureEvent);
1155: }
1156:
1157: FeatureEvent getEvent(int i) {
1158: return (FeatureEvent) events.get(i);
1159: }
1160:
1161: }
1162: Listener listener1 = new Listener("one");
1163: Listener listener2 = new Listener("two");
1164:
1165: store1.addFeatureListener(listener1);
1166: store2.addFeatureListener(listener2);
1167: FilterFactory factory = CommonFactoryFinder
1168: .getFilterFactory(null);
1169:
1170: // test that only the listener listening with the current transaction
1171: // gets the event.
1172: final Feature feature = roadFeatures[0];
1173: store1.removeFeatures(factory.id(Collections.singleton(factory
1174: .featureId(feature.getID()))));
1175: assertEquals(1, listener1.events.size());
1176: assertEquals(0, listener2.events.size());
1177: FeatureEvent event = listener1.getEvent(0);
1178: assertEquals(feature.getBounds(), event.getBounds());
1179: assertEquals(FeatureEvent.FEATURES_REMOVED, event
1180: .getEventType());
1181:
1182: // test that commit only sends events to listener2.
1183: listener1.events.clear();
1184: listener2.events.clear();
1185:
1186: store1.getTransaction().commit();
1187:
1188: assertEquals(0, listener1.events.size());
1189:
1190: assertEquals(3, listener2.events.size());
1191: event = listener2.getEvent(0);
1192: assertEquals(feature.getBounds(), event.getBounds());
1193: assertEquals(FeatureEvent.FEATURES_REMOVED, event
1194: .getEventType());
1195:
1196: // test add same as modify
1197: listener1.events.clear();
1198: listener2.events.clear();
1199:
1200: store1.addFeatures(DataUtilities.collection(feature));
1201:
1202: assertEquals(1, listener1.events.size());
1203: event = listener1.getEvent(0);
1204: assertEquals(feature.getBounds(), event.getBounds());
1205: assertEquals(FeatureEvent.FEATURES_ADDED, event.getEventType());
1206: assertEquals(0, listener2.events.size());
1207:
1208: // test that rollback only sends events to listener1.
1209: listener1.events.clear();
1210: listener2.events.clear();
1211:
1212: store1.getTransaction().rollback();
1213:
1214: assertEquals(1, listener1.events.size());
1215: event = listener1.getEvent(0);
1216: assertNull(event.getBounds());
1217: assertEquals(FeatureEvent.FEATURES_CHANGED, event
1218: .getEventType());
1219:
1220: assertEquals(0, listener2.events.size());
1221:
1222: // this is how Auto_commit is supposed to work
1223: listener1.events.clear();
1224: listener2.events.clear();
1225: store2.addFeatures(DataUtilities.collection(feature));
1226:
1227: assertEquals(1, listener1.events.size());
1228: event = listener1.getEvent(0);
1229: assertEquals(feature.getBounds(), event.getBounds());
1230: assertEquals(FeatureEvent.FEATURES_ADDED, event.getEventType());
1231: assertEquals(0, listener2.events.size());
1232:
1233: t1.close();
1234: }
1235:
1236: //
1237: // FeatureLocking Testing
1238: //
1239: /*
1240: * Test for void lockFeatures()
1241: */
1242: public void testLockFeatures() throws IOException {
1243: FeatureLock lock = FeatureLockFactory.generate("test", 3600);
1244: FeatureLocking road = (FeatureLocking) data
1245: .getFeatureSource("road");
1246: road.setFeatureLock(lock);
1247:
1248: assertFalse(isLocked("road", "road.rd1"));
1249: road.lockFeatures();
1250: assertTrue(isLocked("road", "road.rd1"));
1251: }
1252:
1253: public void testUnLockFeatures() throws IOException {
1254: FeatureLock lock = FeatureLockFactory.generate("test", 3600);
1255: FeatureLocking road = (FeatureLocking) data
1256: .getFeatureSource("road");
1257: road.setFeatureLock(lock);
1258: road.lockFeatures();
1259:
1260: try {
1261: road.unLockFeatures();
1262: fail("unlock should fail due on AUTO_COMMIT");
1263: } catch (IOException expected) {
1264: }
1265: Transaction t = new DefaultTransaction();
1266: road.setTransaction(t);
1267: try {
1268: road.unLockFeatures();
1269: fail("unlock should fail due lack of authorization");
1270: } catch (IOException expected) {
1271: }
1272: t.addAuthorization(lock.getAuthorization());
1273: road.unLockFeatures();
1274: t.close();
1275: }
1276:
1277: public void testLockFeatureInteraction() throws IOException {
1278: FeatureLock lockA = FeatureLockFactory.generate("LockA", 3600);
1279: FeatureLock lockB = FeatureLockFactory.generate("LockB", 3600);
1280: Transaction t1 = new DefaultTransaction();
1281: Transaction t2 = new DefaultTransaction();
1282: FeatureLocking road1 = (FeatureLocking) data
1283: .getFeatureSource("road");
1284: FeatureLocking road2 = (FeatureLocking) data
1285: .getFeatureSource("road");
1286: road1.setTransaction(t1);
1287: road2.setTransaction(t2);
1288: road1.setFeatureLock(lockA);
1289: road2.setFeatureLock(lockB);
1290:
1291: assertFalse(isLocked("road", "road.rd1"));
1292: assertFalse(isLocked("road", "road.rd2"));
1293: assertFalse(isLocked("road", "road.rd3"));
1294:
1295: road1.lockFeatures(rd1Filter);
1296: assertTrue(isLocked("road", "road.rd1"));
1297: assertFalse(isLocked("road", "road.rd2"));
1298: assertFalse(isLocked("road", "road.rd3"));
1299:
1300: road2.lockFeatures(rd2Filter);
1301: assertTrue(isLocked("road", "road.rd1"));
1302: assertTrue(isLocked("road", "road.rd2"));
1303: assertFalse(isLocked("road", "road.rd3"));
1304:
1305: try {
1306: road1.unLockFeatures(rd1Filter);
1307: fail("need authorization");
1308: } catch (IOException expected) {
1309: }
1310: t1.addAuthorization(lockA.getAuthorization());
1311: try {
1312: road1.unLockFeatures(rd2Filter);
1313: fail("need correct authorization");
1314: } catch (IOException expected) {
1315: }
1316: road1.unLockFeatures(rd1Filter);
1317: assertFalse(isLocked("road", "road.rd1"));
1318: assertTrue(isLocked("road", "road.rd2"));
1319: assertFalse(isLocked("road", "road.rd3"));
1320:
1321: t2.addAuthorization(lockB.getAuthorization());
1322: road2.unLockFeatures(rd2Filter);
1323: assertFalse(isLocked("road", "road.rd1"));
1324: assertFalse(isLocked("road", "road.rd2"));
1325: assertFalse(isLocked("road", "road.rd3"));
1326:
1327: t1.close();
1328: t2.close();
1329: }
1330:
1331: /**
1332: * This one started to fail and I don't know why, but don't care
1333: * since MemoryDataAccess is just an excercise for feature reading
1334: * no need for locking.
1335: */
1336: public void _Pending_testGetFeatureLockingExpire() throws Exception {
1337: FeatureLock lock = FeatureLockFactory.generate("Timed", 1);
1338: FeatureLocking road = (FeatureLocking) data
1339: .getFeatureSource("road");
1340: road.setFeatureLock(lock);
1341: assertFalse(isLocked("road", "road.rd1"));
1342: road.lockFeatures(rd1Filter);
1343: assertTrue(isLocked("road", "road.rd1"));
1344: long then = System.currentTimeMillis();
1345: do {
1346: Thread.sleep(15);
1347: } while (then == System.currentTimeMillis());
1348: assertFalse(isLocked("road", "road.rd1"));
1349: }
1350: }
|