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