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.util.Collections; 020import java.util.Iterator; 021import java.util.List; 022 023import org.apache.commons.lang3.Validate; 024 025/** 026 * <p> 027 * A {@code DiffResult} contains a collection of the differences between two 028 * {@link Diffable} objects. Typically these differences are displayed using 029 * {@link #toString()} method, which returns a string describing the fields that 030 * differ between the objects. 031 * </p> 032 * <p> 033 * Use a {@link DiffBuilder} to build a {@code DiffResult} comparing two objects. 034 * </p> 035 * @param <T> type of the left and right object. 036 * 037 * @since 3.3 038 */ 039public class DiffResult<T> implements Iterable<Diff<?>> { 040 041 /** 042 * <p> 043 * The {@code String} returned when the objects have no differences: 044 * {@value} 045 * </p> 046 */ 047 public static final String OBJECTS_SAME_STRING = ""; 048 049 private static final String DIFFERS_STRING = "differs from"; 050 051 private final List<Diff<?>> diffs; 052 private final T lhs; 053 private final T rhs; 054 private final ToStringStyle style; 055 056 /** 057 * <p> 058 * Creates a {@link DiffResult} containing the differences between two 059 * objects. 060 * </p> 061 * 062 * @param lhs 063 * the left hand object 064 * @param rhs 065 * the right hand object 066 * @param diffs 067 * the list of differences, may be empty 068 * @param style 069 * the style to use for the {@link #toString()} method. May be 070 * {@code null}, in which case 071 * {@link ToStringStyle#DEFAULT_STYLE} is used 072 * @throws IllegalArgumentException 073 * if {@code lhs}, {@code rhs} or {@code diffs} is {@code null} 074 */ 075 DiffResult(final T lhs, final T rhs, final List<Diff<?>> diffs, 076 final ToStringStyle style) { 077 Validate.notNull(lhs, "Left hand object cannot be null"); 078 Validate.notNull(rhs, "Right hand object cannot be null"); 079 Validate.notNull(diffs, "List of differences cannot be null"); 080 081 this.diffs = diffs; 082 this.lhs = lhs; 083 this.rhs = rhs; 084 085 if (style == null) { 086 this.style = ToStringStyle.DEFAULT_STYLE; 087 } else { 088 this.style = style; 089 } 090 } 091 092 /** 093 * <p>Returns the object the right object has been compared to.</p> 094 * 095 * @return the left object of the diff 096 * @since 3.10 097 */ 098 public T getLeft() { 099 return this.lhs; 100 } 101 102 /** 103 * <p>Returns the object the left object has been compared to.</p> 104 * 105 * @return the right object of the diff 106 * @since 3.10 107 */ 108 public T getRight() { 109 return this.rhs; 110 } 111 112 /** 113 * <p> 114 * Returns an unmodifiable list of {@code Diff}s. The list may be empty if 115 * there were no differences between the objects. 116 * </p> 117 * 118 * @return an unmodifiable list of {@code Diff}s 119 */ 120 public List<Diff<?>> getDiffs() { 121 return Collections.unmodifiableList(diffs); 122 } 123 124 /** 125 * <p> 126 * Returns the number of differences between the two objects. 127 * </p> 128 * 129 * @return the number of differences 130 */ 131 public int getNumberOfDiffs() { 132 return diffs.size(); 133 } 134 135 /** 136 * <p> 137 * Returns the style used by the {@link #toString()} method. 138 * </p> 139 * 140 * @return the style 141 */ 142 public ToStringStyle getToStringStyle() { 143 return style; 144 } 145 146 /** 147 * <p> 148 * Builds a {@code String} description of the differences contained within 149 * this {@code DiffResult}. A {@link ToStringBuilder} is used for each object 150 * and the style of the output is governed by the {@code ToStringStyle} 151 * passed to the constructor. 152 * </p> 153 * 154 * <p> 155 * If there are no differences stored in this list, the method will return 156 * {@link #OBJECTS_SAME_STRING}. Otherwise, using the example given in 157 * {@link Diffable} and {@link ToStringStyle#SHORT_PREFIX_STYLE}, an output 158 * might be: 159 * </p> 160 * 161 * <pre> 162 * Person[name=John Doe,age=32] differs from Person[name=Joe Bloggs,age=26] 163 * </pre> 164 * 165 * <p> 166 * This indicates that the objects differ in name and age, but not in 167 * smoking status. 168 * </p> 169 * 170 * <p> 171 * To use a different {@code ToStringStyle} for an instance of this class, 172 * use {@link #toString(ToStringStyle)}. 173 * </p> 174 * 175 * @return a {@code String} description of the differences. 176 */ 177 @Override 178 public String toString() { 179 return toString(style); 180 } 181 182 /** 183 * <p> 184 * Builds a {@code String} description of the differences contained within 185 * this {@code DiffResult}, using the supplied {@code ToStringStyle}. 186 * </p> 187 * 188 * @param style 189 * the {@code ToStringStyle} to use when outputting the objects 190 * 191 * @return a {@code String} description of the differences. 192 */ 193 public String toString(final ToStringStyle style) { 194 if (diffs.isEmpty()) { 195 return OBJECTS_SAME_STRING; 196 } 197 198 final ToStringBuilder lhsBuilder = new ToStringBuilder(lhs, style); 199 final ToStringBuilder rhsBuilder = new ToStringBuilder(rhs, style); 200 201 for (final Diff<?> diff : diffs) { 202 lhsBuilder.append(diff.getFieldName(), diff.getLeft()); 203 rhsBuilder.append(diff.getFieldName(), diff.getRight()); 204 } 205 206 return String.format("%s %s %s", lhsBuilder.build(), DIFFERS_STRING, 207 rhsBuilder.build()); 208 } 209 210 /** 211 * <p> 212 * Returns an iterator over the {@code Diff} objects contained in this list. 213 * </p> 214 * 215 * @return the iterator 216 */ 217 @Override 218 public Iterator<Diff<?>> iterator() { 219 return diffs.iterator(); 220 } 221}