    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      https://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.lang3.builder;
    018
    019import java.lang.reflect.Type;
    020import java.util.Objects;
    021
    022import org.apache.commons.lang3.ObjectUtils;
    023import org.apache.commons.lang3.reflect.TypeUtils;
    024import org.apache.commons.lang3.tuple.Pair;
    025
    026/**
    027 * A {@link Diff} contains the differences between two {@link Diffable} class
    028 * fields.
    029 *
    030 * <p>
    031 * Typically, {@link Diff}s are retrieved by using a {@link DiffBuilder} to
    032 * produce a {@link DiffResult}, containing the differences between two objects.
    033 * </p>
    034 *
    035 * @param <T>
    036 *            The type of object contained within this {@link Diff}. Differences
    037 *            between primitive objects are stored as their Object wrapper
    038 *            equivalent.
    039 * @since 3.3
    040 */
    041public abstract class Diff<T> extends Pair<T, T> {
    042
    043    private static final long serialVersionUID = 1L;
    044
    045    /** The field type. */
    046    private final Type type;
    047
    048    /** The field name. */
    049    private final String fieldName;
    050
    051    /**
    052     * Constructs a new {@link Diff} for the given field name.
    053     *
    054     * @param fieldName
    055     *            the field name
    056     */
    057    protected Diff(final String fieldName) {
    058        this.fieldName = Objects.requireNonNull(fieldName);
    059        this.type = ObjectUtils.getIfNull(TypeUtils.getTypeArguments(getClass(), Diff.class).get(Diff.class.getTypeParameters()[0]), Object.class);
    060    }
    061
    062    Diff(final String fieldName, final Type type) {
    063        this.fieldName = Objects.requireNonNull(fieldName);
    064        this.type = Objects.requireNonNull(type);
    065    }
    066
    067    /**
    068     * Gets the name of the field.
    069     *
    070     * @return the field name
    071     */
    072    public final String getFieldName() {
    073        return fieldName;
    074    }
    075
    076    /**
    077     * Gets the type of the field.
    078     *
    079     * @return the field type
    080     * @deprecated Unused, will be removed in 4.0.0.
    081     */
    082    @Deprecated
    083    public final Type getType() {
    084        return type;
    085    }
    086
    087    /**
    088     * Throws {@link UnsupportedOperationException}.
    089     *
    090     * @param value
    091     *            ignored
    092     * @return nothing
    093     */
    094    @Override
    095    public final T setValue(final T value) {
    096        throw new UnsupportedOperationException("Cannot alter Diff object.");
    097    }
    098
    099    /**
    100     * Returns a {@link String} representation of the {@link Diff}, with the
    101     * following format:
    102     *
    103     * <pre>
    104     * [fieldname: left-value, right-value]
    105     * </pre>
    106     *
    107     * @return the string representation
    108     */
    109    @Override
    110    public final String toString() {
    111        return String.format("[%s: %s, %s]", fieldName, getLeft(), getRight());
    112    }
    113}