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());
+ }
+
+}