Source Code Cross Referenced for VersionedOperationsOnlineTest.java in  » GIS » GeoTools-2.4.1 » org » geotools » data » postgis » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » org.geotools.data.postgis 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *    GeoTools - OpenSource mapping toolkit
0003:         *    http://geotools.org
0004:         *    (C) 2002-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.postgis;
0017:
0018:        import java.io.IOException;
0019:        import java.sql.Connection;
0020:        import java.sql.Statement;
0021:        import java.util.Arrays;
0022:        import java.util.Collections;
0023:        import java.util.HashSet;
0024:        import java.util.List;
0025:        import java.util.NoSuchElementException;
0026:        import java.util.Set;
0027:
0028:        import junit.framework.Test;
0029:        import junit.framework.TestSuite;
0030:        import junit.textui.ResultPrinter;
0031:
0032:        import org.geotools.data.DataUtilities;
0033:        import org.geotools.data.DefaultQuery;
0034:        import org.geotools.data.DefaultTransaction;
0035:        import org.geotools.data.FeatureLocking;
0036:        import org.geotools.data.FeatureReader;
0037:        import org.geotools.data.FeatureStore;
0038:        import org.geotools.data.FeatureWriter;
0039:        import org.geotools.data.Query;
0040:        import org.geotools.data.Transaction;
0041:        import org.geotools.data.VersioningFeatureSource;
0042:        import org.geotools.factory.CommonFactoryFinder;
0043:        import org.geotools.feature.AttributeType;
0044:        import org.geotools.feature.Feature;
0045:        import org.geotools.feature.FeatureCollection;
0046:        import org.geotools.feature.FeatureIterator;
0047:        import org.geotools.feature.FeatureType;
0048:        import org.geotools.feature.IllegalAttributeException;
0049:        import org.geotools.referencing.CRS;
0050:        import org.opengis.filter.Filter;
0051:        import org.opengis.filter.FilterFactory;
0052:        import org.opengis.filter.Id;
0053:        import org.opengis.filter.identity.FeatureId;
0054:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
0055:
0056:        import com.vividsolutions.jts.geom.Coordinate;
0057:        import com.vividsolutions.jts.geom.Envelope;
0058:
0059:        public class VersionedOperationsOnlineTest extends
0060:                AbstractVersionedPostgisDataTestCase {
0061:            FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);
0062:
0063:            public VersionedOperationsOnlineTest(String name) {
0064:                super (name);
0065:            }
0066:
0067:            public void testTypeNames() throws IOException {
0068:                VersionedPostgisDataStore ds = getDataStore();
0069:                List typeNames = Arrays.asList(ds.getTypeNames());
0070:                assertTrue(typeNames.contains("road"));
0071:                assertFalse(typeNames.contains("road_wfc_view"));
0072:                assertTrue(typeNames.contains("lake"));
0073:                assertFalse(typeNames.contains("lake_wfc_view"));
0074:                assertTrue(typeNames.contains("river"));
0075:                assertFalse(typeNames.contains("rivel_wfc_view"));
0076:                assertTrue(typeNames.contains("rail"));
0077:                assertFalse(typeNames.contains("rail_wfc_view"));
0078:                assertTrue(typeNames.contains("nopk"));
0079:                assertFalse(typeNames.contains("nopk_wfc_view"));
0080:                assertTrue(typeNames
0081:                        .contains(VersionedPostgisDataStore.TBL_CHANGESETS));
0082:
0083:                assertFalse(typeNames
0084:                        .contains(VersionedPostgisDataStore.TBL_VERSIONEDTABLES));
0085:                assertFalse(typeNames
0086:                        .contains(VersionedPostgisDataStore.TBL_TABLESCHANGED));
0087:            }
0088:
0089:            /**
0090:             * Changesets is special, it's an internal table exposed for log access purposes, and it's not
0091:             * writable
0092:             */
0093:            public void testChangesetFeatureType() throws IOException {
0094:                VersionedPostgisDataStore ds = getDataStore();
0095:                FeatureType ft = ds
0096:                        .getSchema(VersionedPostgisDataStore.TBL_CHANGESETS);
0097:                assertNotNull(ft.getAttributeType("revision"));
0098:                assertFalse(ds
0099:                        .getFeatureSource(VersionedPostgisDataStore.TBL_CHANGESETS) instanceof  FeatureStore);
0100:            }
0101:
0102:            public void testVersionEnableDisableFeatureType()
0103:                    throws IOException {
0104:                VersionedPostgisDataStore ds = getDataStore();
0105:                FeatureType ft = ds.getSchema("road");
0106:                assertFalse(ds.isVersioned("road"));
0107:
0108:                // version
0109:                ds.setVersioned("road", true, "gimbo",
0110:                        "Initial import of roads");
0111:                assertTrue(ds.isVersioned("road"));
0112:                assertEquals(ft, ds.getSchema("road"));
0113:                if (ds.getFIDMapper("road").returnFIDColumnsAsAttributes())
0114:                    assertNotNull(ds.wrapped.getSchema("road")
0115:                            .getAttributeType("revision"));
0116:                assertNotNull(ds.wrapped.getSchema("road").getAttributeType(
0117:                        "expired"));
0118:                // check we don't see the versioned feature collection as a public type
0119:                assertFalse(Arrays.asList(ds.getTypeNames()).contains(
0120:                        "road_vfc_view"));
0121:
0122:                // check the versioned feature collection view is there
0123:                FeatureType view = ds.wrapped.getSchema("road_vfc_view");
0124:                AttributeType[] types = view.getAttributeTypes();
0125:                assertEquals(ft.getAttributeCount() + 12, view
0126:                        .getAttributeCount());
0127:                assertEquals("creationVersion", types[0].getLocalName());
0128:                assertEquals("createdBy", types[1].getLocalName());
0129:                assertEquals("creationDate", types[2].getLocalName());
0130:                assertEquals("creationMessage", types[3].getLocalName());
0131:                assertEquals("lastUpdateVersion", types[4].getLocalName());
0132:                assertEquals("lastUpdatedBy", types[5].getLocalName());
0133:                assertEquals("lastUpdateDate", types[6].getLocalName());
0134:                assertEquals("lastUpdateMessage", types[7].getLocalName());
0135:                // check the versioned feature collation is not visible outside of the verioning datastore
0136:                try {
0137:                    ds.getSchema("road_vfc_view");
0138:                    fail("The versioning feature collection for road should not be visible as a standalone type");
0139:                } catch (IOException e) {
0140:                    // ok
0141:                }
0142:
0143:                // un-version
0144:                ds.setVersioned("road", false, "gimbo",
0145:                        "Versioning no more needed");
0146:                assertFalse(ds.isVersioned("road"));
0147:                assertEquals(ft, ds.getSchema("road"));
0148:                assertNull(ds.wrapped.getSchema("road").getAttributeType(
0149:                        "revision"));
0150:                assertNull(ds.wrapped.getSchema("road").getAttributeType(
0151:                        "expired"));
0152:                try {
0153:                    ds.wrapped.getSchema("road_vfc_view");
0154:                    fail("The versioning view should not be there anymore");
0155:                } catch (IOException e) {
0156:                    // ok
0157:                }
0158:            }
0159:
0160:            public void testNonExistentTypes() throws IOException {
0161:                VersionedPostgisDataStore ds = getDataStore();
0162:                try {
0163:                    ds.isVersioned("blablabla");
0164:                    fail("Non existent type blablabla accepted anyways...");
0165:                } catch (IOException e) {
0166:                    // ok, does not exist
0167:                }
0168:
0169:                ds.setVersioned("road", true, "gimbo",
0170:                        "Initial import of roads");
0171:                try {
0172:                    ds.isVersioned(ds.getVFCViewName("road"));
0173:                    fail("Versioned feature collection view accepted as a legitimate type...");
0174:                } catch (IOException e) {
0175:                    // ok, should not be accepted
0176:                }
0177:            }
0178:
0179:            public void testVersionEnableChangeSets() throws IOException {
0180:                VersionedPostgisDataStore ds = getDataStore();
0181:                ds.getSchema(VersionedPostgisDataStore.TBL_CHANGESETS);
0182:                assertFalse(ds.isVersioned("road"));
0183:
0184:                // try version, should fail
0185:                try {
0186:                    ds.setVersioned(VersionedPostgisDataStore.TBL_CHANGESETS,
0187:                            true, "gimbo", "Initial import of roads");
0188:                    fail("It should not be possible to version enable changesets");
0189:                } catch (IOException e) {
0190:                }
0191:            }
0192:
0193:            public void testVersionEnableEmptyTable() throws IOException {
0194:                VersionedPostgisDataStore ds = getDataStore();
0195:                assertFalse(ds.isVersioned("empty"));
0196:
0197:                // try version enable, should go well despite the table being empty
0198:                ds.setVersioned("empty", true, "gimbo",
0199:                        "Version enable deep space void");
0200:                assertTrue(ds.isVersioned("empty"));
0201:            }
0202:
0203:            public void testVersionEnablePointTable() throws IOException {
0204:                VersionedPostgisDataStore ds = getDataStore();
0205:                assertFalse(ds.isVersioned("point"));
0206:
0207:                // try version enable, should go well despite the single geom not making up a bbox
0208:                // for the changeset
0209:                ds.setVersioned("point", true, "gimbo",
0210:                        "Version enable a tiny damn point");
0211:                assertTrue(ds.isVersioned("point"));
0212:            }
0213:
0214:            public void testGetFeatureReader() throws IOException,
0215:                    NoSuchElementException, Exception {
0216:                VersionedPostgisDataStore ds = getDataStore();
0217:
0218:                FeatureType originalFt = ds.getSchema("road");
0219:                ds
0220:                        .setVersioned("road", true, "gimbo",
0221:                                "version enabling stuff");
0222:                DefaultQuery q = new DefaultQuery("road");
0223:                FeatureReader fr = ds.wrapped.getFeatureReader(q,
0224:                        Transaction.AUTO_COMMIT);
0225:                while (fr.hasNext()) {
0226:                    Feature f = fr.next();
0227:                    assertEquals(new Long(1), (Long) f.getAttribute("revision"));
0228:                    assertEquals(new Long(Long.MAX_VALUE), (Long) f
0229:                            .getAttribute("expired"));
0230:                }
0231:                fr.close();
0232:
0233:                // now insert by hand three revisions of first road and check we can
0234:                // extract the good ones
0235:                SqlTestUtils
0236:                        .execute(pool,
0237:                                "INSERT INTO CHANGESETS VALUES(2, 'gimbo', default, '', null)");
0238:                SqlTestUtils
0239:                        .execute(pool,
0240:                                "INSERT INTO CHANGESETS VALUES(3, 'gimbo', default, '', null)");
0241:                SqlTestUtils.execute(pool,
0242:                        "INSERT INTO ROAD SELECT FID, ID, GEOM, 'r1 rev 2', 2, 3, 2 "
0243:                                + "FROM ROAD WHERE ID = 1 AND EXPIRED = "
0244:                                + Long.MAX_VALUE);
0245:                SqlTestUtils.execute(pool,
0246:                        "INSERT INTO ROAD SELECT FID, ID, GEOM, 'r1 rev 3', 3,  "
0247:                                + Long.MAX_VALUE + ", 2 "
0248:                                + "FROM ROAD WHERE ID = 1 AND EXPIRED = "
0249:                                + Long.MAX_VALUE);
0250:                SqlTestUtils.execute(pool,
0251:                        "UPDATE ROAD SET EXPIRED = 2 WHERE ID = 1 AND REVISION = 1 AND EXPIRED = "
0252:                                + Long.MAX_VALUE);
0253:
0254:                // non versioned data store should return two more features now
0255:                assertEquals(roadFeatures.length + 2, ds.wrapped
0256:                        .getFeatureSource("road").getCount(Query.ALL));
0257:
0258:                // no revision info, use last
0259:                Filter idFilter = ff.equals(ff.property("id"), ff.literal(1l));
0260:                q = new DefaultQuery("road", idFilter);
0261:                fr = ds.getFeatureReader(q, Transaction.AUTO_COMMIT);
0262:                // make sure the type is the same as if we were working against a non
0263:                // versioned datastore
0264:                assertEquals(originalFt, fr.getFeatureType());
0265:                assertTrue(fr.hasNext());
0266:                Feature f = fr.next();
0267:                assertEquals("road.rd1", f.getID());
0268:                assertEquals("r1 rev 3", f.getAttribute("name"));
0269:                assertFalse(fr.hasNext());
0270:                fr.close();
0271:
0272:                // now extract revision 1
0273:                q = new DefaultQuery("road", idFilter);
0274:                q.setVersion("1");
0275:                fr = ds.getFeatureReader(q, Transaction.AUTO_COMMIT);
0276:                assertTrue(fr.hasNext());
0277:                f = fr.next();
0278:                assertEquals("road.rd1", f.getID());
0279:                assertEquals("r1", f.getAttribute("name"));
0280:                assertFalse(fr.hasNext());
0281:                fr.close();
0282:
0283:                // and now extract revision 2
0284:                q = new DefaultQuery("road", idFilter);
0285:                q.setVersion("2");
0286:                fr = ds.getFeatureReader(q, Transaction.AUTO_COMMIT);
0287:                assertTrue(fr.hasNext());
0288:                f = fr.next();
0289:                assertEquals("road.rd1", f.getID());
0290:                assertEquals("r1 rev 2", f.getAttribute("name"));
0291:                assertFalse(fr.hasNext());
0292:                fr.close();
0293:
0294:                // now try the same with a fid filter
0295:                Filter fidFilter = ff.id(Collections.singleton(ff
0296:                        .featureId("road.rd1")));
0297:                q = new DefaultQuery("road", fidFilter);
0298:
0299:                // fid and last revision
0300:                fr = ds.getFeatureReader(q, Transaction.AUTO_COMMIT);
0301:                assertTrue(fr.hasNext());
0302:                f = fr.next();
0303:                assertEquals("road.rd1", f.getID());
0304:                assertEquals("r1 rev 3", f.getAttribute("name"));
0305:                assertFalse(fr.hasNext());
0306:                fr.close();
0307:
0308:                // fid and specific revision
0309:                q = new DefaultQuery("road", fidFilter);
0310:                q.setVersion("2");
0311:                fr = ds.getFeatureReader(q, Transaction.AUTO_COMMIT);
0312:                assertTrue(fr.hasNext());
0313:                f = fr.next();
0314:                assertEquals("road.rd1", f.getID());
0315:                assertEquals("r1 rev 2", f.getAttribute("name"));
0316:                assertFalse(fr.hasNext());
0317:                fr.close();
0318:            }
0319:
0320:            public void testFidFilter() throws IOException,
0321:                    NoSuchElementException, IllegalAttributeException {
0322:                VersionedPostgisDataStore ds = getDataStore();
0323:
0324:                // check querying with fids out of the expected format does not break
0325:                // the datastore
0326:                Filter f = ff
0327:                        .id(new HashSet(Arrays.asList(new FeatureId[] {
0328:                                ff.featureId("road.rd1"),
0329:                                ff.featureId("strangeId") })));
0330:                Query q = new DefaultQuery("road", f);
0331:                FeatureReader fr = ds.getFeatureReader(q,
0332:                        Transaction.AUTO_COMMIT);
0333:                assertTrue(fr.hasNext());
0334:                fr.next();
0335:                assertFalse(fr.hasNext());
0336:                fr.close();
0337:
0338:                // check querying with fids out of the expected format does not break
0339:                // the datastore
0340:                // this one should turn the filter into a Filter.EXCLUDE thing
0341:                f = ff.id(new HashSet(Arrays.asList(new FeatureId[] { ff
0342:                        .featureId("xyz:?strangeId") })));
0343:                q = new DefaultQuery("road", f);
0344:                fr = ds.getFeatureReader(q, Transaction.AUTO_COMMIT);
0345:                assertFalse(fr.hasNext());
0346:                fr.close();
0347:
0348:                // check querying with fids out of the expected format does not break
0349:                // the datastore
0350:                // this one was putting the filter splitter in dismay
0351:                f = ff.id(new HashSet(Arrays.asList(new FeatureId[] { ff
0352:                        .featureId("xyz:?strangeId") })));
0353:                f = ff.and(f, ff.bbox("geom", -100, -100, 100, 100, null));
0354:                q = new DefaultQuery("road", f);
0355:                fr = ds.getFeatureReader(q, Transaction.AUTO_COMMIT);
0356:                assertFalse(fr.hasNext());
0357:                fr.close();
0358:            }
0359:
0360:            public void testGetFeatureWriter() throws IOException,
0361:                    NoSuchElementException, Exception {
0362:                VersionedPostgisDataStore ds = getDataStore();
0363:                Envelope originalBounds = ds.wrapped.getFeatureSource("road")
0364:                        .getBounds();
0365:
0366:                // version enable road
0367:                FeatureType originalFt = ds.getSchema("road");
0368:                ds
0369:                        .setVersioned("road", true, "gimbo",
0370:                                "version enabling stuff");
0371:
0372:                // build a filter to extract just road 1
0373:                Filter filter = ff.id(Collections.singleton(ff
0374:                        .featureId("road.rd1")));
0375:
0376:                // now write one revision
0377:                Transaction t = createTransaction("gimbo", "first change");
0378:                FeatureWriter fw = ds.getFeatureWriter("road", filter, t);
0379:                assertTrue(fw.hasNext());
0380:                Feature f = fw.next();
0381:                f.setAttribute("name", "r1 rev 2");
0382:                fw.write();
0383:                fw.close();
0384:                t.commit();
0385:                assertEquals(new Long(2), t
0386:                        .getProperty(VersionedPostgisDataStore.REVISION));
0387:                assertEquals("2", t
0388:                        .getProperty(VersionedPostgisDataStore.VERSION));
0389:                t.close();
0390:
0391:                // write another
0392:                t = createTransaction("gimbo", "second change");
0393:                fw = ds.getFeatureWriter("road", filter, t);
0394:                assertTrue(fw.hasNext());
0395:                f = fw.next();
0396:                f.setAttribute("name", "r1 rev 3");
0397:                fw.write();
0398:                fw.close();
0399:                t.commit();
0400:                t.close();
0401:
0402:                // check we have the rigth changesets in the database
0403:                DefaultQuery q = new DefaultQuery(
0404:                        VersionedPostgisDataStore.TBL_CHANGESETS);
0405:                t = new DefaultTransaction();
0406:                FeatureReader fr = ds.getFeatureReader(q, t);
0407:                // ... ah, would very much like to sort on revision...
0408:                // ... first revision, import
0409:                assertTrue(fr.hasNext());
0410:                f = fr.next();
0411:                assertEquals(new Long(1), f.getAttribute("revision"));
0412:                // TODO : get revision back among the attributes
0413:                // assertEquals(new Long(1), f.getAttribute("revision"));
0414:                assertEquals(originalBounds, f.getDefaultGeometry()
0415:                        .getEnvelopeInternal());
0416:                // ... first change
0417:                assertTrue(fr.hasNext());
0418:                f = fr.next();
0419:                assertEquals(new Long(2), f.getAttribute("revision"));
0420:                assertEquals("first change", f.getAttribute("message"));
0421:                assertEquals(
0422:                        roadFeatures[0].getDefaultGeometry().getEnvelope(), f
0423:                                .getDefaultGeometry().getEnvelope());
0424:                // ... second change
0425:                assertTrue(fr.hasNext());
0426:                f = fr.next();
0427:                assertEquals(new Long(3), f.getAttribute("revision"));
0428:                assertEquals("second change", f.getAttribute("message"));
0429:                assertEquals(
0430:                        roadFeatures[0].getDefaultGeometry().getEnvelope(), f
0431:                                .getDefaultGeometry().getEnvelope());
0432:                // finish
0433:                assertFalse(fr.hasNext());
0434:                fr.close();
0435:                t.close();
0436:
0437:                // no revision info, use last
0438:                Filter idFilter = ff.equals(ff.property("id"), ff.literal(1l));
0439:                q = new DefaultQuery("road", idFilter);
0440:                fr = ds.getFeatureReader(q, Transaction.AUTO_COMMIT);
0441:                // make sure the type is the same as if we were working against a non
0442:                // versioned datastore
0443:                assertEquals(originalFt, fr.getFeatureType());
0444:                assertTrue(fr.hasNext());
0445:                f = fr.next();
0446:                assertEquals("r1 rev 3", f.getAttribute("name"));
0447:                assertFalse(fr.hasNext());
0448:                fr.close();
0449:
0450:                // now extract revision 1
0451:                q = new DefaultQuery("road", idFilter);
0452:                q.setVersion("1");
0453:                fr = ds.getFeatureReader(q, Transaction.AUTO_COMMIT);
0454:                assertTrue(fr.hasNext());
0455:                f = fr.next();
0456:                assertEquals("r1", f.getAttribute("name"));
0457:                assertFalse(fr.hasNext());
0458:                fr.close();
0459:
0460:                // and now extract revision 2
0461:                q = new DefaultQuery("road", idFilter);
0462:                q.setVersion("2");
0463:                fr = ds.getFeatureReader(q, Transaction.AUTO_COMMIT);
0464:                assertTrue(fr.hasNext());
0465:                f = fr.next();
0466:                assertEquals("r1 rev 2", f.getAttribute("name"));
0467:                assertFalse(fr.hasNext());
0468:                fr.close();
0469:            }
0470:
0471:            public void testAppendFeatures() throws IOException,
0472:                    IllegalAttributeException {
0473:                VersionedPostgisDataStore ds = getDataStore();
0474:
0475:                // version enable road and river
0476:                ds
0477:                        .setVersioned("road", true, "gimbo",
0478:                                "version enabling roads");
0479:                ds.setVersioned("river", true, "gimbo",
0480:                        "version enabling river");
0481:
0482:                // create a transaction and append some features to both feature types
0483:                Transaction t = createTransaction("mambo",
0484:                        "Today I feel like adding fetures, yeah");
0485:                FeatureWriter fw = ds.getFeatureWriterAppend("road", t);
0486:                // ... new road
0487:                Feature f = fw.next();
0488:                f.setAttribute(0, new Integer(4));
0489:                f.setAttribute(1, line(new int[] { 3, 3, 4, 4, 5, 10 }));
0490:                f.setAttribute(2, "r4");
0491:                fw.write();
0492:                String rd4id = f.getID();
0493:                fw.close();
0494:                // ... new river
0495:                fw = ds.getFeatureWriterAppend("river", t);
0496:                f = fw.next();
0497:                f.setAttribute(0, new Integer(4));
0498:                f.setAttribute(1, lines(new int[][] { { 0, 0, 1, 10 } }));
0499:                f.setAttribute(2, "rv4");
0500:                f.setAttribute(3, new Double(6.5));
0501:                fw.write();
0502:                String rv4id = f.getID();
0503:                fw.close();
0504:                // ... end
0505:                t.commit();
0506:
0507:                // check features are there
0508:                // ... roads
0509:                DefaultQuery q = new DefaultQuery("road", ff.id(Collections
0510:                        .singleton(ff.featureId(rd4id))));
0511:                FeatureReader fr = ds.getFeatureReader(q, t);
0512:                assertTrue(fr.hasNext());
0513:                fr.close();
0514:                // ... rivers
0515:                q = new DefaultQuery("river", ff.id(Collections.singleton(ff
0516:                        .featureId(rv4id))));
0517:                fr = ds.getFeatureReader(q, t);
0518:                assertTrue(fr.hasNext());
0519:                fr.close();
0520:
0521:                // ok, now check we registered the modification to both tables in the
0522:                // same revision
0523:                assertEquals(3, ds.getLastRevision());
0524:                List types = Arrays
0525:                        .asList(ds.getModifiedFeatureTypes("2", "3"));
0526:                assertEquals(2, types.size());
0527:                assertTrue(types.contains("river"));
0528:                assertTrue(types.contains("road"));
0529:
0530:                // remember to close down the transaction
0531:                t.close();
0532:            }
0533:
0534:            /**
0535:             * The datastore used to choke on single point changes because the change bbox would be an
0536:             * invalid polygon. Plus the feature collection seems to ignore the version set in the query
0537:             * used to gather it
0538:             * 
0539:             * @throws Exception
0540:             */
0541:            public void testPointChange() throws Exception {
0542:                VersionedPostgisDataStore ds = getDataStore();
0543:
0544:                // version enable tree
0545:                ds.setVersioned("tree", true, "gimbo", "versioning trees");
0546:
0547:                // now create one feature
0548:                FeatureWriter fw = ds.getFeatureWriterAppend("tree",
0549:                        Transaction.AUTO_COMMIT);
0550:                assertFalse(fw.hasNext());
0551:                Feature f = fw.next();
0552:                f.setAttribute(0, gf.createPoint(new Coordinate(50, 50)));
0553:                f.setAttribute(1, "NewTreeOnTheBlock");
0554:                fw.write();
0555:                fw.close();
0556:            }
0557:
0558:            /**
0559:             * The datastore used to choke on single point changes because the change bbox would be an
0560:             * invalid polygon. Plus the feature collection seems to ignore the version set in the query
0561:             * used to gather it
0562:             * 
0563:             * @throws Exception
0564:             */
0565:            public void testFeatureSourceBounds() throws Exception {
0566:                VersionedPostgisDataStore ds = getDataStore();
0567:
0568:                // version enable tree
0569:                ds.setVersioned("tree", true, "gimbo", "versioning trees");
0570:
0571:                // now create one feature
0572:                FeatureWriter fw = ds.getFeatureWriter("tree",
0573:                        Transaction.AUTO_COMMIT);
0574:                assertTrue(fw.hasNext());
0575:                Feature f = fw.next();
0576:                Envelope oldBounds = f.getBounds();
0577:                f.setAttribute(0, gf.createPoint(new Coordinate(50, 50)));
0578:                fw.write();
0579:                fw.close();
0580:
0581:                // try to gather an old snapshot and check the bounds are really the old
0582:                // ones
0583:                DefaultQuery q = new DefaultQuery();
0584:                q.setVersion("1");
0585:                Envelope e = ds.getFeatureSource("tree").getBounds(q);
0586:                assertEquals(oldBounds, e);
0587:            }
0588:
0589:            public void testDeleteFeatures() throws IOException,
0590:                    NoSuchElementException, IllegalAttributeException {
0591:                VersionedPostgisDataStore ds = getDataStore();
0592:
0593:                // version enable road
0594:                ds
0595:                        .setVersioned("road", true, "gimbo",
0596:                                "version enabling stuff");
0597:
0598:                // build a filter to extract just road 1
0599:                Filter filter = ff.id(Collections.singleton(ff
0600:                        .featureId("road.rd1")));
0601:
0602:                // now delete one feature
0603:                Transaction t = createTransaction("gimbo", "first change");
0604:                FeatureWriter fw = ds.getFeatureWriter("road", filter, t);
0605:                assertTrue(fw.hasNext());
0606:                fw.next();
0607:                fw.remove();
0608:                fw.close();
0609:                t.commit();
0610:                t.close();
0611:
0612:                // and now see if it's still there
0613:                FeatureReader fr = ds.getFeatureReader(
0614:                        new DefaultQuery("road"), Transaction.AUTO_COMMIT);
0615:                while (fr.hasNext())
0616:                    assertFalse(fr.next().getID().equals("road.rd1"));
0617:                fr.close();
0618:            }
0619:
0620:            /**
0621:             * Versioned datastore broke if the same feature got updated twice in the same transaction
0622:             * (since it tried to create a new record at revions x, then expired it, and created another
0623:             * again at revision x).
0624:             * 
0625:             * @throws Exception
0626:             * 
0627:             */
0628:            public void testDoubleUpdate() throws Exception {
0629:                VersionedPostgisDataStore ds = getDataStore();
0630:
0631:                // version enable trees
0632:                ds
0633:                        .setVersioned("tree", true, "udig",
0634:                                "I like to doubly update things in the same transaction :-)");
0635:
0636:                // build a filter to extract just road 1
0637:                Filter filter = ff.id(Collections.singleton(ff
0638:                        .featureId("tree.1")));
0639:
0640:                // setup a transaction
0641:                Transaction t = createTransaction("gimbo", "double update");
0642:                FeatureStore store = (FeatureStore) ds.getFeatureSource("tree");
0643:                FeatureType treeSchema = ds.getSchema("tree");
0644:                store.setTransaction(t);
0645:                assertEquals(1, store.getFeatures(filter).size());
0646:                store.modifyFeatures(treeSchema.getAttributeType("name"),
0647:                        "update1", filter);
0648:                store.modifyFeatures(treeSchema.getAttributeType("name"),
0649:                        "update2", filter);
0650:                t.commit();
0651:
0652:                // make sure the second update is the one that went in
0653:                FeatureCollection fc = store.getFeatures(filter);
0654:                FeatureIterator fi = fc.features();
0655:                assertTrue(fi.hasNext());
0656:                Feature f = fi.next();
0657:                assertEquals("update2", f.getAttribute("name"));
0658:                assertFalse(fi.hasNext());
0659:                fi.close();
0660:                t.close();
0661:            }
0662:
0663:            /**
0664:             * Check insert/delete in the same transaction works
0665:             * 
0666:             * @throws Exception
0667:             * 
0668:             */
0669:            public void testInsertDelete() throws Exception {
0670:                VersionedPostgisDataStore ds = getDataStore();
0671:
0672:                // version enable trees
0673:                ds.setVersioned("tree", true, "gimbo",
0674:                        "What do you want, I'm undecided...");
0675:
0676:                // create a new feature
0677:                Feature tree = treeType.create(new Object[] {
0678:                        gf.createPoint(new Coordinate(7, 7)), "SmallPine" },
0679:                        "tree.tr2");
0680:
0681:                // setup a transaction
0682:                Transaction t = createTransaction("gimbo", "double update");
0683:                FeatureStore store = (FeatureStore) ds.getFeatureSource("tree");
0684:                store.setTransaction(t);
0685:                Set ids = store.addFeatures(DataUtilities.collection(tree));
0686:                Filter filter = ff.id(Collections.singleton(ff
0687:                        .featureId((String) ids.iterator().next())));
0688:                store.removeFeatures(filter);
0689:                t.commit();
0690:
0691:                // check it's not there
0692:                assertEquals(0, store.getFeatures(filter).size());
0693:                t.close();
0694:            }
0695:
0696:            /**
0697:             * Same as double update, but for the insert/update case
0698:             * 
0699:             * @throws Exception
0700:             * 
0701:             */
0702:            public void testInsertUpdate() throws Exception {
0703:                VersionedPostgisDataStore ds = getDataStore();
0704:
0705:                // version enable trees
0706:                ds.setVersioned("tree", true, "gimbo",
0707:                        "What do you want, I'm undecided...");
0708:
0709:                // create a new feature
0710:                Feature tree = treeType.create(new Object[] {
0711:                        gf.createPoint(new Coordinate(7, 7)), "SmallPine" },
0712:                        "tree.tr2");
0713:
0714:                // setup a transaction
0715:                Transaction t = createTransaction("gimbo", "double update");
0716:                FeatureType treeSchema = ds.getSchema("tree");
0717:                FeatureStore store = (FeatureStore) ds.getFeatureSource("tree");
0718:                store.setTransaction(t);
0719:                Set ids = store.addFeatures(DataUtilities.collection(tree));
0720:                Filter filter = ff.id(Collections.singleton(ff
0721:                        .featureId((String) ids.iterator().next())));
0722:                assertEquals(1, store.getFeatures(filter).size());
0723:                store.modifyFeatures(treeSchema.getAttributeType("name"),
0724:                        "update1", filter);
0725:                t.commit();
0726:                t.close();
0727:            }
0728:
0729:            public void testSerialIdWriting() throws IOException,
0730:                    IllegalArgumentException, IllegalAttributeException {
0731:                VersionedPostgisDataStore ds = getDataStore();
0732:                ds
0733:                        .setVersioned("rail", true, "mambo",
0734:                                "Version enabling rails");
0735:
0736:                Transaction t = createTransaction("serial",
0737:                        "Feature modification");
0738:                FeatureWriter fw = ds.getFeatureWriter("rail", Filter.INCLUDE,
0739:                        t);
0740:                assertTrue(fw.hasNext());
0741:                Feature f = fw.next();
0742:                f.setDefaultGeometry(line(new int[] { 0, 0, -10, -10 }));
0743:                fw.write();
0744:                fw.close();
0745:                t.commit();
0746:
0747:                fw = ds.getFeatureWriterAppend("rail", t);
0748:                f = fw.next();
0749:                f.setDefaultGeometry(line(new int[] { -10, -10, -20, -10 }));
0750:                fw.write();
0751:                assertEquals("rail.2", f.getID());
0752:                fw.close();
0753:                t.commit();
0754:
0755:                fw = ds.getFeatureWriter("rail", ff.id(Collections.singleton(ff
0756:                        .featureId("rail.1"))), t);
0757:                assertTrue(fw.hasNext());
0758:                f = fw.next();
0759:                fw.remove();
0760:                fw.close();
0761:                t.commit();
0762:                t.close();
0763:            }
0764:
0765:            public void testPlainModifiedIds() throws IOException,
0766:                    IllegalAttributeException {
0767:                VersionedPostgisDataStore ds = getDataStore();
0768:                String newId = buildRiverHistory();
0769:
0770:                // check modified feature types are the proper ones
0771:                // full history
0772:                String[] modifiedTypes = ds.getModifiedFeatureTypes("1", null);
0773:                assertEquals(1, modifiedTypes.length);
0774:                assertEquals("river", modifiedTypes[0]);
0775:
0776:                // get features modified in first revisions, without filters
0777:                Transaction ac = Transaction.AUTO_COMMIT;
0778:                // ... all history
0779:                ModifiedFeatureIds mfids = ds.getModifiedFeatureFIDs("river",
0780:                        "1", "5", Filter.INCLUDE, null, ac);
0781:                assertEquals(1, mfids.getCreated().size());
0782:                assertEquals(1, mfids.getDeleted().size());
0783:                assertEquals(1, mfids.getModified().size());
0784:                assertTrue(mfids.getCreated().contains(newId));
0785:                assertTrue(mfids.getDeleted().contains("river.rv2"));
0786:                assertTrue(mfids.getModified().contains("river.rv1"));
0787:                // ... just first modification
0788:                mfids = ds.getModifiedFeatureFIDs("river", "1", "2",
0789:                        Filter.INCLUDE, null, ac);
0790:                assertEquals(0, mfids.getCreated().size());
0791:                assertEquals(0, mfids.getDeleted().size());
0792:                assertEquals(2, mfids.getModified().size());
0793:                assertTrue(mfids.getModified().contains("river.rv1"));
0794:                assertTrue(mfids.getModified().contains("river.rv2"));
0795:                // ... just second one
0796:                mfids = ds.getModifiedFeatureFIDs("river", "2", "3",
0797:                        Filter.INCLUDE, null, ac);
0798:                assertEquals(0, mfids.getCreated().size());
0799:                assertEquals(0, mfids.getDeleted().size());
0800:                assertEquals(1, mfids.getModified().size());
0801:                assertTrue(mfids.getModified().contains("river.rv2"));
0802:                // ... just creation and deletion
0803:                mfids = ds.getModifiedFeatureFIDs("river", "3", "5",
0804:                        Filter.INCLUDE, null, ac);
0805:                assertEquals(1, mfids.getCreated().size());
0806:                assertEquals(1, mfids.getDeleted().size());
0807:                assertEquals(0, mfids.getModified().size());
0808:                assertTrue(mfids.getCreated().contains(newId));
0809:                assertTrue(mfids.getDeleted().contains("river.rv2"));
0810:                // ... a non existent one
0811:                mfids = ds.getModifiedFeatureFIDs("river", "10", "11",
0812:                        Filter.INCLUDE, null, ac);
0813:                assertEquals(0, mfids.getCreated().size());
0814:                assertEquals(0, mfids.getDeleted().size());
0815:                assertEquals(0, mfids.getModified().size());
0816:
0817:                // now check with some filters too
0818:                // ... a fid one
0819:                Filter fidFilter = ff.id(Collections.singleton(ff
0820:                        .featureId("river.rv1")));
0821:                mfids = ds.getModifiedFeatureFIDs("river", "1", "3", fidFilter,
0822:                        null, ac);
0823:                assertEquals(0, mfids.getCreated().size());
0824:                assertEquals(0, mfids.getDeleted().size());
0825:                assertEquals(1, mfids.getModified().size());
0826:                assertTrue(mfids.getModified().contains("river.rv1"));
0827:                // ... a bbox one
0828:                Filter bboxFilter = ff.bbox("geom", 100, 100, 300, 300, null);
0829:                mfids = ds.getModifiedFeatureFIDs("river", "1", "3",
0830:                        bboxFilter, null, ac);
0831:                assertEquals(0, mfids.getCreated().size());
0832:                assertEquals(0, mfids.getDeleted().size());
0833:                assertEquals(1, mfids.getModified().size());
0834:                assertTrue(mfids.getModified().contains("river.rv2"));
0835:                // ... a non encodable one, matching
0836:                Filter roundedFlowFilter = ff.equals(ff.function("ceil", ff
0837:                        .property("flow")), ff.literal(10));
0838:                mfids = ds.getModifiedFeatureFIDs("river", "1", "3",
0839:                        roundedFlowFilter, null, ac);
0840:                assertEquals(0, mfids.getCreated().size());
0841:                assertEquals(0, mfids.getDeleted().size());
0842:                assertEquals(1, mfids.getModified().size());
0843:                assertTrue(mfids.getModified().contains("river.rv1"));
0844:                // ... same filter, but feature not modified in those revisions
0845:                mfids = ds.getModifiedFeatureFIDs("river", "2", "3",
0846:                        roundedFlowFilter, null, ac);
0847:                assertEquals(0, mfids.getCreated().size());
0848:                assertEquals(0, mfids.getDeleted().size());
0849:                assertEquals(0, mfids.getModified().size());
0850:                // ... a non encodable one, not matching
0851:                Filter roundedFlowFilter2 = ff.equals(ff.function("ceil", ff
0852:                        .property("flow")), ff.literal(11));
0853:                mfids = ds.getModifiedFeatureFIDs("river", "1", "3",
0854:                        roundedFlowFilter2, null, ac);
0855:                assertEquals(0, mfids.getCreated().size());
0856:                assertEquals(0, mfids.getDeleted().size());
0857:                assertEquals(0, mfids.getModified().size());
0858:            }
0859:
0860:            public void testUserModifiedIds() throws IOException,
0861:                    IllegalAttributeException {
0862:                VersionedPostgisDataStore ds = getDataStore();
0863:                String newId = buildRiverHistory();
0864:
0865:                // check modified feature types are the proper ones
0866:                // full history
0867:                String[] modifiedTypes = ds.getModifiedFeatureTypes("1", null);
0868:                assertEquals(1, modifiedTypes.length);
0869:                assertEquals("river", modifiedTypes[0]);
0870:
0871:                // get features modified in first revisions, without filters
0872:                Transaction ac = Transaction.AUTO_COMMIT;
0873:                // ... all history, all users
0874:                ModifiedFeatureIds mfids = ds.getModifiedFeatureFIDs("river",
0875:                        "1", "5", Filter.INCLUDE, new String[] { "lamb",
0876:                                "trout" }, ac);
0877:                assertEquals(1, mfids.getCreated().size());
0878:                assertEquals(1, mfids.getDeleted().size());
0879:                assertEquals(1, mfids.getModified().size());
0880:                // ... just first modification, but with the wrong user
0881:                mfids = ds.getModifiedFeatureFIDs("river", "1", "2",
0882:                        Filter.INCLUDE, new String[] { "trout" }, ac);
0883:                assertEquals(0, mfids.getCreated().size());
0884:                assertEquals(0, mfids.getDeleted().size());
0885:                assertEquals(0, mfids.getModified().size());
0886:                // ... again the first modification, right user this time
0887:                mfids = ds.getModifiedFeatureFIDs("river", "1", "2",
0888:                        Filter.INCLUDE, new String[] { "lamb" }, ac);
0889:                assertEquals(0, mfids.getCreated().size());
0890:                assertEquals(0, mfids.getDeleted().size());
0891:                assertEquals(2, mfids.getModified().size());
0892:                // ... let's see what trout did between 1 and 4
0893:                mfids = ds.getModifiedFeatureFIDs("river", "1", "4",
0894:                        Filter.INCLUDE, new String[] { "trout" }, ac);
0895:                assertEquals(0, mfids.getCreated().size());
0896:                assertEquals(0, mfids.getDeleted().size());
0897:                assertEquals(1, mfids.getModified().size());
0898:                assertTrue(mfids.getModified().contains("river.rv2"));
0899:            }
0900:
0901:            public void testModifiedIdsUnversioned() throws IOException,
0902:                    IllegalAttributeException {
0903:                VersionedPostgisDataStore ds = getDataStore();
0904:
0905:                // check we get no modifications out of an unversioned feature type
0906:                ModifiedFeatureIds mfids = ds
0907:                        .getModifiedFeatureFIDs("river", "1", "5",
0908:                                Filter.INCLUDE, null, Transaction.AUTO_COMMIT);
0909:                assertTrue(mfids.getCreated().isEmpty());
0910:                assertTrue(mfids.getDeleted().isEmpty());
0911:                assertTrue(mfids.getModified().isEmpty());
0912:            }
0913:
0914:            public void testRollbackDeleted() throws IOException,
0915:                    IllegalAttributeException {
0916:                VersionedPostgisDataStore ds = getDataStore();
0917:                buildRiverHistory();
0918:
0919:                Filter rv2Filter = ff.id(Collections.singleton(ff
0920:                        .featureId("river.rv2")));
0921:                FeatureReader fr = ds.getFeatureReader(new DefaultQuery(
0922:                        "river", rv2Filter), Transaction.AUTO_COMMIT);
0923:                assertFalse(fr.hasNext());
0924:                fr.close();
0925:
0926:                // try to rollback to revision 4, that is, rollback last deletion
0927:                Transaction t = createTransaction("Mambo",
0928:                        "Gimbo, what did you do? "
0929:                                + "Now I have to rollback your changes!");
0930:                VersionedPostgisFeatureStore fs = (VersionedPostgisFeatureStore) ds
0931:                        .getFeatureSource("river");
0932:                fs.setTransaction(t);
0933:                fs.rollback("4", Filter.INCLUDE, null);
0934:                t.commit();
0935:
0936:                // now check rv2 is again there
0937:                fr = ds.getFeatureReader(new DefaultQuery("river", rv2Filter),
0938:                        Transaction.AUTO_COMMIT);
0939:                assertTrue(fr.hasNext());
0940:                fr.close();
0941:                assertEquals(3, fs.getFeatures(Filter.INCLUDE).size());
0942:                t.close();
0943:            }
0944:
0945:            public void testRollbackCreatedDeleted() throws IOException,
0946:                    IllegalAttributeException {
0947:                VersionedPostgisDataStore ds = getDataStore();
0948:                String newId = buildRiverHistory();
0949:
0950:                // try to rollback to revision 3, that is, rollback last deletion and
0951:                // creation
0952:                Transaction t = createTransaction("Mambo",
0953:                        "Gimbo, what did you do? "
0954:                                + "Now I have to rollback your changes!");
0955:                VersionedPostgisFeatureStore fs = (VersionedPostgisFeatureStore) ds
0956:                        .getFeatureSource("river");
0957:                fs.setTransaction(t);
0958:                fs.rollback("3", Filter.INCLUDE, null);
0959:                t.commit();
0960:
0961:                // now check rv2 is again there
0962:                Filter rv2Filter = ff.id(Collections.singleton(ff
0963:                        .featureId("river.rv2")));
0964:                Filter newFilter = ff.id(Collections.singleton(ff
0965:                        .featureId(newId)));
0966:                FeatureReader fr = ds.getFeatureReader(new DefaultQuery(
0967:                        "river", rv2Filter), Transaction.AUTO_COMMIT);
0968:                assertTrue(fr.hasNext());
0969:                fr.close();
0970:                fr = ds.getFeatureReader(new DefaultQuery("river", newFilter),
0971:                        Transaction.AUTO_COMMIT);
0972:                assertFalse(fr.hasNext());
0973:                fr.close();
0974:                assertEquals(2, fs.getFeatures(Filter.INCLUDE).size());
0975:
0976:                t.close();
0977:            }
0978:
0979:            public void testRollbackAll() throws IOException,
0980:                    IllegalAttributeException {
0981:                VersionedPostgisDataStore ds = getDataStore();
0982:                buildRiverHistory();
0983:
0984:                // try to rollback to revision 3, that is, rollback last deletion and
0985:                // creation
0986:                Transaction t = createTransaction("Mambo",
0987:                        "Gimbo, what did you do? "
0988:                                + "Now I have to rollback your changes!");
0989:                VersionedPostgisFeatureStore fs = (VersionedPostgisFeatureStore) ds
0990:                        .getFeatureSource("river");
0991:                fs.setTransaction(t);
0992:                fs.rollback("1", Filter.INCLUDE, null);
0993:                t.commit();
0994:
0995:                // now check river features are just like at the beginning
0996:                FeatureCollection fc = fs.getFeatures();
0997:                assertEquals(riverFeatures.length, fc.size());
0998:                for (int i = 0; i < riverFeatures.length; i++) {
0999:                    assertTrue(fc.contains(riverFeatures[i]));
1000:                }
1001:                t.close();
1002:            }
1003:
1004:            public void testRollbackUserChanges() throws IOException,
1005:                    IllegalAttributeException {
1006:                VersionedPostgisDataStore ds = getDataStore();
1007:                buildRiverHistory();
1008:
1009:                // try to rollback to revision 3, that is, rollback last deletion and
1010:                // creation
1011:                Transaction t = createTransaction("Lamb",
1012:                        "Trout, what did you do? "
1013:                                + "Now I have to rollback your changes!");
1014:                VersionedPostgisFeatureStore fs = (VersionedPostgisFeatureStore) ds
1015:                        .getFeatureSource("river");
1016:                fs.setTransaction(t);
1017:                fs.rollback("1", Filter.INCLUDE, new String[] { "trout" });
1018:                t.commit();
1019:
1020:                // now check that rv2 is again there an equal to the original, rv3 has not rolled back
1021:                // and rv1 is still modified
1022:                FeatureCollection fc = fs.getFeatures();
1023:                assertEquals(riverFeatures.length + 1, fc.size());
1024:                assertTrue(fc.contains(riverFeatures[1]));
1025:                FeatureIterator fi = fc.features();
1026:                while (fi.hasNext()) {
1027:                    Feature f = fi.next();
1028:                    if (f.getID().equals("river.rv1"))
1029:                        assertFalse(f.equals(riverFeatures[1]));
1030:                    else if (f.getID().equals("river.rv2"))
1031:                        assertEquals(riverFeatures[1], f);
1032:                    else
1033:                        assertEquals(new Integer(3), f.getAttribute("id"));
1034:                }
1035:                fi.close();
1036:                t.close();
1037:            }
1038:
1039:            public void testVolatilePk() throws IOException,
1040:                    IllegalAttributeException {
1041:                VersionedPostgisDataStore ds = getDataStore();
1042:
1043:                assertTrue(ds.getFeatureSource("river") instanceof  FeatureLocking);
1044:                assertFalse(ds.getFeatureSource("nopk") instanceof  FeatureLocking);
1045:            }
1046:
1047:            public void testFeatureStoreUnversioned() throws IOException,
1048:                    IllegalAttributeException {
1049:                VersionedPostgisDataStore ds = getDataStore();
1050:
1051:                // try to get a feature store for an unversioned type, it should be a
1052:                // plain feature store
1053:                // not the versioned one
1054:                FeatureStore fs = (FeatureStore) ds.getFeatureSource("river");
1055:                assertFalse(fs instanceof  VersionedPostgisFeatureStore);
1056:            }
1057:
1058:            public void testLog() throws IOException, IllegalAttributeException {
1059:                VersionedPostgisDataStore ds = getDataStore();
1060:                String newId = buildRiverHistory();
1061:                VersionedPostgisFeatureStore fs = (VersionedPostgisFeatureStore) ds
1062:                        .getFeatureSource("river");
1063:
1064:                // get log only for newly created features
1065:                Filter newIdFilter = ff.id(Collections.singleton(ff
1066:                        .featureId(newId)));
1067:                FeatureCollection fc = fs.getLog("1", "5", newIdFilter, null,
1068:                        -1);
1069:                assertEquals(1, fc.size());
1070:                FeatureIterator it = fc.features();
1071:                Feature f = it.next();
1072:                assertEquals("changesets.4", f.getID());
1073:                assertEquals("lamb", f.getAttribute("author"));
1074:                assertEquals("third change", f.getAttribute("message"));
1075:                it.close();
1076:
1077:                // get log for rv2 (most modified)
1078:                Filter rv2IdFilter = ff.id(Collections.singleton(ff
1079:                        .featureId("river.rv2")));
1080:                fc = fs.getLog("1", "5", rv2IdFilter, null, -1);
1081:                assertEquals(3, fc.size());
1082:                it = fc.features();
1083:                f = it.next();
1084:                assertEquals(new Long(5), f.getAttribute("revision"));
1085:                assertEquals("trout", f.getAttribute("author"));
1086:                assertEquals("fourth change", f.getAttribute("message"));
1087:                f = it.next();
1088:                assertEquals(new Long(3), f.getAttribute("revision"));
1089:                assertEquals("trout", f.getAttribute("author"));
1090:                assertEquals("second change", f.getAttribute("message"));
1091:                f = it.next();
1092:                assertEquals(new Long(2), f.getAttribute("revision"));
1093:                assertEquals("lamb", f.getAttribute("author"));
1094:                assertEquals("first change", f.getAttribute("message"));
1095:                it.close();
1096:
1097:                // get log for rv1
1098:                Filter rv1IdFilter = ff.id(Collections.singleton(ff
1099:                        .featureId("river.rv1")));
1100:                fc = fs.getLog("1", "5", rv1IdFilter, null, -1);
1101:                assertEquals(1, fc.size());
1102:                it = fc.features();
1103:                f = it.next();
1104:                assertEquals("changesets.2", f.getID());
1105:                assertEquals("lamb", f.getAttribute("author"));
1106:                assertEquals("first change", f.getAttribute("message"));
1107:                it.close();
1108:
1109:                // make sure the symbolic names for feature versions do work
1110:                fc = fs.getLog("FIRST", "LAST", Filter.INCLUDE, null, -1);
1111:                assertEquals(4, fc.size());
1112:
1113:                // make sure the old way to specify the current version works too
1114:                fc = fs.getLog("FIRST", "CURRENT", Filter.INCLUDE, null, -1);
1115:                assertEquals(4, fc.size());
1116:
1117:                // make sure maxRows works
1118:                fc = fs.getLog("FIRST", "LAST", Filter.INCLUDE, null, 1);
1119:                assertEquals(1, fc.size());
1120:
1121:                // try out with an inverted sequence and see if we get an inverted log order
1122:                fc = fs.getLog("LAST", "FIRST", Filter.INCLUDE, null, -1);
1123:                assertEquals(4, fc.size());
1124:                it = fc.features();
1125:                f = it.next();
1126:                long r1 = ((Long) f.getAttribute("revision")).longValue();
1127:                f = it.next();
1128:                long r2 = ((Long) f.getAttribute("revision")).longValue();
1129:                assertTrue(r1 < r2);
1130:                it.close();
1131:            }
1132:
1133:            public void testDiff() throws IOException,
1134:                    IllegalAttributeException {
1135:                VersionedPostgisDataStore ds = getDataStore();
1136:                buildRiverHistory();
1137:                VersionedPostgisFeatureStore fs = (VersionedPostgisFeatureStore) ds
1138:                        .getFeatureSource("river");
1139:
1140:                // forward, deletion changeset
1141:                FeatureDiffReader fdr = fs.getDifferences("4", "5",
1142:                        Filter.INCLUDE, null);
1143:                assertEquals(fs.getSchema(), fdr.getSchema());
1144:                assertTrue(fdr.hasNext());
1145:                FeatureDiff diff = fdr.next();
1146:                assertEquals("river.rv2", diff.getID());
1147:                assertEquals(FeatureDiff.DELETED, diff.getState());
1148:                assertFalse(fdr.hasNext());
1149:                fdr.close();
1150:
1151:                // same changeset, but backwards
1152:                fdr = fs.getDifferences("5", "4", Filter.INCLUDE, null);
1153:                assertEquals(fs.getSchema(), fdr.getSchema());
1154:                assertTrue(fdr.hasNext());
1155:                diff = fdr.next();
1156:                assertEquals("river.rv2", diff.getID());
1157:                assertEquals(FeatureDiff.INSERTED, diff.getState());
1158:                assertEquals("rv2 v3", diff.getFeature().getAttribute("river"));
1159:                assertEquals(new Double(3.0), diff.getFeature().getAttribute(
1160:                        "flow"));
1161:                // ... can't compare directly, they have different geometry factories
1162:                // (afaik)
1163:                assertTrue(DataUtilities.attributesEqual(lines(new int[][] { {
1164:                        200, 200, 120, 120 } }), diff.getFeature()
1165:                        .getDefaultGeometry()));
1166:                assertFalse(fdr.hasNext());
1167:                fdr.close();
1168:
1169:                // forward diff, two modifications on changeset 1-2, and check reader reset while
1170:                // you're at it
1171:                fdr = fs.getDifferences("1", "2", Filter.INCLUDE, null);
1172:                for (int i = 0; i < 2; i++) {
1173:                    fdr.reset();
1174:                    assertEquals(fs.getSchema(), fdr.getSchema());
1175:                    Set ids = new HashSet(Arrays.asList(new String[] {
1176:                            "river.rv1", "river.rv2" }));
1177:                    assertTrue(fdr.hasNext());
1178:                    while (fdr.hasNext()) {
1179:                        diff = fdr.next();
1180:                        assertTrue("Unexpected id: " + diff.getID(), ids
1181:                                .remove(diff.getID()));
1182:                        assertEquals("1", fdr.getFromVersion());
1183:                        assertEquals("2", fdr.getToVersion());
1184:                        assertEquals(FeatureDiff.UPDATED, diff.state);
1185:                        if (diff.getID().equals("river.rv1")) {
1186:                            assertEquals(2, diff.getChangedAttributes().size());
1187:                            assertTrue(diff.getChangedAttributes().contains(
1188:                                    "river"));
1189:                            assertTrue(diff.getChangedAttributes().contains(
1190:                                    "flow"));
1191:                            assertEquals("rv1 v2", diff.getFeature()
1192:                                    .getAttribute("river"));
1193:                            assertEquals(new Double(9.6), diff.getFeature()
1194:                                    .getAttribute("flow"));
1195:                        } else {
1196:                            assertEquals(2, diff.getChangedAttributes().size());
1197:                            assertEquals("rv2 v2", diff.getFeature()
1198:                                    .getAttribute("river"));
1199:                            assertTrue(DataUtilities
1200:                                    .attributesEqual(lines(new int[][] { { 100,
1201:                                            100, 120, 120 } }), diff
1202:                                            .getFeature().getAttribute("geom")));
1203:                        }
1204:                    }
1205:                }
1206:                fdr.close();
1207:
1208:                // forward diff on creation
1209:                fdr = fs.getDifferences("3", "4", Filter.INCLUDE, null);
1210:                assertEquals(fs.getSchema(), fdr.getSchema());
1211:                assertTrue(fdr.hasNext());
1212:                diff = fdr.next();
1213:                assertEquals(FeatureDiff.INSERTED, diff.getState());
1214:                assertEquals(fs.getSchema(), diff.getFeature().getFeatureType());
1215:                assertFalse(fdr.hasNext());
1216:                fdr.close();
1217:            }
1218:
1219:            /**
1220:             * Create history, rollback it, diff used to report changes anyways
1221:             * @throws IOException 
1222:             * @throws IllegalAttributeException 
1223:             */
1224:            public void testRollbackDiff() throws IOException,
1225:                    IllegalAttributeException {
1226:                VersionedPostgisDataStore ds = getDataStore();
1227:                buildRiverHistory();
1228:
1229:                // try to rollback to revision 1, that is, rollback everything
1230:                Transaction t = createTransaction("Mambo",
1231:                        "Restarting the world");
1232:                VersionedPostgisFeatureStore fs = (VersionedPostgisFeatureStore) ds
1233:                        .getFeatureSource("river");
1234:                fs.setTransaction(t);
1235:                fs.rollback("1", Filter.INCLUDE, null);
1236:                t.commit();
1237:
1238:                // now extract a diff between current revision and the last one
1239:                FeatureDiffReader reader = fs.getDifferences("1", null, null,
1240:                        null);
1241:                assertFalse(reader.hasNext());
1242:                reader.close();
1243:                t.close();
1244:            }
1245:
1246:            public void testVersionedCollection() throws Exception {
1247:                VersionedPostgisDataStore ds = getDataStore();
1248:                buildRiverHistory();
1249:
1250:                VersioningFeatureSource fs = (VersioningFeatureSource) ds
1251:                        .getFeatureSource("river");
1252:                // smoke test, can we get it?
1253:                FeatureCollection vfc = fs.getVersionedFeatures();
1254:                FeatureCollection fc = fs.getFeatures();
1255:                assertEquals(vfc.size(), fc.size());
1256:                final int vfcAttributesCount = vfc.getSchema()
1257:                        .getAttributeCount();
1258:                assertEquals(fc.getSchema().getAttributeCount() + 8,
1259:                        vfcAttributesCount);
1260:                assertEquals("creationVersion", vfc.getSchema()
1261:                        .getAttributeType(0).getLocalName());
1262:                assertEquals("createdBy", vfc.getSchema().getAttributeType(1)
1263:                        .getLocalName());
1264:                assertEquals("creationDate", vfc.getSchema()
1265:                        .getAttributeType(2).getLocalName());
1266:                assertEquals("creationMessage", vfc.getSchema()
1267:                        .getAttributeType(3).getLocalName());
1268:                assertEquals("lastUpdateVersion", vfc.getSchema()
1269:                        .getAttributeType(4).getLocalName());
1270:                assertEquals("lastUpdatedBy", vfc.getSchema().getAttributeType(
1271:                        5).getLocalName());
1272:                assertEquals("lastUpdateDate", vfc.getSchema()
1273:                        .getAttributeType(6).getLocalName());
1274:                assertEquals("lastUpdateMessage", vfc.getSchema()
1275:                        .getAttributeType(7).getLocalName());
1276:                final FeatureIterator vfr = vfc.features();
1277:                final FeatureIterator fr = fc.features();
1278:                final Feature vf = vfr.next();
1279:                final Feature f = fr.next();
1280:                vfr.close();
1281:                fr.close();
1282:                assertEquals(fc.getSchema().getTypeName(), vfc.getSchema()
1283:                        .getTypeName());
1284:                assertEquals(f.getFeatureType().getTypeName(), vf
1285:                        .getFeatureType().getTypeName());
1286:                assertEquals(vfcAttributesCount, vfc.getSchema()
1287:                        .getAttributeCount());
1288:                assertEquals(f.getID(), vf.getID());
1289:                for (int i = 0; i < f.getFeatureType().getAttributeCount(); i++) {
1290:                    assertTrue(DataUtilities.attributesEqual(f.getAttribute(i),
1291:                            vf.getAttribute(i + 8)));
1292:                }
1293:            }
1294:
1295:            public void testReprojectedVersionedCollection() throws Exception {
1296:                VersionedPostgisDataStore ds = getDataStore();
1297:                ds
1298:                        .setVersioned("rail", true, "mambo",
1299:                                "version enabling stuff");
1300:
1301:                VersioningFeatureSource fs = (VersioningFeatureSource) ds
1302:                        .getFeatureSource("rail");
1303:                DefaultQuery dq = new DefaultQuery();
1304:                final CoordinateReferenceSystem epsg3003 = CRS
1305:                        .decode("EPSG:3003");
1306:                dq.setCoordinateSystemReproject(epsg3003);
1307:                FeatureCollection fc = fs.getVersionedFeatures(dq);
1308:                assertEquals(epsg3003, fc.getSchema().getDefaultGeometry()
1309:                        .getCoordinateSystem());
1310:            }
1311:
1312:            public void testMissingVersionedCollection() throws Exception {
1313:                VersionedPostgisDataStore ds = getDataStore();
1314:                buildRiverHistory();
1315:
1316:                // drop the versioning collection view to make the db in the
1317:                // same condition as an old db
1318:                Connection conn = null;
1319:                Statement st = null;
1320:                try {
1321:                    conn = pool.getConnection();
1322:                    st = conn.createStatement();
1323:                    st.execute("drop view river_vfc_view");
1324:                } catch (Exception e) {
1325:
1326:                }
1327:
1328:                VersioningFeatureSource fs = (VersioningFeatureSource) ds
1329:                        .getFeatureSource("river");
1330:                // now, will the datastore create the view on the fly?
1331:                FeatureCollection vfc = fs.getVersionedFeatures();
1332:                FeatureCollection fc = fs.getFeatures();
1333:                assertEquals(vfc.size(), fc.size());
1334:                assertEquals(vfc.getSchema().getDefaultGeometry(), fc
1335:                        .getSchema().getDefaultGeometry());
1336:            }
1337:
1338:            public void testVersionedCollectionFidFilter() throws Exception {
1339:                VersionedPostgisDataStore ds = getDataStore();
1340:                buildRiverHistory();
1341:
1342:                // drop the versioning collection view to make the db in the
1343:                // same condition as an old db
1344:                Connection conn = null;
1345:                Statement st = null;
1346:                try {
1347:                    conn = pool.getConnection();
1348:                    st = conn.createStatement();
1349:                    st.execute("drop view river_vfc_view");
1350:                } catch (Exception e) {
1351:
1352:                }
1353:
1354:                VersioningFeatureSource fs = (VersioningFeatureSource) ds
1355:                        .getFeatureSource("river");
1356:                final Id fidFilter = ff.id(Collections.singleton(ff
1357:                        .featureId("river.rv1")));
1358:                FeatureCollection vfc = fs.getVersionedFeatures(fidFilter);
1359:                FeatureCollection fc = fs.getFeatures(fidFilter);
1360:                assertEquals(vfc.size(), fc.size());
1361:                assertEquals(1, vfc.size());
1362:            }
1363:
1364:            /**
1365:             * Version enables rivers
1366:             * 
1367:             * @param ds
1368:             * @return
1369:             * @throws IOException
1370:             * @throws IllegalAttributeException
1371:             */
1372:            protected String buildRiverHistory() throws IOException,
1373:                    IllegalAttributeException {
1374:                VersionedPostgisDataStore ds = getDataStore();
1375:                ds.setVersioned("river", true, "mambo",
1376:                        "version enabling stuff");
1377:
1378:                // revision 2), modify two elements, rv1 and rv2
1379:                Transaction t = createTransaction("lamb", "first change");
1380:                FeatureWriter fw = ds.getFeatureWriter("river", Filter.INCLUDE,
1381:                        t);
1382:                while (fw.hasNext()) {
1383:                    Feature f = fw.next();
1384:                    if (f.getID().equals("river.rv1")) {
1385:                        f.setAttribute("river", "rv1 v2");
1386:                        f.setAttribute("flow", new Double(9.6));
1387:                    } else {
1388:                        f.setAttribute("river", "rv2 v2");
1389:                        f.setAttribute("geom", lines(new int[][] { { 100, 100,
1390:                                120, 120 } }));
1391:                    }
1392:                    fw.write();
1393:                }
1394:                fw.close();
1395:                t.commit();
1396:                t.close();
1397:
1398:                // revision 3) modify just one, rv2
1399:                t = createTransaction("trout", "second change");
1400:                fw = ds.getFeatureWriter("river", Filter.INCLUDE, t);
1401:                while (fw.hasNext()) {
1402:                    Feature f = fw.next();
1403:                    if (f.getID().equals("river.rv2")) {
1404:                        f.setAttribute("river", "rv2 v3");
1405:                        f.setAttribute("geom", lines(new int[][] { { 200, 200,
1406:                                120, 120 } }));
1407:                    }
1408:                    fw.write();
1409:                }
1410:                fw.close();
1411:                t.commit();
1412:                t.close();
1413:
1414:                // revision 4) create a new feature, rv3
1415:                t = createTransaction("lamb", "third change");
1416:                fw = ds.getFeatureWriterAppend("river", t);
1417:                Feature f = fw.next();
1418:                f.setAttribute("id", new Integer(3));
1419:                f.setAttribute("geom",
1420:                        lines(new int[][] { { 300, 300, 301, 301 } }));
1421:                f.setAttribute("river", "rv2 v3");
1422:                f.setAttribute("flow", new Double(12.2));
1423:                fw.write();
1424:                String newId = f.getID();
1425:                fw.close();
1426:                t.commit();
1427:                t.close();
1428:
1429:                // revision 5), delete river rv2
1430:                t = createTransaction("trout", "fourth change");
1431:                fw = ds.getFeatureWriter("river", Filter.INCLUDE, t);
1432:                while (fw.hasNext()) {
1433:                    f = fw.next();
1434:                    if (f.getID().equals("river.rv2")) {
1435:                        fw.remove();
1436:                    } else {
1437:                        fw.write();
1438:                    }
1439:                }
1440:                fw.close();
1441:                t.commit();
1442:                t.close();
1443:                return newId;
1444:            }
1445:
1446:            private Transaction createTransaction(String author, String message)
1447:                    throws IOException {
1448:                Transaction t = new DefaultTransaction();
1449:                t.putProperty(VersionedPostgisDataStore.AUTHOR, author);
1450:                t.putProperty(VersionedPostgisDataStore.MESSAGE, message);
1451:                return t;
1452:            }
1453:
1454:            public static void main(String[] args) {
1455:                junit.textui.TestRunner runner = new junit.textui.TestRunner();
1456:                runner.setPrinter(new ResultPrinter(System.out) {
1457:
1458:                    public void startTest(Test test) {
1459:                        getWriter().println("About to run " + test);
1460:                        super .startTest(test);
1461:                    }
1462:
1463:                    public void endTest(Test test) {
1464:                        super .endTest(test);
1465:                        System.gc();
1466:                        System.gc();
1467:                        System.gc();
1468:                        Runtime.getRuntime().runFinalization();
1469:                        getWriter().println("Test ended: " + test);
1470:                        getWriter().println();
1471:                    }
1472:
1473:                });
1474:                runner
1475:                        .doRun(new TestSuite(
1476:                                VersionedOperationsOnlineTest.class));
1477:            }
1478:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.