improved classloading behaviour in JBoss 7 modules

git-svn-id: https://svn.apache.org/repos/asf/click/trunk/click@1384773 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/org/apache/click/service/MVELPropertyService.java b/framework/src/org/apache/click/service/MVELPropertyService.java
index 6ecd318..4d28473 100644
--- a/framework/src/org/apache/click/service/MVELPropertyService.java
+++ b/framework/src/org/apache/click/service/MVELPropertyService.java
@@ -26,6 +26,7 @@
 

 import javax.servlet.ServletContext;

 

+import org.apache.click.util.ClassLoaderCache;

 import org.apache.click.util.PropertyUtils;

 import org.mvel2.MVEL;

 

@@ -34,9 +35,9 @@
  */

 public class MVELPropertyService implements PropertyService {

 

-    /** Provides a synchronized cache of MVEL expressions. */

-    private static final Map<String, Serializable> MVEL_EXPRESSION_CACHE

-        = new ConcurrentHashMap<String, Serializable>();

+    // Expression cache with support for multiple classloader caching

+    private static final ClassLoaderCache<Map<String, Serializable>>

+        EXPRESSION_CL_CACHE = new ClassLoaderCache<Map<String, Serializable>>();

 

     // Public Methods --------------------------------------------------------

 

@@ -92,11 +93,11 @@
 

         String expression = target.getClass().getSimpleName() + "." + name + " = value";

 

-        Serializable compiledExpression = MVEL_EXPRESSION_CACHE.get(expression);

+        Serializable compiledExpression = getExpressionCache().get(expression);

 

         if (compiledExpression == null) {

             compiledExpression = MVEL.compileExpression(expression);

-            MVEL_EXPRESSION_CACHE.put(expression, compiledExpression);

+            getExpressionCache().put(expression, compiledExpression);

         }

 

         Map<String, Object> vars = new HashMap<String, Object>();

@@ -106,4 +107,16 @@
         MVEL.executeExpression(compiledExpression, vars);

     }

 

+    // Private Methods --------------------------------------------------------

+

+    private static Map<String, Serializable> getExpressionCache() {

+        Map<String, Serializable> expressionCache = EXPRESSION_CL_CACHE.get();

+        if (expressionCache == null) {

+            expressionCache = new ConcurrentHashMap<String, Serializable>();

+            EXPRESSION_CL_CACHE.put(expressionCache);

+        }

+

+        return expressionCache;

+    }

+

 }

diff --git a/framework/src/org/apache/click/service/OGNLPropertyService.java b/framework/src/org/apache/click/service/OGNLPropertyService.java
index a446728..445b091 100644
--- a/framework/src/org/apache/click/service/OGNLPropertyService.java
+++ b/framework/src/org/apache/click/service/OGNLPropertyService.java
@@ -24,9 +24,13 @@
 

 import javax.servlet.ServletContext;

 

+import ognl.DefaultMemberAccess;

+import ognl.MemberAccess;

 import ognl.Ognl;

 import ognl.OgnlException;

+import ognl.TypeConverter;

 

+import org.apache.click.util.ClassLoaderCache;

 import org.apache.click.util.PropertyUtils;

 

 /**

@@ -34,9 +38,17 @@
  */

 public class OGNLPropertyService implements PropertyService {

 

-    /** Provides a synchronized cache of OGNL expressions. */

-    private static final Map<String, Object> OGNL_EXPRESSION_CACHE

-        = new ConcurrentHashMap<String, Object>();

+    // OGNL Expression cache with support for multiple classloader caching

+    private static final ClassLoaderCache<Map<String, Object>>

+        EXPRESSION_CL_CACHE = new ClassLoaderCache<Map<String, Object>>();

+

+    // Protected Variables ---------------------------------------------------

+

+    /** The OGNL object member accessor. */

+    protected MemberAccess memberAccess;

+

+    /** The OGNL data marshalling type converter. */

+    protected TypeConverter typeConverter;

 

     //Public Methods  --------------------------------------------------------

 

@@ -116,16 +128,17 @@
      * @param value the property value to set

      */

     public void setValue(Object target, String name, Object value) {

-        OGNLTypeConverter typeConverter = new OGNLTypeConverter();

 

-        Map<?, ?> ognlContext =

-            Ognl.createDefaultContext(target, null, typeConverter);

+        Map<?, ?> ognlContext = Ognl.createDefaultContext(target,

+                                                          null,

+                                                          getTypeConverter(),

+                                                          getMemberAccess());

 

         try {

-            Object expression = OGNL_EXPRESSION_CACHE.get(name);

+            Object expression = getExpressionCache().get(name);

             if (expression == null) {

                 expression = Ognl.parseExpression(name);

-                OGNL_EXPRESSION_CACHE.put(name, expression);

+                getExpressionCache().put(name, expression);

             }

 

             Ognl.setValue(expression, ognlContext, target, value);

@@ -136,5 +149,45 @@
         }

     }

 

+    // Protected Methods ------------------------------------------------------

+

+    /**

+     * Return the OGNL object MemberAccess instance.

+     *

+     * @return the OGNL object MemberAccess instance

+     */

+    protected MemberAccess getMemberAccess() {

+        if (memberAccess == null) {

+            memberAccess = new DefaultMemberAccess(true);

+        }

+

+        return memberAccess;

+    }

+

+    /**

+     * Return the OGNL data marshalling TypeConverter instance.

+     *

+     * @return the OGNL data marshalling TypeConverter instance

+     */

+    protected TypeConverter getTypeConverter() {

+        if (typeConverter == null) {

+            typeConverter = new OGNLTypeConverter();

+        }

+

+        return typeConverter;

+    }

+

+    // Private Methods --------------------------------------------------------

+

+    private static Map<String, Object> getExpressionCache() {

+        Map<String, Object> expressionCache = EXPRESSION_CL_CACHE.get();

+        if (expressionCache == null) {

+            expressionCache = new ConcurrentHashMap<String, Object>();

+            EXPRESSION_CL_CACHE.put(expressionCache);

+        }

+

+        return expressionCache;

+    }

+

 }

 

diff --git a/framework/src/org/apache/click/util/PropertyUtils.java b/framework/src/org/apache/click/util/PropertyUtils.java
index 6382e23..0f5d9f2 100644
--- a/framework/src/org/apache/click/util/PropertyUtils.java
+++ b/framework/src/org/apache/click/util/PropertyUtils.java
@@ -19,8 +19,6 @@
 package org.apache.click.util;

 

 import java.lang.reflect.Method;

-import java.util.Collections;

-import java.util.HashMap;

 import java.util.Map;

 import java.util.concurrent.ConcurrentHashMap;

 

@@ -38,16 +36,12 @@
  */

 public class PropertyUtils {

 

-    /** Provides a synchronized cache of get value reflection methods. */

-    private static final Map<String, Object> GET_METHOD_CACHE

-        = new ConcurrentHashMap<String, Object>();

-

     /**

      * Provides a synchronized cache of get value reflection methods, with

      * support for multiple class loaders.

      */

-    private static final Map<ClassLoader, Map<CacheKey, Method>> GET_METHOD_CLASSLOADER_CACHE

-        = Collections.synchronizedMap(new HashMap<ClassLoader, Map<CacheKey, Method>>());

+    private static final ClassLoaderCache<Map<CacheKey, Method>> GET_METHOD_CLASSLOADER_CACHE

+        = new ClassLoaderCache<Map<CacheKey, Method>>();

 

     // -------------------------------------------------------- Public Methods

 

@@ -219,12 +213,10 @@
     }

 

     private static Map<CacheKey, Method> getGetMethodCache() {

-        ClassLoader cl = Thread.currentThread().getContextClassLoader();

-

-        Map<CacheKey, Method> getMethodCache = GET_METHOD_CLASSLOADER_CACHE.get(cl);

+        Map<CacheKey, Method> getMethodCache = GET_METHOD_CLASSLOADER_CACHE.get();

         if (getMethodCache == null) {

             getMethodCache = new ConcurrentHashMap<CacheKey, Method>();

-            GET_METHOD_CLASSLOADER_CACHE.put(cl, getMethodCache);

+            GET_METHOD_CLASSLOADER_CACHE.put(getMethodCache);

         }

 

         return getMethodCache;