Mercurial Hosting > nabble
comparison src/nabble/naml/namespaces/BasicNamespace.java @ 0:7ecd1a4ef557
add content
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 21 Mar 2019 19:15:52 -0600 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:7ecd1a4ef557 |
---|---|
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 } |