Source Code Cross Referenced for VelocimacroFactory.java in  » Template-Engine » Velocity » org » apache » velocity » runtime » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Template Engine » Velocity » org.apache.velocity.runtime 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.apache.velocity.runtime;
002:
003:        /*
004:         * Licensed to the Apache Software Foundation (ASF) under one
005:         * or more contributor license agreements.  See the NOTICE file
006:         * distributed with this work for additional information
007:         * regarding copyright ownership.  The ASF licenses this file
008:         * to you under the Apache License, Version 2.0 (the
009:         * "License"); you may not use this file except in compliance
010:         * with the License.  You may obtain a copy of the License at
011:         *
012:         *   http://www.apache.org/licenses/LICENSE-2.0
013:         *
014:         * Unless required by applicable law or agreed to in writing,
015:         * software distributed under the License is distributed on an
016:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017:         * KIND, either express or implied.  See the License for the
018:         * specific language governing permissions and limitations
019:         * under the License.    
020:         */
021:
022:        import java.util.HashMap;
023:        import java.util.Map;
024:        import java.util.Vector;
025:
026:        import org.apache.commons.lang.StringUtils;
027:        import org.apache.velocity.Template;
028:        import org.apache.velocity.runtime.directive.Directive;
029:        import org.apache.velocity.runtime.directive.Macro;
030:        import org.apache.velocity.runtime.directive.VelocimacroProxy;
031:        import org.apache.velocity.runtime.log.LogDisplayWrapper;
032:
033:        /**
034:         *  VelocimacroFactory.java
035:         *
036:         *   manages the set of VMs in a running Velocity engine.
037:         *
038:         * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
039:         * @version $Id: VelocimacroFactory.java 469919 2006-11-01 14:35:46Z henning $
040:         */
041:        public class VelocimacroFactory {
042:            /**
043:             *  runtime services for this instance
044:             */
045:            private final RuntimeServices rsvc;
046:
047:            /**
048:             *  the log for this instance
049:             */
050:            private final LogDisplayWrapper log;
051:
052:            /**
053:             *  VMManager : deal with namespace management
054:             *  and actually keeps all the VM definitions
055:             */
056:            private VelocimacroManager vmManager = null;
057:
058:            /**
059:             *  determines if replacement of global VMs are allowed
060:             *  controlled by  VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL
061:             */
062:            private boolean replaceAllowed = false;
063:
064:            /**
065:             *  controls if new VMs can be added.  Set by
066:             *  VM_PERM_ALLOW_INLINE  Note the assumption that only
067:             *  through inline defs can this happen.
068:             *  additions through autoloaded VMs is allowed
069:             */
070:            private boolean addNewAllowed = true;
071:
072:            /**
073:             *  sets if template-local namespace in used
074:             */
075:            private boolean templateLocal = false;
076:
077:            /**
078:             *  determines if the libraries are auto-loaded
079:             *  when they change
080:             */
081:            private boolean autoReloadLibrary = false;
082:
083:            /**
084:             *  vector of the library names
085:             */
086:            private Vector macroLibVec = null;
087:
088:            /**
089:             *  map of the library Template objects
090:             *  used for reload determination
091:             */
092:            private Map libModMap;
093:
094:            /**
095:             *  C'tor for the VelociMacro factory.
096:             *
097:             * @param rsvc Reference to a runtime services object.
098:             */
099:            public VelocimacroFactory(final RuntimeServices rsvc) {
100:                this .rsvc = rsvc;
101:                this .log = new LogDisplayWrapper(rsvc.getLog(),
102:                        "Velocimacro : ", rsvc.getBoolean(
103:                                RuntimeConstants.VM_MESSAGES_ON, true));
104:
105:                /*
106:                 *  we always access in a synchronized(), so we
107:                 *  can use an unsynchronized hashmap
108:                 */
109:                libModMap = new HashMap();
110:                vmManager = new VelocimacroManager(rsvc);
111:            }
112:
113:            /**
114:             *  initialize the factory - setup all permissions
115:             *  load all global libraries.
116:             */
117:            public void initVelocimacro() {
118:                /*
119:                 *  maybe I'm just paranoid...
120:                 */
121:                synchronized (this ) {
122:                    log.trace("initialization starting.");
123:
124:                    /*
125:                     *   allow replacements while we add the libraries, if exist
126:                     */
127:                    setReplacementPermission(true);
128:
129:                    /*
130:                     *  add all library macros to the global namespace
131:                     */
132:
133:                    vmManager.setNamespaceUsage(false);
134:
135:                    /*
136:                     *  now, if there is a global or local libraries specified, use them.
137:                     *  All we have to do is get the template. The template will be parsed;
138:                     *  VM's  are added during the parse phase
139:                     */
140:
141:                    Object libfiles = rsvc
142:                            .getProperty(RuntimeConstants.VM_LIBRARY);
143:
144:                    if (libfiles == null) {
145:                        log.debug("\"" + RuntimeConstants.VM_LIBRARY
146:                                + "\" is not set.  Trying default library: "
147:                                + RuntimeConstants.VM_LIBRARY_DEFAULT);
148:
149:                        // try the default library.
150:                        if (rsvc
151:                                .getLoaderNameForResource(RuntimeConstants.VM_LIBRARY_DEFAULT) != null) {
152:                            libfiles = RuntimeConstants.VM_LIBRARY_DEFAULT;
153:                        } else {
154:                            log.debug("Default library not found.");
155:                        }
156:                    }
157:
158:                    if (libfiles != null) {
159:                        if (libfiles instanceof  Vector) {
160:                            macroLibVec = (Vector) libfiles;
161:                        } else if (libfiles instanceof  String) {
162:                            macroLibVec = new Vector();
163:                            macroLibVec.addElement(libfiles);
164:                        }
165:
166:                        for (int i = 0; i < macroLibVec.size(); i++) {
167:                            String lib = (String) macroLibVec.elementAt(i);
168:
169:                            /*
170:                             * only if it's a non-empty string do we bother
171:                             */
172:
173:                            if (StringUtils.isNotEmpty(lib)) {
174:                                /*
175:                                 *  let the VMManager know that the following is coming
176:                                 *  from libraries - need to know for auto-load
177:                                 */
178:
179:                                vmManager.setRegisterFromLib(true);
180:
181:                                log
182:                                        .debug("adding VMs from VM library : "
183:                                                + lib);
184:
185:                                try {
186:                                    Template template = rsvc.getTemplate(lib);
187:
188:                                    /*
189:                                     *  save the template.  This depends on the assumption
190:                                     *  that the Template object won't change - currently
191:                                     *  this is how the Resource manager works
192:                                     */
193:
194:                                    Twonk twonk = new Twonk();
195:                                    twonk.template = template;
196:                                    twonk.modificationTime = template
197:                                            .getLastModified();
198:                                    libModMap.put(lib, twonk);
199:                                } catch (Exception e) {
200:                                    log.error(true,
201:                                            "Velocimacro : Error using VM library : "
202:                                                    + lib, e);
203:                                }
204:
205:                                log.trace("VM library registration complete.");
206:
207:                                vmManager.setRegisterFromLib(false);
208:                            }
209:                        }
210:                    }
211:
212:                    /*
213:                     *   now, the permissions
214:                     */
215:
216:                    /*
217:                     *  allowinline : anything after this will be an inline macro, I think
218:                     *  there is the question if a #include is an inline, and I think so
219:                     *
220:                     *  default = true
221:                     */
222:                    setAddMacroPermission(true);
223:
224:                    if (!rsvc.getBoolean(RuntimeConstants.VM_PERM_ALLOW_INLINE,
225:                            true)) {
226:                        setAddMacroPermission(false);
227:
228:                        log
229:                                .info("allowInline = false : VMs can NOT be defined inline in templates");
230:                    } else {
231:                        log
232:                                .debug("allowInline = true : VMs can be defined inline in templates");
233:                    }
234:
235:                    /*
236:                     *  allowInlineToReplaceGlobal : allows an inline VM , if allowed at all,
237:                     *  to replace an existing global VM
238:                     *
239:                     *  default = false
240:                     */
241:                    setReplacementPermission(false);
242:
243:                    if (rsvc
244:                            .getBoolean(
245:                                    RuntimeConstants.VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL,
246:                                    false)) {
247:                        setReplacementPermission(true);
248:
249:                        log
250:                                .info("allowInlineToOverride = true : VMs "
251:                                        + "defined inline may replace previous VM definitions");
252:                    } else {
253:                        log
254:                                .debug("allowInlineToOverride = false : VMs "
255:                                        + "defined inline may NOT replace previous VM definitions");
256:                    }
257:
258:                    /*
259:                     * now turn on namespace handling as far as permissions allow in the
260:                     * manager, and also set it here for gating purposes
261:                     */
262:                    vmManager.setNamespaceUsage(true);
263:
264:                    /*
265:                     *  template-local inline VM mode : default is off
266:                     */
267:                    setTemplateLocalInline(rsvc.getBoolean(
268:                            RuntimeConstants.VM_PERM_INLINE_LOCAL, false));
269:
270:                    if (getTemplateLocalInline()) {
271:                        log
272:                                .info("allowInlineLocal = true : VMs "
273:                                        + "defined inline will be local to their defining template only.");
274:                    } else {
275:                        log
276:                                .debug("allowInlineLocal = false : VMs "
277:                                        + "defined inline will be global in scope if allowed.");
278:                    }
279:
280:                    vmManager
281:                            .setTemplateLocalInlineVM(getTemplateLocalInline());
282:
283:                    /*
284:                     *  autoload VM libraries
285:                     */
286:                    setAutoload(rsvc.getBoolean(
287:                            RuntimeConstants.VM_LIBRARY_AUTORELOAD, false));
288:
289:                    if (getAutoload()) {
290:                        log
291:                                .info("autoload on : VM system "
292:                                        + "will automatically reload global library macros");
293:                    } else {
294:                        log
295:                                .debug("autoload off : VM system "
296:                                        + "will not automatically reload global library macros");
297:                    }
298:
299:                    log.trace("Velocimacro : initialization complete.");
300:                }
301:            }
302:
303:            /**
304:             *  adds a macro to the factory.
305:             *
306:             * @param name Name of the Macro to add.
307:             * @param macroBody String representation of the macro.
308:             * @param argArray Macro arguments. First element is the macro name.
309:             * @param sourceTemplate Source template from which the macro gets registered.
310:             * @return True if Macro was registered successfully.
311:             */
312:            public boolean addVelocimacro(String name, String macroBody,
313:                    String argArray[], String sourceTemplate) {
314:                /*
315:                 * maybe we should throw an exception, maybe just tell
316:                 * the caller like this...
317:                 *
318:                 * I hate this : maybe exceptions are in order here...
319:                 */
320:                if (name == null || macroBody == null || argArray == null
321:                        || sourceTemplate == null) {
322:                    log
323:                            .warn("VM addition rejected : programmer error : arg null");
324:                    return false;
325:                }
326:
327:                /*
328:                 *  see if the current ruleset allows this addition
329:                 */
330:
331:                if (!canAddVelocimacro(name, sourceTemplate)) {
332:                    return false;
333:                }
334:
335:                /*
336:                 *  seems like all is good.  Lets do it.
337:                 */
338:                synchronized (this ) {
339:                    vmManager.addVM(name, macroBody, argArray, sourceTemplate);
340:                }
341:
342:                /*
343:                 * Report addition of the new Velocimacro.
344:                 */
345:                StringBuffer msg = new StringBuffer("added ");
346:                Macro.macroToString(msg, argArray);
347:                msg.append(" : source = ").append(sourceTemplate);
348:                log.info(msg.toString());
349:
350:                return true;
351:            }
352:
353:            /**
354:             *  determines if a given macro/namespace (name, source) combo is allowed
355:             *  to be added
356:             *
357:             *  @param name Name of VM to add
358:             *  @param sourceTemplate Source template that contains the defintion of the VM
359:             *  @return true if it is allowed to be added, false otherwise
360:             */
361:            private synchronized boolean canAddVelocimacro(String name,
362:                    String sourceTemplate) {
363:                /*
364:                 *  short circuit and do it if autoloader is on, and the
365:                 *  template is one of the library templates
366:                 */
367:
368:                if (getAutoload() && (macroLibVec != null)) {
369:                    /*
370:                     *  see if this is a library template
371:                     */
372:
373:                    for (int i = 0; i < macroLibVec.size(); i++) {
374:                        String lib = (String) macroLibVec.elementAt(i);
375:
376:                        if (lib.equals(sourceTemplate)) {
377:                            return true;
378:                        }
379:                    }
380:                }
381:
382:                /*
383:                 * maybe the rules should be in manager?  I dunno. It's to manage
384:                 * the namespace issues first, are we allowed to add VMs at all?
385:                 * This trumps all.
386:                 */
387:                if (!addNewAllowed) {
388:                    log.warn("VM addition rejected : " + name
389:                            + " : inline VMs not allowed.");
390:                    return false;
391:                }
392:
393:                /*
394:                 *  are they local in scope?  Then it is ok to add.
395:                 */
396:                if (!templateLocal) {
397:                    /*
398:                     * otherwise, if we have it already in global namespace, and they can't replace
399:                     * since local templates are not allowed, the global namespace is implied.
400:                     *  remember, we don't know anything about namespace managment here, so lets
401:                     *  note do anything fancy like trying to give it the global namespace here
402:                     *
403:                     *  so if we have it, and we aren't allowed to replace, bail
404:                     */
405:                    if (isVelocimacro(name, sourceTemplate) && !replaceAllowed) {
406:                        log
407:                                .warn("VM addition rejected : "
408:                                        + name
409:                                        + " : inline not allowed to replace existing VM");
410:                        return false;
411:                    }
412:                }
413:
414:                return true;
415:            }
416:
417:            /**
418:             *  Tells the world if a given directive string is a Velocimacro
419:             * @param vm Name of the Macro.
420:             * @param sourceTemplate Source template from which the macro should be loaded.
421:             * @return True if the given name is a macro.
422:             */
423:            public boolean isVelocimacro(String vm, String sourceTemplate) {
424:                synchronized (this ) {
425:                    /*
426:                     * first we check the locals to see if we have
427:                     * a local definition for this template
428:                     */
429:                    if (vmManager.get(vm, sourceTemplate) != null)
430:                        return true;
431:                }
432:                return false;
433:            }
434:
435:            /**
436:             *  actual factory : creates a Directive that will
437:             *  behave correctly wrt getting the framework to
438:             *  dig out the correct # of args
439:             * @param vmName Name of the Macro.
440:             * @param sourceTemplate Source template from which the macro should be loaded.
441:             * @return A directive representing the Macro.
442:             */
443:            public Directive getVelocimacro(String vmName, String sourceTemplate) {
444:                VelocimacroProxy vp = null;
445:
446:                synchronized (this ) {
447:                    /*
448:                     *  don't ask - do
449:                     */
450:
451:                    vp = vmManager.get(vmName, sourceTemplate);
452:
453:                    /*
454:                     *  if this exists, and autoload is on, we need to check
455:                     *  where this VM came from
456:                     */
457:
458:                    if (vp != null && getAutoload()) {
459:                        /*
460:                         *  see if this VM came from a library.  Need to pass sourceTemplate
461:                         *  in the event namespaces are set, as it could be masked by local
462:                         */
463:
464:                        String lib = vmManager.getLibraryName(vmName,
465:                                sourceTemplate);
466:
467:                        if (lib != null) {
468:                            try {
469:                                /*
470:                                 *  get the template from our map
471:                                 */
472:
473:                                Twonk tw = (Twonk) libModMap.get(lib);
474:
475:                                if (tw != null) {
476:                                    Template template = tw.template;
477:
478:                                    /*
479:                                     *  now, compare the last modified time of the resource
480:                                     *  with the last modified time of the template
481:                                     *  if the file has changed, then reload. Otherwise, we should
482:                                     *  be ok.
483:                                     */
484:
485:                                    long tt = tw.modificationTime;
486:                                    long ft = template.getResourceLoader()
487:                                            .getLastModified(template);
488:
489:                                    if (ft > tt) {
490:                                        log
491:                                                .debug("auto-reloading VMs from VM library : "
492:                                                        + lib);
493:
494:                                        /*
495:                                         *  when there are VMs in a library that invoke each other,
496:                                         *  there are calls into getVelocimacro() from the init()
497:                                         *  process of the VM directive.  To stop the infinite loop
498:                                         *  we save the current time reported by the resource loader
499:                                         *  and then be honest when the reload is complete
500:                                         */
501:
502:                                        tw.modificationTime = ft;
503:
504:                                        template = rsvc.getTemplate(lib);
505:
506:                                        /*
507:                                         * and now we be honest
508:                                         */
509:
510:                                        tw.template = template;
511:                                        tw.modificationTime = template
512:                                                .getLastModified();
513:
514:                                        /*
515:                                         *  note that we don't need to put this twonk back
516:                                         *  into the map, as we can just use the same reference
517:                                         *  and this block is synchronized
518:                                         */
519:                                    }
520:                                }
521:                            } catch (Exception e) {
522:                                log.error(true,
523:                                        "Velocimacro : Error using VM library : "
524:                                                + lib, e);
525:                            }
526:
527:                            /*
528:                             *  and get again
529:                             */
530:
531:                            vp = vmManager.get(vmName, sourceTemplate);
532:                        }
533:                    }
534:                }
535:
536:                return vp;
537:            }
538:
539:            /**
540:             *  tells the vmManager to dump the specified namespace
541:             * @param namespace Namespace to dump.
542:             * @return True if namespace has been dumped successfully.
543:             */
544:            public boolean dumpVMNamespace(String namespace) {
545:                return vmManager.dumpNamespace(namespace);
546:            }
547:
548:            /**
549:             *  sets permission to have VMs local in scope to their declaring template
550:             *  note that this is really taken care of in the VMManager class, but
551:             *  we need it here for gating purposes in addVM
552:             *  eventually, I will slide this all into the manager, maybe.
553:             */
554:            private void setTemplateLocalInline(boolean b) {
555:                templateLocal = b;
556:            }
557:
558:            private boolean getTemplateLocalInline() {
559:                return templateLocal;
560:            }
561:
562:            /**
563:             *   sets the permission to add new macros
564:             */
565:            private boolean setAddMacroPermission(final boolean addNewAllowed) {
566:                boolean b = this .addNewAllowed;
567:                this .addNewAllowed = addNewAllowed;
568:                return b;
569:            }
570:
571:            /**
572:             *    sets the permission for allowing addMacro() calls to
573:             *    replace existing VM's
574:             */
575:            private boolean setReplacementPermission(boolean arg) {
576:                boolean b = replaceAllowed;
577:                replaceAllowed = arg;
578:                return b;
579:            }
580:
581:            /**
582:             *  set the switch for automatic reloading of
583:             *  global library-based VMs
584:             */
585:            private void setAutoload(boolean b) {
586:                autoReloadLibrary = b;
587:            }
588:
589:            /**
590:             *  get the switch for automatic reloading of
591:             *  global library-based VMs
592:             */
593:            private boolean getAutoload() {
594:                return autoReloadLibrary;
595:            }
596:
597:            /**
598:             * small container class to hold the tuple
599:             * of a template and modification time.
600:             * We keep the modification time so we can
601:             * 'override' it on a reload to prevent
602:             * recursive reload due to inter-calling
603:             * VMs in a library
604:             */
605:            private static class Twonk {
606:                /** Template kept in this container. */
607:                public Template template;
608:
609:                /** modification time of the template. */
610:                public long modificationTime;
611:            }
612:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.