0
|
1 package nabble.naml.compiler;
|
|
2
|
|
3 import fschmidt.util.java.Stack;
|
|
4
|
|
5 import java.util.HashSet;
|
|
6 import java.util.Map;
|
|
7 import java.util.Set;
|
|
8
|
|
9
|
|
10 public final class Template extends Compiler.Traceable {
|
|
11 private final Program program;
|
|
12 private final Chunk chunk;
|
|
13 private final Class[] baseClasses;
|
|
14 public final Macro macro;
|
|
15
|
|
16 Template(Compiler compiler,Program program,Chunk chunk,Class[] baseClasses,Macro macro) {
|
|
17 super(compiler);
|
|
18 this.program = program;
|
|
19 this.chunk = chunk;
|
|
20 this.baseClasses = baseClasses;
|
|
21 this.macro = macro;
|
|
22 }
|
|
23
|
|
24 public String name() {
|
|
25 return macro.name;
|
|
26 }
|
|
27
|
|
28 public final Program program() {
|
|
29 return program;
|
|
30 }
|
|
31
|
|
32 public final void run(IPrintWriter out,Map<String,Object> args,Object... base) {
|
|
33 run(0,Encoder.TEXT,out,args,base);
|
|
34 out.flush();
|
|
35 }
|
|
36
|
|
37 final void run(int callDepth,Encoder encoder,IPrintWriter out,Map<String,Object> args,Object... base) {
|
|
38 Set<String> argNames = macro.parameters;
|
|
39 if( !argNames.containsAll(args.keySet()) ) {
|
|
40 Set<String> badArgs = new HashSet<String>(args.keySet());
|
|
41 badArgs.removeAll(argNames);
|
|
42 throw new RuntimeException("invalid args: "+badArgs);
|
|
43 }
|
|
44 Stack<StackTrace> stack = StackTrace.stack();
|
|
45 stack.push(stackTrace);
|
|
46 try {
|
|
47 check(base);
|
|
48 RunState runState = new RunStateImpl(this,callDepth,encoder);
|
|
49 for( Object obj : base ) {
|
|
50 runState.push(obj);
|
|
51 }
|
|
52 for( Map.Entry<String,Object> entry : args.entrySet() ) {
|
|
53 String key = entry.getKey();
|
|
54 Object value = entry.getValue();
|
|
55 if( value instanceof String ) {
|
|
56 runState.putArg( key, (String)value );
|
|
57 } else {
|
|
58 runState.putArg( key, runState.saveNamespace(value) );
|
|
59 }
|
|
60 }
|
|
61 chunk.run(out,runState);
|
|
62 } catch (ExitException e) {
|
|
63 // do nothing.
|
|
64 } finally {
|
|
65 stack.pop();
|
|
66 }
|
|
67 }
|
|
68
|
|
69 private void check(Object[] base) {
|
|
70 if( base.length != baseClasses.length )
|
|
71 throw new TemplateRuntimeException("base mismatch base.length="+base.length+" baseClasses.length="+baseClasses.length);
|
|
72 for( int i=0; i<baseClasses.length; i++ ) {
|
|
73 if( !baseClasses[i].isInstance(base[i]) )
|
|
74 throw new TemplateRuntimeException("base mismatch");
|
|
75 }
|
|
76 }
|
|
77
|
|
78 // private static void handle(Exception e) {
|
|
79 // if( e instanceof RuntimeException )
|
|
80 // throw (RuntimeException)e;
|
|
81 // throw new TemplateRuntimeException(e);
|
|
82 // }
|
|
83
|
|
84 public static String stringValue(Object obj) {
|
|
85 if( obj==null )
|
|
86 return null;
|
|
87 return obj.toString();
|
|
88 }
|
|
89
|
|
90 public static boolean booleanValue(String s)
|
|
91 throws BooleanFormatException
|
|
92 {
|
|
93 if( s.equalsIgnoreCase("true") )
|
|
94 return true;
|
|
95 if( s.equalsIgnoreCase("false") )
|
|
96 return false;
|
|
97 throw new BooleanFormatException("For input string: \""+s+"\"");
|
|
98 }
|
|
99
|
|
100 public static boolean booleanValue(Object obj)
|
|
101 throws BooleanFormatException
|
|
102 {
|
|
103 String s = stringValue(obj);
|
|
104 if( s==null )
|
|
105 throw new BooleanFormatException("For input string: null");
|
|
106 return booleanValue(s);
|
|
107 }
|
|
108
|
|
109 public static boolean booleanValue(Object obj,boolean defaultValue)
|
|
110 throws BooleanFormatException
|
|
111 {
|
|
112 String s = stringValue(obj);
|
|
113 if( s==null )
|
|
114 return defaultValue;
|
|
115 return booleanValue(s);
|
|
116 }
|
|
117
|
|
118 public static int intValue(Object obj)
|
|
119 throws NumberFormatException
|
|
120 {
|
|
121 String s = stringValue(obj);
|
|
122 return Integer.parseInt(s);
|
|
123 }
|
|
124
|
|
125 public static int intValue(Object obj, int defaultValue)
|
|
126 throws NumberFormatException
|
|
127 {
|
|
128 String s = stringValue(obj);
|
|
129 if( s==null )
|
|
130 return defaultValue;
|
|
131 return Integer.parseInt(s);
|
|
132 }
|
|
133
|
|
134 public static long longValue(Object obj)
|
|
135 throws NumberFormatException
|
|
136 {
|
|
137 String s = stringValue(obj);
|
|
138 return Long.parseLong(s);
|
|
139 }
|
|
140
|
|
141 }
|