001// ______________________________________________________
002// Generated by sql2java - https://github.com/10km/sql2java-2-6-7 (custom branch) 
003// modified by guyadong from
004// sql2java original version https://sourceforge.net/projects/sql2java/ 
005// JDBC driver used at code generation time: com.mysql.jdbc.Driver
006// template: comparetobuilder.java.vm
007// ______________________________________________________
008package net.gdface.facelog.db;
009
010/*
011 * Copyright 2002-2005 The Apache Software Foundation.
012 * 
013 * Licensed under the Apache License, Version 2.0 (the "License");
014 * you may not use this file except in compliance with the License.
015 * You may obtain a copy of the License at
016 * 
017 *      http://www.apache.org/licenses/LICENSE-2.0
018 * 
019 * Unless required by applicable law or agreed to in writing, software
020 * distributed under the License is distributed on an "AS IS" BASIS,
021 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
022 * See the License for the specific language governing permissions and
023 * limitations under the License.
024 */
025
026import java.lang.reflect.AccessibleObject;
027import java.lang.reflect.Field;
028import java.lang.reflect.Modifier;
029import java.util.Comparator;
030
031/** 
032 * Assists in implementing {@link java.lang.Comparable#compareTo(Object)} methods.
033 *
034 * <p>It is consistent with <code>equals(Object)</code> and
035 * <code>hashcode()</code> built with {@link EqualsBuilder} and
036 * {@link HashCodeBuilder}.</p>
037 *
038 * <p>Two Objects that compare equal using <code>equals(Object)</code> should normally
039 * also compare equal using <code>compareTo(Object)</code>.</p>
040 *
041 * <p>All relevant fields should be included in the calculation of the
042 * comparison. Derived fields may be ignored. The same fields, in the same
043 * order, should be used in both <code>compareTo(Object)</code> and
044 * <code>equals(Object)</code>.</p>
045 *
046 * <p>To use this class write code as follows:</p>
047 *
048 * <pre>
049 * public class MyClass {
050 *   String field1;
051 *   int field2;
052 *   boolean field3;
053 *
054 *   ...
055 *
056 *   public int compareTo(Object o) {
057 *     MyClass myClass = (MyClass) o;
058 *     return new CompareToBuilder()
059 *       .appendSuper(super.compareTo(o)
060 *       .append(this.field1, myClass.field1)
061 *       .append(this.field2, myClass.field2)
062 *       .append(this.field3, myClass.field3)
063 *       .toComparison();
064 *   }
065 * }
066 * </pre>
067 *
068 * <p>Alternatively, there is are {@link #reflectionCompare reflectionCompare} method that uses
069 * reflection to determine the fields to append. Because fields can be private,
070 * <code>reflectionCompare</code> uses {@link java.lang.reflect.AccessibleObject#setAccessible(boolean)} to
071 * bypass normal access control checks. This will fail under a security manager,
072 * unless the appropriate permissions are set up correctly. It is also
073 * slower than appending explicitly.</p>
074 *
075 * <p>A typical implementation of <code>compareTo(Object)</code> using
076 * <code>reflectionCompare</code> looks like:</p>
077
078 * <pre>
079 * public int compareTo(Object o) {
080 *   return CompareToBuilder.reflectionCompare(this, o);
081 * }
082 * </pre>
083 *
084 * @see java.lang.Comparable
085 * @see java.lang.Object#equals(Object)
086 * @see java.lang.Object#hashCode()
087 * @see EqualsBuilder
088 * @see HashCodeBuilder
089 * @author <a href="mailto:steve.downey@netfolio.com">Steve Downey</a>
090 * @author Stephen Colebourne
091 * @author Gary Gregory
092 * @author Pete Gieser
093 * @since 1.0
094 * @version $Id: CompareToBuilder.java 161243 2005-04-14 04:30:28Z ggregory $
095 */
096public class CompareToBuilder {
097    
098    /**
099     * Current state of the comparison as appended fields are checked.
100     */
101    private int comparison;
102
103    /**
104     * <p>Constructor for CompareToBuilder.</p>
105     *
106     * <p>Starts off assuming that the objects are equal. Multiple calls are 
107     * then made to the various append methods, followed by a call to 
108     * {@link #toComparison} to get the result.</p>
109     */
110    public CompareToBuilder() {
111        super();
112        comparison = 0;
113    }
114
115    //-----------------------------------------------------------------------
116    /** 
117     * <p>Compares two <code>Object</code>s via reflection.</p>
118     *
119     * <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
120     * is used to bypass normal access control checks. This will fail under a 
121     * security manager unless the appropriate permissions are set.</p>
122     *
123     * <ul>
124     * <li>Static fields will not be compared</li>
125     * <li>Transient members will be not be compared, as they are likely derived
126     *     fields</li>
127     * <li>Superclass fields will be compared</li>
128     * </ul>
129     *
130     * <p>If both <code>lhs</code> and <code>rhs</code> are <code>null</code>,
131     * they are considered equal.</p>
132     *
133     * @param lhs  left-hand object
134     * @param rhs  right-hand object
135     * @return a negative integer, zero, or a positive integer as <code>lhs</code>
136     *  is less than, equal to, or greater than <code>rhs</code>
137     * @throws NullPointerException  if either (but not both) parameters are
138     *  <code>null</code>
139     * @throws ClassCastException  if <code>rhs</code> is not assignment-compatible
140     *  with <code>lhs</code>
141     */
142    public static int reflectionCompare(Object lhs, Object rhs) {
143        return reflectionCompare(lhs, rhs, false, null);
144    }
145
146    /**
147     * <p>Compares two <code>Object</code>s via reflection.</p>
148     *
149     * <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
150     * is used to bypass normal access control checks. This will fail under a 
151     * security manager unless the appropriate permissions are set.</p>
152     *
153     * <ul>
154     * <li>Static fields will not be compared</li>
155     * <li>If <code>compareTransients</code> is <code>true</code>,
156     *     compares transient members.  Otherwise ignores them, as they
157     *     are likely derived fields.</li>
158     * <li>Superclass fields will be compared</li>
159     * </ul>
160     *
161     * <p>If both <code>lhs</code> and <code>rhs</code> are <code>null</code>,
162     * they are considered equal.</p>
163     *
164     * @param lhs  left-hand object
165     * @param rhs  right-hand object
166     * @param compareTransients  whether to compare transient fields
167     * @return a negative integer, zero, or a positive integer as <code>lhs</code>
168     *  is less than, equal to, or greater than <code>rhs</code>
169     * @throws NullPointerException  if either <code>lhs</code> or <code>rhs</code>
170     *  (but not both) is <code>null</code>
171     * @throws ClassCastException  if <code>rhs</code> is not assignment-compatible
172     *  with <code>lhs</code>
173     */
174    public static int reflectionCompare(Object lhs, Object rhs, boolean compareTransients) {
175        return reflectionCompare(lhs, rhs, compareTransients, null);
176    }
177
178    /**
179     * <p>Compares two <code>Object</code>s via reflection.</p>
180     *
181     * <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
182     * is used to bypass normal access control checks. This will fail under a 
183     * security manager unless the appropriate permissions are set.</p>
184     *
185     * <ul>
186     * <li>Static fields will not be compared</li>
187     * <li>If the <code>compareTransients</code> is <code>true</code>,
188     *     compares transient members.  Otherwise ignores them, as they
189     *     are likely derived fields.</li>
190     * <li>Compares superclass fields up to and including <code>reflectUpToClass</code>.
191     *     If <code>reflectUpToClass</code> is <code>null</code>, compares all superclass fields.</li>
192     * </ul>
193     *
194     * <p>If both <code>lhs</code> and <code>rhs</code> are <code>null</code>,
195     * they are considered equal.</p>
196     *
197     * @param lhs  left-hand object
198     * @param rhs  right-hand object
199     * @param compareTransients  whether to compare transient fields
200     * @param reflectUpToClass  last superclass for which fields are compared
201     * @return a negative integer, zero, or a positive integer as <code>lhs</code>
202     *  is less than, equal to, or greater than <code>rhs</code>
203     * @throws NullPointerException  if either <code>lhs</code> or <code>rhs</code>
204     *  (but not both) is <code>null</code>
205     * @throws ClassCastException  if <code>rhs</code> is not assignment-compatible
206     *  with <code>lhs</code>
207     * @since 2.0
208     */
209    public static int reflectionCompare(Object lhs, Object rhs, boolean compareTransients, Class reflectUpToClass) {
210        if (lhs == rhs) {
211            return 0;
212        }
213        if (lhs == null || rhs == null) {
214            throw new NullPointerException();
215        }
216        Class lhsClazz = lhs.getClass();
217        if (!lhsClazz.isInstance(rhs)) {
218            throw new ClassCastException();
219        }
220        CompareToBuilder compareToBuilder = new CompareToBuilder();
221        reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients);
222        while (lhsClazz.getSuperclass() != null && lhsClazz != reflectUpToClass) {
223            lhsClazz = lhsClazz.getSuperclass();
224            reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients);
225        }
226        return compareToBuilder.toComparison();
227    }
228
229    /**
230     * <p>Appends to <code>builder</code> the comparison of <code>lhs</code>
231     * to <code>rhs</code> using the fields defined in <code>clazz</code>.</p>
232     * 
233     * @param lhs  left-hand object
234     * @param rhs  right-hand object
235     * @param clazz  <code>Class</code> that defines fields to be compared
236     * @param builder  <code>CompareToBuilder</code> to append to
237     * @param useTransients  whether to compare transient fields
238     */
239    private static void reflectionAppend(
240        Object lhs,
241        Object rhs,
242        Class clazz,
243        CompareToBuilder builder,
244        boolean useTransients) {
245        
246        Field[] fields = clazz.getDeclaredFields();
247        AccessibleObject.setAccessible(fields, true);
248        for (int i = 0; i < fields.length && builder.comparison == 0; i++) {
249            Field f = fields[i];
250            if ((f.getName().indexOf('$') == -1)
251                && (useTransients || !Modifier.isTransient(f.getModifiers()))
252                && (!Modifier.isStatic(f.getModifiers()))) {
253                try {
254                    builder.append(f.get(lhs), f.get(rhs));
255                } catch (IllegalAccessException e) {
256                    // This can't happen. Would get a Security exception instead.
257                    // Throw a runtime exception in case the impossible happens.
258                    throw new InternalError("Unexpected IllegalAccessException");
259                }
260            }
261        }
262    }
263
264    //-----------------------------------------------------------------------
265    /**
266     * <p>Appends to the <code>builder</code> the <code>compareTo(Object)</code>
267     * result of the superclass.</p>
268     *
269     * @param superCompareTo  result of calling <code>super.compareTo(Object)</code>
270     * @return this - used to chain append calls
271     * @since 2.0
272     */
273    public CompareToBuilder appendSuper(int superCompareTo) {
274        if (comparison != 0) {
275            return this;
276        }
277        comparison = superCompareTo;
278        return this;
279    }
280    
281    //-----------------------------------------------------------------------
282    /**
283     * <p>Appends to the <code>builder</code> the comparison of
284     * two <code>Object</code>s.</p>
285     *
286     * <ol>
287     * <li>Check if <code>lhs == rhs</code></li>
288     * <li>Check if either <code>lhs</code> or <code>rhs</code> is <code>null</code>,
289     *     a <code>null</code> object is less than a non-<code>null</code> object</li>
290     * <li>Check the object contents</li>
291     * </ol>
292     * 
293     * <p><code>lhs</code> must either be an array or implement {@link Comparable}.</p>
294     *
295     * @param lhs  left-hand object
296     * @param rhs  right-hand object
297     * @return this - used to chain append calls
298     * @throws ClassCastException  if <code>rhs</code> is not assignment-compatible
299     *  with <code>lhs</code>
300     */
301    public CompareToBuilder append(Object lhs, Object rhs) {
302        return append(lhs, rhs, null);
303    }
304
305    /**
306     * <p>Appends to the <code>builder</code> the comparison of
307     * two <code>Object</code>s.</p>
308     *
309     * <ol>
310     * <li>Check if <code>lhs == rhs</code></li>
311     * <li>Check if either <code>lhs</code> or <code>rhs</code> is <code>null</code>,
312     *     a <code>null</code> object is less than a non-<code>null</code> object</li>
313     * <li>Check the object contents</li>
314     * </ol>
315     *
316     * <p>If <code>lhs</code> is an array, array comparison methods will be used.
317     * Otherwise <code>comparator</code> will be used to compare the objects.
318     * If <code>comparator</code> is <code>null</code>, <code>lhs</code> must
319     * implement {@link Comparable} instead.</p>
320     *
321     * @param lhs  left-hand object
322     * @param rhs  right-hand object
323     * @param comparator  <code>Comparator</code> used to compare the objects,
324     *  <code>null</code> means treat lhs as <code>Comparable</code>
325     * @return this - used to chain append calls
326     * @throws ClassCastException  if <code>rhs</code> is not assignment-compatible
327     *  with <code>lhs</code>
328     * @since 2.0
329     */
330    public CompareToBuilder append(Object lhs, Object rhs, Comparator comparator) {
331        if (comparison != 0) {
332            return this;
333        }
334        if (lhs == rhs) {
335            return this;
336        }
337        if (lhs == null) {
338            comparison = -1;
339            return this;
340        }
341        if (rhs == null) {
342            comparison = +1;
343            return this;
344        }
345        if (lhs.getClass().isArray()) {
346            // switch on type of array, to dispatch to the correct handler
347            // handles multi dimensional arrays
348            // throws a ClassCastException if rhs is not the correct array type
349            if (lhs instanceof long[]) {
350                append((long[]) lhs, (long[]) rhs);
351            } else if (lhs instanceof int[]) {
352                append((int[]) lhs, (int[]) rhs);
353            } else if (lhs instanceof short[]) {
354                append((short[]) lhs, (short[]) rhs);
355            } else if (lhs instanceof char[]) {
356                append((char[]) lhs, (char[]) rhs);
357            } else if (lhs instanceof byte[]) {
358                append((byte[]) lhs, (byte[]) rhs);
359            } else if (lhs instanceof double[]) {
360                append((double[]) lhs, (double[]) rhs);
361            } else if (lhs instanceof float[]) {
362                append((float[]) lhs, (float[]) rhs);
363            } else if (lhs instanceof boolean[]) {
364                append((boolean[]) lhs, (boolean[]) rhs);
365            } else {
366                // not an array of primitives
367                // throws a ClassCastException if rhs is not an array
368                append((Object[]) lhs, (Object[]) rhs, comparator);
369            }
370        } else {
371            // the simple case, not an array, just test the element
372            if (comparator == null) {
373                comparison = ((Comparable) lhs).compareTo(rhs);
374            } else {
375                comparison = comparator.compare(lhs, rhs);
376            }
377        }
378        return this;
379    }
380
381    //-------------------------------------------------------------------------
382    /**
383     * Appends to the <code>builder</code> the comparison of
384     * two <code>long</code>s.
385     *
386     * @param lhs  left-hand value
387     * @param rhs  right-hand value
388     * @return this - used to chain append calls
389     */
390    public CompareToBuilder append(long lhs, long rhs) {
391        if (comparison != 0) {
392            return this;
393        }
394        comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
395        return this;
396    }
397
398    /**
399     * Appends to the <code>builder</code> the comparison of
400     * two <code>int</code>s.
401     *
402     * @param lhs  left-hand value
403     * @param rhs  right-hand value
404     * @return this - used to chain append calls
405     */
406    public CompareToBuilder append(int lhs, int rhs) {
407        if (comparison != 0) {
408            return this;
409        }
410        comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
411        return this;
412    }
413
414    /**
415     * Appends to the <code>builder</code> the comparison of
416     * two <code>short</code>s.
417     * 
418     * @param lhs  left-hand value
419     * @param rhs  right-hand value
420     * @return this - used to chain append calls
421     */
422    public CompareToBuilder append(short lhs, short rhs) {
423        if (comparison != 0) {
424            return this;
425        }
426        comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
427        return this;
428    }
429
430    /**
431     * Appends to the <code>builder</code> the comparison of
432     * two <code>char</code>s.
433     *
434     * @param lhs  left-hand value
435     * @param rhs  right-hand value
436     * @return this - used to chain append calls
437     */
438    public CompareToBuilder append(char lhs, char rhs) {
439        if (comparison != 0) {
440            return this;
441        }
442        comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
443        return this;
444    }
445
446    /**
447     * Appends to the <code>builder</code> the comparison of
448     * two <code>byte</code>s.
449     * 
450     * @param lhs  left-hand value
451     * @param rhs  right-hand value
452     * @return this - used to chain append calls
453     */
454    public CompareToBuilder append(byte lhs, byte rhs) {
455        if (comparison != 0) {
456            return this;
457        }
458        comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
459        return this;
460    }
461
462    /**
463     * <p>Appends to the <code>builder</code> the comparison of
464     * two <code>double</code>s.</p>
465     *
466     * <p>This handles NaNs, Infinities, and <code>-0.0</code>.</p>
467     *
468     * <p>It is compatible with the hash code generated by
469     * <code>HashCodeBuilder</code>.</p>
470     *
471     * @param lhs  left-hand value
472     * @param rhs  right-hand value
473     * @return this - used to chain append calls
474     */
475    public CompareToBuilder append(double lhs, double rhs) {
476        if (comparison != 0) {
477            return this;
478        }
479        comparison = compare(lhs, rhs);
480        return this;
481    }
482
483    /**
484     * <p>Appends to the <code>builder</code> the comparison of
485     * two <code>float</code>s.</p>
486     *
487     * <p>This handles NaNs, Infinities, and <code>-0.0</code>.</p>
488     *
489     * <p>It is compatible with the hash code generated by
490     * <code>HashCodeBuilder</code>.</p>
491     *
492     * @param lhs  left-hand value
493     * @param rhs  right-hand value
494     * @return this - used to chain append calls
495     */
496    public CompareToBuilder append(float lhs, float rhs) {
497        if (comparison != 0) {
498            return this;
499        }
500        comparison = compare(lhs, rhs);
501        return this;
502    }
503
504    /**
505     * Appends to the <code>builder</code> the comparison of
506     * two <code>booleans</code>s.
507     *
508     * @param lhs  left-hand value
509     * @param rhs  right-hand value
510     * @return this - used to chain append calls
511      */
512    public CompareToBuilder append(boolean lhs, boolean rhs) {
513        if (comparison != 0) {
514            return this;
515        }
516        if (lhs == rhs) {
517            return this;
518        }
519        if (lhs == false) {
520            comparison = -1;
521        } else {
522            comparison = +1;
523        }
524        return this;
525    }
526
527    //-----------------------------------------------------------------------
528    /**
529     * <p>Appends to the <code>builder</code> the deep comparison of
530     * two <code>Object</code> arrays.</p>
531     *
532     * <ol>
533     *  <li>Check if arrays are the same using <code>==</code></li>
534     *  <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
535     *  <li>Check array length, a short length array is less than a long length array</li>
536     *  <li>Check array contents element by element using {@link #append(Object, Object, Comparator)}</li>
537     * </ol>
538     *
539     * <p>This method will also will be called for the top level of multi-dimensional,
540     * ragged, and multi-typed arrays.</p>
541     *
542     * @param lhs  left-hand array
543     * @param rhs  right-hand array
544     * @return this - used to chain append calls
545     * @throws ClassCastException  if <code>rhs</code> is not assignment-compatible
546     *  with <code>lhs</code>
547     */
548    public CompareToBuilder append(Object[] lhs, Object[] rhs) {
549        return append(lhs, rhs, null);
550    }
551    
552    /**
553     * <p>Appends to the <code>builder</code> the deep comparison of
554     * two <code>Object</code> arrays.</p>
555     *
556     * <ol>
557     *  <li>Check if arrays are the same using <code>==</code></li>
558     *  <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
559     *  <li>Check array length, a short length array is less than a long length array</li>
560     *  <li>Check array contents element by element using {@link #append(Object, Object, Comparator)}</li>
561     * </ol>
562     *
563     * <p>This method will also will be called for the top level of multi-dimensional,
564     * ragged, and multi-typed arrays.</p>
565     *
566     * @param lhs  left-hand array
567     * @param rhs  right-hand array
568     * @param comparator  <code>Comparator</code> to use to compare the array elements,
569     *  <code>null</code> means to treat <code>lhs</code> elements as <code>Comparable</code>.
570     * @return this - used to chain append calls
571     * @throws ClassCastException  if <code>rhs</code> is not assignment-compatible
572     *  with <code>lhs</code>
573     * @since 2.0
574     */
575    public CompareToBuilder append(Object[] lhs, Object[] rhs, Comparator comparator) {
576        if (comparison != 0) {
577            return this;
578        }
579        if (lhs == rhs) {
580            return this;
581        }
582        if (lhs == null) {
583            comparison = -1;
584            return this;
585        }
586        if (rhs == null) {
587            comparison = +1;
588            return this;
589        }
590        if (lhs.length != rhs.length) {
591            comparison = (lhs.length < rhs.length) ? -1 : +1;
592            return this;
593        }
594        for (int i = 0; i < lhs.length && comparison == 0; i++) {
595            append(lhs[i], rhs[i], comparator);
596        }
597        return this;
598    }
599
600    /**
601     * <p>Appends to the <code>builder</code> the deep comparison of
602     * two <code>long</code> arrays.</p>
603     *
604     * <ol>
605     *  <li>Check if arrays are the same using <code>==</code></li>
606     *  <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
607     *  <li>Check array length, a shorter length array is less than a longer length array</li>
608     *  <li>Check array contents element by element using {@link #append(long, long)}</li>
609     * </ol>
610     *
611     * @param lhs  left-hand array
612     * @param rhs  right-hand array
613     * @return this - used to chain append calls
614     */
615    public CompareToBuilder append(long[] lhs, long[] rhs) {
616        if (comparison != 0) {
617            return this;
618        }
619        if (lhs == rhs) {
620            return this;
621        }
622        if (lhs == null) {
623            comparison = -1;
624            return this;
625        }
626        if (rhs == null) {
627            comparison = +1;
628            return this;
629        }
630        if (lhs.length != rhs.length) {
631            comparison = (lhs.length < rhs.length) ? -1 : +1;
632            return this;
633        }
634        for (int i = 0; i < lhs.length && comparison == 0; i++) {
635            append(lhs[i], rhs[i]);
636        }
637        return this;
638    }
639
640    /**
641     * <p>Appends to the <code>builder</code> the deep comparison of
642     * two <code>int</code> arrays.</p>
643     *
644     * <ol>
645     *  <li>Check if arrays are the same using <code>==</code></li>
646     *  <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
647     *  <li>Check array length, a shorter length array is less than a longer length array</li>
648     *  <li>Check array contents element by element using {@link #append(int, int)}</li>
649     * </ol>
650     *
651     * @param lhs  left-hand array
652     * @param rhs  right-hand array
653     * @return this - used to chain append calls
654     */
655    public CompareToBuilder append(int[] lhs, int[] rhs) {
656        if (comparison != 0) {
657            return this;
658        }
659        if (lhs == rhs) {
660            return this;
661        }
662        if (lhs == null) {
663            comparison = -1;
664            return this;
665        }
666        if (rhs == null) {
667            comparison = +1;
668            return this;
669        }
670        if (lhs.length != rhs.length) {
671            comparison = (lhs.length < rhs.length) ? -1 : +1;
672            return this;
673        }
674        for (int i = 0; i < lhs.length && comparison == 0; i++) {
675            append(lhs[i], rhs[i]);
676        }
677        return this;
678    }
679
680    /**
681     * <p>Appends to the <code>builder</code> the deep comparison of
682     * two <code>short</code> arrays.</p>
683     *
684     * <ol>
685     *  <li>Check if arrays are the same using <code>==</code></li>
686     *  <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
687     *  <li>Check array length, a shorter length array is less than a longer length array</li>
688     *  <li>Check array contents element by element using {@link #append(short, short)}</li>
689     * </ol>
690     *
691     * @param lhs  left-hand array
692     * @param rhs  right-hand array
693     * @return this - used to chain append calls
694     */
695    public CompareToBuilder append(short[] lhs, short[] rhs) {
696        if (comparison != 0) {
697            return this;
698        }
699        if (lhs == rhs) {
700            return this;
701        }
702        if (lhs == null) {
703            comparison = -1;
704            return this;
705        }
706        if (rhs == null) {
707            comparison = +1;
708            return this;
709        }
710        if (lhs.length != rhs.length) {
711            comparison = (lhs.length < rhs.length) ? -1 : +1;
712            return this;
713        }
714        for (int i = 0; i < lhs.length && comparison == 0; i++) {
715            append(lhs[i], rhs[i]);
716        }
717        return this;
718    }
719
720    /**
721     * <p>Appends to the <code>builder</code> the deep comparison of
722     * two <code>char</code> arrays.</p>
723     *
724     * <ol>
725     *  <li>Check if arrays are the same using <code>==</code></li>
726     *  <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
727     *  <li>Check array length, a shorter length array is less than a longer length array</li>
728     *  <li>Check array contents element by element using {@link #append(char, char)}</li>
729     * </ol>
730     *
731     * @param lhs  left-hand array
732     * @param rhs  right-hand array
733     * @return this - used to chain append calls
734     */
735    public CompareToBuilder append(char[] lhs, char[] rhs) {
736        if (comparison != 0) {
737            return this;
738        }
739        if (lhs == rhs) {
740            return this;
741        }
742        if (lhs == null) {
743            comparison = -1;
744            return this;
745        }
746        if (rhs == null) {
747            comparison = +1;
748            return this;
749        }
750        if (lhs.length != rhs.length) {
751            comparison = (lhs.length < rhs.length) ? -1 : +1;
752            return this;
753        }
754        for (int i = 0; i < lhs.length && comparison == 0; i++) {
755            append(lhs[i], rhs[i]);
756        }
757        return this;
758    }
759
760    /**
761     * <p>Appends to the <code>builder</code> the deep comparison of
762     * two <code>byte</code> arrays.</p>
763     *
764     * <ol>
765     *  <li>Check if arrays are the same using <code>==</code></li>
766     *  <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
767     *  <li>Check array length, a shorter length array is less than a longer length array</li>
768     *  <li>Check array contents element by element using {@link #append(byte, byte)}</li>
769     * </ol>
770     *
771     * @param lhs  left-hand array
772     * @param rhs  right-hand array
773     * @return this - used to chain append calls
774     */
775    public CompareToBuilder append(byte[] lhs, byte[] rhs) {
776        if (comparison != 0) {
777            return this;
778        }
779        if (lhs == rhs) {
780            return this;
781        }
782        if (lhs == null) {
783            comparison = -1;
784            return this;
785        }
786        if (rhs == null) {
787            comparison = +1;
788            return this;
789        }
790        if (lhs.length != rhs.length) {
791            comparison = (lhs.length < rhs.length) ? -1 : +1;
792            return this;
793        }
794        for (int i = 0; i < lhs.length && comparison == 0; i++) {
795            append(lhs[i], rhs[i]);
796        }
797        return this;
798    }
799
800    /**
801     * <p>Appends to the <code>builder</code> the deep comparison of
802     * two <code>double</code> arrays.</p>
803     *
804     * <ol>
805     *  <li>Check if arrays are the same using <code>==</code></li>
806     *  <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
807     *  <li>Check array length, a shorter length array is less than a longer length array</li>
808     *  <li>Check array contents element by element using {@link #append(double, double)}</li>
809     * </ol>
810     *
811     * @param lhs  left-hand array
812     * @param rhs  right-hand array
813     * @return this - used to chain append calls
814     */
815    public CompareToBuilder append(double[] lhs, double[] rhs) {
816        if (comparison != 0) {
817            return this;
818        }
819        if (lhs == rhs) {
820            return this;
821        }
822        if (lhs == null) {
823            comparison = -1;
824            return this;
825        }
826        if (rhs == null) {
827            comparison = +1;
828            return this;
829        }
830        if (lhs.length != rhs.length) {
831            comparison = (lhs.length < rhs.length) ? -1 : +1;
832            return this;
833        }
834        for (int i = 0; i < lhs.length && comparison == 0; i++) {
835            append(lhs[i], rhs[i]);
836        }
837        return this;
838    }
839
840    /**
841     * <p>Appends to the <code>builder</code> the deep comparison of
842     * two <code>float</code> arrays.</p>
843     *
844     * <ol>
845     *  <li>Check if arrays are the same using <code>==</code></li>
846     *  <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
847     *  <li>Check array length, a shorter length array is less than a longer length array</li>
848     *  <li>Check array contents element by element using {@link #append(float, float)}</li>
849     * </ol>
850     *
851     * @param lhs  left-hand array
852     * @param rhs  right-hand array
853     * @return this - used to chain append calls
854     */
855    public CompareToBuilder append(float[] lhs, float[] rhs) {
856        if (comparison != 0) {
857            return this;
858        }
859        if (lhs == rhs) {
860            return this;
861        }
862        if (lhs == null) {
863            comparison = -1;
864            return this;
865        }
866        if (rhs == null) {
867            comparison = +1;
868            return this;
869        }
870        if (lhs.length != rhs.length) {
871            comparison = (lhs.length < rhs.length) ? -1 : +1;
872            return this;
873        }
874        for (int i = 0; i < lhs.length && comparison == 0; i++) {
875            append(lhs[i], rhs[i]);
876        }
877        return this;
878    }
879
880    /**
881     * <p>Appends to the <code>builder</code> the deep comparison of
882     * two <code>boolean</code> arrays.</p>
883     *
884     * <ol>
885     *  <li>Check if arrays are the same using <code>==</code></li>
886     *  <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
887     *  <li>Check array length, a shorter length array is less than a longer length array</li>
888     *  <li>Check array contents element by element using {@link #append(boolean, boolean)}</li>
889     * </ol>
890     *
891     * @param lhs  left-hand array
892     * @param rhs  right-hand array
893     * @return this - used to chain append calls
894     */
895    public CompareToBuilder append(boolean[] lhs, boolean[] rhs) {
896        if (comparison != 0) {
897            return this;
898        }
899        if (lhs == rhs) {
900            return this;
901        }
902        if (lhs == null) {
903            comparison = -1;
904            return this;
905        }
906        if (rhs == null) {
907            comparison = +1;
908            return this;
909        }
910        if (lhs.length != rhs.length) {
911            comparison = (lhs.length < rhs.length) ? -1 : +1;
912            return this;
913        }
914        for (int i = 0; i < lhs.length && comparison == 0; i++) {
915            append(lhs[i], rhs[i]);
916        }
917        return this;
918    }
919
920    //-----------------------------------------------------------------------
921    /**
922     * Returns a negative integer, a positive integer, or zero as
923     * the <code>builder</code> has judged the "left-hand" side
924     * as less than, greater than, or equal to the "right-hand"
925     * side.
926     * 
927     * @return final comparison result
928     */
929    public int toComparison() {
930        return comparison;
931    }
932    //-----------------------------------------------------------------------
933    /**
934     * <p>Compares two <code>doubles</code> for order.</p>
935     *
936     * <p>This method is more comprehensive than the standard Java greater
937     * than, less than and equals operators.</p>
938     * <ul>
939     *  <li>It returns <code>-1</code> if the first value is less than the second.</li>
940     *  <li>It returns <code>+1</code> if the first value is greater than the second.</li>
941     *  <li>It returns <code>0</code> if the values are equal.</li>
942     * </ul>
943     *
944     * <p>
945     * The ordering is as follows, largest to smallest:
946     * <ul>
947     *  <li>NaN
948     *  <li>Positive infinity
949     *  <li>Maximum double
950     *  <li>Normal positive numbers
951     *  <li>+0.0
952     *  <li>-0.0
953     *  <li>Normal negative numbers
954     *  <li>Minimum double (<code>-Double.MAX_VALUE</code>)
955     *  <li>Negative infinity
956     * </ul>
957     * </p>
958     *
959     * <p>Comparing <code>NaN</code> with <code>NaN</code> will
960     * return <code>0</code>.</p>
961     * 
962     * @param lhs  the first <code>double</code>
963     * @param rhs  the second <code>double</code>
964     * @return <code>-1</code> if lhs is less, <code>+1</code> if greater,
965     *  <code>0</code> if equal to rhs
966     */
967    private int compare(double lhs, double rhs) {
968        if (lhs < rhs) {
969            return -1;
970        }
971        if (lhs > rhs) {
972            return +1;
973        }
974        // Need to compare bits to handle 0.0 == -0.0 being true
975        // compare should put -0.0 < +0.0
976        // Two NaNs are also == for compare purposes
977        // where NaN == NaN is false
978        long lhsBits = Double.doubleToLongBits(lhs);
979        long rhsBits = Double.doubleToLongBits(rhs);
980        if (lhsBits == rhsBits) {
981            return 0;
982        }
983        // Something exotic! A comparison to NaN or 0.0 vs -0.0
984        // Fortunately NaN's long is > than everything else
985        // Also negzeros bits < poszero
986        // NAN: 9221120237041090560
987        // MAX: 9218868437227405311
988        // NEGZERO: -9223372036854775808
989        if (lhsBits < rhsBits) {
990            return -1;
991        } else {
992            return +1;
993        }
994    }
995    
996    /**
997     * <p>Compares two floats for order.</p>
998     *
999     * <p>This method is more comprehensive than the standard Java greater than,
1000     * less than and equals operators.</p>
1001     * <ul>
1002     *  <li>It returns <code>-1</code> if the first value is less than the second.
1003     *  <li>It returns <code>+1</code> if the first value is greater than the second.
1004     *  <li>It returns <code>0</code> if the values are equal.
1005     * </ul>
1006     *
1007     * <p> The ordering is as follows, largest to smallest:
1008     * <ul>
1009     * <li>NaN
1010     * <li>Positive infinity
1011     * <li>Maximum float
1012     * <li>Normal positive numbers
1013     * <li>+0.0
1014     * <li>-0.0
1015     * <li>Normal negative numbers
1016     * <li>Minimum float (<code>-Float.MAX_VALUE</code>)
1017     * <li>Negative infinity
1018     * </ul>
1019     *
1020     * <p>Comparing <code>NaN</code> with <code>NaN</code> will return
1021     * <code>0</code>.</p>
1022     * 
1023     * @param lhs  the first <code>float</code>
1024     * @param rhs  the second <code>float</code>
1025     * @return <code>-1</code> if lhs is less, <code>+1</code> if greater,
1026     *  <code>0</code> if equal to rhs
1027     */
1028    private int compare(float lhs, float rhs) {
1029        if (lhs < rhs) {
1030            return -1;
1031        }
1032        if (lhs > rhs) {
1033            return +1;
1034        }
1035        //Need to compare bits to handle 0.0 == -0.0 being true
1036        // compare should put -0.0 < +0.0
1037        // Two NaNs are also == for compare purposes
1038        // where NaN == NaN is false
1039        int lhsBits = Float.floatToIntBits(lhs);
1040        int rhsBits = Float.floatToIntBits(rhs);
1041        if (lhsBits == rhsBits) {
1042            return 0;
1043        }
1044        //Something exotic! A comparison to NaN or 0.0 vs -0.0
1045        //Fortunately NaN's int is > than everything else
1046        //Also negzeros bits < poszero
1047        //NAN: 2143289344
1048        //MAX: 2139095039
1049        //NEGZERO: -2147483648
1050        if (lhsBits < rhsBits) {
1051            return -1;
1052        } else {
1053            return +1;
1054        }
1055    }
1056}
1057
1058