/* Copyright (c) 2003-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;


/** Use this interface to create custom CSV data loaders.
 *    <p>This callback interface allows you to handle each data line separately as it is loaded.
 *  To implement this interface, please extend {@link CustomLineListener}, as that will help keep your code 
 *  compatible with future versions.</p>  
 *    <p>To use a <code>LineListener</code>, call the {@link CsvManager#load(Object, LineListener)} or 
 *  {@link CsvManager#load(Object, LineSpec, LineListener)} methods.</p>
 *    <p>When you pass an instance of <code>LineListener</code> to {@link CsvManager}, it will
 *  call the {@link #handleLine handleLine} method each time a data line is loaded. 
 *  The string values of the data fields are provided as
 *  a <code>String[]</code> array. When a badly formatted line is encountered, 
 *  the {@link #handleBadLine handleBadLine} method is called instead.</p>
 *    <p>As <code>CsvManager</code> loads the CSV data, it calls the
 *  methods of the <code>LineListener</code> in a defined sequence:</p>
 *    <ol><li>{@link #setCsvSpec setCsvSpec}</li>
 *        <li>{@link #setLineSpec setLineSpec}</li>
 *        <li>{@link #startProcess startProcess}</li>
 *        <li>{@link #handleLine handleLine}</li>
 *        <li>{@link #endProcess endProcess}</li></ol>
 *    <p>The {@link #handleLine handleLine} method is called once for each line in the CSV file.</p>
 *    <p>When writing your own <code>LineListener</code>, the easiest way to get started is to review the source code for the
 *  existing <code>LineListeners</code> used by <code>CsvManager</code>. <code>CsvManager</code> uses <code>LineListeners</code> 
 *  internally for all data loading operations.
 *  The {@link BasicLineListener} is a very simple example and a good place to start.
 *  Here is the full list of standard <code>LineListeners</code>:</p>
 *    <ul><li>{@link BasicLineListener}</li>
 *        <li>{@link AsListsLineListener}</li>
 *        <li>{@link TableModelLineListener}</li>
 *        <li>{@link ResultSetLineListener}</li>
 *        <li>{@link BeanLineListener}</li></ul>
 *    <p>Note: you may assume in your implementation that no parameters are <code>null</code>.</p>
 *    <p><b>Error Handling</b><br />
 *  The <code>handleLine</code> method can return a {@link BadLine} object that describes a semantically incorrect
 *  line of data. This allows you to perform validation against the input data. You can also return a <code>BadLine</code> when database
 *  access fails, or some other problem occurs. When everything is OK, there is no need to return a <code>BadLine</code>, 
 *  simply return <code>null</code> from the <code>handleLine</code> method. You can also allow <code>Exceptions</code> to pass up
 *  to the <code>CustomLineListener</code> class, without handling them yourself. 
 *  In this case <code>CsvManager</code> will handle them for you, either
 *  halting the load operation, or creating a <code>BadLine</code> and storing it, depending on the value of the
 *  {@link CsvSpec#setIgnoreBadLines CsvSpec.setIgnoreBadLines} setting.</p>
 *    <p>If you set <code>setIgnoreBadLines</code> to <code>true</code> then loading of CSV data will continue
 *  even when badly formatted data lines are encountered. If this setting is <code>false</code> (the default), then loading is halted
 *  and a {@link CsvManagerException} <code>(CODE_bad_line)</code> is thrown <i>after</i> <code>handleBadLine</code> is called.</p>
 *    <p><b>Important</b><br />
 *  In order to ensure the greatest compatibility with future releases and to take advantage of additional error handling
 *  functionality, please implement your <code>LineListener</code> by extending the abstract {@link CustomLineListener} class.
 *  This class ensures that all data you receive is well-formed (no <code>nulls</code>), and also creates standard
 *  exceptions when problems do occur.</p>
 *    <p>Compatibility Note: <i>CSV Manager 1.1</i> used {@link LineListenerSupport}
 *  instead of <code>CustomLineListener</code>. Existing code will still work with this base class, but you should
 *  always use <code>CustomLineListener</code> for new code.</p> 
 *    <p>The <b><a href="LineListener.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>
 *  
 *  @see CustomLineListener
 *  @see BasicLineListener
 *  @see CsvManager
 *  @see CsvManagerException
 */
public interface LineListener {

  /** Set the current {@link CsvSpec} settings.
   *   <p>You can implement this method to get the values of the current settings,
   *  and use them to modify your data handling. For example, {@link TableModelLineListener}
   *  uses the custom property <code>TableModel.editable</code> to make any 
   *  {@link javax.swing.table.TableModel TableModels} that it returns editable. You can easily use your own
   *  custom properties by calling the {@link CsvSpec#setProperty(String, String) CsvSpec.setProperty} method.</p>
   *    <p>Note: to actually set the {@link CsvSpec} object, you use {@link CsvManager#setCsvSpec CsvManager.setCsvSpec}.</p>
   *    <p><b>Implement by overriding {@link CustomLineListener#setCsvSpecImpl CustomLineListener.setCsvSpecImpl}.</b></p>
   *  @param pCsvSpec <code>CsvSpec</code> object
   */
  public void setCsvSpec( CsvSpec pCsvSpec );



  /** Set the current {@link LineSpec} settings.
   *   <p>You can implement this method to get the current <code>LineSpec</code> you specified for the data you are loading.
   *  The <code>LineSpec</code> provides additional information about each data field. For example, {@link BeanLineListener}
   *  uses the {@link LineSpec#getFieldNames field names} metadata to determine the right get and set methods for
   *  each data field.</p>
   *   <p>You can add your own metadata for use by {@link CustomLineListener CustomLineListeners} 
   *  by subclassing <code>LineSpec</code> and adding appropriate methods to return your custom metadata.</p>
   *  <p><b>Implement by overriding {@link CustomLineListener#setLineSpecImpl CustomLineListener.setLineSpecImpl}.</b></p>
   *  @param pLineSpec <code>LineSpec</code> object
   */
  public void setLineSpec( LineSpec pLineSpec );

  
  /** Called just before loading of the CSV data starts.
   *    <p>You should use this method to initialise any data receivers in your <code>LineListener</code>.
   *  For example, you can initialise any database connections or other resources that you need to use to process the data.</p>
   *    <p><b>Implement by overriding {@link CustomLineListener#startProcessImpl CustomLineListener.startProcessImpl}.</b></p>
   *  @see #endProcess
   */
  public void startProcess();


  
  /** Implement this method to directly access the data for each line as it is parsed. 
   *    <p>The parameter <code>pLine</code> is a <code>String[]</code> that is normally
   *  {@link CsvSpec#setNumFields setNumFields} in length. If fewer than
   *  <code>pNumFields</code> columns are found in the current line, then
   *  the remaining elements of <code>pLine</code> are empty strings. If more than
   *  <code>pNumFields</code> columns are found, then <code>pLine</code> is a <code>String[]</code> array large enough to
   *  contain all data fields found. In both cases, the parameter <code>pNumFields</code>   
   *  indicates the exact number of data fields found.</p>
   *    <p>This method should return a {@link BadLine} object if the data in <code>pLine</code>
   *  was invalid in some way. Data lines that cannot be parsed due to syntax errors are not sent to the
   *  <code>LineListener</code> via this method. However, syntactically correct lines may still contain invalid data
   *  and this should be indicated by returning a {@link BadLine} object describing the problem from this method. 
   *  Return <code>null</code>
   *  if the data was acceptable. This return value is used to maintain internal bad line counts so that
   *  the loading statistics are correct. The use of a return value rather than an <code>Exception</code> was chosen
   *  for performance reasons. You may still throw a {@link java.lang.RuntimeException} from within this method
   *  and {@link CsvManager} will record the error, passing on the <code>Exception</code> contained in
   *  a {@link CsvManagerException} ({@link CsvManagerException#CODE_internal_exception CODE_internal_exception}, 
   *  or continuing to load data if {@link CsvManager#setIgnoreBadLines} is <code>true</code>.</p>
   *    <p><b>Implement by overriding {@link CustomLineListener#handleLineImpl CustomLineListener.handleLineImpl}.</b></p>
   *
   *  @param pLine line data as text
   *  @param pNumFields number of data fields found
   *  @param pLineNumber line number index, counting from 1
   *  @param pOriginalLine original line of data
   *  @return <code>null</code> if line is OK, {@link BadLine} object if line was bad in some way
   */
  public BadLine handleLine( String[] pLine, int pNumFields, long pLineNumber, String pOriginalLine );


  /** Called when a badly formatted data line is encountered.
   *    <p>This method is only called once (and data loading stops) 
   *  if {@link CsvManager#setIgnoreBadLines} is <code>false</code> (the default).
   *  If {@link CsvManager#setIgnoreBadLines} is <code>true</code>, each badly formatted line is 
   *  sent to the <code>LineListener</code> implementation via this method.</p>
   *    <p>The text of the badly formatted line is given by {@link BadLine#getOriginalLine} and
   *  the parser error message (or other internal error) is given in the {@link BadLine#getErrorMsg}.</p>
   *    <p>The error message description passed to this method is not suitable for non-technical users. To get a user-friendly message set
   *  {@link CsvManager#setIgnoreBadLines} to <code>false</code> and call {@link CsvManagerException#toString} on any
   *  {@link CsvManagerException}s that are thrown while loading CSV data.</p>
   *    <p><b>Implement by overriding {@link CustomLineListener#handleBadLineImpl CustomLineListener.handleBadLineImpl}.</b></p>
   *  @param pBadLine {@link BadLine} object describing problem
   */
  public void handleBadLine( BadLine pBadLine );



  /** Called just after loading of the CSV data ends.
   *    <p>You should use this method to release any resources used by your <code>LineListener</code>.</p>
   *    <p><b>Implement by overriding {@link CustomLineListener#endProcessImpl CustomLineListener.endProcessImpl}.</b></p>
   *  @see #startProcess
   */
  public void endProcess();

}
Syntax Highlighting created using the com.Ostermiller.Syntax package.
Saturday, October 28 2006 at 12:45