| 
001 /*002  * Copyright 2008-2015 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 }
 |