1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| package org.apache.hivemind.impl; |
16 |
| |
17 |
| import org.apache.commons.logging.Log; |
18 |
| import org.apache.commons.logging.LogFactory; |
19 |
| import org.apache.hivemind.ErrorHandler; |
20 |
| import org.apache.hivemind.Location; |
21 |
| import org.apache.hivemind.SymbolSource; |
22 |
| |
23 |
| |
24 |
| |
25 |
| |
26 |
| |
27 |
| |
28 |
| |
29 |
| public class SymbolExpander |
30 |
| { |
31 |
| private ErrorHandler _errorHandler; |
32 |
| |
33 |
| private SymbolSource _source; |
34 |
| |
35 |
155
| public SymbolExpander(ErrorHandler handler, SymbolSource source)
|
36 |
| { |
37 |
155
| _errorHandler = handler;
|
38 |
155
| _source = source;
|
39 |
| } |
40 |
| |
41 |
| private static final Log LOG = LogFactory.getLog(SymbolExpander.class); |
42 |
| |
43 |
| private static final int STATE_START = 0; |
44 |
| |
45 |
| private static final int STATE_DOLLAR = 1; |
46 |
| |
47 |
| private static final int STATE_COLLECT_SYMBOL_NAME = 2; |
48 |
| |
49 |
| |
50 |
| |
51 |
| |
52 |
| |
53 |
| |
54 |
| |
55 |
| |
56 |
| |
57 |
| |
58 |
| |
59 |
7157
| public String expandSymbols(String text, Location location)
|
60 |
| { |
61 |
7157
| StringBuffer result = new StringBuffer(text.length());
|
62 |
7157
| char[] buffer = text.toCharArray();
|
63 |
7157
| int state = STATE_START;
|
64 |
7157
| int blockStart = 0;
|
65 |
7157
| int blockLength = 0;
|
66 |
7157
| int symbolStart = -1;
|
67 |
7157
| int symbolLength = 0;
|
68 |
7157
| int i = 0;
|
69 |
7157
| int braceDepth = 0;
|
70 |
7157
| boolean anySymbols = false;
|
71 |
| |
72 |
7157
| while (i < buffer.length)
|
73 |
| { |
74 |
132237
| char ch = buffer[i];
|
75 |
| |
76 |
132237
| switch (state)
|
77 |
| { |
78 |
132135
| case STATE_START:
|
79 |
| |
80 |
132135
| if (ch == '$')
|
81 |
| { |
82 |
18
| state = STATE_DOLLAR;
|
83 |
18
| i++;
|
84 |
18
| continue;
|
85 |
| } |
86 |
| |
87 |
132117
| blockLength++;
|
88 |
132117
| i++;
|
89 |
132117
| continue;
|
90 |
| |
91 |
17
| case STATE_DOLLAR:
|
92 |
| |
93 |
17
| if (ch == '{')
|
94 |
| { |
95 |
14
| state = STATE_COLLECT_SYMBOL_NAME;
|
96 |
14
| i++;
|
97 |
| |
98 |
14
| symbolStart = i;
|
99 |
14
| symbolLength = 0;
|
100 |
14
| braceDepth = 1;
|
101 |
| |
102 |
14
| continue;
|
103 |
| } |
104 |
| |
105 |
| |
106 |
| |
107 |
| |
108 |
| |
109 |
3
| if (ch == '$')
|
110 |
| { |
111 |
| |
112 |
| |
113 |
| |
114 |
2
| anySymbols = true;
|
115 |
| |
116 |
2
| if (blockLength > 0)
|
117 |
1
| result.append(buffer, blockStart, blockLength);
|
118 |
| |
119 |
2
| result.append(ch);
|
120 |
| |
121 |
2
| i++;
|
122 |
2
| blockStart = i;
|
123 |
2
| blockLength = 0;
|
124 |
2
| state = STATE_START;
|
125 |
| |
126 |
2
| continue;
|
127 |
| } |
128 |
| |
129 |
| |
130 |
| |
131 |
| |
132 |
1
| blockLength++;
|
133 |
| |
134 |
1
| state = STATE_START;
|
135 |
1
| continue;
|
136 |
| |
137 |
85
| case STATE_COLLECT_SYMBOL_NAME:
|
138 |
| |
139 |
85
| if (ch != '}')
|
140 |
| { |
141 |
71
| if (ch == '{')
|
142 |
1
| braceDepth++;
|
143 |
| |
144 |
71
| i++;
|
145 |
71
| symbolLength++;
|
146 |
71
| continue;
|
147 |
| } |
148 |
| |
149 |
14
| braceDepth--;
|
150 |
| |
151 |
14
| if (braceDepth > 0)
|
152 |
| { |
153 |
1
| i++;
|
154 |
1
| symbolLength++;
|
155 |
1
| continue;
|
156 |
| } |
157 |
| |
158 |
| |
159 |
| |
160 |
| |
161 |
| |
162 |
13
| if (symbolLength == 0)
|
163 |
1
| blockLength += 3;
|
164 |
| |
165 |
| |
166 |
| |
167 |
| |
168 |
13
| if (blockLength > 0)
|
169 |
6
| result.append(buffer, blockStart, blockLength);
|
170 |
| |
171 |
13
| if (symbolLength > 0)
|
172 |
| { |
173 |
12
| String variableName = text.substring(symbolStart, symbolStart
|
174 |
| + symbolLength); |
175 |
| |
176 |
12
| result.append(expandSymbol(variableName, location));
|
177 |
| |
178 |
12
| anySymbols = true;
|
179 |
| } |
180 |
| |
181 |
13
| i++;
|
182 |
13
| blockStart = i;
|
183 |
13
| blockLength = 0;
|
184 |
| |
185 |
| |
186 |
| |
187 |
13
| state = STATE_START;
|
188 |
| |
189 |
13
| continue;
|
190 |
| } |
191 |
| |
192 |
| } |
193 |
| |
194 |
| |
195 |
| |
196 |
| |
197 |
7157
| if (!anySymbols)
|
198 |
7144
| return text;
|
199 |
| |
200 |
| |
201 |
| |
202 |
| |
203 |
13
| if (state == STATE_DOLLAR)
|
204 |
1
| blockLength++;
|
205 |
| |
206 |
13
| if (state == STATE_COLLECT_SYMBOL_NAME)
|
207 |
1
| blockLength += symbolLength + 2;
|
208 |
| |
209 |
13
| if (blockLength > 0)
|
210 |
5
| result.append(buffer, blockStart, blockLength);
|
211 |
| |
212 |
13
| return result.toString();
|
213 |
| } |
214 |
| |
215 |
12
| private String expandSymbol(String name, Location location)
|
216 |
| { |
217 |
12
| String value = _source.valueForSymbol(name);
|
218 |
| |
219 |
12
| if (value != null)
|
220 |
10
| return value;
|
221 |
| |
222 |
2
| _errorHandler.error(LOG, ImplMessages.noSuchSymbol(name), location, null);
|
223 |
| |
224 |
2
| return "${" + name + "}";
|
225 |
| } |
226 |
| |
227 |
| } |