984 lines
28 KiB
Java
984 lines
28 KiB
Java
/*
|
|
* 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.commons.lang3.builder;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.List;
|
|
|
|
import org.apache.commons.lang3.ArrayUtils;
|
|
import org.apache.commons.lang3.Validate;
|
|
|
|
/**
|
|
* <p>
|
|
* Assists in implementing {@link Diffable#diff(Object)} methods.
|
|
* </p>
|
|
*
|
|
* <p>
|
|
* To use this class, write code as follows:
|
|
* </p>
|
|
*
|
|
* <pre>
|
|
* public class Person implements Diffable<Person> {
|
|
* String name;
|
|
* int age;
|
|
* boolean smoker;
|
|
*
|
|
* ...
|
|
*
|
|
* public DiffResult diff(Person obj) {
|
|
* // No need for null check, as NullPointerException correct if obj is null
|
|
* return new DiffBuilder(this, obj, ToStringStyle.SHORT_PREFIX_STYLE)
|
|
* .append("name", this.name, obj.name)
|
|
* .append("age", this.age, obj.age)
|
|
* .append("smoker", this.smoker, obj.smoker)
|
|
* .build();
|
|
* }
|
|
* }
|
|
* </pre>
|
|
*
|
|
* <p>
|
|
* The {@code ToStringStyle} passed to the constructor is embedded in the
|
|
* returned {@code DiffResult} and influences the style of the
|
|
* {@code DiffResult.toString()} method. This style choice can be overridden by
|
|
* calling {@link DiffResult#toString(ToStringStyle)}.
|
|
* </p>
|
|
*
|
|
* @param <T> type of the left and right object.
|
|
* @see Diffable
|
|
* @see Diff
|
|
* @see DiffResult
|
|
* @see ToStringStyle
|
|
* @since 3.3
|
|
*/
|
|
public class DiffBuilder<T> implements Builder<DiffResult<T>> {
|
|
|
|
private final List<Diff<?>> diffs;
|
|
private final boolean objectsTriviallyEqual;
|
|
private final T left;
|
|
private final T right;
|
|
private final ToStringStyle style;
|
|
|
|
/**
|
|
* <p>
|
|
* Constructs a builder for the specified objects with the specified style.
|
|
* </p>
|
|
*
|
|
* <p>
|
|
* If {@code lhs == rhs} or {@code lhs.equals(rhs)} then the builder will
|
|
* not evaluate any calls to {@code append(...)} and will return an empty
|
|
* {@link DiffResult} when {@link #build()} is executed.
|
|
* </p>
|
|
*
|
|
* @param lhs
|
|
* {@code this} object
|
|
* @param rhs
|
|
* the object to diff against
|
|
* @param style
|
|
* the style will use when outputting the objects, {@code null}
|
|
* uses the default
|
|
* @param testTriviallyEqual
|
|
* If true, this will test if lhs and rhs are the same or equal.
|
|
* All of the append(fieldName, lhs, rhs) methods will abort
|
|
* without creating a field {@link Diff} if the trivially equal
|
|
* test is enabled and returns true. The result of this test
|
|
* is never changed throughout the life of this {@link DiffBuilder}.
|
|
* @throws IllegalArgumentException
|
|
* if {@code lhs} or {@code rhs} is {@code null}
|
|
* @since 3.4
|
|
*/
|
|
public DiffBuilder(final T lhs, final T rhs,
|
|
final ToStringStyle style, final boolean testTriviallyEqual) {
|
|
|
|
Validate.notNull(lhs, "lhs");
|
|
Validate.notNull(rhs, "rhs");
|
|
|
|
this.diffs = new ArrayList<>();
|
|
this.left = lhs;
|
|
this.right = rhs;
|
|
this.style = style;
|
|
|
|
// Don't compare any fields if objects equal
|
|
this.objectsTriviallyEqual = testTriviallyEqual && (lhs == rhs || lhs.equals(rhs));
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Constructs a builder for the specified objects with the specified style.
|
|
* </p>
|
|
*
|
|
* <p>
|
|
* If {@code lhs == rhs} or {@code lhs.equals(rhs)} then the builder will
|
|
* not evaluate any calls to {@code append(...)} and will return an empty
|
|
* {@link DiffResult} when {@link #build()} is executed.
|
|
* </p>
|
|
*
|
|
* <p>
|
|
* This delegates to {@link #DiffBuilder(Object, Object, ToStringStyle, boolean)}
|
|
* with the testTriviallyEqual flag enabled.
|
|
* </p>
|
|
*
|
|
* @param lhs
|
|
* {@code this} object
|
|
* @param rhs
|
|
* the object to diff against
|
|
* @param style
|
|
* the style will use when outputting the objects, {@code null}
|
|
* uses the default
|
|
* @throws IllegalArgumentException
|
|
* if {@code lhs} or {@code rhs} is {@code null}
|
|
*/
|
|
public DiffBuilder(final T lhs, final T rhs,
|
|
final ToStringStyle style) {
|
|
|
|
this(lhs, rhs, style, true);
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code boolean}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code boolean}
|
|
* @param rhs
|
|
* the right hand {@code boolean}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final boolean lhs,
|
|
final boolean rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (lhs != rhs) {
|
|
diffs.add(new Diff<Boolean>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Boolean getLeft() {
|
|
return Boolean.valueOf(lhs);
|
|
}
|
|
|
|
@Override
|
|
public Boolean getRight() {
|
|
return Boolean.valueOf(rhs);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code boolean[]}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code boolean[]}
|
|
* @param rhs
|
|
* the right hand {@code boolean[]}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final boolean[] lhs,
|
|
final boolean[] rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (!Arrays.equals(lhs, rhs)) {
|
|
diffs.add(new Diff<Boolean[]>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Boolean[] getLeft() {
|
|
return ArrayUtils.toObject(lhs);
|
|
}
|
|
|
|
@Override
|
|
public Boolean[] getRight() {
|
|
return ArrayUtils.toObject(rhs);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code byte}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code byte}
|
|
* @param rhs
|
|
* the right hand {@code byte}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final byte lhs,
|
|
final byte rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (lhs != rhs) {
|
|
diffs.add(new Diff<Byte>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Byte getLeft() {
|
|
return Byte.valueOf(lhs);
|
|
}
|
|
|
|
@Override
|
|
public Byte getRight() {
|
|
return Byte.valueOf(rhs);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code byte[]}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code byte[]}
|
|
* @param rhs
|
|
* the right hand {@code byte[]}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final byte[] lhs,
|
|
final byte[] rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (!Arrays.equals(lhs, rhs)) {
|
|
diffs.add(new Diff<Byte[]>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Byte[] getLeft() {
|
|
return ArrayUtils.toObject(lhs);
|
|
}
|
|
|
|
@Override
|
|
public Byte[] getRight() {
|
|
return ArrayUtils.toObject(rhs);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code char}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code char}
|
|
* @param rhs
|
|
* the right hand {@code char}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final char lhs,
|
|
final char rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (lhs != rhs) {
|
|
diffs.add(new Diff<Character>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Character getLeft() {
|
|
return Character.valueOf(lhs);
|
|
}
|
|
|
|
@Override
|
|
public Character getRight() {
|
|
return Character.valueOf(rhs);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code char[]}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code char[]}
|
|
* @param rhs
|
|
* the right hand {@code char[]}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final char[] lhs,
|
|
final char[] rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (!Arrays.equals(lhs, rhs)) {
|
|
diffs.add(new Diff<Character[]>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Character[] getLeft() {
|
|
return ArrayUtils.toObject(lhs);
|
|
}
|
|
|
|
@Override
|
|
public Character[] getRight() {
|
|
return ArrayUtils.toObject(rhs);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code double}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code double}
|
|
* @param rhs
|
|
* the right hand {@code double}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final double lhs,
|
|
final double rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (Double.doubleToLongBits(lhs) != Double.doubleToLongBits(rhs)) {
|
|
diffs.add(new Diff<Double>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Double getLeft() {
|
|
return Double.valueOf(lhs);
|
|
}
|
|
|
|
@Override
|
|
public Double getRight() {
|
|
return Double.valueOf(rhs);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code double[]}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code double[]}
|
|
* @param rhs
|
|
* the right hand {@code double[]}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final double[] lhs,
|
|
final double[] rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (!Arrays.equals(lhs, rhs)) {
|
|
diffs.add(new Diff<Double[]>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Double[] getLeft() {
|
|
return ArrayUtils.toObject(lhs);
|
|
}
|
|
|
|
@Override
|
|
public Double[] getRight() {
|
|
return ArrayUtils.toObject(rhs);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code float}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code float}
|
|
* @param rhs
|
|
* the right hand {@code float}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final float lhs,
|
|
final float rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (Float.floatToIntBits(lhs) != Float.floatToIntBits(rhs)) {
|
|
diffs.add(new Diff<Float>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Float getLeft() {
|
|
return Float.valueOf(lhs);
|
|
}
|
|
|
|
@Override
|
|
public Float getRight() {
|
|
return Float.valueOf(rhs);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code float[]}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code float[]}
|
|
* @param rhs
|
|
* the right hand {@code float[]}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final float[] lhs,
|
|
final float[] rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (!Arrays.equals(lhs, rhs)) {
|
|
diffs.add(new Diff<Float[]>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Float[] getLeft() {
|
|
return ArrayUtils.toObject(lhs);
|
|
}
|
|
|
|
@Override
|
|
public Float[] getRight() {
|
|
return ArrayUtils.toObject(rhs);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code int}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code int}
|
|
* @param rhs
|
|
* the right hand {@code int}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final int lhs,
|
|
final int rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (lhs != rhs) {
|
|
diffs.add(new Diff<Integer>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Integer getLeft() {
|
|
return Integer.valueOf(lhs);
|
|
}
|
|
|
|
@Override
|
|
public Integer getRight() {
|
|
return Integer.valueOf(rhs);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code int[]}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code int[]}
|
|
* @param rhs
|
|
* the right hand {@code int[]}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final int[] lhs,
|
|
final int[] rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (!Arrays.equals(lhs, rhs)) {
|
|
diffs.add(new Diff<Integer[]>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Integer[] getLeft() {
|
|
return ArrayUtils.toObject(lhs);
|
|
}
|
|
|
|
@Override
|
|
public Integer[] getRight() {
|
|
return ArrayUtils.toObject(rhs);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code long}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code long}
|
|
* @param rhs
|
|
* the right hand {@code long}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final long lhs,
|
|
final long rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (lhs != rhs) {
|
|
diffs.add(new Diff<Long>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Long getLeft() {
|
|
return Long.valueOf(lhs);
|
|
}
|
|
|
|
@Override
|
|
public Long getRight() {
|
|
return Long.valueOf(rhs);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code long[]}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code long[]}
|
|
* @param rhs
|
|
* the right hand {@code long[]}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final long[] lhs,
|
|
final long[] rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (!Arrays.equals(lhs, rhs)) {
|
|
diffs.add(new Diff<Long[]>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Long[] getLeft() {
|
|
return ArrayUtils.toObject(lhs);
|
|
}
|
|
|
|
@Override
|
|
public Long[] getRight() {
|
|
return ArrayUtils.toObject(rhs);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code short}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code short}
|
|
* @param rhs
|
|
* the right hand {@code short}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final short lhs,
|
|
final short rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (lhs != rhs) {
|
|
diffs.add(new Diff<Short>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Short getLeft() {
|
|
return Short.valueOf(lhs);
|
|
}
|
|
|
|
@Override
|
|
public Short getRight() {
|
|
return Short.valueOf(rhs);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code short[]}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code short[]}
|
|
* @param rhs
|
|
* the right hand {@code short[]}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final short[] lhs,
|
|
final short[] rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (!Arrays.equals(lhs, rhs)) {
|
|
diffs.add(new Diff<Short[]>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Short[] getLeft() {
|
|
return ArrayUtils.toObject(lhs);
|
|
}
|
|
|
|
@Override
|
|
public Short[] getRight() {
|
|
return ArrayUtils.toObject(rhs);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code Objects}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code Object}
|
|
* @param rhs
|
|
* the right hand {@code Object}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final Object lhs,
|
|
final Object rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
if (lhs == rhs) {
|
|
return this;
|
|
}
|
|
|
|
final Object objectToTest;
|
|
if (lhs != null) {
|
|
objectToTest = lhs;
|
|
} else {
|
|
// rhs cannot be null, as lhs != rhs
|
|
objectToTest = rhs;
|
|
}
|
|
|
|
if (objectToTest.getClass().isArray()) {
|
|
if (objectToTest instanceof boolean[]) {
|
|
return append(fieldName, (boolean[]) lhs, (boolean[]) rhs);
|
|
}
|
|
if (objectToTest instanceof byte[]) {
|
|
return append(fieldName, (byte[]) lhs, (byte[]) rhs);
|
|
}
|
|
if (objectToTest instanceof char[]) {
|
|
return append(fieldName, (char[]) lhs, (char[]) rhs);
|
|
}
|
|
if (objectToTest instanceof double[]) {
|
|
return append(fieldName, (double[]) lhs, (double[]) rhs);
|
|
}
|
|
if (objectToTest instanceof float[]) {
|
|
return append(fieldName, (float[]) lhs, (float[]) rhs);
|
|
}
|
|
if (objectToTest instanceof int[]) {
|
|
return append(fieldName, (int[]) lhs, (int[]) rhs);
|
|
}
|
|
if (objectToTest instanceof long[]) {
|
|
return append(fieldName, (long[]) lhs, (long[]) rhs);
|
|
}
|
|
if (objectToTest instanceof short[]) {
|
|
return append(fieldName, (short[]) lhs, (short[]) rhs);
|
|
}
|
|
|
|
return append(fieldName, (Object[]) lhs, (Object[]) rhs);
|
|
}
|
|
|
|
// Not array type
|
|
if (lhs != null && lhs.equals(rhs)) {
|
|
return this;
|
|
}
|
|
|
|
diffs.add(new Diff<Object>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Object getLeft() {
|
|
return lhs;
|
|
}
|
|
|
|
@Override
|
|
public Object getRight() {
|
|
return rhs;
|
|
}
|
|
});
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Test if two {@code Object[]}s are equal.
|
|
* </p>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param lhs
|
|
* the left hand {@code Object[]}
|
|
* @param rhs
|
|
* the right hand {@code Object[]}
|
|
* @return this
|
|
* @throws IllegalArgumentException
|
|
* if field name is {@code null}
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName, final Object[] lhs,
|
|
final Object[] rhs) {
|
|
validateFieldNameNotNull(fieldName);
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
|
|
if (!Arrays.equals(lhs, rhs)) {
|
|
diffs.add(new Diff<Object[]>(fieldName) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public Object[] getLeft() {
|
|
return lhs;
|
|
}
|
|
|
|
@Override
|
|
public Object[] getRight() {
|
|
return rhs;
|
|
}
|
|
});
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Append diffs from another {@code DiffResult}.
|
|
* </p>
|
|
*
|
|
* <p>
|
|
* This method is useful if you want to compare properties which are
|
|
* themselves Diffable and would like to know which specific part of
|
|
* it is different.
|
|
* </p>
|
|
*
|
|
* <pre>
|
|
* public class Person implements Diffable<Person> {
|
|
* String name;
|
|
* Address address; // implements Diffable<Address>
|
|
*
|
|
* ...
|
|
*
|
|
* public DiffResult diff(Person obj) {
|
|
* return new DiffBuilder(this, obj, ToStringStyle.SHORT_PREFIX_STYLE)
|
|
* .append("name", this.name, obj.name)
|
|
* .append("address", this.address.diff(obj.address))
|
|
* .build();
|
|
* }
|
|
* }
|
|
* </pre>
|
|
*
|
|
* @param fieldName
|
|
* the field name
|
|
* @param diffResult
|
|
* the {@code DiffResult} to append
|
|
* @return this
|
|
* @throws NullPointerException if field name is {@code null}
|
|
* @since 3.5
|
|
*/
|
|
public DiffBuilder<T> append(final String fieldName,
|
|
final DiffResult<T> diffResult) {
|
|
validateFieldNameNotNull(fieldName);
|
|
Validate.notNull(diffResult, "diffResult");
|
|
if (objectsTriviallyEqual) {
|
|
return this;
|
|
}
|
|
|
|
for (final Diff<?> diff : diffResult.getDiffs()) {
|
|
append(fieldName + "." + diff.getFieldName(),
|
|
diff.getLeft(), diff.getRight());
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Builds a {@link DiffResult} based on the differences appended to this
|
|
* builder.
|
|
* </p>
|
|
*
|
|
* @return a {@code DiffResult} containing the differences between the two
|
|
* objects.
|
|
*/
|
|
@Override
|
|
public DiffResult<T> build() {
|
|
return new DiffResult<>(left, right, diffs, style);
|
|
}
|
|
|
|
private void validateFieldNameNotNull(final String fieldName) {
|
|
Validate.notNull(fieldName, "fieldName");
|
|
}
|
|
|
|
}
|