KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tapestry > script > AbstractTokenRule


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

15 package org.apache.tapestry.script;
16
17 import org.apache.hivemind.Location;
18 import org.apache.tapestry.util.xml.BaseRule;
19 import org.apache.tapestry.util.xml.RuleDirectedParser;
20
21 /**
22  * Base class for the rules that build {@link org.apache.tapestry.script.IScriptToken}s.
23  * Used with classes that can contain a mix of text and elements (those that
24  * accept "full content").
25  *
26  *
27  * @author Howard Lewis Ship
28  * @since 3.0
29  **/

30
31 abstract class AbstractTokenRule extends BaseRule
32 {
33
34     /**
35      * Adds a token to its parent, the top object on the stack.
36      */

37     protected void addToParent(RuleDirectedParser parser, IScriptToken token)
38     {
39         IScriptToken parent = (IScriptToken) parser.peek();
40
41         parent.addToken(token);
42     }
43
44     /**
45      * Peeks at the top object on the stack (which must be a {@link IScriptToken}),
46      * and converts the text into a series of {@link org.apache.tapestry.script.StaticToken} and
47      * {@link org.apache.tapestry.script.InsertToken}s.
48      */

49
50     public void content(RuleDirectedParser parser, String JavaDoc content)
51     {
52         IScriptToken token = (IScriptToken) parser.peek();
53
54         addTextTokens(token, content, parser.getLocation());
55     }
56
57     private static final int STATE_START = 0;
58     private static final int STATE_DOLLAR = 1;
59     private static final int STATE_COLLECT_EXPRESSION = 2;
60
61     /**
62      * Parses the provided text and converts it into a series of
63      */

64     protected void addTextTokens(IScriptToken token, String JavaDoc text, Location location)
65     {
66         char[] buffer = text.toCharArray();
67         int state = STATE_START;
68         int blockStart = 0;
69         int blockLength = 0;
70         int expressionStart = -1;
71         int expressionLength = 0;
72         int i = 0;
73         int braceDepth = 0;
74
75         while (i < buffer.length)
76         {
77             char ch = buffer[i];
78
79             switch (state)
80             {
81                 case STATE_START :
82
83                     if (ch == '$')
84                     {
85                         state = STATE_DOLLAR;
86                         i++;
87                         continue;
88                     }
89
90                     blockLength++;
91                     i++;
92                     continue;
93
94                 case STATE_DOLLAR :
95
96                     if (ch == '{')
97                     {
98                         state = STATE_COLLECT_EXPRESSION;
99                         i++;
100
101                         expressionStart = i;
102                         expressionLength = 0;
103                         braceDepth = 1;
104
105                         continue;
106                     }
107
108                     // The '$' was just what it was, not the start of a ${} expression
109
// block, so include it as part of the static text block.
110

111                     blockLength++;
112
113                     state = STATE_START;
114                     continue;
115
116                 case STATE_COLLECT_EXPRESSION :
117
118                     if (ch != '}')
119                     {
120                         if (ch == '{')
121                             braceDepth++;
122
123                         i++;
124                         expressionLength++;
125                         continue;
126                     }
127
128                     braceDepth--;
129
130                     if (braceDepth > 0)
131                     {
132                         i++;
133                         expressionLength++;
134                         continue;
135                     }
136
137                     // Hit the closing brace of an expression.
138

139                     // Degenerate case: the string "${}".
140

141                     if (expressionLength == 0)
142                         blockLength += 3;
143
144                     if (blockLength > 0)
145                         token.addToken(constructStatic(text, blockStart, blockLength, location));
146
147                     if (expressionLength > 0)
148                     {
149                         String JavaDoc expression =
150                             text.substring(expressionStart, expressionStart + expressionLength);
151
152                         token.addToken(new InsertToken(expression, location));
153                     }
154
155                     i++;
156                     blockStart = i;
157                     blockLength = 0;
158
159                     // And drop into state start
160

161                     state = STATE_START;
162
163                     continue;
164             }
165
166         }
167
168         // OK, to handle the end. Couple of degenerate cases where
169
// a ${...} was incomplete, so we adust the block length.
170

171         if (state == STATE_DOLLAR)
172             blockLength++;
173
174         if (state == STATE_COLLECT_EXPRESSION)
175             blockLength += expressionLength + 2;
176
177         if (blockLength > 0)
178             token.addToken(constructStatic(text, blockStart, blockLength, location));
179     }
180
181     private IScriptToken constructStatic(
182         String JavaDoc text,
183         int blockStart,
184         int blockLength,
185         Location location)
186     {
187         String JavaDoc literal = text.substring(blockStart, blockStart + blockLength);
188
189         return new StaticToken(literal, location);
190     }
191 }
192
Popular Tags