Source Code Cross Referenced for HashCodeBuilder.java in  » Portal » jetspeed-2.1.3 » org » apache » jetspeed » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Portal » jetspeed 2.1.3 » org.apache.jetspeed.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         * 
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:        package org.apache.jetspeed.util;
018:
019:        import java.lang.reflect.Field;
020:        import java.lang.reflect.Modifier;
021:
022:        /**
023:         * <code>HashCode</code> generation routines.
024:         * <p>
025:         * This class enables a good hashcode to be built for any class. It follows
026:         * the rules laid out in the book Effective Java, by Joshua Bloch. Writing a 
027:         * good hashCode is actually quite difficult. This class aims to simplify the 
028:         * process.
029:         * <p>
030:         * All relevant fields from the object should be included in the hashCode. Derived
031:         * fields may be excluded. In general, any field used in the equals method must be
032:         * used in the hashCode method. 
033:         * <p>
034:         * To use this class write code as follows:
035:         * <pre>
036:         * public class Person {
037:         *   String name;
038:         *   int age;
039:         *   boolean isSmoker;
040:         *   ...
041:         * 
042:         *   public int hashCode() {
043:         *     // you pick a hard-coded, randomly chosen, non-zero, odd number
044:         *     // ideally different for each class
045:         *     return new HashCodeBuilder(17, 37).   
046:         *       append(name).
047:         *       append(age).
048:         *       append(smoker).
049:         *       toHashCode();
050:         *   }
051:         * }
052:         * </pre>
053:         * <p>
054:         * Alternatively, there is a method that uses reflection to determine
055:         * the fields to test. Because these fields are usually private, the method, 
056:         * <code>reflectionHashCode</code>, uses <code>Field.setAccessible</code> to
057:         * change the visibility of the fields. This will fail under a security manager, 
058:         * unless the appropriate permissions are set. It is also slower than testing 
059:         * explicitly.
060:         * <p>
061:         * A typical invocation for this method would look like:
062:         * <pre>
063:         * public boolean hashCode(Object o) {
064:         *   return HashCodeBuilder.reflectionHashCode(this);
065:         * }
066:         * </pre>
067:         * 
068:         * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
069:         * @version $Id: HashCodeBuilder.java 517121 2007-03-12 07:45:49Z ate $
070:         */
071:        public class HashCodeBuilder {
072:
073:            /**
074:             * Constant to use in building the hashCode
075:             */
076:            private final int iConstant;
077:            /**
078:             * Running total of the hashCode
079:             */
080:            private int iTotal = 0;
081:
082:            /**
083:             * Constructor for HashCodeBuilder.
084:             * This constructor uses two hard coded choices for the constants needed
085:             * to build a hashCode.
086:             */
087:            public HashCodeBuilder() {
088:                super ();
089:                iConstant = 37;
090:                iTotal = 17;
091:            }
092:
093:            /**
094:             * Constructor for HashCodeBuilder.
095:             * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally
096:             * these should be different for each class, however this is not vital.
097:             * Prime numbers are preferred, especially for the multiplier.
098:             * 
099:             * @param initialNonZeroOddNumber  a non-zero, odd number used as the initial value
100:             * @param multiplierNonZeroOddNumber  a non-zero, odd number used as the multiplier
101:             * @throws IllegalArgumentException if the number is zero or even
102:             */
103:            public HashCodeBuilder(int initialNonZeroOddNumber,
104:                    int multiplierNonZeroOddNumber) {
105:                super ();
106:                if (initialNonZeroOddNumber == 0) {
107:                    throw new IllegalArgumentException(
108:                            "HashCodeBuilder requires a non zero initial value");
109:                }
110:                if (initialNonZeroOddNumber % 2 == 0) {
111:                    throw new IllegalArgumentException(
112:                            "HashCodeBuilder requires an odd initial value");
113:                }
114:                if (multiplierNonZeroOddNumber == 0) {
115:                    throw new IllegalArgumentException(
116:                            "HashCodeBuilder requires a non zero multiplier");
117:                }
118:                if (multiplierNonZeroOddNumber % 2 == 0) {
119:                    throw new IllegalArgumentException(
120:                            "HashCodeBuilder requires an odd multiplier");
121:                }
122:                iConstant = multiplierNonZeroOddNumber;
123:                iTotal = initialNonZeroOddNumber;
124:            }
125:
126:            //-------------------------------------------------------------------------
127:
128:            /**
129:             * This method uses reflection to build a valid hash code. 
130:             * <p>
131:             * It uses Field.setAccessible to gain access to private fields. This means
132:             * that it will throw a security exception if run under a security manger, if
133:             * the permissions are not set up.
134:             * It is also not as efficient as testing explicitly. 
135:             * Transient members will be not be used, as they are likely derived 
136:             * fields, and not part of the value of the object. 
137:             * Static fields will not be tested.
138:             * This constructor uses two hard coded choices for the constants needed
139:             * to build a hash code.
140:             * 
141:             * @param object  the object to create a hash code for
142:             * @return int hash code
143:             * @throws IllegalArgumentException if the object is null
144:             */
145:            public static int reflectionHashCode(Object object) {
146:                return reflectionHashCode(object, false);
147:            }
148:
149:            /**
150:             * This method uses reflection to build a valid hash code. 
151:             * <p>
152:             * It uses Field.setAccessible to gain access to private fields. This means
153:             * that it will throw a security exception if run under a security manger, if
154:             * the permissions are not set up.
155:             * It is also not as efficient as testing explicitly. 
156:             * If the TestTransients parameter is set to true, transient members will be
157:             * tested, otherwise they are ignored, as they are likely derived fields, and
158:             * not part of the value of the object. 
159:             * Static fields will not be tested.
160:             * This constructor uses two hard coded choices for the constants needed
161:             * to build a hash code.
162:             * 
163:             * @param object  the object to create a hash code for
164:             * @param testTransients  whether to include transient fields
165:             * @return int hash code
166:             * @throws IllegalArgumentException if the object is null
167:             */
168:            public static int reflectionHashCode(Object object,
169:                    boolean testTransients) {
170:                return reflectionHashCode(17, 37, object, testTransients);
171:            }
172:
173:            /**
174:             * This method uses reflection to build a valid hash code. 
175:             * <p>
176:             * It uses Field.setAccessible to gain access to private fields. This means
177:             * that it will throw a security exception if run under a security manger, if
178:             * the permissions are not set up.
179:             * It is also not as efficient as testing explicitly. 
180:             * Transient members will be not be used, as they are likely derived 
181:             * fields, and not part of the value of the object. 
182:             * Static fields will not be tested.
183:             * <p>
184:             * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally
185:             * these should be different for each class, however this is not vital.
186:             * Prime numbers are preferred, especially for the multiplier.
187:             * 
188:             * @param initialNonZeroOddNumber  a non-zero, odd number used as the initial value
189:             * @param multiplierNonZeroOddNumber  a non-zero, odd number used as the multiplier
190:             * @param object  the object to create a hash code for
191:             * @return int hash code
192:             * @throws IllegalArgumentException if the object is null
193:             * @throws IllegalArgumentException if the number is zero or even
194:             */
195:            public static int reflectionHashCode(int initialNonZeroOddNumber,
196:                    int multiplierNonZeroOddNumber, Object object) {
197:                return reflectionHashCode(initialNonZeroOddNumber,
198:                        multiplierNonZeroOddNumber, object, false);
199:            }
200:
201:            /**
202:             * This method uses reflection to build a valid hash code. 
203:             * <p>
204:             * It uses Field.setAccessible to gain access to private fields. This means
205:             * that it will throw a security exception if run under a security manger, if
206:             * the permissions are not set up.
207:             * It is also not as efficient as testing explicitly. 
208:             * If the TestTransients parameter is set to true, transient members will be
209:             * tested, otherwise they are ignored, as they are likely derived fields, and
210:             * not part of the value of the object. 
211:             * Static fields will not be tested.
212:             * <p>
213:             * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally
214:             * these should be different for each class, however this is not vital.
215:             * Prime numbers are preferred, especially for the multiplier.
216:             * 
217:             * @param initialNonZeroOddNumber
218:             * @param multiplierNonZeroOddNumber
219:             * @param object  the object to create a hash code for
220:             * @param testTransients  whether to include transient fields
221:             * @return int hash code
222:             * @throws IllegalArgumentException if the object is null
223:             * @throws IllegalArgumentException if the number is zero or even
224:             */
225:            public static int reflectionHashCode(int initialNonZeroOddNumber,
226:                    int multiplierNonZeroOddNumber, Object object,
227:                    boolean testTransients) {
228:
229:                if (object == null) {
230:                    throw new IllegalArgumentException(
231:                            "The object to build a hash code for must not be null");
232:                }
233:                HashCodeBuilder hashCodeBuilder = new HashCodeBuilder(
234:                        initialNonZeroOddNumber, multiplierNonZeroOddNumber);
235:                Field[] fields = object.getClass().getDeclaredFields();
236:                Field.setAccessible(fields, true);
237:                for (int i = 0; i < fields.length; ++i) {
238:                    Field f = fields[i];
239:                    if (testTransients
240:                            || !Modifier.isTransient(f.getModifiers())) {
241:                        if (!Modifier.isStatic(f.getModifiers())) {
242:                            try {
243:                                hashCodeBuilder.append(f.get(object));
244:                            } catch (IllegalAccessException e) {
245:                                //this can't happen. Would get a Security exception instead
246:                                //throw a runtime exception in case the impossible happens.
247:                                throw new InternalError(
248:                                        "Unexpected IllegalAccessException");
249:                            }
250:                        }
251:                    }
252:                }
253:                return hashCodeBuilder.toHashCode();
254:            }
255:
256:            //-------------------------------------------------------------------------
257:
258:            /**
259:             * Append a hashCode for an Object.
260:             *
261:             * @param object  the object to add to the hashCode
262:             * @return this
263:             */
264:            public HashCodeBuilder append(Object object) {
265:                if (object == null) {
266:                    iTotal = iTotal * iConstant;
267:
268:                } else {
269:                    if (object.getClass().isArray() == false) {
270:                        //the simple case, not an array, just the element 
271:                        iTotal = iTotal * iConstant + object.hashCode();
272:
273:                    } else {
274:                        //'Switch' on type of array, to dispatch to the correct handler
275:                        // This handles multi dimensional arrays
276:                        if (object instanceof  long[]) {
277:                            append((long[]) object);
278:                        } else if (object instanceof  int[]) {
279:                            append((int[]) object);
280:                        } else if (object instanceof  short[]) {
281:                            append((short[]) object);
282:                        } else if (object instanceof  char[]) {
283:                            append((char[]) object);
284:                        } else if (object instanceof  byte[]) {
285:                            append((byte[]) object);
286:                        } else if (object instanceof  double[]) {
287:                            append((double[]) object);
288:                        } else if (object instanceof  float[]) {
289:                            append((float[]) object);
290:                        } else if (object instanceof  boolean[]) {
291:                            append((boolean[]) object);
292:                        } else {
293:                            // Not an array of primitives
294:                            append((Object[]) object);
295:                        }
296:                    }
297:                }
298:                return this ;
299:            }
300:
301:            /**
302:             * Append a hashCode for a long.
303:             *
304:             * @param value  the long to add to the hashCode
305:             * @return this
306:             */
307:            public HashCodeBuilder append(long value) {
308:                iTotal = iTotal * iConstant + ((int) (value ^ (value >> 32)));
309:                return this ;
310:            }
311:
312:            /**
313:             * Append a hashCode for an int.
314:             *
315:             * @param value  the int to add to the hashCode
316:             * @return this
317:             */
318:            public HashCodeBuilder append(int value) {
319:                iTotal = iTotal * iConstant + value;
320:                return this ;
321:            }
322:
323:            /**
324:             * Append a hashCode for a short.
325:             *
326:             * @param value  the short to add to the hashCode
327:             * @return this
328:             */
329:            public HashCodeBuilder append(short value) {
330:                iTotal = iTotal * iConstant + value;
331:                return this ;
332:            }
333:
334:            /**
335:             * Append a hashCode for a char.
336:             *
337:             * @param value  the char to add to the hashCode
338:             * @return this
339:             */
340:            public HashCodeBuilder append(char value) {
341:                iTotal = iTotal * iConstant + value;
342:                return this ;
343:            }
344:
345:            /**
346:             * Append a hashCode for a byte.
347:             *
348:             * @param value  the byte to add to the hashCode
349:             * @return this
350:             */
351:            public HashCodeBuilder append(byte value) {
352:                iTotal = iTotal * iConstant + value;
353:                return this ;
354:            }
355:
356:            /**
357:             * Append a hashCode for a double.
358:             *
359:             * @param value  the double to add to the hashCode
360:             * @return this
361:             */
362:            public HashCodeBuilder append(double value) {
363:                return append(Double.doubleToLongBits(value));
364:            }
365:
366:            /**
367:             * Append a hashCode for a float.
368:             *
369:             * @param value  the float to add to the hashCode
370:             * @return this
371:             */
372:            public HashCodeBuilder append(float value) {
373:                iTotal = iTotal * iConstant + Float.floatToIntBits(value);
374:                return this ;
375:            }
376:
377:            /**
378:             * Append a hashCode for a long.
379:             *
380:             * @param value  the long to add to the hashCode
381:             * @return this
382:             */
383:            public HashCodeBuilder append(boolean value) {
384:                iTotal = iTotal * iConstant + (value ? 0 : 1);
385:                return this ;
386:            }
387:
388:            /**
389:             * Append a hashCode for an Object array.
390:             *
391:             * @param array  the array to add to the hashCode
392:             * @return this
393:             */
394:            public HashCodeBuilder append(Object[] array) {
395:                if (array == null) {
396:                    iTotal = iTotal * iConstant;
397:                } else {
398:                    for (int i = 0; i < array.length; i++) {
399:                        append(array[i]);
400:                    }
401:                }
402:                return this ;
403:            }
404:
405:            /**
406:             * Append a hashCode for a long array.
407:             *
408:             * @param array  the array to add to the hashCode
409:             * @return this
410:             */
411:            public HashCodeBuilder append(long[] array) {
412:                if (array == null) {
413:                    iTotal = iTotal * iConstant;
414:                } else {
415:                    for (int i = 0; i < array.length; i++) {
416:                        append(array[i]);
417:                    }
418:                }
419:                return this ;
420:            }
421:
422:            /**
423:             * Append a hashCode for an int array.
424:             *
425:             * @param array  the array to add to the hashCode
426:             * @return this
427:             */
428:            public HashCodeBuilder append(int[] array) {
429:                if (array == null) {
430:                    iTotal = iTotal * iConstant;
431:                } else {
432:                    for (int i = 0; i < array.length; i++) {
433:                        append(array[i]);
434:                    }
435:                }
436:                return this ;
437:            }
438:
439:            /**
440:             * Append a hashCode for a short array.
441:             *
442:             * @param array  the array to add to the hashCode
443:             * @return this
444:             */
445:            public HashCodeBuilder append(short[] array) {
446:                if (array == null) {
447:                    iTotal = iTotal * iConstant;
448:                } else {
449:                    for (int i = 0; i < array.length; i++) {
450:                        append(array[i]);
451:                    }
452:                }
453:                return this ;
454:            }
455:
456:            /**
457:             * Append a hashCode for a char array.
458:             *
459:             * @param array  the array to add to the hashCode
460:             * @return this
461:             */
462:            public HashCodeBuilder append(char[] array) {
463:                if (array == null) {
464:                    iTotal = iTotal * iConstant;
465:                } else {
466:                    for (int i = 0; i < array.length; i++) {
467:                        append(array[i]);
468:                    }
469:                }
470:                return this ;
471:            }
472:
473:            /**
474:             * Append a hashCode for a byte array.
475:             *
476:             * @param array  the array to add to the hashCode
477:             * @return this
478:             */
479:            public HashCodeBuilder append(byte[] array) {
480:                if (array == null) {
481:                    iTotal = iTotal * iConstant;
482:                } else {
483:                    for (int i = 0; i < array.length; i++) {
484:                        append(array[i]);
485:                    }
486:                }
487:                return this ;
488:            }
489:
490:            /**
491:             * Append a hashCode for a double array.
492:             *
493:             * @param array  the array to add to the hashCode
494:             * @return this
495:             */
496:            public HashCodeBuilder append(double[] array) {
497:                if (array == null) {
498:                    iTotal = iTotal * iConstant;
499:                } else {
500:                    for (int i = 0; i < array.length; i++) {
501:                        append(array[i]);
502:                    }
503:                }
504:                return this ;
505:            }
506:
507:            /**
508:             * Append a hashCode for a float array.
509:             *
510:             * @param array  the array to add to the hashCode
511:             * @return this
512:             */
513:            public HashCodeBuilder append(float[] array) {
514:                if (array == null) {
515:                    iTotal = iTotal * iConstant;
516:                } else {
517:                    for (int i = 0; i < array.length; i++) {
518:                        append(array[i]);
519:                    }
520:                }
521:                return this ;
522:            }
523:
524:            /**
525:             * Append a hashCode for a boolean array.
526:             *
527:             * @param array  the array to add to the hashCode
528:             * @return this
529:             */
530:            public HashCodeBuilder append(boolean[] array) {
531:                if (array == null) {
532:                    iTotal = iTotal * iConstant;
533:                } else {
534:                    for (int i = 0; i < array.length; i++) {
535:                        append(array[i]);
536:                    }
537:                }
538:                return this ;
539:            }
540:
541:            /**
542:             * Return the computed hashCode
543:             * 
544:             * @return int hashCode based on the fields appended
545:             */
546:            public int toHashCode() {
547:                return iTotal;
548:            }
549:
550:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.