001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2003-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; either
009: * version 2.1 of the License, or (at your option) any later version.
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: * Created on Aug 3, 2004
017: */
018: package org.geotools.data.vpf.file;
019:
020: import java.io.File;
021: import java.io.FileNotFoundException;
022: import java.io.IOException;
023: import java.util.ArrayList;
024: import java.util.HashMap;
025: import java.util.Iterator;
026: import java.util.Map;
027: import java.util.StringTokenizer;
028:
029: import org.geotools.data.AbstractDataStore;
030: import org.geotools.data.FeatureReader;
031: import org.geotools.feature.FeatureType;
032: import org.geotools.feature.SchemaException;
033:
034: /**
035: * A data store for VPF files. Any file can be retrieved from here.
036: * If you want joins (for example features with their geometries),
037: * you will have to look elsewhere.
038: * Hopefully some one will take advantage of this class to provide
039: * the full functionality.
040: * @author <a href="mailto:jeff@ionicenterprise.com">Jeff Yutzler</a>
041: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/unsupported/vpf/src/main/java/org/geotools/data/vpf/file/VPFFileStore.java $
042: */
043: public class VPFFileStore extends AbstractDataStore {
044: /**
045: * A collection of files which are available
046: * Don't ask me how/when to close them!
047: */
048: private Map files;
049:
050: /**
051: * Default constructor. Nothing special
052: *
053: */
054: public VPFFileStore() {
055: files = new HashMap();
056: }
057:
058: /* (non-Javadoc)
059: * @see org.geotools.data.AbstractDataStore#getTypeNames()
060: */
061: public String[] getTypeNames() {
062: String[] result = new String[files.size()];
063: int counter = 0;
064: VPFFile currentFile;
065: Iterator iter = files.keySet().iterator();
066:
067: while (iter.hasNext()) {
068: currentFile = (VPFFile) iter.next();
069: result[counter] = currentFile.getTypeName();
070: }
071:
072: return result;
073: }
074:
075: /* (non-Javadoc)
076: * @see org.geotools.data.AbstractDataStore#getSchema(java.lang.String)
077: */
078: public FeatureType getSchema(String pathName) throws IOException {
079: FeatureType result = null;
080:
081: if (files.containsKey(pathName)) {
082: result = (FeatureType) files.get(pathName);
083: } else {
084: try {
085: result = findFile(pathName);
086: } catch (SchemaException exc) {
087: throw new IOException("Schema error in path: "
088: + pathName + "\n" + exc.getMessage());
089: }
090:
091: files.put(pathName, result);
092: }
093:
094: return result;
095: }
096:
097: // How on earth does one get from the query to this method?
098: /* (non-Javadoc)
099: * @see org.geotools.data.AbstractDataStore#getFeatureReader(java.lang.String)
100: */
101: protected FeatureReader getFeatureReader(String pathName)
102: throws IOException {
103: return new VPFFileFeatureReader((VPFFile) getSchema(pathName));
104: }
105:
106: /**
107: * Closes all of the opoen files and removes them from the collection of
108: * open files.
109: *
110: */
111: public void reset() {
112: Iterator iter = files.values().iterator();
113: VPFFile file = null;
114: while (iter.hasNext()) {
115: try {
116: file = (VPFFile) iter.next();
117: file.close();
118: } catch (Exception exc) {
119: // No idea why this might happen
120: exc.printStackTrace();
121: }
122: }
123: files.clear();
124: }
125:
126: /**
127: * This does basically a case independent file search
128: * through the pathName to try to find the file.
129: * This is necessary due to many problems seen with VPF
130: * data disks where the file names specified in the VPF files
131: * do not match the case of the files on disk.
132: **/
133: private VPFFile findFile(String pathName) throws IOException,
134: SchemaException {
135:
136: if (new File(pathName).exists())
137: return new VPFFile(pathName);
138:
139: ArrayList matches = new ArrayList();
140: matches.add(""); // Need to start with something in the list
141: StringTokenizer st = new StringTokenizer(pathName,
142: File.separator);
143: while (st.hasMoreTokens() && !matches.isEmpty()) {
144: String curr = st.nextToken();
145: String currUpper = curr.toUpperCase();
146: String currLower = curr.toLowerCase();
147: boolean useUpper = !curr.equals(currUpper);
148: boolean useLower = !curr.equals(currLower);
149: ArrayList newMatches = new ArrayList();
150:
151: for (Iterator it = matches.iterator(); it.hasNext();) {
152: String match = (String) it.next();
153: String tmp = match + File.separator + curr;
154:
155: if (new File(tmp).exists())
156: newMatches.add(tmp);
157: else {
158: // For performance reasons only do the upper and lower case checks
159: // if the "as-is" check fails.
160: if (useUpper) {
161: tmp = match + File.separator + currUpper;
162: if (new File(tmp).exists())
163: newMatches.add(tmp);
164: }
165:
166: if (useLower) {
167: tmp = match + File.separator + currLower;
168: if (new File(tmp).exists())
169: newMatches.add(tmp);
170: }
171: }
172: }
173: matches = newMatches;
174: }
175:
176: if (matches.isEmpty()) {
177: throw new FileNotFoundException("Could not find file: "
178: + pathName);
179: }
180:
181: return new VPFFile((String) matches.get(0));
182: }
183: }
|