OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 177 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 177 Rev 180
Line 14... Line 14...
14
 package org.openconcerto.utils;
14
 package org.openconcerto.utils;
15
 
15
 
16
import org.openconcerto.utils.cc.IClosure;
16
import org.openconcerto.utils.cc.IClosure;
17
import org.openconcerto.utils.cc.IPredicate;
17
import org.openconcerto.utils.cc.IPredicate;
18
import org.openconcerto.utils.cc.ITransformer;
18
import org.openconcerto.utils.cc.ITransformer;
-
 
19
import org.openconcerto.utils.cc.ITransformerExn;
19
import org.openconcerto.utils.cc.IdentityHashSet;
20
import org.openconcerto.utils.cc.IdentityHashSet;
20
import org.openconcerto.utils.cc.IdentitySet;
21
import org.openconcerto.utils.cc.IdentitySet;
21
import org.openconcerto.utils.cc.LinkedIdentitySet;
22
import org.openconcerto.utils.cc.LinkedIdentitySet;
22
import org.openconcerto.utils.cc.Transformer;
23
import org.openconcerto.utils.cc.Transformer;
23
 
24
 
Line 27... Line 28...
27
import java.util.Arrays;
28
import java.util.Arrays;
28
import java.util.Collection;
29
import java.util.Collection;
29
import java.util.Collections;
30
import java.util.Collections;
30
import java.util.HashMap;
31
import java.util.HashMap;
31
import java.util.HashSet;
32
import java.util.HashSet;
-
 
33
import java.util.IdentityHashMap;
32
import java.util.Iterator;
34
import java.util.Iterator;
33
import java.util.LinkedHashMap;
35
import java.util.LinkedHashMap;
-
 
36
import java.util.LinkedHashSet;
34
import java.util.LinkedList;
37
import java.util.LinkedList;
35
import java.util.List;
38
import java.util.List;
36
import java.util.ListIterator;
39
import java.util.ListIterator;
37
import java.util.Map;
40
import java.util.Map;
38
import java.util.Map.Entry;
41
import java.util.Map.Entry;
39
import java.util.NoSuchElementException;
42
import java.util.NoSuchElementException;
40
import java.util.RandomAccess;
43
import java.util.RandomAccess;
41
import java.util.Set;
44
import java.util.Set;
-
 
45
import java.util.SortedMap;
-
 
46
import java.util.SortedSet;
-
 
47
import java.util.TreeMap;
-
 
48
import java.util.TreeSet;
-
 
49
import java.util.function.Function;
42
import java.util.regex.Pattern;
50
import java.util.regex.Pattern;
43
 
51
 
44
/**
52
/**
45
 * Une classe regroupant des méthodes utilitaires pour les collections.
53
 * Une classe regroupant des méthodes utilitaires pour les collections.
46
 * 
54
 * 
Line 238... Line 246...
238
     */
246
     */
239
    static public void delete(List<?> l, int from) {
247
    static public void delete(List<?> l, int from) {
240
        delete(l, from, -1);
248
        delete(l, from, -1);
241
    }
249
    }
242
 
250
 
243
    public static <T> void filter(Collection<T> collection, IPredicate<? super T> predicate) {
-
 
244
        org.apache.commons.collections.CollectionUtils.filter(collection, predicate);
-
 
245
    }
-
 
246
 
-
 
247
    public static <T> boolean exists(Collection<T> collection, IPredicate<? super T> predicate) {
251
    public static <T> boolean exists(Collection<T> collection, IPredicate<? super T> predicate) {
248
        return org.apache.commons.collections.CollectionUtils.exists(collection, predicate);
252
        return collection.stream().anyMatch(predicate::evaluateChecked);
249
    }
253
    }
250
 
254
 
251
    /**
255
    /**
252
     * Convertit une map en 2 listes, une pour les clefs, une pour les valeurs.
256
     * Convertit une map en 2 listes, une pour les clefs, une pour les valeurs.
253
     * 
257
     * 
Line 283... Line 287...
283
                map.put(e.getKey(), e.getValue());
287
                map.put(e.getKey(), e.getValue());
284
        }
288
        }
285
        return map;
289
        return map;
286
    }
290
    }
287
 
291
 
-
 
292
    // compared to computeIfAbsent() :
-
 
293
    // 1. allow exceptions
-
 
294
    // 2. allow nulls
-
 
295
    static public <K, V, X extends Exception> V computeIfAbsent(final Map<K, V> map, final K key, final ITransformerExn<K, V, X> function, final boolean allowNullValue) throws X {
-
 
296
        V res = map.get(key);
-
 
297
        final boolean contains;
-
 
298
        if (allowNullValue) {
-
 
299
            contains = res != null || map.containsKey(key);
-
 
300
        } else {
-
 
301
            contains = res != null;
-
 
302
        }
-
 
303
        if (!contains) {
-
 
304
            res = function.transformChecked(key);
-
 
305
            if (res == null && !allowNullValue)
-
 
306
                throw new IllegalStateException("Null value computed for key '" + key + "'");
-
 
307
            map.put(key, res);
-
 
308
        }
-
 
309
        assert allowNullValue || res != null;
-
 
310
        return res;
-
 
311
    }
-
 
312
 
288
    /**
313
    /**
289
     * Compute the index that have changed (added or removed) between 2 lists. One of the lists MUST
314
     * Compute the index that have changed (added or removed) between 2 lists. One of the lists MUST
290
     * be a sublist of the other, ie the to go from one to the other we just add or remove items but
315
     * be a sublist of the other, ie the to go from one to the other we just add or remove items but
291
     * we don't do both.
316
     * we don't do both.
292
     * 
317
     * 
Line 375... Line 400...
375
 
400
 
376
    static public <C extends Collection<?>> boolean containsAny(final C coll1, final C coll2) {
401
    static public <C extends Collection<?>> boolean containsAny(final C coll1, final C coll2) {
377
        return !Collections.disjoint(coll1, coll2);
402
        return !Collections.disjoint(coll1, coll2);
378
    }
403
    }
379
 
404
 
380
    static public final <T> boolean identityContains(final Collection<T> coll, final T item) {
405
    static public final boolean identityContains(final Collection<?> coll, final Object item) {
381
        for (final T v : coll) {
406
        for (final Object v : coll) {
382
            if (item == v)
407
            if (item == v)
383
                return true;
408
                return true;
384
        }
409
        }
385
        return false;
410
        return false;
386
    }
411
    }
387
 
412
 
-
 
413
    static public final boolean identityEquals(final List<?> coll1, final List<?> coll2) {
-
 
414
        if (coll1 == coll2)
-
 
415
            return true;
-
 
416
        final int size = coll1.size();
-
 
417
        if (size != coll2.size())
-
 
418
            return false;
-
 
419
        if (size == 0)
-
 
420
            return true;
-
 
421
 
-
 
422
        final Iterator<?> iter1 = coll1.iterator();
-
 
423
        final Iterator<?> iter2 = coll2.iterator();
-
 
424
        while (iter1.hasNext()) {
-
 
425
            final Object elem1 = iter1.next();
-
 
426
            final Object elem2 = iter2.next();
-
 
427
            if (elem1 != elem2)
-
 
428
                return false;
-
 
429
        }
-
 
430
        assert !iter2.hasNext();
-
 
431
        return true;
-
 
432
    }
-
 
433
 
388
    /**
434
    /**
389
     * Convert an array to a list of a different type.
435
     * Convert an array to a list of a different type.
390
     * 
436
     * 
391
     * @param <U> type of array
437
     * @param <U> type of array
392
     * @param <T> type of list
438
     * @param <T> type of list
Line 900... Line 946...
900
        private Object readResolve() {
946
        private Object readResolve() {
901
            return EMPTY_SET;
947
            return EMPTY_SET;
902
        }
948
        }
903
    }
949
    }
904
 
950
 
-
 
951
    public static final <T> List<T> toImmutableList(final Collection<? extends T> coll) {
-
 
952
        return toImmutableList(coll, ArrayList::new);
-
 
953
    }
-
 
954
 
-
 
955
    public static final <T, C extends Collection<? extends T>> List<T> toImmutableList(final C coll, final Function<? super C, ? extends List<T>> createColl) {
-
 
956
        if (coll.isEmpty())
-
 
957
            return Collections.emptyList();
-
 
958
        return Collections.unmodifiableList(createColl.apply(coll));
-
 
959
    }
-
 
960
 
-
 
961
    public static final <T> Set<T> toImmutableSet(final Collection<T> coll) {
-
 
962
        if (coll instanceof SortedSet) {
-
 
963
            // force TreeSet(SortedSet) to keep Comparator
-
 
964
            // ATTN see eclipse bug below about wrong constructor, we need SortedSet<T>, not
-
 
965
            // SortedSet<? extends T>, otherwise "Open Declaration" will match to TreeSet(SortedSet)
-
 
966
            // but not at runtime.
-
 
967
            return toImmutableSet((SortedSet<T>) coll, TreeSet::new);
-
 
968
        } else if (coll instanceof IdentitySet) {
-
 
969
            return toImmutableSet((IdentitySet<? extends T>) coll, LinkedIdentitySet::new);
-
 
970
        } else {
-
 
971
            // In doubt, keep order
-
 
972
            // ATTN LinkedHashSet extends HashSet
-
 
973
            return toImmutableSet(coll, coll.getClass() == HashSet.class ? HashSet::new : LinkedHashSet::new);
-
 
974
        }
-
 
975
    }
-
 
976
 
-
 
977
    public static final <T, C extends Collection<? extends T>> Set<T> toImmutableSet(final C coll, final Function<? super C, ? extends Set<T>> createColl) {
-
 
978
        if (coll.isEmpty())
-
 
979
            return Collections.emptySet();
-
 
980
        final Set<T> res = createColl.apply(coll);
-
 
981
        return Collections.unmodifiableSet(res);
-
 
982
    }
-
 
983
 
-
 
984
    /**
-
 
985
     * Return an immutable map equal to the passed one.
-
 
986
     * 
-
 
987
     * @param <K> type of keys.
-
 
988
     * @param <V> type of values.
-
 
989
     * @param map the map, not "? extends K" to be able to copy {@link SortedMap}.
-
 
990
     * @return an immutable map.
-
 
991
     */
-
 
992
    public static final <K, V> Map<K, V> toImmutableMap(final Map<K, ? extends V> map) {
-
 
993
        if (map instanceof SortedMap) {
-
 
994
            // force TreeMap(SortedMap) to keep Comparator
-
 
995
            // ATTN see eclipse bug below about wrong constructor
-
 
996
            return toImmutableMap((SortedMap<K, ? extends V>) map, TreeMap::new);
-
 
997
        } else if (map instanceof IdentityHashMap) {
-
 
998
            return toImmutableMap((IdentityHashMap<? extends K, ? extends V>) map, IdentityHashMap::new);
-
 
999
        } else {
-
 
1000
            // In doubt, keep order
-
 
1001
            // ATTN LinkedHashMap extends HashMap
-
 
1002
            return toImmutableMap(map, map.getClass() == HashMap.class ? HashMap::new : LinkedHashMap::new);
-
 
1003
        }
-
 
1004
    }
-
 
1005
 
-
 
1006
    /**
-
 
1007
     * Return an immutable map with the same entries as the passed one. NOTE: <code>copyMap</code>
-
 
1008
     * <strong>must</strong> copy the entries so that a modification of <code>map</code> doesn't
-
 
1009
     * affect the copy.
-
 
1010
     * 
-
 
1011
     * @param <K> type of keys.
-
 
1012
     * @param <V> type of values.
-
 
1013
     * @param <InMap> type of passed map, ATTN if {@link SortedMap} eclipse "Open Declaration"
-
 
1014
     *        matches <code>TreeMap::new</code> to {@link TreeMap#TreeMap(SortedMap)} ignoring
-
 
1015
     *        generic type (i.e. it is declared with "K" but we pass "? extends K") but
-
 
1016
     *        {@link TreeMap#TreeMap(Map)} is (correctly) executed at runtime.
-
 
1017
     * @param map the map.
-
 
1018
     * @param copyFunction how to copy the passed map.
-
 
1019
     * @return an immutable map.
-
 
1020
     */
-
 
1021
    public static final <K, V, InMap extends Map<? extends K, ? extends V>> Map<K, V> toImmutableMap(final InMap map, final Function<? super InMap, ? extends Map<K, V>> copyFunction) {
-
 
1022
        if (map.isEmpty())
-
 
1023
            return Collections.emptyMap();
-
 
1024
        return Collections.unmodifiableMap(copyFunction.apply(map));
-
 
1025
    }
-
 
1026
 
905
    public static <K, V> Map<K, V> createMap(K key, V val, K key2, V val2) {
1027
    public static <K, V> Map<K, V> createMap(K key, V val, K key2, V val2) {
906
        // arguments are ordered, so should the result
1028
        // arguments are ordered, so should the result
907
        final Map<K, V> res = new LinkedHashMap<K, V>();
1029
        final Map<K, V> res = new LinkedHashMap<K, V>();
908
        res.put(key, val);
1030
        res.put(key, val);
909
        res.put(key2, val2);
1031
        res.put(key2, val2);