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.