Coverage Report - org.apache.commons.ognl.ASTStaticMethod
 
Classes in this File Line Coverage Branch Coverage Complexity
ASTStaticMethod
78%
51/65
52%
19/36
3.182
 
 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.OgnlExpressionCompiler;
 24  
 import org.apache.commons.ognl.enhance.UnsupportedCompilationException;
 25  
 
 26  
 import java.lang.reflect.Method;
 27  
 
 28  
 /**
 29  
  * $Id: ASTStaticMethod.java 1194869 2011-10-29 11:10:16Z mcucchiara $
 30  
  *
 31  
  * @author Luke Blanshard (blanshlu@netscape.net)
 32  
  * @author Drew Davidson (drew@ognl.org)
 33  
  */
 34  
 public class ASTStaticMethod
 35  
     extends SimpleNode
 36  
     implements NodeType
 37  
 {
 38  
 
 39  
     private String className;
 40  
 
 41  
     private String methodName;
 42  
 
 43  
     private Class getterClass;
 44  
 
 45  
     public ASTStaticMethod( int id )
 46  
     {
 47  20
         super( id );
 48  20
     }
 49  
 
 50  
     public ASTStaticMethod( OgnlParser p, int id )
 51  
     {
 52  0
         super( p, id );
 53  0
     }
 54  
 
 55  
     /**
 56  
      * Called from parser action.
 57  
      */
 58  
     void init( String className, String methodName )
 59  
     {
 60  20
         this.className = className;
 61  20
         this.methodName = methodName;
 62  20
     }
 63  
 
 64  
     protected Object getValueBody( OgnlContext context, Object source )
 65  
         throws OgnlException
 66  
     {
 67  27
         ObjectArrayPool objectArrayPool = OgnlRuntime.getObjectArrayPool();
 68  27
         Object[] args = objectArrayPool.create( jjtGetNumChildren() );
 69  27
         Object root = context.getRoot();
 70  
 
 71  
         try
 72  
         {
 73  48
             for ( int i = 0, icount = args.length; i < icount; ++i )
 74  
             {
 75  21
                 args[i] = children[i].getValue( context, root );
 76  
             }
 77  
 
 78  27
             return OgnlRuntime.callStaticMethod( context, className, methodName, args );
 79  
         }
 80  
         finally
 81  
         {
 82  26
             objectArrayPool.recycle( args );
 83  
         }
 84  
     }
 85  
 
 86  
     public Class getGetterClass()
 87  
     {
 88  4
         return getterClass;
 89  
     }
 90  
 
 91  
     public Class getSetterClass()
 92  
     {
 93  0
         return getterClass;
 94  
     }
 95  
 
 96  
     public String toGetSourceString( OgnlContext context, Object target )
 97  
     {
 98  20
         String result = className + "#" + methodName + "(";
 99  
 
 100  
         try
 101  
         {
 102  20
             Class clazz = OgnlRuntime.classForName( context, className );
 103  20
             Method m = OgnlRuntime.getMethod( context, clazz, methodName, children, true );
 104  
 
 105  20
             if ( clazz == null || m == null )
 106  
             {
 107  2
                 throw new UnsupportedCompilationException(
 108  
                     "Unable to find class/method combo " + className + " / " + methodName );
 109  
             }
 110  
 
 111  18
             if ( !context.getMemberAccess().isAccessible( context, clazz, m, methodName ) )
 112  
             {
 113  2
                 throw new UnsupportedCompilationException(
 114  
                     "Method is not accessible, check your jvm runtime security settings. " + "For static class method "
 115  
                         + className + " / " + methodName );
 116  
             }
 117  
 
 118  16
             OgnlExpressionCompiler compiler = OgnlRuntime.getCompiler( context );
 119  16
             if ( ( children != null ) && ( children.length > 0 ) )
 120  
             {
 121  10
                 Class[] parms = m.getParameterTypes();
 122  
 
 123  22
                 for ( int i = 0; i < children.length; i++ )
 124  
                 {
 125  12
                     if ( i > 0 )
 126  
                     {
 127  2
                         result = result + ", ";
 128  
                     }
 129  
 
 130  12
                     Class prevType = context.getCurrentType();
 131  
 
 132  12
                     Node child = children[i];
 133  12
                     Object root = context.getRoot();
 134  
 
 135  12
                     String parmString = ASTMethodUtil.getParmString( context, root, child, prevType );
 136  
 
 137  12
                     Class valueClass = ASTMethodUtil.getValueClass( context, root, child );
 138  
 
 139  12
                     if ( valueClass != parms[i] )
 140  
                     {
 141  4
                         if ( parms[i].isArray() )
 142  
                         {
 143  0
                             parmString = compiler.createLocalReference( context, "(" + ExpressionCompiler.getCastString(
 144  
                                 parms[i] ) + ")org.apache.commons.ognl.OgnlOps.toArray(" + parmString + ", "
 145  
                                 + parms[i].getComponentType().getName() + ".class, true)", parms[i] );
 146  
 
 147  
                         }
 148  4
                         else if ( parms[i].isPrimitive() )
 149  
                         {
 150  4
                             Class wrapClass = OgnlRuntime.getPrimitiveWrapperClass( parms[i] );
 151  
 
 152  4
                             parmString = compiler.createLocalReference( context, "((" + wrapClass.getName()
 153  
                                 + ")org.apache.commons.ognl.OgnlOps.convertValue(" + parmString + ","
 154  
                                 + wrapClass.getName() + ".class, true))." + OgnlRuntime.getNumericValueGetter(
 155  
                                 wrapClass ), parms[i] );
 156  
 
 157  4
                         }
 158  0
                         else if ( parms[i] != Object.class )
 159  
                         {
 160  0
                             parmString = compiler.createLocalReference( context, "(" + parms[i].getName()
 161  
                                 + ")org.apache.commons.ognl.OgnlOps.convertValue(" + parmString + ","
 162  
                                 + parms[i].getName() + ".class)", parms[i] );
 163  
                         }
 164  0
                         else if ( ( NodeType.class.isInstance( child ) && ( (NodeType) child ).getGetterClass() != null
 165  
                             && Number.class.isAssignableFrom( ( (NodeType) child ).getGetterClass() ) )
 166  
                             || valueClass.isPrimitive() )
 167  
                         {
 168  0
                             parmString = " ($w) " + parmString;
 169  
                         }
 170  0
                         else if ( valueClass.isPrimitive() )
 171  
                         {
 172  0
                             parmString = "($w) " + parmString;
 173  
                         }
 174  
                     }
 175  
 
 176  12
                     result += parmString;
 177  
                 }
 178  
             }
 179  
 
 180  16
             result += ")";
 181  
 
 182  
             try
 183  
             {
 184  16
                 Object contextObj = getValueBody( context, target );
 185  16
                 context.setCurrentObject( contextObj );
 186  
             }
 187  0
             catch ( Throwable t )
 188  
             {
 189  
                 // ignore
 190  16
             }
 191  
 
 192  16
             if ( m != null )
 193  
             {
 194  16
                 getterClass = m.getReturnType();
 195  
 
 196  16
                 context.setCurrentType( m.getReturnType() );
 197  16
                 context.setCurrentAccessor( compiler.getSuperOrInterfaceClass( m, m.getDeclaringClass() ) );
 198  
             }
 199  
 
 200  
         }
 201  4
         catch ( Throwable t )
 202  
         {
 203  4
             throw OgnlOps.castToRuntime( t );
 204  16
         }
 205  
 
 206  16
         return result;
 207  
     }
 208  
 
 209  
     public String toSetSourceString( OgnlContext context, Object target )
 210  
     {
 211  7
         return toGetSourceString( context, target );
 212  
     }
 213  
 
 214  
     public <R, P> R accept( NodeVisitor<? extends R, ? super P> visitor, P data )
 215  
         throws OgnlException
 216  
     {
 217  0
         return visitor.visit( this, data );
 218  
     }
 219  
 
 220  
     /**
 221  
      * Get the class name for this method.
 222  
      *
 223  
      * @return the class name.
 224  
      * @since 4.0
 225  
      */
 226  
     public String getClassName()
 227  
     {
 228  0
         return className;
 229  
     }
 230  
 
 231  
     /**
 232  
      * Get the method name for this method.
 233  
      *
 234  
      * @return the method name.
 235  
      * @since 4.0
 236  
      */
 237  
     public String getMethodName()
 238  
     {
 239  0
         return methodName;
 240  
     }
 241  
 }