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;
0009: * version 2.1 of the License.
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;
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.Iterator;
0023: import java.util.List;
0024: import java.util.NoSuchElementException;
0025: import java.util.logging.Level;
0026: import java.util.logging.Logger;
0027:
0028: import org.geotools.factory.CommonFactoryFinder;
0029: import org.geotools.feature.AttributeType;
0030: import org.geotools.feature.Feature;
0031: import org.geotools.feature.FeatureCollection;
0032: import org.geotools.feature.FeatureIterator;
0033: import org.geotools.feature.FeatureType;
0034: import org.geotools.feature.IllegalAttributeException;
0035: import org.geotools.feature.SimpleFeature;
0036: import org.opengis.filter.Filter;
0037: import org.opengis.filter.FilterFactory;
0038: import org.opengis.filter.Id;
0039:
0040: import com.vividsolutions.jts.geom.Envelope;
0041: import com.vividsolutions.jts.geom.Geometry;
0042: import com.vividsolutions.jts.geom.MultiLineString;
0043:
0044: /**
0045: * An abstract super class for testing datastore implementations. All datastore implementations should
0046: * has a test case that extends this class.
0047: *
0048: * @author Jesse Eichar, Refractions Research
0049: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/data/AbstractDataStoreTest.java $
0050: */
0051: public abstract class AbstractDataStoreTest extends DataTestCase {
0052: /** The logger for the filter module. */
0053: private static final Logger LOGGER = org.geotools.util.logging.Logging
0054: .getLogger("org.geotools.hsql");
0055: DataStore data;
0056:
0057: public AbstractDataStoreTest(String arg0) {
0058: super (arg0);
0059: }
0060:
0061: /**
0062: * Creates a new instance of the datastore. The datastore must not have a
0063: * roads or rivers type.
0064: *
0065: *
0066: * @throws Exception
0067: */
0068: public abstract DataStore createDataStore() throws Exception;
0069:
0070: /**
0071: * This method must remove the roads and rivers types from the datastore.
0072: * It must also close all connections to the datastore if it has
0073: * connections and get rid of any temporary files.
0074: *
0075: * @param data DOCUMENT ME!
0076: *
0077: *
0078: * @throws Exception
0079: */
0080: public abstract DataStore tearDownDataStore(DataStore data)
0081: throws Exception;
0082:
0083: /*
0084: * @see TestCase#setUp()
0085: */
0086: protected void setUp() throws Exception {
0087: //We won't call the super.setUp() since this datastore doesn't work well with
0088: //lowercase names, we'll override it instead (the exact same code though, just
0089: //in lowercase...this was done so that other datastore may discover this
0090: //shortcoming if it's applicable)
0091: //
0092: dataSetUp();
0093:
0094: try {
0095: data = createDataStore();
0096: } catch (Exception e) {
0097: LOGGER.log(Level.INFO, "exception while making schema", e);
0098: }
0099:
0100: data.createSchema(roadType);
0101: data.createSchema(riverType);
0102:
0103: FeatureStore roads = ((FeatureStore) data
0104: .getFeatureSource(roadType.getTypeName()));
0105:
0106: roads.addFeatures(DataUtilities.collection(roadFeatures));
0107:
0108: FeatureStore rivers = ((FeatureStore) data
0109: .getFeatureSource(riverType.getTypeName()));
0110:
0111: rivers.addFeatures(DataUtilities.collection(riverFeatures));
0112:
0113: // Now that we have seeded the contents we need to
0114: // set up our arrays in the same order
0115: //
0116: roadFeatures = grabArray(roads.getFeatures(),
0117: roadFeatures.length);
0118: riverFeatures = grabArray(rivers.getFeatures(),
0119: riverFeatures.length);
0120: }
0121:
0122: SimpleFeature[] grabArray(FeatureCollection features, int size) {
0123: try {
0124: SimpleFeature array[] = new SimpleFeature[size];
0125: array = (SimpleFeature[]) features.toArray(array);
0126: assertNotNull(array);
0127:
0128: return array;
0129: } finally {
0130: features.purge();
0131: }
0132: }
0133:
0134: protected void tearDown() throws Exception {
0135: tearDownDataStore(data);
0136: data = null;
0137: super .tearDown();
0138: }
0139:
0140: public void testFeatureEvents() throws Exception {
0141: FeatureStore store1 = (FeatureStore) data
0142: .getFeatureSource(roadFeatures[0].getFeatureType()
0143: .getTypeName());
0144: FeatureStore store2 = (FeatureStore) data
0145: .getFeatureSource(roadFeatures[0].getFeatureType()
0146: .getTypeName());
0147: store1.setTransaction(new DefaultTransaction());
0148: class Listener implements FeatureListener {
0149: String name;
0150: List events = new ArrayList();
0151:
0152: public Listener(String name) {
0153: this .name = name;
0154: }
0155:
0156: public void changed(FeatureEvent featureEvent) {
0157: this .events.add(featureEvent);
0158: }
0159:
0160: FeatureEvent getEvent(int i) {
0161: return (FeatureEvent) events.get(i);
0162: }
0163: }
0164:
0165: Listener listener1 = new Listener("one");
0166: Listener listener2 = new Listener("two");
0167:
0168: store1.addFeatureListener(listener1);
0169: store2.addFeatureListener(listener2);
0170:
0171: FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);
0172:
0173: //test that only the listener listening with the current transaction gets the event.
0174: final Feature feature = roadFeatures[0];
0175: Id fidFilter = ff.id(Collections.singleton(ff.featureId(feature
0176: .getID())));
0177:
0178: store1.removeFeatures(fidFilter);
0179:
0180: assertEquals(1, listener1.events.size());
0181: assertEquals(0, listener2.events.size());
0182:
0183: FeatureEvent event = listener1.getEvent(0);
0184: assertEquals(feature.getBounds(), event.getBounds());
0185: assertEquals(FeatureEvent.FEATURES_REMOVED, event
0186: .getEventType());
0187:
0188: //test that commit only sends events to listener2.
0189: listener1.events.clear();
0190: listener2.events.clear();
0191:
0192: store1.getTransaction().commit();
0193:
0194: assertEquals(0, listener1.events.size());
0195: assertEquals(2, listener2.events.size());
0196:
0197: event = listener2.getEvent(0);
0198: assertEquals(feature.getBounds(), event.getBounds());
0199: assertEquals(FeatureEvent.FEATURES_REMOVED, event
0200: .getEventType());
0201:
0202: //test add same as modify
0203: listener1.events.clear();
0204: listener2.events.clear();
0205:
0206: store1.addFeatures(DataUtilities.collection(feature));
0207:
0208: assertEquals(1, listener1.events.size());
0209: event = listener1.getEvent(0);
0210: assertEquals(feature.getBounds(), event.getBounds());
0211: assertEquals(FeatureEvent.FEATURES_ADDED, event.getEventType());
0212: assertEquals(0, listener2.events.size());
0213:
0214: //test that rollback only sends events to listener1.
0215: listener1.events.clear();
0216: listener2.events.clear();
0217:
0218: store1.getTransaction().rollback();
0219:
0220: assertEquals(1, listener1.events.size());
0221: event = listener1.getEvent(0);
0222: assertNull(event.getBounds());
0223: assertEquals(FeatureEvent.FEATURES_CHANGED, event
0224: .getEventType());
0225:
0226: assertEquals(0, listener2.events.size());
0227:
0228: //// this is how Auto_commit is supposed to work
0229: // listener1.events.clear();
0230: // listener2.events.clear();
0231: // store2.addFeatures(new FeatureReader( ){
0232: //
0233: // public FeatureType getFeatureType() {
0234: // return feature.getFeatureType();
0235: // }
0236: // boolean hasNext=true;
0237: // public Feature next() throws IOException, IllegalAttributeException, NoSuchElementException {
0238: // hasNext=false;
0239: // return feature;
0240: // }
0241: //
0242: // public boolean hasNext() throws IOException {
0243: // return hasNext;
0244: // }
0245: //
0246: // public void close() throws IOException {
0247: // //do nothing.
0248: // }
0249: //
0250: // });
0251: //
0252: // assertEquals( 1, listener1.events.size() );
0253: // event=listener1.getEvent(0);
0254: // assertEquals(feature.getBounds(),event.getBounds() );
0255: // assertEquals(FeatureEvent.FEATURES_ADDED, event.getEventType() );
0256: // assertEquals( 0, listener2.events.size() );
0257: }
0258:
0259: public void testFixture() throws Exception {
0260: FeatureType type = DataUtilities.createType(
0261: "namespace.typename",
0262: "name:String,id:0,geom:MultiLineString");
0263: assertEquals("namespace", new URI("namespace"), type
0264: .getNamespace());
0265: assertEquals("typename", "typename", type.getTypeName());
0266: assertEquals("attributes", 3, type.getAttributeCount());
0267:
0268: AttributeType[] a = type.getAttributeTypes();
0269: assertEquals("a1", "name", a[0].getName());
0270: assertEquals("a1", String.class, a[0].getType());
0271:
0272: assertEquals("a2", "id", a[1].getName());
0273: assertEquals("a2", Integer.class, a[1].getType());
0274:
0275: assertEquals("a3", "geom", a[2].getName());
0276: assertEquals("a3", MultiLineString.class, a[2].getType());
0277: }
0278:
0279: public void testGetFeatureTypes() {
0280: String[] names;
0281:
0282: try {
0283: names = data.getTypeNames();
0284: assertEquals(2, names.length);
0285: assertTrue(contains(names, "ROAD"));
0286: assertTrue(contains(names, "RIVER"));
0287: } catch (IOException e) {
0288: e.printStackTrace();
0289: fail("Fail with an IOException trying to getTypeNames()");
0290: }
0291: }
0292:
0293: boolean contains(Object[] array, Object expected) {
0294: if ((array == null) || (array.length == 0)) {
0295: return false;
0296: }
0297:
0298: for (int i = 0; i < array.length; i++) {
0299: if (array[i].equals(expected)) {
0300: return true;
0301: }
0302: }
0303:
0304: return false;
0305: }
0306:
0307: /**
0308: * Checks that a given FeatureCollection contains the specified feature
0309: *
0310: * @param fc the feature collection we're going to search
0311: * @param f the feature we're looking for
0312: *
0313: * @return true if the feature is in the feature collection, false
0314: * otherwise
0315: */
0316: boolean containsFeatureCollection(FeatureCollection fc, Feature f) {
0317: if ((fc == null) || fc.isEmpty()) {
0318: return false;
0319: }
0320:
0321: return containsFeature(fc.toArray(), f);
0322: }
0323:
0324: /**
0325: * Checks that a given Feature array contains the specified feature
0326: *
0327: * @param array must be an array of features
0328: * @param expected the expected feature we're looking for
0329: *
0330: * @return true if the feature is found, false otherwise
0331: */
0332: boolean containsFeature(Object[] array, Object expected) {
0333: if ((array == null) || (array.length == 0)) {
0334: return false;
0335: }
0336:
0337: for (int i = 0; i < array.length; i++) {
0338: if (isFeatureEqual((Feature) array[i], (Feature) expected)) {
0339: return true;
0340: }
0341: }
0342:
0343: return false;
0344: }
0345:
0346: /**
0347: * This function is stolen from DefaultFeature equals method. We want to
0348: * check for equality except for featureId which we expect to be
0349: * different.
0350: *
0351: * @param feature1 the Feature to test against.
0352: * @param feature2 the Feature to test for equality.
0353: *
0354: * @return <code>true</code> if the object is equal, <code>false</code>
0355: * otherwise.
0356: */
0357: public boolean isFeatureEqual(Feature feature1, Feature feature2) {
0358: if (feature2 == null) {
0359: return false;
0360: }
0361:
0362: if (feature2 == feature1) {
0363: return true;
0364: }
0365:
0366: if (!feature2.getFeatureType()
0367: .equals(feature1.getFeatureType())) {
0368: return false;
0369: }
0370:
0371: // if (!featureId.equals(feat.getID())) {
0372: // return false;
0373: // }
0374: for (int i = 0, ii = feature1.getNumberOfAttributes(); i < ii; i++) {
0375: Object otherAtt = feature2.getAttribute(i);
0376:
0377: if (feature1.getAttribute(i) == null) {
0378: if (otherAtt != null) {
0379: return false;
0380: }
0381: } else {
0382: if (!feature1.getAttribute(i).equals(otherAtt)) {
0383: if (feature1.getAttribute(i) instanceof Geometry
0384: && otherAtt instanceof Geometry) {
0385: // we need to special case Geometry
0386: // as JTS is broken
0387: // Geometry.equals( Object ) and Geometry.equals( Geometry )
0388: // are different
0389: // (We should fold this knowledge into AttributeType...)
0390: //
0391: if (!((Geometry) feature1.getAttribute(i))
0392: .equals((Geometry) otherAtt)) {
0393: return false;
0394: }
0395: } else {
0396: return false;
0397: }
0398: }
0399: }
0400: }
0401:
0402: return true;
0403: }
0404:
0405: /**
0406: * Like contain but based on match rather than equals
0407: *
0408: * @param array DOCUMENT ME!
0409: * @param expected DOCUMENT ME!
0410: *
0411: * @return DOCUMENT ME!
0412: */
0413: boolean containsLax(Feature[] array, Feature expected) {
0414: if ((array == null) || (array.length == 0)) {
0415: return false;
0416: }
0417:
0418: FeatureType type = expected.getFeatureType();
0419:
0420: for (int i = 0; i < array.length; i++) {
0421: if (match(array[i], expected)) {
0422: return true;
0423: }
0424: }
0425:
0426: return false;
0427: }
0428:
0429: /**
0430: * Compare based on attributes not getID allows comparison of Diff contents
0431: *
0432: * @param expected DOCUMENT ME!
0433: * @param actual DOCUMENT ME!
0434: *
0435: * @return DOCUMENT ME!
0436: */
0437: boolean match(Feature expected, Feature actual) {
0438: FeatureType type = expected.getFeatureType();
0439:
0440: for (int i = 0; i < type.getAttributeCount(); i++) {
0441: Object av = actual.getAttribute(i);
0442: Object ev = expected.getAttribute(i);
0443:
0444: if ((av == null) && (ev != null)) {
0445: return false;
0446: } else if ((ev == null) && (av != null)) {
0447: return false;
0448: } else if (av instanceof Geometry && ev instanceof Geometry) {
0449: Geometry ag = (Geometry) av;
0450: Geometry eg = (Geometry) ev;
0451:
0452: if (!ag.equals(eg)) {
0453: return false;
0454: }
0455: } else if (!av.equals(ev)) {
0456: return false;
0457: }
0458: }
0459:
0460: return true;
0461: }
0462:
0463: public void testGetSchema() throws IOException {
0464: assertEquals(roadType, data.getSchema("ROAD"));
0465: assertEquals(riverType, data.getSchema("RIVER"));
0466: }
0467:
0468: void assertCovers(String msg, FeatureCollection c1,
0469: FeatureCollection c2) {
0470: if (c1 == c2) {
0471: return;
0472: }
0473:
0474: assertNotNull(msg, c1);
0475: assertNotNull(msg, c2);
0476: assertEquals(msg + " size", c1.size(), c2.size());
0477:
0478: Feature f;
0479:
0480: for (FeatureIterator i = c1.features(); i.hasNext();) {
0481: f = i.next();
0482: assertTrue(msg + " " + f.getID(),
0483: containsFeatureCollection(c2, f)); //c2.contains(f));
0484: }
0485: }
0486:
0487: public void testGetFeatureReader() throws IOException,
0488: IllegalAttributeException {
0489: Query query = new DefaultQuery(roadType.getTypeName());
0490: FeatureReader reader = data.getFeatureReader(query,
0491: Transaction.AUTO_COMMIT);
0492: assertCovered(roadFeatures, reader);
0493: assertEquals(false, reader.hasNext());
0494: }
0495:
0496: public void testGetFeatureReaderMutability() throws IOException,
0497: IllegalAttributeException {
0498: Query query = new DefaultQuery(roadType.getTypeName());
0499: FeatureReader reader = data.getFeatureReader(query,
0500: Transaction.AUTO_COMMIT);
0501: Feature feature;
0502:
0503: while (reader.hasNext()) {
0504: feature = (Feature) reader.next();
0505: feature.setAttribute("NAME", null);
0506: }
0507:
0508: reader.close();
0509:
0510: reader = data.getFeatureReader(query, Transaction.AUTO_COMMIT);
0511:
0512: while (reader.hasNext()) {
0513: feature = (Feature) reader.next();
0514: assertNotNull(feature.getAttribute("NAME"));
0515: }
0516:
0517: reader.close();
0518:
0519: try {
0520: reader.next();
0521: fail("next should fail with an IOException or NoSuchElementException");
0522: } catch (IOException expected) {
0523: } catch (NoSuchElementException expected) {
0524: }
0525: }
0526:
0527: public void testGetFeatureReaderConcurancy()
0528: throws NoSuchElementException, IOException,
0529: IllegalAttributeException {
0530: Query query = new DefaultQuery(roadType.getTypeName());
0531: FeatureReader reader1 = data.getFeatureReader(query,
0532: Transaction.AUTO_COMMIT);
0533: FeatureReader reader2 = data.getFeatureReader(query,
0534: Transaction.AUTO_COMMIT);
0535: query = new DefaultQuery(riverType.getTypeName());
0536:
0537: FeatureReader reader3 = data.getFeatureReader(query,
0538: Transaction.AUTO_COMMIT);
0539:
0540: while (reader1.hasNext() || reader2.hasNext()
0541: || reader3.hasNext()) {
0542: assertTrue(containsFeature(roadFeatures, reader1.next()));
0543: assertTrue(containsFeature(roadFeatures, reader2.next()));
0544:
0545: if (reader3.hasNext()) {
0546: assertTrue(containsFeature(riverFeatures, reader3
0547: .next()));
0548: }
0549: }
0550:
0551: try {
0552: reader1.next();
0553: fail("next should fail with an IOException or NoSuchElementException");
0554: } catch (IOException expected) {
0555: } catch (NoSuchElementException expected) {
0556: }
0557:
0558: try {
0559: reader2.next();
0560: fail("next should fail with an IOException or NoSuchElementException");
0561: } catch (IOException expected) {
0562: } catch (NoSuchElementException expected) {
0563: }
0564:
0565: try {
0566: reader3.next();
0567: fail("next should fail with an IOException or NoSuchElementException");
0568: } catch (IOException expected) {
0569: } catch (NoSuchElementException expected) {
0570: }
0571:
0572: reader1.close();
0573: reader2.close();
0574: reader3.close();
0575: }
0576:
0577: public void testGetFeatureReaderFilterAutoCommit()
0578: throws NoSuchElementException, IOException,
0579: IllegalAttributeException {
0580: FeatureType type = data.getSchema("ROAD");
0581: FeatureReader reader;
0582:
0583: reader = data.getFeatureReader(new DefaultQuery("ROAD"),
0584: Transaction.AUTO_COMMIT);
0585: assertFalse(reader instanceof FilteringFeatureReader);
0586: assertEquals(type, reader.getFeatureType());
0587: assertEquals(roadFeatures.length, count(reader));
0588:
0589: reader = data.getFeatureReader(new DefaultQuery("ROAD",
0590: Filter.EXCLUDE), Transaction.AUTO_COMMIT);
0591:
0592: //TODO: This assert sucks since it EXPECTS an emptyFeatureWriter...well, we got A writer...
0593: //and it was empty; that's good enough dammit! Even more, the very next assert fails since
0594: //an emptyFeatureReader looks to not contain the featureType anyways!
0595: //asserting that the count is 0 just below accomplishes the same thing!
0596: //assertTrue(reader instanceof EmptyFeatureReader);
0597: assertEquals(type, reader.getFeatureType());
0598: assertEquals(0, count(reader));
0599:
0600: reader = data.getFeatureReader(new DefaultQuery("ROAD",
0601: rd1Filter), Transaction.AUTO_COMMIT);
0602:
0603: //TODO: Do we care what type it is? In fact, we'll never get FilteringFeatureReader
0604: //since the filtering is done on the DB side!
0605: // assertTrue(reader instanceof JDBCFeatureReader);//FilteringFeatureReader);
0606: assertEquals(type, reader.getFeatureType());
0607: assertEquals(1, count(reader));
0608: }
0609:
0610: public void testGetFeatureReaderFilterTransaction()
0611: throws NoSuchElementException, IOException,
0612: IllegalAttributeException {
0613: Transaction t = new DefaultTransaction();
0614: FeatureType type = data.getSchema("ROAD");
0615: FeatureReader reader;
0616:
0617: reader = data.getFeatureReader(new DefaultQuery("ROAD",
0618: Filter.EXCLUDE), t);
0619:
0620: //TODO: remove this silly check!
0621: //assertTrue(reader instanceof EmptyFeatureReader);
0622: assertEquals(type, reader.getFeatureType());
0623: assertEquals(0, count(reader));
0624:
0625: reader = data.getFeatureReader(new DefaultQuery("ROAD"), t);
0626: assertTrue(reader instanceof DiffFeatureReader);
0627: assertEquals(type, reader.getFeatureType());
0628: assertEquals(roadFeatures.length, count(reader));
0629:
0630: reader = data.getFeatureReader(new DefaultQuery("ROAD",
0631: rd1Filter), t);
0632:
0633: //assertTrue(reader instanceof DiffFeatureReader);//Currently wrapped by a filtering feature reader
0634: assertEquals(type, reader.getFeatureType());
0635: assertEquals(1, count(reader));
0636:
0637: FeatureStore store = (FeatureStore) data
0638: .getFeatureSource("ROAD");
0639: store.setTransaction(t);
0640: store.removeFeatures(rd1Filter);
0641:
0642: reader = data.getFeatureReader(new DefaultQuery("ROAD",
0643: Filter.EXCLUDE), t);
0644: assertEquals(0, count(reader));
0645:
0646: reader = data.getFeatureReader(new DefaultQuery("ROAD"), t);
0647: assertEquals(roadFeatures.length - 1, count(reader));
0648:
0649: reader = data.getFeatureReader(new DefaultQuery("ROAD",
0650: rd1Filter), t);
0651: assertEquals(0, count(reader));
0652:
0653: t.rollback();
0654: reader = data.getFeatureReader(new DefaultQuery("ROAD",
0655: Filter.EXCLUDE), t);
0656: assertEquals(0, count(reader));
0657:
0658: reader = data.getFeatureReader(new DefaultQuery("ROAD"), t);
0659: assertEquals(roadFeatures.length, count(reader));
0660:
0661: reader = data.getFeatureReader(new DefaultQuery("ROAD",
0662: rd1Filter), t);
0663: assertEquals(1, count(reader));
0664: }
0665:
0666: void assertCovered(Feature[] features, FeatureReader reader)
0667: throws NoSuchElementException, IOException,
0668: IllegalAttributeException {
0669: int count = 0;
0670:
0671: try {
0672: while (reader.hasNext()) {
0673: assertTrue(containsFeature(features, reader.next()));
0674: count++;
0675: }
0676: } finally {
0677: //This is not a good idea, since later tests try and run a reader.hasNext() !!
0678: //reader.close();
0679: }
0680:
0681: assertEquals(features.length, count);
0682: }
0683:
0684: /**
0685: * Ensure that FeatureReader reader contains extactly the contents of
0686: * array.
0687: *
0688: * @param reader DOCUMENT ME!
0689: * @param array DOCUMENT ME!
0690: *
0691: * @return DOCUMENT ME!
0692: *
0693: * @throws NoSuchElementException DOCUMENT ME!
0694: * @throws IOException DOCUMENT ME!
0695: * @throws IllegalAttributeException DOCUMENT ME!
0696: */
0697: boolean covers(FeatureCollection features, Feature[] array)
0698: throws NoSuchElementException, IOException,
0699: IllegalAttributeException {
0700:
0701: Feature feature;
0702: int count = 0;
0703: Iterator i = features.iterator();
0704: try {
0705: while (i.hasNext()) {
0706: feature = (Feature) i.next();
0707: if (!containsFeature(array, feature)) {
0708: return false;
0709: }
0710: count++;
0711: }
0712: } finally {
0713: features.close(i);
0714: }
0715: return count == array.length;
0716: }
0717:
0718: /**
0719: * Ensure that FeatureReader reader contains extactly the contents of
0720: * array.
0721: *
0722: * @param reader DOCUMENT ME!
0723: * @param array DOCUMENT ME!
0724: *
0725: * @return DOCUMENT ME!
0726: *
0727: * @throws NoSuchElementException DOCUMENT ME!
0728: * @throws IOException DOCUMENT ME!
0729: * @throws IllegalAttributeException DOCUMENT ME!
0730: */
0731: boolean covers(FeatureReader reader, Feature[] array)
0732: throws NoSuchElementException, IOException,
0733: IllegalAttributeException {
0734: Feature feature;
0735: int count = 0;
0736:
0737: try {
0738: while (reader.hasNext()) {
0739: feature = reader.next();
0740:
0741: assertNotNull("feature", feature);
0742: if (!containsFeature(array, feature)) {
0743: fail("feature " + feature.getID() + " not listed");
0744: return false;
0745: }
0746: count++;
0747: }
0748: } finally {
0749: reader.close();
0750: }
0751: assertEquals("covers", count, array.length);
0752: return true;
0753: }
0754:
0755: boolean covers(FeatureIterator reader, Feature[] array)
0756: throws NoSuchElementException, IOException {
0757: Feature feature;
0758: int count = 0;
0759:
0760: try {
0761: while (reader.hasNext()) {
0762: feature = reader.next();
0763:
0764: assertNotNull("feature", feature);
0765: if (!containsFeature(array, feature)) {
0766: fail("feature " + feature.getID() + " not listed");
0767: return false;
0768: }
0769: count++;
0770: }
0771: } finally {
0772: reader.close();
0773: }
0774: assertEquals("covers", count, array.length);
0775: return true;
0776: }
0777:
0778: boolean coversLax(FeatureReader reader, Feature[] array)
0779: throws NoSuchElementException, IOException,
0780: IllegalAttributeException {
0781: Feature feature;
0782: int count = 0;
0783:
0784: try {
0785: while (reader.hasNext()) {
0786: feature = reader.next();
0787:
0788: if (!containsLax(array, feature)) {
0789: return false;
0790: }
0791:
0792: count++;
0793: }
0794: } finally {
0795: reader.close();
0796: }
0797: return count == array.length;
0798: }
0799:
0800: boolean coversLax(FeatureIterator reader, Feature[] array)
0801: throws NoSuchElementException, IOException,
0802: IllegalAttributeException {
0803: Feature feature;
0804: int count = 0;
0805:
0806: try {
0807: while (reader.hasNext()) {
0808: feature = reader.next();
0809:
0810: if (!containsLax(array, feature)) {
0811: return false;
0812: }
0813:
0814: count++;
0815: }
0816: } finally {
0817: reader.close();
0818: }
0819: return count == array.length;
0820: }
0821:
0822: void dump(FeatureReader reader) throws NoSuchElementException,
0823: IOException, IllegalAttributeException {
0824: Feature feature;
0825: int count = 0;
0826:
0827: try {
0828: while (reader.hasNext()) {
0829: feature = reader.next();
0830: System.out.println(count + " feature:" + feature);
0831: count++;
0832: }
0833: } finally {
0834: reader.close();
0835: }
0836: }
0837:
0838: void dump(Object[] array) {
0839: for (int i = 0; i < array.length; i++) {
0840: System.out.println(i + " feature:" + array[i]);
0841: }
0842: }
0843:
0844: /*
0845: * Test for FeatureWriter getFeatureWriter(String, Filter, Transaction)
0846: */
0847: public void testGetFeatureWriter() throws NoSuchElementException,
0848: IOException, IllegalAttributeException {
0849: FeatureWriter writer = data.getFeatureWriter("ROAD",
0850: Transaction.AUTO_COMMIT);
0851: assertEquals(roadFeatures.length, count(writer));
0852:
0853: try {
0854: writer.hasNext();
0855: fail("Should not be able to use a closed writer");
0856: } catch (IOException expected) {
0857: }
0858:
0859: try {
0860: writer.next();
0861: fail("Should not be able to use a closed writer");
0862: } catch (IOException expected) {
0863: }
0864: }
0865:
0866: public void testGetFeatureWriterRemove() throws IOException,
0867: IllegalAttributeException {
0868: FeatureWriter writer = data.getFeatureWriter("ROAD",
0869: Transaction.AUTO_COMMIT);
0870: Feature feature;
0871:
0872: while (writer.hasNext()) {
0873: feature = writer.next();
0874:
0875: if (feature.getID().equals(roadFeatures[0].getID())) {
0876: writer.remove();
0877: }
0878: }
0879:
0880: writer = data.getFeatureWriter("ROAD", Transaction.AUTO_COMMIT);
0881: assertEquals(roadFeatures.length - 1, count(writer));
0882: }
0883:
0884: public void testGetFeaturesWriterAdd() throws IOException,
0885: IllegalAttributeException {
0886: FeatureWriter writer = data.getFeatureWriter("ROAD",
0887: Transaction.AUTO_COMMIT);
0888: SimpleFeature feature;
0889:
0890: while (writer.hasNext()) {
0891: feature = (SimpleFeature) writer.next();
0892: }
0893:
0894: assertFalse(writer.hasNext());
0895: feature = (SimpleFeature) writer.next();
0896: feature.setAttributes(newRoad.getAttributes(null));
0897: writer.write();
0898: assertFalse(writer.hasNext());
0899:
0900: writer = data.getFeatureWriter("ROAD", Transaction.AUTO_COMMIT);
0901: assertEquals(roadFeatures.length + 1, count(writer));
0902: }
0903:
0904: public void testGetFeaturesWriterModify() throws IOException,
0905: IllegalAttributeException {
0906: FeatureWriter writer = data.getFeatureWriter("ROAD",
0907: Transaction.AUTO_COMMIT);
0908: Feature feature;
0909:
0910: while (writer.hasNext()) {
0911: feature = writer.next();
0912:
0913: if (feature.getID().equals(roadFeatures[0].getID())) {
0914: feature.setAttribute("NAME", "changed");
0915: writer.write();
0916: }
0917: }
0918:
0919: feature = null;
0920:
0921: FeatureReader reader = data.getFeatureReader(new DefaultQuery(
0922: "ROAD", rd1Filter), Transaction.AUTO_COMMIT);
0923:
0924: if (reader.hasNext()) {
0925: feature = reader.next();
0926: }
0927:
0928: // feature = (Feature) data.features("ROAD").get("road.rd1");
0929: assertEquals("changed", feature.getAttribute("NAME"));
0930: }
0931:
0932: public void testGetFeatureWriterTypeNameTransaction()
0933: throws NoSuchElementException, IOException,
0934: IllegalAttributeException {
0935: FeatureWriter writer;
0936:
0937: writer = data.getFeatureWriter("ROAD", Transaction.AUTO_COMMIT);
0938: assertEquals(roadFeatures.length, count(writer));
0939: writer.close();
0940: }
0941:
0942: public void testGetFeatureWriterAppendTypeNameTransaction()
0943: throws Exception {
0944: FeatureWriter writer;
0945:
0946: writer = data.getFeatureWriterAppend("ROAD",
0947: Transaction.AUTO_COMMIT);
0948: assertEquals(0, count(writer));
0949: writer.close();
0950: }
0951:
0952: /*
0953: * Test for FeatureWriter getFeatureWriter(String, boolean, Transaction)
0954: */
0955: public void testGetFeatureWriterFilter()
0956: throws NoSuchElementException, IOException,
0957: IllegalAttributeException {
0958: FeatureWriter writer;
0959:
0960: writer = data.getFeatureWriter("ROAD", Filter.EXCLUDE,
0961: Transaction.AUTO_COMMIT);
0962: assertFalse(writer.hasNext());
0963:
0964: //TODO: This assert sucks since it EXPECTS an emptyFeatureWriter...well, we got A writer...
0965: //and it was empty; that's good enough dammit!
0966: // assertTrue(writer instanceof EmptyFeatureWriter);
0967: assertEquals(0, count(writer));
0968:
0969: writer = data.getFeatureWriter("ROAD", Filter.INCLUDE,
0970: Transaction.AUTO_COMMIT);
0971: assertFalse(writer instanceof FilteringFeatureWriter);
0972: assertEquals(roadFeatures.length, count(writer));
0973:
0974: writer = data.getFeatureWriter("ROAD", rd1Filter,
0975: Transaction.AUTO_COMMIT);
0976:
0977: //TODO: Do we care what type it is? In fact, we'll never get FilteringFeatureWriter
0978: //since the filtering is done on the DB side!
0979: // assertTrue(writer instanceof JDBCFeatureWriter);//FilteringFeatureWriter);
0980: assertEquals(1, count(writer));
0981: }
0982:
0983: /**
0984: * Test two transactions one removing feature, and one adding a feature.
0985: *
0986: * @throws Exception DOCUMENT ME!
0987: */
0988: public void testGetFeatureWriterTransaction() throws Exception {
0989: Transaction t1 = new DefaultTransaction();
0990: Transaction t2 = new DefaultTransaction();
0991: FeatureWriter writer1 = data.getFeatureWriter("ROAD",
0992: rd1Filter, t1);
0993: FeatureWriter writer2 = data.getFeatureWriterAppend("ROAD", t2);
0994:
0995: FeatureType road = data.getSchema("ROAD");
0996: FeatureReader reader;
0997: SimpleFeature feature;
0998: SimpleFeature[] ORIGIONAL = roadFeatures;
0999: Feature[] REMOVE = new Feature[ORIGIONAL.length - 1];
1000: Feature[] ADD = new Feature[ORIGIONAL.length + 1];
1001: Feature[] FINAL = new Feature[ORIGIONAL.length];
1002: int i;
1003: int index;
1004: index = 0;
1005:
1006: for (i = 0; i < ORIGIONAL.length; i++) {
1007: feature = ORIGIONAL[i];
1008:
1009: if (!feature.getID().equals(roadFeatures[0].getID())) {
1010: REMOVE[index++] = feature;
1011: }
1012: }
1013:
1014: for (i = 0; i < ORIGIONAL.length; i++) {
1015: ADD[i] = ORIGIONAL[i];
1016: }
1017:
1018: ADD[i] = newRoad;
1019:
1020: for (i = 0; i < REMOVE.length; i++) {
1021: FINAL[i] = REMOVE[i];
1022: }
1023:
1024: FINAL[i] = newRoad;
1025:
1026: // start of with ORIGINAL
1027: reader = data.getFeatureReader(new DefaultQuery("ROAD"),
1028: Transaction.AUTO_COMMIT);
1029: assertTrue(covers(reader, ORIGIONAL));
1030:
1031: // writer 1 removes road.rd1 on t1
1032: // -------------------------------
1033: // - tests transaction independence from DataStore
1034: while (writer1.hasNext()) {
1035: feature = (SimpleFeature) writer1.next();
1036: assertEquals(roadFeatures[0].getID(), feature.getID());
1037: writer1.remove();
1038: }
1039:
1040: // still have ORIGIONAL and t1 has REMOVE
1041: reader = data.getFeatureReader(new DefaultQuery("ROAD"),
1042: Transaction.AUTO_COMMIT);
1043:
1044: assertTrue(covers(reader, ORIGIONAL));
1045:
1046: reader = data.getFeatureReader(new DefaultQuery("ROAD"), t1);
1047: assertTrue(covers(reader, REMOVE));
1048:
1049: // close writer1
1050: // --------------
1051: // ensure that modification is left up to transaction commmit
1052: writer1.close();
1053:
1054: // We still have ORIGIONAL and t1 has REMOVE
1055: reader = data.getFeatureReader(new DefaultQuery("ROAD"),
1056: Transaction.AUTO_COMMIT);
1057: assertTrue(covers(reader, ORIGIONAL));
1058: reader = data.getFeatureReader(new DefaultQuery("ROAD"), t1);
1059: assertTrue(covers(reader, REMOVE));
1060:
1061: // writer 2 adds road.rd4 on t2
1062: // ----------------------------
1063: // - tests transaction independence from each other
1064: feature = (SimpleFeature) writer2.next();
1065: feature.setAttributes(newRoad.getAttributes(null));
1066: writer2.write();
1067:
1068: // We still have ORIGIONAL and t2 has ADD
1069: reader = data.getFeatureReader(new DefaultQuery("ROAD"),
1070: Transaction.AUTO_COMMIT);
1071: assertTrue(covers(reader, ORIGIONAL));
1072: reader = data.getFeatureReader(new DefaultQuery("ROAD"), t2);
1073: assertTrue(coversLax(reader, ADD));
1074:
1075: // close writer2
1076: // -------------
1077: // ensure that modification is left up to transaction commmit
1078: writer2.close();
1079:
1080: // Still have ORIGIONAL and t2 has ADD
1081: reader = data.getFeatureReader(new DefaultQuery("ROAD"),
1082: Transaction.AUTO_COMMIT);
1083: assertTrue(covers(reader, ORIGIONAL));
1084: reader = data.getFeatureReader(new DefaultQuery("ROAD"), t2);
1085: assertTrue(coversLax(reader, ADD));
1086:
1087: // commit t1
1088: // ---------
1089: // -ensure that delayed writing of transactions takes place
1090: //
1091: t1.commit();
1092:
1093: // We now have REMOVE, as does t1 (which has not additional diffs)
1094: // t2 will have FINAL
1095: reader = data.getFeatureReader(new DefaultQuery("ROAD"),
1096: Transaction.AUTO_COMMIT);
1097: assertTrue(covers(reader, REMOVE));
1098: reader = data.getFeatureReader(new DefaultQuery("ROAD"), t1);
1099: assertTrue(covers(reader, REMOVE));
1100: reader = data.getFeatureReader(new DefaultQuery("ROAD"), t2);
1101: assertTrue(coversLax(reader, FINAL));
1102:
1103: // commit t2
1104: // ---------
1105: // -ensure that everyone is FINAL at the end of the day
1106: t2.commit();
1107:
1108: // We now have Number( remove one and add one)
1109: reader = data.getFeatureReader(new DefaultQuery("ROAD"),
1110: Transaction.AUTO_COMMIT);
1111: reader = data.getFeatureReader(new DefaultQuery("ROAD"),
1112: Transaction.AUTO_COMMIT);
1113: assertTrue(coversLax(reader, FINAL));
1114: reader = data.getFeatureReader(new DefaultQuery("ROAD"), t1);
1115: assertTrue(coversLax(reader, FINAL));
1116: reader = data.getFeatureReader(new DefaultQuery("ROAD"), t2);
1117: assertTrue(coversLax(reader, FINAL));
1118: }
1119:
1120: //FIXME: This test will fail for all DB datastores because of the getBounds issue...
1121: //should revisit later.
1122: //
1123: // Feature Source Testing
1124: public void atestGetFeatureSourceRoad() throws IOException {
1125: FeatureSource road = data.getFeatureSource("ROAD");
1126:
1127: assertEquals(roadType, road.getSchema());
1128: assertEquals(data, road.getDataStore());
1129: assertEquals(3, road.getCount(Query.ALL));
1130:
1131: //TODO: which way to get the bounds?
1132: assertEquals(new Envelope(1, 5, 0, 4), road.getFeatures(
1133: Query.ALL).getBounds()); //road.getBounds(Query.ALL));
1134:
1135: FeatureCollection all = road.getFeatures();
1136: assertEquals(3, all.size());
1137: assertEquals(roadBounds, all.getBounds());
1138:
1139: FeatureCollection expected = DataUtilities
1140: .collection(roadFeatures);
1141:
1142: assertCovers("ALL", expected, all);
1143: assertEquals(roadBounds, all.getBounds());
1144:
1145: FeatureCollection some = road.getFeatures(rd12Filter);
1146: assertEquals(2, some.size());
1147: assertEquals(rd12Bounds, some.getBounds());
1148: assertEquals(some.getSchema(), road.getSchema());
1149:
1150: //TODO: what should be done here? change the query to get GEOM or not?
1151: //We need to fetch "GEOM" since we'll need to create the bounds based
1152: //on the geometry later on (getting the geom from the DB is expensive and
1153: //so far unsupported
1154: DefaultQuery query = new DefaultQuery("ROAD", rd12Filter,
1155: new String[] { "NAME", });
1156:
1157: FeatureCollection half = road.getFeatures(query);
1158: assertEquals(2, half.size());
1159: assertEquals(1, half.getSchema().getAttributeCount());
1160:
1161: FeatureIterator reader = half.features();
1162: FeatureType type = half.getSchema();
1163: reader.close();
1164:
1165: FeatureType actual = half.getSchema();
1166:
1167: assertEquals(type.getTypeName(), actual.getTypeName());
1168: assertEquals(type.getNamespace(), actual.getNamespace());
1169: assertEquals(type.getAttributeCount(), actual
1170: .getAttributeCount());
1171:
1172: for (int i = 0; i < type.getAttributeCount(); i++) {
1173: assertEquals(type.getAttributeType(i), actual
1174: .getAttributeType(i));
1175: }
1176:
1177: assertNull(type.getDefaultGeometry());
1178: assertEquals(type.getDefaultGeometry(), actual
1179: .getDefaultGeometry());
1180: assertEquals(type, actual);
1181:
1182: Envelope b = half.getBounds();
1183: assertEquals(new Envelope(1, 5, 0, 4), b);
1184: }
1185:
1186: public void testGetFeatureSourceRiver()
1187: throws NoSuchElementException, IOException,
1188: IllegalAttributeException {
1189: FeatureSource river = data.getFeatureSource("RIVER");
1190:
1191: assertEquals(riverType, river.getSchema());
1192: assertEquals(data, river.getDataStore());
1193:
1194: FeatureCollection all = river.getFeatures();
1195: assertEquals(2, all.size());
1196: assertEquals(riverBounds, all.getBounds());
1197: assertTrue("RIVERS", covers(all.features(), riverFeatures));
1198:
1199: FeatureCollection expected = DataUtilities
1200: .collection(riverFeatures);
1201: assertCovers("ALL", expected, all);
1202: assertEquals(riverBounds, all.getBounds());
1203: }
1204:
1205: //
1206: // Feature Store Testing
1207: //
1208: public void testGetFeatureStoreModifyFeatures1() throws IOException {
1209: FeatureStore road = (FeatureStore) data
1210: .getFeatureSource("ROAD");
1211: AttributeType name = roadType.getAttributeType("NAME");
1212: road.modifyFeatures(name, "changed", rd1Filter);
1213:
1214: FeatureCollection results = road.getFeatures(rd1Filter);
1215: assertEquals("changed", results.features().next().getAttribute(
1216: "NAME"));
1217: }
1218:
1219: public void testGetFeatureStoreModifyFeatures2() throws IOException {
1220: FeatureStore road = (FeatureStore) data
1221: .getFeatureSource("ROAD");
1222: AttributeType name = roadType.getAttributeType("NAME");
1223: road.modifyFeatures(new AttributeType[] { name, },
1224: new Object[] { "changed", }, rd1Filter);
1225:
1226: FeatureCollection results = road.getFeatures(rd1Filter);
1227: assertEquals("changed", results.features().next().getAttribute(
1228: "NAME"));
1229: }
1230:
1231: public void testGetFeatureStoreRemoveFeatures() throws IOException {
1232: FeatureStore road = (FeatureStore) data
1233: .getFeatureSource("ROAD");
1234:
1235: road.removeFeatures(rd1Filter);
1236: assertEquals(0, road.getFeatures(rd1Filter).size());
1237: assertEquals(roadFeatures.length - 1, road.getFeatures().size());
1238: }
1239:
1240: public void testGetFeatureStoreAddFeatures() throws IOException {
1241: FeatureReader reader = DataUtilities
1242: .reader(new Feature[] { newRoad, });
1243: FeatureStore road = (FeatureStore) data
1244: .getFeatureSource("ROAD");
1245:
1246: road.addFeatures(DataUtilities.collection(reader));
1247: assertEquals(roadFeatures.length + 1, road.getFeatures().size());
1248: }
1249:
1250: public void testGetFeatureStoreSetFeatures() throws IOException {
1251: FeatureReader reader = DataUtilities
1252: .reader(new Feature[] { newRoad, });
1253: FeatureStore road = (FeatureStore) data
1254: .getFeatureSource("ROAD");
1255:
1256: road.setFeatures(reader);
1257: assertEquals(1, road.getFeatures().size());
1258: }
1259:
1260: public void testGetFeatureStoreTransactionSupport()
1261: throws Exception {
1262: Transaction t1 = new DefaultTransaction();
1263: Transaction t2 = new DefaultTransaction();
1264:
1265: FeatureStore road = (FeatureStore) data
1266: .getFeatureSource("ROAD");
1267: FeatureStore road1 = (FeatureStore) data
1268: .getFeatureSource("ROAD");
1269: FeatureStore road2 = (FeatureStore) data
1270: .getFeatureSource("ROAD");
1271:
1272: road1.setTransaction(t1);
1273: road2.setTransaction(t2);
1274:
1275: Feature feature;
1276: Feature[] ORIGIONAL = roadFeatures;
1277: Feature[] REMOVE = new Feature[ORIGIONAL.length - 1];
1278: Feature[] ADD = new Feature[ORIGIONAL.length + 1];
1279: Feature[] FINAL = new Feature[ORIGIONAL.length];
1280: int i;
1281: int index;
1282: index = 0;
1283:
1284: for (i = 0; i < ORIGIONAL.length; i++) {
1285: feature = ORIGIONAL[i];
1286:
1287: if (!feature.getID().equals(roadFeatures[0].getID())) {
1288: REMOVE[index++] = feature;
1289: }
1290: }
1291:
1292: for (i = 0; i < ORIGIONAL.length; i++) {
1293: ADD[i] = ORIGIONAL[i];
1294: }
1295:
1296: ADD[i] = newRoad;
1297:
1298: for (i = 0; i < REMOVE.length; i++) {
1299: FINAL[i] = REMOVE[i];
1300: }
1301:
1302: FINAL[i] = newRoad;
1303:
1304: // start of with ORIGINAL
1305: assertTrue(covers(road.getFeatures().features(), ORIGIONAL));
1306:
1307: // road1 removes road.rd1 on t1
1308: // -------------------------------
1309: // - tests transaction independence from DataStore
1310: road1.removeFeatures(rd1Filter);
1311:
1312: // still have ORIGIONAL and t1 has REMOVE
1313: assertTrue(covers(road.getFeatures().features(), ORIGIONAL));
1314: assertTrue(covers(road1.getFeatures().features(), REMOVE));
1315:
1316: // road2 adds road.rd4 on t2
1317: // ----------------------------
1318: // - tests transaction independence from each other
1319: FeatureCollection collection = DataUtilities
1320: .collection(new Feature[] { newRoad, });
1321: road2.addFeatures(collection);
1322:
1323: // We still have ORIGIONAL, t1 has REMOVE, and t2 has ADD
1324: assertTrue(covers(road.getFeatures().features(), ORIGIONAL));
1325: assertTrue(covers(road1.getFeatures().features(), REMOVE));
1326: assertTrue(coversLax(road2.getFeatures().features(), ADD));
1327:
1328: // commit t1
1329: // ---------
1330: // -ensure that delayed writing of transactions takes place
1331: //
1332: t1.commit();
1333:
1334: // We now have REMOVE, as does t1 (which has not additional diffs)
1335: // t2 will have FINAL
1336: assertTrue(covers(road.getFeatures().features(), REMOVE));
1337: assertTrue(covers(road1.getFeatures().features(), REMOVE));
1338: assertTrue(coversLax(road2.getFeatures().features(), FINAL));
1339:
1340: // commit t2
1341: // ---------
1342: // -ensure that everyone is FINAL at the end of the day
1343: t2.commit();
1344:
1345: // We now have Number( remove one and add one)
1346: assertTrue(coversLax(road.getFeatures().features(), FINAL));
1347: assertTrue(coversLax(road1.getFeatures().features(), FINAL));
1348: assertTrue(coversLax(road2.getFeatures().features(), FINAL));
1349: }
1350:
1351: boolean isLocked(String typeName, String fid) {
1352: InProcessLockingManager lockingManager = (InProcessLockingManager) data
1353: .getLockingManager();
1354:
1355: return lockingManager.isLocked(typeName, fid);
1356: }
1357:
1358: //
1359: // FeatureLocking Testing
1360: //
1361:
1362: /*
1363: * Test for void lockFeatures()
1364: */
1365: public void testLockFeatures() throws IOException {
1366: FeatureLock lock = FeatureLockFactory.generate("test", 3600);
1367: FeatureLocking road = (FeatureLocking) data
1368: .getFeatureSource("ROAD");
1369: road.setFeatureLock(lock);
1370:
1371: assertFalse(isLocked("ROAD", roadFeatures[0].getID()));
1372: road.lockFeatures();
1373: assertTrue(isLocked("ROAD", roadFeatures[0].getID()));
1374: }
1375:
1376: public void testUnLockFeatures() throws IOException {
1377: FeatureLock lock = FeatureLockFactory.generate("test", 360000);
1378: FeatureLocking road = (FeatureLocking) data
1379: .getFeatureSource("ROAD");
1380: road.setFeatureLock(lock);
1381: road.lockFeatures();
1382:
1383: try {
1384: road.unLockFeatures();
1385: fail("unlock should fail due on AUTO_COMMIT");
1386: } catch (IOException expected) {
1387: }
1388:
1389: Transaction t = new DefaultTransaction();
1390: road.setTransaction(t);
1391:
1392: try {
1393: road.unLockFeatures();
1394: fail("unlock should fail due lack of authorization");
1395: } catch (IOException expected) {
1396: }
1397:
1398: t.addAuthorization(lock.getAuthorization());
1399: road.unLockFeatures();
1400: }
1401:
1402: public void testLockFeatureInteraction() throws IOException {
1403: FeatureLock lockA = FeatureLockFactory.generate("LockA", 3600);
1404: FeatureLock lockB = FeatureLockFactory.generate("LockB", 3600);
1405: Transaction t1 = new DefaultTransaction();
1406: Transaction t2 = new DefaultTransaction();
1407: FeatureLocking road1 = (FeatureLocking) data
1408: .getFeatureSource("ROAD");
1409: FeatureLocking road2 = (FeatureLocking) data
1410: .getFeatureSource("ROAD");
1411: road1.setTransaction(t1);
1412: road2.setTransaction(t2);
1413: road1.setFeatureLock(lockA);
1414: road2.setFeatureLock(lockB);
1415:
1416: assertFalse(isLocked("ROAD", roadFeatures[0].getID()));
1417: assertFalse(isLocked("ROAD", roadFeatures[1].getID()));
1418: assertFalse(isLocked("ROAD", roadFeatures[2].getID()));
1419:
1420: road1.lockFeatures(rd1Filter);
1421: assertTrue(isLocked("ROAD", roadFeatures[0].getID()));
1422: assertFalse(isLocked("ROAD", roadFeatures[1].getID()));
1423: assertFalse(isLocked("ROAD", roadFeatures[2].getID()));
1424:
1425: road2.lockFeatures(rd2Filter);
1426: assertTrue(isLocked("ROAD", roadFeatures[0].getID()));
1427: assertTrue(isLocked("ROAD", roadFeatures[1].getID()));
1428: assertFalse(isLocked("ROAD", roadFeatures[2].getID()));
1429:
1430: try {
1431: road1.unLockFeatures(rd1Filter);
1432: fail("need authorization");
1433: } catch (IOException expected) {
1434: }
1435:
1436: t1.addAuthorization(lockA.getAuthorization());
1437:
1438: try {
1439: road1.unLockFeatures(rd2Filter);
1440: fail("need correct authorization");
1441: } catch (IOException expected) {
1442: }
1443:
1444: road1.unLockFeatures(rd1Filter);
1445: assertFalse(isLocked("ROAD", roadFeatures[0].getID()));
1446: assertTrue(isLocked("ROAD", roadFeatures[1].getID()));
1447: assertFalse(isLocked("ROAD", roadFeatures[2].getID()));
1448:
1449: t2.addAuthorization(lockB.getAuthorization());
1450: road2.unLockFeatures(rd2Filter);
1451: assertFalse(isLocked("ROAD", roadFeatures[0].getID()));
1452: assertFalse(isLocked("ROAD", roadFeatures[1].getID()));
1453: assertFalse(isLocked("ROAD", roadFeatures[2].getID()));
1454: }
1455:
1456: public void testGetFeatureLockingExpire() throws Exception {
1457: FeatureLock lock = FeatureLockFactory.generate("Timed", 1);
1458: FeatureLocking road = (FeatureLocking) data
1459: .getFeatureSource("ROAD");
1460: road.setFeatureLock(lock);
1461: assertFalse(isLocked("ROAD", roadFeatures[0].getID()));
1462: road.lockFeatures(rd1Filter);
1463: assertTrue(isLocked("ROAD", roadFeatures[0].getID()));
1464: Thread.sleep(50);
1465: assertFalse(isLocked("ROAD", roadFeatures[0].getID()));
1466: }
1467:
1468: public void testCreateSchema() throws Exception {
1469: String typename = "NewType";
1470: FeatureType t = DataUtilities.createType(typename,
1471: "*geom:Geometry");
1472: data.createSchema(t);
1473:
1474: String[] names = data.getTypeNames();
1475: boolean foundNewType = false;
1476:
1477: for (int i = 0; i < names.length; i++) {
1478: if (names[i].equalsIgnoreCase(typename)) {
1479: foundNewType = true;
1480: }
1481: }
1482:
1483: assertTrue(foundNewType);
1484: }
1485: }
|