commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mcucchi...@apache.org
Subject svn commit: r1188000 [2/3] - in /commons/proper/ognl/trunk: ./ src/main/java/org/apache/commons/ognl/ src/main/java/org/apache/commons/ognl/enhance/ src/main/java/org/apache/commons/ognl/internal/ src/main/java/org/apache/commons/ognl/internal/entry/ s...
Date Sun, 23 Oct 2011 23:10:27 GMT
Modified: commons/proper/ognl/trunk/src/main/java/org/apache/commons/ognl/OgnlRuntime.java
URL: http://svn.apache.org/viewvc/commons/proper/ognl/trunk/src/main/java/org/apache/commons/ognl/OgnlRuntime.java?rev=1188000&r1=1187999&r2=1188000&view=diff
==============================================================================
--- commons/proper/ognl/trunk/src/main/java/org/apache/commons/ognl/OgnlRuntime.java (original)
+++ commons/proper/ognl/trunk/src/main/java/org/apache/commons/ognl/OgnlRuntime.java Sun Oct 23 23:10:24 2011
@@ -23,8 +23,25 @@ package org.apache.commons.ognl;
 
 import org.apache.commons.ognl.enhance.ExpressionCompiler;
 import org.apache.commons.ognl.enhance.OgnlExpressionCompiler;
+import org.apache.commons.ognl.internal.Cache;
+import org.apache.commons.ognl.internal.CacheException;
+import org.apache.commons.ognl.internal.CacheFactory;
 import org.apache.commons.ognl.internal.ClassCache;
-import org.apache.commons.ognl.internal.ClassCacheImpl;
+import org.apache.commons.ognl.internal.ClassCacheHandler;
+import org.apache.commons.ognl.internal.HashMapCacheFactory;
+import org.apache.commons.ognl.internal.entry.CacheEntryFactory;
+import org.apache.commons.ognl.internal.entry.ClassCacheEntryFactory;
+import org.apache.commons.ognl.internal.entry.DeclaredMethodCacheEntry;
+import org.apache.commons.ognl.internal.entry.DeclaredMethodCacheEntryFactory;
+import org.apache.commons.ognl.internal.entry.FiedlCacheEntryFactory;
+import org.apache.commons.ognl.internal.entry.GenericMethodParameterTypeCacheEntry;
+import org.apache.commons.ognl.internal.entry.GenericMethodParameterTypeFactory;
+import org.apache.commons.ognl.internal.entry.MethodAccessCacheEntryFactory;
+import org.apache.commons.ognl.internal.entry.MethodAccessEntryValue;
+import org.apache.commons.ognl.internal.entry.MethodPermCacheEntryFactory;
+import org.apache.commons.ognl.internal.entry.PermissionCacheEntry;
+import org.apache.commons.ognl.internal.entry.PermissionCacheEntryFactory;
+import org.apache.commons.ognl.internal.entry.PropertyDescriptorCacheEntryFactory;
 
 import java.beans.BeanInfo;
 import java.beans.IndexedPropertyDescriptor;
@@ -32,11 +49,8 @@ import java.beans.IntrospectionException
 import java.beans.Introspector;
 import java.beans.MethodDescriptor;
 import java.beans.PropertyDescriptor;
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
-import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
@@ -44,7 +58,6 @@ import java.lang.reflect.Modifier;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Proxy;
 import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.security.Permission;
@@ -68,7 +81,7 @@ import java.util.Set;
  * <li>Core runtime configuration point for setting/using global {@link TypeConverter} / {@link OgnlExpressionCompiler}
  * / {@link NullHandler} instances / etc..</li>
  * </ul>
- * 
+ *
  * @author Luke Blanshard (blanshlu@netscape.net)
  * @author Drew Davidson (drew@ognl.org)
  */
@@ -79,11 +92,11 @@ public class OgnlRuntime
      * Constant expression used to indicate that a given method / property couldn't be found during reflection
      * operations.
      */
-    public static final Object NotFound = new Object();
+    public static final Object NotFound = new Object( );
 
-    public static final Object[] NoArguments = new Object[] {};
+    public static final Object[] NoArguments = new Object[]{ };
 
-    public static final Class<?>[] NoArgumentTypes = new Class<?>[] {};
+    public static final Class<?>[] NoArgumentTypes = new Class<?>[]{ };
 
     /**
      * Token returned by TypeConverter for no conversion possible
@@ -128,7 +141,7 @@ public class OgnlRuntime
     /**
      * Prefix padding for hexadecimal numbers to HEX_LENGTH.
      */
-    private static final Map<Integer, String> HEX_PADDING = new HashMap<Integer, String>();
+    private static final Map<Integer, String> HEX_PADDING = new HashMap<Integer, String>( );
 
     private static final int HEX_LENGTH = 8;
 
@@ -144,52 +157,80 @@ public class OgnlRuntime
 
     private static boolean _jdkChecked = false;
 
-    static final ClassCache _methodAccessors = new ClassCacheImpl();
+    private static CacheFactory cacheFactory = new HashMapCacheFactory( );
 
-    static final ClassCache _propertyAccessors = new ClassCacheImpl();
+    static final ClassCache<MethodAccessor> _methodAccessors = cacheFactory.createClassCache( );
 
-    static final ClassCache _elementsAccessors = new ClassCacheImpl();
+    static final ClassCache<PropertyAccessor> _propertyAccessors = cacheFactory.createClassCache( );
 
-    static final ClassCache _nullHandlers = new ClassCacheImpl();
+    static final ClassCache<ElementsAccessor> _elementsAccessors = cacheFactory.createClassCache( );
 
-    static final ClassCache _propertyDescriptorCache = new ClassCacheImpl();
+    static final ClassCache<NullHandler> _nullHandlers = cacheFactory.createClassCache( );
 
-    static final ClassCache _constructorCache = new ClassCacheImpl();
+    static final ClassCache<Map<String, PropertyDescriptor>> _propertyDescriptorCache =
+        cacheFactory.createClassCache( new PropertyDescriptorCacheEntryFactory( ) );
 
-    static final ClassCache _staticMethodCache = new ClassCacheImpl();
-
-    static final ClassCache _instanceMethodCache = new ClassCacheImpl();
-
-    static final ClassCache _invokePermissionCache = new ClassCacheImpl();
+    static final ClassCache<List<Constructor<?>>> _constructorCache =
+        cacheFactory.createClassCache( new ClassCacheEntryFactory<List<Constructor<?>>>( )
+        {
+            public List<Constructor<?>> create( Class<?> key )
+                throws CacheException
+            {
+                return Arrays.asList( key.getConstructors( ) );
+            }
+        } );
 
-    static final ClassCache _fieldCache = new ClassCacheImpl();
+    static final Cache<DeclaredMethodCacheEntry, Map<String, List<Method>>> _methodCache =
+        cacheFactory.createCache( new DeclaredMethodCacheEntryFactory( ) );
 
-    static final List<Class<?>> _superclasses = new ArrayList<Class<?>>(); /* Used by fieldCache lookup */
+    static final Cache<PermissionCacheEntry, Permission> _invokePermissionCache =
+        cacheFactory.createCache( new PermissionCacheEntryFactory( ) );
 
-    static final ClassCache[] _declaredMethods = new ClassCache[] { new ClassCacheImpl(), new ClassCacheImpl() };
+    static final ClassCache<Map<String, Field>> _fieldCache =
+        cacheFactory.createClassCache( new FiedlCacheEntryFactory( ) );
 
     static final Map<String, Class<?>> _primitiveTypes = new HashMap<String, Class<?>>( 101 );
 
-    static final ClassCache _primitiveDefaults = new ClassCacheImpl();
+    static final Map<Class<?>, Object> _primitiveDefaults = new HashMap<Class<?>, Object>( 20 );
 
-    static final Map<Method, Class<?>[]> _methodParameterTypesCache = new HashMap<Method, Class<?>[]>( 101 );
+    static final Cache<Method, Class<?>[]> _methodParameterTypesCache =
+        cacheFactory.createCache( new CacheEntryFactory<Method, Class<?>[]>( )
+        {
+            public Class<?>[] create( Method key )
+                throws CacheException
+            {
+                return key.getParameterTypes( );
+            }
+        } );
 
-    static final Map<Method, Class<?>[]> _genericMethodParameterTypesCache = new HashMap<Method, Class<?>[]>( 101 );
+    static final Cache<GenericMethodParameterTypeCacheEntry, Class<?>[]> _genericMethodParameterTypesCache =
+        cacheFactory.createCache( new GenericMethodParameterTypeFactory( ) );
 
-    static final Map<Constructor<?>, Class<?>[]> _ctorParameterTypesCache = new HashMap<Constructor<?>, Class<?>[]>( 101 );
+    static final Cache<Constructor<?>, Class<?>[]> _ctorParameterTypesCache =
+        cacheFactory.createCache( new CacheEntryFactory<Constructor<?>, Class<?>[]>( )
+        {
+            public Class<?>[] create( Constructor<?> key )
+                throws CacheException
+            {
+                return key.getParameterTypes( );
+            }
+        } );
 
-    static SecurityManager _securityManager = System.getSecurityManager();
+    static SecurityManager _securityManager = System.getSecurityManager( );
 
-    static final EvaluationPool _evaluationPool = new EvaluationPool();
+    static final EvaluationPool _evaluationPool = new EvaluationPool( );
 
-    static final ObjectArrayPool _objectArrayPool = new ObjectArrayPool();
+    static final ObjectArrayPool _objectArrayPool = new ObjectArrayPool( );
 
-    static final IntHashMap<Integer, Boolean> _methodAccessCache = new IntHashMap<Integer, Boolean>();
+    static final Cache<Method, MethodAccessEntryValue> _methodAccessCache =
+        cacheFactory.createCache( new MethodAccessCacheEntryFactory( ) );
 
-    static final IntHashMap<Integer, Boolean> _methodPermCache = new IntHashMap<Integer, Boolean>();
+    private static final MethodPermCacheEntryFactory methodPermCacheEntryFactory =
+        new MethodPermCacheEntryFactory( _securityManager );
 
-    static final Map<OgnlContext, OgnlExpressionCompiler> expressionCompilerMap = new HashMap<OgnlContext, OgnlExpressionCompiler>();
+    static final Cache<Method, Boolean> _methodPermCache = cacheFactory.createCache( methodPermCacheEntryFactory );
 
+    static final Map<OgnlContext, OgnlExpressionCompiler> expressionCompilerMap = new HashMap<OgnlContext, OgnlExpressionCompiler>();
 
     static ClassCacheInspector _cacheInspector;
 
@@ -198,7 +239,24 @@ public class OgnlRuntime
      */
     private static OgnlExpressionCompiler _compiler;
 
-    private static Map<Class<?>, Class<?>> PRIMITIVE_WRAPPER_CLASSES = new IdentityHashMap<Class<?>, Class<?>>();
+    /**
+     * Lazy loading of Javassist library
+     */
+    static
+    {
+        try
+        {
+            Class.forName( "javassist.ClassPool" );
+            _compiler = new ExpressionCompiler( );
+        }
+        catch ( ClassNotFoundException e )
+        {
+            throw new IllegalArgumentException(
+                "Javassist library is missing in classpath! Please add missed dependency!", e );
+        }
+    }
+
+    private static Map<Class<?>, Class<?>> PRIMITIVE_WRAPPER_CLASSES = new IdentityHashMap<Class<?>, Class<?>>( );
 
     /**
      * Used to provide primitive type equivalent conversions into and out of native / object types.
@@ -223,7 +281,8 @@ public class OgnlRuntime
         PRIMITIVE_WRAPPER_CLASSES.put( Double.class, Double.TYPE );
     }
 
-    private static final Map<Class<? extends Number>, String> NUMERIC_CASTS = new HashMap<Class<? extends Number>, String>();
+    private static final Map<Class<? extends Number>, String> NUMERIC_CASTS =
+        new HashMap<Class<? extends Number>, String>( );
 
     /**
      * Constant strings for casting different primitive types.
@@ -238,7 +297,7 @@ public class OgnlRuntime
         NUMERIC_CASTS.put( BigInteger.class, "" );
     }
 
-    private static final Map<Class<?>, String> NUMERIC_VALUES = new HashMap<Class<?>, String>();
+    private static final Map<Class<?>, String> NUMERIC_VALUES = new HashMap<Class<?>, String>( );
 
     /**
      * Constant strings for getting the primitive value of different native types on the generic {@link Number} object
@@ -257,7 +316,8 @@ public class OgnlRuntime
         NUMERIC_VALUES.put( Boolean.class, "booleanValue()" );
     }
 
-    private static final Map<Class<? extends Number>, String> NUMERIC_LITERALS = new HashMap<Class<? extends Number>, String>();
+    private static final Map<Class<? extends Number>, String> NUMERIC_LITERALS =
+        new HashMap<Class<? extends Number>, String>( );
 
     /**
      * Numeric primitive literal string expressions.
@@ -277,7 +337,7 @@ public class OgnlRuntime
         NUMERIC_LITERALS.put( BigDecimal.class, "d" );
     }
 
-    private static final Map<Class<?>, Object> NUMERIC_DEFAULTS = new HashMap<Class<?>, Object>();
+    private static final Map<Class<?>, Object> NUMERIC_DEFAULTS = new HashMap<Class<?>, Object>( );
 
     static
     {
@@ -296,9 +356,9 @@ public class OgnlRuntime
 
     static
     {
-        PropertyAccessor p = new ArrayPropertyAccessor();
+        PropertyAccessor p = new ArrayPropertyAccessor( );
 
-        setPropertyAccessor( Object.class, new ObjectPropertyAccessor() );
+        setPropertyAccessor( Object.class, new ObjectPropertyAccessor( ) );
         setPropertyAccessor( byte[].class, p );
         setPropertyAccessor( short[].class, p );
         setPropertyAccessor( char[].class, p );
@@ -307,15 +367,15 @@ public class OgnlRuntime
         setPropertyAccessor( float[].class, p );
         setPropertyAccessor( double[].class, p );
         setPropertyAccessor( Object[].class, p );
-        setPropertyAccessor( List.class, new ListPropertyAccessor() );
-        setPropertyAccessor( Map.class, new MapPropertyAccessor() );
-        setPropertyAccessor( Set.class, new SetPropertyAccessor() );
-        setPropertyAccessor( Iterator.class, new IteratorPropertyAccessor() );
-        setPropertyAccessor( Enumeration.class, new EnumerationPropertyAccessor() );
+        setPropertyAccessor( List.class, new ListPropertyAccessor( ) );
+        setPropertyAccessor( Map.class, new MapPropertyAccessor( ) );
+        setPropertyAccessor( Set.class, new SetPropertyAccessor( ) );
+        setPropertyAccessor( Iterator.class, new IteratorPropertyAccessor( ) );
+        setPropertyAccessor( Enumeration.class, new EnumerationPropertyAccessor( ) );
 
-        ElementsAccessor e = new ArrayElementsAccessor();
+        ElementsAccessor e = new ArrayElementsAccessor( );
 
-        setElementsAccessor( Object.class, new ObjectElementsAccessor() );
+        setElementsAccessor( Object.class, new ObjectElementsAccessor( ) );
         setElementsAccessor( byte[].class, e );
         setElementsAccessor( short[].class, e );
         setElementsAccessor( char[].class, e );
@@ -324,13 +384,13 @@ public class OgnlRuntime
         setElementsAccessor( float[].class, e );
         setElementsAccessor( double[].class, e );
         setElementsAccessor( Object[].class, e );
-        setElementsAccessor( Collection.class, new CollectionElementsAccessor() );
-        setElementsAccessor( Map.class, new MapElementsAccessor() );
-        setElementsAccessor( Iterator.class, new IteratorElementsAccessor() );
-        setElementsAccessor( Enumeration.class, new EnumerationElementsAccessor() );
-        setElementsAccessor( Number.class, new NumberElementsAccessor() );
+        setElementsAccessor( Collection.class, new CollectionElementsAccessor( ) );
+        setElementsAccessor( Map.class, new MapElementsAccessor( ) );
+        setElementsAccessor( Iterator.class, new IteratorElementsAccessor( ) );
+        setElementsAccessor( Enumeration.class, new EnumerationElementsAccessor( ) );
+        setElementsAccessor( Number.class, new NumberElementsAccessor( ) );
 
-        NullHandler nh = new ObjectNullHandler();
+        NullHandler nh = new ObjectNullHandler( );
 
         setNullHandler( Object.class, nh );
         setNullHandler( byte[].class, nh );
@@ -342,7 +402,7 @@ public class OgnlRuntime
         setNullHandler( double[].class, nh );
         setNullHandler( Object[].class, nh );
 
-        MethodAccessor ma = new ObjectMethodAccessor();
+        MethodAccessor ma = new ObjectMethodAccessor( );
 
         setMethodAccessor( Object.class, ma );
         setMethodAccessor( byte[].class, ma );
@@ -387,31 +447,29 @@ public class OgnlRuntime
      * care.
      * </p>
      */
-    public static void clearCache()
+    public static void clearCache( )
     {
-        _methodParameterTypesCache.clear();
-        _ctorParameterTypesCache.clear();
-        _propertyDescriptorCache.clear();
-        _constructorCache.clear();
-        _staticMethodCache.clear();
-        _instanceMethodCache.clear();
-        _invokePermissionCache.clear();
-        _fieldCache.clear();
-        _superclasses.clear();
-        _declaredMethods[0].clear();
-        _declaredMethods[1].clear();
-        _methodAccessCache.clear();
+        _methodParameterTypesCache.clear( );
+        _ctorParameterTypesCache.clear( );
+        _propertyDescriptorCache.clear( );
+        _constructorCache.clear( );
+         _methodCache.clear( );
+        _invokePermissionCache.clear( );
+         _fieldCache.clear( );
+        _methodAccessCache.clear( );
     }
 
     /**
      * Checks if the current jvm is java language >= 1.5 compatible.
-     * 
+     *
      * @return True if jdk15 features are present.
      */
-    public static boolean isJdk15()
+    public static boolean isJdk15( )
     {
         if ( _jdkChecked )
+        {
             return _jdk15;
+        }
 
         try
         {
@@ -492,7 +550,7 @@ public class OgnlRuntime
      */
     public static Class<?> getTargetClass( Object o )
     {
-        return ( o == null ) ? null : ( ( o instanceof Class ) ? (Class<?>) o : o.getClass() );
+        return ( o == null ) ? null : ( ( o instanceof Class ) ? (Class<?>) o : o.getClass( ) );
     }
 
     /**
@@ -500,7 +558,7 @@ public class OgnlRuntime
      */
     public static String getBaseName( Object o )
     {
-        return ( o == null ) ? null : getClassBaseName( o.getClass() );
+        return ( o == null ) ? null : getClassBaseName( o.getClass( ) );
     }
 
     /**
@@ -508,7 +566,7 @@ public class OgnlRuntime
      */
     public static String getClassBaseName( Class<?> c )
     {
-        String s = c.getName();
+        String s = c.getName( );
 
         return s.substring( s.lastIndexOf( '.' ) + 1 );
     }
@@ -517,7 +575,7 @@ public class OgnlRuntime
     {
         if ( !( o instanceof Class ) )
         {
-            o = o.getClass();
+            o = o.getClass( );
         }
 
         return getClassName( (Class<?>) o, fullyQualified );
@@ -525,7 +583,7 @@ public class OgnlRuntime
 
     public static String getClassName( Class<?> c, boolean fullyQualified )
     {
-        return fullyQualified ? c.getName() : getClassBaseName( c );
+        return fullyQualified ? c.getName( ) : getClassBaseName( c );
     }
 
     /**
@@ -533,7 +591,7 @@ public class OgnlRuntime
      */
     public static String getPackageName( Object o )
     {
-        return ( o == null ) ? null : getClassPackageName( o.getClass() );
+        return ( o == null ) ? null : getClassPackageName( o.getClass( ) );
     }
 
     /**
@@ -541,7 +599,7 @@ public class OgnlRuntime
      */
     public static String getClassPackageName( Class<?> c )
     {
-        String s = c.getName();
+        String s = c.getName( );
         int i = s.lastIndexOf( '.' );
 
         return ( i < 0 ) ? null : s.substring( 0, i );
@@ -552,16 +610,16 @@ public class OgnlRuntime
      */
     public static String getPointerString( int num )
     {
-        StringBuffer result = new StringBuffer();
+        StringBuffer result = new StringBuffer( );
         String hex = Integer.toHexString( num ), pad;
-        Integer l = hex.length();
+        Integer l = hex.length( );
 
         // result.append(HEX_PREFIX);
         if ( ( pad = HEX_PADDING.get( l ) ) == null )
         {
-            StringBuffer pb = new StringBuffer();
+            StringBuffer pb = new StringBuffer( );
 
-            for ( int i = hex.length(); i < HEX_LENGTH; i++ )
+            for ( int i = hex.length( ); i < HEX_LENGTH; i++ )
             {
                 pb.append( '0' );
             }
@@ -589,13 +647,13 @@ public class OgnlRuntime
      */
     public static String getUniqueDescriptor( Object object, boolean fullyQualified )
     {
-        StringBuffer result = new StringBuffer();
+        StringBuffer result = new StringBuffer( );
 
         if ( object != null )
         {
             if ( object instanceof Proxy )
             {
-                Class<?> interfaceClass = object.getClass().getInterfaces()[0];
+                Class<?> interfaceClass = object.getClass( ).getInterfaces( )[0];
 
                 result.append( getClassName( interfaceClass, fullyQualified ) );
                 result.append( '^' );
@@ -627,7 +685,7 @@ public class OgnlRuntime
     public static <T> Object[] toArray( List<T> list )
     {
         Object[] result;
-        int size = list.size();
+        int size = list.size( );
 
         if ( size == 0 )
         {
@@ -635,7 +693,7 @@ public class OgnlRuntime
         }
         else
         {
-            result = getObjectArrayPool().create( list.size() );
+            result = getObjectArrayPool( ).create( list.size( ) );
             for ( int i = 0; i < size; i++ )
             {
                 result[i] = list.get( i );
@@ -648,134 +706,40 @@ public class OgnlRuntime
      * Returns the parameter types of the given method.
      */
     public static Class<?>[] getParameterTypes( Method m )
+        throws CacheException
     {
-        synchronized ( _methodParameterTypesCache )
-        {
-            Class<?>[] result;
+        return _methodParameterTypesCache.get( m );
 
-            if ( ( result = _methodParameterTypesCache.get( m ) ) == null )
-            {
-                _methodParameterTypesCache.put( m, result = m.getParameterTypes() );
-            }
-            return result;
-        }
     }
 
     /**
      * Finds the appropriate parameter types for the given {@link Method} and {@link Class} instance of the type the
      * method is associated with. Correctly finds generic types if running in >= 1.5 jre as well.
-     * 
+     *
      * @param type The class type the method is being executed against.
-     * @param m The method to find types for.
+     * @param m    The method to find types for.
      * @return Array of parameter types for the given method.
      */
     public static Class<?>[] findParameterTypes( Class<?> type, Method m )
+        throws CacheException
     {
         if ( type == null )
         {
             return getParameterTypes( m );
         }
 
-        if ( !isJdk15() || type.getGenericSuperclass() == null
-            || !ParameterizedType.class.isInstance( type.getGenericSuperclass() )
-            || m.getDeclaringClass().getTypeParameters() == null )
+        if ( !isJdk15( ) || type.getGenericSuperclass( ) == null || !ParameterizedType.class.isInstance(
+            type.getGenericSuperclass( ) ) || m.getDeclaringClass( ).getTypeParameters( ) == null )
         {
             return getParameterTypes( m );
         }
 
-        synchronized ( _genericMethodParameterTypesCache )
-        {
-            Class<?>[] types;
-
-            if ( ( types = _genericMethodParameterTypesCache.get( m ) ) != null )
-            {
-                ParameterizedType genericSuperclass = (ParameterizedType) type.getGenericSuperclass();
-                if ( Arrays.equals( types, genericSuperclass.getActualTypeArguments() ) )
-                {
-                    return types;
-                }
-            }
-
-            ParameterizedType param = (ParameterizedType) type.getGenericSuperclass();
-            Type[] genTypes = m.getGenericParameterTypes();
-            TypeVariable<?>[] declaredTypes = m.getDeclaringClass().getTypeParameters();
-
-            types = new Class[genTypes.length];
-
-            for ( int i = 0; i < genTypes.length; i++ )
-            {
-                TypeVariable<?> paramType = null;
-
-                if ( TypeVariable.class.isInstance( genTypes[i] ) )
-                {
-                    paramType = (TypeVariable<?>) genTypes[i];
-                }
-                else if ( GenericArrayType.class.isInstance( genTypes[i] ) )
-                {
-                    paramType = (TypeVariable<?>) ( (GenericArrayType) genTypes[i] ).getGenericComponentType();
-                }
-                else if ( ParameterizedType.class.isInstance( genTypes[i] ) )
-                {
-                    types[i] = (Class<?>) ( (ParameterizedType) genTypes[i] ).getRawType();
-                    continue;
-                }
-                else if ( Class.class.isInstance( genTypes[i] ) )
-                {
-                    types[i] = (Class<?>) genTypes[i];
-                    continue;
-                }
-
-                Class<?> resolved = resolveType( param, paramType, declaredTypes );
-
-                if ( resolved != null )
-                {
-                    if ( GenericArrayType.class.isInstance( genTypes[i] ) )
-                    {
-                        resolved = Array.newInstance( resolved, 0 ).getClass();
-                    }
-
-                    types[i] = resolved;
-                    continue;
-                }
-
-                types[i] = m.getParameterTypes()[i];
-            }
-
-            _genericMethodParameterTypesCache.put( m, types );
-
-            return types;
-        }
-    }
-
-    static Class<?> resolveType( ParameterizedType param, TypeVariable<?> var, TypeVariable<?>[] declaredTypes )
-    {
-        if ( param.getActualTypeArguments().length < 1 )
-            return null;
-
-        for ( int i = 0; i < declaredTypes.length; i++ )
-        {
-            if ( !TypeVariable.class.isInstance( param.getActualTypeArguments()[i] )
-                && declaredTypes[i].getName().equals( var.getName() ) )
-            {
-                return (Class<?>) param.getActualTypeArguments()[i];
-            }
-        }
-
-        /*
-         * for (int i=0; i < var.getBounds().length; i++) { Type t = var.getBounds()[i]; Class resolvedType = null; if
-         * (ParameterizedType.class.isInstance(t)) { ParameterizedType pparam = (ParameterizedType)t; for (int e=0; e <
-         * pparam.getActualTypeArguments().length; e++) { if
-         * (!TypeVariable.class.isInstance(pparam.getActualTypeArguments()[e])) continue; resolvedType =
-         * resolveType(pparam, (TypeVariable)pparam.getActualTypeArguments()[e], declaredTypes); } } else { resolvedType
-         * = findType(param.getActualTypeArguments(), (Class)t); } if (resolvedType != null) return resolvedType; }
-         */
-
-        return null;
+        return _genericMethodParameterTypesCache.get( new GenericMethodParameterTypeCacheEntry( m, type ) );
     }
 
     static Class<?> findType( Type[] types, Class<?> type )
     {
-        for ( Type t: types )
+        for ( Type t : types )
         {
             if ( Class.class.isInstance( t ) && type.isAssignableFrom( (Class<?>) t ) )
             {
@@ -790,150 +754,77 @@ public class OgnlRuntime
      * Returns the parameter types of the given method.
      */
     public static Class<?>[] getParameterTypes( Constructor<?> c )
+        throws CacheException
     {
-        synchronized ( _ctorParameterTypesCache )
-        {
-            Class<?>[] result;
-
-            if ( ( result = _ctorParameterTypesCache.get( c ) ) == null )
-            {
-                _ctorParameterTypesCache.put( c, result = c.getParameterTypes() );
-            }
-            return result;
-        }
+        return _ctorParameterTypesCache.get( c );
     }
 
     /**
      * Gets the SecurityManager that OGNL uses to determine permissions for invoking methods.
-     * 
+     *
      * @return SecurityManager for OGNL
      */
-    public static SecurityManager getSecurityManager()
+    public static SecurityManager getSecurityManager( )
     {
         return _securityManager;
     }
 
     /**
      * Sets the SecurityManager that OGNL uses to determine permissions for invoking methods.
-     * 
+     *
      * @param value SecurityManager to set
      */
     public static void setSecurityManager( SecurityManager value )
     {
         _securityManager = value;
+        methodPermCacheEntryFactory.setSecurityManager( value );
     }
 
     /**
      * Permission will be named "invoke.<declaring-class>.<method-name>".
      */
     public static Permission getPermission( Method method )
+        throws CacheException
     {
-        Permission result = null;
-        Class<?> mc = method.getDeclaringClass();
-
-        synchronized ( _invokePermissionCache )
-        {
-            Map<String, Permission> permissions = _invokePermissionCache.get( mc );
-
-            if ( permissions == null )
-            {
-                _invokePermissionCache.put( mc, permissions = new HashMap<String, Permission>( 101 ) );
-            }
-            if ( ( result = permissions.get( method.getName() ) ) == null )
-            {
-                result = new OgnlInvokePermission( "invoke." + mc.getName() + "." + method.getName() );
-                permissions.put( method.getName(), result );
-            }
-        }
-        return result;
+        return _invokePermissionCache.get( new PermissionCacheEntry( method ) );
     }
 
     public static Object invokeMethod( Object target, Method method, Object[] argsArray )
-        throws InvocationTargetException, IllegalAccessException
+        throws InvocationTargetException, IllegalAccessException, CacheException
     {
-        boolean syncInvoke = false;
-        boolean checkPermission = false;
-        int mHash = method.hashCode();
-
-        // only synchronize method invocation if it actually requires it
+        Object result;
 
-        synchronized ( method )
+        if ( _securityManager != null )
         {
-            if ( _methodAccessCache.get( mHash ) == null || _methodAccessCache.get( mHash ) == Boolean.TRUE )
+            if ( !_methodPermCache.get( method ) )
             {
-                syncInvoke = true;
+                throw new IllegalAccessException( "Method [" + method + "] cannot be accessed." );
             }
 
-            if ( _securityManager != null && _methodPermCache.get( mHash ) == null
-                || _methodPermCache.get( mHash ) == Boolean.FALSE )
-            {
-                checkPermission = true;
-            }
         }
+        MethodAccessEntryValue entry = _methodAccessCache.get( method );
 
-        Object result;
-        boolean wasAccessible = true;
-
-        if ( syncInvoke )
+        if ( !entry.isAccessible( ) )
         {
+            // only synchronize method invocation if it actually requires it
             synchronized ( method )
             {
-                if ( checkPermission )
-                {
-                    try
-                    {
-                        _securityManager.checkPermission( getPermission( method ) );
-                        _methodPermCache.put( mHash, Boolean.TRUE );
-                    }
-                    catch ( SecurityException ex )
-                    {
-                        _methodPermCache.put( mHash, Boolean.FALSE );
-                        throw new IllegalAccessException( "Method [" + method + "] cannot be accessed." );
-                    }
-                }
 
-                if ( !Modifier.isPublic( method.getModifiers() )
-                    || !Modifier.isPublic( method.getDeclaringClass().getModifiers() ) )
-                {
-                    if ( !( wasAccessible = ( (AccessibleObject) method ).isAccessible() ) )
-                    {
-                        ( (AccessibleObject) method ).setAccessible( true );
-                        _methodAccessCache.put( mHash, Boolean.TRUE );
-                    }
-                    else
-                    {
-                        _methodAccessCache.put( mHash, Boolean.FALSE );
-                    }
-                }
-                else
+                if ( entry.isNotPublic( ) && !entry.isAccessible( ) )
                 {
-                    _methodAccessCache.put( mHash, Boolean.FALSE );
+                    method.setAccessible( true );
                 }
 
                 result = method.invoke( target, argsArray );
 
-                if ( !wasAccessible )
+                if ( !entry.isAccessible( ) )
                 {
-                    ( (AccessibleObject) method ).setAccessible( false );
+                    method.setAccessible( false );
                 }
             }
         }
         else
         {
-            if ( checkPermission )
-            {
-                try
-                {
-                    _securityManager.checkPermission( getPermission( method ) );
-                    _methodPermCache.put( mHash, Boolean.TRUE );
-                }
-                catch ( SecurityException ex )
-                {
-                    _methodPermCache.put( mHash, Boolean.FALSE );
-                    throw new IllegalAccessException( "Method [" + method + "] cannot be accessed." );
-                }
-            }
-
             result = method.invoke( target, argsArray );
         }
 
@@ -944,34 +835,52 @@ public class OgnlRuntime
      * Gets the class for a method argument that is appropriate for looking up methods by reflection, by looking for the
      * standard primitive wrapper classes and exchanging for them their underlying primitive class objects. Other
      * classes are passed through unchanged.
-     * 
+     *
      * @param arg an object that is being passed to a method
      * @return the class to use to look up the method
      */
     public static Class<?> getArgClass( Object arg )
     {
         if ( arg == null )
+        {
             return null;
-        Class<?> c = arg.getClass();
+        }
+        Class<?> c = arg.getClass( );
         if ( c == Boolean.class )
+        {
             return Boolean.TYPE;
-        else if ( c.getSuperclass() == Number.class )
+        }
+        else if ( c.getSuperclass( ) == Number.class )
         {
             if ( c == Integer.class )
+            {
                 return Integer.TYPE;
+            }
             if ( c == Double.class )
+            {
                 return Double.TYPE;
+            }
             if ( c == Byte.class )
+            {
                 return Byte.TYPE;
+            }
             if ( c == Long.class )
+            {
                 return Long.TYPE;
+            }
             if ( c == Float.class )
+            {
                 return Float.TYPE;
+            }
             if ( c == Short.class )
+            {
                 return Short.TYPE;
+            }
         }
         else if ( c == Character.class )
+        {
             return Character.TYPE;
+        }
         return c;
     }
 
@@ -986,7 +895,7 @@ public class OgnlRuntime
 
         if ( object != null )
         {
-            if ( c.isPrimitive() )
+            if ( c.isPrimitive( ) )
             {
                 if ( getArgClass( object ) != c )
                 {
@@ -1014,7 +923,7 @@ public class OgnlRuntime
     public static boolean areArgsCompatible( Object[] args, Class<?>[] classes, Method m )
     {
         boolean result = true;
-        boolean varArgs = m != null && isJdk15() && m.isVarArgs();
+        boolean varArgs = m != null && isJdk15( ) && m.isVarArgs( );
 
         if ( args.length != classes.length && !varArgs )
         {
@@ -1031,15 +940,15 @@ public class OgnlRuntime
 
                 result = isTypeCompatible( args[index], classes[index] );
 
-                if ( !result && classes[index].isArray() )
+                if ( !result && classes[index].isArray( ) )
                 {
-                    result = isTypeCompatible( args[index], classes[index].getComponentType() );
+                    result = isTypeCompatible( args[index], classes[index].getComponentType( ) );
                 }
             }
         }
         else
         {
-            for ( int index = 0; result && ( index < args.length); ++index )
+            for ( int index = 0; result && ( index < args.length ); ++index )
             {
                 result = isTypeCompatible( args[index], classes[index] );
             }
@@ -1056,13 +965,20 @@ public class OgnlRuntime
         for ( int index = 0; index < classes1.length; ++index )
         {
             Class<?> c1 = classes1[index], c2 = classes2[index];
-            if ( c1 != c2 ){
-                if ( c1.isPrimitive() )
+            if ( c1 != c2 )
+            {
+                if ( c1.isPrimitive( ) )
+                {
                     return true;
+                }
                 else if ( c1.isAssignableFrom( c2 ) )
+                {
                     return false;
+                }
                 else if ( c2.isAssignableFrom( c1 ) )
+                {
                     return true;
+                }
             }
         }
 
@@ -1075,23 +991,41 @@ public class OgnlRuntime
         String result;
 
         if ( Modifier.isPublic( modifiers ) )
+        {
             result = "public";
+        }
         else if ( Modifier.isProtected( modifiers ) )
+        {
             result = "protected";
+        }
         else if ( Modifier.isPrivate( modifiers ) )
+        {
             result = "private";
+        }
         else
+        {
             result = "";
+        }
         if ( Modifier.isStatic( modifiers ) )
+        {
             result = "static " + result;
+        }
         if ( Modifier.isFinal( modifiers ) )
+        {
             result = "final " + result;
+        }
         if ( Modifier.isNative( modifiers ) )
+        {
             result = "native " + result;
+        }
         if ( Modifier.isSynchronized( modifiers ) )
+        {
             result = "synchronized " + result;
+        }
         if ( Modifier.isTransient( modifiers ) )
+        {
             result = "transient " + result;
+        }
         return result;
     }
 
@@ -1104,7 +1038,7 @@ public class OgnlRuntime
         {
             ClassResolver resolver;
 
-            if ( ( context == null ) || ( ( resolver = context.getClassResolver() ) == null ) )
+            if ( ( context == null ) || ( ( resolver = context.getClassResolver( ) ) == null ) )
             {
                 resolver = OgnlContext.DEFAULT_CLASS_RESOLVER;
             }
@@ -1112,7 +1046,9 @@ public class OgnlRuntime
         }
 
         if ( result == null )
+        {
             throw new ClassNotFoundException( "Unable to resolve class: " + className );
+        }
 
         return result;
     }
@@ -1132,6 +1068,7 @@ public class OgnlRuntime
     }
 
     public static Object getPrimitiveDefaultValue( Class<?> forClass )
+        throws OgnlException
     {
         return _primitiveDefaults.get( forClass );
     }
@@ -1143,19 +1080,21 @@ public class OgnlRuntime
 
     public static Object getConvertedType( OgnlContext context, Object target, Member member, String propertyName,
                                            Object value, Class<?> type )
+        throws OgnlException
     {
-        return context.getTypeConverter().convertValue( context, target, member, propertyName, value, type );
+        return context.getTypeConverter( ).convertValue( context, target, member, propertyName, value, type );
     }
 
     public static boolean getConvertedTypes( OgnlContext context, Object target, Member member, String propertyName,
                                              Class<?>[] parameterTypes, Object[] args, Object[] newArgs )
+        throws OgnlException
     {
         boolean result = false;
 
         if ( parameterTypes.length == args.length )
         {
             result = true;
-            for ( int i = 0; result && ( i <= parameterTypes.length - 1); i++ )
+            for ( int i = 0; result && ( i <= parameterTypes.length - 1 ); i++ )
             {
                 Object arg = args[i];
                 Class<?> type = parameterTypes[i];
@@ -1184,16 +1123,18 @@ public class OgnlRuntime
 
     public static Method getConvertedMethodAndArgs( OgnlContext context, Object target, String propertyName,
                                                     List<Method> methods, Object[] args, Object[] newArgs )
+        throws OgnlException
     {
         Method result = null;
-        TypeConverter converter = context.getTypeConverter();
+        TypeConverter converter = context.getTypeConverter( );
 
         if ( ( converter != null ) && ( methods != null ) )
         {
-            for ( int i = 0; ( result == null ) && ( i < methods.size()); i++ )
+            for ( int i = 0; ( result == null ) && ( i < methods.size( ) ); i++ )
             {
                 Method m = methods.get( i );
-                Class<?>[] parameterTypes = findParameterTypes( target != null ? target.getClass() : null, m );// getParameterTypes(m);
+                Class<?>[] parameterTypes =
+                    findParameterTypes( target != null ? target.getClass( ) : null, m );// getParameterTypes(m);
 
                 if ( getConvertedTypes( context, target, m, propertyName, parameterTypes, args, newArgs ) )
                 {
@@ -1204,15 +1145,17 @@ public class OgnlRuntime
         return result;
     }
 
-    public static Constructor<?> getConvertedConstructorAndArgs( OgnlContext context, Object target, List<Constructor<?>> constructors,
-                                                              Object[] args, Object[] newArgs )
+    public static Constructor<?> getConvertedConstructorAndArgs( OgnlContext context, Object target,
+                                                                 List<Constructor<?>> constructors, Object[] args,
+                                                                 Object[] newArgs )
+        throws OgnlException
     {
         Constructor<?> result = null;
-        TypeConverter converter = context.getTypeConverter();
+        TypeConverter converter = context.getTypeConverter( );
 
         if ( ( converter != null ) && ( constructors != null ) )
         {
-            for ( int i = 0; ( result == null ) && ( i < constructors.size()); i++ )
+            for ( int i = 0; ( result == null ) && ( i < constructors.size( ) ); i++ )
             {
                 Constructor<?> ctor = constructors.get( i );
                 Class<?>[] parameterTypes = getParameterTypes( ctor );
@@ -1230,18 +1173,19 @@ public class OgnlRuntime
      * Gets the appropriate method to be called for the given target, method name and arguments. If successful this
      * method will return the Method within the target that can be called and the converted arguments in actualArgs. If
      * unsuccessful this method will return null and the actualArgs will be empty.
-     * 
-     * @param context The current execution context.
-     * @param source Target object to run against or method name.
-     * @param target Instance of object to be run against.
+     *
+     * @param context      The current execution context.
+     * @param source       Target object to run against or method name.
+     * @param target       Instance of object to be run against.
      * @param propertyName Name of property to get method of.
-     * @param methods List of current known methods.
-     * @param args Arguments originally passed in.
-     * @param actualArgs Converted arguments.
+     * @param methods      List of current known methods.
+     * @param args         Arguments originally passed in.
+     * @param actualArgs   Converted arguments.
      * @return Best method match or null if none could be found.
      */
     public static Method getAppropriateMethod( OgnlContext context, Object source, Object target, String propertyName,
                                                List<Method> methods, Object[] args, Object[] actualArgs )
+        throws OgnlException
     {
         Method result = null;
         Class<?>[] resultParameterTypes = null;
@@ -1250,7 +1194,7 @@ public class OgnlRuntime
         {
             for ( Method m : methods )
             {
-                Class<?> typeClass = target != null ? target.getClass() : null;
+                Class<?> typeClass = target != null ? target.getClass( ) : null;
                 if ( typeClass == null && source != null && Class.class.isInstance( source ) )
                 {
                     typeClass = (Class<?>) source;
@@ -1269,7 +1213,7 @@ public class OgnlRuntime
                     {
                         Class<?> type = mParameterTypes[j];
 
-                        if ( type.isPrimitive() && ( actualArgs[j] == null ) )
+                        if ( type.isPrimitive( ) && ( actualArgs[j] == null ) )
                         {
                             actualArgs[j] = getConvertedType( context, source, result, propertyName, null, type );
                         }
@@ -1299,19 +1243,19 @@ public class OgnlRuntime
 
             if ( ( method == null ) || !isMethodAccessible( context, source, method, propertyName ) )
             {
-                StringBuffer buffer = new StringBuffer();
+                StringBuilder buffer = new StringBuilder( );
                 String className = "";
 
                 if ( target != null )
                 {
-                    className = target.getClass().getName() + ".";
+                    className = target.getClass( ).getName( ) + ".";
                 }
 
                 for ( int i = 0, ilast = args.length - 1; i <= ilast; i++ )
                 {
                     Object arg = args[i];
 
-                    buffer.append( ( arg == null ) ? NULL_STRING : arg.getClass().getName() );
+                    buffer.append( ( arg == null ) ? NULL_STRING : arg.getClass( ).getName( ) );
                     if ( i < ilast )
                     {
                         buffer.append( ", " );
@@ -1323,9 +1267,9 @@ public class OgnlRuntime
 
             Object[] convertedArgs = actualArgs;
 
-            if ( isJdk15() && method.isVarArgs() )
+            if ( isJdk15( ) && method.isVarArgs( ) )
             {
-                Class<?>[] parmTypes = method.getParameterTypes();
+                Class<?>[] parmTypes = method.getParameterTypes( );
 
                 // split arguments in to two dimensional array for varargs reflection invocation
                 // where it is expected that the parameter passed in to invoke the method
@@ -1333,7 +1277,7 @@ public class OgnlRuntime
 
                 for ( int i = 0; i < parmTypes.length; i++ )
                 {
-                    if ( parmTypes[i].isArray() )
+                    if ( parmTypes[i].isArray( ) )
                     {
                         convertedArgs = new Object[i + 1];
                         System.arraycopy( actualArgs, 0, convertedArgs, 0, convertedArgs.length );
@@ -1344,7 +1288,7 @@ public class OgnlRuntime
 
                         if ( actualArgs.length > i )
                         {
-                            List<Object> varArgsList = new ArrayList<Object>();
+                            List<Object> varArgsList = new ArrayList<Object>( );
                             for ( int j = i; j < actualArgs.length; j++ )
                             {
                                 if ( actualArgs[j] != null )
@@ -1353,7 +1297,7 @@ public class OgnlRuntime
                                 }
                             }
 
-                            varArgs = varArgsList.toArray();
+                            varArgs = varArgsList.toArray( );
                         }
                         else
                         {
@@ -1379,7 +1323,11 @@ public class OgnlRuntime
         }
         catch ( InvocationTargetException e )
         {
-            reason = e.getTargetException();
+            reason = e.getTargetException( );
+        }
+        catch ( OgnlException e )
+        {
+            reason = e;
         }
         finally
         {
@@ -1396,7 +1344,9 @@ public class OgnlRuntime
         {
             Class<?> targetClass = classForName( context, className );
             if ( targetClass == null )
+            {
                 throw new ClassNotFoundException( "Unable to resolve class with name " + className );
+            }
 
             MethodAccessor ma = getMethodAccessor( targetClass );
 
@@ -1410,11 +1360,11 @@ public class OgnlRuntime
 
     /**
      * Invokes the specified method against the target object.
-     * 
-     * @param context The current execution context.
-     * @param target The object to invoke the method on.
-     * @param methodName Name of the method - as in "getValue" or "add", etc..
-     * @param args Optional arguments needed for method.
+     *
+     * @param context      The current execution context.
+     * @param target       The object to invoke the method on.
+     * @param methodName   Name of the method - as in "getValue" or "add", etc..
+     * @param args         Optional arguments needed for method.
      * @return Result of invoking method.
      * @throws OgnlException For lots of different reasons.
      */
@@ -1422,9 +1372,11 @@ public class OgnlRuntime
         throws OgnlException
     {
         if ( target == null )
+        {
             throw new NullPointerException( "target is null for method " + methodName );
+        }
 
-        return getMethodAccessor( target.getClass() ).callMethod( context, target, methodName, args );
+        return getMethodAccessor( target.getClass( ) ).callMethod( context, target, methodName, args );
     }
 
     public static Object callConstructor( OgnlContext context, String className, Object[] args )
@@ -1454,14 +1406,15 @@ public class OgnlRuntime
             if ( ctor == null )
             {
                 actualArgs = _objectArrayPool.create( args.length );
-                if ( ( ctor = getConvertedConstructorAndArgs( context, target, constructors, args, actualArgs ) ) == null )
+                if ( ( ctor = getConvertedConstructorAndArgs( context, target, constructors, args, actualArgs ) )
+                    == null )
                 {
-                    throw new NoSuchMethodException();
+                    throw new NoSuchMethodException( );
                 }
             }
-            if ( !context.getMemberAccess().isAccessible( context, target, ctor, null ) )
+            if ( !context.getMemberAccess( ).isAccessible( context, target, ctor, null ) )
             {
-                throw new IllegalAccessException( "access denied to " + target.getName() + "()" );
+                throw new IllegalAccessException( "access denied to " + target.getName( ) + "()" );
             }
             return ctor.newInstance( actualArgs );
         }
@@ -1479,7 +1432,7 @@ public class OgnlRuntime
         }
         catch ( InvocationTargetException e )
         {
-            reason = e.getTargetException();
+            reason = e.getTargetException( );
         }
         catch ( InstantiationException e )
         {
@@ -1507,17 +1460,19 @@ public class OgnlRuntime
      * accessible according to the context's MemberAccess. If neither test passes this will return NotFound.
      */
     public static Object getMethodValue( OgnlContext context, Object target, String propertyName,
-                                               boolean checkAccessAndExistence )
+                                         boolean checkAccessAndExistence )
         throws OgnlException, IllegalAccessException, NoSuchMethodException, IntrospectionException
     {
         Object result = null;
-        Method m = getGetMethod( context, ( target == null ) ? null : target.getClass(), propertyName );
+        Method m = getGetMethod( context, ( target == null ) ? null : target.getClass( ), propertyName );
         if ( m == null )
-            m = getReadMethod( ( target == null ) ? null : target.getClass(), propertyName, 0 );
+        {
+            m = getReadMethod( ( target == null ) ? null : target.getClass( ), propertyName, 0 );
+        }
 
         if ( checkAccessAndExistence )
         {
-            if ( ( m == null ) || !context.getMemberAccess().isAccessible( context, target, m, propertyName ) )
+            if ( ( m == null ) || !context.getMemberAccess( ).isAccessible( context, target, m, propertyName ) )
             {
                 result = NotFound;
             }
@@ -1532,7 +1487,7 @@ public class OgnlRuntime
                 }
                 catch ( InvocationTargetException ex )
                 {
-                    throw new OgnlException( propertyName, ex.getTargetException() );
+                    throw new OgnlException( propertyName, ex.getTargetException( ) );
                 }
             }
             else
@@ -1554,11 +1509,11 @@ public class OgnlRuntime
         throws OgnlException, IllegalAccessException, NoSuchMethodException, IntrospectionException
     {
         boolean result = true;
-        Method m = getSetMethod( context, ( target == null ) ? null : target.getClass(), propertyName );
+        Method m = getSetMethod( context, ( target == null ) ? null : target.getClass( ), propertyName );
 
         if ( checkAccessAndExistence )
         {
-            if ( ( m == null ) || !context.getMemberAccess().isAccessible( context, target, m, propertyName ) )
+            if ( ( m == null ) || !context.getMemberAccess( ).isAccessible( context, target, m, propertyName ) )
             {
                 result = false;
             }
@@ -1572,7 +1527,7 @@ public class OgnlRuntime
 
                 try
                 {
-                    callAppropriateMethod( context, target, target, m.getName(), propertyName,
+                    callAppropriateMethod( context, target, target, m.getName( ), propertyName,
                                            Collections.nCopies( 1, m ), args );
                 }
                 finally
@@ -1590,148 +1545,83 @@ public class OgnlRuntime
     }
 
     public static List<Constructor<?>> getConstructors( Class<?> targetClass )
+        throws OgnlException
     {
-        List result;
-
-        synchronized ( _constructorCache )
-        {
-            if ( ( result = (List) _constructorCache.get( targetClass ) ) == null )
-            {
-                _constructorCache.put( targetClass, result = Arrays.asList( targetClass.getConstructors() ) );
-            }
-        }
-        return result;
+        return _constructorCache.get( targetClass );
     }
 
+    /**
+     * @param targetClass
+     * @param staticMethods if true (false) returns only the (non-)static methods
+     * @return Returns the map of methods for a given class
+     * @throws OgnlException
+     */
     public static Map<String, List<Method>> getMethods( Class<?> targetClass, boolean staticMethods )
+        throws OgnlException
     {
-        ClassCache cache = ( staticMethods ? _staticMethodCache : _instanceMethodCache );
-        Map<String, List<Method>> result;
-
-        synchronized ( cache )
+        DeclaredMethodCacheEntry.MethodType type;
+        if ( staticMethods )
         {
-            if ( ( result = cache.get( targetClass ) ) == null )
-            {
-                cache.put( targetClass, result = new HashMap<String, List<Method>>( 23 ) );
-
-                for ( Class<?> c = targetClass; c != null; c = c.getSuperclass() )
-                {
-                    Method[] ma = c.getDeclaredMethods();
-
-                    for ( Method method : ma )
-                    {
-                        // skip over synthetic methods
-
-                        if ( !isMethodCallable( method ) )
-                        {
-                            continue;
-                        }
-
-                        if ( Modifier.isStatic( method.getModifiers() ) == staticMethods )
-                        {
-                            List<Method> ml = result.get( method.getName() );
-
-                            if ( ml == null )
-                            {
-                                result.put( method.getName(), ml = new ArrayList<Method>() );
-                            }
-
-                            ml.add( method );
-                        }
-                    }
-                }
-            }
+            type = DeclaredMethodCacheEntry.MethodType.STATIC;
         }
+        else
+        {
+            type = DeclaredMethodCacheEntry.MethodType.NON_STATIC;
 
-        return result;
+        }
+        return _methodCache.get( new DeclaredMethodCacheEntry( targetClass, type ) );
     }
 
     public static List<Method> getMethods( Class<?> targetClass, String name, boolean staticMethods )
+        throws OgnlException
     {
         return getMethods( targetClass, staticMethods ).get( name );
     }
 
     public static Map<String, Field> getFields( Class<?> targetClass )
+        throws OgnlException
     {
-        Map<String, Field> result;
-
-        synchronized ( _fieldCache )
-        {
-            if ( ( result = _fieldCache.get( targetClass ) ) == null )
-            {
-                Field fa[];
-
-                result = new HashMap<String, Field>( 23 );
-                fa = targetClass.getDeclaredFields();
-                for ( Field field : fa )
-                {
-                    result.put( field.getName(), field );
-                }
-                _fieldCache.put( targetClass, result );
-            }
-        }
-        return result;
+        return _fieldCache.get( targetClass );
     }
 
     public static Field getField( Class<?> inClass, String name )
+        throws OgnlException
     {
-        Field result = null;
+        Field o = getFields( inClass ).get( name );
 
-        synchronized ( _fieldCache )
+        if ( o == null )
         {
-            Field o = getFields( inClass ).get( name );
-
-            if ( o == null )
+            // if o is null, it should search along the superclasses
+            Class<?> sc = inClass.getSuperclass( );
+            while ( sc != null )
             {
-                _superclasses.clear();
-                for ( Class<?> sc = inClass; ( sc != null );  )
-                {
-                    sc = sc.getSuperclass();
-                    if ( ( o = getFields( sc ).get( name ) ) == null )
-                    {
-                        break;
-                    }
-
-                    _superclasses.add( sc );
-
-                    if ( ( result = o ) != null )
-                    {
-                        break;
-                    }
-                }
-                /*
-                 * Bubble the found value (either cache miss or actual field) to all supeclasses that we saw for quicker
-                 * access next time.
-                 */
-                for ( Class<?> _superclass : _superclasses )
+                o = getFields( sc ).get( name );
+                if ( o != null )
                 {
-                    getFields( _superclass ).put( name, result );
+                    return o;
                 }
-            }
-            else
-            {
-                result = o;
+                sc = sc.getSuperclass( );
             }
         }
-        return result;
+        return o;
     }
 
     public static Object getFieldValue( OgnlContext context, Object target, String propertyName )
-        throws NoSuchFieldException
+        throws NoSuchFieldException, OgnlException
     {
         return getFieldValue( context, target, propertyName, false );
     }
 
     public static Object getFieldValue( OgnlContext context, Object target, String propertyName,
                                         boolean checkAccessAndExistence )
-        throws NoSuchFieldException
+        throws NoSuchFieldException, OgnlException
     {
         Object result = null;
-        Field f = getField( ( target == null ) ? null : target.getClass(), propertyName );
+        Field f = getField( ( target == null ) ? null : target.getClass( ), propertyName );
 
         if ( checkAccessAndExistence )
         {
-            if ( ( f == null ) || !context.getMemberAccess().isAccessible( context, target, f, propertyName ) )
+            if ( ( f == null ) || !context.getMemberAccess( ).isAccessible( context, target, f, propertyName ) )
             {
                 result = NotFound;
             }
@@ -1744,13 +1634,13 @@ public class OgnlRuntime
             }
             try
             {
-                Object state = null;
+                Object state;
 
-                if ( !Modifier.isStatic( f.getModifiers() ) )
+                if ( !Modifier.isStatic( f.getModifiers( ) ) )
                 {
-                    state = context.getMemberAccess().setup( context, target, f, propertyName );
+                    state = context.getMemberAccess( ).setup( context, target, f, propertyName );
                     result = f.get( target );
-                    context.getMemberAccess().restore( context, target, f, propertyName, state );
+                    context.getMemberAccess( ).restore( context, target, f, propertyName, state );
                 }
                 else
                 {
@@ -1773,16 +1663,17 @@ public class OgnlRuntime
 
         try
         {
-            Field f = getField( ( target == null ) ? null : target.getClass(), propertyName );
+            Field f = getField( ( target == null ) ? null : target.getClass( ), propertyName );
             Object state;
 
-            if ( ( f != null ) && !Modifier.isStatic( f.getModifiers() ) )
+            if ( ( f != null ) && !Modifier.isStatic( f.getModifiers( ) ) )
             {
-                state = context.getMemberAccess().setup( context, target, f, propertyName );
+                state = context.getMemberAccess( ).setup( context, target, f, propertyName );
                 try
                 {
-                    if ( isTypeCompatible( value, f.getType() )
-                        || ( ( value = getConvertedType( context, target, f, propertyName, value, f.getType() ) ) != null ) )
+                    if ( isTypeCompatible( value, f.getType( ) ) || (
+                        ( value = getConvertedType( context, target, f, propertyName, value, f.getType( ) ) )
+                            != null ) )
                     {
                         f.set( target, value );
                         result = true;
@@ -1790,7 +1681,7 @@ public class OgnlRuntime
                 }
                 finally
                 {
-                    context.getMemberAccess().restore( context, target, f, propertyName, state );
+                    context.getMemberAccess( ).restore( context, target, f, propertyName, state );
                 }
             }
         }
@@ -1802,16 +1693,18 @@ public class OgnlRuntime
     }
 
     public static boolean isFieldAccessible( OgnlContext context, Object target, Class<?> inClass, String propertyName )
+        throws OgnlException
     {
         return isFieldAccessible( context, target, getField( inClass, propertyName ), propertyName );
     }
 
     public static boolean isFieldAccessible( OgnlContext context, Object target, Field field, String propertyName )
     {
-        return context.getMemberAccess().isAccessible( context, target, field, propertyName );
+        return context.getMemberAccess( ).isAccessible( context, target, field, propertyName );
     }
 
     public static boolean hasField( OgnlContext context, Object target, Class<?> inClass, String propertyName )
+        throws OgnlException
     {
         Field f = getField( inClass, propertyName );
 
@@ -1828,8 +1721,8 @@ public class OgnlRuntime
 
             if ( c == null )
             {
-                throw new OgnlException( "Unable to find class " + className + " when resolving field name of "
-                    + fieldName );
+                throw new OgnlException(
+                    "Unable to find class " + className + " when resolving field name of " + fieldName );
             }
 
             /*
@@ -1840,16 +1733,16 @@ public class OgnlRuntime
             {
                 return c;
             }
-            else if ( OgnlRuntime.isJdk15() && c.isEnum() )
+            else if ( OgnlRuntime.isJdk15( ) && c.isEnum( ) )
             {
                 @SuppressWarnings( "unchecked" ) // see the if condition
-                Enum<?> ret = Enum.valueOf( (Class<? extends Enum>) c, fieldName );
+                    Enum<?> ret = Enum.valueOf( (Class<? extends Enum>) c, fieldName );
                 return ret;
             }
             else
             {
                 Field f = c.getField( fieldName );
-                if ( !Modifier.isStatic( f.getModifiers() ) )
+                if ( !Modifier.isStatic( f.getModifiers( ) ) )
                 {
                     throw new OgnlException( "Field " + fieldName + " of class " + className + " is not static" );
                 }
@@ -1877,87 +1770,61 @@ public class OgnlRuntime
         throw new OgnlException( "Could not get static field " + fieldName + " from class " + className, reason );
     }
 
+    /**
+     * @param targetClass
+     * @param propertyName
+     * @param findSets
+     * @return Returns the list of (g)setter of a class for a given property name
+     * @throws OgnlException
+     */
     public static List<Method> getDeclaredMethods( Class<?> targetClass, String propertyName, boolean findSets )
+        throws OgnlException
     {
-        List<Method> result = null;
-        ClassCache cache = _declaredMethods[findSets ? 0 : 1];
-
-        synchronized ( cache )
+        String baseName = Character.toUpperCase( propertyName.charAt( 0 ) ) + propertyName.substring( 1 );
+        List<Method> result = new ArrayList<Method>( );
+        List<String> find = new ArrayList<String>( 2 );
+        if ( findSets )
+        {
+            find.add( SET_PREFIX + baseName );
+        }
+        else
         {
-            Map<String, List<Method>> propertyCache = cache.get( targetClass );
+            find.add( IS_PREFIX + baseName );
+            find.add( GET_PREFIX + baseName );
 
-            if ( ( propertyCache == null ) || ( ( result = propertyCache.get( propertyName ) ) == null ) )
+        }
+        for ( String s : find )
+        {
+            List<Method> methodList = _methodCache.get( new DeclaredMethodCacheEntry( targetClass ) ).get( s );
+            if ( methodList != null )
             {
-
-                String baseName = Character.toUpperCase( propertyName.charAt( 0 ) ) + propertyName.substring( 1 );
-
-                for ( Class<?> c = targetClass; c != null; c = c.getSuperclass() )
-                {
-                    Method[] methods = c.getDeclaredMethods();
-
-                    for ( Method method : methods )
-                    {
-
-                        if ( !isMethodCallable( method ) )
-                        {
-                            continue;
-                        }
-
-                        String ms = method.getName();
-
-                        if ( ms.endsWith( baseName ) )
-                        {
-                            boolean isSet, isIs = false;
-
-                            if ( ( isSet = ms.startsWith( SET_PREFIX ) ) || ms.startsWith( GET_PREFIX ) || ( isIs =
-                                ms.startsWith( IS_PREFIX ) ) )
-                            {
-                                int prefixLength = ( isIs ? 2 : 3 );
-
-                                if ( isSet == findSets )
-                                {
-                                    if ( baseName.length() == ( ms.length() - prefixLength ) )
-                                    {
-                                        if ( result == null )
-                                        {
-                                            result = new ArrayList<Method>();
-                                        }
-                                        result.add( method );
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-                if ( propertyCache == null )
-                {
-                    cache.put( targetClass, propertyCache = new HashMap<String, List<Method>>( 101 ) );
-                }
-
-                propertyCache.put( propertyName, result );
+                result.addAll( methodList );
             }
-            return result;
         }
+
+        return result;
+
     }
 
     /**
      * Convenience used to check if a method is volatile or synthetic so as to avoid calling un-callable methods.
-     * 
+     *
      * @param m The method to check.
      * @return True if the method should be callable, false otherwise.
      */
-    static boolean isMethodCallable( Method m )
+    //TODO: the method was intented as private, so it'd need to move in a util class
+    public static boolean isMethodCallable( Method m )
     {
-        return !( ( isJdk15() && m.isSynthetic() ) || Modifier.isVolatile( m.getModifiers() ) );
+        return !( ( isJdk15( ) && m.isSynthetic( ) ) || Modifier.isVolatile( m.getModifiers( ) ) );
 
     }
 
-    public static Method getGetMethod( OgnlContext context, Class<?> targetClass, String propertyName )
+    public static Method getGetMethod( OgnlContext unused, Class<?> targetClass, String propertyName )
         throws IntrospectionException, OgnlException
     {
         Method result = null;
 
-        List<Method> methods = getDeclaredMethods( targetClass, propertyName, false /* find 'get' methods */);
+        List<Method> methods = getDeclaredMethods( targetClass, propertyName, false /* find 'get' methods */ );
 
         if ( methods != null )
         {
@@ -1978,7 +1845,7 @@ public class OgnlRuntime
 
     public static boolean isMethodAccessible( OgnlContext context, Object target, Method method, String propertyName )
     {
-        return ( method != null ) && context.getMemberAccess().isAccessible( context, target, method, propertyName );
+        return ( method != null ) && context.getMemberAccess( ).isAccessible( context, target, method, propertyName );
     }
 
     public static boolean hasGetMethod( OgnlContext context, Object target, Class<?> targetClass, String propertyName )
@@ -1992,7 +1859,7 @@ public class OgnlRuntime
     {
         Method result = null;
 
-        List<Method> methods = getDeclaredMethods( targetClass, propertyName, true /* find 'set' methods */);
+        List<Method> methods = getDeclaredMethods( targetClass, propertyName, true /* find 'set' methods */ );
 
         if ( methods != null )
         {
@@ -2020,8 +1887,8 @@ public class OgnlRuntime
     public static boolean hasGetProperty( OgnlContext context, Object target, Object oname )
         throws IntrospectionException, OgnlException
     {
-        Class<?> targetClass = ( target == null ) ? null : target.getClass();
-        String name = oname.toString();
+        Class<?> targetClass = ( target == null ) ? null : target.getClass( );
+        String name = oname.toString( );
 
         return hasGetMethod( context, target, targetClass, name ) || hasField( context, target, targetClass, name );
     }
@@ -2029,28 +1896,29 @@ public class OgnlRuntime
     public static boolean hasSetProperty( OgnlContext context, Object target, Object oname )
         throws IntrospectionException, OgnlException
     {
-        Class<?> targetClass = ( target == null ) ? null : target.getClass();
-        String name = oname.toString();
+        Class<?> targetClass = ( target == null ) ? null : target.getClass( );
+        String name = oname.toString( );
 
         return hasSetMethod( context, target, targetClass, name ) || hasField( context, target, targetClass, name );
     }
 
     private static boolean indexMethodCheck( List<Method> methods )
+        throws CacheException
     {
         boolean result = false;
 
-        if ( methods.size() > 0 )
+        if ( methods.size( ) > 0 )
         {
             Method fm = methods.get( 0 );
             Class<?>[] fmpt = getParameterTypes( fm );
             int fmpc = fmpt.length;
-            Class<?> lastMethodClass = fm.getDeclaringClass();
+            Class<?> lastMethodClass = fm.getDeclaringClass( );
 
             result = true;
-            for ( int i = 1; result && ( i < methods.size() ); i++ )
+            for ( int i = 1; result && ( i < methods.size( ) ); i++ )
             {
                 Method m = methods.get( i );
-                Class<?> c = m.getDeclaringClass();
+                Class<?> c = m.getDeclaringClass( );
 
                 // Check to see if more than one method implemented per class
                 if ( lastMethodClass == c )
@@ -2080,14 +1948,15 @@ public class OgnlRuntime
         }
         return result;
     }
-
-    static void findObjectIndexedPropertyDescriptors( Class<?> targetClass, Map<String, PropertyDescriptor> intoMap )
+    //TODO: again, this method was local
+    public static void findObjectIndexedPropertyDescriptors( Class<?> targetClass,
+                                                             Map<String, PropertyDescriptor> intoMap )
         throws OgnlException
     {
         Map<String, List<Method>> allMethods = getMethods( targetClass, false );
         Map<String, List<Method>> pairs = new HashMap<String, List<Method>>( 101 );
 
-        for ( String methodName : allMethods.keySet() )
+        for ( String methodName : allMethods.keySet( ) )
         {
             List<Method> methods = allMethods.get( methodName );
 
@@ -2097,33 +1966,33 @@ public class OgnlRuntime
              */
             if ( indexMethodCheck( methods ) )
             {
-                boolean isGet = false, isSet = false;
+                boolean isGet = false, isSet;
                 Method m = methods.get( 0 );
 
                 if ( ( ( isSet = methodName.startsWith( SET_PREFIX ) ) || ( isGet =
-                    methodName.startsWith( GET_PREFIX ) ) ) && ( methodName.length() > 3 ) )
+                    methodName.startsWith( GET_PREFIX ) ) ) && ( methodName.length( ) > 3 ) )
                 {
                     String propertyName = Introspector.decapitalize( methodName.substring( 3 ) );
                     Class<?>[] parameterTypes = getParameterTypes( m );
                     int parameterCount = parameterTypes.length;
 
-                    if ( isGet && ( parameterCount == 1 ) && ( m.getReturnType() != Void.TYPE ) )
+                    if ( isGet && ( parameterCount == 1 ) && ( m.getReturnType( ) != Void.TYPE ) )
                     {
                         List<Method> pair = pairs.get( propertyName );
 
                         if ( pair == null )
                         {
-                            pairs.put( propertyName, pair = new ArrayList<Method>() );
+                            pairs.put( propertyName, pair = new ArrayList<Method>( ) );
                         }
                         pair.add( m );
                     }
-                    if ( isSet && ( parameterCount == 2 ) && ( m.getReturnType() == Void.TYPE ) )
+                    if ( isSet && ( parameterCount == 2 ) && ( m.getReturnType( ) == Void.TYPE ) )
                     {
                         List<Method> pair = pairs.get( propertyName );
 
                         if ( pair == null )
                         {
-                            pairs.put( propertyName, pair = new ArrayList<Method>() );
+                            pairs.put( propertyName, pair = new ArrayList<Method>( ) );
                         }
                         pair.add( m );
                     }
@@ -2131,20 +2000,20 @@ public class OgnlRuntime
             }
         }
 
-        for ( String propertyName : pairs.keySet() )
+        for ( String propertyName : pairs.keySet( ) )
         {
             List<Method> methods = pairs.get( propertyName );
 
-            if ( methods.size() == 2 )
+            if ( methods.size( ) == 2 )
             {
                 Method method1 = methods.get( 0 ), method2 = methods.get( 1 ), setMethod =
-                    ( method1.getParameterTypes().length == 2 ) ? method1 : method2, getMethod =
+                    ( method1.getParameterTypes( ).length == 2 ) ? method1 : method2, getMethod =
                     ( setMethod == method1 ) ? method2 : method1;
-                Class<?> keyType = getMethod.getParameterTypes()[0], propertyType = getMethod.getReturnType();
+                Class<?> keyType = getMethod.getParameterTypes( )[0], propertyType = getMethod.getReturnType( );
 
-                if ( keyType == setMethod.getParameterTypes()[0] )
+                if ( keyType == setMethod.getParameterTypes( )[0] )
                 {
-                    if ( propertyType == setMethod.getParameterTypes()[1] )
+                    if ( propertyType == setMethod.getParameterTypes( )[1] )
                     {
                         ObjectIndexedPropertyDescriptor propertyDescriptor;
 
@@ -2169,49 +2038,16 @@ public class OgnlRuntime
 
     /**
      * This method returns the property descriptors for the given class as a Map.
-     * 
+     *
      * @param targetClass The class to get the descriptors for.
      * @return Map map of property descriptors for class.
      * @throws IntrospectionException on errors using {@link Introspector}.
-     * @throws OgnlException On general errors.
+     * @throws OgnlException          On general errors.
      */
     public static Map<String, PropertyDescriptor> getPropertyDescriptors( Class<?> targetClass )
         throws IntrospectionException, OgnlException
     {
-        Map<String, PropertyDescriptor> result;
-
-        synchronized ( _propertyDescriptorCache )
-        {
-            if ( ( result = _propertyDescriptorCache.get( targetClass ) ) == null )
-            {
-                PropertyDescriptor[] pda = Introspector.getBeanInfo( targetClass ).getPropertyDescriptors();
-
-                result = new HashMap<String, PropertyDescriptor>( 101 );
-                for ( int i = 0, icount = pda.length; i < icount; i++ )
-                {
-                    // workaround for Introspector bug 6528714 (bugs.sun.com)
-                    if ( pda[i].getReadMethod() != null && !isMethodCallable( pda[i].getReadMethod() ) )
-                    {
-                        pda[i].setReadMethod( findClosestMatchingMethod( targetClass, pda[i].getReadMethod(),
-                                                                         pda[i].getName(), pda[i].getPropertyType(),
-                                                                         true ) );
-                    }
-                    if ( pda[i].getWriteMethod() != null && !isMethodCallable( pda[i].getWriteMethod() ) )
-                    {
-                        pda[i].setWriteMethod( findClosestMatchingMethod( targetClass, pda[i].getWriteMethod(),
-                                                                          pda[i].getName(), pda[i].getPropertyType(),
-                                                                          false ) );
-                    }
-
-                    result.put( pda[i].getName(), pda[i] );
-                }
-
-                findObjectIndexedPropertyDescriptors( targetClass, result );
-                _propertyDescriptorCache.put( targetClass, result );
-            }
-        }
-
-        return result;
+        return _propertyDescriptorCache.get( targetClass );
     }
 
     /**
@@ -2222,64 +2058,35 @@ public class OgnlRuntime
         throws IntrospectionException, OgnlException
     {
         if ( targetClass == null )
-            return null;
-
-        return getPropertyDescriptors( targetClass ).get( propertyName );
-    }
-
-    static Method findClosestMatchingMethod( Class<?> targetClass, Method m, String propertyName, Class<?> propertyType,
-                                             boolean isReadMethod )
-    {
-        List<Method> methods = getDeclaredMethods( targetClass, propertyName, !isReadMethod );
-
-        for ( Method method : methods )
         {
-            if ( method.getName().equals( m.getName() ) && m.getReturnType().isAssignableFrom( m.getReturnType() )
-                && method.getReturnType() == propertyType
-                && method.getParameterTypes().length == m.getParameterTypes().length )
-            {
-                return method;
-            }
+            return null;
         }
 
-        return m;
+        return getPropertyDescriptors( targetClass ).get( propertyName );
     }
 
     public static PropertyDescriptor[] getPropertyDescriptorsArray( Class<?> targetClass )
-        throws IntrospectionException
+        throws IntrospectionException, OgnlException
     {
-        PropertyDescriptor[] result = null;
-
-        if ( targetClass != null )
-        {
-            synchronized ( _propertyDescriptorCache )
-            {
-                if ( ( result = (PropertyDescriptor[]) _propertyDescriptorCache.get( targetClass ) ) == null )
-                {
-                    _propertyDescriptorCache.put( targetClass, result =
-                        Introspector.getBeanInfo( targetClass ).getPropertyDescriptors() );
-                }
-            }
-        }
-        return result;
+        return (PropertyDescriptor[]) getPropertyDescriptors( targetClass ).entrySet( ).toArray( );
     }
 
     /**
      * Gets the property descriptor with the given name for the target class given.
-     * 
+     *
      * @param targetClass Class for which property descriptor is desired
-     * @param name Name of property
+     * @param name        Name of property
      * @return PropertyDescriptor of the named property or null if the class has no property with the given name
      */
     public static PropertyDescriptor getPropertyDescriptorFromArray( Class<?> targetClass, String name )
-        throws IntrospectionException
+        throws IntrospectionException, OgnlException
     {
         PropertyDescriptor result = null;
         PropertyDescriptor[] pda = getPropertyDescriptorsArray( targetClass );
 
         for ( int i = 0, icount = pda.length; ( result == null ) && ( i < icount ); i++ )
         {
-            if ( pda[i].getName().compareTo( name ) == 0 )
+            if ( pda[i].getName( ).compareTo( name ) == 0 )
             {
                 result = pda[i];
             }
@@ -2289,35 +2096,33 @@ public class OgnlRuntime
 
     public static void setMethodAccessor( Class<?> cls, MethodAccessor accessor )
     {
-        synchronized ( _methodAccessors )
-        {
-            _methodAccessors.put( cls, accessor );
-        }
+        _methodAccessors.put( cls, accessor );
     }
 
     public static MethodAccessor getMethodAccessor( Class<?> cls )
         throws OgnlException
     {
-        MethodAccessor answer = (MethodAccessor) getHandler( cls, _methodAccessors );
+        MethodAccessor answer = ClassCacheHandler.getHandler( cls, _methodAccessors );
         if ( answer != null )
+        {
             return answer;
+        }
         throw new OgnlException( "No method accessor for " + cls );
     }
 
     public static void setPropertyAccessor( Class<?> cls, PropertyAccessor accessor )
     {
-        synchronized ( _propertyAccessors )
-        {
-            _propertyAccessors.put( cls, accessor );
-        }
+        _propertyAccessors.put( cls, accessor );
     }
 
     public static PropertyAccessor getPropertyAccessor( Class<?> cls )
         throws OgnlException
     {
-        PropertyAccessor answer = (PropertyAccessor) getHandler( cls, _propertyAccessors );
+        PropertyAccessor answer = ClassCacheHandler.getHandler( cls, _propertyAccessors );
         if ( answer != null )
+        {
             return answer;
+        }
 
         throw new OgnlException( "No property accessor for class " + cls );
     }
@@ -2325,93 +2130,33 @@ public class OgnlRuntime
     public static ElementsAccessor getElementsAccessor( Class<?> cls )
         throws OgnlException
     {
-        ElementsAccessor answer = (ElementsAccessor) getHandler( cls, _elementsAccessors );
+        ElementsAccessor answer = ClassCacheHandler.getHandler( cls, _elementsAccessors );
         if ( answer != null )
+        {
             return answer;
+        }
         throw new OgnlException( "No elements accessor for class " + cls );
     }
 
     public static void setElementsAccessor( Class<?> cls, ElementsAccessor accessor )
     {
-        synchronized ( _elementsAccessors )
-        {
-            _elementsAccessors.put( cls, accessor );
-        }
+        _elementsAccessors.put( cls, accessor );
     }
 
     public static NullHandler getNullHandler( Class<?> cls )
         throws OgnlException
     {
-        NullHandler answer = (NullHandler) getHandler( cls, _nullHandlers );
+        NullHandler answer = ClassCacheHandler.getHandler( cls, _nullHandlers );
         if ( answer != null )
+        {
             return answer;
+        }
         throw new OgnlException( "No null handler for class " + cls );
     }
 
     public static void setNullHandler( Class<?> cls, NullHandler handler )
     {
-        synchronized ( _nullHandlers )
-        {
-            _nullHandlers.put( cls, handler );
-        }
-    }
-
-    private static Object getHandler( Class<?> forClass, ClassCache handlers )
-    {
-        Object answer;
-
-        synchronized ( handlers )
-        {
-            if ( ( answer = handlers.get( forClass ) ) == null )
-            {
-                Class<?> keyFound;
-
-                if ( forClass.isArray() )
-                {
-                    answer = handlers.get( Object[].class );
-                    keyFound = null;
-                }
-                else
-                {
-                    keyFound = forClass;
-                    outer: for ( Class<?> c = forClass; c != null; c = c.getSuperclass() )
-                    {
-                        answer = handlers.get( c );
-                        if ( answer == null )
-                        {
-                            Class<?>[] interfaces = c.getInterfaces();
-                            for ( Class<?> iface : interfaces )
-                            {
-                                answer = handlers.get( iface );
-                                if ( answer == null )
-                                {
-                                    /* Try super-interfaces */
-                                    answer = getHandler( iface, handlers );
-                                }
-                                if ( answer != null )
-                                {
-                                    keyFound = iface;
-                                    break outer;
-                                }
-                            }
-                        }
-                        else
-                        {
-                            keyFound = c;
-                            break;
-                        }
-                    }
-                }
-                if ( answer != null )
-                {
-                    if ( keyFound != forClass )
-                    {
-                        handlers.put( forClass, answer );
-                    }
-                }
-            }
-        }
-        return answer;
+        _nullHandlers.put( cls, handler );
     }
 
     public static Object getProperty( OgnlContext context, Object source, Object name )
@@ -2425,7 +2170,7 @@ public class OgnlRuntime
         }
         if ( ( accessor = getPropertyAccessor( getTargetClass( source ) ) ) == null )
         {
-            throw new OgnlException( "No property accessor for " + getTargetClass( source ).getName() );
+            throw new OgnlException( "No property accessor for " + getTargetClass( source ).getName( ) );
         }
 
         return accessor.getProperty( context, source, name );
@@ -2442,7 +2187,7 @@ public class OgnlRuntime
         }
         if ( ( accessor = getPropertyAccessor( getTargetClass( target ) ) ) == null )
         {
-            throw new OgnlException( "No property accessor for " + getTargetClass( target ).getName() );
+            throw new OgnlException( "No property accessor for " + getTargetClass( target ).getName( ) );
         }
 
         accessor.setProperty( context, target, name, value );
@@ -2492,18 +2237,18 @@ public class OgnlRuntime
 
         try
         {
-            PropertyDescriptor pd = getPropertyDescriptor( ( source == null ) ? null : source.getClass(), name );
+            PropertyDescriptor pd = getPropertyDescriptor( ( source == null ) ? null : source.getClass( ), name );
             Method m;
 
             if ( pd instanceof IndexedPropertyDescriptor )
             {
-                m = ( (IndexedPropertyDescriptor) pd ).getIndexedReadMethod();
+                m = ( (IndexedPropertyDescriptor) pd ).getIndexedReadMethod( );
             }
             else
             {
                 if ( pd instanceof ObjectIndexedPropertyDescriptor )
                 {
-                    m = ( (ObjectIndexedPropertyDescriptor) pd ).getIndexedReadMethod();
+                    m = ( (ObjectIndexedPropertyDescriptor) pd ).getIndexedReadMethod( );
                 }
                 else
                 {
@@ -2511,7 +2256,7 @@ public class OgnlRuntime
                 }
             }
 
-            return callMethod( context, source, m.getName(), args );
+            return callMethod( context, source, m.getName( ), args );
 
         }
         catch ( OgnlException ex )
@@ -2535,18 +2280,18 @@ public class OgnlRuntime
 
         try
         {
-            PropertyDescriptor pd = getPropertyDescriptor( ( source == null ) ? null : source.getClass(), name );
+            PropertyDescriptor pd = getPropertyDescriptor( ( source == null ) ? null : source.getClass( ), name );
             Method m;
 
             if ( pd instanceof IndexedPropertyDescriptor )
             {
-                m = ( (IndexedPropertyDescriptor) pd ).getIndexedWriteMethod();

[... 443 lines stripped ...]


Mime
View raw message