Thread: [Batchserver-cvs] batchserver/src/org/jmonks/batch/io FieldSpec.java, NONE, 1.1 FileParseException.
Brought to you by:
suresh_pragada
From: Suresh <sur...@us...> - 2006-09-15 20:07:54
|
Update of /cvsroot/batchserver/batchserver/src/org/jmonks/batch/io In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv20408 Added Files: FieldSpec.java FileParseException.java FileReader.java FileSpec.java FileSpecException.java FileType.java FileWriter.java package.html ReaderRecord.java Record.java RecordSpec.java RecordType.java WriterRecord.java Log Message: no message --- NEW FILE: FileSpecException.java --- /* * FileSpecException.java * * Created on May 26, 2006, 11:36 PM * * To change this template, choose Tools | Options and locate the template under * the Source Creation and Management node. Right-click the template and choose * Open. You can then make changes to the template in the Source Editor. */ package org.jmonks.batch.io; /** * <p> * FileSpecException is a runtime exception thrown when there is a problem creating * the FileSpec object from the given file contains the file specification. * </p> * * @author Suresh Pragada * @version 1.0 * @since 1.0 */ public class FileSpecException extends RuntimeException { /** * Constructs the FileSpecException by accepting the message describes the * problem. * * @param message Message identifies the problem. */ public FileSpecException(String message) { super(message); } } --- NEW FILE: RecordType.java --- /* * RecordType.java * * Created on May 26, 2006, 11:14 AM * * To change this template, choose Tools | Options and locate the template under * the Source Creation and Management node. Right-click the template and choose * Open. You can then make changes to the template in the Source Editor. */ package org.jmonks.batch.io; /** * <p> * RecordType defines the different kind of records can be available in a file. * This defines the constants to identify all the records as enums. This record * type information should be provided when defining the record spec in file spec. * </p> * * @author Suresh Pragada * @version 1.0 * @since 1.0 */ public final class RecordType { /** * Holds the string representing the record type. */ private String type=null; /** * Private constructor to make sure that RecordType cannot be instantiated from * outside of this class. * * @param type String representing the type of record. * * @throws IllegalArgumentException Throws if the type is null or the value is in use. */ private RecordType(String type) { if(type!=null) { this.type=type; } else throw new IllegalArgumentException("Record type cannot be null."); } /** * Utility method returns the RecordType object matches to the given value. If * it doesnt match with the any pre defined record types, it creates and returns * a new record type. * * @param type String representing the type of record. * * @return Returns the RecordType. * * @throws IllegalArgumentException Throws if the recordType is null or the value is in use. */ public static RecordType toRecordType(String recordType) { if(RecordType.HEADER.toString().equalsIgnoreCase(recordType)) return RecordType.HEADER; else if(RecordType.DETAIL.toString().equalsIgnoreCase(recordType)) return RecordType.DETAIL; else if(RecordType.TRAILER.toString().equalsIgnoreCase(recordType)) return RecordType.TRAILER; else if(RecordType.BLOCK_START.toString().equalsIgnoreCase(recordType)) return RecordType.BLOCK_START; else if(RecordType.BLOCK_END.toString().equalsIgnoreCase(recordType)) return RecordType.BLOCK_END; else return new RecordType(recordType); } /** * Equality will be based on the type. * * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object recordType) { return (recordType!=null) && (this.getClass()==recordType.getClass()) && (this.type.equalsIgnoreCase(recordType.toString())); } /** * Hashcode of the type will be returned as a hash code. * * @see java.lang.Object#hashCode() */ public int hashCode() { return this.type.hashCode(); } /** * Returns the string representation of the RecordType which can be used to * define the record spec in file spec. */ public final String toString() { return type; } /** * Represents the header record and the value to be used in the record * spec is "HEADER". */ public static final RecordType HEADER = new RecordType("HEADER"); /** * Represents the header record and the value to be used in the record * spec is "TRAILER". */ public static final RecordType TRAILER = new RecordType("TRAILER"); /** * Represents the detailed record and the value to be used in the record * spec is "DETAIL". */ public static final RecordType DETAIL = new RecordType("DETAIL"); /** * Represents the starting record of the block and the value to be used in the record * spec is "BLOCK-START". */ public static final RecordType BLOCK_START = new RecordType("BLOCK-START"); /** * Represents the ending record of the block and the value to be used in the record * spec is "BLOCK-END". */ public static final RecordType BLOCK_END = new RecordType("BLOCK-END"); } --- NEW FILE: package.html --- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>IO API Overview</title> </head> <body> Defines API for the clients to read records from the file and write records into the file. <p> This package provides the API for the client programs to work with the files easily irrespective of the file format. This API is based on the analogy that all the files to be read and write have some data in the form of records and each record consists of a set of fields. Structure of these files, records and fields can be defined or configured using xml format. API allows the client programs to reads the records in an iterative manner from the file by specifying the xml file defined the file structure (It will be called as file spec here onwards) and file to read. API allows the client programs to create the record and write that record into the file. </p> <p> <h3>Defining file structure</h3> API expects the file consists of the data in the form of mulitple records and each record consists of multiple fields. Structure of the file will be defined using the root tag <file-spec> accepts the attribute <code>file-type</code> which signifies the kind of format of the file it is defining. Allowed values for the <code>file-type</code> attribute should be from FileType class. This class defines all the available file types can be used. Using the value doesnt exist in the FileType class results FileSpecException being thrown. Implementations may expects other attributes along with the <code>file-type</code> attribute for better file reading and file writing. These additional attributes will be mentioned by the FileSpec impelementors. <pre> <file-spec file-type="file-format"> <!-- Record specs will go on here --> </file-spec> </pre> </p> <p> As every file will have its data in the form of records, each record will be defined using the tag <record-spec> in the <file-spec> tag. Every <code>record-spec</code> will have a <code>record-type</code> attribute which signifies the kind of record it is configuring like header record or detail record or trailer record. This <code>record-type</code> should be unique across the file spec and the value can be taken from RecordType class. Allowed to use other record types not defined in the RecordType class. Along with the <code>record-type</code> attribute each implementation will require additional attributes to idnetify the records in the file and to write the records into the file. These additional attributes will be mentioned by the RecordSpec implementations. <pre> <file-spec file-type="file-format"> <record-spec record-type="detail"> <!-- Record specs will go on here --> </record-spec> </file-spec> </pre> </p> <p> As every record spec consists of set of fields, each field is defined using the tag <field-spec> in <record-spec> tag. Each <code>field-spec</code> should have an attribute </code>field-name</code> identifies the name of the field, which will be used to populate the field values into the record. Based on the implementation, additional attributes will be required along with the <code>field-name</code> to identify the field. Some implementations might not require <code>field-spec</code> elements at all. Whether clients neeeds to define the <code>field-spec</code> elements or not will be decided by RecordSpec implementations. <pre> <file-spec file-type="file-format"> <record-spec record-type="detail"> <field-spec field-name="field-name1"/> </record-spec> </file-spec> </pre> </p> <p> <h3>Reading records from the file</h3> FileReader class helps us in obtaining the FileReader instance through various factory methods by accepting the file to be read and file spec in different forms. FileReader reads data from the file according to the given file spec and when it finds a match to any of the provided record spec, it reads that record and returns field values as ReaderRecord instance. ReaderRecord instance has a method to read the field values by passing the field names. FileReader implementations provides ReaderRecord implementations, which allow additional methods to read the field values. Look at the FileReader implementation javadoc for the additional methods. Reader records can be read from FileReader in an iterative manner. When file reader doesnt have any more records, it returns null indicating that reader doenst have any more records. At this point client can stop requesting for further records. Once done reading all the records, client should close the reader. <br/><br/> Folloing example indicates how to obtain a file reader instance and how to obtain reader record and how to read field values from the reader records. <pre style="color:green"> <i> InputStream fileSpecInputStream= // Get the input stream for the XML file contains the file structure. InputStream fileInputStream= // Get the input stream of the file to be read. FileReader reader=FileReader.getFileReader(fileInputStream,fileSpecInputStream); ReaderRecord record=null; while((record=reader.getNextRecord())!=null) { if(record.getRecordType().equals(RecordType.DETAIL)) { String fieldValue1=record.readField("field-name1"); // Read the rest of the field and does the processing. } } reader.close(); </i> </pre> </p> <p> <h3>Writing records into the file</h3> FileWriter class helps us in obtaining the FileWriter instance through various factory methods by accepting the file to be written and file spec in different forms. FileWriter accepts WriterRecord instances which actually consists of the field values to write the data into the file. WriterRecord instances can be obtained from FileWriter instances. WriterRecord instances provides the method to write the field values associated to field name. FileWriter implementation classes will provide additional methods to write the field values in an effective way into the writer record. Once all the required field values have been pushed into the writer record, this record needs to be submitted to the FileWriter instance. This will writes that record according to the file spec provided while obtaining the file writer instance. Once done writing all the records, file writer needs to be closed. <br/><br/> Folloing example indicates how to obtain a file writer instance and how to obtain writer record and how to write field values into the writer records and how to submit that record to the file writer. <pre style="color:green"> <i> InputStream fileSpecInputStream= // Get the input stream for the XML file contains the file structure. OutputStream fileOutputStream= // Get the output stream of the file to be written/generated. FileWriter writer=FileWriter.getFileWriter(fileOutputStream,fileSpecInputStream); WriterRecord record=writer.createWriterRecord(RecordType.DETAIL); record.writeField("field-name1","field-value1"); // Write all the other field values into the writer record. writer.writeRecord(record); writer.close(); </i> </pre> </p> </body> </html> --- NEW FILE: Record.java --- /* * Record.java * * Created on May 26, 2006, 11:04 AM * * To change this template, choose Tools | Options and locate the template under * the Source Creation and Management node. Right-click the template and choose * Open. You can then make changes to the template in the Source Editor. */ package org.jmonks.batch.io; /** * <p> * Record represents the map of field names and values based on the record spec * defined in the file spec. ReaderRecord and WriterRecord classes provide * the methods to read and write the values to this record object for the * FileReader and FileWriter consequently. * <br> * TODO :: Based on the memory statistics on handling huge files introduces a method to * remove the data from the records, once they have been used. * </p> * * @author Suresh Pragada * @version 1.0 * @since 1.0 */ public abstract class Record { /** * Holds the type of the record. */ private RecordType recordType=null; /** * Creates the record by accepting the record type. * * @param recordType Type of the record. */ protected Record(RecordType recordType) { this.recordType=recordType; } /** * Gets the record type. */ public RecordType getRecordType() { return this.recordType; } } --- NEW FILE: FileParseException.java --- /* * FileParseException.java * * Created on May 26, 2006, 11:42 PM * * To change this template, choose Tools | Options and locate the template under * the Source Creation and Management node. Right-click the template and choose * Open. You can then make changes to the template in the Source Editor. */ package org.jmonks.batch.io; /** * <p> * FileParseException is a runtime exception thrown when there is a problem reading * the records from the file or writing the records into the file. * </p> * * @author Suresh Pragada * @version 1.0 * @since 1.0 */ public class FileParseException extends RuntimeException { /** * Constructs the FileParseException by accepting the message describes * the problem. * * @param message Messages describes the problem. */ public FileParseException(String message) { super(message); } } --- NEW FILE: RecordSpec.java --- /* * RecordSpec.java * * Created on May 26, 2006, 2:21 PM * * To change this template, choose Tools | Options and locate the template under * the Source Creation and Management node. Right-click the template and choose * Open. You can then make changes to the template in the Source Editor. */ package org.jmonks.batch.io; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.log4j.Logger; /** * <p> * RecordSpec represents the <record-spec> element in file spec. * Record spec specifies the format of the record in the form of multiple * field specs and contains the attribute helps in identifying the type of * record and so. Each record spec contains zero or more field specs based * on the file type. * </p> * <p> * Every record-spec element contains record-type attribute * specifies the kind of record it is. Most of these values will be defined * in RecordType class and additional values can be added by extending the * RecordType. The record-type values should be unique across one file spec. * Here is a sample record-spec configuration. * <br> * <pre> * <record-spec record-type="DETAIL"> * <field-spec field-name="consumer-id"> * </field-spec> * </record-spec> * </pre> * </p> * * @author Suresh Pragada * @version 1.0 * @since 1.0 */ public abstract class RecordSpec { /** * Holds the type of the record this spec is representing. */ protected RecordType recordType=null; /** * Holds all the field spec objects. */ protected List fieldSpecList=null; /** * Constant defines the record spec tag name. */ public static final String RECORD_SPEC_TAG_NAME = "record-spec"; /** * Constant defines the record type attribute name. */ public static final String RECORD_TYPE_ATTRIB_NAME = "record-type"; private static Logger logger=Logger.getLogger(RecordSpec.class); /** * Constructs the RecordSpec object by accepting the RecordType. * * @param recordType Type of the record. */ protected RecordSpec(RecordType recordType) { this.recordType=recordType; fieldSpecList=new ArrayList(); } /** * Adds the given field spec object to the record spec. * * @param fieldSpec Field spec object to be added. * * @return Returns true if field spec has been added successfully, flase otherwise. * * @throws IllegalArgumentException If given field spec is null. * @throws org.jmonks.batch.io.FileSpecException If multiple field specs configured with same field name. */ protected boolean addFieldSpec(FieldSpec fieldSpec) { if(fieldSpec==null) throw new IllegalArgumentException("FiledSpec object to add to the record spec cannot be null."); else { for(Iterator iterator=this.fieldSpecList.iterator();iterator.hasNext();) { FieldSpec existingFieldSpec=(FieldSpec)iterator.next(); if(existingFieldSpec.getFieldName().equalsIgnoreCase(fieldSpec.getFieldName())) throw new FileSpecException("Multiple field specs have been defined with same field name = " + fieldSpec.getFieldName()); } return this.fieldSpecList.add(fieldSpec); } } /** * Gets the field spec objects as a list. * * @returns Returns the list contains of all the field specs. */ public List getFieldSpecs() { return fieldSpecList; } /** * Returns the record type of this record spec. */ public RecordType getRecordType() { return this.recordType; } } --- NEW FILE: WriterRecord.java --- /* * WriterRecord.java * * Created on June 2, 2006, 11:26 AM * * To change this template, choose Tools | Options and locate the template under * the Source Creation and Management node. Right-click the template and choose * Open. You can then make changes to the template in the Source Editor. */ package org.jmonks.batch.io; /** * <p> * WriterRecord provides the methods to write the values of the fields into the record. * This record will be created from and submitted to write into the file for the FileWriter's. * </p> * * @author Suresh Pragada * @version 1.0 * @since 1.0 */ public abstract class WriterRecord extends Record { /** * Creates a new instance of WriterRecord by accepting the type of record. * * @param recordType Type of the record. */ protected WriterRecord(RecordType recordType) { super(recordType); } /** * <p> * Writes the given field name and value into the record. The value will be * depends on the type of file. Concrete implementors provide the details * on the kind of the object should be written for different fields and what the field * name corresponds to. * </p> * * @param fieldName Name of the field. * @param fieldValue Value corresponding the field name. */ public abstract void writeField(String fieldName,Object fieldValue); } --- NEW FILE: FileSpec.java --- /* * FileSpec.java * * Created on May 26, 2006, 2:18 PM * * To change this template, choose Tools | Options and locate the template under * the Source Creation and Management node. Right-click the template and choose * Open. You can then make changes to the template in the Source Editor. */ package org.jmonks.batch.io; import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.HashMap; import java.util.Map; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.log4j.Logger; import org.jmonks.batch.io.flat.DelimitedFlatFileFileSpec; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; import org.jmonks.batch.io.xml.XMLFileSpec; import org.jmonks.batch.io.flat.FixedWidthFlatFileFileSpec; /** * <p> * FileSpec represents the file contains specification (spec for short) of any * file to read or write using this package. This provides the factory * method to create the FileSpec object from a file contains the spec * and necessary methods to access the record spec objects. * </p> * <p> * File spec defines the file type and possible records could exists in the file. * Every file spec will contains one or * more record specs. Element file-spec should contain one attribute file-type * defines the type of the file this spec is going to represent. Based on the file * type, there could be other attributes in file-spec element along with file-type * attribute. These attributes can be found from the javadoc of the particular file type * file specs. Here is a sample file-spec configuration. * </p> * <p> * <pre> * <file-spec file-type="fixed-width-flat"> * <record-spec record-type="DETAIL"> * </record-spec> * </file-spec> * </pre> * </p> * * @author Suresh Pragada * @version 1.0 * @since 1.0 */ public abstract class FileSpec { /** * Holds the type of the file this spec is representing. */ protected FileType fileType=null; /** * Map holds the record specs with their record types as keys. */ protected Map recordSpecMap=null; /** * Constant defines the file spec tage name. */ public static final String FILE_SPEC_TAG_NAME = "file-spec"; /** * Constant defines the attribute name file type should contain. */ public static final String FILE_TYPE_ATTRIB_NAME = "file-type"; private static Logger logger=Logger.getLogger(FileSpec.class); /** * Constructs the FileSpec object by accepting file type. * * @param fileType Type of the file this spec is representing. */ protected FileSpec(FileType fileType) { this.fileType=fileType; recordSpecMap=new HashMap(); } /** * Adds the record spec to the file spec. * * @param recordSpec Record spec to be added to the file spec. * * @return Returns true, if record spec is added, false otherwise. * * @throws IllegalArgumentException If recordSpec is null. * @throws org.jmonks.batch.io.FileSpecException If multiple record specs configured with same record type. */ protected boolean addRecordSpec(RecordSpec recordSpec) { if(recordSpec==null) throw new IllegalArgumentException("RecordSpec cannot be null to add to the file spec."); else { if(this.recordSpecMap.containsKey(recordSpec.getRecordType())) { throw new FileSpecException("Duplicate record spec with the same record type " + recordSpec.getRecordType().toString()); } else { this.recordSpecMap.put(recordSpec.getRecordType(),recordSpec); return true; } } } /** * <p> * Gets all the record spec's in this file spec as a list. * * TODO :: There is chance that client might misuse this list. Based on the * performance create a new list and return it. * </p> * * @return Returns record spec's as a collection. */ public Collection getRecordSpecs() { return this.recordSpecMap.values(); } /** * Gets the record spec associated with the given record type. * * @param recordType Record types associated with the record spec. * * @return Retruns the record spec associated with the record type, * null if record spec could not be found. * * @throws IllegalArgumentException If recordType is null. */ public RecordSpec getRecordSpec(RecordType recordType) { if(recordType==null) throw new IllegalArgumentException("RecordType cannot be null to get the record spec from file spec."); else return (RecordSpec)this.recordSpecMap.get(recordType); } /** * Tells whether a record spec is exists with the given record type in the file spec. * * @param recordType Type of the record to check in the file spec. * * @return Return true if there is a record spec with this type, false otherwise. */ public boolean isValidRecordType(RecordType recordType) { return this.recordSpecMap.containsKey(recordType); } /** * Gets the file type. * * @return Returns the file type. */ public FileType getFileType() { return this.fileType; } /** * <p> * Creates the file spec object from the file contains the spec. This looks for * the file-type attribute in file-spec element and creates the appropriate * file spec object. * </p> * @param fileSpecInputStream Input stream represents the file spec. * * @return Returns the file spec object. * * @throws org.jmonks.batch.io.FileSpecException If file-type attribute * is missing or doesnt consists of the type available FileType class * or given file cannot be found or cannot parse the file. */ public static FileSpec createFileSpec(InputStream fileSpecInputStream) { logger.trace("Entering createFileSpec"); try { if(fileSpecInputStream==null) throw new IllegalArgumentException("File spec input stream to read the file spec cannot be null."); DocumentBuilderFactory documentBuilderFactory=DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder=documentBuilderFactory.newDocumentBuilder(); Document document=documentBuilder.parse(fileSpecInputStream); Element fileSpecElement=document.getDocumentElement(); if(FileSpec.FILE_SPEC_TAG_NAME.equals(fileSpecElement.getTagName())) { String configuredFileType=fileSpecElement.getAttribute(FileSpec.FILE_TYPE_ATTRIB_NAME); logger.info("Configured file-type value = " + configuredFileType); FileType fileType=FileType.toFileType(configuredFileType); if(fileType==FileType.FIXED_WIDTH_FLAT_FILE) return FixedWidthFlatFileFileSpec.createFixedWidthFlatFileFileSpec(fileSpecElement); else if(fileType==FileType.DELIMITED_FLAT_FILE) return DelimitedFlatFileFileSpec.createDelimitedFlatFileFileSpec(fileSpecElement); else if(fileType==FileType.XML_FILE) return XMLFileSpec.createXMLFileSpec(fileSpecElement); else throw new FileSpecException("Configured file type " + fileType + " in the file spec is not recognizable."); } else throw new FileSpecException("File spec root element doesnt match the expected " + FileSpec.FILE_SPEC_TAG_NAME + " value in the file spec obtained from the given stream."); } catch(ParserConfigurationException exception) { exception.printStackTrace(); logger.fatal("Couldnt find DOM parser in the classpath to parse the file spec",exception); throw new FileSpecException("Couldnt find DOM parser in the classpath to parse the file spec. Message = " + exception.getMessage()); } catch(SAXException exception) { exception.printStackTrace(); logger.fatal("Parsing exception while parsing the given inputstream.",exception); throw new FileSpecException("Parsing exception while parsing the file spec in given input stream. Message = " + exception.getMessage()); } catch(IOException exception) { exception.printStackTrace(); logger.fatal("IO exception while parsing the given input stream to create the file spec.",exception); throw new FileSpecException("IO exception while parsing the given input stream to create the file spec. Message = " + exception.getMessage()); } } } --- NEW FILE: ReaderRecord.java --- /* * ReaderRecord.java * * Created on June 2, 2006, 11:24 AM * * To change this template, choose Tools | Options and locate the template under * the Source Creation and Management node. Right-click the template and choose * Open. You can then make changes to the template in the Source Editor. */ package org.jmonks.batch.io; /** * <p> * ReaderRecord provides the methods to read the values of the fields from a record. * This record will be generated from the FileReader's. * </p> * * @author Suresh Pragada * @version 1.0 * @since 1.0 */ public abstract class ReaderRecord extends Record { /** * Constructs the ReaderRecord by accepting the record type. * * @param recordType Type of the record. */ protected ReaderRecord(RecordType recordType) { super(recordType); } /** * <p> * Reads the value of the given field from the record. The value will be * depends on the type of file. Concrete implementors provide the details * on the kind of the object they return for different fields and what the field * name corresponds to. * </p> * * @param fieldName Name of the field. * * @return Returns the value of the given field from the record, null if field doesnt exists. */ public abstract Object readField(String fieldName); } --- NEW FILE: FieldSpec.java --- /* * FieldSpec.java * * Created on May 26, 2006, 2:25 PM * * To change this template, choose Tools | Options and locate the template under * the Source Creation and Management node. Right-click the template and choose * Open. You can then make changes to the template in the Source Editor. */ package org.jmonks.batch.io; import org.apache.log4j.Logger; /** * <p> * FieldSpec represents the <field-spec> element in file spec. * Field spec specifies the name of the field and additional attributes to * identifies the field among the record and other properties based on the file type. * Every field-spec element contains <code>field-name</code> attribute identifies among the * record spec. The <code>field-name</code> values should be unique across one record spec. * </p> * <p> * <pre> * <field-spec field-name="consumer-id"/> * </pre> * </p> * * @author Suresh Pragada * @version 1.0 * @since 1.0 */ public abstract class FieldSpec { /** * Holds the name of the field. */ protected String fieldName=null; /** * Constant defines the field spec tag name. */ public static final String FIELD_SPEC_TAG_NAME = "field-spec"; /** * Constant defines the field name atttribute name. */ public static final String FIELD_NAME_ATTRIB_NAME = "field-name"; private static Logger logger=Logger.getLogger(FieldSpec.class); /** * Constructs the FieldSpec object by accepting the field name. * * @param fieldName Name of the field. */ public FieldSpec(String fieldName) { this.fieldName=fieldName; } /** * Returns the field name. */ public String getFieldName() { return this.fieldName; } } --- NEW FILE: FileWriter.java --- /* * FileWriter.java * * Created on June 6, 2006, 8:59 AM * * To change this template, choose Tools | Options and locate the template under * the Source Creation and Management node. Right-click the template and choose * Open. You can then make changes to the template in the Source Editor. */ package org.jmonks.batch.io; import java.io.InputStream; import java.io.OutputStream; import java.io.Writer; import org.apache.log4j.Logger; import org.jmonks.batch.io.flat.DelimitedFlatFileWriter; import org.jmonks.batch.io.flat.FixedWidthFlatFileWriter; import org.jmonks.batch.io.xml.XMLFileWriter; /** * <p> * FileWriter writes the specified file based on the given file spec with * the data written in the form of WriterRecord's. This provides the methods * to create the required records and write them into the file writer. Once finished * writing of all the records file writer should be closed by calling * the appropriate methods. This provides the factory method to create the file writer * based on the file spec. Here is a sample code snippet to use the file writer. * </p> * <p> * <pre> * InputStream fileSpecInputStream=...; * OutputStream fileOutputStream=...; * FileWriter fileWriter=FileWriter.getFileWriter(fileOutputStream,fileSpecInputStream); * WriterRecord record=fileWriter.createWriterRecord(RecordType.DETAIL); * record.writeField("consumer-id","123456"); * //Write the other field values. * fileWriter.writeRecord(record); * fileWriter.close(); * </pre> * </p> * * @author Suresh Pragada * @version 1.0 * @since 1.0 */ public abstract class FileWriter { private static Logger logger=Logger.getLogger(FileWriter.class); /** * Writes the given record into the file. The record should be obtained * from this file writer using the <code>createWriterRecord</code> method. * * @param record WriterRecord that you want to write into the file. * * @throws org.jmonks.batch.io.FileParseException Problems while writing the record into file. */ public abstract void writeRecord(WriterRecord record); /** * Closes the writer and releases all the resources associated with the writer. */ public abstract void close(); /** * Creates the writer record to be used to fill all the field values * and submit to the file writer to write the record into the file. * * @param recordType Type of record. * * @return Retruns the writer record. * * @throws IllegalArgumentException If given record type is not associated with any record spec. */ public abstract WriterRecord createWriterRecord(RecordType recordType); /** * <p> * Factory method to get the file writer. This method returns the appropriate file writer * based on the file type specified in the file spec. * </p> * * @param outputStream Output stream to write the records. * @param fileSpecInputStream Input stream to read the file spec. * * @return Returns the appropriate writer. * * @throws IllegalArgumentException If the given file output stream or file spec input stream is null. * @throws org.jmonks.batch.io.FileSpecException If the configured file type in file spec doesnt * exist in FileType class. */ public static FileWriter getFileWriter(OutputStream outputStream,InputStream fileSpecInputStream) { logger.trace("Entering getFileReader"); if(outputStream==null) throw new IllegalArgumentException("Output stream to write the records cannot be null."); if(fileSpecInputStream==null) throw new IllegalArgumentException("Input stream to read the file spec cannot be null."); FileSpec fileSpec=FileSpec.createFileSpec(fileSpecInputStream); return FileWriter.getFileWriter(outputStream, fileSpec); } /** * <p> * Factory method to get the file writer. This method returns the appropriate file writer * based on the file type specified in the file spec. * </p> * * @param outputStream Output stream to write the records. * @param fileSpec File spec to be used to create the writer. * * @return Returns the appropriate writer. * * @throws IllegalArgumentException If the given file output stream or file spec is null. * @throws org.jmonks.batch.io.FileSpecException If the configured file type in file spec doesnt * exist in FileType class. */ public static FileWriter getFileWriter(OutputStream outputStream, FileSpec fileSpec) { logger.trace("Entering getFileReader"); if(outputStream==null) throw new IllegalArgumentException("Output stream to write the records cannot be null."); if(fileSpec==null) throw new IllegalArgumentException("File spec to create the writer cannot be null."); logger.debug("Given file spec = " + fileSpec.toString()); if(fileSpec.getFileType()==FileType.FIXED_WIDTH_FLAT_FILE) return new FixedWidthFlatFileWriter(outputStream,fileSpec); else if(fileSpec.getFileType()==FileType.DELIMITED_FLAT_FILE) return new DelimitedFlatFileWriter(outputStream, fileSpec); else if(fileSpec.getFileType()==FileType.XML_FILE) return new XMLFileWriter(outputStream,fileSpec); else throw new FileSpecException("Unsupported file type in the file spec = " + fileSpec.getFileType().toString()); } /** * <p> * Factory method to get the file writer. This method returns the appropriate file writer * based on the file type specified in the file spec. * </p> * * @param writer Writer to write the records. * @param fileSpecInputStream Input stream to read the file spec. * * @return Returns the appropriate writer. * * @throws IllegalArgumentException If the given file output stream or file spec input stream is null. * @throws org.jmonks.batch.io.FileSpecException If the configured file type in file spec doesnt * exist in FileType class. */ public static FileWriter getFileWriter(Writer writer,InputStream fileSpecInputStream) { logger.trace("Entering getFileReader"); if(writer==null) throw new IllegalArgumentException("Writer to write the records cannot be null."); if(fileSpecInputStream==null) throw new IllegalArgumentException("Input stream to read the file spec cannot be null."); FileSpec fileSpec=FileSpec.createFileSpec(fileSpecInputStream); return FileWriter.getFileWriter(writer, fileSpec); } /** * <p> * Factory method to get the file writer. This method returns the appropriate file writer * based on the file type specified in the file spec. * </p> * * @param writer Writer to write the records. * @param fileSpec File spec to be used to create the writer. * * @return Returns the appropriate writer. * * @throws IllegalArgumentException If the given file output stream or file spec is null. * @throws org.jmonks.batch.io.FileSpecException If the configured file type in file spec doesnt * exist in FileType class. */ public static FileWriter getFileWriter(Writer writer, FileSpec fileSpec) { logger.trace("Entering getFileReader"); if(writer==null) throw new IllegalArgumentException("Writer to write the records cannot be null."); if(fileSpec==null) throw new IllegalArgumentException("File spec to create the writer cannot be null."); logger.debug("Given file spec = " + fileSpec.toString()); if(fileSpec.getFileType()==FileType.FIXED_WIDTH_FLAT_FILE) return new FixedWidthFlatFileWriter(writer,fileSpec); else if(fileSpec.getFileType()==FileType.DELIMITED_FLAT_FILE) return new DelimitedFlatFileWriter(writer, fileSpec); else if(fileSpec.getFileType()==FileType.XML_FILE) return new XMLFileWriter(writer,fileSpec); else throw new FileSpecException("Unsupported file type in the file spec = " + fileSpec.getFileType().toString()); } } --- NEW FILE: FileReader.java --- /* * FileReader.java * * Created on May 26, 2006, 9:37 AM * * To change this template, choose Tools | Options and locate the template under * the Source Creation and Management node. Right-click the template and choose * Open. You can then make changes to the template in the Source Editor. */ package org.jmonks.batch.io; import java.io.InputStream; import java.io.Reader; import org.apache.log4j.Logger; import org.jmonks.batch.io.flat.DelimitedFlatFileReader; import org.jmonks.batch.io.xml.XMLFileReader; import org.jmonks.batch.io.flat.FixedWidthFlatFileReader; /** * <p> * FileReader reads the specified file based on the given file spec and * returns the data in the form of ReaderRecord's to read the required values referring the field names. * This provides the methods to reads the records in an iterative manner. Once finished * reading all or required records from the file reader, it should be closed by calling * the appropriate methods. This provides the factory method to create the file reader * based on the file spec. Here is a sample code snippet to use the file reader. * </p> * <p> * <pre> * InputStream fileSpecInputStream=...; * InputStream fileInputStream=....; * FileReader fileReader=FileReader.getFileReader(fileInputStream,fileSpecInputStream); * ReaderRecord record=null; * while((record=fileReader.getNextRecord())!=null) * { * if(record.getRecordType()==RecordType.DETAIL) * { * String consumerID=record.readField("consumer-id"); * // Read the rest of the fields and does the processing. * } * } * fileReader.close(); * </pre> * </p> * * @author Suresh Pragada * @version 1.0 * @since 1.0 */ public abstract class FileReader { private static Logger logger=Logger.getLogger(FileReader.class); /** * <p> * Gets the next available record from the file. If file doesnt have any more records * it returns null. * </p> * * @return Returns the next available record from the file, null if it doesnt have any more records. * * @throws org.jmonks.batch.io.FileParseException Problems while parsing the next record. */ public abstract ReaderRecord getNextRecord(); /** * Closes the reader and releases all the resources associated with the reader. */ public abstract void close(); /** * <p> * Factory method to get the file reader. This method returns the appropriate file reader * based on the file type specified in the file spec. * </p> * * @param fileInputStream Input stream to read the data file. * @param fileSpecInputStream Input stream to read the file spec. * * @return Returns the appropriate reader. * * @throws IllegalArgumentException If the given fileInputStream or fileSpecInputStream is null. * @throws org.jmonks.batch.io.FileSpecException If the configured file type in file spec doesnt * exist in FileType class. */ public static FileReader getFileReader(InputStream fileInputStream,InputStream fileSpecInputStream) { logger.trace("Entering getFileReader"); if(fileInputStream==null) throw new IllegalArgumentException("Input stream to read the data file cannot be null."); if(fileSpecInputStream==null) throw new IllegalArgumentException("Input stream to read the file spec cannot be null."); FileSpec fileSpec=FileSpec.createFileSpec(fileSpecInputStream); return FileReader.getFileReader(fileInputStream, fileSpec); } /** * <p> * Factory method to get the file reader. This method returns the appropriate file reader * based on the file type specified in the file spec. * </p> * * @param fileInputStream Input stream to read the data file. * @param fileSpec File spec to create the file reader. * * @return Returns the appropriate file reader. * * @throws IllegalArgumentException If the given fileInputStream or fileSpec is null. * @throws org.jmonks.batch.io.FileSpecException If the configured file type in file spec doesnt * exist in FileType class. */ public static FileReader getFileReader(InputStream fileInputStream, FileSpec fileSpec) { logger.trace("Entering getFileReader"); if(fileInputStream==null) throw new IllegalArgumentException("Input stream to read the data file cannot be null."); if(fileSpec==null) throw new IllegalArgumentException("File spec cannot be null to create the file reader."); logger.debug("Given file spec = " + fileSpec.toString()); if(fileSpec.getFileType()==FileType.FIXED_WIDTH_FLAT_FILE) return new FixedWidthFlatFileReader(fileInputStream,fileSpec); else if(fileSpec.getFileType()==FileType.DELIMITED_FLAT_FILE) return new DelimitedFlatFileReader(fileInputStream,fileSpec); else if(fileSpec.getFileType()==FileType.XML_FILE) return new XMLFileReader(fileInputStream,fileSpec); else throw new FileSpecException("Unsupported file type in the file spec = " + fileSpec.getFileType().toString()); } /** * <p> * Factory method to get the file reader. This method returns the appropriate file reader * based on the file type specified in the file spec. * </p> * * @param reader Reader to read the data file. * @param fileSpecInputStream Input stream to read the file spec. * * @return Returns the appropriate reader. * * @throws IllegalArgumentException If the given reader or fileSpecInputStream is null. * @throws org.jmonks.batch.io.FileSpecException If the configured file type in file spec doesnt * exist in FileType class. */ public static FileReader getFileReader(Reader reader,InputStream fileSpecInputStream) { logger.trace("Entering getFileReader"); if(reader==null) throw new IllegalArgumentException("Reader to read the data file cannot be null."); if(fileSpecInputStream==null) throw new IllegalArgumentException("Input stream to read the file spec cannot be null."); FileSpec fileSpec=FileSpec.createFileSpec(fileSpecInputStream); return FileReader.getFileReader(reader, fileSpec); } /** * <p> * Factory method to get the file reader. This method returns the appropriate file reader * based on the file type specified in the file spec. * </p> * * @param reader Reader to read the data file. * @param fileSpec File spec to create the file reader. * * @return Returns the appropriate reader. * * @throws IllegalArgumentException If the given reader or fileSpec is null. * @throws org.jmonks.batch.io.FileSpecException If the configured file type in file spec doesnt * exist in FileType class. */ public static FileReader getFileReader(Reader reader, FileSpec fileSpec) { logger.trace("Entering getFileReader"); if(reader==null) throw new IllegalArgumentException("Reader to read the data file cannot be null."); if(fileSpec==null) throw new IllegalArgumentException("File spec cannot be null to create the file reader."); logger.debug("Given file spec = " + fileSpec.toString()); if(fileSpec.getFileType()==FileType.FIXED_WIDTH_FLAT_FILE) return new FixedWidthFlatFileReader(reader,fileSpec); else if(fileSpec.getFileType()==FileType.DELIMITED_FLAT_FILE) return new DelimitedFlatFileReader(reader,fileSpec); else if(fileSpec.getFileType()==FileType.XML_FILE) return new XMLFileReader(reader,fileSpec); else throw new FileSpecException("Unsupported file type in the file spec = " + fileSpec.getFileType().toString()); } } --- NEW FILE: FileType.java --- /* * FileType.java * * Created on May 26, 2006, 3:01 PM * * To change this template, choose Tools | Options and locate the template under * the Source Creation and Management node. Right-click the template and choose * Open. You can then make changes to the template in the Source Editor. */ package org.jmonks.batch.io; /** * <p> * FileType defines different kinds of file formats this package supports for * reading and writing. This defines the constants to identify those file formats * that it supports as enums. The file type information should be provided when * defining the file spec to identify the kind of file this spec is going to represent. * </p> * * @author Suresh Pragada * @version 1.0 * @since 1.0 */ public final class FileType { /** * Holds the string representing the file type. */ private String type=null; /** * Private constructor to make sure that FileType cannot be instantiated from * outside of this class. * * @param type String representing the type of file. */ private FileType(String type) { this.type=type; } /** * Utility method returns the FileType object matches to the given value. * * @param type String representing the type of file. * * @return Returns the FileType references matches to the given values, null * if it cannot match to the available file types. */ public static FileType toFileType(String type) { if(FileType.FIXED_WIDTH_FLAT_FILE.toString().equalsIgnoreCase(type)) return FileType.FIXED_WIDTH_FLAT_FILE; else if(FileType.DELIMITED_FLAT_FILE.toString().equalsIgnoreCase(type)) return FileType.DELIMITED_FLAT_FILE; else if(FileType.XML_FILE.toString().equalsIgnoreCase(type)) return FileType.XML_FILE; else return null; } /** * Returns the string representation of the FileType which can be used to * defines the file spec. */ public String toString() { return type; } /** * Represents the fixed width flat files. The value to be used in the file * spec for this kind of file types is "fixed-width-flat". */ public static final FileType FIXED_WIDTH_FLAT_FILE = new FileType("fixed-width-flat"); /** * Represents the delimited flat files. The value to be used in the file * spec for this kind of file types is "delimited-flat". */ public static final FileType DELIMITED_FLAT_FILE = new FileType("delimited-flat"); /** * Represents the xml files. The value to be used in the file * spec for this kind of file types is "xml". */ public static final FileType XML_FILE = new FileType("xml"); } |