Coverage Report - org.apache.commons.el.ArraySuffix
 
Classes in this File Line Coverage Branch Coverage Complexity
ArraySuffix
0%
0/85
0%
0/44
7.625
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *     http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.commons.el;
 18  
 
 19  
 import java.lang.reflect.Array;
 20  
 import java.lang.reflect.InvocationTargetException;
 21  
 import java.util.List;
 22  
 import java.util.Map;
 23  
 
 24  
 import javax.servlet.jsp.el.ELException;
 25  
 import javax.servlet.jsp.el.FunctionMapper;
 26  
 import javax.servlet.jsp.el.VariableResolver;
 27  
 
 28  
 import org.apache.commons.logging.Log;
 29  
 import org.apache.commons.logging.LogFactory;
 30  
 
 31  
 /**
 32  
  *
 33  
  * <p>Represents an operator that obtains a Map entry, an indexed
 34  
  * value, a property value, or an indexed property value of an object.
 35  
  * The following are the rules for evaluating this operator:
 36  
  *
 37  
  * <ul><pre>
 38  
  * Evaluating a[b] (assuming a.b == a["b"])
 39  
  *   a is null
 40  
  *     return null
 41  
  *   b is null
 42  
  *     return null
 43  
  *   a is Map
 44  
  *     !a.containsKey (b)
 45  
  *       return null
 46  
  *     a.get(b) == null
 47  
  *       return null
 48  
  *     otherwise
 49  
  *       return a.get(b)
 50  
  *   a is List or array
 51  
  *     coerce b to int (using coercion rules)
 52  
  *     coercion couldn't be performed
 53  
  *       error
 54  
  *     a.get(b) or Array.get(a, b) throws ArrayIndexOutOfBoundsException or IndexOutOfBoundsException
 55  
  *       return null
 56  
  *     a.get(b) or Array.get(a, b) throws other exception
 57  
  *       error
 58  
  *     return a.get(b) or Array.get(a, b)
 59  
  * 
 60  
  *   coerce b to String
 61  
  *   b is a readable property of a
 62  
  *     getter throws an exception
 63  
  *       error
 64  
  *     otherwise
 65  
  *       return result of getter call
 66  
  *
 67  
  *   otherwise
 68  
  *     error
 69  
  * </pre></ul>
 70  
  * 
 71  
  * @author Nathan Abramson - Art Technology Group
 72  
  * @author Shawn Bayern
 73  
  * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: bayard $
 74  
  **/
 75  
 
 76  
 public class ArraySuffix
 77  
     extends ValueSuffix {
 78  
     
 79  
     //-------------------------------------
 80  
     // Constants
 81  
     //-------------------------------------
 82  0
     private static Log log = LogFactory.getLog(ArraySuffix.class);
 83  
 
 84  
     // Zero-argument array
 85  0
     static Object[] sNoArgs = new Object[0];
 86  
 
 87  
     //-------------------------------------
 88  
     // Properties
 89  
     //-------------------------------------
 90  
     // property index
 91  
 
 92  
     Expression mIndex;
 93  
 
 94  
     public Expression getIndex() {
 95  0
         return mIndex;
 96  
     }
 97  
 
 98  
     public void setIndex(Expression pIndex) {
 99  0
         mIndex = pIndex;
 100  0
     }
 101  
 
 102  
     //-------------------------------------
 103  
     /**
 104  
      *
 105  
      * Constructor
 106  
      **/
 107  0
     public ArraySuffix(Expression pIndex) {
 108  0
         mIndex = pIndex;
 109  0
     }
 110  
 
 111  
     //-------------------------------------
 112  
     /**
 113  
      *
 114  
      * Gets the value of the index
 115  
      **/
 116  
     Object evaluateIndex(
 117  
         VariableResolver pResolver,
 118  
         FunctionMapper functions)
 119  
         throws ELException {
 120  0
         return mIndex.evaluate(pResolver, functions);
 121  
     }
 122  
 
 123  
     //-------------------------------------
 124  
     /**
 125  
      *
 126  
      * Returns the operator symbol
 127  
      **/
 128  
     String getOperatorSymbol() {
 129  0
         return "[]";
 130  
     }
 131  
 
 132  
     //-------------------------------------
 133  
     // ValueSuffix methods
 134  
     //-------------------------------------
 135  
     /**
 136  
      *
 137  
      * Returns the expression in the expression language syntax
 138  
      **/
 139  
     public String getExpressionString() {
 140  0
         return "[" + mIndex.getExpressionString() + "]";
 141  
     }
 142  
 
 143  
     //-------------------------------------
 144  
     /**
 145  
      *
 146  
      * Evaluates the expression in the given context, operating on the
 147  
      * given value.
 148  
      **/
 149  
     public Object evaluate(Object pValue, VariableResolver pResolver, FunctionMapper functions)
 150  
     throws ELException {
 151  
         Object indexVal;
 152  
         String indexStr;
 153  
         BeanInfoProperty property;
 154  
         BeanInfoIndexedProperty ixproperty;
 155  
 
 156  
         // Check for null value
 157  0
         if (pValue == null) {
 158  0
             if (log.isWarnEnabled()) {
 159  0
                 log.warn(
 160  
                     MessageUtil.getMessageWithArgs(
 161  
                         Constants.CANT_GET_INDEXED_VALUE_OF_NULL, getOperatorSymbol()));
 162  0
                 return null;
 163  
             }
 164  
         }
 165  
 
 166  
         // Evaluate the index
 167  0
         else if ((indexVal = evaluateIndex(pResolver, functions))
 168  
             == null) {
 169  0
             if (log.isWarnEnabled()) {
 170  0
                 log.warn(
 171  
                     MessageUtil.getMessageWithArgs(
 172  
                         Constants.CANT_GET_NULL_INDEX, getOperatorSymbol()));
 173  0
                 return null;
 174  
             }
 175  
         }
 176  
 
 177  
         // See if it's a Map
 178  0
         else if (pValue instanceof Map) {
 179  0
             Map val = (Map) pValue;
 180  0
             return val.get(indexVal);
 181  
         }
 182  
 
 183  
         // See if it's a List or array
 184  0
         else if (pValue instanceof List ||
 185  
             pValue.getClass().isArray()) {
 186  0
             Integer indexObj = Coercions.coerceToInteger(indexVal);
 187  0
             if (indexObj == null) {
 188  0
                 if (log.isErrorEnabled()) {
 189  0
                     String message = MessageUtil.getMessageWithArgs(
 190  
                         Constants.BAD_INDEX_VALUE,
 191  
                         getOperatorSymbol(), indexVal.getClass().getName());
 192  0
                     log.error(message);
 193  0
                     throw new ELException(message);
 194  
                 }
 195  0
                 return null;
 196  0
             } else if (pValue instanceof List) {
 197  
                 try {
 198  0
                     return ((List) pValue).get(indexObj.intValue());
 199  0
                 } catch (ArrayIndexOutOfBoundsException aob) {
 200  0
                     if (log.isWarnEnabled()) {
 201  0
                         log.warn(
 202  
                             MessageUtil.getMessageWithArgs(
 203  
                                 Constants.EXCEPTION_ACCESSING_LIST, indexObj), aob);
 204  
                     }   
 205  0
                     return null;
 206  0
                 } catch (IndexOutOfBoundsException iob) {
 207  0
                     if (log.isWarnEnabled()) {
 208  0
                         log.warn(
 209  
                             MessageUtil.getMessageWithArgs(
 210  
                                 Constants.EXCEPTION_ACCESSING_LIST, indexObj), iob);                        
 211  
                     }   
 212  0
                     return null;
 213  0
                 } catch (Throwable t) {
 214  0
                     if (log.isErrorEnabled()) {
 215  0
                         String message = MessageUtil.getMessageWithArgs(
 216  
                             Constants.EXCEPTION_ACCESSING_LIST,
 217  
                             indexObj);
 218  0
                         log.error(message, t);
 219  0
                         throw new ELException(message, t);
 220  
                     }
 221  0
                     return null;
 222  
                 }
 223  
             } else {
 224  
                 try {
 225  0
                     return Array.get(pValue, indexObj.intValue());
 226  0
                 } catch (ArrayIndexOutOfBoundsException aob) {
 227  0
                     if (log.isWarnEnabled()) {
 228  0
                         log.warn(
 229  
                             MessageUtil.getMessageWithArgs(
 230  
                                 Constants.EXCEPTION_ACCESSING_ARRAY, indexObj), aob);
 231  
                     }
 232  0
                     return null;
 233  0
                 } catch (IndexOutOfBoundsException iob) {
 234  0
                     if (log.isWarnEnabled()) {
 235  0
                         log.warn(
 236  
                             MessageUtil.getMessageWithArgs(
 237  
                                 Constants.EXCEPTION_ACCESSING_ARRAY, indexObj), iob);
 238  
                     }
 239  0
                     return null;
 240  0
                 } catch (Throwable t) {
 241  0
                     if (log.isErrorEnabled()) {
 242  0
                         String message = MessageUtil.getMessageWithArgs(
 243  
                             Constants.EXCEPTION_ACCESSING_ARRAY,
 244  
                             indexObj);
 245  0
                         log.error(message, t);
 246  0
                         throw new ELException(message, t);
 247  
                     }
 248  0
                     return null;
 249  
                 }
 250  
             }
 251  
         }
 252  
 
 253  
         // Coerce to a String for property access
 254  
 
 255  0
         else if ((indexStr = Coercions.coerceToString(indexVal)) ==
 256  
             null) {
 257  0
             return null;
 258  
         }
 259  
 
 260  
         // Look for a JavaBean property
 261  0
         else if ((property = BeanInfoManager.getBeanInfoProperty
 262  
             (pValue.getClass(), indexStr)) != null &&
 263  
             property.getReadMethod() != null) {
 264  
             try {
 265  0
                 return property.getReadMethod().invoke(pValue, sNoArgs);
 266  0
             } catch (InvocationTargetException exc) {
 267  0
                 if (log.isErrorEnabled()) {
 268  0
                     String message = MessageUtil.getMessageWithArgs(
 269  
                         Constants.ERROR_GETTING_PROPERTY, indexStr, pValue.getClass().getName());
 270  0
                     Throwable t = exc.getTargetException();
 271  0
                     log.warn(message, t);
 272  0
                     throw new ELException(message, t);
 273  
                 }
 274  0
                 return null;
 275  0
             } catch (Throwable t) {
 276  0
                 if (log.isErrorEnabled()) {
 277  0
                     String message = MessageUtil.getMessageWithArgs(
 278  
                         Constants.ERROR_GETTING_PROPERTY, indexStr, pValue.getClass().getName());                    
 279  0
                     log.warn(message, t);
 280  0
                     throw new ELException(message, t);
 281  
                 }
 282  0
                 return null;
 283  
             }
 284  
         } else {
 285  0
             if (log.isErrorEnabled()) {
 286  0
                 String message = MessageUtil.getMessageWithArgs(
 287  
                     Constants.CANT_FIND_INDEX,
 288  
                     indexVal,
 289  
                     pValue.getClass().getName(),
 290  
                     getOperatorSymbol());
 291  0
                 log.error(message);
 292  0
                 throw new ELException(message);                    
 293  
             }
 294  0
             return null;          
 295  
         }
 296  0
         return null;
 297  
     }
 298  
 
 299  
     public ValueSuffix bindFunctions(final FunctionMapper functions) throws ELException {
 300  0
         return new ArraySuffix(mIndex.bindFunctions(functions));
 301  
     }
 302  
     //-------------------------------------
 303  
 }