Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
TemplateTool |
|
| 1.5384615384615385;1.538 | ||||
TemplateTool$MacroTemplate |
|
| 1.5384615384615385;1.538 | ||||
TemplateTool$MacroTemplateFactory |
|
| 1.5384615384615385;1.538 |
1 | /* | |
2 | * TemplateTool.java | |
3 | * | |
4 | * Created on August 28, 2001, 10:45 PM | |
5 | */ | |
6 | ||
7 | package org.webmacro.servlet; | |
8 | ||
9 | import org.webmacro.Context; | |
10 | import org.webmacro.PropertyException; | |
11 | import org.webmacro.Template; | |
12 | import org.webmacro.ContextTool; | |
13 | import org.webmacro.engine.StringTemplate; | |
14 | ||
15 | import java.util.ArrayList; | |
16 | ||
17 | //import java.util.Map; | |
18 | ||
19 | /** | |
20 | * This is an experimental context tool that allows templates | |
21 | * to be used as macros. The tool places a | |
22 | * MacroTemplateFactory instance into the context that can | |
23 | * be referenced as $Template in WMScript. The factory has | |
24 | * two methods, each of which returns a MacroTemplate object, | |
25 | * created either from a string or a file. | |
26 | * | |
27 | * @author Keats Kirsch | |
28 | * @version 0.2 | |
29 | */ | |
30 | public class TemplateTool extends ContextTool | |
31 | { | |
32 | ||
33 | 0 | private Context _context = null; |
34 | /** | |
35 | * Flag set when destroy is first called, to prevent subsequent calls from | |
36 | * invoking the destroy() method on the factory object. | |
37 | */ | |
38 | //private boolean _destroyed = false; | |
39 | ||
40 | /** Creates new TemplateTool. */ | |
41 | public TemplateTool () | |
42 | 0 | { |
43 | 0 | } |
44 | ||
45 | /** Create a factory object that can be accessed from WMScript as | |
46 | * $Template for creating MacroTemplate objects. | |
47 | * @param c The context of the current request. | |
48 | * @throws PropertyException From the ContextTool interface | |
49 | * @return a new MacroTemplateFactory for each request. | |
50 | */ | |
51 | public Object init (Context c) throws PropertyException | |
52 | { | |
53 | 0 | _context = c; |
54 | 0 | return new MacroTemplateFactory(_context); |
55 | } | |
56 | ||
57 | /** A factory class for creating MacroTemplate objects. | |
58 | */ | |
59 | public class MacroTemplateFactory | |
60 | { | |
61 | ||
62 | private Context _contextLocal; | |
63 | 0 | private ArrayList _macros = new ArrayList(10); |
64 | ||
65 | /** Constructor | |
66 | * @param ctx the context for the current request | |
67 | */ | |
68 | public MacroTemplateFactory (Context ctx) | |
69 | 0 | { |
70 | 0 | _contextLocal = ctx; |
71 | 0 | } |
72 | ||
73 | /** Creates a MacroTemplate from a string with a new context. | |
74 | * @param s the template string | |
75 | * @return the new MacroTemplate | |
76 | */ | |
77 | public MacroTemplate fromString (String s) | |
78 | { | |
79 | 0 | MacroTemplate mt = new MacroTemplate(_contextLocal, s); |
80 | 0 | _macros.add(mt); |
81 | 0 | return mt; |
82 | } | |
83 | ||
84 | /** Creates a MacroTemplate from a file reference with a | |
85 | * new context. | |
86 | * @param fileRef a reference to the template file | |
87 | * @throws org.webmacro.ResourceException if the file cannot be found or parsed | |
88 | * @return a new MacroTemplate | |
89 | */ | |
90 | public MacroTemplate fromFile (String fileRef) | |
91 | throws org.webmacro.ResourceException | |
92 | { | |
93 | 0 | Template t = (Template) _contextLocal.getBroker() |
94 | .getProvider("template").get(fileRef); | |
95 | 0 | MacroTemplate mt = new MacroTemplate(_contextLocal, t); |
96 | 0 | _macros.add(mt); |
97 | 0 | return mt; |
98 | } | |
99 | ||
100 | } | |
101 | ||
102 | /** | |
103 | * Encapsulates a template and a context, allowing a template | |
104 | * to be used like a function or "macro". | |
105 | */ | |
106 | public class MacroTemplate | |
107 | { | |
108 | ||
109 | private Template _template; | |
110 | private Context _contextLocal, _origContext; | |
111 | ||
112 | /** | |
113 | * Constructor. | |
114 | * @param c the current request context | |
115 | * @param t the template to be used as a macro | |
116 | */ | |
117 | public MacroTemplate (Context c, Template t) | |
118 | 0 | { |
119 | 0 | _template = t; |
120 | 0 | _origContext = c; |
121 | // @@@ Just get a new one? | |
122 | 0 | _contextLocal = c.cloneContext(); |
123 | 0 | } |
124 | ||
125 | /** | |
126 | * Construct a MacroTemplate with a StringTemplate. | |
127 | * @param c The context of the current request | |
128 | * @param src the string for the StringTemplate | |
129 | */ | |
130 | public MacroTemplate (Context c, String src) | |
131 | { | |
132 | 0 | this(c, new StringTemplate(c.getBroker(), src)); |
133 | 0 | } |
134 | ||
135 | /** | |
136 | * Exposes the context of the current MacroTemplate. This allows | |
137 | * "arguments" to be set from a template. E.g., | |
138 | * <CODE>#set $myMacro.Args.Name = $User.Name</CODE> | |
139 | * @return the context of the macro | |
140 | */ | |
141 | public Context getArgs () | |
142 | { | |
143 | 0 | return _contextLocal; |
144 | } | |
145 | ||
146 | /** | |
147 | * Evaluates the macro's template against its context and returns the | |
148 | * resulting string. | |
149 | * @throws PropertyException runtime errors in evaluating the macro's template | |
150 | * @return the resultant string after the template is evaluated. | |
151 | */ | |
152 | public Object eval () throws PropertyException | |
153 | { | |
154 | 0 | synchronized (_contextLocal) |
155 | { | |
156 | 0 | return _template.evaluateAsString(_contextLocal); |
157 | 0 | } |
158 | } | |
159 | ||
160 | public Object eval (Object[] args) throws PropertyException | |
161 | { | |
162 | 0 | if (args != null) |
163 | { | |
164 | 0 | for (int i = 0; i < args.length; i++) |
165 | { | |
166 | 0 | _contextLocal.put("arg" + (i + 1), args[i]); |
167 | } | |
168 | 0 | _contextLocal.put("args", args); |
169 | } | |
170 | 0 | return eval(); |
171 | } | |
172 | ||
173 | public Object eval (Object[] args, Object[] names) throws PropertyException | |
174 | { | |
175 | 0 | if (args == null || names == null || args.length != names.length) |
176 | 0 | throw new PropertyException( |
177 | "Usage error: both args must be arrays of equal length!"); | |
178 | 0 | for (int i = 0; i < args.length; i++) |
179 | { | |
180 | 0 | _contextLocal.put(names[i], args[i]); |
181 | } | |
182 | 0 | _contextLocal.put("args", args); |
183 | 0 | return eval(); |
184 | } | |
185 | ||
186 | public Object eval (java.util.Map map) throws PropertyException | |
187 | { | |
188 | 0 | _contextLocal.putAll(map); |
189 | 0 | return eval(); |
190 | } | |
191 | ||
192 | /** | |
193 | * Copies all variables from the current request context into the context | |
194 | * of the macro. | |
195 | */ | |
196 | public void copyCurrentContext () | |
197 | { | |
198 | 0 | synchronized (_contextLocal) |
199 | { | |
200 | 0 | _contextLocal.putAll(_origContext); |
201 | 0 | } |
202 | 0 | } |
203 | ||
204 | } | |
205 | } | |
206 |