EMMA Coverage Report (generated Tue May 18 22:13:27 CDT 2004)
[all classes][org.apache.velocity.util.introspection]

COVERAGE SUMMARY FOR SOURCE FILE [UberspectImpl.java]

nameclass, %method, %block, %line, %
UberspectImpl.java100% (4/4)71%  (17/24)85%  (416/488)84%  (79.4/94)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class UberspectImpl$VelMethodImpl100% (1/1)50%  (3/6)59%  (22/37)56%  (5.6/10)
UberspectImpl$VelMethodImpl (UberspectImpl): void 0%   (0/1)0%   (0/9)0%   (0/3)
getMethodName (): String 0%   (0/1)0%   (0/4)0%   (0/1)
isCacheable (): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
UberspectImpl$VelMethodImpl (UberspectImpl, Method): void 100% (1/1)100% (12/12)100% (4/4)
getReturnType (): Class 100% (1/1)100% (4/4)100% (1/1)
invoke (Object, Object []): Object 100% (1/1)100% (6/6)100% (1/1)
     
class UberspectImpl$VelGetterImpl100% (1/1)80%  (4/5)73%  (24/33)73%  (6.6/9)
UberspectImpl$VelGetterImpl (UberspectImpl): void 0%   (0/1)0%   (0/9)0%   (0/3)
UberspectImpl$VelGetterImpl (UberspectImpl, AbstractExecutor): void 100% (1/1)100% (12/12)100% (4/4)
getMethodName (): String 100% (1/1)100% (5/5)100% (1/1)
invoke (Object): Object 100% (1/1)100% (5/5)100% (1/1)
isCacheable (): boolean 100% (1/1)100% (2/2)100% (1/1)
     
class UberspectImpl$VelSetterImpl100% (1/1)50%  (3/6)77%  (61/79)76%  (14.5/19)
UberspectImpl$VelSetterImpl (UberspectImpl): void 0%   (0/1)0%   (0/12)0%   (0/4)
getMethodName (): String 0%   (0/1)0%   (0/4)0%   (0/1)
isCacheable (): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
UberspectImpl$VelSetterImpl (UberspectImpl, VelMethod): void 100% (1/1)100% (15/15)100% (5/5)
UberspectImpl$VelSetterImpl (UberspectImpl, VelMethod, String): void 100% (1/1)100% (18/18)100% (6/6)
invoke (Object, Object): Object 100% (1/1)100% (28/28)100% (6/6)
     
class UberspectImpl100% (1/1)100% (7/7)91%  (309/339)94%  (52.8/56)
getIterator (Object, Info): Iterator 100% (1/1)79%  (99/125)86%  (12/14)
getMethod (Object, String, Object [], Info): VelMethod 100% (1/1)90%  (19/21)75%  (3/4)
getPropertyGet (Object, String, Info): VelPropertyGet 100% (1/1)98%  (45/46)99%  (6.9/7)
getPropertySet (Object, String, Object, Info): VelPropertySet 100% (1/1)99%  (132/133)100% (24.9/25)
UberspectImpl (): void 100% (1/1)100% (3/3)100% (2/2)
init (): void 100% (1/1)100% (1/1)100% (1/1)
setRuntimeLogger (RuntimeLogger): void 100% (1/1)100% (10/10)100% (3/3)

1package 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 
19import org.apache.velocity.util.ArrayIterator;
20import org.apache.velocity.util.EnumerationIterator;
21import org.apache.velocity.runtime.RuntimeServices;
22import org.apache.velocity.runtime.RuntimeLogger;
23import org.apache.velocity.runtime.parser.node.AbstractExecutor;
24import org.apache.velocity.runtime.parser.node.PropertyExecutor;
25import org.apache.velocity.runtime.parser.node.GetExecutor;
26import org.apache.velocity.runtime.parser.node.BooleanPropertyExecutor;
27 
28import java.lang.reflect.Method;
29import java.util.Iterator;
30import java.util.Collection;
31import java.util.Map;
32import java.util.Enumeration;
33import java.util.ArrayList;
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 */
42public 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
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 obj, Info i)
79            throws Exception
80    {
81        if (obj.getClass().isArray())
82        {
83            return new ArrayIterator(obj);
84        }
85        else if (obj instanceof Collection)
86        {
87            return ((Collection) obj).iterator();
88        }
89        else if (obj instanceof Map)
90        {
91            return ((Map) 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)
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) 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 obj, String methodName, Object[] args, Info i)
131            throws Exception
132    {
133        if (obj == null)
134            return null;
135 
136        Method 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 obj, String identifier, Info i)
145            throws Exception
146    {
147        AbstractExecutor executor;
148 
149        Class 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 obj, String identifier, Object arg, Info i)
183            throws Exception
184    {
185        Class 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[] params = {arg};
196 
197            try
198            {
199                vm = getMethod(obj, "set" + identifier, params, i);
200 
201                if (vm == null)
202                {
203                   throw new NoSuchMethodException();
204                }
205            }
206            catch(NoSuchMethodException nsme2)
207            {
208                StringBuffer sb = new StringBuffer("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();
225                }
226            }
227        }
228        catch (NoSuchMethodException nsme)
229        {
230            /*
231             *  right now, we only support the Map interface
232             */
233 
234            if (Map.class.isAssignableFrom(claz))
235            {
236                Object[] params = {new Object(), new Object()};
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 method = null;
254 
255        public VelMethodImpl(Method m)
256        {
257            method = m;
258        }
259 
260        private VelMethodImpl()
261        {
262        }
263 
264        public Object invoke(Object o, Object[] params)
265            throws Exception
266        {
267            return method.invoke(o, params);
268        }
269 
270        public boolean isCacheable()
271        {
272            return true;
273        }
274 
275        public String getMethodName()
276        {
277            return method.getName();
278        }
279 
280        public Class 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 invoke(Object o)
300            throws Exception
301        {
302            return ae.execute(o);
303        }
304 
305        public boolean isCacheable()
306        {
307            return true;
308        }
309 
310        public String getMethodName()
311        {
312            return ae.getMethod().getName();
313        }
314 
315    }
316 
317    public class VelSetterImpl implements VelPropertySet
318    {
319        VelMethod vm = null;
320        String putKey = null;
321 
322        public VelSetterImpl(VelMethod velmethod)
323        {
324            this.vm = velmethod;
325        }
326 
327        public VelSetterImpl(VelMethod velmethod, String key)
328        {
329            this.vm = velmethod;
330            putKey = key;
331        }
332 
333        private VelSetterImpl()
334        {
335        }
336 
337        public Object invoke(Object o, Object value)
338            throws Exception
339        {
340            ArrayList al = new ArrayList();
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 getMethodName()
361        {
362            return vm.getMethodName();
363        }
364 
365    }
366}

[all classes][org.apache.velocity.util.introspection]
EMMA 2.0.4015 (stable) (C) Vladimir Roubtsov