| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| package org.apache.directory.shared.ldap.util; |
| |
| |
| import java.lang.reflect.AccessibleObject; |
| import java.lang.reflect.Field; |
| import java.lang.reflect.Modifier; |
| |
| import org.apache.directory.shared.i18n.I18n; |
| |
| |
| /** |
| * <p> |
| * Assists in implementing {@link Object#equals(Object)} methods. |
| * </p> |
| * <p> |
| * This class provides methods to build a good equals method for any class. It |
| * follows rules laid out in <a |
| * href="http://java.sun.com/docs/books/effective/index.html">Effective Java</a> , |
| * by Joshua Bloch. In particular the rule for comparing <code>doubles</code>, |
| * <code>floats</code>, and arrays can be tricky. Also, making sure that |
| * <code>equals()</code> and <code>hashCode()</code> are consistent can be |
| * difficult. |
| * </p> |
| * <p> |
| * Two Objects that compare as equals must generate the same hash code, but two |
| * Objects with the same hash code do not have to be equal. |
| * </p> |
| * <p> |
| * All relevant fields should be included in the calculation of equals. Derived |
| * fields may be ignored. In particular, any field used in generating a hash |
| * code must be used in the equals method, and vice versa. |
| * </p> |
| * <p> |
| * Typical use for the code is as follows: |
| * </p> |
| * |
| * <pre> |
| * public boolean equals( Object o ) |
| * { |
| * if ( !( o instanceof MyClass ) ) |
| * { |
| * return false; |
| * } |
| * MyClass rhs = ( MyClass ) o; |
| * return new EqualsBuilder().appendSuper( super.equals( o ) ).append( field1, rhs.field1 ) |
| * .append( field2, rhs.field2 ).append( field3, rhs.field3 ).isEquals(); |
| * } |
| * </pre> |
| * |
| * <p> |
| * Alternatively, there is a method that uses reflection to determine the fields |
| * to test. Because these fields are usually private, the method, |
| * <code>reflectionEquals</code>, uses |
| * <code>AccessibleObject.setAccessible</code> to change the visibility of the |
| * fields. This will fail under a security manager, unless the appropriate |
| * permissions are set up correctly. It is also slower than testing explicitly. |
| * </p> |
| * <p> |
| * A typical invocation for this method would look like: |
| * </p> |
| * |
| * <pre> |
| * public boolean equals( Object o ) |
| * { |
| * return EqualsBuilder.reflectionEquals( this, o ); |
| * } |
| * </pre> |
| * |
| * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> |
| */ |
| public class EqualsBuilder |
| { |
| |
| /** |
| * If the fields tested are equals. The default value is <code>true</code>. |
| */ |
| private boolean isEquals = true; |
| |
| |
| /** |
| * <p> |
| * Constructor for EqualsBuilder. |
| * </p> |
| * <p> |
| * Starts off assuming that equals is <code>true</code>. |
| * </p> |
| * |
| * @see Object#equals(Object) |
| */ |
| public EqualsBuilder() |
| { |
| // do nothing for now. |
| } |
| |
| |
| // ------------------------------------------------------------------------- |
| |
| /** |
| * <p> |
| * This method uses reflection to determine if the two <code>Object</code>s |
| * are equal. |
| * </p> |
| * <p> |
| * It uses <code>AccessibleObject.setAccessible</code> to gain access to |
| * private fields. This means that it will throw a security exception if run |
| * under a security manager, if the permissions are not set up correctly. It |
| * is also not as efficient as testing explicitly. |
| * </p> |
| * <p> |
| * Transient members will be not be tested, as they are likely derived |
| * fields, and not part of the value of the Object. |
| * </p> |
| * <p> |
| * Static fields will not be tested. Superclass fields will be included. |
| * </p> |
| * |
| * @param lhs |
| * <code>this</code> object |
| * @param rhs |
| * the other object |
| * @return <code>true</code> if the two Objects have tested equals. |
| */ |
| public static boolean reflectionEquals( Object lhs, Object rhs ) |
| { |
| return reflectionEquals( lhs, rhs, false, null ); |
| } |
| |
| |
| /** |
| * <p> |
| * This method uses reflection to determine if the two <code>Object</code>s |
| * are equal. |
| * </p> |
| * <p> |
| * It uses <code>AccessibleObject.setAccessible</code> to gain access to |
| * private fields. This means that it will throw a security exception if run |
| * under a security manager, if the permissions are not set up correctly. It |
| * is also not as efficient as testing explicitly. |
| * </p> |
| * <p> |
| * If the TestTransients parameter is set to <code>true</code>, transient |
| * members will be tested, otherwise they are ignored, as they are likely |
| * derived fields, and not part of the value of the <code>Object</code>. |
| * </p> |
| * <p> |
| * Static fields will not be tested. Superclass fields will be included. |
| * </p> |
| * |
| * @param lhs |
| * <code>this</code> object |
| * @param rhs |
| * the other object |
| * @param testTransients |
| * whether to include transient fields |
| * @return <code>true</code> if the two Objects have tested equals. |
| */ |
| public static boolean reflectionEquals( Object lhs, Object rhs, boolean testTransients ) |
| { |
| return reflectionEquals( lhs, rhs, testTransients, null ); |
| } |
| |
| |
| /** |
| * <p> |
| * This method uses reflection to determine if the two <code>Object</code>s |
| * are equal. |
| * </p> |
| * <p> |
| * It uses <code>AccessibleObject.setAccessible</code> to gain access to |
| * private fields. This means that it will throw a security exception if run |
| * under a security manager, if the permissions are not set up correctly. It |
| * is also not as efficient as testing explicitly. |
| * </p> |
| * <p> |
| * If the testTransients parameter is set to <code>true</code>, transient |
| * members will be tested, otherwise they are ignored, as they are likely |
| * derived fields, and not part of the value of the <code>Object</code>. |
| * </p> |
| * <p> |
| * Static fields will not be included. Superclass fields will be appended up |
| * to and including the specified superclass. A null superclass is treated |
| * as java.lang.Object. |
| * </p> |
| * |
| * @param lhs |
| * <code>this</code> object |
| * @param rhs |
| * the other object |
| * @param testTransients |
| * whether to include transient fields |
| * @param reflectUpToClass |
| * the superclass to reflect up to (inclusive), may be |
| * <code>null</code> |
| * @return <code>true</code> if the two Objects have tested equals. |
| * @since 2.0 |
| */ |
| public static boolean reflectionEquals( Object lhs, Object rhs, boolean testTransients, Class reflectUpToClass ) |
| { |
| if ( lhs == rhs ) |
| { |
| return true; |
| } |
| if ( lhs == null || rhs == null ) |
| { |
| return false; |
| } |
| // Find the leaf class since there may be transients in the leaf |
| // class or in classes between the leaf and root. |
| // If we are not testing transients or a subclass has no ivars, |
| // then a subclass can test equals to a superclass. |
| Class lhsClass = lhs.getClass(); |
| Class rhsClass = rhs.getClass(); |
| Class testClass; |
| if ( lhsClass.isInstance( rhs ) ) |
| { |
| testClass = lhsClass; |
| if ( !rhsClass.isInstance( lhs ) ) |
| { |
| // rhsClass is a subclass of lhsClass |
| testClass = rhsClass; |
| } |
| } |
| else if ( rhsClass.isInstance( lhs ) ) |
| { |
| testClass = rhsClass; |
| if ( !lhsClass.isInstance( rhs ) ) |
| { |
| // lhsClass is a subclass of rhsClass |
| testClass = lhsClass; |
| } |
| } |
| else |
| { |
| // The two classes are not related. |
| return false; |
| } |
| EqualsBuilder equalsBuilder = new EqualsBuilder(); |
| try |
| { |
| reflectionAppend( lhs, rhs, testClass, equalsBuilder, testTransients ); |
| while ( testClass.getSuperclass() != null && testClass != reflectUpToClass ) |
| { |
| testClass = testClass.getSuperclass(); |
| reflectionAppend( lhs, rhs, testClass, equalsBuilder, testTransients ); |
| } |
| } |
| catch ( IllegalArgumentException e ) |
| { |
| // In this case, we tried to test a subclass vs. a superclass and |
| // the subclass has ivars or the ivars are transient and |
| // we are testing transients. |
| // If a subclass has ivars that we are trying to test them, we get |
| // an |
| // exception and we know that the objects are not equal. |
| return false; |
| } |
| return equalsBuilder.isEquals(); |
| } |
| |
| |
| /** |
| * <p> |
| * Appends the fields and values defined by the given object of the given |
| * Class. |
| * </p> |
| * |
| * @param lhs |
| * the left hand object |
| * @param rhs |
| * the right hand object |
| * @param clazz |
| * the class to append details of |
| * @param builder |
| * the builder to append to |
| * @param useTransients |
| * whether to test transient fields |
| */ |
| private static void reflectionAppend( Object lhs, Object rhs, Class clazz, EqualsBuilder builder, |
| boolean useTransients ) |
| { |
| Field[] fields = clazz.getDeclaredFields(); |
| AccessibleObject.setAccessible( fields, true ); |
| for ( int i = 0; i < fields.length && builder.isEquals; i++ ) |
| { |
| Field f = fields[i]; |
| if ( ( f.getName().indexOf( '$' ) == -1 ) && ( useTransients || !Modifier.isTransient( f.getModifiers() ) ) |
| && ( !Modifier.isStatic( f.getModifiers() ) ) ) |
| { |
| try |
| { |
| builder.append( f.get( lhs ), f.get( rhs ) ); |
| } |
| catch ( IllegalAccessException e ) |
| { |
| // this can't happen. Would get a Security exception instead |
| // throw a runtime exception in case the impossible happens. |
| throw new InternalError( I18n.err( I18n.ERR_04355 ) ); |
| } |
| } |
| } |
| } |
| |
| |
| // ------------------------------------------------------------------------- |
| |
| /** |
| * <p> |
| * Adds the result of <code>super.equals()</code> to this builder. |
| * </p> |
| * |
| * @param superEquals |
| * the result of calling <code>super.equals()</code> |
| * @return EqualsBuilder - used to chain calls. |
| * @since 2.0 |
| */ |
| public EqualsBuilder appendSuper( boolean superEquals ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| isEquals = superEquals; |
| return this; |
| } |
| |
| |
| // ------------------------------------------------------------------------- |
| |
| /** |
| * <p> |
| * Test if two <code>Object</code>s are equal using their |
| * <code>equals</code> method. |
| * </p> |
| * |
| * @param lhs |
| * the left hand object |
| * @param rhs |
| * the right hand object |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( Object lhs, Object rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| if ( lhs == rhs ) |
| { |
| return this; |
| } |
| if ( lhs == null || rhs == null ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| Class lhsClass = lhs.getClass(); |
| if ( !lhsClass.isArray() ) |
| { |
| // The simple case, not an array, just test the element |
| isEquals = lhs.equals( rhs ); |
| } |
| else if ( lhs.getClass() != rhs.getClass() ) |
| { |
| // Here when we compare different dimensions, for example: a |
| // boolean[][] to a boolean[] |
| this.setEquals( false ); |
| } |
| // 'Switch' on type of array, to dispatch to the correct handler |
| // This handles multi dimensional arrays of the same depth |
| else if ( lhs instanceof long[] ) |
| { |
| append( ( long[] ) lhs, ( long[] ) rhs ); |
| } |
| else if ( lhs instanceof int[] ) |
| { |
| append( ( int[] ) lhs, ( int[] ) rhs ); |
| } |
| else if ( lhs instanceof short[] ) |
| { |
| append( ( short[] ) lhs, ( short[] ) rhs ); |
| } |
| else if ( lhs instanceof char[] ) |
| { |
| append( ( char[] ) lhs, ( char[] ) rhs ); |
| } |
| else if ( lhs instanceof byte[] ) |
| { |
| append( ( byte[] ) lhs, ( byte[] ) rhs ); |
| } |
| else if ( lhs instanceof double[] ) |
| { |
| append( ( double[] ) lhs, ( double[] ) rhs ); |
| } |
| else if ( lhs instanceof float[] ) |
| { |
| append( ( float[] ) lhs, ( float[] ) rhs ); |
| } |
| else if ( lhs instanceof boolean[] ) |
| { |
| append( ( boolean[] ) lhs, ( boolean[] ) rhs ); |
| } |
| else |
| { |
| // Not an array of primitives |
| append( ( Object[] ) lhs, ( Object[] ) rhs ); |
| } |
| return this; |
| } |
| |
| |
| /** |
| * <p> |
| * Test if two <code>long</code> s are equal. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>long</code> |
| * @param rhs |
| * the right hand <code>long</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( long lhs, long rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| isEquals = ( lhs == rhs ); |
| return this; |
| } |
| |
| |
| /** |
| * <p> |
| * Test if two <code>int</code>s are equal. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>int</code> |
| * @param rhs |
| * the right hand <code>int</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( int lhs, int rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| isEquals = ( lhs == rhs ); |
| return this; |
| } |
| |
| |
| /** |
| * <p> |
| * Test if two <code>short</code>s are equal. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>short</code> |
| * @param rhs |
| * the right hand <code>short</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( short lhs, short rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| isEquals = ( lhs == rhs ); |
| return this; |
| } |
| |
| |
| /** |
| * <p> |
| * Test if two <code>char</code>s are equal. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>char</code> |
| * @param rhs |
| * the right hand <code>char</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( char lhs, char rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| isEquals = ( lhs == rhs ); |
| return this; |
| } |
| |
| |
| /** |
| * <p> |
| * Test if two <code>byte</code>s are equal. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>byte</code> |
| * @param rhs |
| * the right hand <code>byte</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( byte lhs, byte rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| isEquals = ( lhs == rhs ); |
| return this; |
| } |
| |
| |
| /** |
| * <p> |
| * Test if two <code>double</code>s are equal by testing that the pattern |
| * of bits returned by <code>doubleToLong</code> are equal. |
| * </p> |
| * <p> |
| * This handles NaNs, Infinities, and <code>-0.0</code>. |
| * </p> |
| * <p> |
| * It is compatible with the hash code generated by |
| * <code>HashCodeBuilder</code>. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>double</code> |
| * @param rhs |
| * the right hand <code>double</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( double lhs, double rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| return append( Double.doubleToLongBits( lhs ), Double.doubleToLongBits( rhs ) ); |
| } |
| |
| |
| /** |
| * <p> |
| * Test if two <code>float</code>s are equal byt testing that the pattern |
| * of bits returned by doubleToLong are equal. |
| * </p> |
| * <p> |
| * This handles NaNs, Infinities, and <code>-0.0</code>. |
| * </p> |
| * <p> |
| * It is compatible with the hash code generated by |
| * <code>HashCodeBuilder</code>. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>float</code> |
| * @param rhs |
| * the right hand <code>float</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( float lhs, float rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| return append( Float.floatToIntBits( lhs ), Float.floatToIntBits( rhs ) ); |
| } |
| |
| |
| /** |
| * <p> |
| * Test if two <code>booleans</code>s are equal. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>boolean</code> |
| * @param rhs |
| * the right hand <code>boolean</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( boolean lhs, boolean rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| isEquals = ( lhs == rhs ); |
| return this; |
| } |
| |
| |
| /** |
| * <p> |
| * Performs a deep comparison of two <code>Object</code> arrays. |
| * </p> |
| * <p> |
| * This also will be called for the top level of multi-dimensional, ragged, |
| * and multi-typed arrays. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>Object[]</code> |
| * @param rhs |
| * the right hand <code>Object[]</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( Object[] lhs, Object[] rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| if ( lhs == rhs ) |
| { |
| return this; |
| } |
| if ( lhs == null || rhs == null ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| if ( lhs.length != rhs.length ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| for ( int i = 0; i < lhs.length && isEquals; ++i ) |
| { |
| append( lhs[i], rhs[i] ); |
| } |
| return this; |
| } |
| |
| |
| /** |
| * <p> |
| * Deep comparison of array of <code>long</code>. Length and all values |
| * are compared. |
| * </p> |
| * <p> |
| * The method {@link #append(long, long)} is used. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>long[]</code> |
| * @param rhs |
| * the right hand <code>long[]</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( long[] lhs, long[] rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| if ( lhs == rhs ) |
| { |
| return this; |
| } |
| if ( lhs == null || rhs == null ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| if ( lhs.length != rhs.length ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| for ( int i = 0; i < lhs.length && isEquals; ++i ) |
| { |
| append( lhs[i], rhs[i] ); |
| } |
| return this; |
| } |
| |
| |
| /** |
| * <p> |
| * Deep comparison of array of <code>int</code>. Length and all values |
| * are compared. |
| * </p> |
| * <p> |
| * The method {@link #append(int, int)} is used. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>int[]</code> |
| * @param rhs |
| * the right hand <code>int[]</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( int[] lhs, int[] rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| if ( lhs == rhs ) |
| { |
| return this; |
| } |
| if ( lhs == null || rhs == null ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| if ( lhs.length != rhs.length ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| for ( int i = 0; i < lhs.length && isEquals; ++i ) |
| { |
| append( lhs[i], rhs[i] ); |
| } |
| return this; |
| } |
| |
| |
| /** |
| * <p> |
| * Deep comparison of array of <code>short</code>. Length and all values |
| * are compared. |
| * </p> |
| * <p> |
| * The method {@link #append(short, short)} is used. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>short[]</code> |
| * @param rhs |
| * the right hand <code>short[]</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( short[] lhs, short[] rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| if ( lhs == rhs ) |
| { |
| return this; |
| } |
| if ( lhs == null || rhs == null ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| if ( lhs.length != rhs.length ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| for ( int i = 0; i < lhs.length && isEquals; ++i ) |
| { |
| append( lhs[i], rhs[i] ); |
| } |
| return this; |
| } |
| |
| |
| /** |
| * <p> |
| * Deep comparison of array of <code>char</code>. Length and all values |
| * are compared. |
| * </p> |
| * <p> |
| * The method {@link #append(char, char)} is used. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>char[]</code> |
| * @param rhs |
| * the right hand <code>char[]</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( char[] lhs, char[] rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| if ( lhs == rhs ) |
| { |
| return this; |
| } |
| if ( lhs == null || rhs == null ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| if ( lhs.length != rhs.length ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| for ( int i = 0; i < lhs.length && isEquals; ++i ) |
| { |
| append( lhs[i], rhs[i] ); |
| } |
| return this; |
| } |
| |
| |
| /** |
| * <p> |
| * Deep comparison of array of <code>byte</code>. Length and all values |
| * are compared. |
| * </p> |
| * <p> |
| * The method {@link #append(byte, byte)} is used. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>byte[]</code> |
| * @param rhs |
| * the right hand <code>byte[]</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( byte[] lhs, byte[] rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| if ( lhs == rhs ) |
| { |
| return this; |
| } |
| if ( lhs == null || rhs == null ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| if ( lhs.length != rhs.length ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| for ( int i = 0; i < lhs.length && isEquals; ++i ) |
| { |
| append( lhs[i], rhs[i] ); |
| } |
| return this; |
| } |
| |
| |
| /** |
| * <p> |
| * Deep comparison of array of <code>double</code>. Length and all values |
| * are compared. |
| * </p> |
| * <p> |
| * The method {@link #append(double, double)} is used. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>double[]</code> |
| * @param rhs |
| * the right hand <code>double[]</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( double[] lhs, double[] rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| if ( lhs == rhs ) |
| { |
| return this; |
| } |
| if ( lhs == null || rhs == null ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| if ( lhs.length != rhs.length ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| for ( int i = 0; i < lhs.length && isEquals; ++i ) |
| { |
| append( lhs[i], rhs[i] ); |
| } |
| return this; |
| } |
| |
| |
| /** |
| * <p> |
| * Deep comparison of array of <code>float</code>. Length and all values |
| * are compared. |
| * </p> |
| * <p> |
| * The method {@link #append(float, float)} is used. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>float[]</code> |
| * @param rhs |
| * the right hand <code>float[]</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( float[] lhs, float[] rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| if ( lhs == rhs ) |
| { |
| return this; |
| } |
| if ( lhs == null || rhs == null ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| if ( lhs.length != rhs.length ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| for ( int i = 0; i < lhs.length && isEquals; ++i ) |
| { |
| append( lhs[i], rhs[i] ); |
| } |
| return this; |
| } |
| |
| |
| /** |
| * <p> |
| * Deep comparison of array of <code>boolean</code>. Length and all |
| * values are compared. |
| * </p> |
| * <p> |
| * The method {@link #append(boolean, boolean)} is used. |
| * </p> |
| * |
| * @param lhs |
| * the left hand <code>boolean[]</code> |
| * @param rhs |
| * the right hand <code>boolean[]</code> |
| * @return EqualsBuilder - used to chain calls. |
| */ |
| public EqualsBuilder append( boolean[] lhs, boolean[] rhs ) |
| { |
| if ( isEquals == false ) |
| { |
| return this; |
| } |
| if ( lhs == rhs ) |
| { |
| return this; |
| } |
| if ( lhs == null || rhs == null ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| if ( lhs.length != rhs.length ) |
| { |
| this.setEquals( false ); |
| return this; |
| } |
| for ( int i = 0; i < lhs.length && isEquals; ++i ) |
| { |
| append( lhs[i], rhs[i] ); |
| } |
| return this; |
| } |
| |
| |
| /** |
| * <p> |
| * Returns <code>true</code> if the fields that have been checked are all |
| * equal. |
| * </p> |
| * |
| * @return boolean |
| */ |
| public boolean isEquals() |
| { |
| return this.isEquals; |
| } |
| |
| |
| /** |
| * Sets the <code>isEquals</code> value. |
| * |
| * @param isEquals |
| * The value to set. |
| */ |
| protected void setEquals( boolean isEquals ) |
| { |
| this.isEquals = isEquals; |
| } |
| } |