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 }