001// ______________________________________________________
002// Generated by sql2java - https://github.com/10km/sql2java-2-6-7 (custom branch) 
003// modified by guyadong from
004// sql2java original version https://sourceforge.net/projects/sql2java/ 
005// JDBC driver used at code generation time: com.mysql.jdbc.Driver
006// template: hashcodebuilder.java.vm
007// ______________________________________________________
008package net.gdface.facelog.db;
009
010/*
011 * Copyright 2002-2005 The Apache Software Foundation.
012 * 
013 * Licensed under the Apache License, Version 2.0 (the "License");
014 * you may not use this file except in compliance with the License.
015 * You may obtain a copy of the License at
016 * 
017 *      http://www.apache.org/licenses/LICENSE-2.0
018 * 
019 * Unless required by applicable law or agreed to in writing, software
020 * distributed under the License is distributed on an "AS IS" BASIS,
021 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
022 * See the License for the specific language governing permissions and
023 * limitations under the License.
024 */
025import java.lang.reflect.AccessibleObject;
026import java.lang.reflect.Field;
027import java.lang.reflect.Modifier;
028
029/**
030 * <p>Assists in implementing {@link Object#hashCode()} methods.</p>
031 *
032 * <p> This class enables a good <code>hashCode</code> method to be built for any class. It
033 * follows the rules laid out in the book
034 * <a href="http://java.sun.com/docs/books/effective/index.html">Effective Java</a>
035 * by Joshua Bloch. Writing a good <code>hashCode</code> method is actually quite
036 * difficult. This class aims to simplify the process.</p>
037 *
038 * <p>All relevant fields from the object should be included in the
039 * <code>hashCode</code> method. Derived fields may be excluded. In general, any
040 * field used in the <code>equals</code> method must be used in the <code>hashCode</code>
041 * method.</p>
042 *
043 * <p>To use this class write code as follows:</p>
044 * <pre>
045 * public class Person {
046 *   String name;
047 *   int age;
048 *   boolean isSmoker;
049 *   ...
050 *
051 *   public int hashCode() {
052 *     // you pick a hard-coded, randomly chosen, non-zero, odd number
053 *     // ideally different for each class
054 *     return new HashCodeBuilder(17, 37).
055 *       append(name).
056 *       append(age).
057 *       append(smoker).
058 *       toHashCode();
059 *   }
060 * }
061 * </pre>
062 *
063 * <p>If required, the superclass <code>hashCode()</code> can be added
064 * using {@link #appendSuper}.</p>
065 *
066 * <p>Alternatively, there is a method that uses reflection to determine
067 * the fields to test. Because these fields are usually private, the method,
068 * <code>reflectionHashCode</code>, uses <code>AccessibleObject.setAccessible</code> to
069 * change the visibility of the fields. This will fail under a security manager,
070 * unless the appropriate permissions are set up correctly. It is also slower
071 * than testing explicitly.</p>
072 *
073 * <p>A typical invocation for this method would look like:</p>
074 * <pre>
075 * public int hashCode() {
076 *   return HashCodeBuilder.reflectionHashCode(this);
077 * }
078 * </pre>
079 *
080 * @author Stephen Colebourne
081 * @author Gary Gregory
082 * @author Pete Gieser
083 * @since 1.0
084 * @version $Id: HashCodeBuilder.java 161243 2005-04-14 04:30:28Z ggregory $
085 */
086public class HashCodeBuilder {
087
088    /**
089     * Constant to use in building the hashCode.
090     */
091    private final int iConstant;
092    /**
093     * Running total of the hashCode.
094     */
095    private int iTotal = 0;
096
097    /**
098     * <p>Uses two hard coded choices for the constants
099     * needed to build a <code>hashCode</code>.</p>
100     */
101    public HashCodeBuilder() {
102        iConstant = 37;
103        iTotal = 17;
104    }
105
106    /**
107     * <p>Two randomly chosen, non-zero, odd numbers must be passed in.
108     * Ideally these should be different for each class, however this is
109     * not vital.</p>
110     *
111     * <p>Prime numbers are preferred, especially for the multiplier.</p>
112     *
113     * @param initialNonZeroOddNumber  a non-zero, odd number used as the initial value
114     * @param multiplierNonZeroOddNumber  a non-zero, odd number used as the multiplier
115     * @throws IllegalArgumentException if the number is zero or even
116     */
117    public HashCodeBuilder(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber) {
118        if (initialNonZeroOddNumber == 0) {
119            throw new IllegalArgumentException("HashCodeBuilder requires a non zero initial value");
120        }
121        if (initialNonZeroOddNumber % 2 == 0) {
122            throw new IllegalArgumentException("HashCodeBuilder requires an odd initial value");
123        }
124        if (multiplierNonZeroOddNumber == 0) {
125            throw new IllegalArgumentException("HashCodeBuilder requires a non zero multiplier");
126        }
127        if (multiplierNonZeroOddNumber % 2 == 0) {
128            throw new IllegalArgumentException("HashCodeBuilder requires an odd multiplier");
129        }
130        iConstant = multiplierNonZeroOddNumber;
131        iTotal = initialNonZeroOddNumber;
132    }
133
134    //-------------------------------------------------------------------------
135
136    /**
137     * <p>This method uses reflection to build a valid hash code.</p>
138     *
139     * <p>This constructor uses two hard coded choices for the constants
140     * needed to build a hash code.</p>
141     *
142     * <p>It uses <code>AccessibleObject.setAccessible</code> to gain access to private
143     * fields. This means that it will throw a security exception if run under
144     * a security manager, if the permissions are not set up correctly. It is
145     * also not as efficient as testing explicitly.</p>
146     *
147     * <p>Transient members will be not be used, as they are likely derived
148     * fields, and not part of the value of the <code>Object</code>.</p>
149     *
150     * <p>Static fields will not be tested. Superclass fields will be included.</p>
151     *
152     * @param object  the Object to create a <code>hashCode</code> for
153     * @return int hash code
154     * @throws IllegalArgumentException if the object is <code>null</code>
155     */
156    public static int reflectionHashCode(Object object) {
157        return reflectionHashCode(17, 37, object, false, null);
158    }
159
160    /**
161     * <p>This method uses reflection to build a valid hash code.</p>
162     *
163     * <p>This constructor uses two hard coded choices for the constants needed
164     * to build a hash code.</p>
165     *
166     * <p> It uses <code>AccessibleObject.setAccessible</code> to gain access to private
167     * fields. This means that it will throw a security exception if run under
168     * a security manager, if the permissions are not set up correctly. It is
169     * also not as efficient as testing explicitly.</p>
170     *
171     * <P>If the TestTransients parameter is set to <code>true</code>, transient
172     * members will be tested, otherwise they are ignored, as they are likely
173     * derived fields, and not part of the value of the <code>Object</code>.</p>
174     *
175     * <p>Static fields will not be tested. Superclass fields will be included.</p>
176     *
177     * @param object  the Object to create a <code>hashCode</code> for
178     * @param testTransients  whether to include transient fields
179     * @return int hash code
180     * @throws IllegalArgumentException if the object is <code>null</code>
181     */
182    public static int reflectionHashCode(Object object, boolean testTransients) {
183        return reflectionHashCode(17, 37, object, testTransients, null);
184    }
185
186    /**
187     * <p>This method uses reflection to build a valid hash code.</p>
188     *
189     * <p>It uses <code>AccessibleObject.setAccessible</code> to gain access to private
190     * fields. This means that it will throw a security exception if run under
191     * a security manager, if the permissions are not set up correctly. It is
192     * also not as efficient as testing explicitly.</p>
193     *
194     * <p>Transient members will be not be used, as they are likely derived
195     * fields, and not part of the value of the <code>Object</code>.</p>
196     *
197     * <p>Static fields will not be tested. Superclass fields will be included.</p>
198     *
199     * <p>Two randomly chosen, non-zero, odd numbers must be passed in. Ideally
200     * these should be different for each class, however this is not vital.
201     * Prime numbers are preferred, especially for the multiplier.</p>
202     *
203     * @param initialNonZeroOddNumber  a non-zero, odd number used as the initial value
204     * @param multiplierNonZeroOddNumber  a non-zero, odd number used as the multiplier
205     * @param object  the Object to create a <code>hashCode</code> for
206     * @return int hash code
207     * @throws IllegalArgumentException if the Object is <code>null</code>
208     * @throws IllegalArgumentException if the number is zero or even
209     */
210    public static int reflectionHashCode(
211            int initialNonZeroOddNumber, int multiplierNonZeroOddNumber, Object object) {
212        return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, false, null);
213    }
214
215    /**
216     * <p>This method uses reflection to build a valid hash code.</p>
217     *
218     * <p>It uses <code>AccessibleObject.setAccessible</code> to gain access to private
219     * fields. This means that it will throw a security exception if run under
220     * a security manager, if the permissions are not set up correctly. It is also
221     * not as efficient as testing explicitly.</p>
222     *
223     * <p>If the TestTransients parameter is set to <code>true</code>, transient
224     * members will be tested, otherwise they are ignored, as they are likely
225     * derived fields, and not part of the value of the <code>Object</code>.</p>
226     *
227     * <p>Static fields will not be tested. Superclass fields will be included.</p>
228     *
229     * <p>Two randomly chosen, non-zero, odd numbers must be passed in. Ideally
230     * these should be different for each class, however this is not vital.
231     * Prime numbers are preferred, especially for the multiplier.</p>
232     *
233     * @param initialNonZeroOddNumber  a non-zero, odd number used as the initial value
234     * @param multiplierNonZeroOddNumber  a non-zero, odd number used as the multiplier
235     * @param object  the Object to create a <code>hashCode</code> for
236     * @param testTransients  whether to include transient fields
237     * @return int hash code
238     * @throws IllegalArgumentException if the Object is <code>null</code>
239     * @throws IllegalArgumentException if the number is zero or even
240     */
241    public static int reflectionHashCode(
242            int initialNonZeroOddNumber, int multiplierNonZeroOddNumber,
243            Object object, boolean testTransients) {
244        return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, testTransients, null);
245    }
246            
247    /**
248     * <p>This method uses reflection to build a valid hash code.</p>
249     *
250     * <p>It uses <code>AccessibleObject.setAccessible</code> to gain access to private
251     * fields. This means that it will throw a security exception if run under
252     * a security manager, if the permissions are not set up correctly. It is also
253     * not as efficient as testing explicitly.</p>
254     *
255     * <p>If the TestTransients parameter is set to <code>true</code>, transient
256     * members will be tested, otherwise they are ignored, as they are likely
257     * derived fields, and not part of the value of the <code>Object</code>.</p>
258     *
259     * <p>Static fields will not be included. Superclass fields will be included
260     * up to and including the specified superclass. A null superclass is treated
261     * as java.lang.Object.</p>
262     *
263     * <p>Two randomly chosen, non-zero, odd numbers must be passed in. Ideally
264     * these should be different for each class, however this is not vital.
265     * Prime numbers are preferred, especially for the multiplier.</p>
266     *
267     * @param initialNonZeroOddNumber  a non-zero, odd number used as the initial value
268     * @param multiplierNonZeroOddNumber  a non-zero, odd number used as the multiplier
269     * @param object  the Object to create a <code>hashCode</code> for
270     * @param testTransients  whether to include transient fields
271     * @param reflectUpToClass  the superclass to reflect up to (inclusive),
272     *  may be <code>null</code>
273     * @return int hash code
274     * @throws IllegalArgumentException if the Object is <code>null</code>
275     * @throws IllegalArgumentException if the number is zero or even
276     * @since 2.0
277     */
278    public static int reflectionHashCode(
279        int initialNonZeroOddNumber,
280        int multiplierNonZeroOddNumber,
281        Object object,
282        boolean testTransients,
283        Class reflectUpToClass) {
284
285        if (object == null) {
286            throw new IllegalArgumentException("The object to build a hash code for must not be null");
287        }
288        HashCodeBuilder builder = new HashCodeBuilder(initialNonZeroOddNumber, multiplierNonZeroOddNumber);
289        Class clazz = object.getClass();
290        reflectionAppend(object, clazz, builder, testTransients);
291        while (clazz.getSuperclass() != null && clazz != reflectUpToClass) {
292            clazz = clazz.getSuperclass();
293            reflectionAppend(object, clazz, builder, testTransients);
294        }
295        return builder.toHashCode();
296    }
297
298    /**
299     * <p>Appends the fields and values defined by the given object of the
300     * given <code>Class</code>.</p>
301     * 
302     * @param object  the object to append details of
303     * @param clazz  the class to append details of
304     * @param builder  the builder to append to
305     * @param useTransients  whether to use transient fields
306     */
307    private static void reflectionAppend(Object object, Class clazz, HashCodeBuilder builder, boolean useTransients) {
308        Field[] fields = clazz.getDeclaredFields();
309        AccessibleObject.setAccessible(fields, true);
310        for (int i = 0; i < fields.length; i++) {
311            Field f = fields[i];
312            if ((f.getName().indexOf('$') == -1)
313                && (useTransients || !Modifier.isTransient(f.getModifiers()))
314                && (!Modifier.isStatic(f.getModifiers()))) {
315                try {
316                    builder.append(f.get(object));
317                } catch (IllegalAccessException e) {
318                    //this can't happen. Would get a Security exception instead
319                    //throw a runtime exception in case the impossible happens.
320                    throw new InternalError("Unexpected IllegalAccessException");
321                }
322            }
323        }
324    }
325
326    //-------------------------------------------------------------------------
327
328    /**
329     * <p>Adds the result of super.hashCode() to this builder.</p>
330     *
331     * @param superHashCode  the result of calling <code>super.hashCode()</code>
332     * @return this HashCodeBuilder, used to chain calls.
333     * @since 2.0
334     */
335    public HashCodeBuilder appendSuper(int superHashCode) {
336        iTotal = iTotal * iConstant + superHashCode;
337        return this;
338    }
339
340    //-------------------------------------------------------------------------
341
342    /**
343     * <p>Append a <code>hashCode</code> for an <code>Object</code>.</p>
344     *
345     * @param object  the Object to add to the <code>hashCode</code>
346     * @return this
347     */
348    public HashCodeBuilder append(Object object) {
349        if (object == null) {
350            iTotal = iTotal * iConstant;
351
352        } else {
353            if (object.getClass().isArray() == false) {
354                //the simple case, not an array, just the element
355                iTotal = iTotal * iConstant + object.hashCode();
356
357            } else {
358                //'Switch' on type of array, to dispatch to the correct handler
359                // This handles multi dimensional arrays
360                if (object instanceof long[]) {
361                    append((long[]) object);
362                } else if (object instanceof int[]) {
363                    append((int[]) object);
364                } else if (object instanceof short[]) {
365                    append((short[]) object);
366                } else if (object instanceof char[]) {
367                    append((char[]) object);
368                } else if (object instanceof byte[]) {
369                    append((byte[]) object);
370                } else if (object instanceof double[]) {
371                    append((double[]) object);
372                } else if (object instanceof float[]) {
373                    append((float[]) object);
374                } else if (object instanceof boolean[]) {
375                    append((boolean[]) object);
376                } else {
377                    // Not an array of primitives
378                    append((Object[]) object);
379                }
380            }
381        }
382        return this;
383    }
384
385    /**
386     * <p>Append a <code>hashCode</code> for a <code>long</code>.</p>
387     *
388     * @param value  the long to add to the <code>hashCode</code>
389     * @return this
390     */
391    public HashCodeBuilder append(long value) {
392        iTotal = iTotal * iConstant + ((int) (value ^ (value >> 32)));
393        return this;
394    }
395
396    /**
397     * <p>Append a <code>hashCode</code> for an <code>int</code>.</p>
398     *
399     * @param value  the int to add to the <code>hashCode</code>
400     * @return this
401     */
402    public HashCodeBuilder append(int value) {
403        iTotal = iTotal * iConstant + value;
404        return this;
405    }
406
407    /**
408     * <p>Append a <code>hashCode</code> for a <code>short</code>.</p>
409     *
410     * @param value  the short to add to the <code>hashCode</code>
411     * @return this
412     */
413    public HashCodeBuilder append(short value) {
414        iTotal = iTotal * iConstant + value;
415        return this;
416    }
417
418    /**
419     * <p>Append a <code>hashCode</code> for a <code>char</code>.</p>
420     *
421     * @param value  the char to add to the <code>hashCode</code>
422     * @return this
423     */
424    public HashCodeBuilder append(char value) {
425        iTotal = iTotal * iConstant + value;
426        return this;
427    }
428
429    /**
430     * <p>Append a <code>hashCode</code> for a <code>byte</code>.</p>
431     *
432     * @param value  the byte to add to the <code>hashCode</code>
433     * @return this
434     */
435    public HashCodeBuilder append(byte value) {
436        iTotal = iTotal * iConstant + value;
437        return this;
438    }
439
440    /**
441     * <p>Append a <code>hashCode</code> for a <code>double</code>.</p>
442     *
443     * @param value  the double to add to the <code>hashCode</code>
444     * @return this
445     */
446    public HashCodeBuilder append(double value) {
447        return append(Double.doubleToLongBits(value));
448    }
449
450    /**
451     * <p>Append a <code>hashCode</code> for a <code>float</code>.</p>
452     *
453     * @param value  the float to add to the <code>hashCode</code>
454     * @return this
455     */
456    public HashCodeBuilder append(float value) {
457        iTotal = iTotal * iConstant + Float.floatToIntBits(value);
458        return this;
459    }
460
461    /**
462     * <p>Append a <code>hashCode</code> for a <code>boolean</code>.</p>
463     * <p>This adds <code>iConstant * 1</code> to the <code>hashCode</code>
464     * and not a <code>1231</code> or <code>1237</code> as done in java.lang.Boolean. 
465     * This is in accordance with the Effective Java design. </p>
466     *
467     * @param value  the boolean to add to the <code>hashCode</code>
468     * @return this
469     */
470    public HashCodeBuilder append(boolean value) {
471        iTotal = iTotal * iConstant + (value ? 0 : 1);
472        return this;
473    }
474
475    /**
476     * <p>Append a <code>hashCode</code> for an <code>Object</code> array.</p>
477     *
478     * @param array  the array to add to the <code>hashCode</code>
479     * @return this
480     */
481    public HashCodeBuilder append(Object[] array) {
482        if (array == null) {
483            iTotal = iTotal * iConstant;
484        } else {
485            for (int i = 0; i < array.length; i++) {
486                append(array[i]);
487            }
488        }
489        return this;
490    }
491
492    /**
493     * <p>Append a <code>hashCode</code> for a <code>long</code> array.</p>
494     *
495     * @param array  the array to add to the <code>hashCode</code>
496     * @return this
497     */
498    public HashCodeBuilder append(long[] array) {
499        if (array == null) {
500            iTotal = iTotal * iConstant;
501        } else {
502            for (int i = 0; i < array.length; i++) {
503                append(array[i]);
504            }
505        }
506        return this;
507    }
508
509    /**
510     * <p>Append a <code>hashCode</code> for an <code>int</code> array.</p>
511     *
512     * @param array  the array to add to the <code>hashCode</code>
513     * @return this
514     */
515    public HashCodeBuilder append(int[] array) {
516        if (array == null) {
517            iTotal = iTotal * iConstant;
518        } else {
519            for (int i = 0; i < array.length; i++) {
520                append(array[i]);
521            }
522        }
523        return this;
524    }
525
526    /**
527     * <p>Append a <code>hashCode</code> for a <code>short</code> array.</p>
528     *
529     * @param array  the array to add to the <code>hashCode</code>
530     * @return this
531     */
532    public HashCodeBuilder append(short[] array) {
533        if (array == null) {
534            iTotal = iTotal * iConstant;
535        } else {
536            for (int i = 0; i < array.length; i++) {
537                append(array[i]);
538            }
539        }
540        return this;
541    }
542
543    /**
544     * <p>Append a <code>hashCode</code> for a <code>char</code> array.</p>
545     *
546     * @param array  the array to add to the <code>hashCode</code>
547     * @return this
548     */
549    public HashCodeBuilder append(char[] array) {
550        if (array == null) {
551            iTotal = iTotal * iConstant;
552        } else {
553            for (int i = 0; i < array.length; i++) {
554                append(array[i]);
555            }
556        }
557        return this;
558    }
559
560    /**
561     * <p>Append a <code>hashCode</code> for a <code>byte</code> array.</p>
562     *
563     * @param array  the array to add to the <code>hashCode</code>
564     * @return this
565     */
566    public HashCodeBuilder append(byte[] array) {
567        if (array == null) {
568            iTotal = iTotal * iConstant;
569        } else {
570            for (int i = 0; i < array.length; i++) {
571                append(array[i]);
572            }
573        }
574        return this;
575    }
576
577    /**
578     * <p>Append a <code>hashCode</code> for a <code>double</code> array.</p>
579     *
580     * @param array  the array to add to the <code>hashCode</code>
581     * @return this
582     */
583    public HashCodeBuilder append(double[] array) {
584        if (array == null) {
585            iTotal = iTotal * iConstant;
586        } else {
587            for (int i = 0; i < array.length; i++) {
588                append(array[i]);
589            }
590        }
591        return this;
592    }
593
594    /**
595     * <p>Append a <code>hashCode</code> for a <code>float</code> array.</p>
596     *
597     * @param array  the array to add to the <code>hashCode</code>
598     * @return this
599     */
600    public HashCodeBuilder append(float[] array) {
601        if (array == null) {
602            iTotal = iTotal * iConstant;
603        } else {
604            for (int i = 0; i < array.length; i++) {
605                append(array[i]);
606            }
607        }
608        return this;
609    }
610
611    /**
612     * <p>Append a <code>hashCode</code> for a <code>boolean</code> array.</p>
613     *
614     * @param array  the array to add to the <code>hashCode</code>
615     * @return this
616     */
617    public HashCodeBuilder append(boolean[] array) {
618        if (array == null) {
619            iTotal = iTotal * iConstant;
620        } else {
621            for (int i = 0; i < array.length; i++) {
622                append(array[i]);
623            }
624        }
625        return this;
626    }
627
628    /**
629     * <p>Return the computed <code>hashCode</code>.</p>
630     *
631     * @return <code>hashCode</code> based on the fields appended
632     */
633    public int toHashCode() {
634        return iTotal;
635    }
636
637}