You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mc...@apache.org on 2011/10/17 02:14:45 UTC

svn commit: r1184962 - in /commons/proper/ognl/branches/new-cache-approach/src: main/java/org/apache/commons/ognl/ main/java/org/apache/commons/ognl/internal/entry/ test/java/org/apache/commons/ognl/internal/

Author: mcucchiara
Date: Mon Oct 17 00:14:45 2011
New Revision: 1184962

URL: http://svn.apache.org/viewvc?rev=1184962&view=rev
Log:
New _methodAccessCache implementation

Added:
    commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/entry/MethodAccessCacheEntryFactory.java
    commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/entry/MethodAccessEntryValue.java
    commons/proper/ognl/branches/new-cache-approach/src/test/java/org/apache/commons/ognl/internal/MethodAccessCacheTest.java
Modified:
    commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/OgnlRuntime.java

Modified: commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/OgnlRuntime.java
URL: http://svn.apache.org/viewvc/commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/OgnlRuntime.java?rev=1184962&r1=1184961&r2=1184962&view=diff
==============================================================================
--- commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/OgnlRuntime.java (original)
+++ commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/OgnlRuntime.java Mon Oct 17 00:14:45 2011
@@ -35,6 +35,8 @@ import org.apache.commons.ognl.internal.
 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;
@@ -215,7 +217,8 @@ public class OgnlRuntime
 
     static final ObjectArrayPool _objectArrayPool = new ObjectArrayPool( );
 
-    static final IntHashMap<Integer, Boolean> _methodAccessCache = new IntHashMap<Integer, Boolean>( );
+    static final Cache<Method, MethodAccessEntryValue> _methodAccessCache =
+            new ConcurrentHashMapCache<Method, MethodAccessEntryValue>( new MethodAccessCacheEntryFactory( ) );;
 
     private static final MethodPermCacheEntryFactory methodPermCacheEntryFactory =
         new MethodPermCacheEntryFactory( _securityManager );
@@ -762,56 +765,32 @@ public class OgnlRuntime
     public static Object invokeMethod( Object target, Method method, Object[] argsArray )
         throws InvocationTargetException, IllegalAccessException, CacheException
     {
-        boolean syncInvoke = 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 ) )
+            if ( !_methodPermCache.get( method ) )
             {
-                syncInvoke = true;
+                throw new IllegalAccessException( "Method [" + method + "] cannot be accessed." );
             }
-        }
 
-        Object result;
-        boolean wasAccessible = true;
+        }
+        MethodAccessEntryValue entry = _methodAccessCache.get( method );
 
-        if ( syncInvoke )
+        if ( !entry.isAccessible())
         {
+            // only synchronize method invocation if it actually requires it
             synchronized ( method )
             {
-                if ( _securityManager != null )
-                {
-                    if ( !_methodPermCache.get( method ) )
-                    {
-                        throw new IllegalAccessException( "Method [" + method + "] cannot be accessed." );
-                    }
-                    
-                }
 
-                if ( !Modifier.isPublic( method.getModifiers( ) ) || !Modifier.isPublic(
-                    method.getDeclaringClass( ).getModifiers( ) ) )
-                {
-                    if ( !( wasAccessible = method.isAccessible( ) ) )
-                    {
-                        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( ) )
                 {
                     method.setAccessible( false );
                 }
@@ -819,14 +798,6 @@ public class OgnlRuntime
         }
         else
         {
-            if ( _securityManager!=null )
-            {
-                if ( !_methodPermCache.get( method ) )
-                {
-                    throw new IllegalAccessException( "Method [" + method + "] cannot be accessed." );
-                }
-            }
-
             result = method.invoke( target, argsArray );
         }
 

Added: commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/entry/MethodAccessCacheEntryFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/entry/MethodAccessCacheEntryFactory.java?rev=1184962&view=auto
==============================================================================
--- commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/entry/MethodAccessCacheEntryFactory.java (added)
+++ commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/entry/MethodAccessCacheEntryFactory.java Mon Oct 17 00:14:45 2011
@@ -0,0 +1,46 @@
+package org.apache.commons.ognl.internal.entry;
+
+import org.apache.commons.ognl.internal.CacheException;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+* User: Maurizio Cucchiara
+* Date: 10/17/11
+* Time: 1:14 AM
+*/
+public class MethodAccessCacheEntryFactory
+    implements CacheEntryFactory<Method, MethodAccessEntryValue>
+{
+
+    public static final MethodAccessEntryValue INACCESSIBLE_NON_PUBLIC_METHOD =
+        new MethodAccessEntryValue( false, true );
+
+    public static final MethodAccessEntryValue ACCESSIBLE_NON_PUBLIC_METHOD =
+        new MethodAccessEntryValue( true, true );
+
+    public static final MethodAccessEntryValue PUBLIC_METHOD = new MethodAccessEntryValue( true );
+
+    public MethodAccessEntryValue create( Method method )
+        throws CacheException
+    {
+        final boolean notPublic = !Modifier.isPublic( method.getModifiers( ) ) || !Modifier.isPublic(
+            method.getDeclaringClass( ).getModifiers( ) );
+        if ( notPublic )
+        {
+            if ( !method.isAccessible( ) )
+            {
+                return INACCESSIBLE_NON_PUBLIC_METHOD;
+            }
+            else
+            {
+                return ACCESSIBLE_NON_PUBLIC_METHOD;
+            }
+        }
+        else
+        {
+            return PUBLIC_METHOD;
+        }
+    }
+}

Added: commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/entry/MethodAccessEntryValue.java
URL: http://svn.apache.org/viewvc/commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/entry/MethodAccessEntryValue.java?rev=1184962&view=auto
==============================================================================
--- commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/entry/MethodAccessEntryValue.java (added)
+++ commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/entry/MethodAccessEntryValue.java Mon Oct 17 00:14:45 2011
@@ -0,0 +1,34 @@
+package org.apache.commons.ognl.internal.entry;
+
+/**
+* User: Maurizio Cucchiara
+* Date: 10/17/11
+* Time: 1:13 AM
+*/
+public class MethodAccessEntryValue
+{
+    private boolean isAccessible;
+
+    private boolean notPublic;
+
+    public MethodAccessEntryValue( boolean accessible )
+    {
+        this.isAccessible = accessible;
+    }
+
+    public MethodAccessEntryValue( boolean accessible, boolean notPublic )
+    {
+        isAccessible = accessible;
+        this.notPublic = notPublic;
+    }
+
+    public boolean isAccessible( )
+    {
+        return isAccessible;
+    }
+
+    public boolean isNotPublic( )
+    {
+        return notPublic;
+    }
+}

Added: commons/proper/ognl/branches/new-cache-approach/src/test/java/org/apache/commons/ognl/internal/MethodAccessCacheTest.java
URL: http://svn.apache.org/viewvc/commons/proper/ognl/branches/new-cache-approach/src/test/java/org/apache/commons/ognl/internal/MethodAccessCacheTest.java?rev=1184962&view=auto
==============================================================================
--- commons/proper/ognl/branches/new-cache-approach/src/test/java/org/apache/commons/ognl/internal/MethodAccessCacheTest.java (added)
+++ commons/proper/ognl/branches/new-cache-approach/src/test/java/org/apache/commons/ognl/internal/MethodAccessCacheTest.java Mon Oct 17 00:14:45 2011
@@ -0,0 +1,52 @@
+package org.apache.commons.ognl.internal;
+
+import org.apache.commons.ognl.internal.entry.MethodAccessCacheEntryFactory;
+import org.apache.commons.ognl.internal.entry.MethodAccessEntryValue;
+import org.apache.commons.ognl.test.objects.Root;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.lang.reflect.Method;
+
+/**
+ * User: Maurizio Cucchiara
+ * Date: 10/17/11
+ * Time: 12:59 AM
+ */
+public class MethodAccessCacheTest
+{
+    private Cache<Method, MethodAccessEntryValue> cache =
+        new ConcurrentHashMapCache<Method, MethodAccessEntryValue>( new MethodAccessCacheEntryFactory( ) );
+
+    @Test
+    public void testGetAccessibleNonPublicMethod( )
+        throws Exception
+    {
+        Method method = Root.class.getDeclaredMethod( "getPrivateAccessorIntValue3" );
+        MethodAccessEntryValue methodAccessValue = cache.get( method );
+        Assert.assertTrue( methodAccessValue.isNotPublic( ) );
+        Assert.assertFalse( methodAccessValue.isAccessible());
+    }
+
+    @Test
+    public void testGetNotAccessibleNonPublicMethod( )
+        throws Exception
+    {
+        Method method = Root.class.getDeclaredMethod( "getPrivateAccessorIntValue3" );
+        method.setAccessible( true );
+        MethodAccessEntryValue methodAccessValue = cache.get( method );
+        Assert.assertTrue( methodAccessValue.isNotPublic( ) );
+        Assert.assertTrue( methodAccessValue.isAccessible());
+    }
+
+    @Test
+    public void testGetPublicMethod( )
+        throws NoSuchMethodException, CacheException
+    {
+        Method method = Root.class.getDeclaredMethod( "getArray" );
+        MethodAccessEntryValue methodAccessValue = cache.get( method );
+        Assert.assertFalse( methodAccessValue.isNotPublic( ) );
+        Assert.assertTrue( methodAccessValue.isAccessible());
+    }
+
+}