1
2
3
4
5 package org.rcfaces.core.internal.util;
6
7 import java.util.ArrayList;
8 import java.util.Iterator;
9 import java.util.LinkedList;
10 import java.util.List;
11
12 import javax.faces.FacesException;
13
14 import org.rcfaces.core.validator.IParameter;
15
16
17
18
19
20 public class CommandParserIterator implements Iterator {
21 private static final String REVISION = "$Revision: 1.18 $";
22
23 private static final IParameter[] EMPTY_PARAMETERS = new IParameter[0];
24
25 private final Iterator iterator;
26
27 public CommandParserIterator(String validatorCommand)
28 throws SyntaxException {
29 this.iterator = parseCommand(validatorCommand);
30 }
31
32 public boolean hasNext() {
33 return iterator.hasNext();
34 }
35
36 public Object next() {
37 return nextCommand();
38 }
39
40 public ICommand nextCommand() {
41 return (ICommand) iterator.next();
42 }
43
44 public void remove() {
45 iterator.remove();
46 }
47
48 private Iterator parseCommand(String validatorCommand)
49 throws SyntaxException {
50 char command[] = validatorCommand.toCharArray();
51
52 List list = new ArrayList();
53
54 Command cmd = null;
55
56 for (int i = 0; i < command.length;) {
57 char ch = command[i];
58
59 if (Character.isJavaIdentifierStart(ch)) {
60 cmd = new Command();
61 list.add(cmd);
62
63 i = startCommandString(cmd, command, i);
64
65 } else if (ch == '(') {
66 if (cmd == null) {
67 throw new SyntaxException(
68 "Debut des parametres avant nom de fonction.",
69 command, i);
70 }
71 i = startParameterString(cmd, command, i + 1);
72 cmd = null;
73
74 } else if (ch == ';') {
75 cmd = null;
76 i++;
77
78 } else if (Character.isWhitespace(ch)) {
79 i++;
80
81 } else {
82 throw new SyntaxException("Caractere non prevu (ascii="
83 + ((int) ch) + ") '" + ch + "'.", command, i);
84 }
85 }
86
87 return list.iterator();
88 }
89
90 private int startParameterString(Command cmd, char[] command, int i)
91 throws SyntaxException {
92 int start = i;
93 boolean nextParameter = false;
94
95 for (; i < command.length;) {
96 char ch = command[i];
97
98 if (ch == ')') {
99 return i + 1;
100
101 } else if (Character.isWhitespace(ch)) {
102 i++;
103 continue;
104
105 } else if (ch == '"' || ch == '\'') {
106 if (nextParameter) {
107 throw new SyntaxException(
108 "Mauvais separateur de parametres.", command, i);
109 }
110
111 nextParameter = true;
112
113 i = startLitteralString(cmd, command, i);
114
115 } else if (Character.isDigit(ch)) {
116 if (nextParameter) {
117 throw new SyntaxException(
118 "Mauvais separateur de parametres.", command, i);
119 }
120 nextParameter = true;
121 i = startNumberString(cmd, command, i);
122
123 } else if (Character.isJavaIdentifierStart(ch)) {
124 if (nextParameter) {
125 throw new SyntaxException(
126 "Mauvais separateur de parametres.", command, i);
127 }
128 nextParameter = true;
129 i = startIdentifierString(cmd, command, i);
130
131 } else if (ch == ',') {
132 nextParameter = false;
133 i++;
134 } else {
135
136 throw new SyntaxException("Caractere non prevu.", command, i);
137 }
138
139 }
140 throw new SyntaxException("Pas de fermeture des parametres.", command,
141 start);
142 }
143
144 private int startIdentifierString(Command cmd, char[] command, int i)
145 throws SyntaxException {
146 int start = i;
147
148 for (; i < command.length; i++) {
149 char ch = command[i];
150
151 if (Character.isWhitespace(ch) || ch == ',') {
152 cmd.addParameter(new String(command, start, i - start));
153 return i;
154 }
155
156 if (Character.isJavaIdentifierPart(ch)) {
157 continue;
158 }
159
160 throw new SyntaxException("Mauvaise syntaxe du nombre.", command,
161 start);
162 }
163
164 throw new SyntaxException("La chaine de caractere ne se ferme pas.",
165 command, start);
166 }
167
168 private int startNumberString(Command cmd, char[] command, int i)
169 throws SyntaxException {
170 int start = i;
171
172 for (; i < command.length; i++) {
173 char ch = command[i];
174
175 if (Character.isDigit(ch) || ch == '.') {
176 continue;
177 }
178
179 break;
180 }
181
182 cmd.addParameter(new String(command, start, i - start));
183 return i;
184 }
185
186 private int startLitteralString(Command cmd, char[] command, int i)
187 throws SyntaxException {
188 char end = command[i++];
189 int start = i;
190
191 for (; i < command.length; i++) {
192 char ch = command[i];
193
194 if (ch == end) {
195 cmd.addParameter(new String(command, start, i - start));
196 return i + 1;
197 }
198 if (ch == '\\') {
199 i++;
200 }
201 }
202
203 throw new SyntaxException("La chaine de caractere ne se ferme pas.",
204 command, start);
205 }
206
207 private int startCommandString(Command cmd, char[] command, int i) {
208 int start = i;
209
210 for (; i < command.length; i++) {
211 char ch = command[i];
212
213 if (Character.isJavaIdentifierPart(ch) == false && ch != '.') {
214 break;
215 }
216 }
217
218
219 cmd.setName(new String(command, start, i - start));
220
221 return i;
222 }
223
224
225
226
227
228 public interface ICommand {
229 String getName();
230
231 IParameter[] listParameters();
232 }
233
234 private static class Command implements ICommand {
235 private static final String REVISION = "$Revision: 1.18 $";
236
237 private String name;
238
239 private List parameters;
240
241 public String getName() {
242 return name;
243 }
244
245 public void setName(String name) {
246 this.name = name;
247 }
248
249 public void addParameter(String parameterValue) {
250 if (parameters == null) {
251 parameters = new LinkedList();
252 }
253 parameters.add(parameterValue);
254 }
255
256 public IParameter[] listParameters() {
257 if (parameters == null || parameters.size() < 1) {
258 return EMPTY_PARAMETERS;
259 }
260
261 IParameter ps[] = new IParameter[parameters.size()];
262 int i = 0;
263 for (Iterator it = parameters.iterator(); it.hasNext();) {
264 String value = (String) it.next();
265
266 ps[i++] = new Parameter(i, value);
267 }
268
269 return ps;
270 }
271 }
272
273 private static class Parameter implements IParameter {
274 private static final String REVISION = "$Revision: 1.18 $";
275
276 private final String name;
277
278 private final String value;
279
280 public Parameter(int index, String value) {
281 this.name = "param" + index;
282 this.value = value;
283 }
284
285 public String getName() {
286 return name;
287 }
288
289 public String getValue() {
290 return value;
291 }
292
293 }
294
295
296
297
298
299
300 public static class SyntaxException extends FacesException {
301
302 private static final String REVISION = "$Revision: 1.18 $";
303
304 private static final long serialVersionUID = 2866070330212947352L;
305
306 private String command;
307
308 private int position;
309
310 SyntaxException(String message, char command[], int position) {
311 this(message, new String(command), position);
312 }
313
314 SyntaxException(String message, String command, int position) {
315 super(message + " [message='" + command + "' position='" + position
316 + "']", null);
317
318 this.command = command;
319 this.position = position;
320 }
321
322 public final String getCommand() {
323 return command;
324 }
325
326 public final int getPosition() {
327 return position;
328 }
329 }
330
331 }