KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > iapi > types > DateTimeParser


1 /*
2
3    Derby - Class org.apache.derby.iapi.types.DateTimeParser
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.iapi.types;
23
24 import org.apache.derby.iapi.reference.SQLState;
25 import org.apache.derby.iapi.error.StandardException;
26
27 /**
28  * This class provides a simple regular expression parser for standard format dates, times, and timestamps
29  */

30 class DateTimeParser
31 {
32
33     private String JavaDoc str;
34     private String JavaDoc trimmedString;
35     private int len;
36     private int fieldStart;
37     private char currentSeparator;
38
39     DateTimeParser( String JavaDoc str)
40     {
41         this.str = str;
42         len = str.length();
43     }
44
45     /**
46      * Parse the next integer.
47      *
48      * @param maxDigits the maximum number of digits
49      * @param truncationAllowed If true then leading zeroes may be ommitted. If false then the integer must be
50      * exactly ndigits long.
51      * @param separator The separator at the end of the integer. If zero then the integer must be at the end of the string
52      * but may be followed by spaces.
53      * @param isFraction If true then the returned integer will be multiplied by 10**(maxDigits - actualDigitCount)
54      *
55      * @return the integer.
56      *
57      * @exception StandardException invalid syntax.
58      */

59     int parseInt( int maxDigits, boolean truncationAllowed, char[] separator, boolean isFraction)
60         throws StandardException
61     {
62         int number = 0;
63         char c;
64         int digitCount = 0;
65
66         for( ; fieldStart < len; fieldStart++)
67         {
68             c = str.charAt( fieldStart);
69             if( Character.isDigit( c))
70             {
71                 if( digitCount >= maxDigits)
72                     throw StandardException.newException( SQLState.LANG_DATE_SYNTAX_EXCEPTION);
73                 digitCount++;
74                 number = number*10 + Character.digit( c, 10);
75             }
76             else
77                 break;
78         }
79         if( truncationAllowed ? (digitCount == 0 && !isFraction) : (digitCount != maxDigits))
80             throw StandardException.newException( SQLState.LANG_DATE_SYNTAX_EXCEPTION);
81
82         updateCurrentSeparator();
83         
84         if( separator == null)
85         {
86             // separator not required
87
if( fieldStart < len)
88                 fieldStart++;
89         }
90         else
91         {
92             int sepIdx;
93             for( sepIdx = 0; sepIdx < separator.length; sepIdx++)
94             {
95                 if( separator[sepIdx] != 0)
96                 {
97                     if( currentSeparator == separator[sepIdx])
98                     {
99                         fieldStart++;
100                         break;
101                     }
102                 }
103                 else
104                 {
105                     // separator[sepIdx] matches the end of the string
106
int j;
107                     for( j = fieldStart; j < len; j++)
108                     {
109                         if( str.charAt( j) != ' ')
110                             break;
111                     }
112                     if( j == len)
113                     {
114                         fieldStart = j;
115                         break;
116                     }
117                 }
118             }
119             if( sepIdx >= separator.length)
120                 throw StandardException.newException( SQLState.LANG_DATE_SYNTAX_EXCEPTION);
121         }
122
123         if( isFraction)
124         {
125             for(int i = digitCount; i < maxDigits; i++)
126                 number *= 10;
127         }
128         return number;
129     } // end of parseInt
130

131     /**
132      * Determine if the next characters are one of a choice of strings.
133      *
134      * @param choices An array of strings.
135      *
136      * @return An index in choices.
137      *
138      * @exception StandardException if the next characters are not in choices.
139      */

140     int parseChoice( String JavaDoc[] choices) throws StandardException
141     {
142         for( int choiceIdx = 0; choiceIdx < choices.length; choiceIdx++)
143         {
144             String JavaDoc choice = choices[ choiceIdx];
145             int choiceLen = choice.length();
146             if( fieldStart + choiceLen <= len)
147             {
148                 int i;
149                 for( i = 0; i < choiceLen; i++)
150                 {
151                     if( choice.charAt( i) != str.charAt( fieldStart + i))
152                         break;
153                 }
154                 if( i == choiceLen)
155                 {
156                     fieldStart += choiceLen;
157                     updateCurrentSeparator();
158                     return choiceIdx;
159                 }
160             }
161         }
162         throw StandardException.newException( SQLState.LANG_DATE_SYNTAX_EXCEPTION);
163     } // end of parseChoice
164

165     private void updateCurrentSeparator()
166     {
167         if( fieldStart >= len)
168             currentSeparator = 0;
169         else
170         {
171             currentSeparator = str.charAt( fieldStart);
172             if( currentSeparator == ' ')
173             {
174                 // Trailing spaces are always OK. See if we are really at the end
175
for( int i = fieldStart + 1; i < len; i++)
176                 {
177                     if( str.charAt( i) != ' ')
178                         return;
179                 }
180                 currentSeparator = 0;
181                 fieldStart = len;
182             }
183         }
184     } // end of updateCurrentSeparator
185

186     /**
187      * Check that we are at the end of the string: that the rest of the characters, if any, are blanks.
188      *
189      * @return the original string with trailing blanks trimmed off.
190      * @exception StandardException if there are more non-blank characters.
191      */

192     String JavaDoc checkEnd() throws StandardException
193     {
194         int end = fieldStart;
195         for( ; fieldStart < len; fieldStart++)
196         {
197             if( str.charAt( fieldStart) != ' ')
198                 throw StandardException.newException( SQLState.LANG_DATE_SYNTAX_EXCEPTION);
199         }
200         currentSeparator = 0;
201         while( end > 0 && str.charAt( end - 1) == ' ')
202             end--;
203         trimmedString = (end == len) ? str : str.substring( 0, end);
204         return trimmedString;
205     } // end of checkEnd
206

207     /**
208      * Get the parsed string with trailing blanks removed. <b>This method is only valid after checkEnd
209      * has been called.</b>
210      *
211      * @return The string with trailing blanks removed.
212      */

213     String JavaDoc getTrimmedString()
214     {
215         return trimmedString;
216     }
217
218     /**
219      * @return the next separator, 0 if there are none
220      */

221     char nextSeparator()
222     {
223         for( int i = fieldStart + 1; i < len; i++)
224         {
225             char c = str.charAt( i);
226             if( ! Character.isLetterOrDigit( c))
227                 return c;
228         }
229         return 0;
230     }
231
232     /**
233      * @return the separator between the last parsed integer and the next integer, 0 if the parser is at
234      * the end of the string.
235      */

236     char getCurrentSeparator()
237     {
238         return currentSeparator;
239     }
240 }
241
Popular Tags