KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > prefuse > data > parser > ParserFactory


1 package prefuse.data.parser;
2
3 import java.util.Arrays JavaDoc;
4
5 /**
6  * Factory class that maintains a collection of parser instances and returns
7  * the appropriate parser based on a history of samples presented to the
8  * factory. The {@link #sample(String)} method takes a text string and tests
9  * it against all available parsers, updating whether or not the parsers can
10  * successfully parse the value. This method is used in a more automated
11  * fashion by the {@link TypeInferencer} class.
12  *
13  * @author <a HREF="http://jheer.org">jeffrey heer</a>
14  * @see TypeInferencer
15  */

16 public class ParserFactory implements Cloneable JavaDoc {
17     
18     private static final DataParser[] DEFAULT_PARSERS =
19         new DataParser[] {
20             new IntParser(),
21             new LongParser(),
22             new DoubleParser(),
23             new FloatParser(),
24             new BooleanParser(),
25             new ColorIntParser(),
26             new DateParser(),
27             new TimeParser(),
28             new DateTimeParser(),
29             new IntArrayParser(),
30             new LongArrayParser(),
31             new FloatArrayParser(),
32             new DoubleArrayParser(),
33             new StringParser()
34         };
35     
36     private static final ParserFactory DEFAULT_FACTORY =
37         new ParserFactory(DEFAULT_PARSERS);
38     
39     private DataParser[] m_parsers;
40     private boolean[] m_isCandidate;
41     
42     /**
43      * Returns the default parser factory. The default factory tests for the
44      * following data types (in the provided order of precedence):
45      * int, long, double, float, boolean, Date, Time, DateTime, String.
46      */

47     public static ParserFactory getDefaultFactory() {
48         return DEFAULT_FACTORY;
49     }
50     
51     /**
52      * Constructor. Uses a default collection of parsers, testing for the
53      * following data type in the followinf order of precedence:
54      * int, long, double, float, boolean, Date, Time, DateTime, String.
55      */

56     public ParserFactory() {
57         this(DEFAULT_PARSERS);
58     }
59     
60     /**
61      * @see java.lang.Object#clone()
62      */

63     public Object JavaDoc clone() {
64         return new ParserFactory(m_parsers);
65     }
66     
67     /**
68      * <p>Constructor. Takes an array of parsers to test. After creating this
69      * instance, sample data values can be passed in using the
70      * <code>sample()</code> method, and this class will check the sample
71      * against the parsers, computing which parsers can successfully parse the
72      * sample. This process of elimination disregards inappropriate parsers.
73      * After a series of samples, the <code>getParser()</code>
74      * method can be used to retrieve the highest ranking candidate parser.
75      * </p>
76      *
77      * <p>
78      * If no parser can parse all samples, a null value will be returned by
79      * getParser(). For this reason, it is recommended to always use a
80      * StringParser as the last element of the input array, as it is guaranteed
81      * to always parse successfully (by simply returning its input String).
82      * </p>
83      *
84      * <p>
85      * The ordering of parsers in the array is taken to be the desired order
86      * of precendence of the parsers. For example, if both parser[0] and
87      * parser[2] can parse all the available samples, parser[0] will be
88      * returned.
89      * </p>
90      * @param parsers the input DataParsers to use.
91      */

92     public ParserFactory(DataParser[] parsers) {
93         // check integrity of input
94
for ( int i=0; i<parsers.length; ++i ) {
95             if ( parsers[i] == null ) {
96                 throw new IllegalArgumentException JavaDoc(
97                     "Input parsers must be non-null");
98             }
99         }
100         // initialize member variables
101
m_parsers = parsers;
102         m_isCandidate = new boolean[m_parsers.length];
103         reset();
104     }
105     
106     /**
107      * Reset the candidate parser settings, making each parser
108      * equally likely.
109      */

110     protected void reset() {
111         Arrays.fill(m_isCandidate, true);
112     }
113     
114     /**
115      * Sample a data value against the parsers, updating the
116      * parser candidates.
117      * @param val the String value to sample
118      */

119     protected void sample(String JavaDoc val) {
120         for ( int i=0; i<m_parsers.length; ++i ) {
121             if ( m_isCandidate[i] ) {
122                 m_isCandidate[i] = m_parsers[i].canParse(val);
123             }
124         }
125     }
126     
127     /**
128      * Returns the highest ranking parser that successfully can
129      * parse all the input samples viewed by this instance. If
130      * no such parser exists, a null value is returned.
131      * @return the highest-ranking data parser, or null if none
132      */

133     protected DataParser getParser() {
134         for ( int i=0; i<m_parsers.length; ++i ) {
135             if ( m_isCandidate[i] ) {
136                 return m_parsers[i];
137             }
138         }
139         return null;
140     }
141     
142     /**
143      * Returns a parser for the specified data type.
144      * @param type the Class for the data type to parse
145      * @return a parser for the given data type, or null
146      * if no such parser can be found.
147      */

148     public DataParser getParser(Class JavaDoc type) {
149        for ( int i=0; i<m_parsers.length; ++i ) {
150            if ( m_parsers[i].getType().equals(type) ) {
151                return m_parsers[i];
152            }
153        }
154        return null;
155     }
156     
157     /**
158      * Analyzes the given array of String values to determine an
159      * acceptable parser data type.
160      * @param data an array of String values to parse
161      * @param startRow the row from which to begin analyzing the
162      * data array, allowing header rows to be excluded.
163      * @return the appropriate parser for the inferred data type,
164      * of null if none.
165      */

166     public DataParser getParser(String JavaDoc[] data, int startRow) {
167         return getParser(new String JavaDoc[][] { data }, 0, startRow);
168     }
169     
170     /**
171      * Analyzes a column of the given array of String values to
172      * determine an acceptable parser data type.
173      * @param data an 2D array of String values to parse
174      * @param col an index for the column to process
175      * @param startRow the row from which to begin analyzing the
176      * data array, allowing header rows to be excluded.
177      * @return the appropriate parser for the inferred data type,
178      * of null if none.
179      */

180     public DataParser getParser(String JavaDoc[][] data, int col, int startRow) {
181         // sanity check input
182
if ( data == null || data.length == 0 )
183             return null;
184         
185         int nrows = data.length;
186         
187         // analyze each column in turn
188
this.reset();
189         for ( int row=startRow; row<nrows; ++row ) {
190             this.sample(data[row][col]);
191         }
192         
193         DataParser parser = getParser();
194         return parser;
195     }
196     
197 } // end of class ParserFactory
198
Popular Tags