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.BufferedReader;
019: import java.io.File;
020: import java.io.FileReader;
021: import java.io.IOException;
022: import java.util.NoSuchElementException;
023:
024: import org.geotools.data.AttributeReader;
025: import org.geotools.data.DataSourceException;
026: import org.geotools.data.DataUtilities;
027: import org.geotools.feature.AttributeType;
028: import org.geotools.feature.FeatureType;
029: import org.geotools.feature.GeometryAttributeType;
030: import org.geotools.feature.SchemaException;
031: import org.geotools.util.Converters;
032:
033: import com.vividsolutions.jts.geom.GeometryFactory;
034: import com.vividsolutions.jts.io.ParseException;
035: import com.vividsolutions.jts.io.WKTReader;
036:
037: /**
038: * Simple AttributeReader that works against Java properties files.
039: *
040: * <p>
041: * This AttributeReader is part of the geotools2 DataStore tutorial, and should
042: * be considered a Toy.
043: * </p>
044: *
045: * <p>
046: * The content of this file should start with a the property "_" with the value
047: * being the typeSpec describing the featureType. Thereafter each line will
048: * should have a FeatureID as the property and the attribtues as the value
049: * separated by | characters.
050: * </p>
051: * <pre><code>
052: * _=id:Integer|name:String|geom:Geometry
053: * fid1=1|Jody|<i>well known text</i>
054: * fid2=2|Brent|<i>well known text</i>
055: * fid3=3|Dave|<i>well known text</i>
056: * </code></pre>
057: *
058: *<p>
059: * May values may be represented by a special tag: <code><null></code>. An empty element: <code>||</code>
060: * is interprested as the empty string:
061: *</p>
062: *<pre>
063: * <code>
064: * fid4=4||<null> -> Feature( id=2, name="", geom=null )
065: * </code>
066: *</pre>
067: * @author jgarnett
068: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/demo/property/src/main/java/org/geotools/data/property/PropertyAttributeReader.java $
069: */
070: public class PropertyAttributeReader implements AttributeReader {
071: /** DOCUMENT ME! */
072: private static final WKTReader wktReader = new WKTReader(
073: new GeometryFactory());
074:
075: /** DOCUMENT ME! */
076: BufferedReader reader;
077:
078: /** DOCUMENT ME! */
079: FeatureType type;
080:
081: /** DOCUMENT ME! */
082: String line;
083:
084: /** DOCUMENT ME! */
085: String next;
086:
087: String[] text;
088:
089: String fid;
090:
091: /**
092: * Creates a new PropertyAttributeReader object.
093: *
094: * @param file DOCUMENT ME!
095: *
096: * @throws IOException DOCUMENT ME!
097: * @throws DataSourceException DOCUMENT ME!
098: */
099: public PropertyAttributeReader(File file) throws IOException {
100: String typeName = typeName(file);
101: String namespace = namespace(file);
102: reader = new BufferedReader(new FileReader(file));
103:
104: //read until "_=";
105: while ((line = reader.readLine()) != null) {
106: if (line.startsWith("_="))
107: break;
108: }
109:
110: if ((line == null) || !line.startsWith("_=")) {
111: throw new IOException(typeName + " schema not available");
112: }
113:
114: String typeSpec = line.substring(2);
115:
116: try {
117: type = DataUtilities.createType(namespace + typeName,
118: typeSpec);
119: } catch (SchemaException e) {
120: throw new DataSourceException(typeName
121: + " schema not available", e);
122: }
123:
124: line = null;
125: next = null;
126: }
127:
128: /**
129: * DOCUMENT ME!
130: *
131: * @param file DOCUMENT ME!
132: *
133: * @return DOCUMENT ME!
134: */
135: private static String typeName(File file) {
136: String name = file.getName();
137: int split = name.lastIndexOf('.');
138:
139: return (split == -1) ? name : name.substring(0, split);
140: }
141:
142: /**
143: * DOCUMENT ME!
144: *
145: * @param file DOCUMENT ME!
146: *
147: * @return DOCUMENT ME!
148: */
149: private static String namespace(File file) {
150: File parent = file.getParentFile();
151:
152: return (parent == null) ? "" : (parent.getName() + ".");
153: }
154:
155: /**
156: * DOCUMENT ME!
157: *
158: * @return DOCUMENT ME!
159: */
160: public int getAttributeCount() {
161: return type.getAttributeCount();
162: }
163:
164: /**
165: * DOCUMENT ME!
166: *
167: * @param index DOCUMENT ME!
168: *
169: * @return DOCUMENT ME!
170: *
171: * @throws ArrayIndexOutOfBoundsException DOCUMENT ME!
172: */
173: public AttributeType getAttributeType(int index)
174: throws ArrayIndexOutOfBoundsException {
175: return type.getAttributeType(index);
176: }
177:
178: /**
179: * DOCUMENT ME!
180: *
181: * @throws IOException DOCUMENT ME!
182: */
183: public void close() throws IOException {
184: reader.close();
185: reader = null;
186: }
187:
188: /**
189: * DOCUMENT ME!
190: *
191: * @return DOCUMENT ME!
192: *
193: * @throws IOException DOCUMENT ME!
194: */
195: public boolean hasNext() throws IOException {
196: if (next != null) {
197: return true;
198: }
199:
200: next = reader.readLine();
201:
202: return next != null;
203: }
204:
205: /**
206: * DOCUMENT ME!
207: *
208: * @throws IOException DOCUMENT ME!
209: * @throws NoSuchElementException DOCUMENT ME!
210: */
211: public void next() throws IOException {
212: if (hasNext()) {
213: line = next;
214: next = null;
215:
216: int split = line.indexOf('=');
217: fid = line.substring(0, split);
218: text = line.substring(split + 1).split("\\|");
219: if (type.getAttributeCount() != text.length)
220: throw new DataSourceException("format error: expected "
221: + type.getAttributeCount()
222: + " attributes, but found " + text.length
223: + ". [" + line + "]");
224: } else {
225: throw new NoSuchElementException();
226: }
227: }
228:
229: /**
230: * DOCUMENT ME!
231: *
232: * @return DOCUMENT ME!
233: */
234: public String getFeatureID() {
235: if (line == null) {
236: return null;
237: }
238:
239: return fid;
240: }
241:
242: /**
243: * DOCUMENT ME!
244: *
245: * @param index DOCUMENT ME!
246: *
247: * @return DOCUMENT ME!
248: *
249: * @throws IOException DOCUMENT ME!
250: * @throws ArrayIndexOutOfBoundsException DOCUMENT ME!
251: * @throws DataSourceException DOCUMENT ME!
252: */
253: public Object read(int index) throws IOException,
254: ArrayIndexOutOfBoundsException {
255: if (line == null) {
256: throw new IOException(
257: "No content available - did you remeber to call next?");
258: }
259:
260: AttributeType attType = type.getAttributeType(index);
261:
262: String stringValue = null;
263: try {
264: stringValue = text[index];
265: } catch (RuntimeException e1) {
266: e1.printStackTrace();
267: stringValue = null;
268: }
269:
270: //check for special <null> flag
271: if ("<null>".equals(stringValue)) {
272: stringValue = null;
273: }
274: if (stringValue == null) {
275: return null;
276: }
277:
278: //parse the value
279: Object value = null;
280:
281: if (attType instanceof GeometryAttributeType) {
282: try {
283: value = wktReader.read(stringValue);
284: } catch (ParseException e) {
285: throw new DataSourceException(
286: "Can't parse WKT for fid#" + fid, e);
287: }
288: } else {
289: value = Converters.convert(stringValue, attType.getType());
290: }
291:
292: return value;
293: }
294: }
295:
296: /*
297: POINT(529264 4801784)|
298: 038-54|
299: 48|
300: 041|
301: 106|
302: Caser?o Zaldegietxebarrierdikoa (Txopenebenta)|
303: Zaldegietxebarrierdikoa baserria (Txopebenta)|
304: Zaldegietxebarrierdikoa (Txopebenta)|
305: Zaldegietxebarrierdikoa, Caser?o (Txopebenta)|
306: Zaldegietxebarrierdikoa bas
307: */
|