Source Code Cross Referenced for VMProxyArg.java in  » Template-Engine » Velocity » org » apache » velocity » runtime » directive » 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.directive 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.apache.velocity.runtime.directive;
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.io.BufferedReader;
023:        import java.io.StringReader;
024:        import java.io.StringWriter;
025:
026:        import org.apache.velocity.VelocityContext;
027:        import org.apache.velocity.context.InternalContextAdapter;
028:        import org.apache.velocity.context.InternalContextAdapterImpl;
029:        import org.apache.velocity.exception.MethodInvocationException;
030:        import org.apache.velocity.runtime.RuntimeServices;
031:        import org.apache.velocity.runtime.log.Log;
032:        import org.apache.velocity.runtime.parser.ParserTreeConstants;
033:        import org.apache.velocity.runtime.parser.node.ASTReference;
034:        import org.apache.velocity.runtime.parser.node.SimpleNode;
035:
036:        /**
037:         *  The function of this class is to proxy for the calling parameter to the VM.
038:         *
039:         *  This class is designed to be used in conjunction with the VMContext class
040:         *  which knows how to get and set values via it, rather than a simple get()
041:         *  or put() from a hashtable-like object.
042:         *
043:         *  There is probably a lot of undocumented subtlty here, so step lightly.
044:         *
045:         *  We rely on the observation that an instance of this object has a constant
046:         *  state throughout its lifetime as it's bound to the use-instance of a VM.
047:         *  In other words, it's created by the VelocimacroProxy class, to represent
048:         *  one of the arguments to a VM in a specific template.  Since the template
049:         *  is fixed (it's a file...), we don't have to worry that the args to the VM
050:         *  will change.  Yes, the VM will be called in other templates, or in other
051:         *  places on the same template, bit those are different use-instances.
052:         *
053:         *  These arguments can be, in the lingo of
054:         *  the parser, one of :
055:         *   <ul>
056:         *   <li> Reference() : anything that starts with '$'
057:         *   <li> StringLiteral() : something like "$foo" or "hello geir"
058:         *   <li> IntegerLiteral() : 1, 2 etc
059:         *   <li> FloatingPointLiteral() : 1.2, 2e5 etc
060:         *   <li> IntegerRange() : [ 1..2] or [$foo .. $bar]
061:         *   <li> ObjectArray() : [ "a", "b", "c"]
062:         *   <li> True() : true
063:         *   <li> False() : false
064:         *    <li>Word() : not likely - this is simply allowed by the parser so we can have
065:         *             syntactical sugar like #foreach($a in $b)  where 'in' is the Word
066:         *    </ul>
067:         *  Now, Reference(), StringLit, IntegerLiteral, IntRange, ObjArr are all dynamic things, so
068:         *  their value is gotten with the use of a context.  The others are constants.  The trick
069:         *  we rely on is that the context rather than this class really represents the
070:         *  state of the argument. We are simply proxying for the thing, returning the proper value
071:         *  when asked, and storing the proper value in the appropriate context when asked.
072:         *
073:         *  So, the hope here, so an instance of this can be shared across threads, is to
074:         *  keep any dynamic stuff out of it, relying on trick of having the appropriate
075:         *  context handed to us, and when a constant argument, letting VMContext punch that
076:         *  into a local context.
077:         *
078:         *  @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
079:         *  @version $Id: VMProxyArg.java 473363 2006-11-10 15:19:09Z wglass $
080:         */
081:        public class VMProxyArg {
082:            /** in the event our type is switched - we don't care really what it is */
083:            private static final int GENERALSTATIC = -1;
084:
085:            /**  type of arg I will have */
086:            private int type = 0;
087:
088:            /**  the AST if the type is such that it's dynamic (ex. JJTREFERENCE ) */
089:            private SimpleNode nodeTree = null;
090:
091:            /**  reference for the object if we proxy for a static arg like an IntegerLiteral*/
092:            private Object staticObject = null;
093:
094:            /** number of children in our tree if a reference */
095:            private int numTreeChildren = 0;
096:
097:            /** our identity in the current context */
098:            private String contextReference = null;
099:
100:            /** the reference we are proxying for  */
101:            private String callerReference = null;
102:
103:            /** the 'de-dollared' reference if we are a ref but don't have a method attached */
104:            private String singleLevelRef = null;
105:
106:            /** by default, we are dynamic.  safest */
107:            private boolean constant = false;
108:
109:            private RuntimeServices rsvc = null;
110:            private Log log = null;
111:
112:            /**
113:             *  ctor for current impl
114:             *
115:             *  takes the reference literal we are proxying for, the literal
116:             *  the VM we are for is called with...
117:             * @param rs
118:             *
119:             *  @param contextRef reference arg in the definition of the VM, used in the VM
120:             *  @param callerRef  reference used by the caller as an arg to the VM
121:             *  @param t  type of arg : JJTREFERENCE, JJTTRUE, etc
122:             */
123:            public VMProxyArg(RuntimeServices rs, String contextRef,
124:                    String callerRef, int t) {
125:                rsvc = rs;
126:                log = rsvc.getLog();
127:
128:                contextReference = contextRef;
129:                callerReference = callerRef;
130:                type = t;
131:
132:                /*
133:                 *  make our AST if necessary
134:                 */
135:                setup();
136:
137:                /*
138:                 *  if we are multi-node tree, then save the size to
139:                 *  avoid fn call overhead
140:                 */
141:                if (nodeTree != null) {
142:                    numTreeChildren = nodeTree.jjtGetNumChildren();
143:                }
144:
145:                /*
146:                 *  if we are a reference, and 'scalar' (i.e. $foo )
147:                 *  then get the de-dollared ref so we can
148:                 *  hit our context directly, avoiding the AST
149:                 */
150:                if (type == ParserTreeConstants.JJTREFERENCE) {
151:                    if (numTreeChildren == 0) {
152:                        /*
153:                         * do this properly and use the Reference node
154:                         */
155:                        singleLevelRef = ((ASTReference) nodeTree)
156:                                .getRootString();
157:                    }
158:                }
159:            }
160:
161:            /**
162:             *  tells if arg we are poxying for is
163:             *  dynamic or constant.
164:             *
165:             *  @return true of constant, false otherwise
166:             */
167:            public boolean isConstant() {
168:                return constant;
169:            }
170:
171:            /**
172:             *  Invoked by VMContext when Context.put() is called for a proxied reference.
173:             *
174:             *  @param context context to modify via direct placement, or AST.setValue()
175:             *  @param o  new value of reference
176:             *  @return Object currently null
177:             */
178:            public Object setObject(InternalContextAdapter context, Object o) {
179:                /*
180:                 *  if we are a reference, we could be updating a property
181:                 */
182:
183:                if (type == ParserTreeConstants.JJTREFERENCE) {
184:                    if (numTreeChildren > 0) {
185:                        /*
186:                         *  we are a property, and being updated such as
187:                         *  #foo( $bar.BangStart)
188:                         */
189:
190:                        try {
191:                            ((ASTReference) nodeTree).setValue(context, o);
192:                        } catch (MethodInvocationException mie) {
193:                            log
194:                                    .error(
195:                                            "VMProxyArg.getObject() : method invocation error setting value",
196:                                            mie);
197:                        }
198:                    } else {
199:                        /*
200:                         *  we are a 'single level' reference like $foo, so we can set
201:                         *  out context directly
202:                         */
203:
204:                        context.put(singleLevelRef, o);
205:
206:                        // alternate impl : usercontext.put( singleLevelRef, o);
207:                    }
208:                } else {
209:                    /*
210:                     *  if we aren't a reference, then we simply switch type,
211:                     *  get a new value, and it doesn't go into the context
212:                     *
213:                     *  in current impl, this shouldn't happen.
214:                     */
215:
216:                    type = GENERALSTATIC;
217:                    staticObject = o;
218:
219:                    log
220:                            .error("VMProxyArg.setObject() : Programmer error : I am a constant!  No setting! : "
221:                                    + contextReference
222:                                    + " / "
223:                                    + callerReference);
224:                }
225:
226:                return null;
227:            }
228:
229:            /**
230:             *  returns the value of the reference.  Generally, this is only
231:             *  called for dynamic proxies, as the static ones should have
232:             *  been stored in the VMContext's localcontext store
233:             *
234:             *  @param context Context to use for getting current value
235:             *  @return Object value
236:             * @exception MethodInvocationException passes on potential exception from reference method call
237:             */
238:            public Object getObject(InternalContextAdapter context)
239:                    throws MethodInvocationException {
240:                try {
241:
242:                    /*
243:                     *  we need to output based on our type
244:                     */
245:
246:                    Object retObject = null;
247:
248:                    if (type == ParserTreeConstants.JJTREFERENCE) {
249:                        /*
250:                         *  two     cases :  scalar reference ($foo) or multi-level ($foo.bar....)
251:                         */
252:
253:                        if (numTreeChildren == 0) {
254:                            /*
255:                             *  if I am a single-level reference, can I not get get it out of my context?
256:                             */
257:
258:                            retObject = context.get(singleLevelRef);
259:                        } else {
260:                            /*
261:                             *  I need to let the AST produce it for me.
262:                             */
263:
264:                            retObject = nodeTree.execute(null, context);
265:                        }
266:                    } else if (type == ParserTreeConstants.JJTMAP) {
267:                        retObject = nodeTree.value(context);
268:                    } else if (type == ParserTreeConstants.JJTOBJECTARRAY) {
269:                        retObject = nodeTree.value(context);
270:                    } else if (type == ParserTreeConstants.JJTINTEGERRANGE) {
271:                        retObject = nodeTree.value(context);
272:                    } else if (type == ParserTreeConstants.JJTTRUE) {
273:                        retObject = staticObject;
274:                    } else if (type == ParserTreeConstants.JJTFALSE) {
275:                        retObject = staticObject;
276:                    } else if (type == ParserTreeConstants.JJTSTRINGLITERAL) {
277:                        retObject = nodeTree.value(context);
278:                    } else if (type == ParserTreeConstants.JJTINTEGERLITERAL) {
279:                        retObject = staticObject;
280:                    } else if (type == ParserTreeConstants.JJTFLOATINGPOINTLITERAL) {
281:                        retObject = staticObject;
282:                    } else if (type == ParserTreeConstants.JJTTEXT) {
283:                        /*
284:                         *  this really shouldn't happen.  text is just a thowaway arg for #foreach()
285:                         */
286:
287:                        try {
288:                            StringWriter writer = new StringWriter();
289:                            nodeTree.render(context, writer);
290:
291:                            retObject = writer;
292:                        }
293:                        /**
294:                         * pass through application level runtime exceptions
295:                         */
296:                        catch (RuntimeException e) {
297:                            throw e;
298:                        } catch (Exception e) {
299:                            log
300:                                    .error(
301:                                            "VMProxyArg.getObject() : error rendering reference",
302:                                            e);
303:                        }
304:                    } else if (type == GENERALSTATIC) {
305:                        retObject = staticObject;
306:                    } else {
307:                        log.error("Unsupported VM arg type : VM arg = "
308:                                + callerReference + " type = " + type
309:                                + "( VMProxyArg.getObject() )");
310:                    }
311:
312:                    return retObject;
313:                } catch (MethodInvocationException mie) {
314:                    /*
315:                     *  not ideal, but otherwise we propogate out to the
316:                     *  VMContext, and the Context interface's put/get
317:                     *  don't throw. So this is a the best compromise
318:                     *  I can think of
319:                     */
320:
321:                    log
322:                            .error(
323:                                    "VMProxyArg.getObject() : method invocation error getting value",
324:                                    mie);
325:                    throw mie;
326:                }
327:            }
328:
329:            /**
330:             *  does the housekeeping upon creationg.  If a dynamic type
331:             *  it needs to make an AST for further get()/set() operations
332:             *  Anything else is constant.
333:             */
334:            private void setup() {
335:                switch (type) {
336:
337:                case ParserTreeConstants.JJTINTEGERRANGE:
338:                case ParserTreeConstants.JJTREFERENCE:
339:                case ParserTreeConstants.JJTOBJECTARRAY:
340:                case ParserTreeConstants.JJTMAP:
341:                case ParserTreeConstants.JJTSTRINGLITERAL:
342:                case ParserTreeConstants.JJTTEXT: {
343:                    /*
344:                     *  dynamic types, just render
345:                     */
346:
347:                    constant = false;
348:
349:                    try {
350:                        /*
351:                         *  fakie : wrap in  directive to get the parser to treat our args as args
352:                         *   it doesn't matter that #include() can't take all these types, because we
353:                         *   just want the parser to consider our arg as a Directive/VM arg rather than
354:                         *   as if inline in schmoo
355:                         */
356:
357:                        String buff = "#include(" + callerReference + " ) ";
358:
359:                        //ByteArrayInputStream inStream = new ByteArrayInputStream( buff.getBytes() );
360:
361:                        BufferedReader br = new BufferedReader(
362:                                new StringReader(buff));
363:
364:                        nodeTree = rsvc.parse(br, "VMProxyArg:"
365:                                + callerReference, true);
366:
367:                        /*
368:                         *  now, our tree really is the first DirectiveArg(), and only one
369:                         */
370:
371:                        nodeTree = (SimpleNode) nodeTree.jjtGetChild(0)
372:                                .jjtGetChild(0);
373:
374:                        /*
375:                         * sanity check
376:                         */
377:                        if (nodeTree != null) {
378:                            if (nodeTree.getType() != type) {
379:                                log
380:                                        .error("VMProxyArg.setup() : programmer error : type doesn't match node type.");
381:                            }
382:
383:                            /*
384:                             *  init.  be a good citizen and give it an ICA
385:                             */
386:
387:                            InternalContextAdapter ica = new InternalContextAdapterImpl(
388:                                    new VelocityContext());
389:
390:                            ica.pushCurrentTemplateName("VMProxyArg : "
391:                                    + ParserTreeConstants.jjtNodeName[type]);
392:
393:                            nodeTree.init(ica, rsvc);
394:                        }
395:                    }
396:                    /**
397:                     * pass through application level runtime exceptions
398:                     */
399:                    catch (RuntimeException e) {
400:                        throw e;
401:                    } catch (Exception e) {
402:                        log.error("VMProxyArg.setup() : exception "
403:                                + callerReference, e);
404:                    }
405:
406:                    break;
407:                }
408:
409:                case ParserTreeConstants.JJTTRUE: {
410:                    constant = true;
411:                    staticObject = Boolean.TRUE;
412:                    break;
413:                }
414:
415:                case ParserTreeConstants.JJTFALSE: {
416:                    constant = true;
417:                    staticObject = Boolean.FALSE;
418:                    break;
419:                }
420:
421:                case ParserTreeConstants.JJTINTEGERLITERAL: {
422:                    constant = true;
423:                    staticObject = new Integer(callerReference);
424:                    break;
425:                }
426:
427:                case ParserTreeConstants.JJTFLOATINGPOINTLITERAL: {
428:                    constant = true;
429:                    staticObject = new Double(callerReference);
430:                    break;
431:                }
432:
433:                case ParserTreeConstants.JJTWORD: {
434:                    /*
435:                     *  this is technically an error...
436:                     */
437:
438:                    log
439:                            .error("Unsupported arg type : "
440:                                    + callerReference
441:                                    + " You most likely intended to call a VM with a string literal, so enclose with ' or \" characters. (VMProxyArg.setup())");
442:                    constant = true;
443:                    staticObject = callerReference;
444:
445:                    break;
446:                }
447:
448:                default: {
449:                    log.error("VMProxyArg.setup() : unsupported type : "
450:                            + callerReference);
451:                }
452:                }
453:            }
454:
455:            /*
456:             * CODE FOR ALTERNATE IMPL : please ignore.  I will remove when confortable with current.
457:             */
458:
459:            /**
460:             *  not used in current impl
461:             *
462:             *  Constructor for alternate impl where VelProxy class would make new
463:             *  VMProxyArg objects, and use this contructor to avoid reparsing the
464:             *  reference args
465:             *
466:             *  that impl also had the VMProxyArg carry it's context.
467:             * @param model
468:             * @param c
469:             */
470:            public VMProxyArg(VMProxyArg model, InternalContextAdapter c) {
471:                contextReference = model.getContextReference();
472:                callerReference = model.getCallerReference();
473:                nodeTree = model.getNodeTree();
474:                staticObject = model.getStaticObject();
475:                type = model.getType();
476:
477:                if (nodeTree != null)
478:                    numTreeChildren = nodeTree.jjtGetNumChildren();
479:
480:                if (type == ParserTreeConstants.JJTREFERENCE) {
481:                    if (numTreeChildren == 0) {
482:                        /*
483:                         *  use the reference node to do this...
484:                         */
485:                        singleLevelRef = ((ASTReference) nodeTree)
486:                                .getRootString();
487:                    }
488:                }
489:            }
490:
491:            /**
492:             * @return The caller reference.
493:             */
494:            public String getCallerReference() {
495:                return callerReference;
496:            }
497:
498:            /**
499:             * @return The context reference.
500:             */
501:            public String getContextReference() {
502:                return contextReference;
503:            }
504:
505:            /**
506:             * @return The node tree.
507:             */
508:            public SimpleNode getNodeTree() {
509:                return nodeTree;
510:            }
511:
512:            /**
513:             * @return The static object.
514:             */
515:            public Object getStaticObject() {
516:                return staticObject;
517:            }
518:
519:            /**
520:             * @return The type.
521:             */
522:            public int getType() {
523:                return type;
524:            }
525:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.