KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > velocity > runtime > parser > node > ASTIdentifier


1 package org.apache.velocity.runtime.parser.node;
2
3 /*
4  * Copyright 2000-2002,2004 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 import org.apache.velocity.context.InternalContextAdapter;
20 import org.apache.velocity.runtime.parser.Parser;
21 import org.apache.velocity.util.introspection.IntrospectionCacheData;
22 import org.apache.velocity.util.introspection.Info;
23 import org.apache.velocity.util.introspection.VelPropertyGet;
24
25 import org.apache.velocity.exception.MethodInvocationException;
26 import org.apache.velocity.app.event.EventCartridge;
27
28 import java.lang.reflect.InvocationTargetException JavaDoc;
29
30 /**
31  * ASTIdentifier.java
32  *
33  * Method support for identifiers : $foo
34  *
35  * mainly used by ASTRefrence
36  *
37  * Introspection is now moved to 'just in time' or at render / execution
38  * time. There are many reasons why this has to be done, but the
39  * primary two are thread safety, to remove any context-derived
40  * information from class member variables.
41  *
42  * @author <a HREF="mailto:jvanzyl@apache.org">Jason van Zyl</a>
43  * @author <a HREF="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
44  * @version $Id: ASTIdentifier.java,v 1.19.4.1 2004/03/03 23:22:58 geirm Exp $
45  */

46 public class ASTIdentifier extends SimpleNode
47 {
48     private String JavaDoc identifier = "";
49
50     /**
51      * This is really immutable after the init, so keep one for this node
52      */

53     protected Info uberInfo;
54
55     public ASTIdentifier(int id)
56     {
57         super(id);
58     }
59
60     public ASTIdentifier(Parser p, int id)
61     {
62         super(p, id);
63     }
64
65     /** Accept the visitor. **/
66     public Object JavaDoc jjtAccept(ParserVisitor visitor, Object JavaDoc data)
67     {
68         return visitor.visit(this, data);
69     }
70
71     /**
72      * simple init - don't do anything that is context specific.
73      * just get what we need from the AST, which is static.
74      */

75     public Object JavaDoc init(InternalContextAdapter context, Object JavaDoc data)
76         throws Exception JavaDoc
77     {
78         super.init(context, data);
79
80         identifier = getFirstToken().image;
81
82         uberInfo = new Info(context.getCurrentTemplateName(),
83                 getLine(), getColumn());
84
85         return data;
86     }
87
88     /**
89      * invokes the method on the object passed in
90      */

91     public Object JavaDoc execute(Object JavaDoc o, InternalContextAdapter context)
92         throws MethodInvocationException
93     {
94
95         VelPropertyGet vg = null;
96
97         try
98         {
99             Class JavaDoc c = o.getClass();
100
101             /*
102              * first, see if we have this information cached.
103              */

104
105             IntrospectionCacheData icd = context.icacheGet(this);
106
107             /*
108              * if we have the cache data and the class of the object we are
109              * invoked with is the same as that in the cache, then we must
110              * be allright. The last 'variable' is the method name, and
111              * that is fixed in the template :)
112              */

113
114             if (icd != null && icd.contextData == c)
115             {
116                 vg = (VelPropertyGet) icd.thingy;
117             }
118             else
119             {
120                 /*
121                  * otherwise, do the introspection, and cache it. Use the
122                  * uberspector
123                  */

124
125                 vg = rsvc.getUberspect().getPropertyGet(o,identifier, uberInfo);
126
127                 if (vg != null && vg.isCacheable())
128                 {
129                     icd = new IntrospectionCacheData();
130                     icd.contextData = c;
131                     icd.thingy = vg;
132                     context.icachePut(this,icd);
133                 }
134             }
135         }
136         catch(Exception JavaDoc e)
137         {
138             rsvc.error("ASTIdentifier.execute() : identifier = "
139                                + identifier + " : " + e);
140         }
141
142         /*
143          * we have no getter... punt...
144          */

145
146         if (vg == null)
147         {
148             return null;
149         }
150
151         /*
152          * now try and execute. If we get a MIE, throw that
153          * as the app wants to get these. If not, log and punt.
154          */

155         try
156         {
157             return vg.invoke(o);
158         }
159         catch(InvocationTargetException JavaDoc ite)
160         {
161             EventCartridge ec = context.getEventCartridge();
162
163             /*
164              * if we have an event cartridge, see if it wants to veto
165              * also, let non-Exception Throwables go...
166              */

167
168             if (ec != null
169                     && ite.getTargetException() instanceof java.lang.Exception JavaDoc)
170             {
171                 try
172                 {
173                     return ec.methodException(o.getClass(), vg.getMethodName(),
174                             (Exception JavaDoc)ite.getTargetException());
175                 }
176                 catch(Exception JavaDoc e)
177                 {
178                     throw new MethodInvocationException(
179                       "Invocation of method '" + vg.getMethodName() + "'"
180                       + " in " + o.getClass()
181                       + " threw exception "
182                       + ite.getTargetException().getClass() + " : "
183                       + ite.getTargetException().getMessage(),
184                       ite.getTargetException(), vg.getMethodName());
185                 }
186             }
187             else
188             {
189                 /*
190                  * no event cartridge to override. Just throw
191                  */

192
193                 throw new MethodInvocationException(
194                 "Invocation of method '" + vg.getMethodName() + "'"
195                 + " in " + o.getClass()
196                 + " threw exception "
197                 + ite.getTargetException().getClass() + " : "
198                 + ite.getTargetException().getMessage(),
199                 ite.getTargetException(), vg.getMethodName());
200
201
202             }
203         }
204         catch(IllegalArgumentException JavaDoc iae)
205         {
206             return null;
207         }
208         catch(Exception JavaDoc e)
209         {
210             rsvc.error("ASTIdentifier() : exception invoking method "
211                         + "for identifier '" + identifier + "' in "
212                         + o.getClass() + " : " + e);
213         }
214
215         return null;
216     }
217 }
218
Popular Tags