001 /*
002 * Copyright 2008-2016 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package griffon.util;
017
018 import javax.annotation.Nonnull;
019 import java.util.ArrayList;
020 import java.util.Arrays;
021 import java.util.Collection;
022 import java.util.Collections;
023 import java.util.Enumeration;
024 import java.util.HashMap;
025 import java.util.HashSet;
026 import java.util.Iterator;
027 import java.util.LinkedHashMap;
028 import java.util.LinkedHashSet;
029 import java.util.List;
030 import java.util.ListIterator;
031 import java.util.Map;
032 import java.util.Properties;
033 import java.util.Set;
034
035 import static java.util.Objects.requireNonNull;
036
037 /**
038 * <p>Utility class that simplifies creating collections in Java.</p>
039 * <p><strong>Creating Maps</strong><br/>
040 * <pre>
041 * Map<String, Object> m = map()
042 * .e("foo", foo)
043 * .e("bar", bar);
044 * </pre></p>
045 *
046 * <p><strong>Creating Lists</strong><br/>
047 * <pre>
048 * List<String> l = list()
049 * .e("foo")
050 * .e("bar");
051 * </pre></p>
052 *
053 * <p><strong>Creating Maps</strong><br/>
054 * <pre>
055 * Set<String> s = set()
056 * .e("foo")
057 * .e("bar");
058 * </pre></p>
059 *
060 * @author Andres Almiray
061 * @since 2.0.0
062 */
063 public final class CollectionUtils {
064 public static <T> List<T> reverse(List<T> input) {
065 List<T> output = new ArrayList<>(input);
066 Collections.reverse(output);
067 return output;
068 }
069
070 public static <T> List<T> reverse(Collection<T> input) {
071 List<T> output = new ArrayList<>(input);
072 Collections.reverse(output);
073 return output;
074 }
075
076 @SuppressWarnings({"rawtypes", "unchecked"})
077 public static <K, V> Map newMap(Object... keysAndValues) {
078 if (keysAndValues == null) {
079 return Collections.emptyMap();
080 }
081 if (keysAndValues.length % 2 == 1) {
082 throw new IllegalArgumentException("Must have an even number of keys and values");
083 }
084
085 Map<K, V> map = new HashMap<>();
086 for (int i = 0; i < keysAndValues.length; i += 2) {
087 map.put((K) keysAndValues[i], (V) keysAndValues[i + 1]);
088 }
089 return map;
090 }
091
092 @SafeVarargs
093 public static <T> Set<T> newSet(T... values) {
094 if (values == null) {
095 return Collections.emptySet();
096 }
097
098 return new HashSet<>(Arrays.asList(values));
099 }
100
101 @SafeVarargs
102 public static <T> List<T> newList(T... values) {
103 if (values == null) {
104 return Collections.emptyList();
105 }
106
107 return new ArrayList<>(Arrays.asList(values));
108 }
109
110 public static <K, V> MapBuilder<K, V> map() {
111 return map(new LinkedHashMap<K, V>());
112 }
113
114 public static <K, V> MapBuilder<K, V> map(Map<K, V> delegate) {
115 return new MapBuilder<>(delegate);
116 }
117
118 public static <E> ListBuilder<E> list() {
119 return list(new ArrayList<E>());
120 }
121
122 public static <E> ListBuilder<E> list(List<E> delegate) {
123 return new ListBuilder<>(delegate);
124 }
125
126 public static <E> SetBuilder<E> set() {
127 return set(new HashSet<E>());
128 }
129
130 public static <E> SetBuilder<E> set(Set<E> delegate) {
131 return new SetBuilder<>(delegate);
132 }
133
134 /**
135 * Returns an adapted Map as a Properties instance.
136 * <p>
137 * The Map is used live, which means changes made to it will affect the
138 * Properties instance directly.
139 *
140 * @param map the Map instance ot adapt as a Properties instance
141 * @return a new Properties instance backed by the supplied Map.
142 * @since 2.1.0
143 */
144 @Nonnull
145 public static Properties toProperties(@Nonnull Map<String, Object> map) {
146 requireNonNull(map, "Argument 'map' must not be null");
147 return new MapToPropertiesAdapter(map);
148 }
149
150 public static class MapBuilder<K, V> implements Map<K, V> {
151 private final Map<K, V> delegate;
152
153 public MapBuilder(Map<K, V> delegate) {
154 this.delegate = delegate;
155 }
156
157 public MapBuilder<K, V> e(K k, V v) {
158 delegate.put(k, v);
159 return this;
160 }
161
162 public int size() {
163 return delegate.size();
164 }
165
166 public boolean isEmpty() {
167 return delegate.isEmpty();
168 }
169
170 public boolean containsKey(Object o) {
171 return delegate.containsKey(o);
172 }
173
174 public boolean containsValue(Object o) {
175 return delegate.containsValue(o);
176 }
177
178 public V get(Object o) {
179 return delegate.get(o);
180 }
181
182 public V put(K k, V v) {
183 return delegate.put(k, v);
184 }
185
186 public V remove(Object o) {
187 return delegate.remove(o);
188 }
189
190 public void putAll(Map<? extends K, ? extends V> map) {
191 delegate.putAll(map);
192 }
193
194 public void clear() {
195 delegate.clear();
196 }
197
198 public Set<K> keySet() {
199 return delegate.keySet();
200 }
201
202 public Collection<V> values() {
203 return delegate.values();
204 }
205
206 public Set<Entry<K, V>> entrySet() {
207 return delegate.entrySet();
208 }
209
210 @Override
211 public boolean equals(Object o) {
212 return delegate.equals(o);
213 }
214
215 @Override
216 public int hashCode() {
217 return delegate.hashCode();
218 }
219
220 @Override
221 public String toString() {
222 return delegate.toString();
223 }
224 }
225
226 public static class ListBuilder<E> implements List<E> {
227 private final List<E> delegate;
228
229 public ListBuilder(List<E> delegate) {
230 this.delegate = delegate;
231 }
232
233 public ListBuilder<E> e(E e) {
234 delegate.add(e);
235 return this;
236 }
237
238 public int size() {
239 return delegate.size();
240 }
241
242 public boolean isEmpty() {
243 return delegate.isEmpty();
244 }
245
246 public boolean contains(Object o) {
247 return delegate.contains(o);
248 }
249
250 public Iterator<E> iterator() {
251 return delegate.iterator();
252 }
253
254 public Object[] toArray() {
255 return delegate.toArray();
256 }
257
258 public <T> T[] toArray(T[] ts) {
259 return delegate.toArray(ts);
260 }
261
262 public boolean add(E e) {
263 return delegate.add(e);
264 }
265
266 public boolean remove(Object o) {
267 return delegate.remove(o);
268 }
269
270 public boolean containsAll(Collection<?> objects) {
271 return delegate.containsAll(objects);
272 }
273
274 public boolean addAll(Collection<? extends E> es) {
275 return delegate.addAll(es);
276 }
277
278 public boolean addAll(int i, Collection<? extends E> es) {
279 return delegate.addAll(i, es);
280 }
281
282 public boolean removeAll(Collection<?> objects) {
283 return delegate.removeAll(objects);
284 }
285
286 public boolean retainAll(Collection<?> objects) {
287 return delegate.retainAll(objects);
288 }
289
290 public void clear() {
291 delegate.clear();
292 }
293
294 @Override
295 public boolean equals(Object o) {
296 return delegate.equals(o);
297 }
298
299 @Override
300 public int hashCode() {
301 return delegate.hashCode();
302 }
303
304 @Override
305 public String toString() {
306 return delegate.toString();
307 }
308
309 public E get(int i) {
310 return delegate.get(i);
311 }
312
313 public E set(int i, E e) {
314 return delegate.set(i, e);
315 }
316
317 public void add(int i, E e) {
318 delegate.add(i, e);
319 }
320
321 public E remove(int i) {
322 return delegate.remove(i);
323 }
324
325 public int indexOf(Object o) {
326 return delegate.indexOf(o);
327 }
328
329 public int lastIndexOf(Object o) {
330 return delegate.lastIndexOf(o);
331 }
332
333 public ListIterator<E> listIterator() {
334 return delegate.listIterator();
335 }
336
337 public ListIterator<E> listIterator(int i) {
338 return delegate.listIterator(i);
339 }
340
341 public List<E> subList(int i, int i1) {
342 return delegate.subList(i, i1);
343 }
344 }
345
346 public static class SetBuilder<E> implements Set<E> {
347 private final Set<E> delegate;
348
349 public SetBuilder(Set<E> delegate) {
350 this.delegate = delegate;
351 }
352
353 public SetBuilder<E> e(E e) {
354 delegate.add(e);
355 return this;
356 }
357
358 public int size() {
359 return delegate.size();
360 }
361
362 public boolean isEmpty() {
363 return delegate.isEmpty();
364 }
365
366 public boolean contains(Object o) {
367 return delegate.contains(o);
368 }
369
370 public Iterator<E> iterator() {
371 return delegate.iterator();
372 }
373
374 public Object[] toArray() {
375 return delegate.toArray();
376 }
377
378 public <T> T[] toArray(T[] ts) {
379 return delegate.toArray(ts);
380 }
381
382 public boolean add(E e) {
383 return delegate.add(e);
384 }
385
386 public boolean remove(Object o) {
387 return delegate.remove(o);
388 }
389
390 public boolean containsAll(Collection<?> objects) {
391 return delegate.containsAll(objects);
392 }
393
394 public boolean addAll(Collection<? extends E> es) {
395 return delegate.addAll(es);
396 }
397
398 public boolean retainAll(Collection<?> objects) {
399 return delegate.retainAll(objects);
400 }
401
402 public boolean removeAll(Collection<?> objects) {
403 return delegate.removeAll(objects);
404 }
405
406 public void clear() {
407 delegate.clear();
408 }
409
410 @Override
411 public boolean equals(Object o) {
412 return delegate.equals(o);
413 }
414
415 @Override
416 public int hashCode() {
417 return delegate.hashCode();
418 }
419
420 @Override
421 public String toString() {
422 return delegate.toString();
423 }
424 }
425
426 private static class MapToPropertiesAdapter extends Properties {
427 private final Map<String, Object> map;
428
429 private MapToPropertiesAdapter(@Nonnull Map<String, Object> map) {
430 this.map = map;
431 }
432
433 @Override
434 public synchronized Object setProperty(String key, String value) {
435 return map.put(key, value);
436 }
437
438 @Override
439 public String getProperty(String key) {
440 Object value = map.get(key);
441 return value != null ? String.valueOf(value) : null;
442 }
443
444 @Override
445 public String getProperty(String key, String defaultValue) {
446 Object value = map.get(key);
447 return value != null ? String.valueOf(value) : defaultValue;
448 }
449
450 @Override
451 public Enumeration<?> propertyNames() {
452 return keys();
453 }
454
455 @Override
456 public Set<String> stringPropertyNames() {
457 return map.keySet();
458 }
459
460 @Override
461 public synchronized int size() {
462 return map.size();
463 }
464
465 @Override
466 public synchronized boolean isEmpty() {
467 return map.isEmpty();
468 }
469
470 @Override
471 public synchronized Enumeration<Object> keys() {
472 return new Enumeration<Object>() {
473 private Iterator<String> keys = new ArrayList<>(map.keySet()).iterator();
474
475 @Override
476 public boolean hasMoreElements() {
477 return keys.hasNext();
478 }
479
480 @Override
481 public String nextElement() {
482 return keys.next();
483 }
484 };
485 }
486
487 @Override
488 public synchronized Enumeration<Object> elements() {
489 return new Enumeration<Object>() {
490 private Iterator<Object> values = new ArrayList<>(map.values()).iterator();
491
492 @Override
493 public boolean hasMoreElements() {
494 return values.hasNext();
495 }
496
497 @Override
498 public Object nextElement() {
499 return values.next();
500 }
501 };
502 }
503
504 @Override
505 public synchronized boolean contains(Object value) {
506 return map.containsValue(value);
507 }
508
509 @Override
510 public boolean containsValue(Object value) {
511 return map.containsValue(value);
512 }
513
514 @Override
515 public synchronized boolean containsKey(Object key) {
516 return map.containsKey(key);
517 }
518
519 @Override
520 public synchronized Object get(Object key) {
521 return map.get(key);
522 }
523
524 @Override
525 public synchronized Object put(Object key, Object value) {
526 return map.put(String.valueOf(key), value);
527 }
528
529 @Override
530 public synchronized Object remove(Object key) {
531 return map.remove(key);
532 }
533
534 @Override
535 public synchronized void putAll(Map<?, ?> t) {
536 map.putAll((Map<String, Object>) t);
537 }
538
539 @Override
540 public synchronized void clear() {
541 map.clear();
542 }
543
544 @Override
545 public Set<Object> keySet() {
546 return new LinkedHashSet<Object>(map.keySet());
547 }
548
549 @Override
550 public Set<Map.Entry<Object, Object>> entrySet() {
551 Set<Map.Entry<Object, Object>> set = new LinkedHashSet<>((Set) map.entrySet());
552 return new LinkedHashSet<>(set);
553 }
554
555 @Override
556 public Collection<Object> values() {
557 return map.values();
558 }
559
560 @Override
561 public synchronized Object clone() {
562 Map<String, Object> m = new LinkedHashMap<>(map);
563 return new MapToPropertiesAdapter(m);
564 }
565 }
566 }
|