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