Mercurial Hosting > nabble
view 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 |
line wrap: on
line source
package nabble.naml.namespaces; import fschmidt.util.java.ArrayStack; import fschmidt.util.java.ObjectUtils; import fschmidt.util.java.Stack; import fschmidt.util.mail.MailAddress; import nabble.naml.compiler.Command; import nabble.naml.compiler.CommandSpec; import nabble.naml.compiler.CompileException; import nabble.naml.compiler.Encoder; import nabble.naml.compiler.ExitException; import nabble.naml.compiler.IPrintWriter; import nabble.naml.compiler.Interpreter; import nabble.naml.compiler.JavaCommand; import nabble.naml.compiler.Macro; import nabble.naml.compiler.Namespace; import nabble.naml.compiler.ScopedInterpreter; import nabble.naml.compiler.StackTrace; import nabble.naml.compiler.Template; import nabble.naml.compiler.TemplateRuntimeException; import nabble.naml.compiler.NamlNullPointerException; import nabble.view.web.template.DateNamespace; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; import java.util.regex.Matcher; import java.util.regex.Pattern; @Namespace ( name = "basic", global = true ) public final class BasicNamespace { private static final Logger logger = LoggerFactory.getLogger(BasicNamespace.class); private final Template template; public BasicNamespace(Template template) { this.template = template; } public static final CommandSpec exit = CommandSpec.NO_OUTPUT; @CommandDoc( "Exits the page generation and returns the control back to the browser." ) @Command public void exit(IPrintWriter out,Interpreter interp) { throw new ExitException(); } public static final CommandSpec throw_runtime_exception = new CommandSpec.Builder() .dotParameter("text") .outputtedParameters() .build() ; @CommandDoc( value= "Throws a runtime exception to show that something is wrong or broken. "+ "If this command is called, the page will display the full stack trace of the error, which "+ "should be investigated and fixed.", params = {"text=The message displayed by the exception"}, seeAlso = {"throw_template_exception"} ) @Command public void throw_runtime_exception(IPrintWriter out,Interpreter interp) { String text = interp.getArgString("text"); throw new RuntimeException(text); } public static final CommandSpec throw_template_exception = new CommandSpec.Builder() .dotParameter("name") .build() ; @CommandDoc( value= "Throws an exception that can be caught by the @link{catch_exception} command.", params = {"name=The name of the exception, which should be used later for catching and handling."}, seeAlso = {"ExceptionNamespace.exception"} ) @Command public void throw_template_exception(IPrintWriter out,Interpreter interp) throws TemplateException { String name = interp.getArgString("name"); throw TemplateException.newInstance(name); } @Command("true") public static void _true(IPrintWriter out,Interpreter interp) { out.print(true); } @Command("false") public static void _false(IPrintWriter out,Interpreter interp) { out.print(false); } public static final CommandSpec either = new CommandSpec.Builder() .parameters("condition1","condition2") .build() ; @Command public static void either(IPrintWriter out,Interpreter interp) { out.print( interp.getArgAsBoolean("condition1") || interp.getArgAsBoolean("condition2") ); } public static final CommandSpec both = new CommandSpec.Builder() .parameters("condition1","condition2") .build() ; @Command public static void both(IPrintWriter out,Interpreter interp) { out.print( interp.getArgAsBoolean("condition1") && interp.getArgAsBoolean("condition2") ); } public static final CommandSpec _if = new CommandSpec.Builder() .dotParameter("condition") .optionalParameters("then","else") .outputtedParameters("then","else") .dontRemoveNulls() .build() ; @CommandDoc( value= "Calls the \"then\" block if the 'condition' (dot_parameter) is true. " + "Otherwise, calls the \"else\" block (if available).", params = { "condition=Condition to be tested", "then=Block for the true case", "else=Block for the false case" } ) @Command("if") public static void _if(IPrintWriter out,Interpreter interp) { Object block = interp.getArg( interp.getArgAsBoolean("condition") ? "then" : "else" ); if( block != null ) out.print(block); } public static final CommandSpec not = new CommandSpec.Builder() .dotParameter("condition") .build() ; @Command public static void not(IPrintWriter out,Interpreter interp) { out.print( !interp.getArgAsBoolean("condition") ); } private static final CommandSpec optionalValue = new CommandSpec.Builder() .dotParameter("value") .optionalParameters("value") .build() ; public static final CommandSpec hide_null = optionalValue; @Command public static void hide_null(IPrintWriter out,Interpreter interp) { String s = interp.getArgString("value"); if( s != null ) out.print(s); } public static final CommandSpec is_null = optionalValue; @Command public static void is_null(IPrintWriter out,Interpreter interp) { String s = interp.getArgString("value"); out.print( s==null ); } @Command("null") public static void _null(IPrintWriter out,Interpreter interp) { out.print((String)null); } public static final CommandSpec null_exception_to_null = optionalValue; @Command public static void null_exception_to_null(IPrintWriter out,Interpreter interp) { try { out.print( interp.getArgString("value") ); } catch(NamlNullPointerException e) { out.print( (String)null ); } } private static final Random RANDOM = new Random(); public static final CommandSpec random = new CommandSpec.Builder() .parameters("max") .build() ; @Command public void random(IPrintWriter out,Interpreter interp) { int max = interp.getArgAsInt("max"); int r = RANDOM.nextInt(max); out.print(r); } public static final CommandSpec equal = new CommandSpec.Builder() .optionalParameters("value1","value2") .build() ; @Command public static void equal(IPrintWriter out,Interpreter interp) { out.print( ObjectUtils.equals(interp.getArgString("value1"),interp.getArgString("value2")) ); } public static final CommandSpec starts_with = new CommandSpec.Builder() .dotParameter("text") .parameters("prefix") .build() ; @Command public void starts_with(IPrintWriter out,Interpreter interp) { String text = interp.getArgString("text"); String prefix = interp.getArgString("prefix"); out.print( text.startsWith(prefix) ); } public static final CommandSpec ends_with = new CommandSpec.Builder() .dotParameter("text") .parameters("suffix") .build() ; @Command public void ends_with(IPrintWriter out,Interpreter interp) { String text = interp.getArgString("text"); String suffix = interp.getArgString("suffix"); out.print( text.endsWith(suffix) ); } public static final CommandSpec substring = new CommandSpec.Builder() .dotParameter("text") .parameters("begin") .optionalParameters("end") .build() ; @Command public void substring(IPrintWriter out,Interpreter interp) { String text = interp.getArgString("text"); int begin = Integer.parseInt(interp.getArgString("begin")); String end = interp.getArgString("end"); out.print( end==null ? text.substring(begin) : text.substring(begin,Integer.parseInt(end)) ); } public static final CommandSpec contains_substring = new CommandSpec.Builder() .dotParameter("string") .parameters("substring") .build() ; @Command public void contains_substring(IPrintWriter out,Interpreter interp) { out.print( interp.getArgString("string").indexOf(interp.getArgString("substring")) != -1 ); } public static final CommandSpec regex_quote = new CommandSpec.Builder() .dotParameter("string") .build() ; @Command public void regex_quote(IPrintWriter out,Interpreter interp) { out.print( Pattern.quote(interp.getArgString("string")) ); } public static final CommandSpec append = new CommandSpec.Builder() .dotParameter("text") .parameters("suffix") .optionalParameters("text","except_if") .restrictedParameter("except_if","already-included") .build() ; @Command public void append(IPrintWriter out,Interpreter interp) { String text = interp.getArgString("text"); out.print(text); if( text!=null && text.length() > 0 ) { String suffix = interp.getArgString("suffix"); if( !( "already-included".equals(interp.getArgString("except_if")) && text.toLowerCase().indexOf(suffix.toLowerCase()) != -1 ) ) out.print(suffix); } } public static final CommandSpec prepend = new CommandSpec.Builder() .dotParameter("text") .parameters("prefix") .optionalParameters("text","except_if") .restrictedParameter("except_if","already-included") .build() ; @Command public void prepend(IPrintWriter out,Interpreter interp) { String text = interp.getArgString("text"); if( text!=null && text.length() > 0 ) { String prefix = interp.getArgString("prefix"); if( !( "already-included".equals(interp.getArgString("except_if")) && text.toLowerCase().indexOf(prefix.toLowerCase()) != -1 ) ) out.print(prefix); } out.print(text); } public static final CommandSpec separate = new CommandSpec.Builder() .parameters("text1","separator","text2") .build() ; @Command public void separate(IPrintWriter out,Interpreter interp) { String text1 = interp.getArgString("text1"); if( text1 == null ) throw new NullPointerException("text1 is null"); String text2 = interp.getArgString("text2"); if( text2 == null ) throw new NullPointerException("text2 is null"); out.print( text1 ); if( text1.trim().length() > 0 && text2.trim().length() > 0 ) out.print( interp.getArg("separator") ); out.print( text2 ); } /* public static final CommandSpec is_in_namespace = new CommandSpec.Builder() .parameters("name") .build() ; @Command public static void is_in_namespace(IPrintWriter out,Interpreter interp) { out.print( interp.hasNamespace(interp.getArgString("name")) ); } */ public static final CommandSpec is_in_command = new CommandSpec.Builder() .parameters("name") .build() ; @Command public static void is_in_command(IPrintWriter out,Interpreter interp) { out.print( interp.isInCommandStack(interp.getArgString("name")) ); } public static final CommandSpec to_lower_case = CommandSpec.TEXT; @Command public void to_lower_case(IPrintWriter out,Interpreter interp) { out.print( interp.getArgString("text").toLowerCase() ); } public static final CommandSpec to_upper_case = CommandSpec.TEXT; @Command public void to_upper_case(IPrintWriter out,Interpreter interp) { out.print( interp.getArgString("text").toUpperCase() ); } public static final CommandSpec capitalize = CommandSpec.TEXT; @Command public void capitalize(IPrintWriter out,Interpreter interp) { String text = interp.getArgString("text"); String[] words = text.split("[ ]"); StringBuilder b = new StringBuilder(); for (String w : words) { if (b.length() > 0) b.append(' '); b.append(w.substring(0,1).toUpperCase()); b.append(w.substring(1,w.length())); } out.print(b.toString()); } public static final CommandSpec regex = new CommandSpec.Builder() .parameters("pattern","text") .scopedParameters("do") .dotParameter("do") .build() ; @Command public static void regex(IPrintWriter out,ScopedInterpreter<RegexNamespace> interp) { Pattern p = Pattern.compile( interp.getArgString("pattern") ); String s = interp.getArgString("text"); Matcher m = p.matcher(s); RegexNamespace ns = new RegexNamespace(m,s); out.print( interp.getArg(ns,"do") ); } public static final CommandSpec regex_replace_all = new CommandSpec.Builder() .dotParameter("text") .parameters("pattern","replacement") .build() ; @Command public static void regex_replace_all(IPrintWriter out,Interpreter interp) { String text = interp.getArgString("text"); String pattern = interp.getArgString("pattern"); String replacement = interp.getArgString("replacement"); out.print( text.replaceAll(pattern, replacement) ); } public static final CommandSpec regex_replace_first = new CommandSpec.Builder() .dotParameter("text") .parameters("pattern","replacement") .build() ; @Command public static void regex_replace_first(IPrintWriter out,Interpreter interp) { String text = interp.getArgString("text"); String pattern = interp.getArgString("pattern"); String replacement = interp.getArgString("replacement"); out.print( text.replaceFirst(pattern, replacement) ); } public static final CommandSpec string_replace_all = new CommandSpec.Builder() .dotParameter("text") .parameters("target","replacement") .build() ; @Command public static void string_replace_all(IPrintWriter out,Interpreter interp) { out.print( interp.getArgString("text").replace(interp.getArgString("target"),interp.getArgString("replacement")) ); } public static final CommandSpec trim = CommandSpec.TEXT; @Command public static void trim(IPrintWriter out,Interpreter interp) { String s = interp.getArgString("text"); out.print( s==null ? null : s.trim() ); } public static final CommandSpec encode = CommandSpec.OPTIONAL_TEXT; @Command public static void encode(IPrintWriter out,Interpreter interp) { String s = interp.getArgString("text"); out.print( interp.encode(s) ); } public static final CommandSpec use_text_encoder = CommandSpec.OPTIONAL_TEXT; @Command public void use_text_encoder(IPrintWriter out,Interpreter interp) { interp.setEncoder(Encoder.TEXT); String s = interp.getArgString("text"); out.print(s); } public static final CommandSpec use_html_encoder = CommandSpec.OPTIONAL_TEXT; @Command public void use_html_encoder(IPrintWriter out,Interpreter interp) { interp.setEncoder(Encoder.HTML); String s = interp.getArgString("text"); out.print(s); } public static final CommandSpec use_url_encoder = CommandSpec.OPTIONAL_TEXT; @Command public void use_url_encoder(IPrintWriter out,Interpreter interp) { interp.setEncoder(Encoder.URL); String s = interp.getArgString("text"); out.print(s); } public static final CommandSpec is_empty = optionalValue; @Command public static void is_empty(IPrintWriter out,Interpreter interp) { String s = interp.getArgString("value"); out.print( s==null || s.length() == 0 ); } public static final CommandSpec var = new CommandSpec.Builder() .parameters("name") .build() ; @Command public void var(IPrintWriter out,Interpreter interp) { throw new RuntimeException("never"); } public static final CommandSpec set_var = new CommandSpec.Builder() .parameters("name") .dotParameter("value") .optionalParameters("value") .outputtedParameters() .build() ; @Command public void set_var(IPrintWriter out,Interpreter interp) { throw new RuntimeException("never"); } public static final CommandSpec uplevel_var = var; @Command public void uplevel_var(IPrintWriter out,Interpreter interp) { throw new RuntimeException("never"); } public static final CommandSpec uplevel_set_var = set_var; @Command public void uplevel_set_var(IPrintWriter out,Interpreter interp) { throw new RuntimeException("never"); } private final Map<String,String> globalVars = new HashMap<String,String>(); public static final CommandSpec global_var = var; @Command public void global_var(IPrintWriter out,Interpreter interp) { String name = interp.getArgString("name"); out.print( globalVars.get(name) ); } public static final CommandSpec global_set_var = set_var; @Command public void global_set_var(IPrintWriter out,Interpreter interp) { String name = interp.getArgString("name"); String value = interp.getArgString("value"); globalVars.put(name,value); } public static final CommandSpec global_is_var_set = var; @Command public void global_is_var_set(IPrintWriter out,Interpreter interp) { String name = interp.getArgString("name"); out.print( globalVars.containsKey(name) ); } public static final CommandSpec _default = new CommandSpec.Builder() .dotParameter("text") .optionalParameters("text") .parameters("to") .build() ; @Command("default") public static void _default(IPrintWriter out,Interpreter interp) { String text = interp.getArgString("text"); out.print( text!=null ? text : interp.getArgString("to") ); } private static final int whileLimit = 1000000; private static class BreakException extends TemplateRuntimeException { BreakException() { super("break called outside of while"); } } public static final CommandSpec _while = new CommandSpec.Builder() .dotParameter("condition") .parameters("loop") .outputtedParameters("loop") .build() ; @Command("while") public void _while(IPrintWriter out,Interpreter interp) { Object condition = interp.getArg("condition"); Object block = interp.getArg("loop"); int count = 0; try { while( Template.booleanValue(condition) ) { if( ++count > whileLimit ) throw new RuntimeException("while loop limit of "+whileLimit+" iterations exceeded"); out.print(block); } } catch(BreakException e) {} } @Command("break") public void _break(IPrintWriter out,Interpreter interp) { throw new BreakException(); } @Command public void nop(IPrintWriter out,Interpreter interp) {} private static final class ExceptionInfo { private final String forStr; private final TemplateException ex; private ExceptionInfo(String forStr,TemplateException ex) { this.forStr = forStr; this.ex = ex; } } private Stack<ExceptionInfo> exceptionStack = new ArrayStack<ExceptionInfo>(); public static final CommandSpec catch_exception = new CommandSpec.Builder() .parameters("id") .dotParameter("do") .outputtedParameters("do") .build() ; @Command public void catch_exception(IPrintWriter out,Interpreter interp) { String idStr = interp.getArgString("id"); TemplateException ex = null; try { out.print( interp.getArg("do") ); } catch(TemplateRuntimeException e) { Throwable cause = e.getCause(); if( cause instanceof TemplateException ) { ex = (TemplateException)cause; } else { throw e; } } exceptionStack.push( new ExceptionInfo(idStr,ex) ); } @Namespace ( name = "error", global = false ) public static class ExceptionNamespace { protected final TemplateException ex; protected boolean isDone = false; public ExceptionNamespace(TemplateException ex) { this.ex = ex; } public static final CommandSpec exception = new CommandSpec.Builder() .parameters("name") .dotParameter("do") .build() ; @Command public void exception(IPrintWriter out,Interpreter interp) { if( isDone ) return; String name = interp.getArgString("name"); if( ex.isNamed(name) ) { out.print( interp.getArg("do") ); isDone = true; } } public static final CommandSpec unknown_exception = CommandSpec.DO; @Command public void unknown_exception(IPrintWriter out,ScopedInterpreter<UnknownException> interp) { if( isDone ) return; out.print( interp.getArg(new UnknownException(ex), "do") ); isDone = true; } protected static final CommandSpec scopedCommandSpec = new CommandSpec.Builder() .parameters("name") .dotParameter("do") .scopedParameters("do") .build() ; protected final <N> void scopedException(IPrintWriter out,ScopedInterpreter<N> interp,N ns) { if( isDone ) return; String name = interp.getArgString("name"); if( ex.isNamed(name) ) { out.print(interp.getArg(ns,"do")); isDone = true; } } protected final <N> void unnamedScopedException(IPrintWriter out,ScopedInterpreter<N> interp,N ns) { if( isDone ) return; out.print(interp.getArg(ns,"do")); isDone = true; } } @Namespace ( name = "unknown_exception", global = false ) public static class UnknownException extends ExceptionNamespace { public UnknownException(TemplateException ex) { super(ex); } @Command public void message(IPrintWriter out,Interpreter interp) { out.print(ex.getMessage()); } } public static interface ExceptionNamespaceFactory<E extends ExceptionNamespace> { public E newExceptionNamespace(TemplateException ex); } /* private static final ExceptionNamespaceFactory<ExceptionNamespace> myExceptionNamespaceFactory = new ExceptionNamespaceFactory<ExceptionNamespace>() { public ExceptionNamespace newExceptionNamespace(TemplateException ex) { return new ExceptionNamespace(ex); } } ;*/ public static final CommandSpec handle_exception = CommandSpec.DO() .parameters("for") .requiredInStack(BasicNamespace.class) .build() ; /* @Command public void handle_exception(IPrintWriter out,ScopedInterpreter<ExceptionNamespace> interp) { handleException(out,interp,myExceptionNamespaceFactory); } */ public <E extends ExceptionNamespace> void handleException(IPrintWriter out,ScopedInterpreter<E> interp,ExceptionNamespaceFactory<E> factory) { if( exceptionStack.isEmpty() ) throw new RuntimeException("there are no exceptions available to be handled"); ExceptionInfo ei = exceptionStack.pop(); String forStr = interp.getArgString("for"); if( !forStr.equals(ei.forStr) ) throw new RuntimeException("found exception for: "+ei.forStr); if( ei.ex == null ) return; E en = factory.newExceptionNamespace(ei.ex); out.print( interp.getArg(en,"do") ); if( !en.isDone ) { logger.error("unexpected exception"+StackTrace.current(),en.ex); out.print( "Unexpected exception: " + en.ex ); } } public static final CommandSpec has_exception = new CommandSpec.Builder() .parameters("for") .build() ; @Command public void has_exception(IPrintWriter out,Interpreter interp) { if( exceptionStack.isEmpty() ) throw new RuntimeException("there are no exceptions available to be handled"); ExceptionInfo ei = exceptionStack.peek(); String forStr = interp.getArgString("for"); if( !forStr.equals(ei.forStr) ) throw new RuntimeException("found exception for: "+ei.forStr); out.print( ei.ex != null ); } public static final CommandSpec string_list = CommandSpec.DO() .optionalParameters("values","separator","trim") .build() ; @Command public void string_list(IPrintWriter out,ScopedInterpreter<StringList> interp) { List<String> list = new ArrayList<String>(); String csv = interp.getArgString("values"); if( csv != null ) { String separator = interp.getArgString("separator"); if( separator == null ) separator = ","; boolean trim = interp.getArgAsBoolean("trim", true); for( String s : csv.split(separator) ) { list.add( trim? s.trim() : s ); } } Object block = interp.getArg(new StringList(list),"do"); out.print(block); } public static final CommandSpec string_map = new CommandSpec.Builder() .parameters("key") .dotParameter("entries") .build() ; @Command public void string_map(IPrintWriter out, Interpreter interp) { String key = interp.getArgString("key"); String[] entries = interp.getArgString("entries").split("\n"); for (String entry : entries) { String[] keyValue = entry.split(":"); if (key.equals(keyValue[0].trim())) { out.print(keyValue[1].trim()); return; } } out.print((String) null); } public static final CommandSpec _int = CommandSpec.DO() .parameters("i") .build() ; @Command("int") public void _int(IPrintWriter out,ScopedInterpreter<IntegerNamespace> interp) { out.print( interp.getArg(new IntegerNamespace(interp.getArgAsInt("i")),"do") ); } public static final CommandSpec extract_email_address_from = new CommandSpec.Builder() .dotParameter("text") .build() ; @Command public static void extract_email_address_from(IPrintWriter out,Interpreter interp) { String text = interp.getArgString("text").trim(); String email = null; if (new MailAddress(text).isValid()) { email = text; } else { int posOpen = text.lastIndexOf('<'); int posClose = text.lastIndexOf('>'); if (posOpen >= 0 && posClose > posOpen) { String middle = text.substring(posOpen+1, posClose); if (new MailAddress(middle).isValid()) email = middle; } } out.print(email); } @Command public void crlf(IPrintWriter out,Interpreter interp) { out.print("\r\n"); } @Command public void space(IPrintWriter out,Interpreter interp) { out.print(' '); } @Command public void double_quote(IPrintWriter out,Interpreter interp) { out.print("\""); } public static final CommandSpec has_module = new CommandSpec.Builder() .dotParameter("module") .build() ; @Command public static void has_module(IPrintWriter out,Interpreter interp) { out.print( interp.hasModule(interp.getArgString("module")) ); } public static final CommandSpec no_output = CommandSpec.NO_OUTPUT() .dotParameter("text") .build() ; @Command public static void no_output(IPrintWriter out,Interpreter interp) { interp.getArgString("text"); } @Command public static void lt(IPrintWriter out,Interpreter interp) { out.print('<'); } @Command public static void gt(IPrintWriter out,Interpreter interp) { out.print('>'); } public static final CommandSpec now = CommandSpec.DO; @Command public void now(IPrintWriter out,ScopedInterpreter<DateNamespace> interp) { out.print( interp.getArg(new DateNamespace(new Date()), "do" )); } public static final CommandSpec call_depth = CommandSpec.DO; @Command public void call_depth(IPrintWriter out,ScopedInterpreter<IntegerNamespace> interp) { out.print( interp.getArg(new IntegerNamespace(interp.callDepth()),"do") ); } public static final CommandSpec _switch = CommandSpec.DO() .optionalParameters("value") .build() ; @Command("switch") public void _switch(IPrintWriter out,ScopedInterpreter<SwitchNamespace> interp) { out.print( interp.getArg(new SwitchNamespace(interp.getArgString("value")),"do") ); } @Namespace ( name = "switch", global = false, transparent = true ) public static final class SwitchNamespace { private final String value; private boolean isDone = false; private SwitchNamespace(String value) { this.value = value; } @Command public void switch_value(IPrintWriter out,Interpreter interp) { out.print( value ); } public static final CommandSpec _case = new CommandSpec.Builder() .parameters("value") .dotParameter("do") .outputtedParameters() // to trim surrounding white-space .build() ; @Command("case") public void _case(IPrintWriter out,Interpreter interp) { if( !isDone && interp.getArgString("value").equals(value) ) { out.print( interp.getArg("do") ); isDone = true; } } public static final CommandSpec default_case = new CommandSpec.Builder() .dotParameter("do") .outputtedParameters("do") .build() ; @Command public void default_case(IPrintWriter out,Interpreter interp) { if( !isDone ) { out.print( interp.getArg("do") ); isDone = true; } } public static final CommandSpec regex_case = new CommandSpec.Builder() .parameters("regex") .scopedParameters("do") .dotParameter("do") .outputtedParameters("do") .build() ; @Command public void regex_case(IPrintWriter out,ScopedInterpreter<RegexNamespace> interp) { if( !isDone ) { Matcher m = Pattern.compile(interp.getArgString("regex")).matcher(value); if( m.matches() ) { out.print( interp.getArg(new RegexNamespace(m,value),"do") ); isDone = true; } } } } @Namespace ( name = "block", global = false ) public static final class BlockNamespace {} private static final BlockNamespace BLOCK = new BlockNamespace(); public static final CommandSpec block = CommandSpec.DO; @Command public void block(IPrintWriter out,ScopedInterpreter<BlockNamespace> interp) { out.print( interp.getArg(BLOCK,"do") ); } @Namespace ( name = "counter", global = false ) public static final class CounterNamespace { private int counter = 0; public static final CommandSpec increment = CommandSpec.NO_OUTPUT; @Command public void increment(IPrintWriter out,Interpreter interp) { counter++; } @Command public void value(IPrintWriter out,Interpreter interp) { out.print(counter); } } private Map<String,CounterNamespace> counterMap = null; public static final CommandSpec counter = CommandSpec.DO() .parameters("name") .build() ; @Command public void counter(IPrintWriter out,ScopedInterpreter<CounterNamespace> interp) { if( counterMap == null ) counterMap = new HashMap<String,CounterNamespace>(); String name = interp.getArgString("name"); if( name==null ) throw new NullPointerException("name is required"); CounterNamespace ns = counterMap.get(name); if( ns == null ) { ns = new CounterNamespace(); counterMap.put(name,ns); } out.print( interp.getArg(ns,"do") ); } public static final CommandSpec compile_template = CommandSpec.NO_OUTPUT() .parameters("macro","namespaces") .build() ; @Command public void compile_template(IPrintWriter out,Interpreter interp) throws ClassNotFoundException, CompileException { String macroName = interp.getArgString("macro"); String namespacesStr = interp.getArgString("namespaces").trim(); String[] namespaces = namespacesStr.length()==0 ? new String[0] : namespacesStr.split("\\s*,\\s*"); if( interp.template().program().getTemplate( macroName, namespaces ) == null ) throw new RuntimeException("macro '"+macroName+"' not found"); } private static final CommandSpec ID = new CommandSpec.Builder() .parameters("id") .build(); public static final CommandSpec command_exists = ID; @Command public void command_exists(IPrintWriter out, Interpreter interp) { out.print(template.program().getMeaning(interp.getArgString("id")) != null); } public static final CommandSpec command_is_binary = ID; @Command public void command_is_binary(IPrintWriter out, Interpreter interp) { out.print(JavaCommand.isJavaCommandId(interp.getArgString("id"))); } public static final CommandSpec command_name = ID; @Command public void command_name(IPrintWriter out, Interpreter interp) { String id = interp.getArgString("id"); out.print(Macro.getNameFromId(id)); } public static final CommandSpec command_source_name = ID; @Command public void command_source_name(IPrintWriter out, Interpreter interp) { String id = interp.getArgString("id"); out.print(Macro.getSourceFromId(id)); } public static final CommandSpec get_macro_id = new CommandSpec.Builder() .parameters("macro_name") .build() ; @Command public void get_macro_id(IPrintWriter out, Interpreter interp) { String name = interp.getArgString("macro_name"); Collection<Macro> macros = template.program().getMacrosByName(name); if( macros.isEmpty() ) throw new RuntimeException("macro not found"); if( macros.size() != 1 ) throw new RuntimeException("macro not unique"); Macro macro = macros.iterator().next(); out.print(macro.getId()); } }