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