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 *      http://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.defaultIfNull(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}