1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.dbunit.assertion;
22
23 import java.util.Arrays;
24
25 import org.dbunit.dataset.Column;
26 import org.dbunit.dataset.ColumnFilterTable;
27 import org.dbunit.dataset.Columns;
28 import org.dbunit.dataset.DataSetException;
29 import org.dbunit.dataset.ITable;
30 import org.dbunit.dataset.ITableMetaData;
31 import org.dbunit.dataset.NoSuchColumnException;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35
36
37
38
39
40
41
42
43 public class DefaultFailureHandler implements FailureHandler
44 {
45
46
47
48 private static final Logger logger = LoggerFactory.getLogger(DefaultFailureHandler.class);
49
50
51 private String[] _additionalColumnInfo;
52
53 private FailureFactory failureFactory = new DefaultFailureFactory();
54
55
56
57
58 public DefaultFailureHandler()
59 {
60 super();
61 }
62
63
64
65
66
67
68 public DefaultFailureHandler(Column[] additionalColumnInfo)
69 {
70 super();
71
72
73 if (additionalColumnInfo != null) {
74 this._additionalColumnInfo = Columns.getColumnNames(additionalColumnInfo);
75 }
76 }
77
78
79
80
81
82
83 public DefaultFailureHandler(String[] additionalColumnInfo)
84 {
85 super();
86 this._additionalColumnInfo = additionalColumnInfo;
87 }
88
89
90
91
92
93
94 public void setFailureFactory(FailureFactory failureFactory)
95 {
96 if (failureFactory == null) {
97 throw new NullPointerException(
98 "The parameter 'failureFactory' must not be null");
99 }
100 this.failureFactory = failureFactory;
101 }
102
103 public Error createFailure(String message, String expected, String actual)
104 {
105 return this.failureFactory.createFailure(message, expected, actual);
106 }
107
108 public Error createFailure(String message)
109 {
110 return this.failureFactory.createFailure(message);
111 }
112
113 public String getAdditionalInfo(ITable expectedTable, ITable actualTable,
114 int row, String columnName)
115 {
116
117 String additionalInfo = buildAdditionalColumnInfo(expectedTable, actualTable, row);
118 return additionalInfo;
119 }
120
121 private String buildAdditionalColumnInfo(ITable expectedTable, ITable actualTable, int rowIndex)
122 {
123 if(logger.isDebugEnabled())
124 logger.debug("buildAdditionalColumnInfo(expectedTable={}, actualTable={}, rowIndex={}, " +
125 "additionalColumnInfo={}) - start",
126 new Object[] {expectedTable, actualTable, new Integer(rowIndex), _additionalColumnInfo} );
127
128
129 if(_additionalColumnInfo == null || _additionalColumnInfo.length <= 0) {
130 return null;
131 }
132
133 String additionalInfo = "";
134 for (int j = 0; j < _additionalColumnInfo.length; j++) {
135 String columnName = _additionalColumnInfo[j];
136
137 try
138 {
139
140
141 ITable expectedTableForCol = getTableForColumn(expectedTable, columnName);
142 ITable actualTableForCol = getTableForColumn(actualTable, columnName);
143
144 Object expectedKeyValue = expectedTableForCol.getValue(rowIndex, columnName);
145 Object actualKeyValue = actualTableForCol.getValue(rowIndex, columnName);
146 additionalInfo += " ('" + columnName + "': expected=<"+expectedKeyValue+">, actual=<"+actualKeyValue+">)";
147 }
148 catch (DataSetException e)
149 {
150 String msg = "Exception creating more info for column '"+columnName + "'";
151 msg += ": " + e.getClass().getName() + ": " + e.getMessage();
152 logger.info(msg, e);
153 additionalInfo += " (!!!!! " + msg + ")";
154 }
155 }
156
157 if(additionalInfo.length()>0)
158 {
159 additionalInfo = "Additional row info:" + additionalInfo;
160 return additionalInfo;
161 }
162 else
163 {
164 return null;
165 }
166
167 }
168
169
170
171
172
173
174
175 private ITable getTableForColumn(ITable table, String columnName) throws DataSetException
176 {
177 ITableMetaData tableMetaData = table.getTableMetaData();
178 try
179 {
180 tableMetaData.getColumnIndex(columnName);
181
182
183 return table;
184 }
185 catch(NoSuchColumnException e)
186 {
187
188 if(table instanceof ColumnFilterTable)
189 {
190 ITableMetaData originalMetaData = ((ColumnFilterTable)table).getOriginalMetaData();
191 originalMetaData.getColumnIndex(columnName);
192
193
194 return table;
195 }
196 else
197 {
198
199 throw e;
200 }
201 }
202 }
203
204 public void handle(Difference diff)
205 {
206 String msg = buildMessage(diff);
207
208 Error err = this.createFailure(msg,
209 String.valueOf(diff.getExpectedValue()), String.valueOf(diff.getActualValue()));
210
211 throw err;
212 }
213
214 protected String buildMessage(Difference diff)
215 {
216 int row = diff.getRowIndex();
217 String columnName = diff.getColumnName();
218 String tableName = diff.getExpectedTable().getTableMetaData().getTableName();
219
220
221
222 String msg = "value (table=" + tableName + ", row=" + row + ", col=" + columnName;
223
224 String additionalInfo = this.getAdditionalInfo(
225 diff.getExpectedTable(), diff.getActualTable(), row, columnName);
226 if (additionalInfo != null && !additionalInfo.trim().equals(""))
227 msg += ", " + additionalInfo;
228 msg += ")";
229
230 return msg;
231 }
232
233 public String toString()
234 {
235 StringBuffer sb = new StringBuffer();
236 sb.append(DefaultFailureHandler.class.getName()).append("[");
237 sb.append("_additionalColumnInfo=").append(
238 _additionalColumnInfo==null ? "null" : Arrays.asList(_additionalColumnInfo).toString());
239 sb.append("]");
240 return sb.toString();
241 }
242
243
244
245
246
247
248
249
250
251
252
253
254 public static class DefaultFailureFactory implements FailureFactory
255 {
256 public Error createFailure(String message, String expected, String actual)
257 {
258
259 return new DbComparisonFailure(message, expected, actual);
260 }
261
262 public Error createFailure(String message)
263 {
264
265 return new DbAssertionFailedError(message);
266 }
267 }
268
269
270
271 }