View Javadoc

1   /*
2    * The contents of this file are subject to the terms 
3    * of the Common Development and Distribution License 
4    * (the "License").  You may not use this file except 
5    * in compliance with the License.
6    * 
7    * You can obtain a copy of the license at 
8    * http://www.sun.com/cddl/cddl.html. 
9    * See the License for the specific language governing 
10   * permissions and limitations under the License.
11   * 
12   * When distributing Covered Code, include this CDDL 
13   * HEADER in each file and include the License file at 
14   * license.txt.  If applicable, add the following below 
15   * this CDDL HEADER, with the fields enclosed by brackets 
16   * "[]" replaced with your own identifying information: 
17   * Portions Copyright [yyyy] [name of copyright owner]
18   * 
19   * Portions Copyright 2004 eBay, Inc.
20   */
21  package com.ebay.carad.os.vitalsigns.util;
22  
23  import java.util.ArrayList;
24  import java.util.HashMap;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.Map;
28  import java.util.Comparator;
29  import java.util.Collections;
30  import java.util.Set;
31  import java.util.HashSet;
32  import java.util.Collection;
33  import java.util.Arrays;
34  
35  import org.apache.commons.collections.Transformer;
36  import org.apache.commons.collections.MultiHashMap;
37  import org.apache.commons.collections.MultiMap;
38  import org.apache.commons.collections.comparators.ComparableComparator;
39  
40  /***
41   * Utility class for manipulating collections.
42   * 
43   * @author Jeremy Kraybill
44   * @author Jeremy Thomerson
45   * @version $Id$
46   */
47  public final class CollectionUtil {
48  
49  	private CollectionUtil() {
50  		// This block intentionally left blank.  Thank you PMD.
51  	}
52  
53  	/***
54  	 * Transformer to convert objects' string representations to integers.
55  	 */
56  	public static final Transformer TO_INTEGER_TRANSFORM = new Transformer() {
57  		public Object transform(Object obj) {
58  			return Integer.valueOf(obj.toString());
59  		}
60  	};
61  
62  	/***
63  	 * Returns a list contain N lists.
64  	 * 
65  	 * @param containedLists number of lists to contain.
66  	 * @return The list that contains <tt>containedLists</tt> lists.
67  	 */
68  	public static List listOfLists(int containedLists) {
69  		List retList = new ArrayList();
70  		for (int i = 0; i < containedLists; i++) {
71  			List set = new ArrayList();
72  			retList.add(set);
73  		}
74  		return retList;
75  	}
76  
77  	/***
78  	 * Converts the keys of a map to integers and creates a <b>new</b> map with
79  	 * these new keys and the original values.
80  	 * @param inMap
81  	 * @return <b>Non-null</b>
82  	 */
83  	public static Map convertKeysToIntegers(Map inMap) {
84  		Map outMap = new HashMap(inMap.size());
85  		Iterator iterator = inMap.entrySet().iterator();
86  		while (iterator.hasNext()) {
87  			Map.Entry entry = (Map.Entry) iterator.next();
88  			outMap.put(TO_INTEGER_TRANSFORM.transform(entry.getKey().toString()), entry.getValue());
89  		}
90  		return outMap;
91  	}
92  
93  	public static void sortMultiMapLists(MultiHashMap map, Comparator comparator) {
94  		Iterator iterator = map.entrySet().iterator();
95  		while (iterator.hasNext()) {
96  			Map.Entry entry = (Map.Entry) iterator.next();
97  			Collections.sort((List) entry.getValue(), comparator);
98  		}
99  	}
100 
101 	public static MultiMap unmodifiableMultiMap(MultiMap map) {
102 		return new UnmodifiableMultiMap(map);
103 	}
104 
105 	/***
106 	 * Concatinates the elements of the collection into a single string.  Uses each element's "toString" method, and adds a ", " between
107 	 * elements.  This method is mostly intended for use in debug or error messaging where a the collection of items is relevent
108 	 * information.
109 	 * @param coll <b>Non-null</b> collection of <b>Non-null</b> elements
110 	 */
111 	public static String toString(Collection coll) {
112 		StringBuffer buf = new StringBuffer();
113 		Iterator iterator = coll.iterator();
114 		while (iterator.hasNext()) {
115 			buf.append(iterator.next().toString());
116 			if (iterator.hasNext()) {
117 				buf.append(", ");
118 			}
119 		}
120 		return buf.toString();
121 	}
122 
123 	public static class SetComparator implements Comparator {
124 
125 		private final Comparator comparator;
126 
127 		public SetComparator(Comparator comparator) {
128 			this.comparator = comparator;
129 		}
130 
131 		public int compare(Object o1, Object o2) {
132 			if (o1 == o2) {
133 				return 0;
134 			}
135 
136 			Collection set1 = (Collection) o1;
137 			Collection set2 = (Collection) o2;
138 
139 			if (set1.size() != set2.size()) {
140 				return set1.size() - set2.size();
141 			}
142 
143 			Object[] array1 = set1.toArray();
144 			Object[] array2 = set2.toArray();
145 
146 			Arrays.sort(array1, comparator);
147 			Arrays.sort(array2, comparator);
148 
149 			for (int i = 0; i < array1.length; i++) {
150 				int delta = comparator.compare(array1[i], array2[i]);
151 				if (delta != 0) {
152 					return delta;
153 				}
154 			}
155 
156 			return 0;
157 		}
158 	}
159 
160 	public static int compareSets(Collection set1, Collection set2) {
161 		Comparator setComparator = new SetComparator(new ComparableComparator());
162 		return setComparator.compare(set1, set2);
163 	}
164 
165 	public static int compareSets(Collection set1, Collection set2, Comparator comparator) {
166 		Comparator setComparator = new SetComparator(comparator);
167 		return setComparator.compare(set1, set2);
168 	}
169 
170 	private static class UnmodifiableMultiMap implements MultiMap {
171 
172 		private final Map mMap;
173         private final Set allValues;
174 
175 		protected UnmodifiableMultiMap(MultiMap source) {
176 			Map tempMap = new HashMap();
177 			Set tempAllValues = new HashSet();
178 
179 			Iterator iterator = source.entrySet().iterator();
180 			while (iterator.hasNext()) {
181 				Entry entry = (Entry) iterator.next();
182 				Object key = entry.getKey();
183 				Collection values = (Collection) entry.getValue();
184 
185 				if (values != null) {
186 					values = Collections.unmodifiableCollection(values);
187 				}
188 
189 				tempMap.put(key, values);
190 				tempAllValues.addAll(values);
191 			}
192 
193 			mMap = Collections.unmodifiableMap(tempMap);
194 			allValues = Collections.unmodifiableSet(tempAllValues);
195 		}
196 
197 		public int size() { return mMap.size(); }
198 		public boolean isEmpty() { return mMap.isEmpty(); }
199 
200 		public boolean containsKey(Object key) { return mMap.containsKey(key); }
201 		public boolean containsValue(Object value) { return allValues.contains(value); }
202 
203 		public Set keySet() { return mMap.keySet(); }
204 		public Set entrySet() { return mMap.entrySet(); }
205 
206 		public Object get(Object key) { return (Collection) mMap.get(key); }
207 		public Collection values() { return allValues; }
208 
209 		public Object put(Object key, Object value) { throw new UnsupportedOperationException("UnmodifiableMultiMap can not be modified"); }
210 		public void putAll(Map map) { throw new UnsupportedOperationException("UnmodifiableMultiMap can not be modified"); }
211 
212 		public Object remove(Object key) { throw new UnsupportedOperationException("UnmodifiableMultiMap can not be modified"); }
213 		public Object remove(Object key, Object item) { throw new UnsupportedOperationException("UnmodifiableMultiMap can not be modified"); }
214 
215 		public void clear() { throw new UnsupportedOperationException("UnmodifiableMultiMap can not be modified"); }
216 	}
217 }