001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one
003     *  or more contributor license agreements.  See the NOTICE file
004     *  distributed with this work for additional information
005     *  regarding copyright ownership.  The ASF licenses this file
006     *  to you under the Apache License, Version 2.0 (the
007     *  "License"); you may not use this file except in compliance
008     *  with the License.  You may obtain a copy of the License at
009     *  
010     *    http://www.apache.org/licenses/LICENSE-2.0
011     *  
012     *  Unless required by applicable law or agreed to in writing,
013     *  software distributed under the License is distributed on an
014     *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *  KIND, either express or implied.  See the License for the
016     *  specific language governing permissions and limitations
017     *  under the License. 
018     *  
019     */
020    package org.apache.directory.shared.ldap.util;
021    
022    
023    import java.lang.reflect.AccessibleObject;
024    import java.lang.reflect.Field;
025    import java.lang.reflect.Modifier;
026    
027    
028    /**
029     * <p>
030     * Assists in implementing {@link Object#hashCode()} methods.
031     * </p>
032     * <p>
033     * This class enables a good <code>hashCode</code> method to be built for any
034     * class. It follows the rules laid out in the book <a
035     * href="http://java.sun.com/docs/books/effective/index.html">Effective Java</a>
036     * by Joshua Bloch. Writing a good <code>hashCode</code> method is actually
037     * quite difficult. This class aims to simplify the process.
038     * </p>
039     * <p>
040     * All relevant fields from the object should be included in the
041     * <code>hashCode</code> method. Derived fields may be excluded. In general,
042     * any field used in the <code>equals</code> method must be used in the
043     * <code>hashCode</code> method.
044     * </p>
045     * <p>
046     * To use this class write code as follows:
047     * </p>
048     * 
049     * <pre>
050     *  public class Person {
051     *    String name;
052     *    int age;
053     *    boolean isSmoker;
054     *    ...
055     * 
056     *    public int hashCode() {
057     *      // you pick a hard-coded, randomly chosen, non-zero, odd number
058     *      // ideally different for each class
059     *      return new HashCodeBuilder(17, 37).
060     *        append(name).
061     *        append(age).
062     *        append(smoker).
063     *        toHashCode();
064     *    }
065     *  }
066     * </pre>
067     * 
068     * <p>
069     * If required, the superclass <code>hashCode()</code> can be added using
070     * {@link #appendSuper}.
071     * </p>
072     * <p>
073     * Alternatively, there is a method that uses reflection to determine the fields
074     * to test. Because these fields are usually private, the method,
075     * <code>reflectionHashCode</code>, uses
076     * <code>AccessibleObject.setAccessible</code> to change the visibility of the
077     * fields. This will fail under a security manager, unless the appropriate
078     * permissions are set up correctly. It is also slower than testing explicitly.
079     * </p>
080     * <p>
081     * A typical invocation for this method would look like:
082     * </p>
083     * 
084     * <pre>
085     * public int hashCode()
086     * {
087     *     return HashCodeBuilder.reflectionHashCode( this );
088     * }
089     * </pre>
090     * 
091     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
092     */
093    public class HashCodeBuilder
094    {
095    
096        /**
097         * Constant to use in building the hashCode.
098         */
099        private final int iConstant;
100    
101        /**
102         * Running total of the hashCode.
103         */
104        private int iTotal = 0;
105    
106    
107        /**
108         * <p>
109         * Constructor.
110         * </p>
111         * <p>
112         * This constructor uses two hard coded choices for the constants needed to
113         * build a <code>hashCode</code>.
114         * </p>
115         */
116        public HashCodeBuilder()
117        {
118            super();
119            iConstant = 37;
120            iTotal = 17;
121        }
122    
123    
124        /**
125         * <p>
126         * Constructor.
127         * </p>
128         * <p>
129         * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally
130         * these should be different for each class, however this is not vital.
131         * </p>
132         * <p>
133         * Prime numbers are preferred, especially for the multiplier.
134         * </p>
135         * 
136         * @param initialNonZeroOddNumber
137         *            a non-zero, odd number used as the initial value
138         * @param multiplierNonZeroOddNumber
139         *            a non-zero, odd number used as the multiplier
140         * @throws IllegalArgumentException
141         *             if the number is zero or even
142         */
143        public HashCodeBuilder(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber)
144        {
145            super();
146            if ( initialNonZeroOddNumber == 0 )
147            {
148                throw new IllegalArgumentException( "HashCodeBuilder requires a non zero initial value" );
149            }
150            if ( initialNonZeroOddNumber % 2 == 0 )
151            {
152                throw new IllegalArgumentException( "HashCodeBuilder requires an odd initial value" );
153            }
154            if ( multiplierNonZeroOddNumber == 0 )
155            {
156                throw new IllegalArgumentException( "HashCodeBuilder requires a non zero multiplier" );
157            }
158            if ( multiplierNonZeroOddNumber % 2 == 0 )
159            {
160                throw new IllegalArgumentException( "HashCodeBuilder requires an odd multiplier" );
161            }
162            iConstant = multiplierNonZeroOddNumber;
163            iTotal = initialNonZeroOddNumber;
164        }
165    
166    
167        // -------------------------------------------------------------------------
168    
169        /**
170         * <p>
171         * This method uses reflection to build a valid hash code.
172         * </p>
173         * <p>
174         * This constructor uses two hard coded choices for the constants needed to
175         * build a hash code.
176         * </p>
177         * <p>
178         * It uses <code>AccessibleObject.setAccessible</code> to gain access to
179         * private fields. This means that it will throw a security exception if run
180         * under a security manager, if the permissions are not set up correctly. It
181         * is also not as efficient as testing explicitly.
182         * </p>
183         * <p>
184         * Transient members will be not be used, as they are likely derived fields,
185         * and not part of the value of the <code>Object</code>.
186         * </p>
187         * <p>
188         * Static fields will not be tested. Superclass fields will be included.
189         * </p>
190         * 
191         * @param object
192         *            the Object to create a <code>hashCode</code> for
193         * @return int hash code
194         * @throws IllegalArgumentException
195         *             if the object is <code>null</code>
196         */
197        public static int reflectionHashCode( Object object )
198        {
199            return reflectionHashCode( 17, 37, object, false, null );
200        }
201    
202    
203        /**
204         * <p>
205         * This method uses reflection to build a valid hash code.
206         * </p>
207         * <p>
208         * This constructor uses two hard coded choices for the constants needed to
209         * build a hash code.
210         * </p>
211         * <p>
212         * It uses <code>AccessibleObject.setAccessible</code> to gain access to
213         * private fields. This means that it will throw a security exception if run
214         * under a security manager, if the permissions are not set up correctly. It
215         * is also not as efficient as testing explicitly.
216         * </p>
217         * <P>
218         * If the TestTransients parameter is set to <code>true</code>, transient
219         * members will be tested, otherwise they are ignored, as they are likely
220         * derived fields, and not part of the value of the <code>Object</code>.
221         * </p>
222         * <p>
223         * Static fields will not be tested. Superclass fields will be included.
224         * </p>
225         * 
226         * @param object
227         *            the Object to create a <code>hashCode</code> for
228         * @param testTransients
229         *            whether to include transient fields
230         * @return int hash code
231         * @throws IllegalArgumentException
232         *             if the object is <code>null</code>
233         */
234        public static int reflectionHashCode( Object object, boolean testTransients )
235        {
236            return reflectionHashCode( 17, 37, object, testTransients, null );
237        }
238    
239    
240        /**
241         * <p>
242         * This method uses reflection to build a valid hash code.
243         * </p>
244         * <p>
245         * It uses <code>AccessibleObject.setAccessible</code> to gain access to
246         * private fields. This means that it will throw a security exception if run
247         * under a security manager, if the permissions are not set up correctly. It
248         * is also not as efficient as testing explicitly.
249         * </p>
250         * <p>
251         * Transient members will be not be used, as they are likely derived fields,
252         * and not part of the value of the <code>Object</code>.
253         * </p>
254         * <p>
255         * Static fields will not be tested. Superclass fields will be included.
256         * </p>
257         * <p>
258         * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally
259         * these should be different for each class, however this is not vital.
260         * Prime numbers are preferred, especially for the multiplier.
261         * </p>
262         * 
263         * @param initialNonZeroOddNumber
264         *            a non-zero, odd number used as the initial value
265         * @param multiplierNonZeroOddNumber
266         *            a non-zero, odd number used as the multiplier
267         * @param object
268         *            the Object to create a <code>hashCode</code> for
269         * @return int hash code
270         * @throws IllegalArgumentException
271         *             if the Object is <code>null</code>
272         * @throws IllegalArgumentException
273         *             if the number is zero or even
274         */
275        public static int reflectionHashCode( int initialNonZeroOddNumber, int multiplierNonZeroOddNumber, Object object )
276        {
277            return reflectionHashCode( initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, false, null );
278        }
279    
280    
281        /**
282         * <p>
283         * This method uses reflection to build a valid hash code.
284         * </p>
285         * <p>
286         * It uses <code>AccessibleObject.setAccessible</code> to gain access to
287         * private fields. This means that it will throw a security exception if run
288         * under a security manager, if the permissions are not set up correctly. It
289         * is also not as efficient as testing explicitly.
290         * </p>
291         * <p>
292         * If the TestTransients parameter is set to <code>true</code>, transient
293         * members will be tested, otherwise they are ignored, as they are likely
294         * derived fields, and not part of the value of the <code>Object</code>.
295         * </p>
296         * <p>
297         * Static fields will not be tested. Superclass fields will be included.
298         * </p>
299         * <p>
300         * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally
301         * these should be different for each class, however this is not vital.
302         * Prime numbers are preferred, especially for the multiplier.
303         * </p>
304         * 
305         * @param initialNonZeroOddNumber
306         *            a non-zero, odd number used as the initial value
307         * @param multiplierNonZeroOddNumber
308         *            a non-zero, odd number used as the multiplier
309         * @param object
310         *            the Object to create a <code>hashCode</code> for
311         * @param testTransients
312         *            whether to include transient fields
313         * @return int hash code
314         * @throws IllegalArgumentException
315         *             if the Object is <code>null</code>
316         * @throws IllegalArgumentException
317         *             if the number is zero or even
318         */
319        public static int reflectionHashCode( int initialNonZeroOddNumber, int multiplierNonZeroOddNumber, Object object,
320            boolean testTransients )
321        {
322            return reflectionHashCode( initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, testTransients, null );
323        }
324    
325    
326        /**
327         * <p>
328         * This method uses reflection to build a valid hash code.
329         * </p>
330         * <p>
331         * It uses <code>AccessibleObject.setAccessible</code> to gain access to
332         * private fields. This means that it will throw a security exception if run
333         * under a security manager, if the permissions are not set up correctly. It
334         * is also not as efficient as testing explicitly.
335         * </p>
336         * <p>
337         * If the TestTransients parameter is set to <code>true</code>, transient
338         * members will be tested, otherwise they are ignored, as they are likely
339         * derived fields, and not part of the value of the <code>Object</code>.
340         * </p>
341         * <p>
342         * Static fields will not be included. Superclass fields will be included up
343         * to and including the specified superclass. A null superclass is treated
344         * as java.lang.Object.
345         * </p>
346         * <p>
347         * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally
348         * these should be different for each class, however this is not vital.
349         * Prime numbers are preferred, especially for the multiplier.
350         * </p>
351         * 
352         * @param initialNonZeroOddNumber
353         *            a non-zero, odd number used as the initial value
354         * @param multiplierNonZeroOddNumber
355         *            a non-zero, odd number used as the multiplier
356         * @param object
357         *            the Object to create a <code>hashCode</code> for
358         * @param testTransients
359         *            whether to include transient fields
360         * @param reflectUpToClass
361         *            the superclass to reflect up to (inclusive), may be
362         *            <code>null</code>
363         * @return int hash code
364         * @throws IllegalArgumentException
365         *             if the Object is <code>null</code>
366         * @throws IllegalArgumentException
367         *             if the number is zero or even
368         * @since 2.0
369         */
370        public static int reflectionHashCode( int initialNonZeroOddNumber, int multiplierNonZeroOddNumber, Object object,
371            boolean testTransients, Class reflectUpToClass )
372        {
373    
374            if ( object == null )
375            {
376                throw new IllegalArgumentException( "The object to build a hash code for must not be null" );
377            }
378            HashCodeBuilder builder = new HashCodeBuilder( initialNonZeroOddNumber, multiplierNonZeroOddNumber );
379            Class clazz = object.getClass();
380            reflectionAppend( object, clazz, builder, testTransients );
381            while ( clazz.getSuperclass() != null && clazz != reflectUpToClass )
382            {
383                clazz = clazz.getSuperclass();
384                reflectionAppend( object, clazz, builder, testTransients );
385            }
386            return builder.toHashCode();
387        }
388    
389    
390        /**
391         * <p>
392         * Appends the fields and values defined by the given object of the given
393         * <code>Class</code>.
394         * </p>
395         * 
396         * @param object
397         *            the object to append details of
398         * @param clazz
399         *            the class to append details of
400         * @param builder
401         *            the builder to append to
402         * @param useTransients
403         *            whether to use transient fields
404         */
405        private static void reflectionAppend( Object object, Class clazz, HashCodeBuilder builder, boolean useTransients )
406        {
407            Field[] fields = clazz.getDeclaredFields();
408            AccessibleObject.setAccessible( fields, true );
409            for ( int i = 0; i < fields.length; i++ )
410            {
411                Field f = fields[i];
412                if ( ( f.getName().indexOf( '$' ) == -1 ) && ( useTransients || !Modifier.isTransient( f.getModifiers() ) )
413                    && ( !Modifier.isStatic( f.getModifiers() ) ) )
414                {
415                    try
416                    {
417                        builder.append( f.get( object ) );
418                    }
419                    catch ( IllegalAccessException e )
420                    {
421                        // this can't happen. Would get a Security exception instead
422                        // throw a runtime exception in case the impossible happens.
423                        throw new InternalError( "Unexpected IllegalAccessException" );
424                    }
425                }
426            }
427        }
428    
429    
430        // -------------------------------------------------------------------------
431    
432        /**
433         * <p>
434         * Adds the result of super.hashCode() to this builder.
435         * </p>
436         * 
437         * @param superHashCode
438         *            the result of calling <code>super.hashCode()</code>
439         * @return this HashCodeBuilder, used to chain calls.
440         * @since 2.0
441         */
442        public HashCodeBuilder appendSuper( int superHashCode )
443        {
444            iTotal = iTotal * iConstant + superHashCode;
445            return this;
446        }
447    
448    
449        // -------------------------------------------------------------------------
450    
451        /**
452         * <p>
453         * Append a <code>hashCode</code> for an <code>Object</code>.
454         * </p>
455         * 
456         * @param object
457         *            the Object to add to the <code>hashCode</code>
458         * @return this
459         */
460        public HashCodeBuilder append( Object object )
461        {
462            if ( object == null )
463            {
464                iTotal = iTotal * iConstant;
465    
466            }
467            else
468            {
469                if ( object.getClass().isArray() == false )
470                {
471                    // the simple case, not an array, just the element
472                    iTotal = iTotal * iConstant + object.hashCode();
473    
474                }
475                else
476                {
477                    // 'Switch' on type of array, to dispatch to the correct handler
478                    // This handles multi dimensional arrays
479                    if ( object instanceof long[] )
480                    {
481                        append( ( long[] ) object );
482                    }
483                    else if ( object instanceof int[] )
484                    {
485                        append( ( int[] ) object );
486                    }
487                    else if ( object instanceof short[] )
488                    {
489                        append( ( short[] ) object );
490                    }
491                    else if ( object instanceof char[] )
492                    {
493                        append( ( char[] ) object );
494                    }
495                    else if ( object instanceof byte[] )
496                    {
497                        append( ( byte[] ) object );
498                    }
499                    else if ( object instanceof double[] )
500                    {
501                        append( ( double[] ) object );
502                    }
503                    else if ( object instanceof float[] )
504                    {
505                        append( ( float[] ) object );
506                    }
507                    else if ( object instanceof boolean[] )
508                    {
509                        append( ( boolean[] ) object );
510                    }
511                    else
512                    {
513                        // Not an array of primitives
514                        append( ( Object[] ) object );
515                    }
516                }
517            }
518            return this;
519        }
520    
521    
522        /**
523         * <p>
524         * Append a <code>hashCode</code> for a <code>long</code>.
525         * </p>
526         * 
527         * @param value
528         *            the long to add to the <code>hashCode</code>
529         * @return this
530         */
531        public HashCodeBuilder append( long value )
532        {
533            iTotal = iTotal * iConstant + ( ( int ) ( value ^ ( value >> 32 ) ) );
534            return this;
535        }
536    
537    
538        /**
539         * <p>
540         * Append a <code>hashCode</code> for an <code>int</code>.
541         * </p>
542         * 
543         * @param value
544         *            the int to add to the <code>hashCode</code>
545         * @return this
546         */
547        public HashCodeBuilder append( int value )
548        {
549            iTotal = iTotal * iConstant + value;
550            return this;
551        }
552    
553    
554        /**
555         * <p>
556         * Append a <code>hashCode</code> for a <code>short</code>.
557         * </p>
558         * 
559         * @param value
560         *            the short to add to the <code>hashCode</code>
561         * @return this
562         */
563        public HashCodeBuilder append( short value )
564        {
565            iTotal = iTotal * iConstant + value;
566            return this;
567        }
568    
569    
570        /**
571         * <p>
572         * Append a <code>hashCode</code> for a <code>char</code>.
573         * </p>
574         * 
575         * @param value
576         *            the char to add to the <code>hashCode</code>
577         * @return this
578         */
579        public HashCodeBuilder append( char value )
580        {
581            iTotal = iTotal * iConstant + value;
582            return this;
583        }
584    
585    
586        /**
587         * <p>
588         * Append a <code>hashCode</code> for a <code>byte</code>.
589         * </p>
590         * 
591         * @param value
592         *            the byte to add to the <code>hashCode</code>
593         * @return this
594         */
595        public HashCodeBuilder append( byte value )
596        {
597            iTotal = iTotal * iConstant + value;
598            return this;
599        }
600    
601    
602        /**
603         * <p>
604         * Append a <code>hashCode</code> for a <code>double</code>.
605         * </p>
606         * 
607         * @param value
608         *            the double to add to the <code>hashCode</code>
609         * @return this
610         */
611        public HashCodeBuilder append( double value )
612        {
613            return append( Double.doubleToLongBits( value ) );
614        }
615    
616    
617        /**
618         * <p>
619         * Append a <code>hashCode</code> for a <code>float</code>.
620         * </p>
621         * 
622         * @param value
623         *            the float to add to the <code>hashCode</code>
624         * @return this
625         */
626        public HashCodeBuilder append( float value )
627        {
628            iTotal = iTotal * iConstant + Float.floatToIntBits( value );
629            return this;
630        }
631    
632    
633        /**
634         * <p>
635         * Append a <code>hashCode</code> for a <code>boolean</code>.
636         * </p>
637         * <p>
638         * This adds <code>iConstant * 1</code> to the <code>hashCode</code> and
639         * not a <code>1231</code> or <code>1237</code> as done in
640         * java.lang.Boolean. This is in accordance with the Effective Java design.
641         * </p>
642         * 
643         * @param value
644         *            the boolean to add to the <code>hashCode</code>
645         * @return this
646         */
647        public HashCodeBuilder append( boolean value )
648        {
649            iTotal = iTotal * iConstant + ( value ? 0 : 1 );
650            return this;
651        }
652    
653    
654        /**
655         * <p>
656         * Append a <code>hashCode</code> for an <code>Object</code> array.
657         * </p>
658         * 
659         * @param array
660         *            the array to add to the <code>hashCode</code>
661         * @return this
662         */
663        public HashCodeBuilder append( Object[] array )
664        {
665            if ( array == null )
666            {
667                iTotal = iTotal * iConstant;
668            }
669            else
670            {
671                for ( int i = 0; i < array.length; i++ )
672                {
673                    append( array[i] );
674                }
675            }
676            return this;
677        }
678    
679    
680        /**
681         * <p>
682         * Append a <code>hashCode</code> for a <code>long</code> array.
683         * </p>
684         * 
685         * @param array
686         *            the array to add to the <code>hashCode</code>
687         * @return this
688         */
689        public HashCodeBuilder append( long[] array )
690        {
691            if ( array == null )
692            {
693                iTotal = iTotal * iConstant;
694            }
695            else
696            {
697                for ( int i = 0; i < array.length; i++ )
698                {
699                    append( array[i] );
700                }
701            }
702            return this;
703        }
704    
705    
706        /**
707         * <p>
708         * Append a <code>hashCode</code> for an <code>int</code> array.
709         * </p>
710         * 
711         * @param array
712         *            the array to add to the <code>hashCode</code>
713         * @return this
714         */
715        public HashCodeBuilder append( int[] array )
716        {
717            if ( array == null )
718            {
719                iTotal = iTotal * iConstant;
720            }
721            else
722            {
723                for ( int i = 0; i < array.length; i++ )
724                {
725                    append( array[i] );
726                }
727            }
728            return this;
729        }
730    
731    
732        /**
733         * <p>
734         * Append a <code>hashCode</code> for a <code>short</code> array.
735         * </p>
736         * 
737         * @param array
738         *            the array to add to the <code>hashCode</code>
739         * @return this
740         */
741        public HashCodeBuilder append( short[] array )
742        {
743            if ( array == null )
744            {
745                iTotal = iTotal * iConstant;
746            }
747            else
748            {
749                for ( int i = 0; i < array.length; i++ )
750                {
751                    append( array[i] );
752                }
753            }
754            return this;
755        }
756    
757    
758        /**
759         * <p>
760         * Append a <code>hashCode</code> for a <code>char</code> array.
761         * </p>
762         * 
763         * @param array
764         *            the array to add to the <code>hashCode</code>
765         * @return this
766         */
767        public HashCodeBuilder append( char[] array )
768        {
769            if ( array == null )
770            {
771                iTotal = iTotal * iConstant;
772            }
773            else
774            {
775                for ( int i = 0; i < array.length; i++ )
776                {
777                    append( array[i] );
778                }
779            }
780            return this;
781        }
782    
783    
784        /**
785         * <p>
786         * Append a <code>hashCode</code> for a <code>byte</code> array.
787         * </p>
788         * 
789         * @param array
790         *            the array to add to the <code>hashCode</code>
791         * @return this
792         */
793        public HashCodeBuilder append( byte[] array )
794        {
795            if ( array == null )
796            {
797                iTotal = iTotal * iConstant;
798            }
799            else
800            {
801                for ( int i = 0; i < array.length; i++ )
802                {
803                    append( array[i] );
804                }
805            }
806            return this;
807        }
808    
809    
810        /**
811         * <p>
812         * Append a <code>hashCode</code> for a <code>double</code> array.
813         * </p>
814         * 
815         * @param array
816         *            the array to add to the <code>hashCode</code>
817         * @return this
818         */
819        public HashCodeBuilder append( double[] array )
820        {
821            if ( array == null )
822            {
823                iTotal = iTotal * iConstant;
824            }
825            else
826            {
827                for ( int i = 0; i < array.length; i++ )
828                {
829                    append( array[i] );
830                }
831            }
832            return this;
833        }
834    
835    
836        /**
837         * <p>
838         * Append a <code>hashCode</code> for a <code>float</code> array.
839         * </p>
840         * 
841         * @param array
842         *            the array to add to the <code>hashCode</code>
843         * @return this
844         */
845        public HashCodeBuilder append( float[] array )
846        {
847            if ( array == null )
848            {
849                iTotal = iTotal * iConstant;
850            }
851            else
852            {
853                for ( int i = 0; i < array.length; i++ )
854                {
855                    append( array[i] );
856                }
857            }
858            return this;
859        }
860    
861    
862        /**
863         * <p>
864         * Append a <code>hashCode</code> for a <code>boolean</code> array.
865         * </p>
866         * 
867         * @param array
868         *            the array to add to the <code>hashCode</code>
869         * @return this
870         */
871        public HashCodeBuilder append( boolean[] array )
872        {
873            if ( array == null )
874            {
875                iTotal = iTotal * iConstant;
876            }
877            else
878            {
879                for ( int i = 0; i < array.length; i++ )
880                {
881                    append( array[i] );
882                }
883            }
884            return this;
885        }
886    
887    
888        /**
889         * <p>
890         * Return the computed <code>hashCode</code>.
891         * </p>
892         * 
893         * @return <code>hashCode</code> based on the fields appended
894         */
895        public int toHashCode()
896        {
897            return iTotal;
898        }
899    
900    }