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


001:        package org.apache.velocity.runtime.parser.node;
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.lang.reflect.InvocationTargetException;
023:
024:        import org.apache.commons.lang.ArrayUtils;
025:        import org.apache.commons.lang.StringUtils;
026:        import org.apache.velocity.app.event.EventHandlerUtil;
027:        import org.apache.velocity.context.InternalContextAdapter;
028:        import org.apache.velocity.exception.MethodInvocationException;
029:        import org.apache.velocity.exception.TemplateInitException;
030:        import org.apache.velocity.runtime.parser.Parser;
031:        import org.apache.velocity.runtime.parser.ParserVisitor;
032:        import org.apache.velocity.util.introspection.Info;
033:        import org.apache.velocity.util.introspection.IntrospectionCacheData;
034:        import org.apache.velocity.util.introspection.VelMethod;
035:
036:        /**
037:         *  ASTMethod.java
038:         *
039:         *  Method support for references :  $foo.method()
040:         *
041:         *  NOTE :
042:         *
043:         *  introspection is now done at render time.
044:         *
045:         *  Please look at the Parser.jjt file which is
046:         *  what controls the generation of this class.
047:         *
048:         * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
049:         * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
050:         * @version $Id: ASTMethod.java 489650 2006-12-22 13:31:58Z cbrisson $
051:         */
052:        public class ASTMethod extends SimpleNode {
053:            private String methodName = "";
054:            private int paramCount = 0;
055:
056:            protected Info uberInfo;
057:
058:            /**
059:             * @param id
060:             */
061:            public ASTMethod(int id) {
062:                super (id);
063:            }
064:
065:            /**
066:             * @param p
067:             * @param id
068:             */
069:            public ASTMethod(Parser p, int id) {
070:                super (p, id);
071:            }
072:
073:            /**
074:             * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.ParserVisitor, java.lang.Object)
075:             */
076:            public Object jjtAccept(ParserVisitor visitor, Object data) {
077:                return visitor.visit(this , data);
078:            }
079:
080:            /**
081:             *  simple init - init our subtree and get what we can from
082:             *  the AST
083:             * @param context
084:             * @param data
085:             * @return The init result
086:             * @throws TemplateInitException
087:             */
088:            public Object init(InternalContextAdapter context, Object data)
089:                    throws TemplateInitException {
090:                super .init(context, data);
091:
092:                /*
093:                 * make an uberinfo - saves new's later on
094:                 */
095:
096:                uberInfo = new Info(context.getCurrentTemplateName(),
097:                        getLine(), getColumn());
098:                /*
099:                 *  this is about all we can do
100:                 */
101:
102:                methodName = getFirstToken().image;
103:                paramCount = jjtGetNumChildren() - 1;
104:
105:                return data;
106:            }
107:
108:            /**
109:             *  invokes the method.  Returns null if a problem, the
110:             *  actual return if the method returns something, or
111:             *  an empty string "" if the method returns void
112:             * @param o
113:             * @param context
114:             * @return Result or null.
115:             * @throws MethodInvocationException
116:             */
117:            public Object execute(Object o, InternalContextAdapter context)
118:                    throws MethodInvocationException {
119:                /*
120:                 *  new strategy (strategery!) for introspection. Since we want
121:                 *  to be thread- as well as context-safe, we *must* do it now,
122:                 *  at execution time.  There can be no in-node caching,
123:                 *  but if we are careful, we can do it in the context.
124:                 */
125:
126:                VelMethod method = null;
127:
128:                Object[] params = new Object[paramCount];
129:
130:                try {
131:                    /*
132:                     * sadly, we do need recalc the values of the args, as this can
133:                     * change from visit to visit
134:                     */
135:
136:                    final Class[] paramClasses = paramCount > 0 ? new Class[paramCount]
137:                            : ArrayUtils.EMPTY_CLASS_ARRAY;
138:
139:                    for (int j = 0; j < paramCount; j++) {
140:                        params[j] = jjtGetChild(j + 1).value(context);
141:
142:                        if (params[j] != null) {
143:                            paramClasses[j] = params[j].getClass();
144:                        }
145:                    }
146:
147:                    /*
148:                     *   check the cache
149:                     */
150:
151:                    MethodCacheKey mck = new MethodCacheKey(methodName,
152:                            paramClasses);
153:                    IntrospectionCacheData icd = context.icacheGet(mck);
154:
155:                    /*
156:                     *  like ASTIdentifier, if we have cache information, and the
157:                     *  Class of Object o is the same as that in the cache, we are
158:                     *  safe.
159:                     */
160:
161:                    if (icd != null
162:                            && (o != null && icd.contextData == o.getClass())) {
163:
164:                        /*
165:                         * get the method from the cache
166:                         */
167:
168:                        method = (VelMethod) icd.thingy;
169:                    } else {
170:                        /*
171:                         *  otherwise, do the introspection, and then
172:                         *  cache it
173:                         */
174:
175:                        method = rsvc.getUberspect().getMethod(
176:                                o,
177:                                methodName,
178:                                params,
179:                                new Info(context.getCurrentTemplateName(),
180:                                        getLine(), getColumn()));
181:
182:                        if ((method != null) && (o != null)) {
183:                            icd = new IntrospectionCacheData();
184:                            icd.contextData = o.getClass();
185:                            icd.thingy = method;
186:
187:                            context.icachePut(mck, icd);
188:                        }
189:                    }
190:
191:                    /*
192:                     *  if we still haven't gotten the method, either we are calling
193:                     *  a method that doesn't exist (which is fine...)  or I screwed
194:                     *  it up.
195:                     */
196:
197:                    if (method == null) {
198:                        return null;
199:                    }
200:                } catch (MethodInvocationException mie) {
201:                    /*
202:                     *  this can come from the doIntrospection(), as the arg values
203:                     *  are evaluated to find the right method signature.  We just
204:                     *  want to propogate it here, not do anything fancy
205:                     */
206:
207:                    throw mie;
208:                }
209:                /**
210:                 * pass through application level runtime exceptions
211:                 */
212:                catch (RuntimeException e) {
213:                    throw e;
214:                } catch (Exception e) {
215:                    /*
216:                     *  can come from the doIntropection() also, from Introspector
217:                     */
218:
219:                    log
220:                            .error(
221:                                    "ASTMethod.execute() : exception from introspection",
222:                                    e);
223:                    return null;
224:                }
225:
226:                try {
227:                    /*
228:                     *  get the returned object.  It may be null, and that is
229:                     *  valid for something declared with a void return type.
230:                     *  Since the caller is expecting something to be returned,
231:                     *  as long as things are peachy, we can return an empty
232:                     *  String so ASTReference() correctly figures out that
233:                     *  all is well.
234:                     */
235:
236:                    Object obj = method.invoke(o, params);
237:
238:                    if (obj == null) {
239:                        if (method.getReturnType() == Void.TYPE) {
240:                            return "";
241:                        }
242:                    }
243:
244:                    return obj;
245:                } catch (InvocationTargetException ite) {
246:                    /*
247:                     *  In the event that the invocation of the method
248:                     *  itself throws an exception, we want to catch that
249:                     *  wrap it, and throw.  We don't log here as we want to figure
250:                     *  out which reference threw the exception, so do that
251:                     *  above
252:                     */
253:
254:                    /*
255:                     *  let non-Exception Throwables go...
256:                     */
257:
258:                    Throwable t = ite.getTargetException();
259:                    if (t instanceof  Exception) {
260:                        try {
261:                            return EventHandlerUtil.methodException(rsvc,
262:                                    context, o.getClass(), methodName,
263:                                    (Exception) t);
264:                        }
265:
266:                        /**
267:                         * If the event handler throws an exception, then wrap it
268:                         * in a MethodInvocationException.  Don't pass through RuntimeExceptions like other
269:                         * similar catchall code blocks.
270:                         */
271:                        catch (Exception e) {
272:                            throw new MethodInvocationException(
273:                                    "Invocation of method '" + methodName
274:                                            + "' in  " + o.getClass()
275:                                            + " threw exception "
276:                                            + e.toString(), e, methodName,
277:                                    context.getCurrentTemplateName(), this 
278:                                            .getLine(), this .getColumn());
279:                        }
280:                    } else {
281:                        /*
282:                         * no event cartridge to override. Just throw
283:                         */
284:
285:                        throw new MethodInvocationException(
286:                                "Invocation of method '" + methodName
287:                                        + "' in  " + o.getClass()
288:                                        + " threw exception "
289:                                        + ite.getTargetException().toString(),
290:                                ite.getTargetException(), methodName, context
291:                                        .getCurrentTemplateName(), this 
292:                                        .getLine(), this .getColumn());
293:                    }
294:                }
295:                /**
296:                 * pass through application level runtime exceptions
297:                 */
298:                catch (RuntimeException e) {
299:                    throw e;
300:                } catch (Exception e) {
301:                    log.error(
302:                            "ASTMethod.execute() : exception invoking method '"
303:                                    + methodName + "' in " + o.getClass(), e);
304:                    return null;
305:                }
306:            }
307:
308:            /**
309:             * Internal class used as key for method cache.  Combines
310:             * ASTMethod fields with array of parameter classes.  Has
311:             * public access (and complete constructor) for unit test 
312:             * purposes.
313:             */
314:            public static class MethodCacheKey {
315:                private final String methodName;
316:                private final Class[] params;
317:
318:                public MethodCacheKey(String methodName, Class[] params) {
319:                    /** 
320:                     * Should never be initialized with nulls, but to be safe we refuse 
321:                     * to accept them.
322:                     */
323:                    this .methodName = (methodName != null) ? methodName
324:                            : StringUtils.EMPTY;
325:                    this .params = (params != null) ? params
326:                            : ArrayUtils.EMPTY_CLASS_ARRAY;
327:                }
328:
329:                /**
330:                 * @see java.lang.Object#equals(java.lang.Object)
331:                 */
332:                public boolean equals(Object o) {
333:                    /** 
334:                     * note we skip the null test for methodName and params
335:                     * due to the earlier test in the constructor
336:                     */
337:                    if (o instanceof  MethodCacheKey) {
338:                        final MethodCacheKey other = (MethodCacheKey) o;
339:                        if (params.length == other.params.length
340:                                && methodName.equals(other.methodName)) {
341:                            for (int i = 0; i < params.length; ++i) {
342:                                if (params[i] == null) {
343:                                    if (params[i] != other.params[i]) {
344:                                        return false;
345:                                    }
346:                                } else if (!params[i].equals(other.params[i])) {
347:                                    return false;
348:                                }
349:                            }
350:                            return true;
351:                        }
352:                    }
353:                    return false;
354:                }
355:
356:                /**
357:                 * @see java.lang.Object#hashCode()
358:                 */
359:                public int hashCode() {
360:                    int result = 17;
361:
362:                    /** 
363:                     * note we skip the null test for methodName and params
364:                     * due to the earlier test in the constructor
365:                     */
366:                    for (int i = 0; i < params.length; ++i) {
367:                        final Class param = params[i];
368:                        if (param != null) {
369:                            result = result * 37 + param.hashCode();
370:                        }
371:                    }
372:
373:                    result = result * 37 + methodName.hashCode();
374:
375:                    return result;
376:                }
377:            }
378:
379:            /**
380:             * @return Returns the methodName.
381:             */
382:            public String getMethodName() {
383:                return methodName;
384:            }
385:
386:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.