OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 80 | Rev 132 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
17 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 /*
15
 * Créé le 14 avr. 2005
16
 */
17
package org.openconcerto.utils;
18
 
19
import org.openconcerto.utils.cc.ITransformer;
20
 
20 ilm 21
import java.math.BigDecimal;
93 ilm 22
import java.util.Collection;
17 ilm 23
import java.util.Comparator;
93 ilm 24
import java.util.Iterator;
25
import java.util.LinkedHashMap;
17 ilm 26
import java.util.List;
27
 
28
/**
29
 * @author Sylvain CUAZ
30
 */
31
public class CompareUtils {
32
 
33
    /**
34
     * Compare 2 nombres entier avec longValue().
35
     *
36
     * @param n1 le premier nombre.
37
     * @param n2 le deuxième nombre.
38
     * @return 0 si ==, >0 si n1>2.
39
     */
40
    public static final int compareIntNumbers(Number n1, Number n2) {
41
        return compareLong(n1.longValue(), n2.longValue());
42
    }
43
 
44
    static public final int compareInt(int int1, int int2) {
45
        if (int1 < int2)
46
            return -1;
47
        else if (int1 == int2)
48
            return 0;
49
        else
50
            return +1;
51
    }
52
 
53
    static public final int compareLong(long int1, long int2) {
54
        if (int1 < int2)
55
            return -1;
56
        else if (int1 == int2)
57
            return 0;
58
        else
59
            return +1;
60
    }
61
 
62
    /**
25 ilm 63
     * Compare two objects if they're numbers or comparable.
64
     *
65
     * @param o1 first object.
66
     * @param o2 second object.
67
     * @return a negative integer, zero, or a positive integer as o1 is less than, equal to, or
68
     *         greater than o2.
69
     * @throws ClassCastException if o1 is neither a {@link Number} nor a {@link Comparable}, or if
70
     *         o2's type prevents it from being compared to o1.
71
     * @throws NullPointerException if o1 or o2 is <code>null</code>.
72
     * @see Comparable#compareTo(Object)
73
     * @see NumberUtils#compare(Number, Number)
74
     */
75
    static public final int compare(final Object o1, final Object o2) throws ClassCastException {
76
        if (o1 == null || o2 == null)
77
            throw new NullPointerException();
78
        if (o1 instanceof Number && o2 instanceof Number) {
79
            return NumberUtils.compare((Number) o1, (Number) o2);
80
        } else {
81
            // see Arrays.mergeSort()
82
            @SuppressWarnings({ "rawtypes", "unchecked" })
83
            final int res = ((Comparable) o1).compareTo(o2);
84
            return res;
85
        }
86
    }
87
 
80 ilm 88
    static private final Comparator<Comparable<Object>> NATURAL_COMPARATOR = new Comparator<Comparable<Object>>() {
89
        @Override
90
        public int compare(Comparable<Object> o1, Comparable<Object> o2) {
91
            return o1.compareTo(o2);
92
        }
93
    };
94
 
95
    // added in Comparator in Java 8
96
    @SuppressWarnings("unchecked")
97
    static public final <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
98
        return (Comparator<T>) NATURAL_COMPARATOR;
99
    }
100
 
25 ilm 101
    /**
17 ilm 102
     * Renvoie un comparateur qui utilise successivement la liste passée tant que les objets sont
103
     * égaux.
104
     *
105
     * @param comparators une liste de Comparator.
106
     * @return le Comparator demandé.
107
     * @param <T> type of comparator
108
     */
109
    static public final <T> Comparator<T> createComparator(final List<? extends Comparator<T>> comparators) {
110
        return new Comparator<T>() {
111
            public String toString() {
112
                return "CompareUtils comparator with " + comparators;
113
            }
114
 
115
            public int compare(T o1, T o2) {
116
                int result = 0;
117
                int i = 0;
118
                while (i < comparators.size() && result == 0) {
119
                    final Comparator<T> transf = comparators.get(i);
120
                    result = transf.compare(o1, o2);
121
                    i++;
122
                }
123
                return result;
124
            }
125
        };
126
    }
127
 
128
    /**
129
     * Compare 2 objets pouvant être <code>null</code>.
130
     *
131
     * @param o1 the first object, can be <code>null</code>.
132
     * @param o2 the second object, can be <code>null</code>.
133
     * @return <code>true</code> if both are <code>null</code> or if o1.equals(o2).
20 ilm 134
     * @see Object#equals(Object)
17 ilm 135
     */
136
    static public final boolean equals(Object o1, Object o2) {
137
        if (o1 == null && o2 == null)
138
            return true;
139
        if (o1 == null || o2 == null)
140
            return false;
141
        return o1.equals(o2);
142
    }
143
 
20 ilm 144
    /**
145
     * Compare 2 objets pouvant être <code>null</code> avec compareTo(). Useful since for some
146
     * classes equals() is more specific than compareTo()==0, e.g. {@link BigDecimal#equals(Object)}
147
     * doesn't compare the numeric value but instance variables (1E2 is not equal to 100 or 100.00).
148
     *
149
     * @param o1 the first object, can be <code>null</code>.
150
     * @param o2 the second object, can be <code>null</code>.
151
     * @return <code>true</code> if both are <code>null</code> or if o1.compareTo(o2) == 0.
152
     * @see Comparable#compareTo(Object)
153
     */
154
    static public final <T> boolean equalsWithCompareTo(Comparable<T> o1, T o2) {
155
        if (o1 == null && o2 == null)
156
            return true;
157
        if (o1 == null || o2 == null)
158
            return false;
159
        return o1.compareTo(o2) == 0;
160
    }
161
 
93 ilm 162
    /**
163
     * Compare 2 collections in order. Useful since for some classes even though there's an order
164
     * <code>equals()</code> ignores it (e.g. {@link LinkedHashMap#equals(Object)}).
165
     *
166
     * @param c1 the first object, can be <code>null</code>.
167
     * @param c2 the second object, can be <code>null</code>.
168
     * @return <code>true</code> if both are <code>null</code> or if all items in order are
169
     *         {@link #equals(Object, Object)}.
170
     */
171
    static public final boolean equalsUsingIterator(Collection<?> c1, Collection<?> c2) {
172
        if (c1 == null && c2 == null)
173
            return true;
174
        if (c1 == null || c2 == null)
175
            return false;
176
 
177
        final int size = c1.size();
178
        if (size != c2.size())
179
            return false;
180
        else if (size == 0)
181
            return true;
182
 
183
        final Iterator<?> iter1 = c1.iterator();
184
        final Iterator<?> iter2 = c2.iterator();
185
        while (iter1.hasNext()) {
186
            final Object o1 = iter1.next();
187
            final Object o2 = iter2.next();
188
            if (!equals(o1, o2))
189
                return false;
190
        }
191
        assert !iter1.hasNext() && !iter2.hasNext();
192
        return true;
193
    }
194
 
17 ilm 195
    static public interface Equalizer<T> {
196
        public boolean equals(T o1, T o2);
197
    }
198
 
41 ilm 199
    static public final Equalizer<Object> OBJECT_EQ = new Equalizer<Object>() {
200
        public boolean equals(Object o1, Object o2) {
201
            return CompareUtils.equals(o1, o2);
202
        }
203
    };
204
 
17 ilm 205
    static public final <T> boolean equals(List<T> l1, List<T> l2, Equalizer<? super T> comp) {
206
        return compare(l1, l2, comp, null) == null;
207
    }
208
 
209
    /**
210
     * Compare two lists using the provided comparator.
211
     *
212
     * @param <T> type of items
213
     * @param l1 the first list.
214
     * @param l2 the second list.
215
     * @param comp how to compare each item.
216
     * @param toString how to dispay items, can be <code>null</code>.
217
     * @return <code>null</code> if the two lists are equal, otherwise a String explaining the
218
     *         difference.
219
     */
220
    static public final <T> String compare(List<T> l1, List<T> l2, Equalizer<? super T> comp, final ITransformer<? super T, String> toString) {
221
        final int size = l1.size();
222
        if (size != l2.size())
223
            return "unequal size";
224
        for (int i = 0; i < size; i++) {
225
            final T o1 = l1.get(i);
226
            final T o2 = l2.get(i);
227
            if (!comp.equals(o1, o2)) {
228
                final String s1 = toString == null ? String.valueOf(o1) : toString.transformChecked(o1);
229
                final String s2 = toString == null ? String.valueOf(o2) : toString.transformChecked(o2);
230
                return "unequal at " + i + ": " + s1 + " != " + s2;
231
            }
232
        }
233
        return null;
234
    }
235
}