31363bd8407635c748649566978f81f7873a23a1
[aaa.git] / aaa-shiro / impl / src / main / java / org / opendaylight / aaa / impl / shiro / tokenauthrealm / util / HashCodeUtil.java
1 /*****************************************************************************
2  * Copyright (c) 2014, 2017 Hewlett-Packard Development Company, L.P. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  *****************************************************************************/
8
9 package org.opendaylight.aaa.impl.shiro.tokenauthrealm.util;
10
11 import java.lang.reflect.Array;
12
13 /**
14  * Collected methods which allow easy implementation of hashCode.
15  *
16  * <p>
17  * Example use case:
18  *
19  * <pre>
20  * public int hashCode() {
21  *     int result = HashCodeUtil.SEED;
22  *     // collect the contributions of various fields
23  *     result = HashCodeUtil.hash(result, fPrimitive);
24  *     result = HashCodeUtil.hash(result, fObject);
25  *     result = HashCodeUtil.hash(result, fArray);
26  *     return result;
27  * }
28  * </pre>
29  */
30 public final class HashCodeUtil {
31
32     /**
33      * An initial value for a hashCode, to which is added contributions
34      * from fields. Using a non-zero value decreases collisions of
35      * hashCode values.
36      */
37     // PRIVATE
38     private static final int ODD_PRIME_NUMBER = 37;
39
40     public static final int SEED = 23;
41
42     private HashCodeUtil() {
43     }
44
45     /**
46      * Hashing functionality.
47      *
48      * @param seed the seed
49      * @param booleanNumber the boolean number
50      * @return the hash
51      */
52     public static int hash(int seed, boolean booleanNumber) {
53         return firstTerm(seed) + (booleanNumber ? 1 : 0);
54     }
55
56     /**
57      * Hashing functionality.
58      *
59      * @param seed the seed
60      * @param character the character
61      * @return the hash
62      */
63     public static int hash(int seed, char character) {
64         return firstTerm(seed) + character;
65     }
66
67     /**
68      * Hashing functionality.
69      *
70      * @param seed the seed
71      * @param integer the integer
72      * @return the hash
73      */
74     public static int hash(int seed, int integer) {
75         return firstTerm(seed) + integer;
76     }
77
78     /**
79      * Hashing functionality.
80      *
81      * @param seed the seed
82      * @param longNumber the long number
83      * @return the hash
84      */
85     public static int hash(int seed, long longNumber) {
86         return firstTerm(seed) + (int) (longNumber ^ longNumber >>> 32);
87     }
88
89     /**
90      * Hashing functionality.
91      *
92      * @param seed the seed
93      * @param floatNumber the float number
94      * @return the hash
95      */
96     public static int hash(int seed, float floatNumber) {
97         return hash(seed, Float.floatToIntBits(floatNumber));
98     }
99
100     /**
101      * Hashing functionality.
102      *
103      * @param seed the seed
104      * @param doubleNumber the double number
105      * @return the hash
106      */
107     public static int hash(int seed, double doubleNumber) {
108         return hash(seed, Double.doubleToLongBits(doubleNumber));
109     }
110
111     /**
112      * Object can be either a nullable object field or an array.
113      *
114      * <p>
115      * If the object is an array, then each element may be a primitive or
116      * a possibly-null object.
117      *
118      * @param seed the seed
119      * @param object the object
120      * @return the hash
121      */
122     public static int hash(int seed, Object object) {
123         int result = seed;
124         if (object == null) {
125             result = hash(result, 0);
126         } else if (!isArray(object)) {
127             result = hash(result, object.hashCode());
128         } else {
129             int length = Array.getLength(object);
130             for (int idx = 0; idx < length; ++idx) {
131                 Object item = Array.get(object, idx);
132                 // if an item in the array references the array itself, prevent
133                 // infinite looping
134                 if (item != object) {
135                     result = hash(result, item);
136                 }
137             }
138         }
139         return result;
140     }
141
142     private static int firstTerm(int seed) {
143         return ODD_PRIME_NUMBER * seed;
144     }
145
146     private static boolean isArray(Object object) {
147         return object.getClass().isArray();
148     }
149 }