diff --git a/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyAttributeReader.java b/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyAttributeReader.java index 53f4b56..b3f78ff 100644 --- a/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyAttributeReader.java +++ b/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyAttributeReader.java @@ -4,8 +4,11 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; +import java.util.Arrays; import java.util.NoSuchElementException; import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.geotools.data.AttributeReader; import org.geotools.data.DataSourceException; @@ -48,14 +51,19 @@ import com.vividsolutions.jts.geom.Geometry; *

* *
- *  
- *  fid4=4|| -> Feature( id=2, name="", geom=null )
- *  
+ *  fid4=4||
+ * 
+ *

+ * You can use \ to escape a | character, you can also use it to protect newlines:: + *

+ * fid4=4|I have a \\|splitting\\| headache|POINT(0,0)
+ * fid5=5|Example of \nmulti-lin text|POINT(1,1)
+ * fid6=6|Second \\
+ * example of multi-line text|POINT(2,2)
  * 
* * @author Jody Garnett * - * * @source $URL$ */ public class PropertyAttributeReader implements AttributeReader { @@ -183,10 +191,14 @@ public class PropertyAttributeReader implements AttributeReader { if( txt == null ){ break; } + // skip comments if( txt.startsWith("#") || txt.startsWith("!")){ - continue; // skip content + continue; } + // ignore leading white space txt = trimLeft( txt ); + + // handle escaped line feeds used to span multiple lines if( txt.endsWith("\\")){ buffer.append(txt.substring(0,txt.length()-1) ); buffer.append("\n"); @@ -201,13 +213,30 @@ public class PropertyAttributeReader implements AttributeReader { return null; // there is no line } String raw = buffer.toString(); - raw = raw.replace("\\n", "\n" ); - raw = raw.replace("\\r", "\r" ); - raw = raw.replace("\\t", "\t" ); +// String line = decodeString(raw); +// return line; return raw; } /** - * Trim leading white space as described Properties. + * Used to decode common whitespace chracters and escaped | characters. + * + * @param txt Origional raw text as stored + * @return decoded text as provided for storage + * @see PropertyAttributeWriter#encodeString(String) + */ + String decodeString( String txt ){ + // unpack whitespace constants + txt = txt.replace( "\\n", "\n"); + txt = txt.replaceAll("\\r", "\r" ); + + // unpack our our escaped characters + txt = txt.replace("\\|", "|" ); + // txt = txt.replace("\\\\", "\\" ); + + return txt; + } + /** + * Trim leading white space as described Properties file standard. * @see Properties#load(java.io.Reader) * @param txt * @return txt leading whitespace removed @@ -241,14 +270,61 @@ public class PropertyAttributeReader implements AttributeReader { int split = line.indexOf('='); fid = line.substring(0, split); - text = line.substring(split + 1).split("\\|", -1);//use -1 as limit to include empty trailing spaces - if (type.getAttributeCount() != text.length) - throw new DataSourceException("format error: expected " + type.getAttributeCount() - + " attributes, but found " + text.length + ". [" + line + "]"); + String data = line.substring(split+1); + + text = splitIntoText(data); } else { throw new NoSuchElementException(); } } + /** + * Split the provided text using | charater as a seperator. + *

+ * This method respects the used of \ to "escape" a | character allowing + * representations such as the following:

+     * String example="text|example of escaped \\| character|text";
+     * 
+     * // represents: "text|example of escaped \| character|text"
+     * String split=splitIntoText( example );
+ * + * @param data Origional raw text as stored + * @return data split using | as seperator + * @throws DataSourceException if the information stored is inconsistent with the headered provided + */ + private String[] splitIntoText(String data) throws DataSourceException { + // return data.split("|", -1); // use -1 as a limit to include empty trailing spaces + // return data.split("[.-^\\\\]\\|",-1); //use -1 as limit to include empty trailing spaces + + String split[] = new String[type.getAttributeCount()]; + int i = 0; + StringBuilder item = new StringBuilder(); + for (String str : data.split("\\|",-1)) { + if (i == type.getAttributeCount()) { + // limit reached + throw new DataSourceException("format error: expected " + text.length + + " attributes, stopped after finding " + i + ". [" + line + + "] split into " + Arrays.asList(text)); + } + if (str.endsWith("\\")) { +// String shorter = str.substring(0, str.length() - 1); +// item.append(shorter); + item.append(str); + item.append("|"); + } else { + item.append(str); + split[i] = item.toString(); + + i++; + item = new StringBuilder(); + } + } + if (i < type.getAttributeCount()) { + throw new DataSourceException("format error: expected " + type.getAttributeCount() + + " attributes, but only found " + i + ". [" + line + "] split into " + + Arrays.asList(text)); + } + return split; + } /** * Retrieve the FeatureId identifying the current line. @@ -281,18 +357,18 @@ public class PropertyAttributeReader implements AttributeReader { AttributeDescriptor attType = type.getDescriptor(index); String stringValue = null; - boolean isEmpty = "".equals(stringValue); + //boolean isEmpty = "".equals(stringValue); try { - // read the value - stringValue = text[index]; - } catch (RuntimeException e1) { - e1.printStackTrace(); + // read the value and decode any interesting characters + stringValue = decodeString( text[index] ); + } catch (RuntimeException huh) { + huh.printStackTrace(); stringValue = null; } // check for special flag if ("".equals(stringValue)) { stringValue = null; - isEmpty = true; + // isEmpty = true; } if (stringValue == null) { if (attType.isNillable()) { diff --git a/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyAttributeWriter.java b/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyAttributeWriter.java index c688645..9261452 100644 --- a/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyAttributeWriter.java +++ b/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyAttributeWriter.java @@ -20,6 +20,9 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.util.regex.MatchResult; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.geotools.data.AttributeWriter; import org.geotools.data.DataUtilities; @@ -110,22 +113,42 @@ public class PropertyAttributeWriter implements AttributeWriter { if (attribute == null) { writer.write(""); // nothing! } else if( attribute instanceof String){ - // encode newlines - String txt = (String) attribute; - txt = txt.replace("\n", "\\n"); - txt = txt.replace("\r", "\\r"); - writer.write( txt ); + String txt = encodeString((String) attribute); + writer.write( txt ); } else if (attribute instanceof Geometry) { Geometry geometry = (Geometry) attribute; - writer.write( geometry.toText() ); + String txt = geometry.toText(); + + txt = encodeString( txt ); + writer.write( txt ); } else { String txt = Converters.convert( attribute, String.class ); if( txt == null ){ // could not convert? txt = attribute.toString(); } + txt = encodeString( txt ); writer.write( txt ); } } + + /** + * Used to encode common whitespace characters and | character for safe transport. + * + * @param txt + * @return txt encoded for storage + * @see PropertyAttributeReader#decodeString(String) + */ + String encodeString( String txt ){ + // encode our escaped characters + // txt = txt.replace("\\", "\\\\"); + txt = txt.replace("|","\\|"); + + // encode whitespace constants + txt = txt.replace("\n", "\\n"); + txt = txt.replace("\r", "\\r"); + + return txt; + } // write end // close start diff --git a/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyFeatureWriter.java b/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyFeatureWriter.java index 89263ab..f7bf6c1 100644 --- a/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyFeatureWriter.java +++ b/modules/plugin/property/src/main/java/org/geotools/data/property/PropertyFeatureWriter.java @@ -105,6 +105,7 @@ public class PropertyFeatureWriter implements // writeImplementation end // next start + long nextFid = System.currentTimeMillis(); // seed with a big number public SimpleFeature next() throws IOException { if (writer == null) { throw new IOException("Writer has been closed"); @@ -125,7 +126,7 @@ public class PropertyFeatureWriter implements live = SimpleFeatureBuilder.copy(origional); return live; } else { - fid = type.getTypeName() + "." + System.currentTimeMillis(); + fid = type.getTypeName() + "." + (nextFid++); Object values[] = DataUtilities.defaultValues(type); origional = null; diff --git a/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyDataStore2Test.java b/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyDataStore2Test.java index e602f92..322606a 100644 --- a/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyDataStore2Test.java +++ b/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyDataStore2Test.java @@ -16,47 +16,72 @@ */ package org.geotools.data.property; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; -import junit.framework.TestCase; - -import org.geotools.data.DefaultQuery; +import org.geotools.data.DataUtilities; +import org.geotools.data.Query; +import org.geotools.data.collection.ListFeatureCollection; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.data.simple.SimpleFeatureIterator; import org.geotools.data.simple.SimpleFeatureSource; +import org.geotools.data.simple.SimpleFeatureStore; +import org.geotools.factory.CommonFactoryFinder; +import org.geotools.factory.Hints; +import org.geotools.feature.simple.SimpleFeatureBuilder; +import org.geotools.geometry.jts.JTSFactoryFinder; import org.geotools.referencing.CRS; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.opengis.feature.Feature; +import org.opengis.feature.FeatureVisitor; import org.opengis.feature.Property; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.GeometryDescriptor; import org.opengis.feature.type.GeometryType; import org.opengis.filter.Filter; +import org.opengis.filter.FilterFactory2; import org.opengis.referencing.crs.CoordinateReferenceSystem; +import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.LineString; /** - * Test non functionality of PropertyDataStore. + * Test non functionality of PropertyDataStore (problems and enhancements requested through JIRA). * - * @author Jody Garnett, Refractions Research Inc. + * @author Jody Garnett (LISAsoft) * * * @source $URL$ */ -public class PropertyDataStore2Test extends TestCase { +public class PropertyDataStore2Test { PropertyDataStore store; PropertyDataStore sridStore; - /** - * Constructor for SimpleDataStoreTest. - * @param arg0 - */ - public PropertyDataStore2Test(String arg0) { - super(arg0); - } - protected void setUp() throws Exception { + + private PropertyDataStore unusalStore; + + @Before + public void setUp() throws Exception { File dir = new File(".", "propertyTestData" ); dir.mkdir(); @@ -93,24 +118,46 @@ public class PropertyDataStore2Test extends TestCase { writer2.close(); sridStore = new PropertyDataStore(dir2); - super.setUp(); + // Create a similar data store with various unusal problems + File dir3 = new File(".", "propertyTestData3"); + dir3.mkdir(); + File file3 = new File( dir3 ,"unusual.properties"); + if( file3.exists()){ + file3.delete(); + } + + BufferedWriter writer3 = new BufferedWriter( new FileWriter( file3 ) ); + writer3.write("_=id:Integer,*geom:Geometry,data:String"); writer3.newLine(); + writer3.write("fid1=1|LINESTRING(0 0,10 10)|feeling a bit \\|broken up"); writer3.newLine(); + writer3.write("fid2=2|\\\nLINESTRING(20 20,30 30)|\\\nnew line\\\ndiff friendly");writer3.newLine(); + writer3.close(); + unusalStore = new PropertyDataStore( dir3 ); + + // listFileContents( file3 ); } - protected void tearDown() throws Exception { + + @After + public void tearDown() throws Exception { + store.dispose(); File dir = new File( "propertyTestData" ); - File list[]=dir.listFiles(); - for( int i=0; i list = new ArrayList(); + SimpleFeature feature; + + feature = builder.buildFeature("trip1", new Object[]{gf.createPoint( new Coordinate(0,0)), "hello world", 1 }); + feature.getUserData().put( Hints.USE_PROVIDED_FID, true ); + list.add( feature); + + feature = builder.buildFeature("trip2", new Object[]{gf.createPoint( new Coordinate(0,0)), "test if | chracter handling", 2 }); + feature.getUserData().put( Hints.USE_PROVIDED_FID, true ); + list.add( feature ); + + feature= builder.buildFeature("trip3", new Object[]{gf.createPoint( new Coordinate(0,0)), "test of\n multi-line handling", 3 }); + feature.getUserData().put( Hints.USE_PROVIDED_FID, true ); + list.add( feature ); + + feature = builder.buildFeature("trip4", new Object[]{gf.createPoint( new Coordinate(0,0)), " test of\n whitespace handling", 4 }); + feature.getUserData().put( Hints.USE_PROVIDED_FID, true ); + list.add( feature ); + + feature = builder.buildFeature("trip5", new Object[]{gf.createPoint( new Coordinate(0,0)), "test encoding does not get confused over \\n newline and \\twhite space and \\| other markers", 5 }); + feature.getUserData().put( Hints.USE_PROVIDED_FID, true ); + list.add( feature ); + + feature = builder.buildFeature("trip6", new Object[]{gf.createPoint( new Coordinate(0,0)), "How well can we encode 1\\2?", 5 }); + feature.getUserData().put( Hints.USE_PROVIDED_FID, true ); + list.add( feature ); + + ListFeatureCollection features = new ListFeatureCollection(schema, list ); + + unusalStore.createSchema( schema ); + SimpleFeatureStore trip = (SimpleFeatureStore) unusalStore.getFeatureSource("trip"); + + trip.addFeatures( features ); + assertTrue( "trip.properties created", target.exists() ); + + // listFileContents(target); + + assertEquals("stored", list.size(), trip.getCount(Query.ALL)); + + final Map cache = new HashMap(); + SimpleFeatureCollection readFeatures = trip.getFeatures(); + + FeatureVisitor cacheResults = new FeatureVisitor() { + @Override + public void visit(Feature f) { + SimpleFeature feature = (SimpleFeature) f; + cache.put( feature.getID(), feature ); + } + }; + readFeatures.accepts( cacheResults, null ); + assertEquals( "restored", list.size(), cache.size() ); + assertEquals( "hello world", cache.get("trip1").getAttribute("text")); + assertEquals( "test if | chracter handling", cache.get("trip2").getAttribute("text")); + assertEquals( "test of\n multi-line handling", cache.get("trip3").getAttribute("text")); + assertEquals( " test of\n whitespace handling", cache.get("trip4").getAttribute("text")); + + // need some regex magic to make this work + //assertEquals( "test encoding does not get confused over \\n newline and \\twhite space and \\| other markers", cache.get("trip5").getAttribute("text")); + assertEquals( "How well can we encode 1\\2?", cache.get("trip6").getAttribute("text")); + } + + private void listFileContents(File target) throws FileNotFoundException, IOException { + System.out.println("Contents of "+target ); + if( target.exists() ){ + BufferedReader reader = new BufferedReader( new FileReader( target ) ); + String line; + while( (line = reader.readLine()) != null ){ + System.out.println( line ); + } + reader.close(); + } + else { + System.out.println(" ... does not exist"); + } } } diff --git a/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyDataStoreTest.java b/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyDataStoreTest.java index 6a6a6d9..fef4250 100644 --- a/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyDataStoreTest.java +++ b/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyDataStoreTest.java @@ -25,12 +25,10 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.NoSuchElementException; -import java.util.Set; import junit.framework.TestCase; import org.geotools.data.DataUtilities; -import org.geotools.data.DefaultQuery; import org.geotools.data.DefaultTransaction; import org.geotools.data.FeatureReader; import org.geotools.data.FeatureWriter; @@ -43,7 +41,6 @@ import org.geotools.data.simple.SimpleFeatureStore; import org.geotools.factory.CommonFactoryFinder; import org.geotools.factory.Hints; import org.geotools.feature.simple.SimpleFeatureBuilder; -import org.geotools.filter.identity.FeatureIdImpl; import org.opengis.feature.Feature; import org.opengis.feature.FeatureVisitor; import org.opengis.feature.IllegalAttributeException; @@ -55,497 +52,539 @@ import org.opengis.filter.FilterFactory2; import org.opengis.filter.identity.FeatureId; /** - * Test functioning of PropertyDataStore. + * Test functioning of PropertyDataStore (used as conformance testing and examples for the AbstractDataStore tutorial). + * + * @author Jody Garnett (LISAsoft) * - * @author Jody Garnett, Refractions Research Inc. - * - * * @source $URL$ */ public class PropertyDataStoreTest extends TestCase { PropertyDataStore store; - + static FilterFactory2 ff = (FilterFactory2) CommonFactoryFinder.getFilterFactory(null); /** * Constructor for SimpleDataStoreTest. + * * @param arg0 */ public PropertyDataStoreTest(String arg0) { super(arg0); } + protected void setUp() throws Exception { - File dir = new File(".", "propertyTestData" ); + File dir = new File(".", "propertyTestData"); dir.mkdir(); - - File file = new File( dir ,"road.properties"); - if( file.exists()){ + + File file = new File(dir, "road.properties"); + if (file.exists()) { file.delete(); - } - BufferedWriter writer = new BufferedWriter( new FileWriter( file ) ); - writer.write("_=id:Integer,name:String"); writer.newLine(); - writer.write("fid1=1|jody"); writer.newLine(); - writer.write("fid2=2|brent"); writer.newLine(); - writer.write("fid3=3|dave"); writer.newLine(); - writer.write("fid4=4|justin"); writer.newLine(); + } + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + writer.write("_=id:Integer,name:String"); + writer.newLine(); + writer.write("fid1=1|jody"); + writer.newLine(); + writer.write("fid2=2|brent"); + writer.newLine(); + writer.write("fid3=3|dave"); + writer.newLine(); + writer.write("fid4=4|justin"); + writer.newLine(); writer.write("fid5=5|"); writer.close(); - - file = new File( dir ,"dots.in.name.properties"); - if( file.exists()){ + + file = new File(dir, "dots.in.name.properties"); + if (file.exists()) { file.delete(); - } - writer = new BufferedWriter( new FileWriter( file ) ); - writer.write("_=id:Integer,name:String"); writer.newLine(); - writer.write("fid1=1|jody"); writer.newLine(); - writer.write("fid2=2|brent"); writer.newLine(); - writer.write("fid3=3|dave"); writer.newLine(); + } + writer = new BufferedWriter(new FileWriter(file)); + writer.write("_=id:Integer,name:String"); + writer.newLine(); + writer.write("fid1=1|jody"); + writer.newLine(); + writer.write("fid2=2|brent"); + writer.newLine(); + writer.write("fid3=3|dave"); + writer.newLine(); writer.write("fid4=4|justin"); writer.close(); - file = new File( dir ,"multiline.properties"); - if( file.exists()){ + file = new File(dir, "multiline.properties"); + if (file.exists()) { file.delete(); - } - writer = new BufferedWriter( new FileWriter( file ) ); - writer.write("_=id:Integer,name:String"); writer.newLine(); - writer.write("fid1=1|jody \\"); writer.newLine(); - writer.write(" garnett"); writer.newLine(); - writer.write("fid2=2|brent"); writer.newLine(); - writer.write("fid3=3|dave"); writer.newLine(); + } + writer = new BufferedWriter(new FileWriter(file)); + writer.write("_=id:Integer,name:String"); + writer.newLine(); + writer.write("fid1=1|jody \\"); + writer.newLine(); + writer.write(" garnett"); + writer.newLine(); + writer.write("fid2=2|brent"); + writer.newLine(); + writer.write("fid3=3|dave"); + writer.newLine(); writer.write("fid4=4|justin\\\n"); writer.close(); - file = new File( dir ,"table.properties"); - if( file.exists()){ + file = new File(dir, "table.properties"); + if (file.exists()) { file.delete(); - } - writer = new BufferedWriter( new FileWriter( file ) ); - writer.write("_=description:String,name:String"); writer.newLine(); - writer.write("GenericEntity.f004=description-f004|name-f004"); writer.newLine(); - writer.write("GenericEntity.f003=description-f003|"); writer.newLine(); - writer.write("GenericEntity.f007=description-f007|"); writer.newLine(); - writer.write(" GenericEntity.f009=description-f009| "); writer.newLine(); + } + writer = new BufferedWriter(new FileWriter(file)); + writer.write("_=description:String,name:String"); + writer.newLine(); + writer.write("GenericEntity.f004=description-f004|name-f004"); + writer.newLine(); + writer.write("GenericEntity.f003=description-f003|"); + writer.newLine(); + writer.write("GenericEntity.f007=description-f007|"); + writer.newLine(); + writer.write(" GenericEntity.f009=description-f009| "); + writer.newLine(); writer.close(); - - store = new PropertyDataStore( dir ); + + store = new PropertyDataStore(dir); super.setUp(); } + protected void tearDown() throws Exception { - File dir = new File( "propertyTestData" ); - File list[]=dir.listFiles(); - for( int i=0; i reader = store.getFeatureReader( roadQuery, Transaction.AUTO_COMMIT ); + Query roadQuery = new Query("road"); + FeatureReader reader = store.getFeatureReader(roadQuery, + Transaction.AUTO_COMMIT); int count = 0; try { - while( reader.hasNext() ){ + while (reader.hasNext()) { reader.next(); count++; } - } - finally { + } finally { reader.close(); } - assertEquals( 5, count ); - + assertEquals(5, count); + Filter selectFid1; - - selectFid1 = ff.id( Collections.singleton( ff.featureId("fid1") ) ); - reader = store.getFeatureReader( new DefaultQuery("road", selectFid1 ), Transaction.AUTO_COMMIT ); - assertEquals( 1, count( reader ) ); - + + selectFid1 = ff.id(Collections.singleton(ff.featureId("fid1"))); + reader = store.getFeatureReader(new Query("road", selectFid1), Transaction.AUTO_COMMIT); + assertEquals(1, count(reader)); + Transaction transaction = new DefaultTransaction(); - reader = store.getFeatureReader( roadQuery, transaction ); - assertEquals( 5, count( reader )); - - reader = store.getFeatureReader( roadQuery, transaction ); - List list = new ArrayList(); + reader = store.getFeatureReader(roadQuery, transaction); + assertEquals(5, count(reader)); + + reader = store.getFeatureReader(roadQuery, transaction); + List list = new ArrayList(); try { - while( reader.hasNext() ){ - list.add( reader.next().getID() ); + while (reader.hasNext()) { + list.add(reader.next().getID()); } - } - finally { + } finally { reader.close(); } - assertEquals( "[fid1, fid2, fid3, fid4, fid5]", list.toString() ); + assertEquals("[fid1, fid2, fid3, fid4, fid5]", list.toString()); } + /* - * Test for FeatureReader getFeatureReader(String) + * Test for FeatureReader getFeatureReader(String) */ - public void testGetFeatureReaderString() throws NoSuchElementException, IOException, IllegalAttributeException { - FeatureReader reader = store.getFeatureReader("road"); + public void testGetFeatureReaderString() throws NoSuchElementException, IOException, + IllegalAttributeException { + FeatureReader reader = store.getFeatureReader("road"); int count = 0; try { - while( reader.hasNext() ){ - reader.next(); + while (reader.hasNext()) { + reader.next(); count++; } - } - finally { + } finally { reader.close(); } - assertEquals( 5, count ); + assertEquals(5, count); } - private int count( FeatureReader reader ) throws Exception { + + private int count(FeatureReader reader) throws Exception { int count = 0; try { - while( reader.hasNext() ){ + while (reader.hasNext()) { reader.next(); count++; } - } - finally { + } finally { reader.close(); } - return count; - } - private int count( String typeName ) throws Exception { - return count( store.getFeatureReader( typeName ) ); + return count; } - + + private int count(String typeName) throws Exception { + return count(store.getFeatureReader(typeName)); + } + public void testWriterSkipThrough() throws Exception { - PropertyFeatureWriter writer = (PropertyFeatureWriter) - store.createFeatureWriter("road",Transaction.AUTO_COMMIT); - + PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road", + Transaction.AUTO_COMMIT); + File in = writer.read; File out = writer.write; - + int count = 0; - while( writer.hasNext() ){ + while (writer.hasNext()) { writer.next(); count++; } - assertEquals( 5, count ); - assertTrue( in.exists() ); - assertTrue( out.exists() ); + assertEquals(5, count); + assertTrue(in.exists()); + assertTrue(out.exists()); writer.close(); - assertTrue( in.exists() ); - - assertEquals( 5, count( "road" ) ); + assertTrue(in.exists()); + + assertEquals(5, count("road")); } - public void testWriterChangeName() throws Exception{ - PropertyFeatureWriter writer = (PropertyFeatureWriter) - store.createFeatureWriter("road",Transaction.AUTO_COMMIT); - + + public void testWriterChangeName() throws Exception { + PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road", + Transaction.AUTO_COMMIT); + int count = 0; - while( writer.hasNext() ){ + while (writer.hasNext()) { SimpleFeature f = writer.next(); - f.setAttribute(1,"name "+(count+1)); + f.setAttribute(1, "name " + (count + 1)); writer.write(); count++; - } - writer.close(); - assertEquals( 5, count ); - assertEquals( 5, count( "road" )); + } + writer.close(); + assertEquals(5, count); + assertEquals(5, count("road")); } - public void testWriterChangeFirstName() throws Exception{ - PropertyFeatureWriter writer = (PropertyFeatureWriter) - store.createFeatureWriter("road",Transaction.AUTO_COMMIT); + + public void testWriterChangeFirstName() throws Exception { + PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road", + Transaction.AUTO_COMMIT); SimpleFeature f; f = writer.next(); - f.setAttribute(1,"changed"); + f.setAttribute(1, "changed"); writer.write(); - writer.close(); - assertEquals( 5, count( "road" )); + writer.close(); + assertEquals(5, count("road")); } - public void testWriterChangeLastName() throws Exception{ - PropertyFeatureWriter writer = (PropertyFeatureWriter) - store.createFeatureWriter("road",Transaction.AUTO_COMMIT); + + public void testWriterChangeLastName() throws Exception { + PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road", + Transaction.AUTO_COMMIT); SimpleFeature f; writer.next(); writer.next(); - writer.next(); + writer.next(); f = writer.next(); - f.setAttribute(1,"changed"); + f.setAttribute(1, "changed"); writer.write(); - writer.close(); - assertEquals( 5, count( "road" )); - } - public void testWriterChangeAppend() throws Exception{ - PropertyFeatureWriter writer = (PropertyFeatureWriter) - store.createFeatureWriter("road",Transaction.AUTO_COMMIT); + writer.close(); + assertEquals(5, count("road")); + } + + public void testWriterChangeAppend() throws Exception { + PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road", + Transaction.AUTO_COMMIT); SimpleFeature f; writer.next(); writer.next(); writer.next(); writer.next(); writer.next(); - assertFalse( writer.hasNext() ); + assertFalse(writer.hasNext()); f = writer.next(); - assertNotNull( f ); - f.setAttribute(0,new Integer(-1)); - f.setAttribute(1,"new"); + assertNotNull(f); + f.setAttribute(0, new Integer(-1)); + f.setAttribute(1, "new"); writer.write(); writer.close(); - assertEquals( 6, count( "road" )); + assertEquals(6, count("road")); } - public void testWriterAppendLastNull() throws Exception{ - FeatureWriter writer = (FeatureWriter) - store.getFeatureWriterAppend("road", Transaction.AUTO_COMMIT); + + public void testWriterAppendLastNull() throws Exception { + FeatureWriter writer = store + .getFeatureWriterAppend("road", Transaction.AUTO_COMMIT); SimpleFeature f; - assertFalse( writer.hasNext() ); + assertFalse(writer.hasNext()); f = writer.next(); - assertNotNull( f ); - f.setAttribute(0,new Integer(-1)); - f.setAttribute(1,null); // this made the datastore break + assertNotNull(f); + f.setAttribute(0, new Integer(-1)); + f.setAttribute(1, null); // this made the datastore break writer.write(); writer.close(); - assertEquals( 6, count( "road" )); + assertEquals(6, count("road")); } - public void testWriterChangeRemoveFirst() throws Exception{ - PropertyFeatureWriter writer = (PropertyFeatureWriter) - store.createFeatureWriter("road",Transaction.AUTO_COMMIT); - + + public void testWriterChangeRemoveFirst() throws Exception { + PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road", + Transaction.AUTO_COMMIT); + writer.next(); writer.remove(); writer.close(); - assertEquals( 4, count( "road" )); + assertEquals(4, count("road")); } - public void testWriterChangeRemoveLast() throws Exception{ - PropertyFeatureWriter writer = (PropertyFeatureWriter) - store.createFeatureWriter("road",Transaction.AUTO_COMMIT); - + + public void testWriterChangeRemoveLast() throws Exception { + PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road", + Transaction.AUTO_COMMIT); + writer.next(); writer.next(); writer.next(); writer.remove(); writer.close(); - assertEquals( 4, count( "road" )); + assertEquals(4, count("road")); } - public void testWriterChangeRemoveAppend() throws Exception{ - PropertyFeatureWriter writer = (PropertyFeatureWriter) - store.createFeatureWriter("road",Transaction.AUTO_COMMIT); + + public void testWriterChangeRemoveAppend() throws Exception { + PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road", + Transaction.AUTO_COMMIT); SimpleFeature f; writer.next(); writer.next(); writer.next(); - writer.next(); - writer.next(); - - assertFalse( writer.hasNext() ); + writer.next(); + writer.next(); + + assertFalse(writer.hasNext()); f = writer.next(); - assertNotNull( f ); - f.setAttribute(0,new Integer(-1)); - f.setAttribute(1,"new"); + assertNotNull(f); + f.setAttribute(0, new Integer(-1)); + f.setAttribute(1, "new"); writer.remove(); writer.close(); - assertEquals( 5, count( "road" )); + assertEquals(5, count("road")); } - public void testWriterChangeIgnoreAppend() throws Exception{ - PropertyFeatureWriter writer = (PropertyFeatureWriter) - store.createFeatureWriter("road",Transaction.AUTO_COMMIT); + + public void testWriterChangeIgnoreAppend() throws Exception { + PropertyFeatureWriter writer = (PropertyFeatureWriter) store.createFeatureWriter("road", + Transaction.AUTO_COMMIT); SimpleFeature f; writer.next(); writer.next(); writer.next(); writer.next(); writer.next(); - assertFalse( writer.hasNext() ); + assertFalse(writer.hasNext()); f = writer.next(); - assertNotNull( f ); - f.setAttribute(0,new Integer(-1)); - f.setAttribute(1,"new"); + assertNotNull(f); + f.setAttribute(0, new Integer(-1)); + f.setAttribute(1, "new"); writer.close(); - assertEquals( 5, count( "road" )); + assertEquals(5, count("road")); } - + public void testGetFeatureSource() throws Exception { - SimpleFeatureSource road = store.getFeatureSource( "road" ); + SimpleFeatureSource road = store.getFeatureSource("road"); SimpleFeatureCollection features = road.getFeatures(); SimpleFeatureIterator reader = features.features(); - List list = new ArrayList(); + List list = new ArrayList(); try { - while( reader.hasNext() ){ - list.add( reader.next().getID() ); + while (reader.hasNext()) { + list.add(reader.next().getID()); } } finally { reader.close(); } - assertEquals( "[fid1, fid2, fid3, fid4, fid5]", list.toString() ); - assertEquals( 5, road.getCount(Query.ALL) ); - assertTrue( road.getBounds(Query.ALL).isNull() ); - assertEquals( 5, features.size() ); - assertTrue( features.getBounds().isNull() ); - assertEquals( 5, features.size() ); - + assertEquals("[fid1, fid2, fid3, fid4, fid5]", list.toString()); + assertEquals(5, road.getCount(Query.ALL)); + assertTrue(road.getBounds(Query.ALL).isNull()); + assertEquals(5, features.size()); + assertTrue(features.getBounds().isNull()); + assertEquals(5, features.size()); + } /** - * In response to GEOT-1409 Property - * datastore ruins the property file if a string attribute has newlines. + * In response to GEOT-1409 Property datastore ruins the property file if a string attribute + * has newlines. * * @throws Exception */ public void testMultiLine() throws Exception { - SimpleFeatureSource road = store.getFeatureSource( "multiline" ); + SimpleFeatureSource road = store.getFeatureSource("multiline"); FeatureId fid1 = ff.featureId("fid1"); - Filter select = ff.id( Collections.singleton(fid1)); - SimpleFeatureCollection featureCollection = road.getFeatures( select ); + Filter select = ff.id(Collections.singleton(fid1)); + SimpleFeatureCollection featureCollection = road.getFeatures(select); featureCollection.accepts(new FeatureVisitor() { public void visit(Feature f) { SimpleFeature feature = (SimpleFeature) f; String name = (String) feature.getAttribute("name"); - assertEquals( "jody \ngarnett", name ); + assertEquals("jody \ngarnett", name); } - },null); + }, null); } /** - * In response to GEOT-3540 - * PropertyDataStore doesn't support empty trailing spaces. + * In response to GEOT-3540 PropertyDataStore doesn't support empty trailing spaces. *

* Table with no geoemtry, containing null and empty strings at end of line *

* * @throws Exception */ - public void testTable() throws Exception{ - SimpleFeatureSource table = store.getFeatureSource( "table" ); - //GenericEntity.f004=description-f004|name-f004 + public void testTable() throws Exception { + SimpleFeatureSource table = store.getFeatureSource("table"); + // GenericEntity.f004=description-f004|name-f004 FeatureId fid1 = ff.featureId("GenericEntity.f004"); - Filter select = ff.id( Collections.singleton(fid1)); - SimpleFeatureCollection featureCollection = table.getFeatures( select ); + Filter select = ff.id(Collections.singleton(fid1)); + SimpleFeatureCollection featureCollection = table.getFeatures(select); featureCollection.accepts(new FeatureVisitor() { public void visit(Feature f) { SimpleFeature feature = (SimpleFeature) f; String name = (String) feature.getAttribute("name"); - assertEquals( "name-f004", name ); + assertEquals("name-f004", name); } - },null); - //GenericEntity.f003=description-f003| + }, null); + // GenericEntity.f003=description-f003| fid1 = ff.featureId("GenericEntity.f003"); - select = ff.id( Collections.singleton(fid1)); - featureCollection = table.getFeatures( select ); + select = ff.id(Collections.singleton(fid1)); + featureCollection = table.getFeatures(select); featureCollection.accepts(new FeatureVisitor() { public void visit(Feature f) { SimpleFeature feature = (SimpleFeature) f; String name = (String) feature.getAttribute("name"); - System.out.println( name ); - assertNull( "represent null", name ); + System.out.println(name); + assertNull("represent null", name); } - },null); - //GenericEntity.f007=description-f007| + }, null); + // GenericEntity.f007=description-f007| fid1 = ff.featureId("GenericEntity.f007"); - select = ff.id( Collections.singleton(fid1)); - featureCollection = table.getFeatures( select ); + select = ff.id(Collections.singleton(fid1)); + featureCollection = table.getFeatures(select); featureCollection.accepts(new FeatureVisitor() { public void visit(Feature f) { SimpleFeature feature = (SimpleFeature) f; String name = (String) feature.getAttribute("name"); - assertEquals( "represent empty string", "", name ); + assertEquals("represent empty string", "", name); } - },null); - //" GenericEntity.f009=description-f009| " + }, null); + // " GenericEntity.f009=description-f009| " fid1 = ff.featureId("GenericEntity.f009"); - select = ff.id( Collections.singleton(fid1)); - featureCollection = table.getFeatures( select ); + select = ff.id(Collections.singleton(fid1)); + featureCollection = table.getFeatures(select); featureCollection.accepts(new FeatureVisitor() { public void visit(Feature f) { SimpleFeature feature = (SimpleFeature) f; String name = (String) feature.getAttribute("name"); - assertEquals( "represent empty string", " ", name ); + assertEquals("represent empty string", " ", name); } - },null); + }, null); } + public void testTransactionIndependence() throws Exception { - SimpleFeatureType ROAD = store.getSchema( "road" ); - SimpleFeature chrisFeature = - SimpleFeatureBuilder.build(ROAD, new Object[]{ new Integer(5), "chris"}, "fid5" ); - + SimpleFeatureType ROAD = store.getSchema("road"); + SimpleFeature chrisFeature = SimpleFeatureBuilder.build(ROAD, new Object[] { + new Integer(5), "chris" }, "fid5"); + SimpleFeatureStore roadAuto = (SimpleFeatureStore) store.getFeatureSource("road"); - + SimpleFeatureStore roadFromClient1 = (SimpleFeatureStore) store.getFeatureSource("road"); Transaction transaction1 = new DefaultTransaction("Transaction Used by Client 1"); - roadFromClient1.setTransaction( transaction1 ); - + roadFromClient1.setTransaction(transaction1); + SimpleFeatureStore roadFromClient2 = (SimpleFeatureStore) store.getFeatureSource("road"); Transaction transaction2 = new DefaultTransaction("Transaction Used by Client 2"); - roadFromClient2.setTransaction( transaction2 ); + roadFromClient2.setTransaction(transaction2); FilterFactory2 ff = (FilterFactory2) CommonFactoryFinder.getFilterFactory(null); - Filter selectFid1 = ff.id( Collections.singleton( ff.featureId("fid1") )); - + Filter selectFid1 = ff.id(Collections.singleton(ff.featureId("fid1"))); + // Before we edit everything should be the same - assertEquals( "auto before", 5, roadAuto.getFeatures().size() ); - assertEquals( "client 1 before", 5, roadFromClient1.getFeatures().size() ); - assertEquals( "client 2 before", 5, roadFromClient2.getFeatures().size() ); + assertEquals("auto before", 5, roadAuto.getFeatures().size()); + assertEquals("client 1 before", 5, roadFromClient1.getFeatures().size()); + assertEquals("client 2 before", 5, roadFromClient2.getFeatures().size()); // Remove Feature with Fid1 - roadFromClient1.removeFeatures( selectFid1 ); // road1 removes fid1 on t1 - - assertEquals( "auto after client 1 removes fid1", 5, roadAuto.getFeatures().size() ); - assertEquals( "client 1 after client 1 removes fid1", 4, roadFromClient1.getFeatures().size() ); - assertEquals( "client 2 after client 1 removes fid1", 5, roadFromClient2.getFeatures().size() ); - - roadFromClient2.addFeatures( DataUtilities.collection( chrisFeature )); // road2 adds fid5 on t2 - assertEquals( "auto after client 1 removes fid1 and client 2 adds fid5", 5, roadAuto.getFeatures().size() ); - assertEquals( "client 1 after client 1 removes fid1 and client 2 adds fid5", 4, roadFromClient1.getFeatures().size() ); - assertEquals( "cleint 2 after client 1 removes fid1 and client 2 adds fid5", 6, roadFromClient2.getFeatures().size() ); + roadFromClient1.removeFeatures(selectFid1); // road1 removes fid1 on t1 + + assertEquals("auto after client 1 removes fid1", 5, roadAuto.getFeatures().size()); + assertEquals("client 1 after client 1 removes fid1", 4, roadFromClient1.getFeatures() + .size()); + assertEquals("client 2 after client 1 removes fid1", 5, roadFromClient2.getFeatures() + .size()); + + roadFromClient2.addFeatures(DataUtilities.collection(chrisFeature)); // road2 adds fid5 on t2 + assertEquals("auto after client 1 removes fid1 and client 2 adds fid5", 5, roadAuto + .getFeatures().size()); + assertEquals("client 1 after client 1 removes fid1 and client 2 adds fid5", 4, + roadFromClient1.getFeatures().size()); + assertEquals("cleint 2 after client 1 removes fid1 and client 2 adds fid5", 6, + roadFromClient2.getFeatures().size()); transaction1.commit(); - assertEquals( "auto after client 1 commits removal of fid1 (client 2 has added fid5)", 4, roadAuto.getFeatures().size() ); - assertEquals( "client 1 after commiting removal of fid1 (client 2 has added fid5)", 4, roadFromClient1.getFeatures().size() ); - assertEquals( "client 2 after client 1 commits removal of fid1 (client 2 has added fid5)", 5, roadFromClient2.getFeatures().size() ); - + assertEquals("auto after client 1 commits removal of fid1 (client 2 has added fid5)", 4, + roadAuto.getFeatures().size()); + assertEquals("client 1 after commiting removal of fid1 (client 2 has added fid5)", 4, + roadFromClient1.getFeatures().size()); + assertEquals("client 2 after client 1 commits removal of fid1 (client 2 has added fid5)", + 5, roadFromClient2.getFeatures().size()); + transaction2.commit(); - assertEquals( "auto after client 2 commits addition of fid5 (fid1 previously removed)", 5, roadAuto.getFeatures().size() ); - assertEquals( "client 1 after client 2 commits addition of fid5 (fid1 previously removed)", 5, roadFromClient1.getFeatures().size() ); - assertEquals( "client 2 after commiting addition of fid5 (fid1 previously removed)", 5, roadFromClient2.getFeatures().size() ); + assertEquals("auto after client 2 commits addition of fid5 (fid1 previously removed)", 5, + roadAuto.getFeatures().size()); + assertEquals("client 1 after client 2 commits addition of fid5 (fid1 previously removed)", + 5, roadFromClient1.getFeatures().size()); + assertEquals("client 2 after commiting addition of fid5 (fid1 previously removed)", 5, + roadFromClient2.getFeatures().size()); } - + public void testUseExistingFid() throws Exception { - SimpleFeatureType ROAD = store.getSchema( "road" ); - SimpleFeature chrisFeature = SimpleFeatureBuilder.build(ROAD, new Object[]{ new Integer(5), "chris"}, "fid5" ); + SimpleFeatureType ROAD = store.getSchema("road"); + SimpleFeature chrisFeature = SimpleFeatureBuilder.build(ROAD, new Object[] { + new Integer(5), "chris" }, "fid5"); chrisFeature.getUserData().put(Hints.USE_PROVIDED_FID, Boolean.TRUE); - + SimpleFeatureStore roadAuto = (SimpleFeatureStore) store.getFeatureSource("road"); List fids = roadAuto.addFeatures(DataUtilities.collection(chrisFeature)); - + // checke the id was preserved assertEquals(1, fids.size()); FeatureId fid = SimpleFeatureBuilder.createDefaultFeatureIdentifier("fid5"); assertTrue(fids.contains(fid)); - + // manually check the feature with the proper id is actually there - SimpleFeatureIterator it = roadAuto.getFeatures(ff.id(Collections.singleton(fid))).features(); + SimpleFeatureIterator it = roadAuto.getFeatures(ff.id(Collections.singleton(fid))) + .features(); assertTrue(it.hasNext()); SimpleFeature sf = it.next(); it.close(); diff --git a/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyExamples.java b/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyExamples.java index 685cb2a..bc42ca7 100644 --- a/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyExamples.java +++ b/modules/plugin/property/src/test/java/org/geotools/data/property/PropertyExamples.java @@ -3,16 +3,10 @@ package org.geotools.data.property; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; -import java.io.IOException; import java.io.Serializable; -import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; import java.util.Map; -import java.util.Set; import org.geotools.data.DataStore; import org.geotools.data.DataStoreFinder; @@ -30,20 +24,10 @@ import org.geotools.factory.CommonFactoryFinder; import org.geotools.factory.Hints; import org.geotools.feature.FeatureCollections; import org.geotools.feature.simple.SimpleFeatureBuilder; -import org.geotools.feature.simple.SimpleFeatureTypeBuilder; -import org.geotools.filter.text.cql2.CQL; -import org.geotools.filter.text.cql2.CQLException; -import org.opengis.feature.Feature; -import org.opengis.feature.FeatureVisitor; -import org.opengis.feature.Property; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; -import org.opengis.feature.type.AttributeDescriptor; import org.opengis.filter.Filter; import org.opengis.filter.FilterFactory; -import org.opengis.filter.identity.FeatureId; - -import com.vividsolutions.jts.geom.Geometry; /** * @@ -89,6 +73,7 @@ public class PropertyExamples { transactionExample(); removeAllExample(); appendContent(); + replaceAll(); } catch (Throwable t) { t.printStackTrace(); System.exit(1); @@ -225,8 +210,7 @@ public class PropertyExamples { } finally { writer.close(); } - System.out.println("commit " + t); // only now are the contents - // removed + System.out.println("commit " + t); // now the contents are removed t.commit(); } catch (Throwable eek) { t.rollback(); @@ -238,7 +222,7 @@ public class PropertyExamples { System.out.println("\nremoveAllExample end\n"); } - private void replaceAll() throws Exception { + private static void replaceAll() throws Exception { System.out.println("replaceAll start\n"); // replaceAll start Map params = new HashMap();