/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2008, 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.geotools.data.property; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.channels.FileChannel; import org.geotools.data.DataSourceException; import org.geotools.data.DataUtilities; import org.geotools.data.FeatureWriter; import org.geotools.data.Transaction; import org.geotools.feature.IllegalAttributeException; import org.geotools.feature.simple.SimpleFeatureBuilder; import org.geotools.geometry.jts.ReferencedEnvelope; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; public class PropertyFeatureWriter implements FeatureWriter<SimpleFeatureType, SimpleFeature> { PropertyDataStore store; File read; PropertyAttributeReader reader; File write; PropertyAttributeWriter writer; SimpleFeature origional = null; SimpleFeature live = null; public PropertyFeatureWriter( PropertyDataStore dataStore, String typeName ) throws IOException { store = dataStore; File dir = store.directory; read = new File( dir, typeName+".properties"); write = File.createTempFile( typeName+System.currentTimeMillis(), null, dir ); reader = new PropertyAttributeReader( read ); writer = new PropertyAttributeWriter( write, reader.type ); } public SimpleFeatureType getFeatureType() { return reader.type; } public boolean hasNext() throws IOException { if( writer == null) { throw new IOException( "Writer has been closed" ); } if( live != null && origional != null ){ // we have returned something to the user, // and it has not been writen out or removed // writeImplementation( origional ); origional = null; live = null; } return reader.hasNext(); } private void writeImplementation( SimpleFeature f ) throws IOException{ writer.next(); writer.writeFeatureID( f.getID() ); for( int i=0; i<f.getAttributeCount(); i++) { if(f.getAttribute(i) == null) writer.write(i, "<null>"); else writer.write( i, f.getAttribute( i )); } } public SimpleFeature next() throws IOException { if( writer == null ) { throw new IOException( "Writer has been closed" ); } String fid = null; SimpleFeatureType type = reader.type; try { if( hasNext() ){ reader.next(); // grab next line fid = reader.getFeatureID(); Object values[] = new Object[ reader.getAttributeCount() ]; for( int i=0; i< reader.getAttributeCount(); i++){ values[i]=reader.read( i ); } origional = SimpleFeatureBuilder.build(type, values, fid ); live = SimpleFeatureBuilder.copy(origional); return live; } else { fid = type.getName()+"."+System.currentTimeMillis(); Object values[] = DataUtilities.defaultValues( type ); origional = null; live = SimpleFeatureBuilder.build(type, values, fid); return live; } } catch (IllegalAttributeException e) { String message = "Problem creating feature "+(fid != null ? fid : ""); throw new DataSourceException( message, e ); } } public void write() throws IOException { if( live == null){ throw new IOException( "No current feature to write"); } if( live.equals( origional )){ writeImplementation( origional ); } else { writeImplementation( live ); if( origional != null){ ReferencedEnvelope bounds = new ReferencedEnvelope(); bounds.include(live.getBounds()); bounds.include(origional.getBounds()); store.listenerManager.fireFeaturesChanged(live.getFeatureType().getTypeName(), Transaction.AUTO_COMMIT, bounds, false); } else { store.listenerManager.fireFeaturesAdded(live.getFeatureType().getTypeName(), Transaction.AUTO_COMMIT, ReferencedEnvelope.reference(live.getBounds()), false); } } origional = null; live = null; } public void remove() throws IOException { if( live == null){ throw new IOException( "No current feature to remove"); } if( origional != null ){ store.listenerManager.fireFeaturesRemoved(live.getFeatureType().getTypeName(), Transaction.AUTO_COMMIT, ReferencedEnvelope.reference(origional.getBounds()), false); } origional = null; live = null; // prevent live and remove from being written out } public void close() throws IOException { if( writer == null ){ throw new IOException( "writer already closed"); } // write out remaining contents from reader // if applicable while( reader.hasNext() ){ reader.next(); // advance writer.next(); writer.echoLine( reader.line ); // echo unchanged } writer.close(); reader.close(); writer = null; reader = null; read.delete(); if (write.exists() && !write.renameTo(read)) { FileChannel out = new FileOutputStream(read).getChannel(); FileChannel in = new FileInputStream(write).getChannel(); try { long len = in.size(); long copied = out.transferFrom(in, 0, in.size()); if (len != copied) { throw new IOException("unable to complete write"); } } finally { in.close(); out.close(); } } read = null; write = null; store = null; } }