/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2003-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.vpf.file; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.StringTokenizer; import org.geotools.data.AbstractDataStore; import org.geotools.data.FeatureReader; import org.geotools.feature.SchemaException; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; /** * A data store for VPF files. Any file can be retrieved from here. * If you want joins (for example features with their geometries), * you will have to look elsewhere. * Hopefully some one will take advantage of this class to provide * the full functionality. * @author <a href="mailto:jeff@ionicenterprise.com">Jeff Yutzler</a> * * * @source $URL$ */ public class VPFFileStore extends AbstractDataStore { /** * A collection of files which are available * Don't ask me how/when to close them! */ private Map files; /** * Default constructor. Nothing special * */ public VPFFileStore() { files = new HashMap(); } /* (non-Javadoc) * @see org.geotools.data.AbstractDataStore#getTypeNames() */ public String[] getTypeNames() { String[] result = new String[files.size()]; int counter = 0; VPFFile currentFile; Iterator iter = files.keySet().iterator(); while (iter.hasNext()) { currentFile = (VPFFile) iter.next(); result[counter] = currentFile.getTypeName(); } return result; } /* (non-Javadoc) * @see org.geotools.data.AbstractDataStore#getSchema(java.lang.String) */ public SimpleFeatureType getSchema(String pathName) throws IOException { SimpleFeatureType result = null; if (files.containsKey(pathName)) { result = (SimpleFeatureType) files.get(pathName); } else { try { result = findFile(pathName); } catch (SchemaException exc) { throw new IOException("Schema error in path: " + pathName + "\n" + exc.getMessage()); } files.put(pathName, result); } return result; } // How on earth does one get from the query to this method? /* (non-Javadoc) * @see org.geotools.data.AbstractDataStore#getFeatureReader(java.lang.String) */ protected FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(String pathName) throws IOException { return new VPFFileFeatureReader((VPFFile) getSchema(pathName)); } /** * Closes all of the opoen files and removes them from the collection of * open files. * */ public void reset(){ Iterator iter = files.values().iterator(); VPFFile file = null; while(iter.hasNext()){ try { file = (VPFFile)iter.next(); file.close(); } catch (Exception exc) { // No idea why this might happen exc.printStackTrace(); } } files.clear(); } /** * This does basically a case independent file search * through the pathName to try to find the file. * This is necessary due to many problems seen with VPF * data disks where the file names specified in the VPF files * do not match the case of the files on disk. **/ private VPFFile findFile(String pathName) throws IOException, SchemaException { if (new File(pathName).exists()) return new VPFFile(pathName); ArrayList matches = new ArrayList(); matches.add(""); // Need to start with something in the list StringTokenizer st = new StringTokenizer(pathName, File.separator); while (st.hasMoreTokens() && !matches.isEmpty()) { String curr = st.nextToken(); String currUpper = curr.toUpperCase(); String currLower = curr.toLowerCase(); boolean useUpper = !curr.equals(currUpper); boolean useLower = !curr.equals(currLower); ArrayList newMatches = new ArrayList(); for(Iterator it = matches.iterator(); it.hasNext(); ) { String match = (String)it.next(); String tmp = match + File.separator + curr; if (new File(tmp).exists()) newMatches.add(tmp); else { // For performance reasons only do the upper and lower case checks // if the "as-is" check fails. if (useUpper) { tmp = match + File.separator + currUpper; if (new File(tmp).exists()) newMatches.add(tmp); } if (useLower) { tmp = match + File.separator + currLower; if (new File(tmp).exists()) newMatches.add(tmp); } } } matches = newMatches; } if (matches.isEmpty()) { throw new FileNotFoundException("Could not find file: " + pathName); } return new VPFFile((String)matches.get(0)); } }