Return-Path: Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: (qmail 30086 invoked from network); 15 Sep 2009 05:57:10 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 15 Sep 2009 05:57:10 -0000 Received: (qmail 33174 invoked by uid 500); 15 Sep 2009 05:57:09 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 33093 invoked by uid 500); 15 Sep 2009 05:57:08 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 33059 invoked by uid 99); 15 Sep 2009 05:57:08 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 15 Sep 2009 05:57:08 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 15 Sep 2009 05:57:04 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 0FFB323889CF; Tue, 15 Sep 2009 05:56:13 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r815081 - /commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/MultiValueMap.java Date: Tue, 15 Sep 2009 05:56:13 -0000 To: commits@commons.apache.org From: bayard@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090915055613.0FFB323889CF@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: bayard Date: Tue Sep 15 05:56:12 2009 New Revision: 815081 URL: http://svn.apache.org/viewvc?rev=815081&view=rev Log: Merging from -r468106:814127 of collections_jdk5_branch - namely where this code was generified; mostly in r738956. Also see the following revisions: ------------------------------------------------------------------------ r471189 | scolebourne | 2006-11-04 05:57:57 -0800 (Sat, 04 Nov 2006) | 1 line Remove getMap(), getOrderedMap() and getSortedMap() - use decorated() ------------------------------------------------------------------------ r468685 | scolebourne | 2006-10-28 05:30:27 -0700 (Sat, 28 Oct 2006) | 1 line COLLECTIONS-228 - MultiValueMap put and putAll do not return the correct values ------------------------------------------------------------------------ Modified: commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/MultiValueMap.java Modified: commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/MultiValueMap.java URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/MultiValueMap.java?rev=815081&r1=815080&r2=815081&view=diff ============================================================================== --- commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/MultiValueMap.java (original) +++ commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/MultiValueMap.java Tue Sep 15 05:56:12 2009 @@ -29,6 +29,7 @@ import java.util.Map; import java.util.Set; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.Factory; import org.apache.commons.collections.FunctorException; import org.apache.commons.collections.MultiMap; @@ -66,15 +67,15 @@ * @version $Revision$ $Date$ * @since Commons Collections 3.2 */ -public class MultiValueMap extends AbstractMapDecorator implements MultiMap, Serializable { +public class MultiValueMap extends AbstractMapDecorator implements MultiMap, Serializable { /** Serialization version */ private static final long serialVersionUID = -2214159910087182007L; /** The factory for creating value collections. */ - private final Factory collectionFactory; + private final Factory> collectionFactory; /** The cached values. */ - private transient Collection valuesView; + private transient Collection valuesView; /** * Creates a map which wraps the given map and @@ -82,8 +83,9 @@ * * @param map the map to wrap */ - public static MultiValueMap decorate(Map map) { - return new MultiValueMap(map, new ReflectionFactory(ArrayList.class)); + @SuppressWarnings("unchecked") + public static MultiValueMap decorate(Map> map) { + return MultiValueMap.decorate((Map) map, ArrayList.class); } /** @@ -93,8 +95,8 @@ * @param map the map to wrap * @param collectionClass the type of the collection class */ - public static MultiValueMap decorate(Map map, Class collectionClass) { - return new MultiValueMap(map, new ReflectionFactory(collectionClass)); + public static > MultiValueMap decorate(Map map, Class collectionClass) { + return new MultiValueMap(map, new ReflectionFactory(collectionClass)); } /** @@ -104,8 +106,8 @@ * @param map the map to decorate * @param collectionFactory the collection factory (must return a Collection object). */ - public static MultiValueMap decorate(Map map, Factory collectionFactory) { - return new MultiValueMap(map, collectionFactory); + public static > MultiValueMap decorate(Map map, Factory collectionFactory) { + return new MultiValueMap(map, collectionFactory); } //----------------------------------------------------------------------- @@ -113,6 +115,7 @@ * Creates a MultiValueMap based on a HashMap and * storing the multiple values in an ArrayList. */ + @SuppressWarnings("unchecked") public MultiValueMap() { this(new HashMap(), new ReflectionFactory(ArrayList.class)); } @@ -124,8 +127,9 @@ * @param map the map to decorate * @param collectionFactory the collection factory which must return a Collection instance */ - protected MultiValueMap(Map map, Factory collectionFactory) { - super(map); + @SuppressWarnings("unchecked") + protected > MultiValueMap(Map map, Factory collectionFactory) { + super((Map) map); if (collectionFactory == null) { throw new IllegalArgumentException("The factory must not be null"); } @@ -171,7 +175,7 @@ // Collection coll = (Collection) keyValuePair.getValue(); // coll.clear(); // } - getMap().clear(); + decorated().clear(); } /** @@ -187,8 +191,9 @@ * @param value the value to remove * @return the value removed (which was passed in), null if nothing removed */ - public Object remove(Object key, Object value) { - Collection valuesForKey = getCollection(key); + @SuppressWarnings("unchecked") + public V remove(Object key, Object value) { + Collection valuesForKey = getCollection(key); if (valuesForKey == null) { return null; } @@ -199,7 +204,7 @@ if (valuesForKey.isEmpty()) { remove(key); } - return value; + return (V) value; } /** @@ -210,17 +215,14 @@ * @param value the value to search for * @return true if the map contains the value */ + @SuppressWarnings("unchecked") public boolean containsValue(Object value) { - Set pairs = getMap().entrySet(); - if (pairs == null) { - return false; - } - Iterator pairsIterator = pairs.iterator(); - while (pairsIterator.hasNext()) { - Map.Entry keyValuePair = (Map.Entry) pairsIterator.next(); - Collection coll = (Collection) keyValuePair.getValue(); - if (coll.contains(value)) { - return true; + Set> pairs = decorated().entrySet(); + if (pairs != null) { + for (Map.Entry entry : pairs) { + if (((Collection) entry.getValue()).contains(value)) { + return true; + } } } return false; @@ -236,19 +238,20 @@ * @param value the value to add to the collection at the key * @return the value added if the map changed and null if the map did not change */ - public Object put(Object key, Object value) { + @SuppressWarnings("unchecked") + public Object put(K key, Object value) { boolean result = false; - Collection coll = getCollection(key); + Collection coll = getCollection(key); if (coll == null) { coll = createCollection(1); // might produce a non-empty collection - coll.add(value); + coll.add((V) value); if (coll.size() > 0) { // only add if non-zero size to maintain class state - getMap().put(key, coll); + decorated().put(key, coll); result = true; // map definitely changed } } else { - result = coll.add(value); + result = coll.add((V) value); } return (result ? value : null); } @@ -264,17 +267,15 @@ * * @param map the map to copy (either a normal or multi map) */ - public void putAll(Map map) { + @SuppressWarnings("unchecked") + public void putAll(Map map) { if (map instanceof MultiMap) { - for (Iterator it = map.entrySet().iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry) it.next(); - Collection coll = (Collection) entry.getValue(); - putAll(entry.getKey(), coll); + for (Map.Entry entry : ((MultiMap) map).entrySet()) { + putAll(entry.getKey(), (Collection) entry.getValue()); } } else { - for (Iterator it = map.entrySet().iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry) it.next(); - put(entry.getKey(), entry.getValue()); + for (Map.Entry entry : map.entrySet()) { + put(entry.getKey(), (V) entry.getValue()); } } } @@ -286,11 +287,10 @@ * * @return a collection view of the values contained in this map */ - public Collection values() { - if (valuesView == null) { - valuesView = new Values(); - } - return valuesView; + @SuppressWarnings("unchecked") + public Collection values() { + Collection vs = valuesView; + return (Collection) (vs != null ? vs : (valuesView = new Values())); } /** @@ -300,7 +300,7 @@ * @return true if the map contains the value */ public boolean containsValue(Object key, Object value) { - Collection coll = getCollection(key); + Collection coll = getCollection(key); if (coll == null) { return false; } @@ -314,8 +314,9 @@ * @param key the key to retrieve * @return the collection mapped to the key, null if no mapping */ - public Collection getCollection(Object key) { - return (Collection) getMap().get(key); + @SuppressWarnings("unchecked") + public Collection getCollection(Object key) { + return (Collection) decorated().get(key); } /** @@ -325,7 +326,7 @@ * @return the size of the collection at the key, zero if key not in map */ public int size(Object key) { - Collection coll = getCollection(key); + Collection coll = getCollection(key); if (coll == null) { return 0; } @@ -340,18 +341,18 @@ * @param values the values to add to the collection at the key, null ignored * @return true if this map changed */ - public boolean putAll(Object key, Collection values) { + public boolean putAll(K key, Collection values) { if (values == null || values.size() == 0) { return false; } boolean result = false; - Collection coll = getCollection(key); + Collection coll = getCollection(key); if (coll == null) { coll = createCollection(values.size()); // might produce a non-empty collection coll.addAll(values); if (coll.size() > 0) { // only add if non-zero size to maintain class state - getMap().put(key, coll); + decorated().put(key, coll); result = true; // map definitely changed } } else { @@ -366,12 +367,11 @@ * @param key the key to get an iterator for * @return the iterator of the collection at the key, empty iterator if key not in map */ - public Iterator iterator(Object key) { + public Iterator iterator(Object key) { if (!containsKey(key)) { - return EmptyIterator.INSTANCE; - } else { - return new ValuesIterator(key); + return EmptyIterator.getInstance(); } + return new ValuesIterator(key); } /** @@ -381,10 +381,8 @@ */ public int totalSize() { int total = 0; - Collection values = getMap().values(); - for (Iterator it = values.iterator(); it.hasNext();) { - Collection coll = (Collection) it.next(); - total += coll.size(); + for (Object v : decorated().values()) { + total += CollectionUtils.size(v); } return total; } @@ -399,18 +397,18 @@ * @param size the collection size that is about to be added * @return the new collection */ - protected Collection createCollection(int size) { - return (Collection) collectionFactory.create(); + protected Collection createCollection(int size) { + return collectionFactory.create(); } //----------------------------------------------------------------------- /** * Inner class that provides the values view. */ - private class Values extends AbstractCollection { - public Iterator iterator() { - final IteratorChain chain = new IteratorChain(); - for (Iterator it = keySet().iterator(); it.hasNext();) { + private class Values extends AbstractCollection { + public Iterator iterator() { + final IteratorChain chain = new IteratorChain(); + for (Iterator it = keySet().iterator(); it.hasNext();) { chain.addIterator(new ValuesIterator(it.next())); } return chain; @@ -428,10 +426,10 @@ /** * Inner class that provides the values iterator. */ - private class ValuesIterator implements Iterator { + private class ValuesIterator implements Iterator { private final Object key; - private final Collection values; - private final Iterator iterator; + private final Collection values; + private final Iterator iterator; public ValuesIterator(Object key) { this.key = key; @@ -450,7 +448,7 @@ return iterator.hasNext(); } - public Object next() { + public V next() { return iterator.next(); } } @@ -458,14 +456,18 @@ /** * Inner class that provides a simple reflection factory. */ - private static class ReflectionFactory implements Factory, Serializable { - private final Class clazz; + private static class ReflectionFactory> implements Factory, Serializable { + + /** Serialization version */ + private static final long serialVersionUID = 2986114157496788874L; + + private final Class clazz; - public ReflectionFactory(Class clazz) { + public ReflectionFactory(Class clazz) { this.clazz = clazz; } - public Object create() { + public T create() { try { return clazz.newInstance(); } catch (Exception ex) {