Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
HashCodeUtils |
|
| 3.2;3.2 |
1 | package org.jtheque.utils.bean; | |
2 | ||
3 | import org.jtheque.utils.Constants; | |
4 | ||
5 | import java.beans.PropertyDescriptor; | |
6 | ||
7 | /* | |
8 | * This file is part of JTheque. | |
9 | * | |
10 | * JTheque is free software: you can redistribute it and/or modify | |
11 | * it under the terms of the GNU General Public License as published by | |
12 | * the Free Software Foundation, either version 3 of the License. | |
13 | * | |
14 | * JTheque is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License | |
20 | * along with JTheque. If not, see <http://www.gnu.org/licenses/>. | |
21 | */ | |
22 | ||
23 | /** | |
24 | * @author Baptiste Wicht | |
25 | */ | |
26 | public final class HashCodeUtils { | |
27 | private static final int NUMBER_BIT_LENGTH = 32; | |
28 | ||
29 | /** | |
30 | * Utility class, not instanciable. | |
31 | */ | |
32 | private HashCodeUtils() { | |
33 | 0 | super(); |
34 | 0 | } |
35 | ||
36 | /** | |
37 | * Generate a hash code for the bean. | |
38 | * <p/> | |
39 | * Note : The properties of the Object class are not retrieved. | |
40 | * | |
41 | * @param bean The bean. | |
42 | * @return A hash code based on all the properties of the bean. | |
43 | */ | |
44 | public static int hashCode(Object bean) { | |
45 | 4 | int result = Constants.HASH_CODE_START; |
46 | ||
47 | 16 | for (PropertyDescriptor property : ReflectionUtils.getProperties(bean)) { |
48 | 12 | if (property.getReadMethod() == null) { |
49 | 0 | continue; |
50 | } | |
51 | ||
52 | 12 | Object value = ReflectionUtils.getProperty(bean, property); |
53 | ||
54 | 12 | result = computeValue(result, value); |
55 | } | |
56 | ||
57 | 4 | return result; |
58 | } | |
59 | ||
60 | /** | |
61 | * Return the hash code of an object, using the properties in the given list. | |
62 | * | |
63 | * @param bean The bean to generate the hash code from. | |
64 | * @param properties The properties to use to generate the hash code. | |
65 | * @return The hash code of the bean . If there is no properties, the hash code will be 17. | |
66 | */ | |
67 | public static int hashCode(Object bean, String... properties) { | |
68 | 0 | int result = Constants.HASH_CODE_START; |
69 | ||
70 | 0 | for (String property : properties) { |
71 | 0 | Object value = ReflectionUtils.getPropertyValue(bean, property); |
72 | ||
73 | 0 | result = computeValue(result, value); |
74 | } | |
75 | ||
76 | 0 | return result; |
77 | } | |
78 | ||
79 | /** | |
80 | * Return the hash code of an object, using the properties in the given list. | |
81 | * | |
82 | * @param properties The properties to use to generate the hash code. | |
83 | * | |
84 | * @return The hash code of the bean . If there is no properties, the hash code will be 17. | |
85 | */ | |
86 | public static int hashCodeDirect(Object... properties){ | |
87 | 0 | int result = Constants.HASH_CODE_START; |
88 | ||
89 | 0 | for (Object property : properties){ |
90 | 0 | result = computeValue(result, property); |
91 | } | |
92 | ||
93 | 0 | return result; |
94 | } | |
95 | ||
96 | /** | |
97 | * Compute the value with the current result. | |
98 | * | |
99 | * @param result The current hash code result. | |
100 | * @param value The value to compute to the result. | |
101 | * @return The result computed with the value. | |
102 | */ | |
103 | private static int computeValue(int result, Object value) { | |
104 | int hash; | |
105 | ||
106 | 12 | if (value instanceof Double) { |
107 | 0 | Long temp = Double.doubleToLongBits((Double) value); |
108 | 0 | hash = Constants.HASH_CODE_PRIME * result + (int) (temp ^ temp >>> NUMBER_BIT_LENGTH); |
109 | 0 | } else if (value instanceof Long) { |
110 | 4 | Long temp = (Long) value; |
111 | 4 | hash = Constants.HASH_CODE_PRIME * result + (int) (temp ^ temp >>> NUMBER_BIT_LENGTH); |
112 | 4 | } else if (value instanceof Boolean) { |
113 | 0 | hash = Constants.HASH_CODE_PRIME * result + ((Boolean) value ? 0 : 1); |
114 | 8 | } else if (value instanceof Float) { |
115 | 0 | hash = Constants.HASH_CODE_PRIME * result + Float.floatToIntBits((Float) value); |
116 | 8 | } else if (value instanceof Number) { |
117 | 4 | hash = Constants.HASH_CODE_PRIME * result + ((Number) value).intValue(); |
118 | } else { | |
119 | 4 | hash = Constants.HASH_CODE_PRIME * result + (value == null ? 0 : value.hashCode()); |
120 | } | |
121 | ||
122 | 12 | return hash; |
123 | } | |
124 | } |