KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > treeprocessor > variables > VariableExpressionTokenizer


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

16 package org.apache.cocoon.components.treeprocessor.variables;
17
18 import org.apache.cocoon.sitemap.PatternException;
19
20 /**
21  * Parses "Text {module:{module:attribute}} more text {variable}" types of
22  * expressions. Supports escaping of braces with '\' character, and nested
23  * expressions.
24  *
25  * @version CVS $Id: VariableExpressionTokenizer.java 54079 2004-10-08 13:30:28Z vgritsenko $
26  */

27 public final class VariableExpressionTokenizer {
28
29     /**
30      * Callback for tokenizer
31      */

32     public interface TokenReciever {
33         int OPEN = -2;
34         int CLOSE = -3;
35         int COLON = -4;
36         int TEXT = -5;
37         int MODULE = -6;
38         int VARIABLE = -8;
39
40         /**
41          * Reports parsed tokens.
42          */

43         void addToken(int type, String JavaDoc value) throws PatternException;
44     }
45
46     /**
47      * Tokenizes specified expression. Passes tokens to the
48      * reciever.
49      *
50      * @throws PatternException if expression is not valid
51      */

52     public static void tokenize(String JavaDoc expression, TokenReciever reciever) throws PatternException {
53
54         int lastTokenType = 0;
55
56         int openCount = 0;
57         int closeCount = 0;
58
59         int pos = 0;
60         int i;
61         boolean escape = false;
62
63         for (i = 0; i < expression.length(); i++) {
64             final char c = expression.charAt(i);
65
66             if (escape) {
67                 escape = false;
68             } else if (c == '\\' && i < expression.length()) {
69                 char nextChar = expression.charAt(i + 1);
70                 if (nextChar == '{' || nextChar == '}') {
71                     expression = expression.substring(0, i) + expression.substring(i + 1);
72                     escape = true;
73                     i--;
74                 }
75             } else if (c == '{') {
76                 if (i > pos) {
77                     reciever.addToken(lastTokenType = TokenReciever.TEXT, expression.substring(pos, i));
78                 }
79
80                 openCount++;
81                 reciever.addToken(lastTokenType = TokenReciever.OPEN, null);
82
83                 int colonPos = indexOf(expression, ':', i);
84                 int closePos = indexOf(expression, '}', i);
85                 int openPos = indexOf(expression, '{', i);
86
87                 if (openPos < colonPos && openPos < closePos) {
88                     throw new PatternException("Invalid '{' at position " + i +
89                                                " in expression \"" + expression + "\"");
90                 }
91
92                 if (colonPos < closePos) {
93                     // we've found a module
94
String JavaDoc module = expression.substring(i + 1, colonPos);
95                     reciever.addToken(lastTokenType = TokenReciever.MODULE, module);
96                     i = colonPos - 1;
97                 } else {
98                     // Unprefixed name: variable
99
reciever.addToken(lastTokenType = TokenReciever.VARIABLE, expression.substring(i + 1, closePos));
100                     i = closePos - 1;
101                 }
102
103                 pos = i + 1;
104             } else if (c == '}') {
105                 if (i > 0 && expression.charAt(i - 1) == '\\') {
106                     continue;
107                 }
108                 if (i > pos) {
109                     reciever.addToken(lastTokenType = TokenReciever.TEXT, expression.substring(pos, i));
110                 }
111
112                 closeCount++;
113                 reciever.addToken(lastTokenType = TokenReciever.CLOSE, null);
114
115                 pos = i + 1;
116             } else if (c == ':') {
117                 if (lastTokenType != TokenReciever.MODULE || i != pos) {
118                     // this colon isn't part of a module reference
119
continue;
120                 }
121
122                 reciever.addToken(lastTokenType = TokenReciever.COLON, null);
123                 pos = i + 1;
124             }
125         }
126
127         if (i > pos) {
128             reciever.addToken(lastTokenType = TokenReciever.TEXT, expression.substring(pos, i));
129         }
130
131         if (openCount != closeCount) {
132             throw new PatternException("Mismatching braces in expression \"" + expression + "\"");
133         }
134     }
135
136     private static int indexOf(String JavaDoc expression, char chr, int pos) {
137         int location;
138         return (location = expression.indexOf(chr, pos + 1)) != -1? location : expression.length();
139     }
140 }
141
Popular Tags