001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.data.property;
017:
018: import java.io.File;
019: import java.io.FileInputStream;
020: import java.io.FileOutputStream;
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.io.OutputStream;
024: import java.nio.channels.FileChannel;
025:
026: import org.geotools.data.DataSourceException;
027: import org.geotools.data.DataUtilities;
028: import org.geotools.data.FeatureWriter;
029: import org.geotools.data.Transaction;
030: import org.geotools.feature.Feature;
031: import org.geotools.feature.FeatureType;
032: import org.geotools.feature.IllegalAttributeException;
033:
034: import com.vividsolutions.jts.geom.Envelope;
035:
036: public class PropertyFeatureWriter implements FeatureWriter {
037: PropertyDataStore store;
038:
039: File read;
040: PropertyAttributeReader reader;
041:
042: File write;
043: PropertyAttributeWriter writer;
044:
045: Feature origional = null;
046: Feature live = null;
047:
048: public PropertyFeatureWriter(PropertyDataStore dataStore,
049: String typeName) throws IOException {
050: store = dataStore;
051: File dir = store.directory;
052: read = new File(dir, typeName + ".properties");
053: write = File.createTempFile(typeName
054: + System.currentTimeMillis(), null, dir);
055:
056: reader = new PropertyAttributeReader(read);
057: writer = new PropertyAttributeWriter(write, reader.type);
058: }
059:
060: public FeatureType getFeatureType() {
061: return reader.type;
062: }
063:
064: public boolean hasNext() throws IOException {
065: if (writer == null) {
066: throw new IOException("Writer has been closed");
067: }
068: if (live != null && origional != null) {
069: // we have returned something to the user,
070: // and it has not been writen out or removed
071: //
072: writeImplementation(origional);
073: origional = null;
074: live = null;
075: }
076: return reader.hasNext();
077: }
078:
079: private void writeImplementation(Feature f) throws IOException {
080: writer.next();
081: writer.writeFeatureID(f.getID());
082: for (int i = 0; i < f.getNumberOfAttributes(); i++) {
083: writer.write(i, f.getAttribute(i));
084: }
085: }
086:
087: public Feature next() throws IOException {
088: if (writer == null) {
089: throw new IOException("Writer has been closed");
090: }
091: String fid = null;
092: FeatureType type = reader.type;
093: try {
094: if (hasNext()) {
095: reader.next(); // grab next line
096:
097: fid = reader.getFeatureID();
098: Object values[] = new Object[reader.getAttributeCount()];
099: for (int i = 0; i < reader.getAttributeCount(); i++) {
100: values[i] = reader.read(i);
101: }
102:
103: origional = type.create(values, fid);
104: live = type.duplicate(origional);
105: return live;
106: } else {
107: fid = type.getTypeName() + "."
108: + System.currentTimeMillis();
109: Object values[] = DataUtilities.defaultValues(type);
110:
111: origional = null;
112: live = type.create(values, fid);
113: return live;
114: }
115: } catch (IllegalAttributeException e) {
116: String message = "Problem creating feature "
117: + (fid != null ? fid : "");
118: throw new DataSourceException(message, e);
119: }
120: }
121:
122: public void write() throws IOException {
123: if (live == null) {
124: throw new IOException("No current feature to write");
125: }
126: if (live.equals(origional)) {
127: writeImplementation(origional);
128: } else {
129: writeImplementation(live);
130: if (origional != null) {
131: Envelope bounds = new Envelope();
132: bounds.expandToInclude(live.getBounds());
133: bounds.expandToInclude(origional.getBounds());
134: store.listenerManager.fireFeaturesChanged(live
135: .getFeatureType().getTypeName(),
136: Transaction.AUTO_COMMIT, bounds, false);
137: } else {
138: store.listenerManager.fireFeaturesAdded(live
139: .getFeatureType().getTypeName(),
140: Transaction.AUTO_COMMIT, live.getBounds(),
141: false);
142: }
143: }
144: origional = null;
145: live = null;
146: }
147:
148: public void remove() throws IOException {
149: if (live == null) {
150: throw new IOException("No current feature to remove");
151: }
152: if (origional != null) {
153: store.listenerManager.fireFeaturesRemoved(live
154: .getFeatureType().getTypeName(),
155: Transaction.AUTO_COMMIT, origional.getBounds(),
156: false);
157: }
158: origional = null;
159: live = null; // prevent live and remove from being written out
160: }
161:
162: public void close() throws IOException {
163: if (writer == null) {
164: throw new IOException("writer already closed");
165: }
166: // write out remaining contents from reader
167: // if applicable
168: while (reader.hasNext()) {
169: reader.next(); // advance
170: writer.next();
171: writer.echoLine(reader.line); // echo unchanged
172: }
173: writer.close();
174: reader.close();
175: writer = null;
176: reader = null;
177: read.delete();
178:
179: if (write.exists() && !write.renameTo(read)) {
180: FileChannel out = new FileOutputStream(read).getChannel();
181: FileChannel in = new FileInputStream(write).getChannel();
182: try {
183: long len = in.size();
184: long copied = out.transferFrom(in, 0, in.size());
185:
186: if (len != copied) {
187: throw new IOException("unable to complete write");
188: }
189: } finally {
190: in.close();
191: out.close();
192: }
193: }
194: read = null;
195: write = null;
196: store = null;
197: }
198: }
|