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;
020
021import org.apache.commons.lang3.ObjectUtils;
022import org.apache.commons.lang3.reflect.TypeUtils;
023import org.apache.commons.lang3.tuple.Pair;
024
025/**
026 * <p>
027 * A {@code Diff} contains the differences between two {@link Diffable} class
028 * fields.
029 * </p>
030 *
031 * <p>
032 * Typically, {@code Diff}s are retrieved by using a {@link DiffBuilder} to
033 * produce a {@link DiffResult}, containing the differences between two objects.
034 * </p>
035 *
036 *
037 * @param <T>
038 *            The type of object contained within this {@code Diff}. Differences
039 *            between primitive objects are stored as their Object wrapper
040 *            equivalent.
041 * @since 3.3
042 */
043public abstract class Diff<T> extends Pair<T, T> {
044
045    private static final long serialVersionUID = 1L;
046
047    private final Type type;
048    private final String fieldName;
049
050    /**
051     * <p>
052     * Constructs a new {@code Diff} for the given field name.
053     * </p>
054     *
055     * @param fieldName
056     *            the name of the field
057     */
058    protected Diff(final String fieldName) {
059        this.type = ObjectUtils.defaultIfNull(
060                TypeUtils.getTypeArguments(getClass(), Diff.class).get(
061                        Diff.class.getTypeParameters()[0]), Object.class);
062        this.fieldName = fieldName;
063    }
064
065    /**
066     * <p>
067     * Returns the type of the field.
068     * </p>
069     *
070     * @return the field type
071     */
072    public final Type getType() {
073        return type;
074    }
075
076    /**
077     * <p>
078     * Returns the name of the field.
079     * </p>
080     *
081     * @return the field name
082     */
083    public final String getFieldName() {
084        return fieldName;
085    }
086
087    /**
088     * <p>
089     * Returns a {@code String} representation of the {@code Diff}, with the
090     * following format:</p>
091     *
092     * <pre>
093     * [fieldname: left-value, right-value]
094     * </pre>
095     *
096     *
097     * @return the string representation
098     */
099    @Override
100    public final String toString() {
101        return String.format("[%s: %s, %s]", fieldName, getLeft(), getRight());
102    }
103
104    /**
105     * <p>
106     * Throws {@code UnsupportedOperationException}.
107     * </p>
108     *
109     * @param value
110     *            ignored
111     * @return nothing
112     */
113    @Override
114    public final T setValue(final T value) {
115        throw new UnsupportedOperationException("Cannot alter Diff object.");
116    }
117}