Coverage report

| %line | %branch
--- | --- | ---
org.apache.commons.jexl.util.introspection.UberspectImpl |
52% |
84% |

1 |  |
     /*
2 |  |
      * Copyright 2002,2004 The Apache Software Foundation.
3 |  |
      *
4 |  |
      * Licensed under the Apache License, Version 2.0 (the "License");
5 |  |
      * you may not use this file except in compliance with the License.
6 |  |
      * You may obtain a copy of the License at
7 |  |
      *
8 |  |
      *      http://www.apache.org/licenses/LICENSE-2.0
9 |  |
      *
10 |  |
      * Unless required by applicable law or agreed to in writing, software
11 |  |
      * distributed under the License is distributed on an "AS IS" BASIS,
12 |  |
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  |
      * See the License for the specific language governing permissions and
14 |  |
      * limitations under the License.
15 |  |
      */
16 |  |
17 |  |
     package org.apache.commons.jexl.util.introspection;
18 |  |
19 |  |
     import org.apache.commons.jexl.util.ArrayIterator;
20 |  |
     import org.apache.commons.jexl.util.EnumerationIterator;
21 |  |
     import org.apache.commons.jexl.util.AbstractExecutor;
22 |  |
     import org.apache.commons.jexl.util.GetExecutor;
23 |  |
     import org.apache.commons.jexl.util.BooleanPropertyExecutor;
24 |  |
     import org.apache.commons.jexl.util.PropertyExecutor;
25 |  |
     import org.apache.commons.logging.Log;
26 |  |
27 |  |
     import java.lang.reflect.Method;
28 |  |
     import java.lang.reflect.InvocationTargetException;
29 |  |
     import java.util.Iterator;
30 |  |
     import java.util.Collection;
31 |  |
     import java.util.Map;
32 |  |
     import java.util.Enumeration;
33 |  |
     import java.util.ArrayList;
34 |  |
35 |  |
     /**
36 |  |
      * Implementation of Uberspect to provide the default introspective
37 |  |
      * functionality of Velocity.
38 |  |
      *
39 |  |
      * @since 1.0
40 |  |
      * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
41 |  |
      * @version $Id: UberspectImpl.java 398509 2006-05-01 03:34:35Z dion $
42 |  |
      */
43 | 4 |
     public class UberspectImpl implements Uberspect, UberspectLoggable {
44 |  |
         /** index of the first character of the property. */
45 |  |
         private static final int PROPERTY_START_INDEX = 3;
46 |  |
47 |  |
         /**
48 |  |
          * Our runtime logger.
49 |  |
          */
50 |  |
         private Log rlog;
51 |  |
52 |  |
         /**
53 |  |
          * the default Velocity introspector.
54 |  |
          */
55 |  |
         private static Introspector introspector;
56 |  |
57 |  |
         /**
58 |  |
          * init - does nothing - we need to have setRuntimeLogger called before
59 |  |
          * getting our introspector, as the default vel introspector depends upon
60 |  |
          * it.
61 |  |
          * @throws Exception on any error.
62 |  |
          */
63 |  |
         public void init() throws Exception {
64 | 0 |
         }
65 |  |
66 |  |
         /**
67 |  |
          * Sets the runtime logger - this must be called before anything else
68 |  |
          * besides init() as to get the logger. Makes the pull model appealing...
69 |  |
          * @param runtimeLogger service to use for logging.
70 |  |
          */
71 |  |
         public void setRuntimeLogger(Log runtimeLogger) {
72 | 4 |
             rlog = runtimeLogger;
73 | 4 |
             introspector = new Introspector(rlog);
74 | 4 |
         }
75 |  |
76 |  |
         /**
77 |  |
          * {@inheritDoc}
78 |  |
          */
79 |  |
         public Iterator getIterator(Object obj, Info i) throws Exception {
80 | 8 |
             if (obj.getClass().isArray()) {
81 | 2 |
                 return new ArrayIterator(obj);
82 | 6 |
             } else if (obj instanceof Collection) {
83 | 3 |
                 return ((Collection) obj).iterator();
84 | 3 |
             } else if (obj instanceof Map) {
85 | 1 |
                 return ((Map) obj).values().iterator();
86 | 2 |
             } else if (obj instanceof Iterator) {
87 | 1 |
                 rlog.warn("Warning! The iterative " + " is an Iterator in the #foreach() loop at [" + i.getLine() + ","
88 |  |
                     + i.getColumn() + "]" + " in template " + i.getTemplateName() + ". Because it's not resetable,"
89 |  |
                     + " if used in more than once, this may lead to" + " unexpected results.");
90 |  |
91 | 1 |
                 return ((Iterator) obj);
92 | 1 |
             } else if (obj instanceof Enumeration) {
93 | 1 |
                 rlog.warn("Warning! The iterative " + " is an Enumeration in the #foreach() loop at [" + i.getLine() + ","
94 |  |
                     + i.getColumn() + "]" + " in template " + i.getTemplateName() + ". Because it's not resetable,"
95 |  |
                     + " if used in more than once, this may lead to" + " unexpected results.");
96 |  |
97 | 1 |
                 return new EnumerationIterator((Enumeration) obj);
98 |  |
             }
99 |  |
100 |  |
             /* we have no clue what this is */
101 | 0 |
             rlog.warn("Could not determine type of iterator in " + "#foreach loop " + " at [" + i.getLine() + ","
102 |  |
                 + i.getColumn() + "]" + " in template " + i.getTemplateName());
103 |  |
104 | 0 |
             return null;
105 |  |
         }
106 |  |
107 |  |
         /**
108 |  |
          * {@inheritDoc}
109 |  |
          */
110 |  |
         public VelMethod getMethod(Object obj, String methodName, Object[] args, Info i) throws Exception {
111 | 47 |
             if (obj == null) {
112 | 0 |
                 return null;
113 |  |
             }
114 |  |
115 | 47 |
             Method m = introspector.getMethod(obj.getClass(), methodName, args);
116 | 47 |
             if (m == null && obj instanceof Class) {
117 | 1 |
                 m = introspector.getMethod((Class) obj, methodName, args);
118 |  |
             }
119 |  |
120 | 47 |
             return (m == null) ? class="keyword">null : new VelMethodImpl(m);
121 |  |
         }
122 |  |
123 |  |
         /**
124 |  |
          * {@inheritDoc}
125 |  |
          */
126 |  |
         public VelPropertyGet getPropertyGet(Object obj, String identifier, Info i) throws Exception {
127 |  |
             AbstractExecutor executor;
128 |  |
129 | 23 |
             Class claz = obj.getClass();
130 |  |
131 |  |
             /*
132 |  |
              * first try for a getFoo() type of property (also getfoo() )
133 |  |
              */
134 |  |
135 | 23 |
             executor = new PropertyExecutor(rlog, introspector, claz, identifier);
136 |  |
137 |  |
             /*
138 |  |
              * look for boolean isFoo()
139 |  |
              */
140 |  |
141 | 23 |
             if (!executor.isAlive()) {
142 | 3 |
                 executor = new BooleanPropertyExecutor(rlog, introspector, claz, identifier);
143 |  |
             }
144 |  |
145 |  |
             /*
146 |  |
              * if that didn't work, look for get("foo")
147 |  |
              */
148 |  |
149 | 23 |
             if (!executor.isAlive()) {
150 | 1 |
                 executor = new GetExecutor(rlog, introspector, claz, identifier);
151 |  |
             }
152 |  |
153 | 23 |
             return (executor == null) ? class="keyword">null : new VelGetterImpl(executor);
154 |  |
         }
155 |  |
156 |  |
         /**
157 |  |
          * {@inheritDoc}
158 |  |
          */
159 |  |
         public VelPropertySet getPropertySet(Object obj, String identifier, Object arg, Info i) throws Exception {
160 | 0 |
             Class claz = obj.getClass();
161 |  |
162 | 0 |
             VelMethod vm = null;
163 |  |
             try {
164 |  |
                 /*
165 |  |
                  * first, we introspect for the set<identifier> setter method
166 |  |
                  */
167 |  |
168 | 0 |
                 Object[] params = {arg};
169 |  |
170 |  |
                 try {
171 | 0 |
                     vm = getMethod(obj, "set" + identifier, params, i);
172 |  |
173 | 0 |
                     if (vm == null) {
174 | 0 |
                         throw new NoSuchMethodException();
175 |  |
                     }
176 | 0 |
                 } catch (NoSuchMethodException nsme2) {
177 | 0 |
                     StringBuffer sb = new StringBuffer("set");
178 | 0 |
                     sb.append(identifier);
179 |  |
180 | 0 |
                     if (Character.isLowerCase(sb.charAt(PROPERTY_START_INDEX))) {
181 | 0 |
                         sb.setCharAt(PROPERTY_START_INDEX, Character.toUpperCase(sb.charAt(PROPERTY_START_INDEX)));
182 |  |
                     } else {
183 | 0 |
                         sb.setCharAt(PROPERTY_START_INDEX, Character.toLowerCase(sb.charAt(PROPERTY_START_INDEX)));
184 |  |
                     }
185 |  |
186 | 0 |
                     vm = getMethod(obj, sb.toString(), params, i);
187 |  |
188 | 0 |
                     if (vm == null) {
189 | 0 |
                         throw new NoSuchMethodException();
190 |  |
                     }
191 |  |
                 }
192 | 0 |
             } catch (NoSuchMethodException nsme) {
193 |  |
                 /*
194 |  |
                  * right now, we only support the Map interface
195 |  |
                  */
196 |  |
197 | 0 |
                 if (Map.class.isAssignableFrom(claz)) {
198 | 0 |
                     Object[] params = {new Object(), class="keyword">new Object()};
199 |  |
200 | 0 |
                     vm = getMethod(obj, "put", params, i);
201 |  |
202 | 0 |
                     if (vm != null) {
203 | 0 |
                         return new VelSetterImpl(vm, identifier);
204 |  |
                     }
205 |  |
                 }
206 |  |
             }
207 |  |
208 | 0 |
             return (vm == null) ? class="keyword">null : new VelSetterImpl(vm);
209 |  |
         }
210 |  |
211 |  |
         /**
212 |  |
          * An implementation of {@link VelMethod}.
213 |  |
          */
214 |  |
         public class VelMethodImpl implements VelMethod {
215 |  |
             /** the method. */
216 |  |
             protected Method method = null;
217 |  |
             /**
218 |  |
              * Create a new instance.
219 |  |
              *
220 |  |
              * @param m the method.
221 |  |
              */
222 |  |
             public VelMethodImpl(Method m) {
223 |  |
                 method = m;
224 |  |
             }
225 |  |
226 |  |
             /**
227 |  |
              * {@inheritDoc}
228 |  |
              */
229 |  |
             public Object invoke(Object o, Object[] params) throws Exception {
230 |  |
                 try {
231 |  |
                     return method.invoke(o, params);
232 |  |
                 } catch (InvocationTargetException e) {
233 |  |
                     final Throwable t = e.getTargetException();
234 |  |
235 |  |
                     if (t instanceof Exception) {
236 |  |
                         throw (Exception) t;
237 |  |
                     } else if (t instanceof Error) {
238 |  |
                         throw (Error) t;
239 |  |
                     } else {
240 |  |
                         throw e;
241 |  |
                     }
242 |  |
                 }
243 |  |
             }
244 |  |
245 |  |
             /**
246 |  |
              * {@inheritDoc}
247 |  |
              */
248 |  |
             public boolean isCacheable() {
249 |  |
                 return true;
250 |  |
             }
251 |  |
252 |  |
             /**
253 |  |
              * {@inheritDoc}
254 |  |
              */
255 |  |
             public String getMethodName() {
256 |  |
                 return method.getName();
257 |  |
             }
258 |  |
259 |  |
             /**
260 |  |
              * {@inheritDoc}
261 |  |
              */
262 |  |
             public Class getReturnType() {
263 |  |
                 return method.getReturnType();
264 |  |
             }
265 |  |
         }
266 |  |
267 |  |
         /**
268 |  |
          * {@inheritDoc}
269 |  |
          */
270 |  |
         public class VelGetterImpl implements VelPropertyGet {
271 |  |
             /** executor for performing the get. */
272 |  |
             protected AbstractExecutor ae = null;
273 |  |
274 |  |
             /**
275 |  |
              * Create the getter using an {@link AbstractExecutor} to
276 |  |
              * do the work.
277 |  |
              * @param exec the executor.
278 |  |
              */
279 |  |
             public VelGetterImpl(AbstractExecutor exec) {
280 |  |
                 ae = exec;
281 |  |
             }
282 |  |
283 |  |
             /**
284 |  |
              * {@inheritDoc}
285 |  |
              */
286 |  |
             public Object invoke(Object o) throws Exception {
287 |  |
                 return ae.execute(o);
288 |  |
             }
289 |  |
290 |  |
             /**
291 |  |
              * {@inheritDoc}
292 |  |
              */
293 |  |
             public boolean isCacheable() {
294 |  |
                 return true;
295 |  |
             }
296 |  |
297 |  |
             /**
298 |  |
              * {@inheritDoc}
299 |  |
              */
300 |  |
             public String getMethodName() {
301 |  |
                 return ae.getMethod().getName();
302 |  |
             }
303 |  |
         }
304 |  |
305 |  |
         /**
306 |  |
          * {@inheritDoc}
307 |  |
          */
308 |  |
         public class VelSetterImpl implements VelPropertySet {
309 |  |
             /** the method to call. */
310 |  |
             protected VelMethod vm = null;
311 |  |
             /** the key for indexed and other properties. */
312 |  |
             protected String putKey = null;
313 |  |
314 |  |
             /**
315 |  |
              * Create an instance.
316 |  |
              * @param velmethod the method to call on set.
317 |  |
              */
318 |  |
             public VelSetterImpl(VelMethod velmethod) {
319 |  |
                 this.vm = velmethod;
320 |  |
             }
321 |  |
322 |  |
             /**
323 |  |
              * Create an instance.
324 |  |
              * @param velmethod the method to call on set.
325 |  |
              * @param key the index or other value passed to a
326 |  |
              *      setProperty(xxx, value) method.
327 |  |
              */
328 |  |
             public VelSetterImpl(VelMethod velmethod, String key) {
329 |  |
                 this.vm = velmethod;
330 |  |
                 putKey = key;
331 |  |
             }
332 |  |
333 |  |
             /** {@inheritDoc} */
334 |  |
             public Object invoke(Object o, Object value) throws Exception {
335 |  |
                 ArrayList al = new ArrayList();
336 |  |
337 |  |
                 if (putKey == null) {
338 |  |
                     al.add(value);
339 |  |
                 } else {
340 |  |
                     al.add(putKey);
341 |  |
                     al.add(value);
342 |  |
                 }
343 |  |
344 |  |
                 return vm.invoke(o, al.toArray());
345 |  |
             }
346 |  |
347 |  |
             /** {@inheritDoc} */
348 |  |
             public boolean isCacheable() {
349 |  |
                 return true;
350 |  |
             }
351 |  |
352 |  |
             /** {@inheritDoc} */
353 |  |
             public String getMethodName() {
354 |  |
                 return vm.getMethodName();
355 |  |
             }
356 |  |
357 |  |
         }
358 |  |
     }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.