|
|||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||||
java.lang.Objectcom.ricebridge.csvman.LineListenerSupportImpl
com.ricebridge.csvman.CustomLineListener
Extend this class to create your own LineListener.
You can create custom data from CSV files by overriding and implementing the
methods in this class. The basic idea is that you implement the handleLineImpl
method which is called each time a line of CSV data is read from the CSV file. You can then use this data
in whatever way you need.
Here's a very simple example. This LineListener just prints out any data that is loaded. You might use
this for debugging or logging.
import com.ricebridge.csvman.*;
public class PrintingLineListener extends CustomLineListener {
protected BadLine handleLineImpl( String[] pLine, int pNumFields,
long pLineNumber, String pOriginalLine )
{
for( int field = 0; field < pNumFields; field++ ) {
System.out.print( pLine[field] + ", " );
}
System.out.println();
return null;
}
}
You can see from this code that instead of implementing the public LineListener.handleLine
method directly, you implement the protected handleLineImpl method. This insulates you from
API changes and also provides an extra layer of error checking. And CustomLineListener provides default
implementations for most of the methods of LineListener,
so handleLineImpl is the only one you need to worry about.
The handleLineImpl method itself provides you with a lot of information about the
line of CSV data that was just loaded. You get a String[] array (pLine),
containing all the data. In order to reduce errors, this array is always the same size. For lines that
are missing data fields, CSV Manager will add in empty String elements at the end of the array.
Of course, you may want to know exactly how many fields there were in the line, so that's what pNumFields tell you.
When some data fields are missing, pNumFields with then be less than pLine.length.
CSV Manager also gives you the line number (pLineNumber),
and the text of the original line (pOriginalLine), as it appears in the CSV file.
This is so that you can produce nice error messages and logs.
Here's how you actually use this class:
CsvManager csvman = new CsvManager();
PrintingLineListener pln = new PrintingLineListener();
csvManager.load( "input-file.csv", pln );
You just create a new instance of PrintingLineListener,
and then pass it to CsvManager.
When using custom LineListeners, the only thing that is
different from the normal load methods is that there is no return value.
All the data is passed to the custom LineListener instead.
You can still access this data by calling get methods on the custom LineListener.
Of course, you'll have to write those get methods yourself.
For more information about implementing your own LineListeners,
see the LineListener interface documentation. Also, take a look at the other methods you can implement:
Note: You can implement the LineListener interface directly if you need to. The danger is that your
implementation may not remain compatible with future versions of CSV Manager. And you lose all the extra error-handling.
So it's better to stick with extending CustomLineListener if you can.
Finally, if you want to save data with custom processing, see LineProvider.
The Source Code of this Java class is available under a BSD-style license.
LineListener,
LineListenerSupportImpl,
BasicLineListener,
CsvManager,
CsvManagerException| Constructor Summary | |
CustomLineListener()
|
|
| Method Summary | |
protected void |
endProcessImpl()
Implement this method to receive notification that the loading of CSV data has ended. |
protected void |
handleBadLineImpl(BadLine pBadLine)
Implement this method to be notified when badly formatted data is encountered. |
protected abstract BadLine |
handleLineImpl(String[] pLine,
int pNumFields,
long pLineNumber,
String pOriginalLine)
Implement this method to receive each data line as it is loaded. |
protected void |
setCsvSpecImpl(CsvSpec pCsvSpec)
Set the current CsvSpec used for loading CSV files. |
protected void |
setLineSpecImpl(LineSpec pLineSpec)
Set the current LineSpec used for interpreting CSV data fields. |
protected void |
startProcessImpl()
Implement this method to receive notification that the loading of CSV data is about to start. |
| Methods inherited from class com.ricebridge.csvman.LineListenerSupportImpl |
endProcess, handleBadLine, handleLine, setCsvSpec, setLineSpec, startProcess |
| Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Constructor Detail |
public CustomLineListener()
| Method Detail |
protected void setCsvSpecImpl(CsvSpec pCsvSpec)
throws Exception
CsvSpec used for loading CSV files.
You can implement this method when you extend CustomLineListener,
but it is not required.
The CsvSpec controls the CSV loading and saving
process. It contains a number of settings such as the data field and line separators. You can also
set your own custom settings using the CsvSpec.setProperty method.
You can then access these settings inside your own LineListener using the CsvSpec object
passed into this method.
This method is called before setLineSpecImpl is called.
setCsvSpecImpl in class LineListenerSupportImplpCsvSpec - CsvSpec object
ExceptionCsvSpec,
setLineSpecImpl
protected void setLineSpecImpl(LineSpec pLineSpec)
throws Exception
LineSpec used for interpreting CSV data fields.
You can implement this method when you extend CustomLineListener,
but it is not required.
The LineSpec controls the conversion of individual CSV data fields into Java objects.
Whereas CsvSpec controls the entire process, LineSpec only applies to each data field.
In the current version of CSV Manager (1.2), LineSpec is used to load and save Java Beans,
by providing the get and set method names for each data field.
See BeanLineListener for more details.
You can subclass LineSpec to add your own
data field specific information for your own custom LineListeners.
You can then access these settings inside your own LineListener
using the LineSpec object passed into this method.
This method is called after setCsvSpecImpl is called.
setLineSpecImpl in class LineListenerSupportImplpLineSpec - LineSpec object
ExceptionLineSpec,
setCsvSpecImpl,
BeanLineListener
protected void startProcessImpl()
throws Exception
You can implement this method when you extend CustomLineListener,
but it is not required.
You can use this method to initialise any resource you need to process the CSV data. For example you can open a database connection to store the data as it is loaded.
This method is called after setCsvSpecImpl and
setLineSpecImpl.
startProcessImpl in class LineListenerSupportImplExceptionendProcessImpl
protected abstract BadLine handleLineImpl(String[] pLine,
int pNumFields,
long pLineNumber,
String pOriginalLine)
throws Exception
This method must be implemented when you extend CustomLineListener.
This method is where you will do the main work of processing the CSV data. As you get each line in, you can decide what to do with the data. The parameters of this method provide you with a lot of information about the CSV data line that you can use in your application.
First, the pLine parameter contains the actual data as a
String[] array. This array is guaranteed not to contain any null Strings.
If empty data fields are found in the CSV line (for example a,,b => ['a','','b'])
then empty strings are placed in the array. This means that you can avoid nasty
NullPointerExceptions.
Equally nasty are ArrayIndexOutOfBoundsExceptions.
CSV Manager helps you avoid them by making sure that the pLine array is always
long enough. By "long enough", we mean either as long as the longest line found so far, or as long
as is specified by the CsvSpec.setNumFields method.
Of course, this means that in the case where there are fewer data fields than normal, you also
need to know exactly how many data fields there actually were,
as pLine.length will not tell you this. This is what the pNumFields
parameter is for. So if you need to check exactly how many data fields a line had, use
pNumFields.
To help with error reporting, CSV Manager also provides the line number of the
current data line, passed in via pLineNumber. This includes any bad lines found.
pLineNumber is a long, just in case you ever have a really,
really big CSV file.
Finally, you also get the text of the original line (pOriginalLine), so you can create
user-friendly error messages for your users. And it makes debugging easier.
Error Handling: What happens when the data in the CSV file is incorrect in some way?
For example, it might not be valid for your database. In this case, even though the syntax
of the CSV is correct, there is a semantic error. To capture this case, we use the following
contract: if all is well, return a null from handleBadLineImpl.
If there is an error with the data, return a BadLine object describing the error.
This provides consistent handling of errors. At any time you can of course
just throw an Exception, but if you use a BadLine instead then you get
proper summary statistics, nice error reporting, and faster performance as you avoid the overhead
of Exception throwing and catching.
But if you have a error that is not data related, (if for example, your database goes down), then it is
better to throw an Exception.
handleLineImpl in class LineListenerSupportImplpLine - String values of data fields in linepNumFields - Number of data fields actually found on the current linepLineNumber - Count of lines processed so far.pOriginalLine - Text of original data line from data source
null if line is OK, BadLine object if line was bad in some way
ExceptionLineListener.handleLine,
BadLine,
handleBadLineImpl
protected void handleBadLineImpl(BadLine pBadLine)
throws Exception
You can implement this method when you extend CustomLineListener,
but it is not required.
When a syntax error is encountered in the CSV file you are loading, a BadLine object is
created by CSV Manager to describe the problem, and then it is passed to your custom
LineListener for further handling. You can decide how to log the error or what other actions
to take based on your error handling policy.
What happens after handleBadLineImpl is called? It depends on the
CsvSpec.setIgnoreBadLines setting. If this setting is
true, then loading will continue with the rest of the CSV file. If it is
false, then loading will halt and a CsvManagerException will be thrown for
the code that called the CsvManager.load method to catch.
Note: BadLines returned by handleLineImpl are not
passed to this method. Since you already know about them in handeLineImpl, there would not
be much point.
handleBadLineImpl in class LineListenerSupportImplpBadLine - BadLine object describing the error
ExceptionLineListener.handleBadLine,
handleLineImpl
protected void endProcessImpl()
throws Exception
You can implement this method when you extend CustomLineListener,
but it is not required.
You can use this method to close any open resources that were used to handle the CSV data. For example you can close any open database connections.
This method is called last, after all handleLineImpl
and handleBadLineImpl calls have been made.
endProcessImpl in class LineListenerSupportImplExceptionstartProcessImpl
|
|||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||||