// ********************************************************************** // // <copyright> // // BBN Technologies // 10 Moulton Street // Cambridge, MA 02138 // (617) 873-8000 // // Copyright (C) BBNT Solutions LLC. All rights reserved. // // </copyright> // ********************************************************************** // // $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/io/CSVFile.java,v $ // $RCSfile: CSVFile.java,v $ // $Revision: 1.8 $ // $Date: 2005/08/09 18:00:47 $ // $Author: dietrick $ // // ********************************************************************** package com.bbn.openmap.io; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.util.Iterator; import java.util.Vector; import com.bbn.openmap.util.CSVTokenizer; import com.bbn.openmap.util.Debug; import com.bbn.openmap.util.PropUtils; /** * The CSVFile holds on to the contents of a CSV file. * <P> * NOTE: By default, the numbers that are found in the CSV file are converted to * Doubles. Use the load(boolean) method to control this, especially if you are * using the fields later as the key in a Hashtable. */ public class CSVFile implements Iterable<Vector<Object>> { /** The location of the CSV file */ public URL infoUrl; /** The records of the CSV file */ protected Vector<Vector<Object>> infoRecords = null; /** The header record, if there is one */ protected Vector<Object> headerRecord = null; /** Whether file has a line of column headers. */ protected boolean headersExist = true; /** * Don't do anything special, since all defaults are set already */ public CSVFile(String name) throws MalformedURLException { infoUrl = PropUtils.getResourceOrFileOrURL(name); } /** * Don't do anything special, since all defaults are set already */ public CSVFile(URL url) throws MalformedURLException { infoUrl = url; } /** * Set whether the first line should be considered as headers to each column. */ public void setHeadersExist(boolean set) { headersExist = set; } /** * Get whether the first line should be considered as headers to each column. */ public boolean isHeadersExist() { return headersExist; } /** * Reads the numbers and stores them as Doubles. */ public void loadData() { loadData(false); } /** * Read the data in from the file, with the option of reading the numbers in * the files as strings. */ public void loadData(boolean readNumbersAsStrings) { BufferedReader streamReader = null; Vector<Vector<Object>> records = new Vector<Vector<Object>>(); try { Object token = null; boolean header_read = false; if (!headersExist) { header_read = true; headerRecord = new Vector<Object>(); } // This lets the property be specified as a file name // even if it's not specified as file:/<name> in // the properties file. URL csvURL = infoUrl; streamReader = new BufferedReader(new InputStreamReader(csvURL.openStream())); CSVTokenizer csvt = new CSVTokenizer(streamReader, readNumbersAsStrings); int count = 0; token = csvt.token(); while (!csvt.isEOF(token)) { count++; Vector<Object> rec_line = new Vector<Object>(); while (!csvt.isNewline(token)) { rec_line.addElement(token); token = csvt.token(); if (csvt.isEOF(token)) break; } // Don't add the header record, because we don't care // about it. if (header_read) { records.addElement(rec_line); } else if (headersExist) { headerRecord = rec_line; header_read = true; } if (Debug.debugging("csv")) { Debug.output("CSVFile.read: " + rec_line); } token = csvt.token(); } csvt.close(); } catch (java.io.IOException ioe) { throw new com.bbn.openmap.util.HandleError(ioe); } catch (ArrayIndexOutOfBoundsException aioobe) { throw new com.bbn.openmap.util.HandleError(aioobe); } catch (ClassCastException cce) { throw new com.bbn.openmap.util.HandleError(cce); } catch (NullPointerException npe) { // Usually gets fired when the URL isn't properly formatted in windows Debug.error("CSVFile can't open: " + infoUrl + ", check URL notation."); } infoRecords = records; if (Debug.debugging("csv")) { Debug.output("CSVFile: read in " + infoRecords.size() + " records"); } } /** * @return the number of records read. */ public int getNumberOfRecords() { int numberOfRecords = 0; if (infoRecords != null) { numberOfRecords = infoRecords.size(); } return numberOfRecords; } /** * Return a particular Vector representing the contents of a record line in * the CSV file. The record choice is picked via the record number given * -zero is the first one, and the header record, if it exists, does not * count. * * @param recordnumber the number of the record in the csv file. * @return Vector Vector of contents of record line. */ public Vector<Object> getRecord(int recordnumber) { Vector<Object> vector; try { vector = infoRecords.elementAt(recordnumber); } catch (ArrayIndexOutOfBoundsException e) { Debug.error(infoUrl.toString() + ": Don't have information for shape record " + recordnumber); return null; } return vector; } /** * Return an iterator, that can be used to traverse the records of the file. * * @return Iterator */ public Iterator<Vector<Object>> iterator() { if (infoRecords != null) { return infoRecords.iterator(); } else { return new Vector<Vector<Object>>().iterator(); } } }