Coverage Report - org.apache.commons.ognl.ArrayPropertyAccessor
 
Classes in this File Line Coverage Branch Coverage Complexity
ArrayPropertyAccessor
65%
41/63
52%
29/55
7.6
 
 1  
 package org.apache.commons.ognl;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import java.lang.reflect.Array;
 23  
 import java.util.Map;
 24  
 
 25  
 /**
 26  
  * Implementation of PropertyAccessor that uses numbers and dynamic subscripts as properties to index into Java arrays.
 27  
  * 
 28  
  * @author Luke Blanshard (blanshlu@netscape.net)
 29  
  * @author Drew Davidson (drew@ognl.org)
 30  
  */
 31  1
 public class ArrayPropertyAccessor
 32  
     extends ObjectPropertyAccessor
 33  
     implements PropertyAccessor
 34  
 {
 35  
 
 36  
     @Override
 37  
     public Object getProperty( Map<String, Object> context, Object target, Object name )
 38  
         throws OgnlException
 39  
     {
 40  58
         Object result = null;
 41  
 
 42  58
         if ( name instanceof String )
 43  
         {
 44  22
             if ( "length".equals( name ) )
 45  
             {
 46  21
                 result = Array.getLength( target );
 47  
             }
 48  
             else
 49  
             {
 50  1
                 result = super.getProperty( context, target, name );
 51  
             }
 52  
         }
 53  
         else
 54  
         {
 55  36
             Object index = name;
 56  
 
 57  36
             if ( index instanceof DynamicSubscript )
 58  
             {
 59  3
                 int len = Array.getLength( target );
 60  
 
 61  3
                 switch ( ( (DynamicSubscript) index ).getFlag() )
 62  
                 {
 63  
                     case DynamicSubscript.ALL:
 64  1
                         result = Array.newInstance( target.getClass().getComponentType(), len );
 65  1
                         System.arraycopy( target, 0, result, 0, len );
 66  1
                         break;
 67  
                     case DynamicSubscript.FIRST:
 68  0
                         index = ( len > 0 ) ? 0 : -1;
 69  0
                         break;
 70  
                     case DynamicSubscript.MID:
 71  0
                         index = ( len > 0 ) ? ( len / 2 ) : -1;
 72  0
                         break;
 73  
                     case DynamicSubscript.LAST:
 74  2
                         index = ( len > 0 ) ? ( len - 1 ) : -1;
 75  2
                         break;
 76  
                     default: break;
 77  
                 }
 78  
             }
 79  36
             if ( result == null )
 80  
             {
 81  35
                 if ( index instanceof Number )
 82  
                 {
 83  34
                     int i = ( (Number) index ).intValue();
 84  
 
 85  34
                     result = ( i >= 0 ) ? Array.get( target, i ) : null;
 86  34
                 }
 87  
                 else
 88  
                 {
 89  1
                     throw new NoSuchPropertyException( target, index );
 90  
                 }
 91  
             }
 92  
         }
 93  56
         return result;
 94  
     }
 95  
 
 96  
     @Override
 97  
     public void setProperty( Map<String, Object> context, Object target, Object name, Object value )
 98  
         throws OgnlException
 99  
     {
 100  0
         boolean isNumber = ( name instanceof Number );
 101  
 
 102  0
         if ( isNumber || ( name instanceof DynamicSubscript ) )
 103  
         {
 104  0
             TypeConverter converter = ( (OgnlContext) context ).getTypeConverter();
 105  
             Object convertedValue;
 106  
 
 107  0
             convertedValue = converter.convertValue( context, target, null, name.toString(), value,
 108  
                                                      target.getClass().getComponentType() );
 109  0
             if ( isNumber )
 110  
             {
 111  0
                 int i = ( (Number) name ).intValue();
 112  
 
 113  0
                 if ( i >= 0 )
 114  
                 {
 115  0
                     Array.set( target, i, convertedValue );
 116  
                 }
 117  0
             }
 118  
             else
 119  
             {
 120  0
                 int len = Array.getLength( target );
 121  
 
 122  0
                 switch ( ( (DynamicSubscript) name ).getFlag() )
 123  
                 {
 124  
                     case DynamicSubscript.ALL:
 125  0
                         System.arraycopy( target, 0, convertedValue, 0, len );
 126  0
                         return;
 127  
                     default:
 128  
                         break;
 129  
                 }
 130  
             }
 131  0
         }
 132  
         else
 133  
         {
 134  0
             if ( name instanceof String )
 135  
             {
 136  0
                 super.setProperty( context, target, name, value );
 137  
             }
 138  
             else
 139  
             {
 140  0
                 throw new NoSuchPropertyException( target, name );
 141  
             }
 142  
         }
 143  0
     }
 144  
 
 145  
     @Override
 146  
     public String getSourceAccessor( OgnlContext context, Object target, Object index )
 147  
     {
 148  19
         String indexStr = getIndexString( context, index );
 149  
 
 150  19
         context.setCurrentAccessor( target.getClass() );
 151  19
         context.setCurrentType( target.getClass().getComponentType() );
 152  
 
 153  19
         return "[" + indexStr + "]";
 154  
     }
 155  
 
 156  
     @Override
 157  
     public String getSourceSetter( OgnlContext context, Object target, Object index )
 158  
     {
 159  12
         String indexStr = getIndexString( context, index );
 160  
 
 161  12
         Class<?> type = target.getClass().isArray() ? target.getClass().getComponentType() : target.getClass();
 162  
 
 163  12
         context.setCurrentAccessor( target.getClass() );
 164  12
         context.setCurrentType( target.getClass().getComponentType() );
 165  
 
 166  12
         if ( type.isPrimitive() )
 167  
         {
 168  10
             Class<?> wrapClass = OgnlRuntime.getPrimitiveWrapperClass( type );
 169  
 
 170  10
             return "[" + indexStr + "]=((" + wrapClass.getName() + ")org.apache.commons.ognl.OgnlOps.convertValue($3,"
 171  
                 + wrapClass.getName() + ".class, true))." + OgnlRuntime.getNumericValueGetter( wrapClass );
 172  
         }
 173  2
         return "[" + indexStr + "]=org.apache.commons.ognl.OgnlOps.convertValue($3," + type.getName() + ".class)";
 174  
     }
 175  
 
 176  
     private static String getIndexString( OgnlContext context, Object index )
 177  
     {
 178  31
         String indexStr = index.toString();
 179  
 
 180  
         // need to convert to primitive for list index access
 181  
 
 182  
         // System.out.println("index class " + index.getClass() + " current type " + context.getCurrentType() +
 183  
         // " current object class " + context.getCurrentObject().getClass());
 184  
 
 185  31
         if ( context.getCurrentType() != null && !context.getCurrentType().isPrimitive()
 186  
             && Number.class.isAssignableFrom( context.getCurrentType() ) )
 187  
         {
 188  8
             indexStr += "." + OgnlRuntime.getNumericValueGetter( context.getCurrentType() );
 189  
         }
 190  23
         else if ( context.getCurrentObject() != null && Number.class.isAssignableFrom(
 191  
             context.getCurrentObject().getClass() ) && !context.getCurrentType().isPrimitive() )
 192  
         {
 193  
             // means it needs to be cast first as well
 194  
 
 195  2
             String toString =
 196  
                 String.class.isInstance( index ) && context.getCurrentType() != Object.class ? "" : ".toString()";
 197  
 
 198  2
             indexStr = "org.apache.commons.ognl.OgnlOps#getIntValue(" + indexStr + toString + ")";
 199  
         }
 200  31
         return indexStr;
 201  
     }
 202  
 }