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;