blob: 586bc33b1ab2a3bbd3c83e88682025062db8c289 [file] [log] [blame]
package org.apache.commons.ognl;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.commons.ognl.enhance.ExpressionCompiler;
import org.apache.commons.ognl.enhance.OgnlExpressionCompiler;
import org.apache.commons.ognl.enhance.UnsupportedCompilationException;
import java.lang.reflect.Method;
/**
* $Id$
*/
public class ASTStaticMethod
extends SimpleNode
implements NodeType
{
private String className;
private String methodName;
private Class getterClass;
public ASTStaticMethod( int id )
{
super( id );
}
public ASTStaticMethod( OgnlParser p, int id )
{
super( p, id );
}
/**
* Called from parser action.
*/
void init( String className, String methodName )
{
this.className = className;
this.methodName = methodName;
}
protected Object getValueBody( OgnlContext context, Object source )
throws OgnlException
{
Object[] args = new Object[jjtGetNumChildren()];
Object root = context.getRoot();
for ( int i = 0, icount = args.length; i < icount; ++i )
{
args[i] = children[i].getValue( context, root );
}
return OgnlRuntime.callStaticMethod( context, className, methodName, args );
}
public Class getGetterClass()
{
return getterClass;
}
public Class getSetterClass()
{
return getterClass;
}
public String toGetSourceString( OgnlContext context, Object target )
{
StringBuilder result = new StringBuilder(className + "#" + methodName + "(");
try
{
Class clazz = OgnlRuntime.classForName( context, className );
Method m = OgnlRuntime.getMethod( context, clazz, methodName, children, true );
if ( m == null )
{
throw new UnsupportedCompilationException(
"Unable to find class/method combo " + className + " / " + methodName );
}
if ( !context.getMemberAccess().isAccessible( context, clazz, m, methodName ) )
{
throw new UnsupportedCompilationException(
"Method is not accessible, check your jvm runtime security settings. " + "For static class method "
+ className + " / " + methodName );
}
OgnlExpressionCompiler compiler = OgnlRuntime.getCompiler( context );
if ( ( children != null ) && ( children.length > 0 ) )
{
Class[] parms = m.getParameterTypes();
for ( int i = 0; i < children.length; i++ )
{
if ( i > 0 )
{
result.append(", ");
}
Class prevType = context.getCurrentType();
Node child = children[i];
Object root = context.getRoot();
String parmString = ASTMethodUtil.getParmString( context, root, child, prevType );
Class valueClass = ASTMethodUtil.getValueClass( context, root, child );
if ( valueClass != parms[i] )
{
if ( parms[i].isArray() )
{
parmString = compiler.createLocalReference( context, "(" + ExpressionCompiler.getCastString(
parms[i] ) + ")org.apache.commons.ognl.OgnlOps.toArray(" + parmString + ", "
+ parms[i].getComponentType().getName() + ".class, true)", parms[i] );
}
else if ( parms[i].isPrimitive() )
{
Class wrapClass = OgnlRuntime.getPrimitiveWrapperClass( parms[i] );
parmString = compiler.createLocalReference( context, "((" + wrapClass.getName()
+ ")org.apache.commons.ognl.OgnlOps.convertValue(" + parmString + ","
+ wrapClass.getName() + ".class, true))." + OgnlRuntime.getNumericValueGetter(
wrapClass ), parms[i] );
}
else if ( parms[i] != Object.class )
{
parmString = compiler.createLocalReference( context, "(" + parms[i].getName()
+ ")org.apache.commons.ognl.OgnlOps.convertValue(" + parmString + ","
+ parms[i].getName() + ".class)", parms[i] );
}
else if ( ( NodeType.class.isInstance( child ) && ( (NodeType) child ).getGetterClass() != null
&& Number.class.isAssignableFrom( ( (NodeType) child ).getGetterClass() ) )
|| valueClass.isPrimitive() )
{
parmString = " ($w) " + parmString;
}
else if ( valueClass.isPrimitive() )
{
parmString = "($w) " + parmString;
}
}
result.append(parmString);
}
}
result.append(")");
try
{
Object contextObj = getValueBody( context, target );
context.setCurrentObject( contextObj );
}
catch ( Throwable t )
{
// ignore
}
if ( m != null )
{
getterClass = m.getReturnType();
context.setCurrentType( m.getReturnType() );
context.setCurrentAccessor( compiler.getSuperOrInterfaceClass( m, m.getDeclaringClass() ) );
}
}
catch ( Throwable t )
{
throw OgnlOps.castToRuntime( t );
}
return result.toString();
}
public String toSetSourceString( OgnlContext context, Object target )
{
return toGetSourceString( context, target );
}
public <R, P> R accept( NodeVisitor<? extends R, ? super P> visitor, P data )
throws OgnlException
{
return visitor.visit( this, data );
}
/**
* Get the class name for this method.
*
* @return the class name.
* @since 4.0
*/
public String getClassName()
{
return className;
}
/**
* Get the method name for this method.
*
* @return the method name.
* @since 4.0
*/
public String getMethodName()
{
return methodName;
}
}