View Javadoc
1   package org.dbunit.assertion;
2   
3   import java.util.Arrays;
4   import java.util.Collections;
5   import java.util.Map;
6   
7   import org.dbunit.DatabaseUnitException;
8   import org.dbunit.assertion.DbUnitAssert.ComparisonColumn;
9   import org.dbunit.assertion.comparer.value.ValueComparer;
10  import org.dbunit.assertion.comparer.value.ValueComparers;
11  import org.dbunit.dataset.Column;
12  import org.dbunit.dataset.Columns;
13  import org.dbunit.dataset.DataSetException;
14  import org.dbunit.dataset.IDataSet;
15  import org.dbunit.dataset.ITable;
16  import org.dbunit.dataset.ITableMetaData;
17  import org.dbunit.dataset.datatype.DataType;
18  import org.slf4j.Logger;
19  import org.slf4j.LoggerFactory;
20  
21  /**
22   * Base class for DbUnit assert classes containing common methods.
23   *
24   * @author jjensen
25   * @since 2.6
26   */
27  public class DbUnitAssertBase
28  {
29      private final Logger log = LoggerFactory.getLogger(DbUnitAssertBase.class);
30  
31      private FailureFactory junitFailureFactory = getJUnitFailureFactory();
32  
33      /**
34       * @return The default failure handler
35       * @since 2.4
36       */
37      protected FailureHandler getDefaultFailureHandler()
38      {
39          return getDefaultFailureHandler(null);
40      }
41  
42      /**
43       * @return The default failure handler
44       * @since 2.4
45       */
46      protected FailureHandler getDefaultFailureHandler(
47              final Column[] additionalColumnInfo)
48      {
49          final DefaultFailureHandler failureHandler =
50                  new DefaultFailureHandler(additionalColumnInfo);
51          if (junitFailureFactory != null)
52          {
53              failureHandler.setFailureFactory(junitFailureFactory);
54          }
55          return failureHandler;
56      }
57  
58      /**
59       * @return the JUnitFailureFactory if JUnit is on the classpath or
60       *         <code>null</code> if JUnit is not on the classpath.
61       */
62      private FailureFactory getJUnitFailureFactory()
63      {
64          try
65          {
66              Class.forName("junit.framework.Assert");
67              // JUnit available
68              return new JUnitFailureFactory();
69          } catch (final ClassNotFoundException e)
70          {
71              // JUnit not available on the classpath return null
72              log.debug("JUnit does not seem to be on the classpath. " + e);
73          }
74          return null;
75      }
76  
77      /**
78       * @param expectedTableName
79       * @param expectedColumns
80       * @param actualColumns
81       * @param failureHandler
82       *            The {@link FailureHandler} to be used when no datatype can be
83       *            determined
84       * @return The columns to be used for the assertion, including the correct
85       *         datatype
86       * @since 2.4
87       */
88      protected ComparisonColumn[] getComparisonColumns(
89              final String expectedTableName, final Column[] expectedColumns,
90              final Column[] actualColumns, final FailureHandler failureHandler)
91      {
92          final ComparisonColumn[] result =
93                  new ComparisonColumn[expectedColumns.length];
94  
95          for (int j = 0; j < expectedColumns.length; j++)
96          {
97              final Column expectedColumn = expectedColumns[j];
98              final Column actualColumn = actualColumns[j];
99              result[j] = new ComparisonColumn(expectedTableName, expectedColumn,
100                     actualColumn, failureHandler);
101         }
102         return result;
103     }
104 
105     /**
106      * Method to last-minute intercept the comparison of a single expected and
107      * actual value. Designed to be overridden in order to skip cell comparison
108      * by specific cell values.
109      *
110      * @param columnName
111      *            The column being compared
112      * @param expectedValue
113      *            The expected value to be compared
114      * @param actualValue
115      *            The actual value to be compared
116      * @return <code>false</code> always so that the comparison is never skipped
117      * @since 2.4
118      */
119     protected boolean skipCompare(final String columnName,
120             final Object expectedValue, final Object actualValue)
121     {
122         return false;
123     }
124 
125     protected FailureHandler determineFailureHandler(
126             final FailureHandler failureHandler)
127     {
128         final FailureHandler validFailureHandler;
129 
130         if (failureHandler == null)
131         {
132             log.debug("FailureHandler is null. Using default implementation");
133             validFailureHandler = getDefaultFailureHandler();
134         } else
135         {
136             validFailureHandler = failureHandler;
137         }
138 
139         return validFailureHandler;
140     }
141 
142     protected boolean compareRowCounts(final ITable expectedTable,
143             final ITable actualTable, final FailureHandler failureHandler,
144             final String expectedTableName) throws Error
145     {
146         boolean isTablesEmpty;
147 
148         final int expectedRowsCount = expectedTable.getRowCount();
149         int actualRowsCount = 0;
150         boolean skipRowComparison = false;
151         try
152         {
153             actualRowsCount = actualTable.getRowCount();
154         } catch (final UnsupportedOperationException exception)
155         {
156             skipRowComparison = true;
157         }
158 
159         if (skipRowComparison)
160         {
161             isTablesEmpty = false;
162         } else
163         {
164             if (expectedRowsCount != actualRowsCount)
165             {
166                 final String msg =
167                         "row count (table=" + expectedTableName + ")";
168                 final Error error = failureHandler.createFailure(msg,
169                         String.valueOf(expectedRowsCount),
170                         String.valueOf(actualRowsCount));
171                 log.error(error.toString());
172                 throw error;
173             }
174 
175             // if both tables are empty, it is not necessary to compare columns,
176             // as such comparison can fail if column metadata is different
177             // (which could occurs when comparing empty tables)
178             if (expectedRowsCount == 0 && actualRowsCount == 0)
179             {
180                 log.debug("Tables are empty, hence equals.");
181                 isTablesEmpty = true;
182             } else
183             {
184                 isTablesEmpty = false;
185             }
186         }
187 
188         return isTablesEmpty;
189     }
190 
191     protected void compareColumns(final Column[] expectedColumns,
192             final Column[] actualColumns, final ITableMetaData expectedMetaData,
193             final ITableMetaData actualMetaData,
194             final FailureHandler failureHandler) throws DataSetException, Error
195     {
196         final Columns.ColumnDiff columnDiff =
197                 Columns.getColumnDiff(expectedMetaData, actualMetaData);
198         if (columnDiff.hasDifference())
199         {
200             final String message = columnDiff.getMessage();
201             final Error error = failureHandler.createFailure(message,
202                     Columns.getColumnNamesAsString(expectedColumns),
203                     Columns.getColumnNamesAsString(actualColumns));
204             log.error(error.toString());
205             throw error;
206         }
207     }
208 
209     protected void compareTableCounts(final String[] expectedNames,
210             final String[] actualNames, final FailureHandler failureHandler)
211             throws Error
212     {
213         if (expectedNames.length != actualNames.length)
214         {
215             throw failureHandler.createFailure("table count",
216                     String.valueOf(expectedNames.length),
217                     String.valueOf(actualNames.length));
218         }
219     }
220 
221     protected void compareTableNames(final String[] expectedNames,
222             final String[] actualNames, final FailureHandler failureHandler)
223             throws Error
224     {
225         for (int i = 0; i < expectedNames.length; i++)
226         {
227             if (!actualNames[i].equals(expectedNames[i]))
228             {
229                 throw failureHandler.createFailure("tables",
230                         Arrays.asList(expectedNames).toString(),
231                         Arrays.asList(actualNames).toString());
232             }
233         }
234     }
235 
236     protected String[] getSortedTableNames(final IDataSet dataSet)
237             throws DataSetException
238     {
239         log.debug("getSortedTableNames(dataSet={}) - start", dataSet);
240 
241         final String[] names = dataSet.getTableNames();
242         if (!dataSet.isCaseSensitiveTableNames())
243         {
244             for (int i = 0; i < names.length; i++)
245             {
246                 names[i] = names[i].toUpperCase();
247             }
248         }
249         Arrays.sort(names);
250         return names;
251     }
252 
253     /**
254      * Asserts the two specified {@link IDataSet}s comparing their columns using
255      * the specified columnValueComparers or defaultValueComparer and handles
256      * failures using the specified failureHandler. This method ignores the
257      * table names, the columns order, the columns data type, and which columns
258      * are composing the primary keys.
259      *
260      * @param expectedDataSet
261      *            {@link IDataSet} containing all expected results.
262      * @param actualDataSet
263      *            {@link IDataSet} containing all actual results.
264      * @param failureHandler
265      *            The failure handler used if the assert fails because of a data
266      *            mismatch. Provides some additional information that may be
267      *            useful to quickly identify the rows for which the mismatch
268      *            occurred (for example by printing an additional primary key
269      *            column). Can be <code>null</code>.
270      * @param defaultValueComparer
271      *            {@link ValueComparer} to use with column value comparisons
272      *            when the column name for the table is not in the
273      *            tableColumnValueComparers {@link Map}. Can be
274      *            <code>null</code> and will default to
275      *            {@link #getDefaultValueComparer()}.
276      * @param tableColumnValueComparers
277      *            {@link Map} of {@link ValueComparer}s to use for specific
278      *            tables and columns. Key is table name, value is {@link Map} of
279      *            column name in the table to {@link ValueComparer}s. Can be
280      *            <code>null</code> and will default to using
281      *            {@link #getDefaultColumnValueComparerMapForTable(String)} or,
282      *            if that is empty, defaultValueComparer for all columns in all
283      *            tables.
284      * @throws DatabaseUnitException
285      */
286     public void assertWithValueComparer(final IDataSet expectedDataSet,
287             final IDataSet actualDataSet, final FailureHandler failureHandler,
288             final ValueComparer defaultValueComparer,
289             final Map<String, Map<String, ValueComparer>> tableColumnValueComparers)
290             throws DatabaseUnitException
291     {
292         log.debug(
293                 "assertWithValueComparer(expectedDataSet={}, actualDataSet={},"
294                         + " failureHandler={}, defaultValueComparer={},"
295                         + " tableColumnValueComparers={}) - start",
296                 expectedDataSet, actualDataSet, failureHandler,
297                 defaultValueComparer, tableColumnValueComparers);
298 
299         // do not continue if same instance
300         if (expectedDataSet == actualDataSet)
301         {
302             log.debug("The given datasets reference the same object."
303                     + " Skipping comparisons.");
304             return;
305         }
306 
307         final FailureHandler validFailureHandler =
308                 determineFailureHandler(failureHandler);
309 
310         final String[] expectedNames = getSortedTableNames(expectedDataSet);
311         final String[] actualNames = getSortedTableNames(actualDataSet);
312 
313         compareTableCounts(expectedNames, actualNames, validFailureHandler);
314 
315         // table names in no specific order
316         compareTableNames(expectedNames, actualNames, validFailureHandler);
317 
318         compareTables(expectedDataSet, actualDataSet, expectedNames,
319                 validFailureHandler, defaultValueComparer,
320                 tableColumnValueComparers);
321     }
322 
323     protected void compareTables(final IDataSet expectedDataSet,
324             final IDataSet actualDataSet, final String[] expectedNames,
325             final FailureHandler failureHandler,
326             final ValueComparer defaultValueComparer,
327             final Map<String, Map<String, ValueComparer>> tableColumnValueComparers)
328             throws DatabaseUnitException
329     {
330         final Map<String, Map<String, ValueComparer>> validTableColumnValueComparers =
331                 determineValidTableColumnValueComparers(
332                         tableColumnValueComparers);
333 
334         for (int i = 0; i < expectedNames.length; i++)
335         {
336             final String tableName = expectedNames[i];
337 
338             final ITable expectedTable = expectedDataSet.getTable(tableName);
339             final ITable actualTable = actualDataSet.getTable(tableName);
340             final Map<String, ValueComparer> columnValueComparers =
341                     validTableColumnValueComparers.get(tableName);
342 
343             assertWithValueComparer(expectedTable, actualTable, failureHandler,
344                     defaultValueComparer, columnValueComparers);
345         }
346     }
347 
348     /**
349      * Asserts the two specified {@link ITable}s comparing their columns using
350      * the specified columnValueComparers or defaultValueComparer and handles
351      * failures using the specified failureHandler. This method ignores the
352      * table names, the columns order, the columns data type, and which columns
353      * are composing the primary keys.
354      *
355      * @param expectedTable
356      *            {@link ITable} containing all expected results.
357      * @param actualTable
358      *            {@link ITable} containing all actual results.
359      * @param failureHandler
360      *            The failure handler used if the assert fails because of a data
361      *            mismatch. Provides some additional information that may be
362      *            useful to quickly identify the rows for which the mismatch
363      *            occurred (for example by printing an additional primary key
364      *            column). Can be <code>null</code>.
365      * @param defaultValueComparer
366      *            {@link ValueComparer} to use with column value comparisons
367      *            when the column name for the table is not in the
368      *            columnValueComparers {@link Map}. Can be <code>null</code> and
369      *            will default to {@link #getDefaultValueComparer()}.
370      * @param columnValueComparers
371      *            {@link Map} of {@link ValueComparer}s to use for specific
372      *            columns. Key is column name in the table, value is
373      *            {@link ValueComparer} to use in comparing expected to actual
374      *            column values. Can be <code>null</code> and will default to
375      *            using
376      *            {@link #getDefaultColumnValueComparerMapForTable(String)} or,
377      *            if that is empty, defaultValueComparer for all columns in the
378      *            table.
379      * @throws DatabaseUnitException
380      */
381     public void assertWithValueComparer(final ITable expectedTable,
382             final ITable actualTable, final FailureHandler failureHandler,
383             final ValueComparer defaultValueComparer,
384             final Map<String, ValueComparer> columnValueComparers)
385             throws DatabaseUnitException
386     {
387         log.trace("assertWithValueComparer(expectedTable, actualTable,"
388                 + " failureHandler, defaultValueComparer,"
389                 + " columnValueComparers) - start");
390         log.debug("assertWithValueComparer: expectedTable={}", expectedTable);
391         log.debug("assertWithValueComparer: actualTable={}", actualTable);
392         log.debug("assertWithValueComparer: failureHandler={}", failureHandler);
393         log.debug("assertWithValueComparer: defaultValueComparer={}",
394                 defaultValueComparer);
395         log.debug("assertWithValueComparer: columnValueComparers={}",
396                 columnValueComparers);
397 
398         // Do not continue if same instance
399         if (expectedTable == actualTable)
400         {
401             log.debug("The given tables reference the same object."
402                     + " Skipping comparisons.");
403             return;
404         }
405 
406         final FailureHandler validFailureHandler =
407                 determineFailureHandler(failureHandler);
408 
409         final ITableMetaData expectedMetaData =
410                 expectedTable.getTableMetaData();
411         final ITableMetaData actualMetaData = actualTable.getTableMetaData();
412         final String expectedTableName = expectedMetaData.getTableName();
413 
414         final boolean isTablesEmpty = compareRowCounts(expectedTable,
415                 actualTable, validFailureHandler, expectedTableName);
416         if (isTablesEmpty)
417         {
418             return;
419         }
420 
421         // Put the columns into the same order
422         final Column[] expectedColumns =
423                 Columns.getSortedColumns(expectedMetaData);
424         final Column[] actualColumns = Columns.getSortedColumns(actualMetaData);
425 
426         // Verify columns
427         compareColumns(expectedColumns, actualColumns, expectedMetaData,
428                 actualMetaData, validFailureHandler);
429 
430         // Get the datatypes to be used for comparing the sorted columns
431         final ComparisonColumn[] comparisonCols =
432                 getComparisonColumns(expectedTableName, expectedColumns,
433                         actualColumns, validFailureHandler);
434 
435         // Finally compare the data
436         compareData(expectedTable, actualTable, comparisonCols,
437                 validFailureHandler, defaultValueComparer,
438                 columnValueComparers);
439     }
440 
441     /**
442      * @param expectedTable
443      *            Table containing all expected results.
444      * @param actualTable
445      *            Table containing all actual results.
446      * @param comparisonCols
447      *            The columns to be compared, also including the correct
448      *            {@link DataType}s for comparison
449      * @param failureHandler
450      *            The failure handler used if the assert fails because of a data
451      *            mismatch. Provides some additional information that may be
452      *            useful to quickly identify the rows for which the mismatch
453      *            occurred (for example by printing an additional primary key
454      *            column). Must not be <code>null</code> at this stage
455      * @throws DataSetException
456      * @since 2.4
457      */
458     protected void compareData(final ITable expectedTable,
459             final ITable actualTable, final ComparisonColumn[] comparisonCols,
460             final FailureHandler failureHandler) throws DataSetException
461     {
462         final ValueComparer defaultValueComparer = null;
463         final Map<String, ValueComparer> columnValueComparers = null;
464         try
465         {
466             compareData(expectedTable, actualTable, comparisonCols,
467                     failureHandler, defaultValueComparer, columnValueComparers);
468         } catch (final DatabaseUnitException e)
469         {
470             // not-private method, signature change breaks compatability
471             throw new DataSetException(e);
472         }
473     }
474 
475     /**
476      * @param expectedTable
477      *            {@link ITable} containing all expected results.
478      * @param actualTable
479      *            {@link ITable} containing all actual results.
480      * @param comparisonCols
481      *            The columns to be compared, also including the correct
482      *            {@link DataType}s for comparison
483      * @param failureHandler
484      *            The failure handler used if the assert fails because of a data
485      *            mismatch. Provides some additional information that may be
486      *            useful to quickly identify the rows for which the mismatch
487      *            occurred (for example by printing an additional primary key
488      *            column). Must not be <code>null</code> at this stage.
489      * @param defaultValueComparer
490      *            {@link ValueComparer} to use with column value comparisons
491      *            when the column name for the table is not in the
492      *            columnValueComparers {@link Map}. Can be <code>null</code> and
493      *            will default to {@link #getDefaultValueComparer()}.
494      * @param columnValueComparers
495      *            {@link Map} of {@link ValueComparer}s to use for specific
496      *            columns. Key is column name in the table, value is
497      *            {@link ValueComparer} to use in comparing expected to actual
498      *            column values. Can be <code>null</code> and will default to
499      *            using
500      *            {@link #getDefaultColumnValueComparerMapForTable(String)} or,
501      *            if that is empty, defaultValueComparer for all columns in the
502      *            table.
503      * @throws DataSetException
504      * @since 2.4
505      * @since 2.6.0
506      */
507     protected void compareData(final ITable expectedTable,
508             final ITable actualTable, final ComparisonColumn[] comparisonCols,
509             final FailureHandler failureHandler,
510             final ValueComparer defaultValueComparer,
511             final Map<String, ValueComparer> columnValueComparers)
512             throws DatabaseUnitException
513     {
514         log.debug(
515                 "compareData(expectedTable={}, actualTable={}, "
516                         + "comparisonCols={}, failureHandler={},"
517                         + " defaultValueComparer={}, columnValueComparers={})"
518                         + " - start",
519                 expectedTable, actualTable, comparisonCols, failureHandler,
520                 defaultValueComparer, columnValueComparers);
521 
522         if (expectedTable == null)
523         {
524             throw new IllegalArgumentException(
525                     "The parameter 'expectedTable' is null");
526         }
527         if (actualTable == null)
528         {
529             throw new IllegalArgumentException(
530                     "The parameter 'actualTable' is null");
531         }
532         if (comparisonCols == null)
533         {
534             throw new IllegalArgumentException(
535                     "The parameter 'comparisonCols' is null");
536         }
537         if (failureHandler == null)
538         {
539             throw new IllegalArgumentException(
540                     "The parameter 'failureHandler' is null");
541         }
542 
543         final ValueComparer validDefaultValueComparer =
544                 determineValidDefaultValueComparer(defaultValueComparer);
545         final String expectedTableName =
546                 expectedTable.getTableMetaData().getTableName();
547         final Map<String, ValueComparer> validColumnValueComparers =
548                 determineValidColumnValueComparers(columnValueComparers,
549                         expectedTableName);
550 
551         // iterate over all rows
552         for (int rowNum = 0; rowNum < expectedTable.getRowCount(); rowNum++)
553         {
554             // iterate over all columns of the current row
555             final int columnCount = comparisonCols.length;
556             for (int columnNum = 0; columnNum < columnCount; columnNum++)
557             {
558                 compareData(expectedTable, actualTable, comparisonCols,
559                         failureHandler, validDefaultValueComparer,
560                         validColumnValueComparers, rowNum, columnNum);
561             }
562         }
563     }
564 
565     protected void compareData(final ITable expectedTable,
566             final ITable actualTable, final ComparisonColumn[] comparisonCols,
567             final FailureHandler failureHandler,
568             final ValueComparer defaultValueComparer,
569             final Map<String, ValueComparer> columnValueComparers,
570             final int rowNum, final int columnNum) throws DatabaseUnitException
571     {
572         final ComparisonColumn compareColumn = comparisonCols[columnNum];
573 
574         final String columnName = compareColumn.getColumnName();
575         final DataType dataType = compareColumn.getDataType();
576 
577         final Object expectedValue = expectedTable.getValue(rowNum, columnName);
578         final Object actualValue = actualTable.getValue(rowNum, columnName);
579 
580         // Compare the values
581         if (skipCompare(columnName, expectedValue, actualValue))
582         {
583             log.trace(
584                     "skipCompare: ignoring comparison" + " {}={} on column={}",
585                     expectedValue, actualValue, columnName);
586         } else
587         {
588             final ValueComparer valueComparer = determineValueComparer(
589                     columnName, defaultValueComparer, columnValueComparers);
590 
591             log.debug(
592                     "compareData: comparing actualValue={}"
593                             + " to expectedValue={} with valueComparer={}",
594                     actualValue, expectedValue, valueComparer);
595             final String failMessage =
596                     valueComparer.compare(expectedTable, actualTable, rowNum,
597                             columnName, dataType, expectedValue, actualValue);
598 
599             failIfNecessary(expectedTable, actualTable, failureHandler, rowNum,
600                     columnName, expectedValue, actualValue, failMessage);
601         }
602     }
603 
604     protected void failIfNecessary(final ITable expectedTable,
605             final ITable actualTable, final FailureHandler failureHandler,
606             final int rowNum, final String columnName,
607             final Object expectedValue, final Object actualValue,
608             final String failMessage)
609     {
610         if (failMessage != null)
611         {
612             final Difference diff = new Difference(expectedTable, actualTable,
613                     rowNum, columnName, expectedValue, actualValue,
614                     failMessage);
615 
616             failureHandler.handle(diff);
617         }
618     }
619 
620     protected ValueComparer determineValueComparer(final String columnName,
621             final ValueComparer defaultValueComparer,
622             final Map<String, ValueComparer> columnValueComparers)
623     {
624         ValueComparer valueComparer = columnValueComparers.get(columnName);
625         if (valueComparer == null)
626         {
627             log.debug(
628                     "determineValueComparer: using defaultValueComparer='{}'"
629                             + " as columnName='{}' not found"
630                             + " in columnValueComparers='{}'",
631                     defaultValueComparer, columnName, columnValueComparers);
632             valueComparer = defaultValueComparer;
633         }
634 
635         return valueComparer;
636     }
637 
638     protected ValueComparer determineValidDefaultValueComparer(
639             final ValueComparer defaultValueComparer)
640     {
641         final ValueComparer validValueComparer;
642 
643         if (defaultValueComparer == null)
644         {
645             validValueComparer = getDefaultValueComparer();
646             log.debug(
647                     "determineValidDefaultValueComparer:"
648                             + " using getDefaultValueComparer()={}"
649                             + " as defaultValueComparer={}",
650                     validValueComparer, defaultValueComparer);
651         } else
652         {
653             validValueComparer = defaultValueComparer;
654         }
655 
656         return validValueComparer;
657     }
658 
659     protected Map<String, Map<String, ValueComparer>> determineValidTableColumnValueComparers(
660             final Map<String, Map<String, ValueComparer>> tableColumnValueComparers)
661     {
662         final Map<String, Map<String, ValueComparer>> validMap;
663 
664         if (tableColumnValueComparers == null)
665         {
666             validMap = getDefaultTableColumnValueComparerMap();
667             log.debug(
668                     "determineValidTableColumnValueComparers:"
669                             + " using getDefaultTableColumnValueComparerMap()={}"
670                             + " as tableColumnValueComparers={}",
671                     validMap, tableColumnValueComparers);
672         } else
673         {
674             validMap = tableColumnValueComparers;
675         }
676 
677         return validMap;
678     }
679 
680     protected Map<String, ValueComparer> determineValidColumnValueComparers(
681             final Map<String, ValueComparer> columnValueComparers,
682             final String tableName)
683     {
684         final Map<String, ValueComparer> validMap;
685 
686         if (columnValueComparers == null)
687         {
688             validMap = getDefaultColumnValueComparerMapForTable(tableName);
689             log.debug(
690                     "determineValidColumnValueComparers:"
691                             + " using getDefaultValueComparerMap()={}"
692                             + " as columnValueComparers={} for tableName={}",
693                     validMap, columnValueComparers, tableName);
694         } else
695         {
696             validMap = columnValueComparers;
697         }
698 
699         return validMap;
700     }
701 
702     protected ValueComparer getDefaultValueComparer()
703     {
704         return ValueComparers.isActualEqualToExpected;
705     }
706 
707     protected Map<String, Map<String, ValueComparer>> getDefaultTableColumnValueComparerMap()
708     {
709         return Collections.emptyMap();
710     }
711 
712     protected Map<String, ValueComparer> getDefaultColumnValueComparerMapForTable(
713             final String tableName)
714     {
715         return Collections.emptyMap();
716     }
717 }