]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.osgi.boot/src/org/argeo/osgi/boot/internal/springutil/CollectionUtils.java
Main commands in OSGi boot
[lgpl/argeo-commons.git] / org.argeo.osgi.boot / src / org / argeo / osgi / boot / internal / springutil / CollectionUtils.java
1 /*
2 * Copyright 2002-2008 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.argeo.osgi.boot.internal.springutil;
18
19 import java.util.Arrays;
20 import java.util.Collection;
21 import java.util.Enumeration;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Properties;
26
27 /**
28 * Miscellaneous collection utility methods.
29 * Mainly for internal use within the framework.
30 *
31 * @author Juergen Hoeller
32 * @author Rob Harrop
33 * @since 1.1.3
34 */
35 @SuppressWarnings({ "rawtypes", "unchecked" })
36 public abstract class CollectionUtils {
37
38 /**
39 * Return <code>true</code> if the supplied Collection is <code>null</code>
40 * or empty. Otherwise, return <code>false</code>.
41 * @param collection the Collection to check
42 * @return whether the given Collection is empty
43 */
44 public static boolean isEmpty(Collection collection) {
45 return (collection == null || collection.isEmpty());
46 }
47
48 /**
49 * Return <code>true</code> if the supplied Map is <code>null</code>
50 * or empty. Otherwise, return <code>false</code>.
51 * @param map the Map to check
52 * @return whether the given Map is empty
53 */
54 public static boolean isEmpty(Map map) {
55 return (map == null || map.isEmpty());
56 }
57
58 /**
59 * Convert the supplied array into a List. A primitive array gets
60 * converted into a List of the appropriate wrapper type.
61 * <p>A <code>null</code> source value will be converted to an
62 * empty List.
63 * @param source the (potentially primitive) array
64 * @return the converted List result
65 * @see ObjectUtils#toObjectArray(Object)
66 */
67 public static List arrayToList(Object source) {
68 return Arrays.asList(ObjectUtils.toObjectArray(source));
69 }
70
71 /**
72 * Merge the given array into the given Collection.
73 * @param array the array to merge (may be <code>null</code>)
74 * @param collection the target Collection to merge the array into
75 */
76 public static void mergeArrayIntoCollection(Object array, Collection collection) {
77 if (collection == null) {
78 throw new IllegalArgumentException("Collection must not be null");
79 }
80 Object[] arr = ObjectUtils.toObjectArray(array);
81 for (int i = 0; i < arr.length; i++) {
82 collection.add(arr[i]);
83 }
84 }
85
86 /**
87 * Merge the given Properties instance into the given Map,
88 * copying all properties (key-value pairs) over.
89 * <p>Uses <code>Properties.propertyNames()</code> to even catch
90 * default properties linked into the original Properties instance.
91 * @param props the Properties instance to merge (may be <code>null</code>)
92 * @param map the target Map to merge the properties into
93 */
94 public static void mergePropertiesIntoMap(Properties props, Map map) {
95 if (map == null) {
96 throw new IllegalArgumentException("Map must not be null");
97 }
98 if (props != null) {
99 for (Enumeration en = props.propertyNames(); en.hasMoreElements();) {
100 String key = (String) en.nextElement();
101 map.put(key, props.getProperty(key));
102 }
103 }
104 }
105
106
107 /**
108 * Check whether the given Iterator contains the given element.
109 * @param iterator the Iterator to check
110 * @param element the element to look for
111 * @return <code>true</code> if found, <code>false</code> else
112 */
113 public static boolean contains(Iterator iterator, Object element) {
114 if (iterator != null) {
115 while (iterator.hasNext()) {
116 Object candidate = iterator.next();
117 if (ObjectUtils.nullSafeEquals(candidate, element)) {
118 return true;
119 }
120 }
121 }
122 return false;
123 }
124
125 /**
126 * Check whether the given Enumeration contains the given element.
127 * @param enumeration the Enumeration to check
128 * @param element the element to look for
129 * @return <code>true</code> if found, <code>false</code> else
130 */
131 public static boolean contains(Enumeration enumeration, Object element) {
132 if (enumeration != null) {
133 while (enumeration.hasMoreElements()) {
134 Object candidate = enumeration.nextElement();
135 if (ObjectUtils.nullSafeEquals(candidate, element)) {
136 return true;
137 }
138 }
139 }
140 return false;
141 }
142
143 /**
144 * Check whether the given Collection contains the given element instance.
145 * <p>Enforces the given instance to be present, rather than returning
146 * <code>true</code> for an equal element as well.
147 * @param collection the Collection to check
148 * @param element the element to look for
149 * @return <code>true</code> if found, <code>false</code> else
150 */
151 public static boolean containsInstance(Collection collection, Object element) {
152 if (collection != null) {
153 for (Iterator it = collection.iterator(); it.hasNext();) {
154 Object candidate = it.next();
155 if (candidate == element) {
156 return true;
157 }
158 }
159 }
160 return false;
161 }
162
163 /**
164 * Return <code>true</code> if any element in '<code>candidates</code>' is
165 * contained in '<code>source</code>'; otherwise returns <code>false</code>.
166 * @param source the source Collection
167 * @param candidates the candidates to search for
168 * @return whether any of the candidates has been found
169 */
170 public static boolean containsAny(Collection source, Collection candidates) {
171 if (isEmpty(source) || isEmpty(candidates)) {
172 return false;
173 }
174 for (Iterator it = candidates.iterator(); it.hasNext();) {
175 if (source.contains(it.next())) {
176 return true;
177 }
178 }
179 return false;
180 }
181
182 /**
183 * Return the first element in '<code>candidates</code>' that is contained in
184 * '<code>source</code>'. If no element in '<code>candidates</code>' is present in
185 * '<code>source</code>' returns <code>null</code>. Iteration order is
186 * {@link Collection} implementation specific.
187 * @param source the source Collection
188 * @param candidates the candidates to search for
189 * @return the first present object, or <code>null</code> if not found
190 */
191 public static Object findFirstMatch(Collection source, Collection candidates) {
192 if (isEmpty(source) || isEmpty(candidates)) {
193 return null;
194 }
195 for (Iterator it = candidates.iterator(); it.hasNext();) {
196 Object candidate = it.next();
197 if (source.contains(candidate)) {
198 return candidate;
199 }
200 }
201 return null;
202 }
203
204 /**
205 * Find a single value of the given type in the given Collection.
206 * @param collection the Collection to search
207 * @param type the type to look for
208 * @return a value of the given type found if there is a clear match,
209 * or <code>null</code> if none or more than one such value found
210 */
211 public static Object findValueOfType(Collection collection, Class type) {
212 if (isEmpty(collection)) {
213 return null;
214 }
215 Object value = null;
216 for (Iterator it = collection.iterator(); it.hasNext();) {
217 Object obj = it.next();
218 if (type == null || type.isInstance(obj)) {
219 if (value != null) {
220 // More than one value found... no clear single value.
221 return null;
222 }
223 value = obj;
224 }
225 }
226 return value;
227 }
228
229 /**
230 * Find a single value of one of the given types in the given Collection:
231 * searching the Collection for a value of the first type, then
232 * searching for a value of the second type, etc.
233 * @param collection the collection to search
234 * @param types the types to look for, in prioritized order
235 * @return a value of one of the given types found if there is a clear match,
236 * or <code>null</code> if none or more than one such value found
237 */
238 public static Object findValueOfType(Collection collection, Class[] types) {
239 if (isEmpty(collection) || ObjectUtils.isEmpty(types)) {
240 return null;
241 }
242 for (int i = 0; i < types.length; i++) {
243 Object value = findValueOfType(collection, types[i]);
244 if (value != null) {
245 return value;
246 }
247 }
248 return null;
249 }
250
251 /**
252 * Determine whether the given Collection only contains a single unique object.
253 * @param collection the Collection to check
254 * @return <code>true</code> if the collection contains a single reference or
255 * multiple references to the same instance, <code>false</code> else
256 */
257 public static boolean hasUniqueObject(Collection collection) {
258 if (isEmpty(collection)) {
259 return false;
260 }
261 boolean hasCandidate = false;
262 Object candidate = null;
263 for (Iterator it = collection.iterator(); it.hasNext();) {
264 Object elem = it.next();
265 if (!hasCandidate) {
266 hasCandidate = true;
267 candidate = elem;
268 }
269 else if (candidate != elem) {
270 return false;
271 }
272 }
273 return true;
274 }
275
276 }