blob: 677ea2c877352fcfe4f354699f725c6052d6e291 [file] [log] [blame]
/*
* $Id$
* 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.
*/
package org.apache.commons.ognl;
import org.apache.commons.ognl.enhance.OgnlExpressionCompiler;
import org.apache.commons.ognl.internal.CacheException;
import org.apache.commons.ognl.test.objects.BaseGeneric;
import org.apache.commons.ognl.test.objects.Bean1;
import org.apache.commons.ognl.test.objects.Bean2;
import org.apache.commons.ognl.test.objects.FormImpl;
import org.apache.commons.ognl.test.objects.GameGeneric;
import org.apache.commons.ognl.test.objects.GameGenericObject;
import org.apache.commons.ognl.test.objects.GenericCracker;
import org.apache.commons.ognl.test.objects.GenericService;
import org.apache.commons.ognl.test.objects.GenericServiceImpl;
import org.apache.commons.ognl.test.objects.GetterMethods;
import org.apache.commons.ognl.test.objects.IComponent;
import org.apache.commons.ognl.test.objects.IForm;
import org.apache.commons.ognl.test.objects.ListSource;
import org.apache.commons.ognl.test.objects.ListSourceImpl;
import org.apache.commons.ognl.test.objects.OtherObjectIndexed;
import org.apache.commons.ognl.test.objects.Root;
import org.apache.commons.ognl.test.objects.SetterReturns;
import org.apache.commons.ognl.test.objects.SubclassSyntheticObject;
import org.junit.Test;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import static junit.framework.Assert.*;
/**
* Tests various methods / functionality of {@link org.apache.commons.ognl.OgnlRuntime}.
*/
public class TestOgnlRuntime
{
@Test
public void test_Get_Super_Or_Interface_Class()
throws Exception
{
ListSource list = new ListSourceImpl();
Method method = OgnlRuntime.getReadMethod( list.getClass(), "total" );
assertNotNull( method );
OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null );
assertEquals( ListSource.class,
OgnlRuntime.getCompiler( context ).getSuperOrInterfaceClass( method, list.getClass() ) );
}
@Test
public void test_Get_Private_Class()
throws Exception
{
List<String> list = Arrays.asList( "hello", "world" );
Method m = OgnlRuntime.getReadMethod( list.getClass(), "iterator" );
assertNotNull( m );
OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null );
assertEquals( Iterable.class,
OgnlRuntime.getCompiler( context ).getSuperOrInterfaceClass( m, list.getClass() ) );
}
@Test
public void test_Complicated_Inheritance()
throws Exception
{
IForm form = new FormImpl();
Method method = OgnlRuntime.getWriteMethod( form.getClass(), "clientId" );
assertNotNull( method );
OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null );
assertEquals( IComponent.class,
OgnlRuntime.getCompiler( context ).getSuperOrInterfaceClass( method, form.getClass() ) );
}
@Test
public void test_Get_Read_Method()
throws Exception
{
Method method = OgnlRuntime.getReadMethod( Bean2.class, "pageBreakAfter" );
assertNotNull( method );
assertEquals( "isPageBreakAfter", method.getName() );
}
class TestGetters
{
public boolean isEditorDisabled()
{
return false;
}
public boolean isDisabled()
{
return true;
}
public boolean isNotAvailable()
{
return false;
}
public boolean isAvailable()
{
return true;
}
}
@Test
public void test_Get_Read_Method_Multiple()
throws Exception
{
Method method = OgnlRuntime.getReadMethod( TestGetters.class, "disabled" );
assertNotNull( method );
assertEquals( "isDisabled", method.getName() );
}
@Test
public void test_Get_Read_Method_Multiple_Boolean_Getters()
throws Exception
{
Method method = OgnlRuntime.getReadMethod( TestGetters.class, "available" );
assertNotNull( method );
assertEquals( "isAvailable", method.getName() );
method = OgnlRuntime.getReadMethod( TestGetters.class, "notAvailable" );
assertNotNull( method );
assertEquals( "isNotAvailable", method.getName() );
}
@Test
public void test_Find_Method_Mixed_Boolean_Getters()
throws Exception
{
Method method = OgnlRuntime.getReadMethod( GetterMethods.class, "allowDisplay" );
assertNotNull( method );
assertEquals( "getAllowDisplay", method.getName() );
}
@Test
public void test_Get_Appropriate_Method()
throws Exception
{
ListSource list = new ListSourceImpl();
OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null );
Object ret = OgnlRuntime.callMethod( context, list, "addValue", new String[]{ null } );
assert ret != null;
}
@Test
public void test_Call_Static_Method_Invalid_Class()
{
try
{
OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null );
OgnlRuntime.callStaticMethod( context, "made.up.Name", "foo", null );
fail( "ClassNotFoundException should have been thrown by previous reference to <made.up.Name> class." );
}
catch ( Exception et )
{
assertTrue( MethodFailedException.class.isInstance( et ) );
assertTrue( et.getMessage().contains( "made.up.Name" ) );
}
}
@Test
public void test_Setter_Returns()
throws Exception
{
OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null );
SetterReturns root = new SetterReturns();
Method m = OgnlRuntime.getWriteMethod( root.getClass(), "value" );
assertNotNull(m);
Ognl.setValue( "value", context, root, "12__" );
assertEquals( Ognl.getValue( "value", context, root ), "12__" );
}
@Test
public void test_Call_Method_VarArgs()
throws Exception
{
OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null );
GenericService service = new GenericServiceImpl();
GameGenericObject argument = new GameGenericObject();
Object[] args = new Object[2];
args[0] = argument;
assertEquals( "Halo 3", OgnlRuntime.callMethod( context, service, "getFullMessageFor", args ) );
}
@Test
public void test_Class_Cache_Inspector()
throws Exception
{
OgnlRuntime.cache.clear();
assertEquals( 0, OgnlRuntime.cache.propertyDescriptorCache.getSize() );
Root root = new Root();
OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null );
Node expr = Ognl.compileExpression( context, root, "property.bean3.value != null" );
assertTrue( (Boolean) expr.getAccessor().get( context, root ) );
int size = OgnlRuntime.cache.propertyDescriptorCache.getSize();
assertTrue( size > 0 );
OgnlRuntime.clearCache();
assertEquals( 0, OgnlRuntime.cache.propertyDescriptorCache.getSize() );
// now register class cache prevention
OgnlRuntime.setClassCacheInspector( new TestCacheInspector() );
expr = Ognl.compileExpression( context, root, "property.bean3.value != null" );
assertTrue( (Boolean) expr.getAccessor().get( context, root ) );
assertEquals( ( size - 1 ), OgnlRuntime.cache.propertyDescriptorCache.getSize() );
}
class TestCacheInspector
implements ClassCacheInspector
{
public boolean shouldCache( Class<?> type )
{
return !( type == null || type == Root.class );
}
}
@Test
public void test_Set_Generic_Parameter_Types()
throws Exception
{
OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null );
Method method = OgnlRuntime.getSetMethod( context, GenericCracker.class, "param" );
assertNotNull( method );
Class<?>[] types = method.getParameterTypes();
assertEquals( 1, types.length );
assertEquals( Integer.class, types[0] );
}
@Test
public void test_Get_Generic_Parameter_Types()
throws Exception
{
OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null );
Method method = OgnlRuntime.getGetMethod( context, GenericCracker.class, "param" );
assertNotNull( method );
assertEquals( Integer.class, method.getReturnType() );
}
@Test
public void test_Find_Parameter_Types()
throws Exception
{
OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null );
Method method = OgnlRuntime.getSetMethod( context, GameGeneric.class, "ids" );
assertNotNull( method );
Class<?>[] types = OgnlRuntime.findParameterTypes( GameGeneric.class, method );
assertEquals( 1, types.length );
assertEquals( Long[].class, types[0] );
}
@Test
public void test_Find_Parameter_Types_Superclass()
throws Exception
{
OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null );
Method method = OgnlRuntime.getSetMethod( context, BaseGeneric.class, "ids" );
assertNotNull( method );
Class<?>[] types = OgnlRuntime.findParameterTypes( BaseGeneric.class, method );
assertEquals( 1, types.length );
assertEquals( Serializable[].class, types[0] );
}
@Test
public void test_Get_Declared_Methods_With_Synthetic_Methods()
throws Exception
{
List<Method> result = OgnlRuntime.getDeclaredMethods( SubclassSyntheticObject.class, "list", false );
// synthetic method would be
// "public volatile java.util.List org.ognl.test.objects.SubclassSyntheticObject.getList()",
// causing method return size to be 3
assertEquals( 2, result.size() );
}
@Test
public void test_Get_Property_Descriptors_With_Synthetic_Methods()
throws Exception
{
PropertyDescriptor propertyDescriptor = OgnlRuntime.getPropertyDescriptor( SubclassSyntheticObject.class, "list" );
assert propertyDescriptor != null;
assert OgnlRuntime.isMethodCallable( propertyDescriptor.getReadMethod() );
}
private static class GenericParent<T>
{
@SuppressWarnings( "unused" )
public void save( T entity )
{
}
}
private static class StringChild
extends GenericParent<String>
{
}
private static class LongChild
extends GenericParent<Long>
{
}
/**
* Tests OGNL parameter discovery.
*/
@Test
public void testOGNLParameterDiscovery()
throws NoSuchMethodException, CacheException
{
Method saveMethod = GenericParent.class.getMethod( "save", Object.class );
System.out.println( saveMethod );
Class<?>[] longClass = OgnlRuntime.findParameterTypes( LongChild.class, saveMethod );
assertNotSame( longClass[0], String.class );
assertSame( longClass[0], Long.class );
Class<?>[] stringClass = OgnlRuntime.findParameterTypes( StringChild.class, saveMethod );
assertNotSame( "The cached parameter types from previous calls are used", stringClass[0], Long.class );
assertSame( stringClass[0], String.class );
}
@Test
public void testGetField()
throws OgnlException
{
Field field = OgnlRuntime.getField( OtherObjectIndexed.class, "attributes" );
assertNotNull( "Field is null", field );
}
@Test
public void testGetSetMethod()
throws IntrospectionException, OgnlException
{
Method setter = OgnlRuntime.getSetMethod( null, Bean1.class, "bean2" );
Method getter = OgnlRuntime.getGetMethod( null, Bean1.class, "bean2" );
assertNotNull( getter );
assertNull( setter );
}
@Test
public void testGetCompiler()
{
OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null );
OgnlExpressionCompiler compiler1 = OgnlRuntime.getCompiler( context );
context.put( "root2", new Root() );
OgnlExpressionCompiler compiler2 = OgnlRuntime.getCompiler( context );
assertSame( "compilers are not the same", compiler1, compiler2 );
}
@Test
public void testGetPropertyDescriptorFromArray()
throws Exception
{
PropertyDescriptor propertyDescriptor =
OgnlRuntime.getPropertyDescriptorFromArray( Root.class, "disabled" );
assertEquals( "disabled", propertyDescriptor.getName() );
}
}