KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > ssi > ExpressionTokenizer


1 /*
2  * Copyright 1999,2004 The Apache Software Foundation. Licensed under the
3  * Apache License, Version 2.0 (the "License"); you may not use this file
4  * except in compliance with the License. You may obtain a copy of the License
5  * at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable
6  * law or agreed to in writing, software distributed under the License is
7  * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
8  * KIND, either express or implied. See the License for the specific language
9  * governing permissions and limitations under the License.
10  */

11 package org.apache.catalina.ssi;
12
13
14 /**
15  * Parses an expression string to return the individual tokens. This is
16  * patterned similar to the StreamTokenizer in the JDK but customized for SSI
17  * conditional expression parsing.
18  *
19  * @version $Revision: 467222 $
20  * @author Paul Speed
21  */

22 public class ExpressionTokenizer {
23     public static final int TOKEN_STRING = 0;
24     public static final int TOKEN_AND = 1;
25     public static final int TOKEN_OR = 2;
26     public static final int TOKEN_NOT = 3;
27     public static final int TOKEN_EQ = 4;
28     public static final int TOKEN_NOT_EQ = 5;
29     public static final int TOKEN_RBRACE = 6;
30     public static final int TOKEN_LBRACE = 7;
31     public static final int TOKEN_GE = 8;
32     public static final int TOKEN_LE = 9;
33     public static final int TOKEN_GT = 10;
34     public static final int TOKEN_LT = 11;
35     public static final int TOKEN_END = 12;
36     private char[] expr;
37     private String JavaDoc tokenVal = null;
38     private int index;
39     private int length;
40
41
42     /**
43      * Creates a new parser for the specified expression.
44      */

45     public ExpressionTokenizer(String JavaDoc expr) {
46         this.expr = expr.trim().toCharArray();
47         this.length = this.expr.length;
48     }
49
50
51     /**
52      * Returns true if there are more tokens.
53      */

54     public boolean hasMoreTokens() {
55         return index < length;
56     }
57
58
59     /**
60      * Returns the current index for error reporting purposes.
61      */

62     public int getIndex() {
63         return index;
64     }
65
66
67     protected boolean isMetaChar(char c) {
68         return Character.isWhitespace(c) || c == '(' || c == ')' || c == '!'
69                 || c == '<' || c == '>' || c == '|' || c == '&' || c == '=';
70     }
71
72
73     /**
74      * Returns the next token type and initializes any state variables
75      * accordingly.
76      */

77     public int nextToken() {
78         // Skip any leading white space
79
while (index < length && Character.isWhitespace(expr[index]))
80             index++;
81         // Clear the current token val
82
tokenVal = null;
83         if (index == length) return TOKEN_END; // End of string
84
int start = index;
85         char currentChar = expr[index];
86         char nextChar = (char)0;
87         index++;
88         if (index < length) nextChar = expr[index];
89         // Check for a known token start
90
switch (currentChar) {
91             case '(' :
92                 return TOKEN_LBRACE;
93             case ')' :
94                 return TOKEN_RBRACE;
95             case '=' :
96                 return TOKEN_EQ;
97             case '!' :
98                 if (nextChar == '=') {
99                     index++;
100                     return TOKEN_NOT_EQ;
101                 } else {
102                     return TOKEN_NOT;
103                 }
104             case '|' :
105                 if (nextChar == '|') {
106                     index++;
107                     return TOKEN_OR;
108                 }
109                 break;
110             case '&' :
111                 if (nextChar == '&') {
112                     index++;
113                     return TOKEN_AND;
114                 }
115                 break;
116             case '>' :
117                 if (nextChar == '=') {
118                     index++;
119                     return TOKEN_GE; // Greater than or equal
120
} else {
121                     return TOKEN_GT; // Greater than
122
}
123             case '<' :
124                 if (nextChar == '=') {
125                     index++;
126                     return TOKEN_LE; // Less than or equal
127
} else {
128                     return TOKEN_LT; // Less than
129
}
130             default :
131                 // Otherwise it's a string
132
break;
133         }
134         int end = index;
135         // If it's a quoted string then end is the next unescaped quote
136
if (currentChar == '"' || currentChar == '\'') {
137             char endChar = currentChar;
138             boolean escaped = false;
139             start++;
140             for (; index < length; index++) {
141                 if (expr[index] == '\\' && !escaped) {
142                     escaped = true;
143                     continue;
144                 }
145                 if (expr[index] == endChar && !escaped) break;
146                 escaped = false;
147             }
148             end = index;
149             index++; // Skip the end quote
150
} else {
151             // End is the next whitespace character
152
for (; index < length; index++) {
153                 if (isMetaChar(expr[index])) break;
154             }
155             end = index;
156         }
157         // Extract the string from the array
158
this.tokenVal = new String JavaDoc(expr, start, end - start);
159         return TOKEN_STRING;
160     }
161
162
163     /**
164      * Returns the String value of the token if it was type TOKEN_STRING.
165      * Otherwise null is returned.
166      */

167     public String JavaDoc getTokenValue() {
168         return tokenVal;
169     }
170 }
Popular Tags