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/16 09:30:57 UTC
svn commit: r1184772 - in
/commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl:
OgnlRuntime.java internal/ConcurrentClassCache.java
internal/ConcurrentHashMapCache.java
Author: mcucchiara
Date: Sun Oct 16 07:30:57 2011
New Revision: 1184772
URL: http://svn.apache.org/viewvc?rev=1184772&view=rev
Log:
Added abstraction layer
Added:
commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/ConcurrentHashMapCache.java
Modified:
commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/OgnlRuntime.java
commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/ConcurrentClassCache.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=1184772&r1=1184771&r2=1184772&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 Sun Oct 16 07:30:57 2011
@@ -23,12 +23,17 @@ 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.CacheEntryFactory;
-import org.apache.commons.ognl.internal.CacheException;
import org.apache.commons.ognl.internal.ClassCache;
-import org.apache.commons.ognl.internal.ClassCacheEntryFactory;
import org.apache.commons.ognl.internal.ClassCacheHandler;
import org.apache.commons.ognl.internal.ConcurrentClassCache;
+import org.apache.commons.ognl.internal.ConcurrentHashMapCache;
+import org.apache.commons.ognl.internal.entry.FiedlCacheCacheEntryFactory;
+import org.apache.commons.ognl.internal.entry.ConstructorCacheEntryFactory;
+import org.apache.commons.ognl.internal.entry.DeclaredMethodCacheEntry;
+import org.apache.commons.ognl.internal.entry.DeclaredMethodCacheEntryFactory;
+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;
@@ -156,20 +161,19 @@ public class OgnlRuntime
static final ClassCache<NullHandler> _nullHandlers = new ConcurrentClassCache<NullHandler>( );
static final ClassCache<Map<String, PropertyDescriptor>> _propertyDescriptorCache =
- new ConcurrentClassCache<Map<String, PropertyDescriptor>>( );
+ new ConcurrentClassCache<Map<String, PropertyDescriptor>>(new PropertyDescriptorCacheEntryFactory());
- static final ClassCache<List<Constructor<?>>> _constructorCache = new ConcurrentClassCache<List<Constructor<?>>>( );
+ static final ClassCache<List<Constructor<?>>> _constructorCache = new ConcurrentClassCache<List<Constructor<?>>>(new ConstructorCacheEntryFactory() );
- static final ClassCache<Map<String, List<Method>>> _staticMethodCache = new ConcurrentClassCache<Map<String, List<Method>>>( );
+ static final ConcurrentHashMapCache<DeclaredMethodCacheEntry, Map<String, List<Method>>> _methodCache =
+ new ConcurrentHashMapCache<DeclaredMethodCacheEntry, Map<String, List<Method>>>(
+ new DeclaredMethodCacheEntryFactory( ) );
- static final ClassCache<Map<String, List<Method>>> _instanceMethodCache = new ConcurrentClassCache<Map<String, List<Method>>>( );
+ static final ConcurrentHashMapCache<PermissionCacheEntry, Permission> _invokePermissionCache =
+ new ConcurrentHashMapCache<PermissionCacheEntry, Permission>( new PermissionCacheEntryFactory( ) );
- static final ClassCache<Map<String, Permission>> _invokePermissionCache = new ConcurrentClassCache<Map<String, Permission>>( );
-
- static final ClassCache<Map<String, Field>> _fieldCache = new ConcurrentClassCache<Map<String, Field>>( );
-
- static final ClassCache[] _declaredMethods =
- new ClassCache[]{ new ConcurrentClassCache( ), new ConcurrentClassCache( ) };
+ static final ClassCache<Map<String, Field>> _fieldCache =
+ new ConcurrentClassCache<Map<String, Field>>( new FiedlCacheCacheEntryFactory( ) );
static final Map<String, Class<?>> _primitiveTypes = new HashMap<String, Class<?>>( 101 );
@@ -413,12 +417,11 @@ public class OgnlRuntime
_ctorParameterTypesCache.clear( );
_propertyDescriptorCache.clear( );
_constructorCache.clear( );
- _staticMethodCache.clear( );
- _instanceMethodCache.clear( );
+ _methodCache.clear( );
_invokePermissionCache.clear( );
_fieldCache.clear( );
- _declaredMethods[0].clear( );
- _declaredMethods[1].clear( );
+// _setterMethods.clear( );
+// _getterMethods.clear( );
_methodAccessCache.clear( );
}
@@ -819,31 +822,7 @@ public class OgnlRuntime
public static Permission getPermission( final Method method )
throws OgnlException
{
- final Class<?> mc = method.getDeclaringClass( );
-
- CacheEntryFactory<Class<?>, Map<String, Permission>> cacheEntryFactory =
- new CacheEntryFactory<Class<?>, Map<String, Permission>>( )
- {
- public Map<String, Permission> create( Class<?> key )
- throws CacheException
- {
- Map<String, Permission> permissions = _invokePermissionCache.get( mc );
- if ( permissions == null )
- {
- _invokePermissionCache.put( mc, permissions = new HashMap<String, Permission>( 101 ) );
- }
- Permission result = permissions.get( method.getName( ) );
- if ( result == null )
- {
- result = new OgnlInvokePermission( "invoke." + mc.getName( ) + "." + method.getName( ) );
- permissions.put( method.getName( ), result );
- }
- return permissions;
- }
- };
- Map<String, Permission> permissions = _invokePermissionCache.get( mc, cacheEntryFactory );
-
- return permissions.get( method.getName( ) );
+ return _invokePermissionCache.get( new PermissionCacheEntry( method ) );
}
public static Object invokeMethod( Object target, Method method, Object[] argsArray )
@@ -1673,60 +1652,29 @@ public class OgnlRuntime
public static List<Constructor<?>> getConstructors( final Class<?> targetClass )
throws OgnlException
{
- return _constructorCache.get( targetClass, new ClassCacheEntryFactory<List<Constructor<?>>>( )
- {
- public List<Constructor<?>> create( Class<?> key )
- throws CacheException
- {
- return Arrays.asList( targetClass.getConstructors( ) );
- }
- } );
+ return _constructorCache.get( targetClass );
}
- public static Map<String, List<Method>> getMethods( final Class<?> targetClass, final boolean staticMethods )
+ /**
+ * @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
{
- CacheEntryFactory<Class<?>, Map<String, List<Method>>> entryFactory=new CacheEntryFactory<Class<?>, Map<String, List<Method>>>( )
+ DeclaredMethodCacheEntry.MethodType type;
+ if ( staticMethods )
{
- public Map<String, List<Method>> create( Class<?> key )
- throws CacheException
- {
- Map<String, List<Method>> result = new HashMap<String, List<Method>>( 23 );
-
- Class<?> c = key;
- while ( c != null )
- {
- 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 );
- }
- }
- c = c.getSuperclass( );
- }
- return result;
- }
- };
+ type = DeclaredMethodCacheEntry.MethodType.STATIC;
+ }
+ else
+ {
+ type = DeclaredMethodCacheEntry.MethodType.NON_STATIC;
- ClassCache<Map<String, List<Method>>> cache = ( staticMethods ? _staticMethodCache : _instanceMethodCache );
- return cache.get( targetClass, entryFactory );
+ }
+ return _methodCache.get( new DeclaredMethodCacheEntry( targetClass, type) );
}
public static List<Method> getMethods( Class<?> targetClass, String name, boolean staticMethods )
@@ -1738,21 +1686,7 @@ public class OgnlRuntime
public static Map<String, Field> getFields( Class<?> targetClass )
throws OgnlException
{
- CacheEntryFactory<Class<?>, Map<String, Field>> entryFactory=new CacheEntryFactory<Class<?>, Map<String, Field>>( )
- {
- public Map<String, Field> create( Class<?> key )
- throws CacheException
- {
- Field[] declaredFields = key.getDeclaredFields( );
- HashMap<String, Field> result = new HashMap<String, Field>( declaredFields.length);
- for ( Field field : declaredFields )
- {
- result.put( field.getName( ), field );
- }
- return result ;
- }
- };
- return _fieldCache.get( targetClass, entryFactory );
+ return _fieldCache.get( targetClass );
}
public static Field getField( Class<?> inClass, String name )
@@ -1763,7 +1697,7 @@ public class OgnlRuntime
if ( o == null )
{
// if o is null, it should search along the superclasses
- Class<?> sc = inClass.getSuperclass();
+ Class<?> sc = inClass.getSuperclass( );
while ( ( sc != null ) )
{
o = getFields( sc ).get( name );
@@ -1941,68 +1875,39 @@ public class OgnlRuntime
throw new OgnlException( "Could not get static field " + fieldName + " from class " + className, reason );
}
- public static List<Method> getDeclaredMethods( Class<?> targetClass, String propertyName, boolean findSets )
+ /**
+ *
+ * @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( final Class<?> targetClass, final String propertyName,
+ final 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)
{
- Map<String, List<Method>> propertyCache = (Map<String, List<Method>>) cache.get( targetClass );
-
- if ( ( propertyCache == null ) || ( ( result = propertyCache.get( propertyName ) ) == 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 );
- }
- return result;
+ find.add( SET_PREFIX + baseName);
+ } else
+ {
+ find.add( IS_PREFIX + baseName );
+ find.add(GET_PREFIX + baseName );
+
}
+ for ( String s : find )
+ {
+ List<Method> methodList = _methodCache.get( new DeclaredMethodCacheEntry( targetClass ) ).get( s );
+ if(methodList!=null)
+ result.addAll( methodList );
+ }
+
+ return result;
+
}
/**
@@ -2011,7 +1916,8 @@ public class OgnlRuntime
* @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 needs to move in a util class
+ public static boolean isMethodCallable( Method m )
{
return !( ( isJdk15( ) && m.isSynthetic( ) ) || Modifier.isVolatile( m.getModifiers( ) ) );
@@ -2146,7 +2052,8 @@ public class OgnlRuntime
return result;
}
- static void findObjectIndexedPropertyDescriptors( Class<?> targetClass, Map<String, PropertyDescriptor> intoMap )
+ public static void findObjectIndexedPropertyDescriptors( Class<?> targetClass,
+ Map<String, PropertyDescriptor> intoMap )
throws OgnlException
{
Map<String, List<Method>> allMethods = getMethods( targetClass, false );
@@ -2243,50 +2150,7 @@ public class OgnlRuntime
public static Map<String, PropertyDescriptor> getPropertyDescriptors( final Class<?> targetClass )
throws IntrospectionException, OgnlException
{
- return _propertyDescriptorCache.get( targetClass, new ClassCacheEntryFactory<Map<String, PropertyDescriptor>>( )
- {
- public Map<String, PropertyDescriptor> create( Class<?> key )
- throws CacheException
- {
- Map<String, PropertyDescriptor> result = new HashMap<String, PropertyDescriptor>( 101 );
- PropertyDescriptor[] pda;
- try
- {
- pda = Introspector.getBeanInfo( targetClass ).getPropertyDescriptors( );
-
- 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 );
- }
- catch ( IntrospectionException e )
- {
- throw new CacheException( e );
- }
- catch ( OgnlException e )
- {
- throw new CacheException( e );
- }
- return result;
- }
- } );
+ return _propertyDescriptorCache.get( targetClass );
}
/**
@@ -2304,25 +2168,6 @@ public class OgnlRuntime
return getPropertyDescriptors( targetClass ).get( propertyName );
}
- static Method findClosestMatchingMethod( Class<?> targetClass, Method m, String propertyName, Class<?> propertyType,
- boolean isReadMethod )
- throws OgnlException
- {
- 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 m;
- }
-
public static PropertyDescriptor[] getPropertyDescriptorsArray( Class<?> targetClass )
throws IntrospectionException, OgnlException
{
@@ -2596,12 +2441,11 @@ public class OgnlRuntime
_propertyDescriptorCache.setClassInspector( _cacheInspector );
_constructorCache.setClassInspector( _cacheInspector );
- _staticMethodCache.setClassInspector( _cacheInspector );
- _instanceMethodCache.setClassInspector( _cacheInspector );
- _invokePermissionCache.setClassInspector( _cacheInspector );
+// _methodCache.setClassInspector( _cacheInspector );
+// _invokePermissionCache.setClassInspector( _cacheInspector );
_fieldCache.setClassInspector( _cacheInspector );
- _declaredMethods[0].setClassInspector( _cacheInspector );
- _declaredMethods[1].setClassInspector( _cacheInspector );
+// _setterMethods.setClassInspector( _cacheInspector );
+// _getterMethods.setClassInspector( _cacheInspector );
}
public static Method getMethod( OgnlContext context, Class<?> target, String name, Node[] children,
Modified: commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/ConcurrentClassCache.java
URL: http://svn.apache.org/viewvc/commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/ConcurrentClassCache.java?rev=1184772&r1=1184771&r2=1184772&view=diff
==============================================================================
--- commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/ConcurrentClassCache.java (original)
+++ commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/ConcurrentClassCache.java Sun Oct 16 07:30:57 2011
@@ -22,64 +22,35 @@
package org.apache.commons.ognl.internal;
import org.apache.commons.ognl.ClassCacheInspector;
+import org.apache.commons.ognl.internal.entry.CacheEntryFactory;
-import java.util.concurrent.ConcurrentHashMap;
-
-public class ConcurrentClassCache<V>
- implements ClassCache<V>
+public class ConcurrentClassCache<T>
+ extends ConcurrentHashMapCache<Class<?>,T>
+ implements ClassCache<T>
{
private ClassCacheInspector inspector;
- private ConcurrentHashMap<Class<?>, V> cache = new ConcurrentHashMap<Class<?>, V>();
-
- public ConcurrentClassCache()
- {
- }
-
-
- public void setClassInspector( ClassCacheInspector inspector )
- {
- this.inspector = inspector;
- }
-
- public void clear()
+ public ConcurrentClassCache( )
{
- cache.clear();
}
- public int getSize()
+ public ConcurrentClassCache( CacheEntryFactory<Class<?>,T> entryFactory )
{
- return cache.size();
+ super( entryFactory );
}
- public V get( Class<?> key )
- throws CacheException
- {
- return get( key, null );
- }
-
- public V get( Class<?> key, CacheEntryFactory<Class<?>, V> cacheEntryFactory )
- throws CacheException
+ public void setClassInspector( ClassCacheInspector inspector )
{
- V v = cache.get( key );
- if ( v == null && cacheEntryFactory != null )
- {
- return put( key, cacheEntryFactory.create( key ) );
- }
- return v;
+ this.inspector = inspector;
}
- public V put( Class<?> key, V value )
+ @Override
+ public T put( Class<?> key, T value )
{
if ( inspector != null && !inspector.shouldCache( key ) )
{
return value;
}
- V collision = cache.putIfAbsent( key, value );
- if ( collision != null )
- {
- return collision;
- }
- return value;
+ return super.put( key, value );
}
}
Added: commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/ConcurrentHashMapCache.java
URL: http://svn.apache.org/viewvc/commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/ConcurrentHashMapCache.java?rev=1184772&view=auto
==============================================================================
--- commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/ConcurrentHashMapCache.java (added)
+++ commons/proper/ognl/branches/new-cache-approach/src/main/java/org/apache/commons/ognl/internal/ConcurrentHashMapCache.java Sun Oct 16 07:30:57 2011
@@ -0,0 +1,98 @@
+/*
+ * $Id: $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.commons.ognl.internal;
+
+import org.apache.commons.ognl.internal.entry.CacheEntryFactory;
+import org.apache.commons.ognl.internal.entry.MatchingCacheEntryFactory;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+public class ConcurrentHashMapCache<K, V>
+ implements Cache<K, V>
+{
+ private ConcurrentHashMap<K, V> cache = new ConcurrentHashMap<K, V>( );
+
+ private CacheEntryFactory<K, V> cacheEntryFactory;
+
+ public ConcurrentHashMapCache( )
+ {
+ }
+
+ public ConcurrentHashMapCache( CacheEntryFactory<K, V> cacheEntryFactory )
+ {
+ this.cacheEntryFactory = cacheEntryFactory;
+ }
+
+ public void clear( )
+ {
+ cache.clear( );
+ }
+
+ public int getSize( )
+ {
+ return cache.size( );
+ }
+
+ public V get( K key)
+ throws CacheException
+ {
+ V v = cache.get( key );
+ if ( shouldCreate( cacheEntryFactory, v ) )
+ {
+ return put( key, cacheEntryFactory.create( key ) );
+ }
+ return v;
+ }
+
+ protected boolean shouldCreate( CacheEntryFactory<K, V> cacheEntryFactory, V v )
+ throws CacheException
+ {
+ if ( cacheEntryFactory != null )
+ {
+ if ( v == null )
+ {
+ return true;
+ }
+
+ if ( cacheEntryFactory instanceof MatchingCacheEntryFactory)
+ {
+ return !( (MatchingCacheEntryFactory<K,V>) cacheEntryFactory ).match( v );
+ }
+ }
+ return false;
+ }
+
+ public V put( K key, V value )
+ {
+ V collision = cache.putIfAbsent( key, value );
+ if ( collision != null )
+ {
+ return collision;
+ }
+ return value;
+ }
+
+ public boolean contains( K key)
+ {
+ return this.cache.contains( key );
+ }
+}