/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2011, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geoserver.data.versioning.decorator; import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.logging.Logger; import org.apache.commons.collections.map.HashedMap; import org.apache.commons.io.FileUtils; import org.geogit.test.RepositoryTestCase; import org.geotools.data.DataStore; import org.geotools.data.DataUtilities; import org.geotools.data.DefaultTransaction; import org.geotools.data.Transaction; import org.geotools.data.property.PropertyDataStoreFactory; import org.geotools.data.simple.SimpleFeatureStore; import org.geotools.factory.Hints; import org.geotools.feature.DefaultFeatureCollection; import org.geotools.feature.NameImpl; import org.geotools.feature.simple.SimpleFeatureBuilder; import org.geotools.filter.FilterFactoryImpl; import org.geotools.util.logging.Logging; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.Name; import org.opengis.filter.Filter; import org.opengis.filter.FilterFactory2; import org.opengis.filter.identity.FeatureId; public abstract class DecoratedTestCase extends RepositoryTestCase { protected static final String idS1 = "Sample.1"; protected static final String idS2 = "Sample.2"; protected static final String idS3 = "Sample.3"; protected static final String sampleNs = "http://geogit.sample"; protected static final String sampleName = "Sample"; protected static final String sampleTypeSpec = "st:String,it:Integer,pn:Point:srid=4326,db:Double"; private static String newString1 = "New String Value"; private static String newString2 = "Another new string"; private static String newString3 = "Third iteration change."; protected SimpleFeatureType sampleType; protected Name sampleTypeName = new NameImpl(sampleNs, sampleName); protected SimpleFeature sample1; protected SimpleFeature sample2; protected SimpleFeature sample3; protected FeatureId sampleFid1; protected FeatureId sampleFid2; protected FeatureId sampleFid3; protected SimpleFeature sample1b; protected SimpleFeature sample2b; protected SimpleFeature sample3b; protected static final String idT1 = "Test.1"; protected static final String idT2 = "Test.2"; protected static final String idT3 = "Test.3"; protected static final String testName = "Test"; protected static final String testTypeSpec = "st:String,ln:LineString:srid=4326,it:Integer"; protected SimpleFeatureType testType; protected Name testTypeName = new NameImpl(sampleNs, sampleName); protected SimpleFeature test1; protected SimpleFeature test2; protected SimpleFeature test3; protected SimpleFeature test1b; protected SimpleFeature test2b; protected SimpleFeature test3b; protected SimpleFeature test2c; /** * Holds a reference to the unversioned datastore. */ protected DataStore unversioned; /** * Holds a reference to the decorated datastore that will track versioning * info in the backing geogit repository. */ protected DataStoreDecorator versioned; private Integer newInt = new Integer(0); protected static final Logger LOGGER = Logging .getLogger(DecoratedTestCase.class); @Override protected void setUpInternal() throws Exception { PropertyDataStoreFactory fact = new PropertyDataStoreFactory(); File target = new File("target"); File directory = new File(target, "properties"); FileUtils.deleteDirectory(directory); Map params = new HashedMap(); params.put(PropertyDataStoreFactory.DIRECTORY.key, directory.getPath()); params.put(PropertyDataStoreFactory.NAMESPACE.key, sampleNs); unversioned = fact.createNewDataStore(params); versioned = new DataStoreDecorator(unversioned, repo); sampleType = DataUtilities.createType(sampleNs, sampleName, sampleTypeSpec); sample1 = (SimpleFeature) feature(sampleType, idS1, "Sample String 1", new Integer(1), "POINT (0 1)", new Double(2.34)); sample1.getUserData().put(Hints.USE_PROVIDED_FID, Boolean.TRUE); sample2 = (SimpleFeature) feature(sampleType, idS2, "Sample String 2", new Integer(4), "POINT (1 0)", new Double(3380)); sample2.getUserData().put(Hints.USE_PROVIDED_FID, Boolean.TRUE); sample3 = (SimpleFeature) feature(sampleType, idS3, "Sample String 3", new Integer(81), "POINT (2 2)", new Double(78.2)); sample3.getUserData().put(Hints.USE_PROVIDED_FID, Boolean.TRUE); LOGGER.info(sample1.toString()); LOGGER.info(sample2.toString()); LOGGER.info(sample3.toString()); testType = DataUtilities.createType(sampleNs, testName, testTypeSpec); test1 = (SimpleFeature) feature(testType, idT1, "Test String A", "LINESTRING(1 0,0 0,0 1)", new Integer(5)); test1.getUserData().put(Hints.USE_PROVIDED_FID, Boolean.TRUE); test2 = (SimpleFeature) feature(testType, idT2, "Test String B", "LINESTRING(2 6,2 8,3 18)", new Integer(-2)); test2.getUserData().put(Hints.USE_PROVIDED_FID, Boolean.TRUE); test3 = (SimpleFeature) feature(testType, idT3, "Test String C", "LINESTRING(1 0,0 1,-1 0,0 -1,1 0)", new Integer(37)); test3.getUserData().put(Hints.USE_PROVIDED_FID, Boolean.TRUE); LOGGER.info(test1.toString()); LOGGER.info(test2.toString()); LOGGER.info(test3.toString()); versioned.createSchema(sampleType); SimpleFeatureStore store = (SimpleFeatureStore) versioned .getFeatureSource(sampleName); Transaction tranny = new DefaultTransaction( "DecoratedTestCase.setupInternal()"); store.setTransaction(tranny); DefaultFeatureCollection collection = new DefaultFeatureCollection( sampleName, sampleType); collection.add(sample1); collection.add(sample2); collection.add(sample3); List<FeatureId> ids = store.addFeatures(collection); assertEquals(3, ids.size()); sampleFid1 = ids.get(0); sampleFid2 = ids.get(1); sampleFid3 = ids.get(2); tranny.commit(); tranny.close(); versioned.createSchema(testType); SimpleFeatureStore store2 = (SimpleFeatureStore) versioned .getFeatureSource(testName); Transaction tranny2 = new DefaultTransaction( "DecoratedTestCase.setupInternal().2"); store2.setTransaction(tranny2); DefaultFeatureCollection collection2 = new DefaultFeatureCollection( testName, testType); collection2.add(test1); collection2.add(test2); collection2.add(test3); store2.addFeatures(collection2); tranny2.commit(); tranny2.close(); } protected void updateSampleFeatures() throws Exception { Transaction trans = null; assertNull(sample1b); try { SimpleFeatureStore store = (SimpleFeatureStore) versioned .getFeatureSource(sampleName); trans = new DefaultTransaction( "DecoratedTestCase.updateSampleFeatures()"); store.setTransaction(trans); FilterFactory2 ff = new FilterFactoryImpl(); Filter filter = ff.id(ff.featureId(idS1)); store.modifyFeatures("st", newString1, filter); filter = ff.id(ff.featureId(idS2), ff.featureId(idS3)); store.modifyFeatures(new String[] { "st", "it" }, new Object[] { newString2, newInt }, filter); trans.commit(); SimpleFeatureBuilder fb = new SimpleFeatureBuilder(sampleType); sample1b = fb.copy(sample1); sample1b.setAttribute("st", newString1); sample2b = fb.copy(sample2); sample2b.setAttribute("st", newString2); sample2b.setAttribute("it", newInt); sample3b = fb.copy(sample3); sample3b.setAttribute("st", newString2); sample3b.setAttribute("it", newInt); } catch (Exception ex) { if (trans != null) trans.rollback(); throw ex; } finally { if (trans != null) trans.close(); } } protected void updateTestFeatures() throws Exception { Transaction trans = null; assertNull(test1b); try { SimpleFeatureStore store = (SimpleFeatureStore) versioned .getFeatureSource(testName); trans = new DefaultTransaction( "DecoratedTestCase.updateTestFeatures()"); store.setTransaction(trans); FilterFactory2 ff = new FilterFactoryImpl(); Filter filter = ff.id(ff.featureId(idT1)); store.modifyFeatures("st", newString1, filter); filter = ff.id(ff.featureId(idT2), ff.featureId(idT3)); store.modifyFeatures(new String[] { "st", "it" }, new Object[] { newString2, newInt }, filter); trans.commit(); SimpleFeatureBuilder fb = new SimpleFeatureBuilder(testType); test1b = fb.copy(test1); test1b.setAttribute("st", newString1); test2b = fb.copy(test2); test2b.setAttribute("st", newString2); test2b.setAttribute("it", newInt); test3b = fb.copy(test3); test3b.setAttribute("st", newString2); test3b.setAttribute("it", newInt); } catch (Exception ex) { if (trans != null) trans.rollback(); throw ex; } finally { if (trans != null) trans.close(); } } protected void finalTestFeatureUpdate() throws Exception { Transaction trans = null; assertNull(test2c); try { SimpleFeatureStore store = (SimpleFeatureStore) versioned .getFeatureSource(testName); trans = new DefaultTransaction( "DecoratedTestCase.finalTestFeatureUpate()"); store.setTransaction(trans); FilterFactory2 ff = new FilterFactoryImpl(); Filter filter = ff.id(ff.featureId(idT2)); store.modifyFeatures("st", newString3, filter); trans.commit(); SimpleFeatureBuilder fb = new SimpleFeatureBuilder(testType); test2c = fb.copy(test2b); test2c.setAttribute("st", newString3); } catch (Exception ex) { if (trans != null) trans.rollback(); throw ex; } finally { if (trans != null) trans.close(); } } protected List<SimpleFeature> getCurrentFeatures(String typeName) { if (typeName.equals(sampleName)) { if (sample1b == null) return getOriginalFeatures(sampleName); else return getUpdatedFeatures(sampleName); } else if (typeName.equals(testName)) { if (test1b == null) return getOriginalFeatures(testName); else return getUpdatedFeatures(testName); } return new ArrayList<SimpleFeature>(); } protected List<SimpleFeature> getOriginalFeatures(String typeName) { List<SimpleFeature> featList = new ArrayList<SimpleFeature>(); if (typeName.equals(sampleName)) { featList.add(sample1); featList.add(sample2); featList.add(sample3); } else if (typeName.equals(testName)) { featList.add(test1); featList.add(test2); featList.add(test3); } return featList; } protected List<SimpleFeature> getUpdatedFeatures(String typeName) { List<SimpleFeature> featList = new ArrayList<SimpleFeature>(); if (typeName.equals(sampleName)) { featList.add(sample1b); featList.add(sample2b); featList.add(sample3b); } else if (typeName.equals(testName)) { featList.add(test1b); featList.add(test2b); featList.add(test3b); } return featList; } protected List<SimpleFeature> getAllFeatures(String typeName) { List<SimpleFeature> featList = new ArrayList<SimpleFeature>(); if (typeName.equals(sampleName)) { featList.add(sample1); featList.add(sample2); featList.add(sample3); featList.add(sample1b); featList.add(sample2b); featList.add(sample3b); } else if (typeName.equals(testName)) { featList.add(test1); featList.add(test2); featList.add(test3); featList.add(test1b); featList.add(test2b); featList.add(test3b); } return featList; } /** * This function uses the custom comparison function compareFeature * in order to ignore any featureVersion information held by the identifier. * @param feat * @param list * @return */ protected boolean containsFeature(SimpleFeature feat, List<SimpleFeature> list) { if(feat == null) return false; Iterator<SimpleFeature> it = list.iterator(); while (it.hasNext()) { SimpleFeature otherFeat = it.next(); if(compareFeature(feat, otherFeat)) { return true; } } LOGGER.info("Could not match feature to list: " + feat); return false; } /** * This function is meant to compare feature contents with test features, * and as such, needs to ignore featureVersion or rid information * in FeatureId's, as this won't be available during initial creation. * @param feat * @param otherFeat * @return */ protected boolean compareFeature(SimpleFeature feat, SimpleFeature otherFeat) { FeatureId fid = feat.getIdentifier(); FeatureId otherFid = otherFeat.getIdentifier(); if(!fid.equalsFID(otherFid)) { return false; } if(!feat.getFeatureType().equals(otherFeat.getFeatureType())) { return false; } for(int i = 0; i < feat.getAttributeCount(); i++) { Object attr = feat.getAttribute(i); Object otherAttr = otherFeat.getAttribute(i); if(attr == null) { if(otherAttr != null) { return false; } } else { if(otherAttr == null) { return false; } else if(!attr.equals(otherAttr)) { return false; } } } return true; } }