commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nia...@apache.org
Subject svn commit: r687089 - in /commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils: BeanUtils.java ConvertUtilsBean.java PropertyUtilsBean.java WeakFastHashMap.java locale/LocaleConvertUtilsBean.java
Date Tue, 19 Aug 2008 16:33:32 GMT
Author: niallp
Date: Tue Aug 19 09:33:30 2008
New Revision: 687089

URL: http://svn.apache.org/viewvc?rev=687089&view=rev
Log:
BEANUTILS-291 Fix the thread isolation problem on PropertyUtilsBean, ConvertUtilsBean and
LocaleConvertUtilsBean - thanks to Clebert Suconic for identifying this and the patch. I applied
a slightly modified version of Clebert's solution.

Added:
    commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/WeakFastHashMap.java
      - copied, changed from r686833, commons/proper/beanutils/trunk/src/java/org/apache/commons/collections/FastHashMap.java
Modified:
    commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/BeanUtils.java
    commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/ConvertUtilsBean.java
    commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/PropertyUtilsBean.java
    commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/locale/LocaleConvertUtilsBean.java

Modified: commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/BeanUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/BeanUtils.java?rev=687089&r1=687088&r2=687089&view=diff
==============================================================================
--- commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/BeanUtils.java (original)
+++ commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/BeanUtils.java Tue
Aug 19 09:33:30 2008
@@ -466,4 +466,36 @@
     public static boolean initCause(Throwable throwable, Throwable cause) {
         return BeanUtilsBean.getInstance().initCause(throwable, cause);
     }
+
+    /**
+     * Create a cache.
+     * @return a new cache
+     */
+    public static Map createCache() {
+        return new WeakFastHashMap();
+    }
+
+    /**
+     * Return whether a Map is fast
+     * @param map The map
+     * @return Whether it is fast or not.
+     */
+    public static boolean getCacheFast(Map map) {
+        if (map instanceof WeakFastHashMap) {
+            return ((WeakFastHashMap)map).getFast();
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Set whether fast on a Map
+     * @param map The map
+     * @param fast Whether it should be fast or not.
+     */
+    public static void setCacheFast(Map map, boolean fast) {
+        if (map instanceof WeakFastHashMap) {
+            ((WeakFastHashMap)map).setFast(fast);
+        }
+    }
 }

Modified: commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/ConvertUtilsBean.java
URL: http://svn.apache.org/viewvc/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/ConvertUtilsBean.java?rev=687089&r1=687088&r2=687089&view=diff
==============================================================================
--- commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/ConvertUtilsBean.java
(original)
+++ commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/ConvertUtilsBean.java
Tue Aug 19 09:33:30 2008
@@ -27,8 +27,6 @@
 import java.sql.Timestamp;
 import java.util.Calendar;
 import java.util.Collection;
-import java.util.Map;
-import java.util.WeakHashMap;
 
 import org.apache.commons.beanutils.converters.ArrayConverter;
 import org.apache.commons.beanutils.converters.BigDecimalConverter;
@@ -151,7 +149,7 @@
      * The set of {@link Converter}s that can be used to convert Strings
      * into objects of a specified Class, keyed by the destination Class.
      */
-    private Map converters = new WeakHashMap();
+    private WeakFastHashMap converters = new WeakFastHashMap();
 
     /**
      * The <code>Log</code> instance for this class.
@@ -162,7 +160,9 @@
 
     /** Construct a bean with standard converters registered */
     public ConvertUtilsBean() {
+        converters.setFast(false);   
         deregister();
+        converters.setFast(true);
     }
 
     // --------------------------------------------------------- Public Methods

Modified: commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/PropertyUtilsBean.java
URL: http://svn.apache.org/viewvc/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/PropertyUtilsBean.java?rev=687089&r1=687088&r2=687089&view=diff
==============================================================================
--- commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/PropertyUtilsBean.java
(original)
+++ commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/PropertyUtilsBean.java
Tue Aug 19 09:33:30 2008
@@ -30,7 +30,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.WeakHashMap;
 
 import org.apache.commons.beanutils.expression.DefaultResolver;
 import org.apache.commons.beanutils.expression.Resolver;
@@ -121,8 +120,8 @@
      * The cache of PropertyDescriptor arrays for beans we have already
      * introspected, keyed by the java.lang.Class of this object.
      */
-    private Map descriptorsCache = new WeakHashMap();
-    private Map mappedDescriptorsCache = new WeakHashMap();
+    private WeakFastHashMap descriptorsCache = null;
+    private WeakFastHashMap mappedDescriptorsCache = null;
     private static final Class[] EMPTY_CLASS_PARAMETERS = new Class[0];
     private static final Class[] LIST_CLASS_PARAMETER = new Class[] {java.util.List.class};
     
@@ -136,6 +135,10 @@
     
     /** Base constructor */
     public PropertyUtilsBean() {
+        descriptorsCache = new WeakFastHashMap();
+        descriptorsCache.setFast(true);
+        mappedDescriptorsCache = new WeakFastHashMap();
+        mappedDescriptorsCache.setFast(true);
     }
 
 

Copied: commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/WeakFastHashMap.java
(from r686833, commons/proper/beanutils/trunk/src/java/org/apache/commons/collections/FastHashMap.java)
URL: http://svn.apache.org/viewvc/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/WeakFastHashMap.java?p2=commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/WeakFastHashMap.java&p1=commons/proper/beanutils/trunk/src/java/org/apache/commons/collections/FastHashMap.java&r1=686833&r2=687089&rev=687089&view=diff
==============================================================================
--- commons/proper/beanutils/trunk/src/java/org/apache/commons/collections/FastHashMap.java
(original)
+++ commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/WeakFastHashMap.java
Tue Aug 19 09:33:30 2008
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.commons.collections;
+package org.apache.commons.beanutils;
 
 import java.util.Collection;
 import java.util.ConcurrentModificationException;
@@ -22,6 +22,7 @@
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
+import java.util.WeakHashMap;
 
 /**
  * <p>A customized implementation of <code>java.util.HashMap</code> designed
@@ -63,17 +64,17 @@
  * @author Craig R. McClanahan
  * @author Stephen Colebourne
  */
-public class FastHashMap extends HashMap {
+class WeakFastHashMap extends HashMap {
 
     /**
      * The underlying map we are managing.
      */
-    protected HashMap map = null;
+    private Map map = null;
 
     /**
      * Are we currently operating in "fast" mode?
      */
-    protected boolean fast = false;
+    private boolean fast = false;
 
     // Constructors
     // ----------------------------------------------------------------------
@@ -81,9 +82,9 @@
     /**
      * Construct an empty map.
      */
-    public FastHashMap() {
+    public WeakFastHashMap() {
         super();
-        this.map = new HashMap();
+        this.map = createMap();
     }
 
     /**
@@ -91,9 +92,9 @@
      *
      * @param capacity  the initial capacity of the empty map
      */
-    public FastHashMap(int capacity) {
+    public WeakFastHashMap(int capacity) {
         super();
-        this.map = new HashMap(capacity);
+        this.map = createMap(capacity);
     }
 
     /**
@@ -102,9 +103,9 @@
      * @param capacity  the initial capacity of the empty map
      * @param factor  the load factor of the new map
      */
-    public FastHashMap(int capacity, float factor) {
+    public WeakFastHashMap(int capacity, float factor) {
         super();
-        this.map = new HashMap(capacity, factor);
+        this.map = createMap(capacity, factor);
     }
 
     /**
@@ -112,9 +113,9 @@
      *
      * @param map  the map whose mappings are to be copied
      */
-    public FastHashMap(Map map) {
+    public WeakFastHashMap(Map map) {
         super();
-        this.map = new HashMap(map);
+        this.map = createMap(map);
     }
 
 
@@ -246,7 +247,7 @@
     public Object put(Object key, Object value) {
         if (fast) {
             synchronized (this) {
-                HashMap temp = (HashMap) map.clone();
+                Map temp = cloneMap(map);
                 Object result = temp.put(key, value);
                 map = temp;
                 return (result);
@@ -267,7 +268,7 @@
     public void putAll(Map in) {
         if (fast) {
             synchronized (this) {
-                HashMap temp = (HashMap) map.clone();
+                Map temp =  cloneMap(map);
                 temp.putAll(in);
                 map = temp;
             }
@@ -288,7 +289,7 @@
     public Object remove(Object key) {
         if (fast) {
             synchronized (this) {
-                HashMap temp = (HashMap) map.clone();
+                Map temp = cloneMap(map);
                 Object result = temp.remove(key);
                 map = temp;
                 return (result);
@@ -306,7 +307,7 @@
     public void clear() {
         if (fast) {
             synchronized (this) {
-                map = new HashMap();
+                map = createMap();
             }
         } else {
             synchronized (map) {
@@ -417,12 +418,12 @@
      * @return a clone of this map
      */
     public Object clone() {
-        FastHashMap results = null;
+        WeakFastHashMap results = null;
         if (fast) {
-            results = new FastHashMap(map);
+            results = new WeakFastHashMap(map);
         } else {
             synchronized (map) {
-                results = new FastHashMap(map);
+                results = new WeakFastHashMap(map);
             }
         }
         results.setFast(getFast());
@@ -457,6 +458,29 @@
         return new Values();
     }
 
+    // Abstractions on Map creations (for subclasses such as WeakFastHashMap)
+    // ----------------------------------------------------------------------
+
+    protected Map createMap() {
+        return new WeakHashMap();
+    }
+
+    protected Map createMap(int capacity) {
+        return new WeakHashMap(capacity);
+    }
+
+    protected Map createMap(int capacity, float factor) {
+        return new WeakHashMap(capacity, factor);
+    }
+    
+    protected Map createMap(Map map) {
+        return new WeakHashMap(map);
+    }
+    
+    protected Map cloneMap(Map map) {
+        return createMap(map);
+    }
+
     // Map view inner classes
     // ----------------------------------------------------------------------
 
@@ -474,8 +498,8 @@
 
         public void clear() {
             if (fast) {
-                synchronized (FastHashMap.this) {
-                    map = new HashMap();
+                synchronized (WeakFastHashMap.this) {
+                    map = createMap();
                 }
             } else {
                 synchronized (map) {
@@ -486,8 +510,8 @@
 
         public boolean remove(Object o) {
             if (fast) {
-                synchronized (FastHashMap.this) {
-                    HashMap temp = (HashMap) map.clone();
+                synchronized (WeakFastHashMap.this) {
+                    Map temp = cloneMap(map);
                     boolean r = get(temp).remove(o);
                     map = temp;
                     return r;
@@ -501,8 +525,8 @@
 
         public boolean removeAll(Collection o) {
             if (fast) {
-                synchronized (FastHashMap.this) {
-                    HashMap temp = (HashMap) map.clone();
+                synchronized (WeakFastHashMap.this) {
+                    Map temp = cloneMap(map);
                     boolean r = get(temp).removeAll(o);
                     map = temp;
                     return r;
@@ -516,8 +540,8 @@
 
         public boolean retainAll(Collection o) {
             if (fast) {
-                synchronized (FastHashMap.this) {
-                    HashMap temp = (HashMap) map.clone();
+                synchronized (WeakFastHashMap.this) {
+                    Map temp = cloneMap(map);
                     boolean r = get(temp).retainAll(o);
                     map = temp;
                     return r;
@@ -657,11 +681,11 @@
                     throw new IllegalStateException();
                 }
                 if (fast) {
-                    synchronized (FastHashMap.this) {
+                    synchronized (WeakFastHashMap.this) {
                         if (expected != map) {
                             throw new ConcurrentModificationException();
                         }
-                        FastHashMap.this.remove(lastReturned.getKey());
+                        WeakFastHashMap.this.remove(lastReturned.getKey());
                         lastReturned = null;
                         expected = map;
                     }

Modified: commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/locale/LocaleConvertUtilsBean.java
URL: http://svn.apache.org/viewvc/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/locale/LocaleConvertUtilsBean.java?rev=687089&r1=687088&r2=687089&view=diff
==============================================================================
--- commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/locale/LocaleConvertUtilsBean.java
(original)
+++ commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/locale/LocaleConvertUtilsBean.java
Tue Aug 19 09:33:30 2008
@@ -17,6 +17,7 @@
  
 package org.apache.commons.beanutils.locale;
 
+import org.apache.commons.beanutils.BeanUtils;
 import org.apache.commons.beanutils.locale.converters.BigDecimalLocaleConverter;
 import org.apache.commons.beanutils.locale.converters.BigIntegerLocaleConverter;
 import org.apache.commons.beanutils.locale.converters.ByteLocaleConverter;
@@ -38,11 +39,9 @@
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
-import java.util.WeakHashMap;
 
 /**
  * <p>Utility methods for converting locale-sensitive String scalar values to objects
of the
@@ -110,7 +109,7 @@
      *  key = locale
      *  value = FastHashMap of converters for the certain locale.
      */
-    private FastHashMap mapConverters = new FastHashMap();
+    private FastHashMap mapConverters = new DelegateFastHashMap(BeanUtils.createCache());
 
     // --------------------------------------------------------- Constructors
 
@@ -119,7 +118,9 @@
      *  and then registers default locale converters.
      */
     public LocaleConvertUtilsBean() {
+        mapConverters.setFast(false);
         deregister();
+        mapConverters.setFast(true);
     }
     
     // --------------------------------------------------------- Properties
@@ -459,7 +460,7 @@
      */
     protected FastHashMap create(Locale locale) {
 
-        FastHashMap converter = new WeakFastHashMap();
+        FastHashMap converter = new DelegateFastHashMap(BeanUtils.createCache());
         converter.setFast(false);
 
         converter.put(BigDecimal.class, new BigDecimalLocaleConverter(locale, applyLocalized));
@@ -506,58 +507,60 @@
      * releases (where FastHashMap is exposed in the API), but
      * use WeakHashMap to resolve memory leaks.
      */
-    private static class WeakFastHashMap extends FastHashMap {
+    private static class DelegateFastHashMap extends FastHashMap {
 
-        private Map fastMap = new WeakHashMap();
-        private Map slowMap = Collections.synchronizedMap(fastMap);
+        private final Map map;
 
-        private WeakFastHashMap() {
-            super(0);
+        private DelegateFastHashMap(Map map) {
+            this.map = map;
         }
         public void clear() {
-            getMap().clear();
+            map.clear();
         }
         public boolean containsKey(Object key) {
-            return getMap().containsKey(key);
+            return map.containsKey(key);
         }
         public boolean containsValue(Object value) {
-            return getMap().containsValue(value);
+            return map.containsValue(value);
         }
         public Set entrySet() {
-            return getMap().entrySet();
+            return map.entrySet();
         }
         public boolean equals(Object o) {
-            return getMap().equals(o);
+            return map.equals(o);
         }
         public Object get(Object key) {
-            return getMap().get(key);
+            return map.get(key);
         }
         public int hashCode() {
-            return getMap().hashCode();
+            return map.hashCode();
         }
         public boolean isEmpty() {
-            return getMap().isEmpty();
+            return map.isEmpty();
         }
         public Set keySet() {
-            return getMap().keySet();
+            return map.keySet();
         }
         public Object put(Object key, Object value) {
-            return getMap().put(key, value);
+            return map.put(key, value);
         }
         public void putAll(Map m) {
-            getMap().putAll(m);
+            map.putAll(m);
         }
         public Object remove(Object key) {
-            return getMap().remove(key);
+            return map.remove(key);
         }
         public int size() {
-            return getMap().size();
+            return map.size();
         }
         public Collection values() {
-            return getMap().values();
+            return map.values();
+        }
+        public boolean getFast() {
+            return BeanUtils.getCacheFast(map);
         }
-        private Map getMap() {
-            return (getFast() ? fastMap : slowMap);
+        public void setFast(boolean fast) {
+            BeanUtils.setCacheFast(map, fast);
         }
     }
 }



Mime
View raw message