1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.xnap.plugin.gift.net.lexer;
21
22 import java.text.CharacterIterator;
23 import java.text.StringCharacterIterator;
24 import java.util.Enumeration;
25 import java.util.Hashtable;
26 import java.util.Vector;
27
28
29 /***
30 * Command Represents a GiFT-Command
31 *
32 * @author <a href="mailto:tvanlessen@taval.de">Tammo van Lessen</a>
33 * @version CVS $Id: Command.java,v 1.2 2003/10/06 10:17:37 squig Exp $
34 */
35 public class Command
36 {
37
38
39 private Hashtable keys;
40 private Hashtable modifiers;
41 private Vector subCommands;
42 private String cmdArgument;
43 private String cmdModifier;
44 private String command;
45
46
47
48 /***
49 * Creates a new <code>cmd</code>-Command object.
50 *
51 * @param cmd the command's name
52 */
53 public Command(String cmd)
54 {
55 modifiers = new Hashtable();
56 keys = new Hashtable();
57 subCommands = new Vector();
58 command = cmd;
59 cmdModifier = null;
60 cmdArgument = null;
61 }
62
63 /***
64 * Creates an empty Command object.
65 */
66 public Command()
67 {
68 this(null);
69 }
70
71
72
73 /***
74 * Method getAllSubCommandsByName.
75 */
76 public Vector getAllSubCommandsByName(String key)
77 {
78 Command cmd;
79 Vector cmdList = new Vector();
80 for (int i = 0; i < subCommands.size(); i++) {
81 cmd =(Command)subCommands.get(i);
82 if (cmd.getCommand().equalsIgnoreCase(key)) {
83 cmdList.add(cmd);
84 }
85 }
86 return cmdList;
87 }
88
89 /***
90 * returns the command
91 *
92 * @return the command's name
93 */
94 public String getCommand()
95 {
96 return command;
97 }
98
99 /***
100 * Sets the commands argument
101 *
102 * @param arg the argument
103 */
104 public void setCommandArgument(String arg)
105 {
106 cmdArgument = arg;
107 }
108
109 /***
110 * Returns the commands argument
111 *
112 * @return the argument
113 */
114 public String getCommandArgument()
115 {
116 return cmdArgument;
117 }
118
119 /***
120 * Sets the modifier for the command
121 *
122 * @param arg the modifier
123 */
124 public void setCommandModifier(String arg)
125 {
126 cmdModifier = arg;
127 }
128
129 /***
130 * Returns the commands modifier
131 *
132 * @return the modifier
133 */
134 public String getCommandModifier()
135 {
136 return cmdModifier;
137 }
138
139 /***
140 * Returns the argument corresponding to the given key
141 *
142 * @param key the key
143 *
144 * @return the key's argument
145 */
146 public String getKey(String key)
147 {
148 return (String) keys.get(key);
149 }
150
151 /***
152 * Sets the argument for the given key
153 *
154 * @param key the key
155 * @param arg the argument
156 */
157 public void setKeyArgument(String key, String arg)
158 {
159 keys.put(key, arg);
160 }
161
162 /***
163 * Sets the modifier for the specified key.
164 *
165 * @param key the key
166 * @param mod the modifier
167 */
168 public void setKeyModifier(String key, String mod)
169 {
170 modifiers.put(key, mod);
171 }
172
173 /***
174 * Returns the modifier for the given key.
175 *
176 * @param key the key
177 *
178 * @return the modifier
179 */
180 public String getKeyModifier(String key)
181 {
182 return (String) modifiers.get(key);
183 }
184
185 /***
186 * Returns all keys
187 *
188 * @return all keys
189 */
190 public Enumeration getKeys()
191 {
192 return keys.keys();
193 }
194
195 /***
196 * Returns the subcommand by its name
197 * If more subcommands with the same name exists, the first will be returned
198 *
199 * @param key the subcommands name
200 *
201 * @return the subcommand
202 */
203 public Command getSubCommandByName(String key)
204 {
205 Command cmd;
206 for (int i = 0; i < subCommands.size(); i++) {
207 cmd =(Command)subCommands.get(i);
208 if (cmd.getCommand().equalsIgnoreCase(key)) {
209 return cmd;
210 }
211 }
212 return null;
213 }
214
215 /***
216 * Returns all subcommands (its names)
217 *
218 * @return the subcommands
219 */
220 public Vector getSubCommands()
221 {
222 return subCommands;
223 }
224
225 /***
226 * Adds a key with its argument
227 *
228 * @param key the key
229 * @param arg the argument
230 */
231 public void addKey(String key, String arg)
232 {
233 keys.put(key, arg);
234 }
235
236 /***
237 * Adds a key without its argument
238 *
239 * @param key the key
240 */
241 public void addKey(String key)
242 {
243 keys.put(key, "empty");
244 }
245
246 /***
247 * Adds a subcommand
248 *
249 * @param command the subcommand
250 */
251 public void addSubCommand(Command command)
252 {
253 subCommands.add(command);
254 }
255
256 /***
257 * Returns if command has keys
258 *
259 * @return hasKeys
260 */
261 public boolean hasKeys()
262 {
263 return !((keys.size() == 0) ||
264 ((keys.size() == 1) && (keys.get("COMMAND") != null)));
265 }
266
267 /***
268 * Parses the command from a String (GiFT-UI-protocol)
269 *
270 * @param cmd the String
271 */
272 public boolean parse(String cmd)
273 {
274 return parseRecursive(this, new StringCharacterIterator(cmd));
275 }
276
277 /***
278 * Returns the command as String (GiFT-UI-protocol)
279 *
280 * @return the commandstr
281 */
282 public String print()
283 {
284 return print(true);
285 }
286
287 /***
288 * Debugdump
289 *
290 * @return String
291 */
292 public String toString()
293 {
294 String str = "GiFTCommand " + command + "\n";
295 Enumeration en = keys.keys();
296 String key;
297
298 while (en.hasMoreElements()) {
299 key = (String) en.nextElement();
300 str += (" + " + key + " = " + keys.get(key) + "\n");
301 }
302
303 for (int i = 0; i < subCommands.size(); i++) {
304 str += "--- sub ---\n";
305 str += subCommands.get(i);
306 str += "--- /sub ---\n";
307 }
308
309 return str;
310 }
311
312 private String escape(String s)
313 {
314 StringBuffer buffer = new StringBuffer(s.length());
315
316 for (int i = 0; i < s.length(); i++) {
317 char ch = s.charAt(i);
318
319 switch (ch) {
320 case '(':
321 buffer.append('//');
322 buffer.append(ch);
323
324 break;
325
326 case ')':
327 buffer.append('//');
328 buffer.append(ch);
329
330 break;
331
332 case '{':
333 buffer.append('//');
334 buffer.append(ch);
335
336 break;
337
338 case '}':
339 buffer.append('//');
340 buffer.append(ch);
341
342 break;
343
344 case '[':
345 buffer.append('//');
346 buffer.append(ch);
347
348 break;
349
350 case ']':
351 buffer.append('//');
352 buffer.append(ch);
353
354 break;
355
356 case ';':
357 buffer.append('//');
358 buffer.append(ch);
359
360 break;
361
362 case '//':
363 buffer.append('//');
364 buffer.append(ch);
365
366 break;
367
368 default:
369 buffer.append(ch);
370 }
371 }
372
373 return buffer.toString();
374 }
375
376 private boolean parseRecursive(Command cmd, StringCharacterIterator sci)
377 {
378 String currKey = null;
379 char curr;
380
381 while (sci.getIndex() < sci.getEndIndex()) {
382 switch (curr = sci.current()) {
383 case ' ':
384 case '\t':
385 case '\r':
386 case '\n':
387 sci.next();
388
389 continue;
390
391 case '(':
392
393 StringBuffer argBuf = new StringBuffer();
394
395 for (char ch = sci.next();
396 (ch != ')') && (ch != CharacterIterator.DONE);
397 ch = sci.next()) {
398 if (ch == '//') {
399 sci.next();
400 }
401
402 argBuf.append(ch);
403 }
404
405 if (currKey == null) {
406 cmd.setCommandArgument(argBuf.toString());
407 } else {
408 cmd.addKey(currKey, argBuf.toString());
409 currKey = null;
410 }
411
412 sci.next();
413
414 continue;
415
416 case '{':
417 sci.next();
418
419 Command subCommand = new Command(currKey);
420
421 if (this.parseRecursive(subCommand, sci) == false) {
422 return false;
423 }
424
425 sci.next();
426 cmd.addSubCommand(subCommand);
427
428 continue;
429
430 case '}':
431 case ';':
432 return true;
433
434 default:
435
436 StringBuffer buf = new StringBuffer();
437
438 for (char ch = sci.current(); ch != CharacterIterator.DONE;
439 ch = sci.next()) {
440 if (ch == ';') {
441 break;
442 }
443
444 if (ch == '(') {
445 break;
446 }
447
448 if (ch == '{') {
449 break;
450 }
451
452 if (Character.isWhitespace(ch)) {
453 break;
454 }
455
456 if (ch == '//') {
457 sci.next();
458 }
459
460 buf.append(ch);
461 }
462
463 if (cmd.command == null) {
464 cmd.command = buf.toString();
465 } else {
466 currKey = buf.toString();
467 }
468
469 continue;
470 }
471 }
472
473 return false;
474 }
475
476 private String print(boolean root)
477 {
478 String str = "\n";
479
480 if (root) {
481 str += escape(command.toUpperCase());
482 } else {
483 str += escape(command);
484 }
485
486 if (getCommandArgument() != null) {
487 str += ("(" + escape(getCommandArgument()) + ")");
488 }
489
490 if (!root && keys.isEmpty()) {
491 return str;
492 }
493
494 if (!root) {
495 str += "{\n";
496 }
497
498 Enumeration en = keys.keys();
499
500 while (en.hasMoreElements()) {
501 String key = (String) en.nextElement();
502 String keymod = (getKeyModifier(key) == null) ? ""
503 : (" [" +
504 getKeyModifier(key) + "] ");
505 str += (" " + escape(key) + escape(keymod) + "(" +
506 escape((String) keys.get(key)) + ")\n");
507 }
508
509 for (int i = 0; i < subCommands.size(); i++) {
510 str += ((Command) subCommands.get(i)).print(false);
511 }
512
513 str += (root ? ";\n" : "}");
514
515 return str;
516 }
517 }