1 package org.apache.velocity.runtime;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.BufferedReader;
23 import java.io.StringReader;
24 import java.util.Hashtable;
25 import org.apache.velocity.context.InternalContextAdapter;
26 import org.apache.velocity.runtime.directive.VelocimacroProxy;
27 import org.apache.velocity.runtime.parser.node.SimpleNode;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 public class VelocimacroManager
46 {
47 private final RuntimeServices rsvc;
48 private static String GLOBAL_NAMESPACE = "";
49
50 private boolean registerFromLib = false;
51
52
53 private final Hashtable namespaceHash = new Hashtable();
54
55
56 private final Hashtable libraryMap = new Hashtable();
57
58
59
60
61
62 private boolean namespacesOn = true;
63 private boolean inlineLocalMode = false;
64
65
66
67
68 VelocimacroManager(RuntimeServices rsvc)
69 {
70 this.rsvc = rsvc;
71
72
73
74
75
76 addNamespace(GLOBAL_NAMESPACE);
77 }
78
79
80
81
82
83
84
85
86
87 public boolean addVM(final String vmName, final String macroBody, final String argArray[],
88 final String namespace)
89 {
90 MacroEntry me = new MacroEntry(vmName, macroBody, argArray,
91 namespace);
92
93 me.setFromLibrary(registerFromLib);
94
95
96
97
98
99
100
101
102 boolean isLib = true;
103
104 if (registerFromLib)
105 {
106 libraryMap.put(namespace, namespace);
107 }
108 else
109 {
110
111
112
113
114
115
116
117
118 isLib = libraryMap.containsKey(namespace);
119 }
120
121 if (!isLib && usingNamespaces(namespace))
122 {
123
124
125
126
127
128 Hashtable local = getNamespace(namespace, true);
129 local.put(vmName, me);
130
131 return true;
132 }
133 else
134 {
135
136
137
138
139
140 MacroEntry exist = (MacroEntry) getNamespace(GLOBAL_NAMESPACE).get(vmName);
141
142 if (exist != null)
143 {
144 me.setFromLibrary(exist.getFromLibrary());
145 }
146
147
148
149
150
151 getNamespace(GLOBAL_NAMESPACE).put(vmName, me);
152
153 return true;
154 }
155 }
156
157
158
159
160
161
162
163
164 public VelocimacroProxy get(final String vmName, final String namespace)
165 {
166
167 if (usingNamespaces(namespace))
168 {
169 Hashtable local = getNamespace(namespace, false);
170
171
172
173
174
175 if (local != null)
176 {
177 MacroEntry me = (MacroEntry) local.get(vmName);
178
179 if (me != null)
180 {
181 return me.createVelocimacro(namespace);
182 }
183 }
184 }
185
186
187
188
189
190
191 MacroEntry me = (MacroEntry) getNamespace(GLOBAL_NAMESPACE).get( vmName );
192
193 if (me != null)
194 {
195 return me.createVelocimacro(namespace);
196 }
197
198 return null;
199 }
200
201
202
203
204
205
206
207
208
209 public boolean dumpNamespace(final String namespace)
210 {
211 synchronized(this)
212 {
213 if (usingNamespaces(namespace))
214 {
215 Hashtable h = (Hashtable) namespaceHash.remove(namespace);
216
217 if (h == null)
218 {
219 return false;
220 }
221
222 h.clear();
223
224 return true;
225 }
226
227 return false;
228 }
229 }
230
231
232
233
234
235
236
237
238 public void setNamespaceUsage(final boolean namespaceOn)
239 {
240 this.namespacesOn = namespaceOn;
241 }
242
243
244
245
246
247 public void setRegisterFromLib(final boolean registerFromLib)
248 {
249 this.registerFromLib = registerFromLib;
250 }
251
252
253
254
255
256
257 public void setTemplateLocalInlineVM(final boolean inlineLocalMode)
258 {
259 this.inlineLocalMode = inlineLocalMode;
260 }
261
262
263
264
265
266
267
268
269 private Hashtable getNamespace(final String namespace)
270 {
271 return getNamespace(namespace, false);
272 }
273
274
275
276
277
278
279
280
281
282 private Hashtable getNamespace(final String namespace, final boolean addIfNew)
283 {
284 Hashtable h = (Hashtable) namespaceHash.get(namespace);
285
286 if (h == null && addIfNew)
287 {
288 h = addNamespace(namespace);
289 }
290
291 return h;
292 }
293
294
295
296
297
298
299
300 private Hashtable addNamespace(final String namespace)
301 {
302 Hashtable h = new Hashtable();
303 Object oh;
304
305 if ((oh = namespaceHash.put(namespace, h)) != null)
306 {
307
308
309
310
311
312
313
314 namespaceHash.put(namespace, oh);
315
316
317
318
319 return null;
320 }
321
322 return h;
323 }
324
325
326
327
328
329
330
331 private boolean usingNamespaces(final String namespace)
332 {
333
334
335
336
337 if (!namespacesOn)
338 {
339 return false;
340 }
341
342
343
344
345
346 if (inlineLocalMode)
347 {
348 return true;
349 }
350
351 return false;
352 }
353
354
355
356
357
358
359
360 public String getLibraryName(final String vmName, final String namespace)
361 {
362 if (usingNamespaces(namespace))
363 {
364 Hashtable local = getNamespace(namespace, false);
365
366
367
368
369
370
371
372 if ( local != null)
373 {
374 MacroEntry me = (MacroEntry) local.get(vmName);
375
376 if (me != null)
377 {
378 return null;
379 }
380 }
381 }
382
383
384
385
386
387
388 MacroEntry me = (MacroEntry) getNamespace(GLOBAL_NAMESPACE).get(vmName);
389
390 if (me != null)
391 {
392 return me.getSourceTemplate();
393 }
394
395 return null;
396 }
397
398
399
400
401
402 private class MacroEntry
403 {
404 private final String vmName;
405 private final String[] argArray;
406 private final String macroBody;
407 private final String sourceTemplate;
408
409 private SimpleNode nodeTree = null;
410 private boolean fromLibrary = false;
411
412 private MacroEntry(final String vmName, final String macroBody,
413 final String argArray[], final String sourceTemplate)
414 {
415 this.vmName = vmName;
416 this.argArray = argArray;
417 this.macroBody = macroBody;
418 this.sourceTemplate = sourceTemplate;
419 }
420
421
422
423
424
425 public void setFromLibrary(final boolean fromLibrary)
426 {
427 this.fromLibrary = fromLibrary;
428 }
429
430
431
432
433
434 public boolean getFromLibrary()
435 {
436 return fromLibrary;
437 }
438
439
440
441
442
443 public SimpleNode getNodeTree()
444 {
445 return nodeTree;
446 }
447
448
449
450
451
452 public String getSourceTemplate()
453 {
454 return sourceTemplate;
455 }
456
457 VelocimacroProxy createVelocimacro(final String namespace)
458 {
459 VelocimacroProxy vp = new VelocimacroProxy();
460 vp.setName(this.vmName);
461 vp.setArgArray(this.argArray);
462 vp.setMacrobody(this.macroBody);
463 vp.setNodeTree(this.nodeTree);
464 vp.setNamespace(namespace);
465 return vp;
466 }
467
468 void setup(final InternalContextAdapter ica)
469 {
470
471
472
473
474 if( nodeTree == null)
475 {
476 parseTree(ica);
477 }
478 }
479
480 void parseTree(final InternalContextAdapter ica)
481 {
482 try
483 {
484 BufferedReader br = new BufferedReader(new StringReader(macroBody));
485
486 nodeTree = rsvc.parse(br, "VM:" + vmName, true);
487 nodeTree.init(ica, null);
488 }
489 catch (Exception e)
490 {
491 rsvc.getLog().error("VelocimacroManager.parseTree() failed on VM '"
492 + vmName + "'", e);
493 }
494 }
495 }
496 }