Coverage Report - org.apache.commons.ognl.ASTProperty
 
Classes in this File Line Coverage Branch Coverage Complexity
ASTProperty
92%
203/220
81%
120/148
7.062
 
 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 org.apache.commons.ognl.enhance.ExpressionCompiler;
 23  
 import org.apache.commons.ognl.enhance.UnsupportedCompilationException;
 24  
 
 25  
 import java.beans.IndexedPropertyDescriptor;
 26  
 import java.beans.PropertyDescriptor;
 27  
 import java.lang.reflect.Method;
 28  
 import java.util.Iterator;
 29  
 
 30  
 /**
 31  
  * $Id: ASTProperty.java 1197445 2011-11-04 09:13:17Z mcucchiara $
 32  
  *
 33  
  * @author Luke Blanshard (blanshlu@netscape.net)
 34  
  * @author Drew Davidson (drew@ognl.org)
 35  
  */
 36  
 public class ASTProperty
 37  
     extends SimpleNode
 38  
     implements NodeType
 39  
 {
 40  1230
     private boolean indexedAccess = false;
 41  
 
 42  
     private Class getterClass;
 43  
 
 44  
     private Class setterClass;
 45  
 
 46  
     public ASTProperty( int id )
 47  
     {
 48  1230
         super( id );
 49  1230
     }
 50  
 
 51  
     public void setIndexedAccess( boolean value )
 52  
     {
 53  234
         indexedAccess = value;
 54  234
     }
 55  
 
 56  
     /**
 57  
      * Returns true if this property is itself an index reference.
 58  
      *
 59  
      * @return Returns true if this property is itself an index reference.
 60  
      */
 61  
     public boolean isIndexedAccess()
 62  
     {
 63  2523
         return indexedAccess;
 64  
     }
 65  
 
 66  
     /**
 67  
      * Returns true if this property is described by an IndexedPropertyDescriptor and that if followed by an index
 68  
      * specifier it will call the index get/set methods rather than go through property accessors.
 69  
      *
 70  
      * @param context The context
 71  
      * @param source  The object source
 72  
      * @return true, if this property is described by an IndexedPropertyDescriptor
 73  
      * @throws OgnlException if an error occurs
 74  
      */
 75  
     public int getIndexedPropertyType( OgnlContext context, Object source )
 76  
         throws OgnlException
 77  
     {
 78  969
         Class type = context.getCurrentType();
 79  969
         Class prevType = context.getPreviousType();
 80  
         try
 81  
         {
 82  969
             if ( !isIndexedAccess() )
 83  
             {
 84  961
                 Object property = getProperty( context, source );
 85  
 
 86  961
                 if ( property instanceof String )
 87  
                 {
 88  961
                     return OgnlRuntime.getIndexedPropertyType( context, ( source == null )
 89  
                         ? null
 90  
                         : OgnlRuntime.getCompiler( context ).getInterfaceClass( source.getClass() ),
 91  
                                                                (String) property );
 92  
                 }
 93  
             }
 94  
 
 95  8
             return OgnlRuntime.INDEXED_PROPERTY_NONE;
 96  
         }
 97  
         finally
 98  
         {
 99  969
             context.setCurrentObject( source );
 100  969
             context.setCurrentType( type );
 101  969
             context.setPreviousType( prevType );
 102  
         }
 103  
     }
 104  
 
 105  
     public Object getProperty( OgnlContext context, Object source )
 106  
         throws OgnlException
 107  
     {
 108  2532
         return children[0].getValue( context, context.getRoot() );
 109  
     }
 110  
 
 111  
     protected Object getValueBody( OgnlContext context, Object source )
 112  
         throws OgnlException
 113  
     {
 114  1507
         Object property = getProperty( context, source );
 115  
 
 116  1506
         Object result = OgnlRuntime.getProperty( context, source, property );
 117  
 
 118  1402
         if ( result == null )
 119  
         {
 120  76
             result =
 121  
                 OgnlRuntime.getNullHandler( OgnlRuntime.getTargetClass( source ) ).nullPropertyValue( context, source,
 122  
                                                                                                       property );
 123  
         }
 124  
 
 125  1402
         return result;
 126  
     }
 127  
 
 128  
     protected void setValueBody( OgnlContext context, Object target, Object value )
 129  
         throws OgnlException
 130  
     {
 131  27
         OgnlRuntime.setProperty( context, target, getProperty( context, target ), value );
 132  26
     }
 133  
 
 134  
     public boolean isNodeSimpleProperty( OgnlContext context )
 135  
         throws OgnlException
 136  
     {
 137  9
         return ( children != null ) && ( children.length == 1 ) && ( (SimpleNode) children[0] ).isConstant( context );
 138  
     }
 139  
 
 140  
     public Class getGetterClass()
 141  
     {
 142  859
         return getterClass;
 143  
     }
 144  
 
 145  
     public Class getSetterClass()
 146  
     {
 147  215
         return setterClass;
 148  
     }
 149  
 
 150  
     public String toGetSourceString( OgnlContext context, Object target )
 151  
     {
 152  710
         if ( context.getCurrentObject() == null )
 153  
         {
 154  27
             throw new UnsupportedCompilationException( "Current target is null." );
 155  
         }
 156  683
         String result = "";
 157  683
         Method m = null;
 158  
 
 159  
         try
 160  
         {
 161  
             /*
 162  
              * System.out.println("astproperty is indexed? : " + isIndexedAccess() + " child: " +
 163  
              * _children[0].getClass().getName() + " target: " + target.getClass().getName() + " current object: " +
 164  
              * context.getCurrentObject().getClass().getName());
 165  
              */
 166  
 
 167  683
             Node child = children[0];
 168  683
             if ( isIndexedAccess() )
 169  
             {
 170  107
                 Object value = child.getValue( context, context.getRoot() );
 171  
 
 172  106
                 if ( value == null || DynamicSubscript.class.isAssignableFrom( value.getClass() ) )
 173  
                 {
 174  27
                     throw new UnsupportedCompilationException(
 175  
                         "Value passed as indexed property was null or not supported." );
 176  
                 }
 177  
                 // Get root cast string if the child is a type that needs it (like a nested ASTProperty)
 178  
 
 179  79
                 String srcString = getSourceString( context, child );
 180  
 
 181  78
                 if ( context.get( "_indexedMethod" ) != null )
 182  
                 {
 183  15
                     m = (Method) context.remove( "_indexedMethod" );
 184  15
                     getterClass = m.getReturnType();
 185  
 
 186  15
                     Object indexedValue = OgnlRuntime.callMethod( context, target, m.getName(), new Object[]{ value } );
 187  
 
 188  12
                     context.setCurrentType( getterClass );
 189  12
                     context.setCurrentObject( indexedValue );
 190  12
                     context.setCurrentAccessor(
 191  
                         OgnlRuntime.getCompiler( context ).getSuperOrInterfaceClass( m, m.getDeclaringClass() ) );
 192  
 
 193  12
                     return "." + m.getName() + "(" + srcString + ")";
 194  
                 }
 195  
                 else
 196  
                 {
 197  63
                     PropertyAccessor propertyAccessor = OgnlRuntime.getPropertyAccessor( target.getClass() );
 198  
 
 199  
                     // System.out.println("child value : " + _children[0].getValue(context, context.getCurrentObject())
 200  
                     // + " using propaccessor " + p.getClass().getName()
 201  
                     // + " and srcString " + srcString + " on target: " + target);
 202  
 
 203  63
                     Object currentObject = context.getCurrentObject();
 204  63
                     if ( ASTConst.class.isInstance( child ) && Number.class.isInstance( currentObject ) )
 205  
                     {
 206  23
                         context.setCurrentType( OgnlRuntime.getPrimitiveWrapperClass( currentObject.getClass() ) );
 207  
                     }
 208  63
                     Object indexValue = propertyAccessor.getProperty( context, target, value );
 209  63
                     result = propertyAccessor.getSourceAccessor( context, target, srcString );
 210  63
                     getterClass = context.getCurrentType();
 211  63
                     context.setCurrentObject( indexValue );
 212  
 
 213  63
                     return result;
 214  
                 }
 215  
             }
 216  
 
 217  576
             String name = ( (ASTConst) child ).getValue().toString();
 218  
 
 219  576
             target = getTarget( context, target, name );
 220  
 
 221  576
             PropertyDescriptor pd = OgnlRuntime.getPropertyDescriptor( context.getCurrentObject().getClass(), name );
 222  
 
 223  576
             if ( pd != null && pd.getReadMethod() != null && !context.getMemberAccess().isAccessible( context,
 224  
                                                                                                       context.getCurrentObject(),
 225  
                                                                                                       pd.getReadMethod(),
 226  
                                                                                                       name ) )
 227  
             {
 228  2
                 throw new UnsupportedCompilationException( "Member access forbidden for property " + name + " on class "
 229  
                                                                + context.getCurrentObject().getClass() );
 230  
             }
 231  
 
 232  574
             if ( this.getIndexedPropertyType( context, context.getCurrentObject() ) > 0 && pd != null )
 233  
             {
 234  
                 // if an indexed method accessor need to use special property descriptors to find methods
 235  
 
 236  19
                 if ( pd instanceof IndexedPropertyDescriptor )
 237  
                 {
 238  7
                     m = ( (IndexedPropertyDescriptor) pd ).getIndexedReadMethod();
 239  
                 }
 240  
                 else
 241  
                 {
 242  12
                     if ( pd instanceof ObjectIndexedPropertyDescriptor )
 243  
                     {
 244  12
                         m = ( (ObjectIndexedPropertyDescriptor) pd ).getIndexedReadMethod();
 245  
                     }
 246  
                     else
 247  
                     {
 248  0
                         throw new OgnlException( "property '" + name + "' is not an indexed property" );
 249  
                     }
 250  
                 }
 251  
 
 252  19
                 if ( parent == null )
 253  
                 {
 254  
                     // the above pd will be the wrong result sometimes, such as methods like getValue(int) vs String[]
 255  
                     // getValue()
 256  0
                     m = OgnlRuntime.getReadMethod( context.getCurrentObject().getClass(), name );
 257  
 
 258  0
                     result = m.getName() + "()";
 259  0
                     getterClass = m.getReturnType();
 260  
                 }
 261  
                 else
 262  
                 {
 263  19
                     context.put( "_indexedMethod", m );
 264  
                 }
 265  
             }
 266  
             else
 267  
             {
 268  
 
 269  
                 /*
 270  
                  * System.out.println("astproperty trying to get " + name + " on object target: " +
 271  
                  * context.getCurrentObject().getClass().getName() + " current type " + context.getCurrentType() +
 272  
                  * " current accessor " + context.getCurrentAccessor() + " prev type " + context.getPreviousType() +
 273  
                  * " prev accessor " + context.getPreviousAccessor());
 274  
                  */
 275  
 
 276  555
                 PropertyAccessor pa = OgnlRuntime.getPropertyAccessor( context.getCurrentObject().getClass() );
 277  
 
 278  555
                 if ( context.getCurrentObject().getClass().isArray() )
 279  
                 {
 280  7
                     if ( pd == null )
 281  
                     {
 282  7
                         pd = OgnlRuntime.getProperty( context.getCurrentObject().getClass(), name );
 283  
 
 284  7
                         if ( pd != null && pd.getReadMethod() != null )
 285  
                         {
 286  0
                             m = pd.getReadMethod();
 287  0
                             result = pd.getName();
 288  
                         }
 289  
                         else
 290  
                         {
 291  7
                             getterClass = int.class;
 292  7
                             context.setCurrentAccessor( context.getCurrentObject().getClass() );
 293  7
                             context.setCurrentType( int.class );
 294  7
                             result = "." + name;
 295  
                         }
 296  
                     }
 297  
                 }
 298  
                 else
 299  
                 {
 300  548
                     if ( pd != null && pd.getReadMethod() != null )
 301  
                     {
 302  458
                         m = pd.getReadMethod();
 303  458
                         result = "." + m.getName() + "()";
 304  
                     }
 305  90
                     else if ( pa != null )
 306  
                     {
 307  90
                         Object currObj = context.getCurrentObject();
 308  90
                         Class currType = context.getCurrentType();
 309  90
                         Class prevType = context.getPreviousType();
 310  
 
 311  90
                         String srcString = child.toGetSourceString( context, context.getRoot() );
 312  
 
 313  90
                         if ( ASTConst.class.isInstance( child ) && String.class.isInstance(
 314  
                             context.getCurrentObject() ) )
 315  
                         {
 316  90
                             srcString = "\"" + srcString + "\"";
 317  
                         }
 318  90
                         context.setCurrentObject( currObj );
 319  90
                         context.setCurrentType( currType );
 320  90
                         context.setPreviousType( prevType );
 321  
 
 322  90
                         result = pa.getSourceAccessor( context, context.getCurrentObject(), srcString );
 323  
 
 324  90
                         getterClass = context.getCurrentType();
 325  
                     }
 326  
                 }
 327  
             }
 328  
 
 329  
         }
 330  34
         catch ( Throwable t )
 331  
         {
 332  34
             throw OgnlOps.castToRuntime( t );
 333  574
         }
 334  
 
 335  
         // set known property types for NodeType interface when possible
 336  
 
 337  574
         if ( m != null )
 338  
         {
 339  477
             getterClass = m.getReturnType();
 340  
 
 341  477
             context.setCurrentType( m.getReturnType() );
 342  477
             context.setCurrentAccessor(
 343  
                 OgnlRuntime.getCompiler( context ).getSuperOrInterfaceClass( m, m.getDeclaringClass() ) );
 344  
         }
 345  
 
 346  574
         context.setCurrentObject( target );
 347  
 
 348  574
         return result;
 349  
     }
 350  
 
 351  
     Object getTarget( OgnlContext context, Object target, String name )
 352  
         throws OgnlException
 353  
     {
 354  798
         Class<?> clazz = context.getCurrentObject().getClass();
 355  798
         if ( !Iterator.class.isAssignableFrom( clazz ) || ( Iterator.class.isAssignableFrom( clazz ) && !name.contains(
 356  
             "next" ) ) )
 357  
         {
 358  796
             Object currObj = target;
 359  
 
 360  
             try
 361  
             {
 362  796
                 target = getValue( context, context.getCurrentObject() );
 363  
             }
 364  57
             catch ( NoSuchPropertyException e )
 365  
             {
 366  
                 try
 367  
                 {
 368  57
                     target = getValue( context, context.getRoot() );
 369  
                 }
 370  41
                 catch ( NoSuchPropertyException ex )
 371  
                 {
 372  
                     // ignore
 373  16
                 }
 374  
             }
 375  
             finally
 376  
             {
 377  796
                 context.setCurrentObject( currObj );
 378  796
             }
 379  
         }
 380  798
         return target;
 381  
     }
 382  
 
 383  
     Method getIndexedWriteMethod( PropertyDescriptor pd )
 384  
     {
 385  9
         if ( IndexedPropertyDescriptor.class.isInstance( pd ) )
 386  
         {
 387  1
             return ( (IndexedPropertyDescriptor) pd ).getIndexedWriteMethod();
 388  
         }
 389  8
         else if ( ObjectIndexedPropertyDescriptor.class.isInstance( pd ) )
 390  
         {
 391  8
             return ( (ObjectIndexedPropertyDescriptor) pd ).getIndexedWriteMethod();
 392  
         }
 393  
 
 394  0
         return null;
 395  
     }
 396  
 
 397  
     public String toSetSourceString( OgnlContext context, Object target )
 398  
     {
 399  306
         String result = "";
 400  306
         Method m = null;
 401  
 
 402  306
         if ( context.getCurrentObject() == null )
 403  
         {
 404  23
             throw new UnsupportedCompilationException( "Current target is null." );
 405  
         }
 406  
         /*
 407  
          * System.out.println("astproperty(setter) is indexed? : " + isIndexedAccess() + " child: " +
 408  
          * _children[0].getClass().getName() + " target: " + target.getClass().getName() + " children length: " +
 409  
          * _children.length);
 410  
          */
 411  
 
 412  
         try
 413  
         {
 414  
 
 415  283
             Node child = children[0];
 416  283
             if ( isIndexedAccess() )
 417  
             {
 418  61
                 Object value = child.getValue( context, context.getRoot() );
 419  
 
 420  61
                 if ( value == null )
 421  
                 {
 422  0
                     throw new UnsupportedCompilationException(
 423  
                         "Value passed as indexed property is null, can't enhance statement to bytecode." );
 424  
                 }
 425  
 
 426  61
                 String srcString = getSourceString( context, child );
 427  
 
 428  
                 // System.out.println("astproperty setter using indexed value " + value + " and srcString: " +
 429  
                 // srcString);
 430  
 
 431  61
                 if ( context.get( "_indexedMethod" ) != null )
 432  
                 {
 433  12
                     m = (Method) context.remove( "_indexedMethod" );
 434  12
                     PropertyDescriptor pd = (PropertyDescriptor) context.remove( "_indexedDescriptor" );
 435  
 
 436  12
                     boolean lastChild = lastChild( context );
 437  12
                     if ( lastChild )
 438  
                     {
 439  9
                         m = getIndexedWriteMethod( pd );
 440  
 
 441  9
                         if ( m == null )
 442  
                         {
 443  1
                             throw new UnsupportedCompilationException(
 444  
                                 "Indexed property has no corresponding write method." );
 445  
                         }
 446  
                     }
 447  
 
 448  11
                     setterClass = m.getParameterTypes()[0];
 449  
 
 450  11
                     Object indexedValue = null;
 451  11
                     if ( !lastChild )
 452  
                     {
 453  3
                         indexedValue = OgnlRuntime.callMethod( context, target, m.getName(), new Object[]{ value } );
 454  
                     }
 455  11
                     context.setCurrentType( setterClass );
 456  11
                     context.setCurrentAccessor(
 457  
                         OgnlRuntime.getCompiler( context ).getSuperOrInterfaceClass( m, m.getDeclaringClass() ) );
 458  
 
 459  11
                     if ( !lastChild )
 460  
                     {
 461  3
                         context.setCurrentObject( indexedValue );
 462  3
                         return "." + m.getName() + "(" + srcString + ")";
 463  
                     }
 464  
                     else
 465  
                     {
 466  8
                         return "." + m.getName() + "(" + srcString + ", $3)";
 467  
                     }
 468  
                 }
 469  
                 else
 470  
                 {
 471  49
                     PropertyAccessor propertyAccessor = OgnlRuntime.getPropertyAccessor( target.getClass() );
 472  
 
 473  49
                     Object currentObject = context.getCurrentObject();
 474  49
                     if ( ASTConst.class.isInstance( child ) && Number.class.isInstance( currentObject ) )
 475  
                     {
 476  15
                         context.setCurrentType( OgnlRuntime.getPrimitiveWrapperClass( currentObject.getClass() ) );
 477  
                     }
 478  49
                     Object indexValue = propertyAccessor.getProperty( context, target, value );
 479  49
                     result = lastChild( context )
 480  
                         ? propertyAccessor.getSourceSetter( context, target, srcString )
 481  
                         : propertyAccessor.getSourceAccessor( context, target, srcString );
 482  
 
 483  
                     /*
 484  
                      * System.out.println("ASTProperty using propertyaccessor and isLastChild? " + lastChild(context) +
 485  
                      * " generated source of: " + result + " using accessor class: " + p.getClass().getName());
 486  
                      */
 487  
 
 488  
                     // result = p.getSourceAccessor(context, target, srcString);
 489  46
                     getterClass = context.getCurrentType();
 490  46
                     context.setCurrentObject( indexValue );
 491  
 
 492  
                     /*
 493  
                      * PropertyAccessor p = OgnlRuntime.getPropertyAccessor(target.getClass()); if
 494  
                      * (ASTConst.class.isInstance(_children[0]) && Number.class.isInstance(context.getCurrentObject()))
 495  
                      * {
 496  
                      * context.setCurrentType(OgnlRuntime.getPrimitiveWrapperClass(context.getCurrentObject().getClass(
 497  
                      * ))); } result = p.getSourceSetter(context, target, srcString); context.setCurrentObject(value);
 498  
                      * context.setCurrentType(getterClass);
 499  
                      */
 500  46
                     return result;
 501  
                 }
 502  
             }
 503  
 
 504  222
             String name = ( (ASTConst) child ).getValue().toString();
 505  
 
 506  
             // System.out.println(" astprop(setter) : trying to set " + name + " on object target " +
 507  
             // context.getCurrentObject().getClass().getName());
 508  
 
 509  222
             target = getTarget( context, target, name );
 510  
 
 511  222
             PropertyDescriptor pd = OgnlRuntime.getPropertyDescriptor(
 512  
                 OgnlRuntime.getCompiler( context ).getInterfaceClass( context.getCurrentObject().getClass() ), name );
 513  
 
 514  222
             if ( pd != null )
 515  
             {
 516  170
                 Method pdMethod = lastChild( context ) ? pd.getWriteMethod() : pd.getReadMethod();
 517  
 
 518  170
                 if ( pdMethod != null && !context.getMemberAccess().isAccessible( context, context.getCurrentObject(),
 519  
                                                                                   pdMethod, name ) )
 520  
                 {
 521  2
                     throw new UnsupportedCompilationException(
 522  
                         "Member access forbidden for property " + name + " on class "
 523  
                             + context.getCurrentObject().getClass() );
 524  
                 }
 525  
             }
 526  
 
 527  220
             if ( pd != null && this.getIndexedPropertyType( context, context.getCurrentObject() ) > 0 )
 528  
             {
 529  
                 // if an indexed method accessor need to use special property descriptors to find methods
 530  
 
 531  12
                 if ( pd instanceof IndexedPropertyDescriptor )
 532  
                 {
 533  1
                     IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
 534  1
                     m = lastChild( context ) ? ipd.getIndexedWriteMethod() : ipd.getIndexedReadMethod();
 535  1
                 }
 536  
                 else
 537  
                 {
 538  11
                     if ( pd instanceof ObjectIndexedPropertyDescriptor )
 539  
                     {
 540  11
                         ObjectIndexedPropertyDescriptor opd = (ObjectIndexedPropertyDescriptor) pd;
 541  
 
 542  11
                         m = lastChild( context ) ? opd.getIndexedWriteMethod() : opd.getIndexedReadMethod();
 543  11
                     }
 544  
                     else
 545  
                     {
 546  0
                         throw new OgnlException( "property '" + name + "' is not an indexed property" );
 547  
                     }
 548  
                 }
 549  
 
 550  12
                 if ( parent == null )
 551  
                 {
 552  
                     // the above pd will be the wrong result sometimes, such as methods like getValue(int) vs String[]
 553  
                     // getValue()
 554  
 
 555  0
                     m = OgnlRuntime.getWriteMethod( context.getCurrentObject().getClass(), name );
 556  0
                     Class parm = m.getParameterTypes()[0];
 557  0
                     String cast = parm.isArray() ? ExpressionCompiler.getCastString( parm ) : parm.getName();
 558  
 
 559  0
                     result = m.getName() + "((" + cast + ")$3)";
 560  0
                     setterClass = parm;
 561  0
                 }
 562  
                 else
 563  
                 {
 564  12
                     context.put( "_indexedMethod", m );
 565  12
                     context.put( "_indexedDescriptor", pd );
 566  
                 }
 567  
 
 568  
             }
 569  
             else
 570  
             {
 571  208
                 PropertyAccessor pa = OgnlRuntime.getPropertyAccessor( context.getCurrentObject().getClass() );
 572  
 
 573  
                 /*
 574  
                  * System.out.println("astproperty trying to set " + name + " on object target: " +
 575  
                  * context.getCurrentObject().getClass().getName() + " using propertyaccessor type: " + pa);
 576  
                  */
 577  
 
 578  208
                 if ( target != null )
 579  
                 {
 580  198
                     setterClass = target.getClass();
 581  
                 }
 582  208
                 if ( parent != null && pd != null && pa == null )
 583  
                 {
 584  0
                     m = pd.getReadMethod();
 585  0
                     result = m.getName() + "()";
 586  
                 }
 587  
                 else
 588  
                 {
 589  208
                     if ( context.getCurrentObject().getClass().isArray() )
 590  
                     {
 591  2
                         result = "";
 592  
                     }
 593  206
                     else if ( pa != null )
 594  
                     {
 595  206
                         Object currObj = context.getCurrentObject();
 596  
                         // Class currType = context.getCurrentType();
 597  
                         // Class prevType = context.getPreviousType();
 598  
 
 599  206
                         String srcString = child.toGetSourceString( context, context.getRoot() );
 600  
 
 601  206
                         if ( ASTConst.class.isInstance( child ) && String.class.isInstance(
 602  
                             context.getCurrentObject() ) )
 603  
                         {
 604  206
                             srcString = "\"" + srcString + "\"";
 605  
                         }
 606  
 
 607  206
                         context.setCurrentObject( currObj );
 608  
                         // context.setCurrentType(currType);
 609  
                         // context.setPreviousType(prevType);
 610  
 
 611  206
                         if ( !lastChild( context ) )
 612  
                         {
 613  112
                             result = pa.getSourceAccessor( context, context.getCurrentObject(), srcString );
 614  
                         }
 615  
                         else
 616  
                         {
 617  94
                             result = pa.getSourceSetter( context, context.getCurrentObject(), srcString );
 618  
                         }
 619  
 
 620  172
                         getterClass = context.getCurrentType();
 621  
                     }
 622  
                 }
 623  
             }
 624  
 
 625  
         }
 626  40
         catch ( Throwable t )
 627  
         {
 628  40
             throw OgnlOps.castToRuntime( t );
 629  186
         }
 630  
 
 631  186
         context.setCurrentObject( target );
 632  
 
 633  186
         if ( m != null )
 634  
         {
 635  12
             context.setCurrentType( m.getReturnType() );
 636  12
             context.setCurrentAccessor(
 637  
                 OgnlRuntime.getCompiler( context ).getSuperOrInterfaceClass( m, m.getDeclaringClass() ) );
 638  
         }
 639  
 
 640  186
         return result;
 641  
     }
 642  
 
 643  
     public <R, P> R accept( NodeVisitor<? extends R, ? super P> visitor, P data )
 644  
         throws OgnlException
 645  
     {
 646  2
         return visitor.visit( this, data );
 647  
     }
 648  
 
 649  
     private static String getSourceString( OgnlContext context, Node child )
 650  
     {
 651  140
         String srcString = child.toGetSourceString( context, context.getRoot() );
 652  139
         srcString = ExpressionCompiler.getRootExpression( child, context.getRoot(), context ) + srcString;
 653  
 
 654  139
         if ( ASTChain.class.isInstance( child ) )
 655  
         {
 656  2
             String cast = (String) context.remove( ExpressionCompiler.PRE_CAST );
 657  2
             if ( cast != null )
 658  
             {
 659  2
                 srcString = cast + srcString;
 660  
             }
 661  
         }
 662  
 
 663  139
         if ( ASTConst.class.isInstance( child ) && String.class.isInstance( context.getCurrentObject() ) )
 664  
         {
 665  47
             srcString = "\"" + srcString + "\"";
 666  
         }
 667  
         // System.out.println("indexed getting with child srcString: " + srcString + " value class: " +
 668  
         // value.getClass() + " and child: " + _children[0].getClass());
 669  139
         return srcString;
 670  
     }
 671  
 
 672  
 }