KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > velocity > util > introspection > UberspectImpl


1 package org.apache.velocity.util.introspection;
2
3 /*
4  * Copyright 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.util.ArrayIterator;
20 import org.apache.velocity.util.EnumerationIterator;
21 import org.apache.velocity.runtime.RuntimeServices;
22 import org.apache.velocity.runtime.RuntimeLogger;
23 import org.apache.velocity.runtime.parser.node.AbstractExecutor;
24 import org.apache.velocity.runtime.parser.node.PropertyExecutor;
25 import org.apache.velocity.runtime.parser.node.GetExecutor;
26 import org.apache.velocity.runtime.parser.node.BooleanPropertyExecutor;
27
28 import java.lang.reflect.Method JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.Collection JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.Enumeration JavaDoc;
33 import java.util.ArrayList JavaDoc;
34
35 /**
36  * Implementation of Uberspect to provide the default introspective
37  * functionality of Velocity
38  *
39  * @author <a HREF="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
40  * @version $Id: UberspectImpl.java,v 1.2.4.1 2004/03/03 23:23:08 geirm Exp $
41  */

42 public class UberspectImpl implements Uberspect, UberspectLoggable
43 {
44     /**
45      * Our runtime logger.
46      */

47     private RuntimeLogger rlog;
48
49     /**
50      * the default Velocity introspector
51      */

52     private static Introspector introspector;
53
54     /**
55      * init - does nothing - we need to have setRuntimeLogger
56      * called before getting our introspector, as the default
57      * vel introspector depends upon it.
58      */

59     public void init()
60         throws Exception JavaDoc
61     {
62     }
63
64     /**
65      * Sets the runtime logger - this must be called before anything
66      * else besides init() as to get the logger. Makes the pull
67      * model appealing...
68      */

69     public void setRuntimeLogger(RuntimeLogger runtimeLogger)
70     {
71         rlog = runtimeLogger;
72         introspector = new Introspector(rlog);
73     }
74
75     /**
76      * To support iteratives - #foreach()
77      */

78     public Iterator getIterator(Object JavaDoc obj, Info i)
79             throws Exception JavaDoc
80     {
81         if (obj.getClass().isArray())
82         {
83             return new ArrayIterator(obj);
84         }
85         else if (obj instanceof Collection JavaDoc)
86         {
87             return ((Collection JavaDoc) obj).iterator();
88         }
89         else if (obj instanceof Map JavaDoc)
90         {
91             return ((Map JavaDoc) obj).values().iterator();
92         }
93         else if (obj instanceof Iterator)
94         {
95             rlog.warn ("Warning! The iterative "
96                           + " is an Iterator in the #foreach() loop at ["
97                           + i.getLine() + "," + i.getColumn() + "]"
98                           + " in template " + i.getTemplateName()
99                           + ". Because it's not resetable,"
100                           + " if used in more than once, this may lead to"
101                           + " unexpected results.");
102
103             return ((Iterator) obj);
104         }
105         else if (obj instanceof Enumeration JavaDoc)
106         {
107             rlog.warn ("Warning! The iterative "
108                           + " is an Enumeration in the #foreach() loop at ["
109                           + i.getLine() + "," + i.getColumn() + "]"
110                           + " in template " + i.getTemplateName()
111                           + ". Because it's not resetable,"
112                           + " if used in more than once, this may lead to"
113                           + " unexpected results.");
114
115             return new EnumerationIterator((Enumeration JavaDoc) obj);
116         }
117
118         /* we have no clue what this is */
119         rlog.warn ("Could not determine type of iterator in "
120                       + "#foreach loop "
121                       + " at [" + i.getLine() + "," + i.getColumn() + "]"
122                       + " in template " + i.getTemplateName() );
123
124         return null;
125     }
126
127     /**
128      * Method
129      */

130     public VelMethod getMethod(Object JavaDoc obj, String JavaDoc methodName, Object JavaDoc[] args, Info i)
131             throws Exception JavaDoc
132     {
133         if (obj == null)
134             return null;
135
136         Method JavaDoc m = introspector.getMethod(obj.getClass(), methodName, args);
137
138         return (m != null) ? new VelMethodImpl(m) : null;
139     }
140
141     /**
142      * Property getter
143      */

144     public VelPropertyGet getPropertyGet(Object JavaDoc obj, String JavaDoc identifier, Info i)
145             throws Exception JavaDoc
146     {
147         AbstractExecutor executor;
148
149         Class JavaDoc claz = obj.getClass();
150
151         /*
152          * first try for a getFoo() type of property
153          * (also getfoo() )
154          */

155
156         executor = new PropertyExecutor(rlog,introspector, claz, identifier);
157
158         /*
159          * if that didn't work, look for get("foo")
160          */

161
162         if (executor.isAlive() == false)
163         {
164             executor = new GetExecutor(rlog, introspector, claz, identifier);
165         }
166
167         /*
168          * finally, look for boolean isFoo()
169          */

170
171         if( executor.isAlive() == false)
172         {
173             executor = new BooleanPropertyExecutor(rlog, introspector, claz, identifier);
174         }
175
176         return (executor != null) ? new VelGetterImpl(executor) : null;
177     }
178
179     /**
180      * Property setter
181      */

182     public VelPropertySet getPropertySet(Object JavaDoc obj, String JavaDoc identifier, Object JavaDoc arg, Info i)
183             throws Exception JavaDoc
184     {
185         Class JavaDoc claz = obj.getClass();
186
187         VelPropertySet vs = null;
188         VelMethod vm = null;
189         try
190         {
191             /*
192              * first, we introspect for the set<identifier> setter method
193              */

194
195             Object JavaDoc[] params = {arg};
196
197             try
198             {
199                 vm = getMethod(obj, "set" + identifier, params, i);
200
201                 if (vm == null)
202                 {
203                    throw new NoSuchMethodException JavaDoc();
204                 }
205             }
206             catch(NoSuchMethodException JavaDoc nsme2)
207             {
208                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc("set");
209                 sb.append(identifier);
210
211                 if (Character.isLowerCase( sb.charAt(3)))
212                 {
213                     sb.setCharAt(3, Character.toUpperCase(sb.charAt(3)));
214                 }
215                 else
216                 {
217                     sb.setCharAt(3, Character.toLowerCase(sb.charAt(3)));
218                 }
219
220                 vm = getMethod(obj, sb.toString(), params, i);
221
222                 if (vm == null)
223                 {
224                    throw new NoSuchMethodException JavaDoc();
225                 }
226             }
227         }
228         catch (NoSuchMethodException JavaDoc nsme)
229         {
230             /*
231              * right now, we only support the Map interface
232              */

233
234             if (Map JavaDoc.class.isAssignableFrom(claz))
235             {
236                 Object JavaDoc[] params = {new Object JavaDoc(), new Object JavaDoc()};
237
238                 vm = getMethod(obj, "put", params, i);
239
240                 if (vm!=null)
241                     return new VelSetterImpl(vm, identifier);
242             }
243        }
244
245        return (vm!=null) ? new VelSetterImpl(vm) : null;
246     }
247
248     /**
249      * Implementation of VelMethod
250      */

251     public class VelMethodImpl implements VelMethod
252     {
253         Method JavaDoc method = null;
254
255         public VelMethodImpl(Method JavaDoc m)
256         {
257             method = m;
258         }
259
260         private VelMethodImpl()
261         {
262         }
263
264         public Object JavaDoc invoke(Object JavaDoc o, Object JavaDoc[] params)
265             throws Exception JavaDoc
266         {
267             return method.invoke(o, params);
268         }
269
270         public boolean isCacheable()
271         {
272             return true;
273         }
274
275         public String JavaDoc getMethodName()
276         {
277             return method.getName();
278         }
279
280         public Class JavaDoc getReturnType()
281         {
282             return method.getReturnType();
283         }
284     }
285
286     public class VelGetterImpl implements VelPropertyGet
287     {
288         AbstractExecutor ae = null;
289
290         public VelGetterImpl(AbstractExecutor exec)
291         {
292             ae = exec;
293         }
294
295         private VelGetterImpl()
296         {
297         }
298
299         public Object JavaDoc invoke(Object JavaDoc o)
300             throws Exception JavaDoc
301         {
302             return ae.execute(o);
303         }
304
305         public boolean isCacheable()
306         {
307             return true;
308         }
309
310         public String JavaDoc getMethodName()
311         {
312             return ae.getMethod().getName();
313         }
314
315     }
316
317     public class VelSetterImpl implements VelPropertySet
318     {
319         VelMethod vm = null;
320         String JavaDoc putKey = null;
321
322         public VelSetterImpl(VelMethod velmethod)
323         {
324             this.vm = velmethod;
325         }
326
327         public VelSetterImpl(VelMethod velmethod, String JavaDoc key)
328         {
329             this.vm = velmethod;
330             putKey = key;
331         }
332
333         private VelSetterImpl()
334         {
335         }
336
337         public Object JavaDoc invoke(Object JavaDoc o, Object JavaDoc value)
338             throws Exception JavaDoc
339         {
340             ArrayList JavaDoc al = new ArrayList JavaDoc();
341
342             if (putKey != null)
343             {
344                 al.add(putKey);
345                 al.add(value);
346             }
347             else
348             {
349                 al.add(value);
350             }
351
352             return vm.invoke(o,al.toArray());
353         }
354
355         public boolean isCacheable()
356         {
357             return true;
358         }
359
360         public String JavaDoc getMethodName()
361         {
362             return vm.getMethodName();
363         }
364
365     }
366 }
367
Popular Tags