/* Copyright (c) 2006 Ricebridge. All Rights Reserved. * * This file is available under the terms and conditions of the * Ricebridge "Open Source API" policy; Ricebridge grants use of this * copyrighted work under the terms of a BSD-style license only. See * http://www.opensource.org/licenses/bsd-license.php for more * information. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * - Neither the name of the Ricebridge nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.ricebridge.csvman; /** Load CSV data lines as you need them. * <p>This interface allows you to load CSV data lines as a stream of data, one at a time. Instead * of loading an entire CSV file, as with the {@link CsvManager#load(Object) CsvManager.load} method, or * implementing a {@link CustomLineListener}, <code>CsvLoader</code> lets you access the data * directly using {@link java.util.Iterator}-style <code>hasNext</code> and <code>next</code> methods.</p> * <p>To start a loading operation, use the {@link CsvManager#makeLoader(Object) CsvManager.makeLoader} * method. This returns a <code>CsvLoader</code> object. Then use the following sequence * of method calls:</p> * <ul><li>{@link #begin} - required, tells the <code>CsvLoader</code> to open the data resource (usually a CSV file on disk)</li> * <li>{@link #hasNext} - required, returns <code>true</code> if there's another line of data left</li> * <li>{@link #next} - required, returns the next line of data as a <code>String[]</code> array</li> * <li>{@link #end} - required, tells the <code>CsvLoader</code> to close the data resource (usually a CSV file on disk)</li></ul> * <p>Here is some example code:</p> * <pre><!--code-[--> * File csvfile = new File( "mydata.csv" ); * CsvManager csvman = new CsvManager(); * CsvLoader loader = csvman.makeLoader( csvfile ); * * loader.begin(); * while( loader.hasNext() ) { * String[] fields = loader.next(); * * for( int field = 0; field < fields.length; field++ ) { * System.out.print( fields[field]+", " ); * } * System.out.println(); * } * loader.end(); * <!--code-]--></pre> * <p>Because only one line is read at a time, * you can use <code>CsvLoader</code> to load really big CSV files without running out of memory.</p> * <p>Why does <code>CsvLoader</code> have {@link #begin} and {@link #end} methods and why do you need to call them? * Good question! Unlike the other ways of loading CSV data provided by <i>CSV Manager</i>, when you use * a <code>CsvLoader</code>, <i>you</i> control the loading process. That means you control how often a new data line * is extracted from the CSV file. And you control when the loading process begins and ends. You can begin the * loading process sometime after you actually create the <code>CsvLoader</code>, and you can end it at any time, without having * to load the entire file.</p> * <p><b>Error Handling:</b> if the CSV file contains a badly-formatted line, then a {@link CsvManagerException} will * be thrown from the {@link #next} method. If the {@link CsvSpec#setIgnoreBadLines setIgnoreBadLines} setting * is <code>true</code>, then you can continue to call {@link #hasNext} and {@link #next} after a bad line * <code>Exception</code>. You just have to deal with the <code>Exception</code> yourself. Note that each data line * is actually read in the <code>hasNext</code> method and stored for retrieval from the <code>next</code> method.</p> * <p>If you also want to save CSV data one line at a time, check out the {@link CsvSaver} class, which works in * pretty much the same way as <code>CsvLoader</code>. </p> * <p>The <b><a href="CsvLoader.java.html">Source Code</a></b> of this Java class * is available under a <a href="http://www.opensource.org/licenses/bsd-license.php">BSD-style license</a>.</p> * * @since 1.2.1 * @see CsvSaver * @see LineListener * @see CsvManager#load(Object) */ public interface CsvLoader { /** Tell the <code>CsvLoader</code> you want to begin the loading process. * <p>This is where the CSV file input stream is opened for reading.</p> */ public void begin(); /** Check if there's another line of data in the CSV file, and return <code>true</code> if so. * <p>Note: this method actually has to load the next line of data to know if there is one, so this method is * where data is read from the CSV file. You can get the line of data using the {@link #next} method.</p> */ public boolean hasNext(); /** Get the next line of data as a <code>String[]</code> array. * <p><code>CsvLoader</code> always returns the data as a <code>String[]</code> array. * To get the data into another format, you will have to convert the data yourself. For example, * you can use the utility classes {@link CsvResultSet} and {@link CsvTableModel} to create * {@link java.sql.ResultSet ResultSets} and {@link javax.swing.table.TableModel TableModels}. * Review the source code of the appropriate {@link LineListener} to see how they are used.</p> * <p>The length of the <code>String[]</code> array returned by this method will be at least * {@link CsvSpec#setNumFields CsvSpec.setNumFields} elements. If longer lines are encountered, then * the array will be as long as the longest line seen so far. Empty fields at the end are returned * as empty <code>Strings</code>. This approach prevents {@link ArrayIndexOutOfBoundsException} and * {@link NullPointerException} errors. However, if you do need to know the exact number of data fields * in any given CSV line then you should use a {@link CustomLineListener} instead, which provides * more information about each line.</p> * <p><b>Error Handling:</b> when an error occurs, this method always throws a {@link CsvManagerException}. * The details of the bad line are available via the * {@link CsvManagerException#getBadLine CsvManagerException.getBadLine} method. An exception is also thrown * even if {@link CsvSpec#setIgnoreBadLines CsvSpec.setIgnoreBadLines} is set to <code>true</code>. However in * this case you can continue to call {@link #hasNext} and <code>next</code> to get the remaining good lines and you * are not required to stop processing.</p> */ public String[] next(); /** Tell the <code>CsvLoader</code> you want to end the loading process. * <p>This is where the CSV file input stream is closed.</p> */ public void end(); }