Coverage report

  %line %branch
org.apache.commons.jexl.parser.ASTArrayAccess
75% 
98% 

 1  
 /*
 2  
  * Copyright 2002-2006 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.parser;
 18  
 
 19  
 import org.apache.commons.jexl.JexlContext;
 20  
 import org.apache.commons.jexl.util.Coercion;
 21  
 import org.apache.commons.jexl.util.Introspector;
 22  
 import org.apache.commons.jexl.util.introspection.Info;
 23  
 import org.apache.commons.jexl.util.introspection.VelPropertyGet;
 24  
 
 25  
 import java.util.List;
 26  
 import java.util.Map;
 27  
 import java.lang.reflect.Array;
 28  
 
 29  
 /**
 30  
  * Like an ASTIdentifier, but with array access allowed.
 31  
  * 
 32  
  * $foo[2]
 33  
  * 
 34  
  * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
 35  
  * @version $Id: ASTArrayAccess.java 398180 2006-04-29 15:40:35Z dion $
 36  
  */
 37  
 public class ASTArrayAccess extends SimpleNode {
 38  
     /** dummy velocity info. */
 39  3
     private static final Info DUMMY = new Info("", 1, 1);
 40  
 
 41  
     /**
 42  
      * Create the node given an id.
 43  
      * 
 44  
      * @param id node id.
 45  
      */
 46  
     public ASTArrayAccess(int id) {
 47  0
         super(id);
 48  0
     }
 49  
 
 50  
     /**
 51  
      * Create a node with the given parser and id.
 52  
      * 
 53  
      * @param p a parser.
 54  
      * @param id node id.
 55  
      */
 56  
     public ASTArrayAccess(Parser p, int id) {
 57  13
         super(p, id);
 58  13
     }
 59  
 
 60  
     /** {@inheritDoc} */
 61  
     public Object jjtAccept(ParserVisitor visitor, Object data) {
 62  0
         return visitor.visit(this, data);
 63  
     }
 64  
 
 65  
     /**
 66  
      * evaluate array access upon a base object.
 67  
      * 
 68  
      * foo.bar[2]
 69  
      * 
 70  
      * makes me rethink the array operator :)
 71  
      * @param jc the {@link JexlContext} to evaluate against.
 72  
      * @param obj not used.
 73  
      * @return the value of the array expression.
 74  
      * @throws Exception on any error
 75  
      */
 76  
     public Object execute(Object obj, JexlContext jc) throws Exception {
 77  2
         ASTIdentifier base = (ASTIdentifier) jjtGetChild(0);
 78  
 
 79  2
         Object result = base.execute(obj, jc);
 80  
 
 81  
         /*
 82  
          * ignore the first child - it's our identifier
 83  
          */
 84  5
         for (int i = 1; i < jjtGetNumChildren(); i++) {
 85  3
             Object loc = ((SimpleNode) jjtGetChild(i)).value(jc);
 86  
 
 87  3
             if (loc == null) {
 88  0
                 return null;
 89  
             }
 90  
 
 91  3
             result = evaluateExpr(result, loc);
 92  
         }
 93  
 
 94  2
         return result;
 95  
     }
 96  
 
 97  
     /** {@inheritDoc} */
 98  
     public Object value(JexlContext jc) throws Exception {
 99  
         /*
 100  
          * get the base ASTIdentifier
 101  
          */
 102  
 
 103  11
         ASTIdentifier base = (ASTIdentifier) jjtGetChild(0);
 104  
 
 105  11
         Object o = base.value(jc);
 106  
 
 107  
         /*
 108  
          * ignore the first child - it's our identifier
 109  
          */
 110  23
         for (int i = 1; i < jjtGetNumChildren(); i++) {
 111  12
             Object loc = ((SimpleNode) jjtGetChild(i)).value(jc);
 112  
 
 113  12
             if (loc == null) {
 114  0
                 return null;
 115  
             }
 116  
 
 117  12
             o = evaluateExpr(o, loc);
 118  
         }
 119  
 
 120  11
         return o;
 121  
     }
 122  
 
 123  
     /**
 124  
      * Evaluate the Array expression 'loc' on the given object, o.
 125  
      * e.g. in 'a[2]', <code>2</code> is 'loc' and <code>a</code> is 'o'.
 126  
      * 
 127  
      * If o or loc are null, null is returned.
 128  
      * If o is a Map, o.get(loc) is returned.
 129  
      * If o is a List, o.get(loc) is returned. loc must resolve to an int value.
 130  
      * If o is an Array, o[loc] is returned. loc must resolve to an int value.
 131  
      * Otherwise loc is treated as a bean property of o.
 132  
      *  
 133  
      * @param o an object to be accessed using the array operator or '.' operator.
 134  
      * @param loc the index of the object to be returned.
 135  
      * @return the resulting value.
 136  
      * @throws Exception on any error.
 137  
      */
 138  
     public static Object evaluateExpr(Object o, Object loc) throws Exception {
 139  
         /*
 140  
          * following the JSTL EL rules
 141  
          */
 142  
 
 143  55
         if (o == null) {
 144  15
             return null;
 145  
         }
 146  
 
 147  40
         if (loc == null) {
 148  0
             return null;
 149  
         }
 150  
 
 151  40
         if (o instanceof Map) {
 152  5
             if (!((Map) o).containsKey(loc)) {
 153  0
                 return null;
 154  
             }
 155  
 
 156  5
             return ((Map) o).get(loc);
 157  35
         } else if (o instanceof List) {
 158  4
             int idx = Coercion.coerceInteger(loc).class="keyword">intValue();
 159  
 
 160  
             try {
 161  4
                 return ((List) o).get(idx);
 162  
             } catch (IndexOutOfBoundsException iobe) {
 163  0
                 return null;
 164  
             }
 165  31
         } else if (o.getClass().isArray()) {
 166  8
             int idx = Coercion.coerceInteger(loc).class="keyword">intValue();
 167  
 
 168  
             try {
 169  8
                 return Array.get(o, idx);
 170  
             } catch (ArrayIndexOutOfBoundsException aiobe) {
 171  0
                 return null;
 172  
             }
 173  
         } else {
 174  
             /*
 175  
              * "Otherwise (a JavaBean object)..." huh? :)
 176  
              */
 177  
 
 178  23
             String s = loc.toString();
 179  
 
 180  23
             VelPropertyGet vg = Introspector.getUberspect().getPropertyGet(o, s, DUMMY);
 181  
 
 182  23
             if (vg != null) {
 183  23
                 return vg.invoke(o);
 184  
             }
 185  
         }
 186  
 
 187  0
         throw new Exception("Unsupported object type for array [] accessor");
 188  
     }
 189  
 
 190  
     /**
 191  
      * Gets the variable name piece of the expression.
 192  
      * @return a String of the identifer. 
 193  
      * @see ASTIdentifier#getIdentifierString().
 194  
      */
 195  
     public String getIdentifierString() {
 196  0
         return ((ASTIdentifier) jjtGetChild(0)).getIdentifierString();
 197  
     }
 198  
 }

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