0
|
1 package nabble.naml.namespaces;
|
|
2
|
|
3 import fschmidt.util.java.ArrayStack;
|
|
4 import fschmidt.util.java.ObjectUtils;
|
|
5 import fschmidt.util.java.Stack;
|
|
6 import fschmidt.util.mail.MailAddress;
|
|
7 import nabble.naml.compiler.Command;
|
|
8 import nabble.naml.compiler.CommandSpec;
|
|
9 import nabble.naml.compiler.CompileException;
|
|
10 import nabble.naml.compiler.Encoder;
|
|
11 import nabble.naml.compiler.ExitException;
|
|
12 import nabble.naml.compiler.IPrintWriter;
|
|
13 import nabble.naml.compiler.Interpreter;
|
|
14 import nabble.naml.compiler.JavaCommand;
|
|
15 import nabble.naml.compiler.Macro;
|
|
16 import nabble.naml.compiler.Namespace;
|
|
17 import nabble.naml.compiler.ScopedInterpreter;
|
|
18 import nabble.naml.compiler.StackTrace;
|
|
19 import nabble.naml.compiler.Template;
|
|
20 import nabble.naml.compiler.TemplateRuntimeException;
|
|
21 import nabble.naml.compiler.NamlNullPointerException;
|
|
22 import nabble.view.web.template.DateNamespace;
|
|
23 import org.slf4j.Logger;
|
|
24 import org.slf4j.LoggerFactory;
|
|
25
|
|
26 import java.util.ArrayList;
|
|
27 import java.util.Collection;
|
|
28 import java.util.Date;
|
|
29 import java.util.HashMap;
|
|
30 import java.util.List;
|
|
31 import java.util.Map;
|
|
32 import java.util.Random;
|
|
33 import java.util.regex.Matcher;
|
|
34 import java.util.regex.Pattern;
|
|
35
|
|
36
|
|
37 @Namespace (
|
|
38 name = "basic",
|
|
39 global = true
|
|
40 )
|
|
41 public final class BasicNamespace {
|
|
42 private static final Logger logger = LoggerFactory.getLogger(BasicNamespace.class);
|
|
43
|
|
44 private final Template template;
|
|
45
|
|
46 public BasicNamespace(Template template) {
|
|
47 this.template = template;
|
|
48 }
|
|
49
|
|
50 public static final CommandSpec exit = CommandSpec.NO_OUTPUT;
|
|
51
|
|
52 @CommandDoc(
|
|
53 "Exits the page generation and returns the control back to the browser."
|
|
54 )
|
|
55 @Command public void exit(IPrintWriter out,Interpreter interp) {
|
|
56 throw new ExitException();
|
|
57 }
|
|
58
|
|
59 public static final CommandSpec throw_runtime_exception = new CommandSpec.Builder()
|
|
60 .dotParameter("text")
|
|
61 .outputtedParameters()
|
|
62 .build()
|
|
63 ;
|
|
64
|
|
65 @CommandDoc(
|
|
66 value= "Throws a runtime exception to show that something is wrong or broken. "+
|
|
67 "If this command is called, the page will display the full stack trace of the error, which "+
|
|
68 "should be investigated and fixed.",
|
|
69 params = {"text=The message displayed by the exception"},
|
|
70 seeAlso = {"throw_template_exception"}
|
|
71 )
|
|
72 @Command public void throw_runtime_exception(IPrintWriter out,Interpreter interp) {
|
|
73 String text = interp.getArgString("text");
|
|
74 throw new RuntimeException(text);
|
|
75 }
|
|
76
|
|
77 public static final CommandSpec throw_template_exception = new CommandSpec.Builder()
|
|
78 .dotParameter("name")
|
|
79 .build()
|
|
80 ;
|
|
81
|
|
82 @CommandDoc(
|
|
83 value= "Throws an exception that can be caught by the @link{catch_exception} command.",
|
|
84 params = {"name=The name of the exception, which should be used later for catching and handling."},
|
|
85 seeAlso = {"ExceptionNamespace.exception"}
|
|
86 )
|
|
87 @Command public void throw_template_exception(IPrintWriter out,Interpreter interp)
|
|
88 throws TemplateException
|
|
89 {
|
|
90 String name = interp.getArgString("name");
|
|
91 throw TemplateException.newInstance(name);
|
|
92 }
|
|
93
|
|
94 @Command("true") public static void _true(IPrintWriter out,Interpreter interp) {
|
|
95 out.print(true);
|
|
96 }
|
|
97
|
|
98 @Command("false") public static void _false(IPrintWriter out,Interpreter interp) {
|
|
99 out.print(false);
|
|
100 }
|
|
101
|
|
102 public static final CommandSpec either = new CommandSpec.Builder()
|
|
103 .parameters("condition1","condition2")
|
|
104 .build()
|
|
105 ;
|
|
106
|
|
107 @Command public static void either(IPrintWriter out,Interpreter interp) {
|
|
108 out.print( interp.getArgAsBoolean("condition1") || interp.getArgAsBoolean("condition2") );
|
|
109 }
|
|
110
|
|
111 public static final CommandSpec both = new CommandSpec.Builder()
|
|
112 .parameters("condition1","condition2")
|
|
113 .build()
|
|
114 ;
|
|
115
|
|
116 @Command public static void both(IPrintWriter out,Interpreter interp) {
|
|
117 out.print( interp.getArgAsBoolean("condition1") && interp.getArgAsBoolean("condition2") );
|
|
118 }
|
|
119
|
|
120 public static final CommandSpec _if = new CommandSpec.Builder()
|
|
121 .dotParameter("condition")
|
|
122 .optionalParameters("then","else")
|
|
123 .outputtedParameters("then","else")
|
|
124 .dontRemoveNulls()
|
|
125 .build()
|
|
126 ;
|
|
127
|
|
128 @CommandDoc(
|
|
129 value= "Calls the \"then\" block if the 'condition' (dot_parameter) is true. " +
|
|
130 "Otherwise, calls the \"else\" block (if available).",
|
|
131 params = {
|
|
132 "condition=Condition to be tested",
|
|
133 "then=Block for the true case",
|
|
134 "else=Block for the false case"
|
|
135 }
|
|
136 )
|
|
137 @Command("if") public static void _if(IPrintWriter out,Interpreter interp) {
|
|
138 Object block = interp.getArg( interp.getArgAsBoolean("condition") ? "then" : "else" );
|
|
139 if( block != null )
|
|
140 out.print(block);
|
|
141 }
|
|
142
|
|
143 public static final CommandSpec not = new CommandSpec.Builder()
|
|
144 .dotParameter("condition")
|
|
145 .build()
|
|
146 ;
|
|
147
|
|
148 @Command public static void not(IPrintWriter out,Interpreter interp) {
|
|
149 out.print( !interp.getArgAsBoolean("condition") );
|
|
150 }
|
|
151
|
|
152 private static final CommandSpec optionalValue = new CommandSpec.Builder()
|
|
153 .dotParameter("value")
|
|
154 .optionalParameters("value")
|
|
155 .build()
|
|
156 ;
|
|
157
|
|
158 public static final CommandSpec hide_null = optionalValue;
|
|
159
|
|
160 @Command public static void hide_null(IPrintWriter out,Interpreter interp) {
|
|
161 String s = interp.getArgString("value");
|
|
162 if( s != null )
|
|
163 out.print(s);
|
|
164 }
|
|
165
|
|
166
|
|
167 public static final CommandSpec is_null = optionalValue;
|
|
168
|
|
169 @Command public static void is_null(IPrintWriter out,Interpreter interp) {
|
|
170 String s = interp.getArgString("value");
|
|
171 out.print( s==null );
|
|
172 }
|
|
173
|
|
174 @Command("null") public static void _null(IPrintWriter out,Interpreter interp) {
|
|
175 out.print((String)null);
|
|
176 }
|
|
177
|
|
178 public static final CommandSpec null_exception_to_null = optionalValue;
|
|
179
|
|
180 @Command public static void null_exception_to_null(IPrintWriter out,Interpreter interp) {
|
|
181 try {
|
|
182 out.print( interp.getArgString("value") );
|
|
183 } catch(NamlNullPointerException e) {
|
|
184 out.print( (String)null );
|
|
185 }
|
|
186 }
|
|
187
|
|
188 private static final Random RANDOM = new Random();
|
|
189
|
|
190 public static final CommandSpec random = new CommandSpec.Builder()
|
|
191 .parameters("max")
|
|
192 .build()
|
|
193 ;
|
|
194
|
|
195 @Command public void random(IPrintWriter out,Interpreter interp) {
|
|
196 int max = interp.getArgAsInt("max");
|
|
197 int r = RANDOM.nextInt(max);
|
|
198 out.print(r);
|
|
199 }
|
|
200
|
|
201 public static final CommandSpec equal = new CommandSpec.Builder()
|
|
202 .optionalParameters("value1","value2")
|
|
203 .build()
|
|
204 ;
|
|
205
|
|
206 @Command public static void equal(IPrintWriter out,Interpreter interp) {
|
|
207 out.print( ObjectUtils.equals(interp.getArgString("value1"),interp.getArgString("value2")) );
|
|
208 }
|
|
209
|
|
210 public static final CommandSpec starts_with = new CommandSpec.Builder()
|
|
211 .dotParameter("text")
|
|
212 .parameters("prefix")
|
|
213 .build()
|
|
214 ;
|
|
215
|
|
216 @Command public void starts_with(IPrintWriter out,Interpreter interp) {
|
|
217 String text = interp.getArgString("text");
|
|
218 String prefix = interp.getArgString("prefix");
|
|
219 out.print( text.startsWith(prefix) );
|
|
220 }
|
|
221
|
|
222 public static final CommandSpec ends_with = new CommandSpec.Builder()
|
|
223 .dotParameter("text")
|
|
224 .parameters("suffix")
|
|
225 .build()
|
|
226 ;
|
|
227
|
|
228 @Command public void ends_with(IPrintWriter out,Interpreter interp) {
|
|
229 String text = interp.getArgString("text");
|
|
230 String suffix = interp.getArgString("suffix");
|
|
231 out.print( text.endsWith(suffix) );
|
|
232 }
|
|
233
|
|
234 public static final CommandSpec substring = new CommandSpec.Builder()
|
|
235 .dotParameter("text")
|
|
236 .parameters("begin")
|
|
237 .optionalParameters("end")
|
|
238 .build()
|
|
239 ;
|
|
240
|
|
241 @Command public void substring(IPrintWriter out,Interpreter interp) {
|
|
242 String text = interp.getArgString("text");
|
|
243 int begin = Integer.parseInt(interp.getArgString("begin"));
|
|
244 String end = interp.getArgString("end");
|
|
245 out.print( end==null ? text.substring(begin) : text.substring(begin,Integer.parseInt(end)) );
|
|
246 }
|
|
247
|
|
248 public static final CommandSpec contains_substring = new CommandSpec.Builder()
|
|
249 .dotParameter("string")
|
|
250 .parameters("substring")
|
|
251 .build()
|
|
252 ;
|
|
253
|
|
254 @Command public void contains_substring(IPrintWriter out,Interpreter interp) {
|
|
255 out.print( interp.getArgString("string").indexOf(interp.getArgString("substring")) != -1 );
|
|
256 }
|
|
257
|
|
258 public static final CommandSpec regex_quote = new CommandSpec.Builder()
|
|
259 .dotParameter("string")
|
|
260 .build()
|
|
261 ;
|
|
262
|
|
263 @Command public void regex_quote(IPrintWriter out,Interpreter interp) {
|
|
264 out.print( Pattern.quote(interp.getArgString("string")) );
|
|
265 }
|
|
266
|
|
267 public static final CommandSpec append = new CommandSpec.Builder()
|
|
268 .dotParameter("text")
|
|
269 .parameters("suffix")
|
|
270 .optionalParameters("text","except_if")
|
|
271 .restrictedParameter("except_if","already-included")
|
|
272 .build()
|
|
273 ;
|
|
274
|
|
275 @Command public void append(IPrintWriter out,Interpreter interp) {
|
|
276 String text = interp.getArgString("text");
|
|
277 out.print(text);
|
|
278 if( text!=null && text.length() > 0 ) {
|
|
279 String suffix = interp.getArgString("suffix");
|
|
280 if( !( "already-included".equals(interp.getArgString("except_if"))
|
|
281 && text.toLowerCase().indexOf(suffix.toLowerCase()) != -1
|
|
282 ) )
|
|
283 out.print(suffix);
|
|
284 }
|
|
285 }
|
|
286
|
|
287 public static final CommandSpec prepend = new CommandSpec.Builder()
|
|
288 .dotParameter("text")
|
|
289 .parameters("prefix")
|
|
290 .optionalParameters("text","except_if")
|
|
291 .restrictedParameter("except_if","already-included")
|
|
292 .build()
|
|
293 ;
|
|
294
|
|
295 @Command public void prepend(IPrintWriter out,Interpreter interp) {
|
|
296 String text = interp.getArgString("text");
|
|
297 if( text!=null && text.length() > 0 ) {
|
|
298 String prefix = interp.getArgString("prefix");
|
|
299 if( !( "already-included".equals(interp.getArgString("except_if"))
|
|
300 && text.toLowerCase().indexOf(prefix.toLowerCase()) != -1
|
|
301 ) )
|
|
302 out.print(prefix);
|
|
303 }
|
|
304 out.print(text);
|
|
305 }
|
|
306
|
|
307 public static final CommandSpec separate = new CommandSpec.Builder()
|
|
308 .parameters("text1","separator","text2")
|
|
309 .build()
|
|
310 ;
|
|
311
|
|
312 @Command public void separate(IPrintWriter out,Interpreter interp) {
|
|
313 String text1 = interp.getArgString("text1");
|
|
314 if( text1 == null )
|
|
315 throw new NullPointerException("text1 is null");
|
|
316 String text2 = interp.getArgString("text2");
|
|
317 if( text2 == null )
|
|
318 throw new NullPointerException("text2 is null");
|
|
319 out.print( text1 );
|
|
320 if( text1.trim().length() > 0 && text2.trim().length() > 0 )
|
|
321 out.print( interp.getArg("separator") );
|
|
322 out.print( text2 );
|
|
323 }
|
|
324
|
|
325 /*
|
|
326 public static final CommandSpec is_in_namespace = new CommandSpec.Builder()
|
|
327 .parameters("name")
|
|
328 .build()
|
|
329 ;
|
|
330
|
|
331 @Command public static void is_in_namespace(IPrintWriter out,Interpreter interp) {
|
|
332 out.print( interp.hasNamespace(interp.getArgString("name")) );
|
|
333 }
|
|
334 */
|
|
335
|
|
336 public static final CommandSpec is_in_command = new CommandSpec.Builder()
|
|
337 .parameters("name")
|
|
338 .build()
|
|
339 ;
|
|
340
|
|
341 @Command public static void is_in_command(IPrintWriter out,Interpreter interp) {
|
|
342 out.print( interp.isInCommandStack(interp.getArgString("name")) );
|
|
343 }
|
|
344
|
|
345
|
|
346 public static final CommandSpec to_lower_case = CommandSpec.TEXT;
|
|
347
|
|
348 @Command public void to_lower_case(IPrintWriter out,Interpreter interp) {
|
|
349 out.print( interp.getArgString("text").toLowerCase() );
|
|
350 }
|
|
351
|
|
352 public static final CommandSpec to_upper_case = CommandSpec.TEXT;
|
|
353
|
|
354 @Command public void to_upper_case(IPrintWriter out,Interpreter interp) {
|
|
355 out.print( interp.getArgString("text").toUpperCase() );
|
|
356 }
|
|
357
|
|
358 public static final CommandSpec capitalize = CommandSpec.TEXT;
|
|
359
|
|
360 @Command public void capitalize(IPrintWriter out,Interpreter interp) {
|
|
361 String text = interp.getArgString("text");
|
|
362 String[] words = text.split("[ ]");
|
|
363 StringBuilder b = new StringBuilder();
|
|
364 for (String w : words) {
|
|
365 if (b.length() > 0)
|
|
366 b.append(' ');
|
|
367 b.append(w.substring(0,1).toUpperCase());
|
|
368 b.append(w.substring(1,w.length()));
|
|
369 }
|
|
370 out.print(b.toString());
|
|
371 }
|
|
372
|
|
373 public static final CommandSpec regex = new CommandSpec.Builder()
|
|
374 .parameters("pattern","text")
|
|
375 .scopedParameters("do")
|
|
376 .dotParameter("do")
|
|
377 .build()
|
|
378 ;
|
|
379
|
|
380 @Command public static void regex(IPrintWriter out,ScopedInterpreter<RegexNamespace> interp) {
|
|
381 Pattern p = Pattern.compile( interp.getArgString("pattern") );
|
|
382 String s = interp.getArgString("text");
|
|
383 Matcher m = p.matcher(s);
|
|
384 RegexNamespace ns = new RegexNamespace(m,s);
|
|
385 out.print( interp.getArg(ns,"do") );
|
|
386 }
|
|
387
|
|
388 public static final CommandSpec regex_replace_all = new CommandSpec.Builder()
|
|
389 .dotParameter("text")
|
|
390 .parameters("pattern","replacement")
|
|
391 .build()
|
|
392 ;
|
|
393
|
|
394 @Command public static void regex_replace_all(IPrintWriter out,Interpreter interp) {
|
|
395 String text = interp.getArgString("text");
|
|
396 String pattern = interp.getArgString("pattern");
|
|
397 String replacement = interp.getArgString("replacement");
|
|
398 out.print( text.replaceAll(pattern, replacement) );
|
|
399 }
|
|
400
|
|
401 public static final CommandSpec regex_replace_first = new CommandSpec.Builder()
|
|
402 .dotParameter("text")
|
|
403 .parameters("pattern","replacement")
|
|
404 .build()
|
|
405 ;
|
|
406
|
|
407 @Command public static void regex_replace_first(IPrintWriter out,Interpreter interp) {
|
|
408 String text = interp.getArgString("text");
|
|
409 String pattern = interp.getArgString("pattern");
|
|
410 String replacement = interp.getArgString("replacement");
|
|
411 out.print( text.replaceFirst(pattern, replacement) );
|
|
412 }
|
|
413
|
|
414 public static final CommandSpec string_replace_all = new CommandSpec.Builder()
|
|
415 .dotParameter("text")
|
|
416 .parameters("target","replacement")
|
|
417 .build()
|
|
418 ;
|
|
419
|
|
420 @Command public static void string_replace_all(IPrintWriter out,Interpreter interp) {
|
|
421 out.print( interp.getArgString("text").replace(interp.getArgString("target"),interp.getArgString("replacement")) );
|
|
422 }
|
|
423
|
|
424 public static final CommandSpec trim = CommandSpec.TEXT;
|
|
425
|
|
426 @Command public static void trim(IPrintWriter out,Interpreter interp) {
|
|
427 String s = interp.getArgString("text");
|
|
428 out.print( s==null ? null : s.trim() );
|
|
429 }
|
|
430
|
|
431 public static final CommandSpec encode = CommandSpec.OPTIONAL_TEXT;
|
|
432
|
|
433 @Command public static void encode(IPrintWriter out,Interpreter interp) {
|
|
434 String s = interp.getArgString("text");
|
|
435 out.print( interp.encode(s) );
|
|
436 }
|
|
437
|
|
438 public static final CommandSpec use_text_encoder = CommandSpec.OPTIONAL_TEXT;
|
|
439
|
|
440 @Command public void use_text_encoder(IPrintWriter out,Interpreter interp) {
|
|
441 interp.setEncoder(Encoder.TEXT);
|
|
442 String s = interp.getArgString("text");
|
|
443 out.print(s);
|
|
444 }
|
|
445
|
|
446 public static final CommandSpec use_html_encoder = CommandSpec.OPTIONAL_TEXT;
|
|
447
|
|
448 @Command public void use_html_encoder(IPrintWriter out,Interpreter interp) {
|
|
449 interp.setEncoder(Encoder.HTML);
|
|
450 String s = interp.getArgString("text");
|
|
451 out.print(s);
|
|
452 }
|
|
453
|
|
454 public static final CommandSpec use_url_encoder = CommandSpec.OPTIONAL_TEXT;
|
|
455
|
|
456 @Command public void use_url_encoder(IPrintWriter out,Interpreter interp) {
|
|
457 interp.setEncoder(Encoder.URL);
|
|
458 String s = interp.getArgString("text");
|
|
459 out.print(s);
|
|
460 }
|
|
461
|
|
462 public static final CommandSpec is_empty = optionalValue;
|
|
463
|
|
464 @Command public static void is_empty(IPrintWriter out,Interpreter interp) {
|
|
465 String s = interp.getArgString("value");
|
|
466 out.print( s==null || s.length() == 0 );
|
|
467 }
|
|
468
|
|
469
|
|
470 public static final CommandSpec var = new CommandSpec.Builder()
|
|
471 .parameters("name")
|
|
472 .build()
|
|
473 ;
|
|
474
|
|
475 @Command public void var(IPrintWriter out,Interpreter interp) {
|
|
476 throw new RuntimeException("never");
|
|
477 }
|
|
478
|
|
479 public static final CommandSpec set_var = new CommandSpec.Builder()
|
|
480 .parameters("name")
|
|
481 .dotParameter("value")
|
|
482 .optionalParameters("value")
|
|
483 .outputtedParameters()
|
|
484 .build()
|
|
485 ;
|
|
486
|
|
487 @Command public void set_var(IPrintWriter out,Interpreter interp) {
|
|
488 throw new RuntimeException("never");
|
|
489 }
|
|
490
|
|
491 public static final CommandSpec uplevel_var = var;
|
|
492
|
|
493 @Command public void uplevel_var(IPrintWriter out,Interpreter interp) {
|
|
494 throw new RuntimeException("never");
|
|
495 }
|
|
496
|
|
497 public static final CommandSpec uplevel_set_var = set_var;
|
|
498
|
|
499 @Command public void uplevel_set_var(IPrintWriter out,Interpreter interp) {
|
|
500 throw new RuntimeException("never");
|
|
501 }
|
|
502
|
|
503 private final Map<String,String> globalVars = new HashMap<String,String>();
|
|
504
|
|
505 public static final CommandSpec global_var = var;
|
|
506
|
|
507 @Command public void global_var(IPrintWriter out,Interpreter interp) {
|
|
508 String name = interp.getArgString("name");
|
|
509 out.print( globalVars.get(name) );
|
|
510 }
|
|
511
|
|
512 public static final CommandSpec global_set_var = set_var;
|
|
513
|
|
514 @Command public void global_set_var(IPrintWriter out,Interpreter interp) {
|
|
515 String name = interp.getArgString("name");
|
|
516 String value = interp.getArgString("value");
|
|
517 globalVars.put(name,value);
|
|
518 }
|
|
519
|
|
520 public static final CommandSpec global_is_var_set = var;
|
|
521
|
|
522 @Command public void global_is_var_set(IPrintWriter out,Interpreter interp) {
|
|
523 String name = interp.getArgString("name");
|
|
524 out.print( globalVars.containsKey(name) );
|
|
525 }
|
|
526
|
|
527
|
|
528 public static final CommandSpec _default = new CommandSpec.Builder()
|
|
529 .dotParameter("text")
|
|
530 .optionalParameters("text")
|
|
531 .parameters("to")
|
|
532 .build()
|
|
533 ;
|
|
534
|
|
535 @Command("default") public static void _default(IPrintWriter out,Interpreter interp) {
|
|
536 String text = interp.getArgString("text");
|
|
537 out.print( text!=null ? text : interp.getArgString("to") );
|
|
538 }
|
|
539
|
|
540 private static final int whileLimit = 1000000;
|
|
541
|
|
542 private static class BreakException extends TemplateRuntimeException {
|
|
543 BreakException() {
|
|
544 super("break called outside of while");
|
|
545 }
|
|
546 }
|
|
547
|
|
548 public static final CommandSpec _while = new CommandSpec.Builder()
|
|
549 .dotParameter("condition")
|
|
550 .parameters("loop")
|
|
551 .outputtedParameters("loop")
|
|
552 .build()
|
|
553 ;
|
|
554
|
|
555 @Command("while") public void _while(IPrintWriter out,Interpreter interp) {
|
|
556 Object condition = interp.getArg("condition");
|
|
557 Object block = interp.getArg("loop");
|
|
558 int count = 0;
|
|
559 try {
|
|
560 while( Template.booleanValue(condition) ) {
|
|
561 if( ++count > whileLimit )
|
|
562 throw new RuntimeException("while loop limit of "+whileLimit+" iterations exceeded");
|
|
563 out.print(block);
|
|
564 }
|
|
565 } catch(BreakException e) {}
|
|
566 }
|
|
567
|
|
568 @Command("break") public void _break(IPrintWriter out,Interpreter interp) {
|
|
569 throw new BreakException();
|
|
570 }
|
|
571
|
|
572
|
|
573 @Command public void nop(IPrintWriter out,Interpreter interp) {}
|
|
574
|
|
575
|
|
576 private static final class ExceptionInfo {
|
|
577 private final String forStr;
|
|
578 private final TemplateException ex;
|
|
579
|
|
580 private ExceptionInfo(String forStr,TemplateException ex) {
|
|
581 this.forStr = forStr;
|
|
582 this.ex = ex;
|
|
583 }
|
|
584 }
|
|
585
|
|
586 private Stack<ExceptionInfo> exceptionStack = new ArrayStack<ExceptionInfo>();
|
|
587
|
|
588 public static final CommandSpec catch_exception = new CommandSpec.Builder()
|
|
589 .parameters("id")
|
|
590 .dotParameter("do")
|
|
591 .outputtedParameters("do")
|
|
592 .build()
|
|
593 ;
|
|
594
|
|
595 @Command public void catch_exception(IPrintWriter out,Interpreter interp) {
|
|
596 String idStr = interp.getArgString("id");
|
|
597 TemplateException ex = null;
|
|
598 try {
|
|
599 out.print( interp.getArg("do") );
|
|
600 } catch(TemplateRuntimeException e) {
|
|
601 Throwable cause = e.getCause();
|
|
602 if( cause instanceof TemplateException ) {
|
|
603 ex = (TemplateException)cause;
|
|
604 } else {
|
|
605 throw e;
|
|
606 }
|
|
607 }
|
|
608 exceptionStack.push( new ExceptionInfo(idStr,ex) );
|
|
609 }
|
|
610
|
|
611 @Namespace (
|
|
612 name = "error",
|
|
613 global = false
|
|
614 )
|
|
615 public static class ExceptionNamespace {
|
|
616 protected final TemplateException ex;
|
|
617 protected boolean isDone = false;
|
|
618
|
|
619 public ExceptionNamespace(TemplateException ex) {
|
|
620 this.ex = ex;
|
|
621 }
|
|
622
|
|
623 public static final CommandSpec exception = new CommandSpec.Builder()
|
|
624 .parameters("name")
|
|
625 .dotParameter("do")
|
|
626 .build()
|
|
627 ;
|
|
628
|
|
629 @Command public void exception(IPrintWriter out,Interpreter interp) {
|
|
630 if( isDone )
|
|
631 return;
|
|
632 String name = interp.getArgString("name");
|
|
633 if( ex.isNamed(name) ) {
|
|
634 out.print( interp.getArg("do") );
|
|
635 isDone = true;
|
|
636 }
|
|
637 }
|
|
638
|
|
639 public static final CommandSpec unknown_exception = CommandSpec.DO;
|
|
640
|
|
641 @Command public void unknown_exception(IPrintWriter out,ScopedInterpreter<UnknownException> interp) {
|
|
642 if( isDone )
|
|
643 return;
|
|
644 out.print( interp.getArg(new UnknownException(ex), "do") );
|
|
645 isDone = true;
|
|
646 }
|
|
647
|
|
648 protected static final CommandSpec scopedCommandSpec = new CommandSpec.Builder()
|
|
649 .parameters("name")
|
|
650 .dotParameter("do")
|
|
651 .scopedParameters("do")
|
|
652 .build()
|
|
653 ;
|
|
654
|
|
655 protected final <N> void scopedException(IPrintWriter out,ScopedInterpreter<N> interp,N ns) {
|
|
656 if( isDone )
|
|
657 return;
|
|
658 String name = interp.getArgString("name");
|
|
659 if( ex.isNamed(name) ) {
|
|
660 out.print(interp.getArg(ns,"do"));
|
|
661 isDone = true;
|
|
662 }
|
|
663 }
|
|
664
|
|
665 protected final <N> void unnamedScopedException(IPrintWriter out,ScopedInterpreter<N> interp,N ns) {
|
|
666 if( isDone )
|
|
667 return;
|
|
668 out.print(interp.getArg(ns,"do"));
|
|
669 isDone = true;
|
|
670 }
|
|
671
|
|
672 }
|
|
673
|
|
674 @Namespace (
|
|
675 name = "unknown_exception",
|
|
676 global = false
|
|
677 )
|
|
678 public static class UnknownException extends ExceptionNamespace {
|
|
679
|
|
680 public UnknownException(TemplateException ex) {
|
|
681 super(ex);
|
|
682 }
|
|
683
|
|
684 @Command public void message(IPrintWriter out,Interpreter interp) {
|
|
685 out.print(ex.getMessage());
|
|
686 }
|
|
687 }
|
|
688
|
|
689 public static interface ExceptionNamespaceFactory<E extends ExceptionNamespace> {
|
|
690 public E newExceptionNamespace(TemplateException ex);
|
|
691 }
|
|
692
|
|
693 /* private static final ExceptionNamespaceFactory<ExceptionNamespace> myExceptionNamespaceFactory =
|
|
694 new ExceptionNamespaceFactory<ExceptionNamespace>() {
|
|
695 public ExceptionNamespace newExceptionNamespace(TemplateException ex) {
|
|
696 return new ExceptionNamespace(ex);
|
|
697 }
|
|
698 }
|
|
699 ;*/
|
|
700
|
|
701 public static final CommandSpec handle_exception = CommandSpec.DO()
|
|
702 .parameters("for")
|
|
703 .requiredInStack(BasicNamespace.class)
|
|
704 .build()
|
|
705 ;
|
|
706 /*
|
|
707 @Command public void handle_exception(IPrintWriter out,ScopedInterpreter<ExceptionNamespace> interp) {
|
|
708 handleException(out,interp,myExceptionNamespaceFactory);
|
|
709 }
|
|
710 */
|
|
711 public <E extends ExceptionNamespace> void handleException(IPrintWriter out,ScopedInterpreter<E> interp,ExceptionNamespaceFactory<E> factory) {
|
|
712 if( exceptionStack.isEmpty() )
|
|
713 throw new RuntimeException("there are no exceptions available to be handled");
|
|
714 ExceptionInfo ei = exceptionStack.pop();
|
|
715 String forStr = interp.getArgString("for");
|
|
716 if( !forStr.equals(ei.forStr) )
|
|
717 throw new RuntimeException("found exception for: "+ei.forStr);
|
|
718 if( ei.ex == null )
|
|
719 return;
|
|
720 E en = factory.newExceptionNamespace(ei.ex);
|
|
721 out.print( interp.getArg(en,"do") );
|
|
722 if( !en.isDone ) {
|
|
723 logger.error("unexpected exception"+StackTrace.current(),en.ex);
|
|
724 out.print( "Unexpected exception: " + en.ex );
|
|
725 }
|
|
726 }
|
|
727
|
|
728 public static final CommandSpec has_exception = new CommandSpec.Builder()
|
|
729 .parameters("for")
|
|
730 .build()
|
|
731 ;
|
|
732
|
|
733 @Command public void has_exception(IPrintWriter out,Interpreter interp) {
|
|
734 if( exceptionStack.isEmpty() )
|
|
735 throw new RuntimeException("there are no exceptions available to be handled");
|
|
736 ExceptionInfo ei = exceptionStack.peek();
|
|
737 String forStr = interp.getArgString("for");
|
|
738 if( !forStr.equals(ei.forStr) )
|
|
739 throw new RuntimeException("found exception for: "+ei.forStr);
|
|
740 out.print( ei.ex != null );
|
|
741 }
|
|
742
|
|
743 public static final CommandSpec string_list = CommandSpec.DO()
|
|
744 .optionalParameters("values","separator","trim")
|
|
745 .build()
|
|
746 ;
|
|
747
|
|
748 @Command public void string_list(IPrintWriter out,ScopedInterpreter<StringList> interp) {
|
|
749 List<String> list = new ArrayList<String>();
|
|
750 String csv = interp.getArgString("values");
|
|
751 if( csv != null ) {
|
|
752 String separator = interp.getArgString("separator");
|
|
753 if( separator == null )
|
|
754 separator = ",";
|
|
755 boolean trim = interp.getArgAsBoolean("trim", true);
|
|
756 for( String s : csv.split(separator) ) {
|
|
757 list.add( trim? s.trim() : s );
|
|
758 }
|
|
759 }
|
|
760 Object block = interp.getArg(new StringList(list),"do");
|
|
761 out.print(block);
|
|
762 }
|
|
763
|
|
764 public static final CommandSpec string_map = new CommandSpec.Builder()
|
|
765 .parameters("key")
|
|
766 .dotParameter("entries")
|
|
767 .build()
|
|
768 ;
|
|
769
|
|
770 @Command public void string_map(IPrintWriter out, Interpreter interp) {
|
|
771 String key = interp.getArgString("key");
|
|
772 String[] entries = interp.getArgString("entries").split("\n");
|
|
773 for (String entry : entries) {
|
|
774 String[] keyValue = entry.split(":");
|
|
775 if (key.equals(keyValue[0].trim())) {
|
|
776 out.print(keyValue[1].trim());
|
|
777 return;
|
|
778 }
|
|
779 }
|
|
780 out.print((String) null);
|
|
781 }
|
|
782
|
|
783 public static final CommandSpec _int = CommandSpec.DO()
|
|
784 .parameters("i")
|
|
785 .build()
|
|
786 ;
|
|
787
|
|
788 @Command("int") public void _int(IPrintWriter out,ScopedInterpreter<IntegerNamespace> interp) {
|
|
789 out.print( interp.getArg(new IntegerNamespace(interp.getArgAsInt("i")),"do") );
|
|
790 }
|
|
791
|
|
792 public static final CommandSpec extract_email_address_from = new CommandSpec.Builder()
|
|
793 .dotParameter("text")
|
|
794 .build()
|
|
795 ;
|
|
796
|
|
797 @Command public static void extract_email_address_from(IPrintWriter out,Interpreter interp) {
|
|
798 String text = interp.getArgString("text").trim();
|
|
799 String email = null;
|
|
800 if (new MailAddress(text).isValid()) {
|
|
801 email = text;
|
|
802 } else {
|
|
803 int posOpen = text.lastIndexOf('<');
|
|
804 int posClose = text.lastIndexOf('>');
|
|
805 if (posOpen >= 0 && posClose > posOpen) {
|
|
806 String middle = text.substring(posOpen+1, posClose);
|
|
807 if (new MailAddress(middle).isValid())
|
|
808 email = middle;
|
|
809 }
|
|
810 }
|
|
811 out.print(email);
|
|
812 }
|
|
813
|
|
814 @Command public void crlf(IPrintWriter out,Interpreter interp) {
|
|
815 out.print("\r\n");
|
|
816 }
|
|
817
|
|
818 @Command public void space(IPrintWriter out,Interpreter interp) {
|
|
819 out.print(' ');
|
|
820 }
|
|
821
|
|
822 @Command public void double_quote(IPrintWriter out,Interpreter interp) {
|
|
823 out.print("\"");
|
|
824 }
|
|
825
|
|
826 public static final CommandSpec has_module = new CommandSpec.Builder()
|
|
827 .dotParameter("module")
|
|
828 .build()
|
|
829 ;
|
|
830
|
|
831 @Command public static void has_module(IPrintWriter out,Interpreter interp) {
|
|
832 out.print( interp.hasModule(interp.getArgString("module")) );
|
|
833 }
|
|
834
|
|
835 public static final CommandSpec no_output = CommandSpec.NO_OUTPUT()
|
|
836 .dotParameter("text")
|
|
837 .build()
|
|
838 ;
|
|
839
|
|
840 @Command public static void no_output(IPrintWriter out,Interpreter interp) {
|
|
841 interp.getArgString("text");
|
|
842 }
|
|
843
|
|
844
|
|
845 @Command public static void lt(IPrintWriter out,Interpreter interp) {
|
|
846 out.print('<');
|
|
847 }
|
|
848
|
|
849 @Command public static void gt(IPrintWriter out,Interpreter interp) {
|
|
850 out.print('>');
|
|
851 }
|
|
852
|
|
853 public static final CommandSpec now = CommandSpec.DO;
|
|
854
|
|
855 @Command public void now(IPrintWriter out,ScopedInterpreter<DateNamespace> interp) {
|
|
856 out.print( interp.getArg(new DateNamespace(new Date()), "do" ));
|
|
857 }
|
|
858
|
|
859 public static final CommandSpec call_depth = CommandSpec.DO;
|
|
860
|
|
861 @Command public void call_depth(IPrintWriter out,ScopedInterpreter<IntegerNamespace> interp) {
|
|
862 out.print( interp.getArg(new IntegerNamespace(interp.callDepth()),"do") );
|
|
863 }
|
|
864
|
|
865
|
|
866 public static final CommandSpec _switch = CommandSpec.DO()
|
|
867 .optionalParameters("value")
|
|
868 .build()
|
|
869 ;
|
|
870
|
|
871 @Command("switch") public void _switch(IPrintWriter out,ScopedInterpreter<SwitchNamespace> interp) {
|
|
872 out.print( interp.getArg(new SwitchNamespace(interp.getArgString("value")),"do") );
|
|
873 }
|
|
874
|
|
875 @Namespace (
|
|
876 name = "switch",
|
|
877 global = false,
|
|
878 transparent = true
|
|
879 )
|
|
880 public static final class SwitchNamespace {
|
|
881 private final String value;
|
|
882 private boolean isDone = false;
|
|
883
|
|
884 private SwitchNamespace(String value) {
|
|
885 this.value = value;
|
|
886 }
|
|
887
|
|
888 @Command public void switch_value(IPrintWriter out,Interpreter interp) {
|
|
889 out.print( value );
|
|
890 }
|
|
891
|
|
892 public static final CommandSpec _case = new CommandSpec.Builder()
|
|
893 .parameters("value")
|
|
894 .dotParameter("do")
|
|
895 .outputtedParameters() // to trim surrounding white-space
|
|
896 .build()
|
|
897 ;
|
|
898
|
|
899 @Command("case") public void _case(IPrintWriter out,Interpreter interp) {
|
|
900 if( !isDone && interp.getArgString("value").equals(value) ) {
|
|
901 out.print( interp.getArg("do") );
|
|
902 isDone = true;
|
|
903 }
|
|
904 }
|
|
905
|
|
906 public static final CommandSpec default_case = new CommandSpec.Builder()
|
|
907 .dotParameter("do")
|
|
908 .outputtedParameters("do")
|
|
909 .build()
|
|
910 ;
|
|
911
|
|
912 @Command public void default_case(IPrintWriter out,Interpreter interp) {
|
|
913 if( !isDone ) {
|
|
914 out.print( interp.getArg("do") );
|
|
915 isDone = true;
|
|
916 }
|
|
917 }
|
|
918
|
|
919 public static final CommandSpec regex_case = new CommandSpec.Builder()
|
|
920 .parameters("regex")
|
|
921 .scopedParameters("do")
|
|
922 .dotParameter("do")
|
|
923 .outputtedParameters("do")
|
|
924 .build()
|
|
925 ;
|
|
926
|
|
927 @Command public void regex_case(IPrintWriter out,ScopedInterpreter<RegexNamespace> interp) {
|
|
928 if( !isDone ) {
|
|
929 Matcher m = Pattern.compile(interp.getArgString("regex")).matcher(value);
|
|
930 if( m.matches() ) {
|
|
931 out.print( interp.getArg(new RegexNamespace(m,value),"do") );
|
|
932 isDone = true;
|
|
933 }
|
|
934 }
|
|
935 }
|
|
936
|
|
937 }
|
|
938
|
|
939
|
|
940
|
|
941 @Namespace (
|
|
942 name = "block",
|
|
943 global = false
|
|
944 )
|
|
945 public static final class BlockNamespace {}
|
|
946
|
|
947 private static final BlockNamespace BLOCK = new BlockNamespace();
|
|
948
|
|
949 public static final CommandSpec block = CommandSpec.DO;
|
|
950
|
|
951 @Command public void block(IPrintWriter out,ScopedInterpreter<BlockNamespace> interp) {
|
|
952 out.print( interp.getArg(BLOCK,"do") );
|
|
953 }
|
|
954
|
|
955
|
|
956
|
|
957 @Namespace (
|
|
958 name = "counter",
|
|
959 global = false
|
|
960 )
|
|
961 public static final class CounterNamespace {
|
|
962 private int counter = 0;
|
|
963
|
|
964 public static final CommandSpec increment = CommandSpec.NO_OUTPUT;
|
|
965
|
|
966 @Command public void increment(IPrintWriter out,Interpreter interp) {
|
|
967 counter++;
|
|
968 }
|
|
969
|
|
970 @Command public void value(IPrintWriter out,Interpreter interp) {
|
|
971 out.print(counter);
|
|
972 }
|
|
973
|
|
974 }
|
|
975
|
|
976 private Map<String,CounterNamespace> counterMap = null;
|
|
977
|
|
978 public static final CommandSpec counter = CommandSpec.DO()
|
|
979 .parameters("name")
|
|
980 .build()
|
|
981 ;
|
|
982
|
|
983 @Command public void counter(IPrintWriter out,ScopedInterpreter<CounterNamespace> interp) {
|
|
984 if( counterMap == null )
|
|
985 counterMap = new HashMap<String,CounterNamespace>();
|
|
986 String name = interp.getArgString("name");
|
|
987 if( name==null )
|
|
988 throw new NullPointerException("name is required");
|
|
989 CounterNamespace ns = counterMap.get(name);
|
|
990 if( ns == null ) {
|
|
991 ns = new CounterNamespace();
|
|
992 counterMap.put(name,ns);
|
|
993 }
|
|
994 out.print( interp.getArg(ns,"do") );
|
|
995 }
|
|
996
|
|
997
|
|
998 public static final CommandSpec compile_template = CommandSpec.NO_OUTPUT()
|
|
999 .parameters("macro","namespaces")
|
|
1000 .build()
|
|
1001 ;
|
|
1002
|
|
1003 @Command public void compile_template(IPrintWriter out,Interpreter interp)
|
|
1004 throws ClassNotFoundException, CompileException
|
|
1005 {
|
|
1006 String macroName = interp.getArgString("macro");
|
|
1007 String namespacesStr = interp.getArgString("namespaces").trim();
|
|
1008 String[] namespaces = namespacesStr.length()==0 ? new String[0] : namespacesStr.split("\\s*,\\s*");
|
|
1009 if( interp.template().program().getTemplate( macroName, namespaces ) == null )
|
|
1010 throw new RuntimeException("macro '"+macroName+"' not found");
|
|
1011 }
|
|
1012
|
|
1013
|
|
1014
|
|
1015
|
|
1016 private static final CommandSpec ID = new CommandSpec.Builder()
|
|
1017 .parameters("id")
|
|
1018 .build();
|
|
1019
|
|
1020 public static final CommandSpec command_exists = ID;
|
|
1021
|
|
1022 @Command public void command_exists(IPrintWriter out, Interpreter interp) {
|
|
1023 out.print(template.program().getMeaning(interp.getArgString("id")) != null);
|
|
1024 }
|
|
1025
|
|
1026 public static final CommandSpec command_is_binary = ID;
|
|
1027
|
|
1028 @Command public void command_is_binary(IPrintWriter out, Interpreter interp) {
|
|
1029 out.print(JavaCommand.isJavaCommandId(interp.getArgString("id")));
|
|
1030 }
|
|
1031
|
|
1032 public static final CommandSpec command_name = ID;
|
|
1033
|
|
1034 @Command public void command_name(IPrintWriter out, Interpreter interp) {
|
|
1035 String id = interp.getArgString("id");
|
|
1036 out.print(Macro.getNameFromId(id));
|
|
1037 }
|
|
1038
|
|
1039 public static final CommandSpec command_source_name = ID;
|
|
1040
|
|
1041 @Command public void command_source_name(IPrintWriter out, Interpreter interp) {
|
|
1042 String id = interp.getArgString("id");
|
|
1043 out.print(Macro.getSourceFromId(id));
|
|
1044 }
|
|
1045
|
|
1046
|
|
1047 public static final CommandSpec get_macro_id = new CommandSpec.Builder()
|
|
1048 .parameters("macro_name")
|
|
1049 .build()
|
|
1050 ;
|
|
1051
|
|
1052 @Command public void get_macro_id(IPrintWriter out, Interpreter interp) {
|
|
1053 String name = interp.getArgString("macro_name");
|
|
1054 Collection<Macro> macros = template.program().getMacrosByName(name);
|
|
1055 if( macros.isEmpty() )
|
|
1056 throw new RuntimeException("macro not found");
|
|
1057 if( macros.size() != 1 )
|
|
1058 throw new RuntimeException("macro not unique");
|
|
1059 Macro macro = macros.iterator().next();
|
|
1060 out.print(macro.getId());
|
|
1061 }
|
|
1062
|
|
1063
|
|
1064 }
|