001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2005-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.mif;
017:
018: import org.geotools.data.AbstractDataStore;
019: import org.geotools.data.FeatureReader;
020: import org.geotools.data.FeatureWriter;
021: import org.geotools.feature.FeatureType;
022: import java.io.File;
023: import java.io.IOException;
024: import java.util.HashMap;
025: import java.util.Iterator;
026:
027: /**
028: * <p>
029: * MIFDataStore gives read and write access to MapInfo MIF files. It can be
030: * instantiated either on a single .mif file, or on a directory (thus exposing
031: * all the mif files within).
032: * </p>
033: *
034: * <p>
035: * MIFDataStore is a replacement for the MapInfoDataStore, which was based on
036: * the legacy MapInfoDataSource.
037: * </p>
038: *
039: * @author Luca S. Percich, AMA-MI
040: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/unsupported/mif/src/main/java/org/geotools/data/mif/MIFDataStore.java $
041: * @version $Id: MIFDataStore.java 22266 2006-10-19 11:30:55Z acuster $
042: */
043: public class MIFDataStore extends AbstractDataStore {
044: // MIF Header clause names
045: public static final String HCLAUSE_VERSION = "version";
046: public static final String HCLAUSE_CHARSET = "charset";
047: public static final String HCLAUSE_DELIMITER = "delimiter";
048: public static final String HCLAUSE_UNIQUE = "unique";
049: public static final String HCLAUSE_INDEX = "index";
050: public static final String HCLAUSE_COORDSYS = "coordsys";
051: public static final String HCLAUSE_TRANSFORM = "transform";
052:
053: // Config parameter names
054: public static final String PARAM_FIELDCASE = "fieldCase";
055: public static final String PARAM_GEOMFACTORY = "geometryFactory";
056: public static final String PARAM_GEOMNAME = "geometryFieldName";
057: public static final String PARAM_GEOMTYPE = "geometryType";
058: public static final String PARAM_SRID = "SRID";
059:
060: // The path in which MIF/MIDs are being stored, or the single MIF file
061: private File filePath;
062:
063: // The parameter maps to pass to MIFFile constructors
064: private HashMap params = null;
065:
066: // A map of MIFFileHolders, indexed by FeatureType name
067: private HashMap mifFileHolders = new HashMap();
068:
069: /**
070: * <p>
071: * Builds a new MIFDataStore given a mif file or directory path.
072: * </p>
073: *
074: * <p>
075: * Each feature type is represented by a MIFFile object
076: * </p>
077: *
078: * @param path location (directory) of the mif files to read, or full path
079: * of a single mif file. If a directory is given, the headers of
080: * all the mif files in it are read.
081: * @param params The MIFFile parameters map, see MIFFile for a full
082: * description.
083: *
084: * @throws IOException Path does not exists, or error accessing files
085: *
086: * @see MIFFile#MIFFile(String, Map)
087: */
088: public MIFDataStore(String path, HashMap params) throws IOException {
089: // TODO use url instead of String
090: super (true); // Is writable
091:
092: this .params = (params != null) ? params : new HashMap();
093:
094: filePath = new File(String.valueOf(path));
095:
096: if (filePath.isDirectory()) {
097: scanFiles(filePath);
098: } else {
099: // Try to access a single .mif file - might have been specified with no extension
100: registerMIF(filePath.getAbsolutePath());
101: }
102: }
103:
104: /**
105: * <p>
106: * Looks for all the .mif files in the given Path
107: * </p>
108: *
109: * @param filePath
110: *
111: * @return the number of mif files found
112: *
113: * @throws IOException
114: */
115: private int scanFiles(File filePath) throws IOException {
116: if (!filePath.isDirectory()) {
117: return 0;
118: }
119:
120: File[] files = filePath.listFiles();
121:
122: int found = 0;
123:
124: for (int i = 0; i < files.length; i++) {
125: String fName = files[i].getName();
126:
127: if ((fName.length() > 4)
128: && (fName.toLowerCase().indexOf(".mif") == (fName
129: .length() - 4))) {
130: fName = fName.substring(0, fName.length() - 4);
131:
132: if (mifFileHolders.get(fName) == null) {
133: registerMIF(files[i].getAbsolutePath());
134: found++;
135: }
136: }
137: }
138:
139: return found;
140: }
141:
142: /**
143: * <p>
144: * Given a FeatureType, creates the corresponding MIFFile object in the
145: * current directory
146: * </p>
147: * .
148: *
149: * @param featureType The FeatureType
150: *
151: * @throws IOException if init path is not a directory or a MIFFile object
152: * cannot be created
153: */
154: public void createSchema(FeatureType featureType)
155: throws IOException {
156: if (!filePath.isDirectory()) {
157: throw new IOException(
158: "Can't create schema on a MIF DataStore instantiated from a single MIF file");
159: }
160:
161: try {
162: File newFile = new File(filePath, featureType.getTypeName()
163: + ".mif");
164: MIFFile mf = new MIFFile(newFile.getAbsolutePath(),
165: featureType, params);
166: MIFFileHolder mfh = new MIFFileHolder(mf);
167: mifFileHolders.put(mf.getSchema().getTypeName(), mfh);
168: } catch (Exception e) {
169: throw new IOException("Unable to create MIFFile object: "
170: + e.getMessage());
171: }
172: }
173:
174: /**
175: * <p>
176: * Returns the list of type names (mif files)
177: * </p>
178: *
179: * @return The list of type names
180: *
181: * @throws IOException Couldn't scan path for files
182: */
183: public String[] getTypeNames() throws IOException {
184: scanFiles(filePath); // re-scans path just in case some file was added
185:
186: String[] names = new String[mifFileHolders.size()];
187: int index = 0;
188:
189: for (Iterator i = mifFileHolders.keySet().iterator(); i
190: .hasNext();)
191: names[index++] = (String) i.next();
192:
193: return names;
194: }
195:
196: /**
197: * <p>
198: * Returns the schema given a type name
199: * </p>
200: *
201: * @param typeName
202: *
203: *
204: * @throws IOException
205: */
206: public FeatureType getSchema(String typeName) throws IOException {
207: return getMIFFile(typeName).getSchema();
208: }
209:
210: /**
211: * Gets a FeatureReader from a MIFFile object
212: *
213: * @param typeName name of the FeatureType
214: *
215: * @return The FeatureReader
216: *
217: * @throws IOException
218: */
219: protected FeatureReader getFeatureReader(String typeName)
220: throws IOException {
221: return getMIFFile(typeName).getFeatureReader();
222: }
223:
224: /**
225: * Gets a FeatureWriter from a MIFFile object
226: *
227: * @param typeName
228: *
229: *
230: * @throws IOException
231: */
232: protected FeatureWriter getFeatureWriter(String typeName)
233: throws IOException {
234: return getMIFFile(typeName).getFeatureWriter();
235: }
236:
237: /**
238: * <p>
239: * Loads a MIF file header and create the corresponding schema.
240: * </p>
241: *
242: * @param path path of single .MIF file.
243: *
244: * @throws IOException
245: */
246: private void registerMIF(String path) throws IOException {
247: MIFFile mf = new MIFFile(path, params);
248: MIFFileHolder mfh = new MIFFileHolder(mf);
249: FeatureType ft = mf.getSchema();
250: mifFileHolders.put(ft.getTypeName(), mfh);
251: }
252:
253: /**
254: * <p>
255: * Returns a MIFFile object given its type name.
256: * </p>
257: *
258: * @param typeName
259: *
260: */
261: private MIFFile getMIFFile(String typeName) {
262: MIFFileHolder mifHolder = (MIFFileHolder) mifFileHolders
263: .get(typeName);
264:
265: if (mifHolder != null) {
266: return mifHolder.mifFile;
267: }
268:
269: try {
270: if (scanFiles(filePath) == 0) {
271: return null; // no more file read
272: }
273: } catch (IOException e) {
274: }
275:
276: mifHolder = (MIFFileHolder) mifFileHolders.get(typeName);
277:
278: if (mifHolder != null) {
279: return mifHolder.mifFile;
280: }
281:
282: return null;
283: }
284:
285: // Utility class for holding MIFFile objects
286: private class MIFFileHolder {
287: private MIFFile mifFile = null;
288:
289: //private boolean modified = false;
290: //private boolean inSync = true;
291: private MIFFileHolder(MIFFile mifFile) {
292: this.mifFile = mifFile;
293: }
294: }
295: }
|