View Javadoc

1   /*
2    * $Id: TestOgnlRuntime.java 1203594 2011-11-18 11:04:51Z mcucchiara $
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   * http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   */
20  package org.apache.commons.ognl;
21  
22  import org.apache.commons.ognl.enhance.OgnlExpressionCompiler;
23  import org.apache.commons.ognl.internal.CacheException;
24  import org.apache.commons.ognl.test.objects.BaseGeneric;
25  import org.apache.commons.ognl.test.objects.Bean1;
26  import org.apache.commons.ognl.test.objects.Bean2;
27  import org.apache.commons.ognl.test.objects.FormImpl;
28  import org.apache.commons.ognl.test.objects.GameGeneric;
29  import org.apache.commons.ognl.test.objects.GameGenericObject;
30  import org.apache.commons.ognl.test.objects.GenericCracker;
31  import org.apache.commons.ognl.test.objects.GenericService;
32  import org.apache.commons.ognl.test.objects.GenericServiceImpl;
33  import org.apache.commons.ognl.test.objects.GetterMethods;
34  import org.apache.commons.ognl.test.objects.IComponent;
35  import org.apache.commons.ognl.test.objects.IForm;
36  import org.apache.commons.ognl.test.objects.ListSource;
37  import org.apache.commons.ognl.test.objects.ListSourceImpl;
38  import org.apache.commons.ognl.test.objects.OtherObjectIndexed;
39  import org.apache.commons.ognl.test.objects.Root;
40  import org.apache.commons.ognl.test.objects.SetterReturns;
41  import org.apache.commons.ognl.test.objects.SubclassSyntheticObject;
42  import org.junit.Test;
43  
44  import java.beans.IntrospectionException;
45  import java.beans.PropertyDescriptor;
46  import java.io.Serializable;
47  import java.lang.reflect.Field;
48  import java.lang.reflect.Method;
49  import java.util.Arrays;
50  import java.util.List;
51  
52  import static junit.framework.Assert.*;
53  
54  /**
55   * Tests various methods / functionality of {@link org.apache.commons.ognl.OgnlRuntime}.
56   */
57  public class TestOgnlRuntime
58  {
59  
60      @Test
61      public void test_Get_Super_Or_Interface_Class()
62          throws Exception
63      {
64          ListSource list = new ListSourceImpl();
65  
66          Method method = OgnlRuntime.getReadMethod( list.getClass(), "total" );
67          assertNotNull( method );
68  
69          OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null );
70          assertEquals( ListSource.class,
71                        OgnlRuntime.getCompiler( context ).getSuperOrInterfaceClass( method, list.getClass() ) );
72      }
73  
74      @Test
75      public void test_Get_Private_Class()
76          throws Exception
77      {
78          List list = Arrays.asList( "hello", "world" );
79  
80          Method m = OgnlRuntime.getReadMethod( list.getClass(), "iterator" );
81          assertNotNull( m );
82  
83          OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null );
84          assertEquals( Iterable.class,
85                        OgnlRuntime.getCompiler( context ).getSuperOrInterfaceClass( m, list.getClass() ) );
86      }
87  
88      @Test
89      public void test_Complicated_Inheritance()
90          throws Exception
91      {
92          IForm form = new FormImpl();
93  
94          Method method = OgnlRuntime.getWriteMethod( form.getClass(), "clientId" );
95          assertNotNull( method );
96  
97          OgnlContext context = (OgnlContext) Ognl.createDefaultContext( null );
98          assertEquals( IComponent.class,
99                        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 }