001 /* 002 * $Id: TestOgnlRuntime.java 1203594 2011-11-18 11:04:51Z mcucchiara $ 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 */ 020 package org.apache.commons.ognl; 021 022 import org.apache.commons.ognl.enhance.OgnlExpressionCompiler; 023 import org.apache.commons.ognl.internal.CacheException; 024 import org.apache.commons.ognl.test.objects.BaseGeneric; 025 import org.apache.commons.ognl.test.objects.Bean1; 026 import org.apache.commons.ognl.test.objects.Bean2; 027 import org.apache.commons.ognl.test.objects.FormImpl; 028 import org.apache.commons.ognl.test.objects.GameGeneric; 029 import org.apache.commons.ognl.test.objects.GameGenericObject; 030 import org.apache.commons.ognl.test.objects.GenericCracker; 031 import org.apache.commons.ognl.test.objects.GenericService; 032 import org.apache.commons.ognl.test.objects.GenericServiceImpl; 033 import org.apache.commons.ognl.test.objects.GetterMethods; 034 import org.apache.commons.ognl.test.objects.IComponent; 035 import org.apache.commons.ognl.test.objects.IForm; 036 import org.apache.commons.ognl.test.objects.ListSource; 037 import org.apache.commons.ognl.test.objects.ListSourceImpl; 038 import org.apache.commons.ognl.test.objects.OtherObjectIndexed; 039 import org.apache.commons.ognl.test.objects.Root; 040 import org.apache.commons.ognl.test.objects.SetterReturns; 041 import org.apache.commons.ognl.test.objects.SubclassSyntheticObject; 042 import org.junit.Test; 043 044 import java.beans.IntrospectionException; 045 import java.beans.PropertyDescriptor; 046 import java.io.Serializable; 047 import java.lang.reflect.Field; 048 import java.lang.reflect.Method; 049 import java.util.Arrays; 050 import java.util.List; 051 052 import static junit.framework.Assert.*; 053 054 /** 055 * Tests various methods / functionality of {@link org.apache.commons.ognl.OgnlRuntime}. 056 */ 057 public class TestOgnlRuntime 058 { 059 060 @Test 061 public void test_Get_Super_Or_Interface_Class() 062 throws Exception 063 { 064 ListSource list = new ListSourceImpl(); 065 066 Method method = OgnlRuntime.getReadMethod( list.getClass(), "total" ); 067 assertNotNull( method ); 068 069 OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null ); 070 assertEquals( ListSource.class, 071 OgnlRuntime.getCompiler( context ).getSuperOrInterfaceClass( method, list.getClass() ) ); 072 } 073 074 @Test 075 public void test_Get_Private_Class() 076 throws Exception 077 { 078 List list = Arrays.asList( "hello", "world" ); 079 080 Method m = OgnlRuntime.getReadMethod( list.getClass(), "iterator" ); 081 assertNotNull( m ); 082 083 OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null ); 084 assertEquals( Iterable.class, 085 OgnlRuntime.getCompiler( context ).getSuperOrInterfaceClass( m, list.getClass() ) ); 086 } 087 088 @Test 089 public void test_Complicated_Inheritance() 090 throws Exception 091 { 092 IForm form = new FormImpl(); 093 094 Method method = OgnlRuntime.getWriteMethod( form.getClass(), "clientId" ); 095 assertNotNull( method ); 096 097 OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null ); 098 assertEquals( IComponent.class, 099 OgnlRuntime.getCompiler( context ).getSuperOrInterfaceClass( method, form.getClass() ) ); 100 } 101 102 @Test 103 public void test_Get_Read_Method() 104 throws Exception 105 { 106 Method method = OgnlRuntime.getReadMethod( Bean2.class, "pageBreakAfter" ); 107 assertNotNull( method ); 108 109 assertEquals( "isPageBreakAfter", method.getName() ); 110 } 111 112 class TestGetters 113 { 114 public boolean isEditorDisabled() 115 { 116 return false; 117 } 118 119 public boolean isDisabled() 120 { 121 return true; 122 } 123 124 public boolean isNotAvailable() 125 { 126 return false; 127 } 128 129 public boolean isAvailable() 130 { 131 return true; 132 } 133 } 134 135 @Test 136 public void test_Get_Read_Method_Multiple() 137 throws Exception 138 { 139 Method method = OgnlRuntime.getReadMethod( TestGetters.class, "disabled" ); 140 assertNotNull( method ); 141 142 assertEquals( "isDisabled", method.getName() ); 143 } 144 145 @Test 146 public void test_Get_Read_Method_Multiple_Boolean_Getters() 147 throws Exception 148 { 149 Method method = OgnlRuntime.getReadMethod( TestGetters.class, "available" ); 150 assertNotNull( method ); 151 152 assertEquals( "isAvailable", method.getName() ); 153 154 method = OgnlRuntime.getReadMethod( TestGetters.class, "notAvailable" ); 155 assertNotNull( method ); 156 157 assertEquals( "isNotAvailable", method.getName() ); 158 } 159 160 @Test 161 public void test_Find_Method_Mixed_Boolean_Getters() 162 throws Exception 163 { 164 Method method = OgnlRuntime.getReadMethod( GetterMethods.class, "allowDisplay" ); 165 assertNotNull( method ); 166 167 assertEquals( "getAllowDisplay", method.getName() ); 168 } 169 170 @Test 171 public void test_Get_Appropriate_Method() 172 throws Exception 173 { 174 ListSource list = new ListSourceImpl(); 175 OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null ); 176 177 Object ret = OgnlRuntime.callMethod( context, list, "addValue", new String[]{ null } ); 178 179 assert ret != null; 180 } 181 182 @Test 183 public void test_Call_Static_Method_Invalid_Class() 184 { 185 186 try 187 { 188 OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null ); 189 OgnlRuntime.callStaticMethod( context, "made.up.Name", "foo", null ); 190 191 fail( "ClassNotFoundException should have been thrown by previous reference to <made.up.Name> class." ); 192 } 193 catch ( Exception et ) 194 { 195 assertTrue( MethodFailedException.class.isInstance( et ) ); 196 assertTrue( et.getMessage().contains( "made.up.Name" ) ); 197 } 198 } 199 200 @Test 201 public void test_Setter_Returns() 202 throws Exception 203 { 204 OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null ); 205 SetterReturns root = new SetterReturns(); 206 207 Method m = OgnlRuntime.getWriteMethod( root.getClass(), "value" ); 208 assertTrue( m != null ); 209 210 Ognl.setValue( "value", context, root, "12__" ); 211 assertEquals( Ognl.getValue( "value", context, root ), "12__" ); 212 } 213 214 @Test 215 public void test_Call_Method_VarArgs() 216 throws Exception 217 { 218 OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null ); 219 GenericService service = new GenericServiceImpl(); 220 221 GameGenericObject argument = new GameGenericObject(); 222 223 Object[] args = OgnlRuntime.getObjectArrayPool().create( 2 ); 224 args[0] = argument; 225 226 assertEquals( "Halo 3", OgnlRuntime.callMethod( context, service, "getFullMessageFor", args ) ); 227 } 228 229 @Test 230 public void test_Class_Cache_Inspector() 231 throws Exception 232 { 233 OgnlRuntime.cache.clear(); 234 235 assertEquals( 0, OgnlRuntime.cache.propertyDescriptorCache.getSize() ); 236 237 Root root = new Root(); 238 OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null ); 239 Node expr = Ognl.compileExpression( context, root, "property.bean3.value != null" ); 240 241 assertTrue( (Boolean) expr.getAccessor().get( context, root ) ); 242 243 int size = OgnlRuntime.cache.propertyDescriptorCache.getSize(); 244 assertTrue( size > 0 ); 245 246 OgnlRuntime.clearCache(); 247 assertEquals( 0, OgnlRuntime.cache.propertyDescriptorCache.getSize() ); 248 249 // now register class cache prevention 250 251 OgnlRuntime.setClassCacheInspector( new TestCacheInspector() ); 252 253 expr = Ognl.compileExpression( context, root, "property.bean3.value != null" ); 254 assertTrue( (Boolean) expr.getAccessor().get( context, root ) ); 255 256 assertEquals( ( size - 1 ), OgnlRuntime.cache.propertyDescriptorCache.getSize() ); 257 } 258 259 class TestCacheInspector 260 implements ClassCacheInspector 261 { 262 263 public boolean shouldCache( Class<?> type ) 264 { 265 return !( type == null || type == Root.class ); 266 } 267 } 268 269 @Test 270 public void test_Set_Generic_Parameter_Types() 271 throws Exception 272 { 273 OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null ); 274 275 Method method = OgnlRuntime.getSetMethod( context, GenericCracker.class, "param" ); 276 assertNotNull( method ); 277 278 Class[] types = method.getParameterTypes(); 279 assertEquals( 1, types.length ); 280 assertEquals( Integer.class, types[0] ); 281 } 282 283 @Test 284 public void test_Get_Generic_Parameter_Types() 285 throws Exception 286 { 287 OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null ); 288 289 Method method = OgnlRuntime.getGetMethod( context, GenericCracker.class, "param" ); 290 assertNotNull( method ); 291 292 assertEquals( Integer.class, method.getReturnType() ); 293 } 294 295 @Test 296 public void test_Find_Parameter_Types() 297 throws Exception 298 { 299 OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null ); 300 301 Method method = OgnlRuntime.getSetMethod( context, GameGeneric.class, "ids" ); 302 assertNotNull( method ); 303 304 Class[] types = OgnlRuntime.findParameterTypes( GameGeneric.class, method ); 305 assertEquals( 1, types.length ); 306 assertEquals( Long[].class, types[0] ); 307 } 308 309 @Test 310 public void test_Find_Parameter_Types_Superclass() 311 throws Exception 312 { 313 OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null ); 314 315 Method method = OgnlRuntime.getSetMethod( context, BaseGeneric.class, "ids" ); 316 assertNotNull( method ); 317 318 Class[] types = OgnlRuntime.findParameterTypes( BaseGeneric.class, method ); 319 assertEquals( 1, types.length ); 320 assertEquals( Serializable[].class, types[0] ); 321 } 322 323 @Test 324 public void test_Get_Declared_Methods_With_Synthetic_Methods() 325 throws Exception 326 { 327 List result = OgnlRuntime.getDeclaredMethods( SubclassSyntheticObject.class, "list", false ); 328 329 // synthetic method would be 330 // "public volatile java.util.List org.ognl.test.objects.SubclassSyntheticObject.getList()", 331 // causing method return size to be 3 332 333 assertEquals( 2, result.size() ); 334 } 335 336 @Test 337 public void test_Get_Property_Descriptors_With_Synthetic_Methods() 338 throws Exception 339 { 340 PropertyDescriptor propertyDescriptor = OgnlRuntime.getPropertyDescriptor( SubclassSyntheticObject.class, "list" ); 341 342 assert propertyDescriptor != null; 343 assert OgnlRuntime.isMethodCallable( propertyDescriptor.getReadMethod() ); 344 } 345 346 private static class GenericParent<T> 347 { 348 public void save( T entity ) 349 { 350 351 } 352 } 353 354 private static class StringChild 355 extends GenericParent<String> 356 { 357 358 } 359 360 private static class LongChild 361 extends GenericParent<Long> 362 { 363 364 } 365 366 /** 367 * Tests OGNL parameter discovery. 368 */ 369 @Test 370 public void testOGNLParameterDiscovery() 371 throws NoSuchMethodException, CacheException 372 { 373 Method saveMethod = GenericParent.class.getMethod( "save", Object.class ); 374 System.out.println( saveMethod ); 375 376 Class[] longClass = OgnlRuntime.findParameterTypes( LongChild.class, saveMethod ); 377 assertNotSame( longClass[0], String.class ); 378 assertSame( longClass[0], Long.class ); 379 380 Class[] stringClass = OgnlRuntime.findParameterTypes( StringChild.class, saveMethod ); 381 assertNotSame( "The cached parameter types from previous calls are used", stringClass[0], Long.class ); 382 assertSame( stringClass[0], String.class ); 383 } 384 385 @Test 386 public void testGetField() 387 throws OgnlException 388 { 389 Field field = OgnlRuntime.getField( OtherObjectIndexed.class, "attributes" ); 390 assertNotNull( "Field is null", field ); 391 } 392 393 @Test 394 public void testGetSetMethod() 395 throws IntrospectionException, OgnlException 396 { 397 Method setter = OgnlRuntime.getSetMethod( null, Bean1.class, "bean2" ); 398 Method getter = OgnlRuntime.getGetMethod( null, Bean1.class, "bean2" ); 399 assertNotNull( getter ); 400 assertNull( setter ); 401 } 402 403 @Test 404 public void testGetCompiler() 405 { 406 OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null ); 407 OgnlExpressionCompiler compiler1 = OgnlRuntime.getCompiler( context ); 408 context.put( "root2", new Root() ); 409 OgnlExpressionCompiler compiler2 = OgnlRuntime.getCompiler( context ); 410 assertSame( "compilers are not the same", compiler1, compiler2 ); 411 } 412 413 @Test 414 public void testGetPropertyDescriptorFromArray() 415 throws Exception 416 { 417 PropertyDescriptor propertyDescriptor = 418 OgnlRuntime.getPropertyDescriptorFromArray( Root.class, "disabled" ); 419 assertEquals( "disabled", propertyDescriptor.getName() ); 420 } 421 }