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}