KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jodd > datetime > formatter > AbstractFormatter


1 // Copyright (c) 2003-2007, Jodd Team (jodd.sf.net). All Rights Reserved.
2

3 package jodd.datetime.formatter;
4
5 import jodd.datetime.DateTimeStamp;
6 import jodd.datetime.JDateTime;
7
8 /**
9  * Abstract formatter for easier {@link JdtFormatter} implementations.
10  * <p>
11  * For setting date and time, default formatter parses input String against
12  * specified format. It extracts parts of input string upon patterns
13  * and then each part is converted to a number for a date/time information.
14  * It doesn't ignore any non-number charater. If conversion fails,
15  * <code>null</code> is returned.
16  *
17  * <p>
18  * Getting date time is also user firendly. Specified format may not only
19  * contains patterns but also any text. To remove errors in decoding when
20  * text may be recognized as one of patterns, format text may be quoted
21  * with the special escape sign. Double quote in the text will be decoded
22  * as a single quote, of course.
23  * <p>
24  *
25  * It is not necessary to have parsers for all patterns.
26  */

27 public abstract class AbstractFormatter implements JdtFormatter {
28
29     /**
30      * Availiable patterns list. Used by {@link #findPattern(char[], int)}
31      * when parsing date time format. Each formatter will have its own set of
32      * patterns, in strictly defined order.
33      */

34     protected char[][] patterns;
35
36     /**
37      * Escape character.
38      */

39     protected char ESCAPE_CHAR = '\'';
40
41
42     /**
43      * Converts String array of patterns to char arrays.
44      */

45     protected void preparePatterns(String JavaDoc[] spat) {
46         patterns = new char[spat.length][];
47         for (int i = 0; i < spat.length; i++) {
48             patterns[i] = spat[i].toCharArray();
49         }
50     }
51
52     /**
53      * Finds the longest pattern in provided format starting from specified possition.
54      * All availiable patterns are stored in {@link #patterns}.
55      *
56      * @param format date time format to examine
57      * @param i starting index
58      *
59      * @return 0-based index of founded pattern, or <code>-1</code> if pattern not found
60      */

61     protected int findPattern(char[] format, int i) {
62         int frmtc_len = format.length;
63         boolean match;
64         int n, lastn = -1;
65         int maxLen = 0;
66         for (n = 0; n < patterns.length; n++) {
67             char[] curr = patterns[n]; // current pattern from the pattern list
68
if (i > frmtc_len - curr.length) {
69                 continue;
70             }
71             match = true;
72             int delta = 0;
73             while (delta < curr.length) { // match given pattern
74
if (curr[delta] != format[i + delta]) {
75                     match = false; // no match, goto next
76
break;
77                 }
78                 delta++;
79             }
80             if (match == true) { // match
81
if (patterns[n].length > maxLen) { // find longest match
82
lastn = n;
83                     maxLen = patterns[n].length;
84                 }
85             }
86         }
87         return lastn;
88     }
89
90     // ---------------------------------------------------------------- convert
91

92     /**
93      * Creates a date-time string for founded pattern. Founded patterns
94      * is identified by its {@link #patterns} index.
95      *
96      * @param patternIndex index of founded pattern
97      * @param jdt date time information
98      */

99     protected abstract String JavaDoc convertPattern(int patternIndex, JDateTime jdt);
100
101     /**
102      * @see jodd.datetime.formatter.JdtFormatter#convert(jodd.datetime.JDateTime, String)
103      */

104     public String JavaDoc convert(JDateTime jdt, String JavaDoc format) {
105         char[] fmtc = format.toCharArray();
106         int fmtc_len = fmtc.length;
107         StringBuffer JavaDoc result = new StringBuffer JavaDoc(fmtc_len);
108
109         int i = 0;
110         while (i < fmtc_len) {
111             if (fmtc[i] == ESCAPE_CHAR) { // quote founded
112
int end = i + 1;
113                 while (end < fmtc_len) {
114                     if (fmtc[end] == ESCAPE_CHAR) { // second quote founded
115
if (end + 1 < fmtc_len) {
116                             end++;
117                             if (fmtc[end] == ESCAPE_CHAR) { // skip double quotes
118
result.append(ESCAPE_CHAR); // and continue
119
} else {
120                                 break;
121                             }
122                         }
123                     } else {
124                         result.append(fmtc[end]);
125                     }
126                     end++;
127                 }
128                 i = end;
129                 continue; // end of quoted string, continue the main loop
130
}
131
132             int n = findPattern(fmtc, i);
133             if (n != -1) { // pattern founded
134
result.append(convertPattern(n, jdt));
135                 i += patterns[n].length;
136             } else {
137                 result.append(fmtc[i]);
138                 i++;
139             }
140         }
141         return result.toString();
142     }
143
144     // ---------------------------------------------------------------- parse
145

146     /**
147      * Parses value for matched pattern. Founded patterns
148      * is identified by its {@link #patterns} index.
149      * Note that value may represent both integer and decimals.
150      * May throw {@link NumberFormatException}.
151      *
152      * @param patternIndex index of founded pattern
153      * @param value value to parse
154      * @param destination destination to modify
155      */

156     protected abstract void parseValue(int patternIndex, String JavaDoc value, DateTimeStamp destination);
157
158     /**
159      * @see jodd.datetime.formatter.JdtFormatter#parse(String, String)
160      */

161     public DateTimeStamp parse(String JavaDoc string, String JavaDoc format) {
162         char[] sc = string.toCharArray();
163         char[] fc = format.toCharArray();
164
165         int i = 0, j = 0;
166         int slen = string.length();
167         int tlen = format.length();
168
169         DateTimeStamp time = new DateTimeStamp();
170
171         while (true) {
172             int n = findPattern(fc, i);
173             if (n != -1) { // pattern founded
174
i += patterns[n].length;
175                 StringBuffer JavaDoc w = new StringBuffer JavaDoc();
176                 char next = 0xFFFF;
177                 if (i < tlen) {
178                     next = fc[i]; // next = delimeter
179
}
180                 while ((j < slen) && (sc[j] != next)) {
181                     w.append(sc[j]);
182                     j++;
183                 }
184                 try {
185                     parseValue(n, w.toString(), time);
186                 } catch (NumberFormatException JavaDoc nfe) {
187                     return null;
188                 }
189             } else {
190                 if (fc[i] == sc[j]) {
191                     j++;
192                 }
193                 i++;
194             }
195             if ((i == tlen) || (j == slen)) {
196                 break;
197             }
198         }
199         return time;
200     }
201 }
202
Popular Tags