KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > prefuse > data > io > AbstractTextTableReader


1 package prefuse.data.io;
2
3 import java.io.IOException JavaDoc;
4 import java.io.InputStream JavaDoc;
5 import java.util.ArrayList JavaDoc;
6
7 import prefuse.data.Table;
8 import prefuse.data.parser.DataParseException;
9 import prefuse.data.parser.DataParser;
10 import prefuse.data.parser.ParserFactory;
11 import prefuse.data.parser.TypeInferencer;
12 import prefuse.util.collections.ByteArrayList;
13 import prefuse.util.io.IOLib;
14
15 /**
16  * Abstract base class for TableReader instances that read in a table
17  * from a textual data file.
18  *
19  * @author <a HREF="http://jheer.org">jeffrey heer</a>
20  */

21 public abstract class AbstractTextTableReader extends AbstractTableReader {
22
23     private ParserFactory m_pfactory;
24     private boolean m_hasHeader;
25     
26     /**
27      * Create a new AbstractTextTableReader using a default ParserFactory.
28      */

29     public AbstractTextTableReader() {
30         this(ParserFactory.getDefaultFactory());
31     }
32
33     /**
34      * Create a new AbstractTextTableReader.
35      * @param parserFactory the ParserFactory to use for parsing text strings
36      * into table values.
37      */

38     public AbstractTextTableReader(ParserFactory parserFactory) {
39         m_pfactory = parserFactory;
40         m_hasHeader = true;
41     }
42     
43     /**
44      * Set whether or not the table data file includes a header row.
45      * @param hasHeaderRow true if the the data file includes a header row,
46      * false otherwise.
47      */

48     public void setHasHeader(boolean hasHeaderRow) {
49         m_hasHeader = hasHeaderRow;
50     }
51     
52     /**
53      * @see prefuse.data.io.AbstractTableReader#readTable(java.io.InputStream)
54      */

55     public Table readTable(InputStream JavaDoc is) throws DataIOException {
56         
57         // determine input stream capabilities
58
// if we can't reset the stream, we read in all the bytes
59
// and make our own local stream
60
ByteArrayList buf = null;
61         if ( is.markSupported() ) {
62             // mark the stream to our reset point
63
is.mark(Integer.MAX_VALUE);
64         } else {
65             // load in the entirety of the input stream
66
try {
67                 buf = IOLib.readAsBytes(is);
68             } catch ( IOException JavaDoc ioe ) {
69                 throw new DataIOException(ioe);
70             }
71             // create our own input stream
72
is = buf.getAsInputStream();
73         }
74         
75         final TypeInferencer di = new TypeInferencer(m_pfactory);
76         final ArrayList JavaDoc headers = new ArrayList JavaDoc();
77         final int[] dim = new int[] { 0, 0 };
78         
79         TableReadListener scanner = new TableReadListener() {
80             int prevLine = -1;
81             public void readValue(int line, int col, String JavaDoc value)
82                 throws DataParseException
83             {
84                 // sample value to determine data type
85
if ( line > 1 || !m_hasHeader ) {
86                     di.sample(col-1, value);
87                     
88                     // update num rows
89
if ( line != prevLine ) {
90                         prevLine = line;
91                         dim[0]++;
92                     }
93                 } else if ( line == 1 && m_hasHeader ) {
94                     headers.add(value);
95                 }
96                 
97                 // update num cols
98
if ( col > dim[1] )
99                     dim[1] = col;
100             }
101         };
102         
103         // do a scan of the stream, collecting length and type data
104
try {
105             read(is, scanner);
106         } catch ( IOException JavaDoc ioe ) {
107             throw new DataIOException(ioe);
108         } catch ( DataParseException de ) {
109             // can't happen
110
}
111         
112         // create the table
113
int nrows = dim[0];
114         int ncols = dim[1];
115         final Table table = new Table(nrows, ncols);
116         
117         // create the table columns
118
for ( int i=0; i < ncols; ++i ) {
119             String JavaDoc header;
120             if ( m_hasHeader ) {
121                 header = (String JavaDoc)headers.get(i);
122             } else {
123                 header = getDefaultHeader(i);
124             }
125             table.addColumn(header, di.getType(i));
126             table.getColumn(i).setParser(di.getParser(i));
127         }
128         
129         // reset dim array, will hold row/col indices
130
dim[0] = dim[1] = -1;
131         
132         TableReadListener parser = new TableReadListener() {
133             int prevLine = -1;
134             public void readValue(int line, int col, String JavaDoc value)
135                 throws DataParseException
136             {
137                 // early exit on header value
138
if ( line == 1 && m_hasHeader )
139                     return;
140                 if ( line != prevLine ) {
141                     prevLine = line;
142                     ++dim[0];
143                 }
144                 dim[1] = col-1;
145                 
146                 // XXX NOTE-2005.08.29-jheer
147
// For now we use generic routines for filling column values.
148
// This results in the autoboxing of primitive types, slowing
149
// performance a bit and possibly triggering avoidable garbage
150
// collections. If this proves to be a problem down the road,
151
// we can add more nuance later.
152
DataParser dp = di.getParser(dim[1]);
153                 table.set(dim[0], dim[1], dp.parse(value));
154             }
155         };
156         
157         // read the data into the table
158
try {
159             // prepare the input stream
160
if ( is.markSupported() ) {
161                 is.reset();
162             } else {
163                 is = buf.getAsInputStream();
164             }
165             // read the data
166
read(is, parser);
167         } catch ( IOException JavaDoc ioe ) {
168             throw new DataIOException(ioe);
169         } catch ( DataParseException de ) {
170             throw new DataIOException("Parse exception for column "
171                     + '\"' + dim[1] + '\"' + " at row: " + dim[0], de);
172         }
173         
174         return table;
175     }
176     
177     /**
178      * Returns default column header names of the type "A", "B", ...,
179      * "Z", "AA", "AB", etc.
180      * @param idx the index of the column header
181      * @return a default column header name for the given index.
182      */

183     public static String JavaDoc getDefaultHeader(int idx) {
184         if ( idx == 0 ) return "A";
185         int len = ((int)(Math.log(idx) / Math.log(26))) + 1;
186         char[] h = new char[len];
187         int p = len;
188         
189         h[--p] = (char)('A'+(idx%26));
190         idx = idx / 26;
191         
192         while ( idx > 26 ) {
193             h[--p] = (char)('A'+(idx%26));
194             idx = idx/26;
195         }
196         if ( idx > 0 ) {
197             h[--p] = (char)('A'+((idx-1)%26));
198         }
199
200         return new String JavaDoc(h, p, len);
201     }
202     
203     /**
204      * Scans the input stream, making call backs for each encountered entry
205      * on the provided TextReadListener.
206      * @param is the InputStream to read
207      * @param trl the TextReadListener that will receive callbacks
208      * @throws IOException
209      * @throws DataParseException
210      */

211     protected abstract void read(InputStream JavaDoc is, TableReadListener trl)
212         throws IOException JavaDoc, DataParseException;
213
214 } // end of abstract class AbstractTextTableReader
215
Popular Tags