org.dbunit.dataset.Columns Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dbunit Show documentation
Show all versions of dbunit Show documentation
dbUnit is a JUnit extension (also usable from Ant and Maven) targeted for database-driven projects that, among other things, puts your database into a known state between test runs. This is an excellent way to avoid the myriad of problems that can occur when one test case corrupts the database and causes subsequent tests to fail or exacerbate the damage.
/*
*
* The DbUnit Database Testing Framework
* Copyright (C)2002-2004, DbUnit.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package org.dbunit.dataset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import org.dbunit.dataset.filter.IColumnFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class exclusively provides static methods that operate on {@link Column} objects.
*
* @author gommma
* @version $Revision$
* @since 2.3.0
*/
public class Columns
{
/**
* Logger for this class
*/
private static final Logger logger = LoggerFactory.getLogger(Columns.class);
private static final ColumnComparator COLUMN_COMPARATOR = new ColumnComparator();
private static final Column[] EMPTY_COLUMNS = new Column[0];
private Columns()
{
}
/**
* Search and return the {@link Column}s from the specified column array that
* match one of the given columnNames
.
*
* Note that this method has a bad performance compared to {@link #findColumnsByName(String[], ITableMetaData)}
* because it iterates over all columns.
*
* @param columnNames the names of the columns to search.
* @param columns the array of columns in which the columnNames
will be searched.
* @return the column array which is empty if no column has been found or no
* column names have been given
* @see #findColumnsByName(String[], ITableMetaData)
*/
public static Column[] getColumns(String[] columnNames, Column[] columns) {
if (logger.isDebugEnabled())
logger.debug("getColumns(columnNames={}, columns={}) - start",
new Object[]{ columnNames, columns });
if (columnNames == null || columnNames.length == 0)
{
return EMPTY_COLUMNS;
}
List resultList = new ArrayList();
for (int i = 0; i < columnNames.length; i++)
{
Column column = Columns.getColumn(columnNames[i], columns);
if (column != null)
{
resultList.add(column);
}
}
return (Column[])resultList.toArray(new Column[0]);
}
/**
* Searches for the given columns
using only the {@link Column#getColumnName()}
* in the given tableMetaData
* @param columnNames The column names that are searched in the given table metadata
* @param tableMetaData The table metadata in which the columns are searched by name
* @return The column objects from the given tableMetaData
* @throws NoSuchColumnException if the given column has not been found
* @throws DataSetException if something goes wrong when trying to retrieve the columns
*/
public static Column[] findColumnsByName(String[] columnNames,
ITableMetaData tableMetaData)
throws NoSuchColumnException, DataSetException
{
logger.debug("findColumnsByName(columnNames={}, tableMetaData={}) - start", columnNames, tableMetaData);
Column[] resultColumns = new Column[columnNames.length];
for (int i = 0; i < columnNames.length; i++)
{
String sortColumn = columnNames[i];
int colIndex = tableMetaData.getColumnIndex(sortColumn);
resultColumns[i] = tableMetaData.getColumns()[colIndex];
}
return resultColumns;
}
/**
* Searches for the given columns
using only the {@link Column#getColumnName()}
* in the given tableMetaData
* @param columns The columns whose names are searched in the given table metadata
* @param tableMetaData The table metadata in which the columns are searched by name
* @return The column objects from the given tableMetaData
* @throws NoSuchColumnException if the given column has not been found
* @throws DataSetException if something goes wrong when trying to retrieve the columns
*/
public static Column[] findColumnsByName(Column[] columns,
ITableMetaData tableMetaData)
throws NoSuchColumnException, DataSetException
{
logger.debug("findColumnsByName(columns={}, tableMetaData={}) - start", columns, tableMetaData);
Column[] resultColumns = new Column[columns.length];
for (int i = 0; i < columns.length; i++)
{
Column sortColumn = columns[i];
int colIndex = tableMetaData.getColumnIndex(sortColumn.getColumnName());
resultColumns[i] = tableMetaData.getColumns()[colIndex];
}
return resultColumns;
}
/**
* Search and return the specified column from the specified column array.
*
* Note that this method has a bad performance compared to {@link ITableMetaData#getColumnIndex(String)}
* because it iterates over all columns.
*
* @param columnName the name of the column to search.
* @param columns the array of columns in which the columnName
will be searched.
* @return the column or null
if the column is not found
*/
public static Column getColumn(String columnName, Column[] columns)
{
logger.debug("getColumn(columnName={}, columns={}) - start", columnName, columns);
for (int i = 0; i < columns.length; i++)
{
Column column = columns[i];
if (columnName.equalsIgnoreCase(columns[i].getColumnName()))
{
return column;
}
}
return null;
}
/**
* Search and return the specified column from the specified column array.
*
* @param columnName the name of the column to search.
* @param columns the array of columns in which the columnName
will be searched.
* @param tableName The name of the table to which the column array belongs -
* only needed for the exception message in case of a validation failure
* @return the valid column
* @throws NoSuchColumnException If no column exists with the given name
*/
public static Column getColumnValidated(String columnName, Column[] columns, String tableName)
throws NoSuchColumnException
{
if (logger.isDebugEnabled())
logger.debug("getColumn(columnName={}, columns={}, tableName={}) - start",
new Object[] {columnName, columns, tableName } );
Column column = Columns.getColumn(columnName, columns);
if(column==null)
{
throw new NoSuchColumnException(tableName, columnName);
}
return column;
}
/**
* Search and return the columns from the specified column array which are
* accepted by the given {@link IColumnFilter}.
* @param tableName The name of the table which is needed for the filter invocation
* @param columns All available columns to which the filter will be applied
* @param columnFilter The column filter that is applied to the given columns
* @return The columns that are accepted by the given filter
*/
public static Column[] getColumns(String tableName, Column[] columns,
IColumnFilter columnFilter)
{
if (logger.isDebugEnabled())
logger.debug("getColumns(tableName={}, columns={}, columnFilter={}) - start",
new Object[]{ tableName, columns, columnFilter });
List resultList = new ArrayList();
for (int i = 0; i < columns.length; i++)
{
Column column = columns[i];
if (columnFilter.accept(tableName, column))
{
resultList.add(column);
}
}
return (Column[])resultList.toArray(new Column[0]);
}
/**
* Returns a sorted array of column objects
*
* @param metaData The metaData needed to get the columns to be sorted
* @return The columns sorted by their column names, ignoring the case of the column names
* @throws DataSetException
*/
public static Column[] getSortedColumns(ITableMetaData metaData)
throws DataSetException
{
logger.debug("getSortedColumns(metaData={}) - start", metaData);
Column[] columns = metaData.getColumns();
Column[] sortColumns = new Column[columns.length];
System.arraycopy(columns, 0, sortColumns, 0, columns.length);
Arrays.sort(sortColumns, COLUMN_COMPARATOR);
return sortColumns;
}
/**
* Returns the names of the given column objects as string array
* @param columns The column objects
* @return The names of the given column objects
* @since 2.4
*/
public static String[] getColumnNames(Column[] columns)
{
String[] result = new String[columns.length];
for (int i = 0; i < columns.length; i++) {
result[i] = columns[i].getColumnName();
}
return result;
}
/**
* Creates a pretty string representation of the given column names
* @param columns The columns to be formatted
* @return The string representation of the given column names
*/
public static String getColumnNamesAsString(Column[] columns)
{
logger.debug("getColumnNamesAsString(columns={}) - start", columns);
String[] names = new String[columns.length];
for (int i = 0; i < columns.length; i++)
{
Column column = columns[i];
names[i] = column.getColumnName();
}
return Arrays.asList(names).toString();
}
/**
* Merges the two arrays of columns so that all of the columns are available in the result array.
* The first array is considered as master and if a column with a specific name is available in
* both arrays the one from the first array is used.
* @param referenceColumns reference columns treated as master columns during the merge
* @param columnsToMerge potentially new columns to be merged if they do not yet exist in the referenceColumns
* @return Array of merged columns
*/
public static Column[] mergeColumnsByName(Column[] referenceColumns, Column[] columnsToMerge) {
logger.debug("mergeColumnsByName(referenceColumns={}, columnsToMerge={}) - start", referenceColumns, columnsToMerge);
List resultList = new ArrayList(Arrays.asList(referenceColumns));
List columnsToMergeNotInRefList = new ArrayList(Arrays.asList(columnsToMerge));
// All columns that exist in the referenceColumns
for (int i = 0; i < referenceColumns.length; i++) {
Column refColumn = referenceColumns[i];
for (int k = 0; k < columnsToMerge.length; k++) {
Column columnToMerge = columnsToMerge[k];
// Check if this colToMerge exists in the refColumn
if(columnToMerge.getColumnName().equals(refColumn.getColumnName())) {
// We found the column in the refColumns - so no candidate for adding to the result list
columnsToMergeNotInRefList.remove(columnToMerge);
break;
}
}
}
// Add all "columnsToMerge" that have not been found in the referenceColumnList
resultList.addAll(columnsToMergeNotInRefList);
return (Column[]) resultList.toArray(new Column[]{});
}
/**
* Returns the column difference of the two given {@link ITableMetaData} objects
* @param expectedMetaData
* @param actualMetaData
* @return The columns that differ in the both given {@link ITableMetaData} objects
* @throws DataSetException
*/
public static ColumnDiff getColumnDiff(ITableMetaData expectedMetaData,
ITableMetaData actualMetaData)
throws DataSetException
{
return new ColumnDiff(expectedMetaData, actualMetaData);
}
// ColumnComparator class
private static class ColumnComparator implements Comparator
{
/**
* Logger for this class
*/
private static final Logger logger = LoggerFactory.getLogger(ColumnComparator.class);
/**
* Compare columns by name ignoring case
* @see java.util.Comparator#compare(T, T)
*/
public int compare(Object o1, Object o2)
{
logger.debug("compare(o1={}, o2={}) - start", o1, o2);
Column column1 = (Column)o1;
Column column2 = (Column)o2;
String columnName1 = column1.getColumnName();
String columnName2 = column2.getColumnName();
return columnName1.compareToIgnoreCase(columnName2);
}
}
/**
* Describes the {@link Column}s that are different in two tables.
* @author gommma
* @version $Revision$
* @since 2.3.0
*/
public static class ColumnDiff
{
/**
* Logger for this class
*/
private static final Logger logger = LoggerFactory.getLogger(ColumnDiff.class);
/**
* String message that is returned when no difference has been found in the compared columns
*/
private static final String NO_DIFFERENCE = "no difference found";
/**
* The columns that exist in the expected result but not in the actual
*/
private Column[] expected;
/**
* The columns that exist in the actual result but not in the expected
*/
private Column[] actual;
private ITableMetaData expectedMetaData;
private ITableMetaData actualMetaData;
/**
* Creates the difference between the two metadata's columns
* @param expectedMetaData The metadata of the expected results table
* @param actualMetaData The metadata of the actual results table
* @throws DataSetException
*/
public ColumnDiff(ITableMetaData expectedMetaData,
ITableMetaData actualMetaData)
throws DataSetException
{
if (expectedMetaData == null) {
throw new NullPointerException(
"The parameter 'expectedMetaData' must not be null");
}
if (actualMetaData == null) {
throw new NullPointerException(
"The parameter 'actualMetaData' must not be null");
}
this.expectedMetaData = expectedMetaData;
this.actualMetaData = actualMetaData;
Column[] allExpectedCols = expectedMetaData.getColumns();
Column[] allActualCols = actualMetaData.getColumns();
// Get the columns that are missing on the actual side (walk through actual
// columns and look for them in the expected metadata)
this.actual = findMissingColumnsIn(expectedMetaData, allActualCols);
// Get the columns that are missing on the expected side (walk through expected
// columns and look for them in the actual metadata)
this.expected = findMissingColumnsIn(actualMetaData, allExpectedCols);
}
/**
* Searches and returns all columns that are missing in the given {@link ITableMetaData} object
* @param metaDataToCheck The {@link ITableMetaData} in which the given columns should be searched
* @param columnsToSearch The columns to be searched in the given {@link ITableMetaData}
* @return Those {@link Column}s out of the columnsToSearch that have not been found in metaDataToCheck
* @throws DataSetException
*/
private Column[] findMissingColumnsIn(ITableMetaData metaDataToCheck,
Column[] columnsToSearch) throws DataSetException
{
logger.debug("findMissingColumnsIn(metaDataToCheck={}, columnsToSearch={})", metaDataToCheck, columnsToSearch);
List columnsNotFound = new ArrayList();
for (int i = 0; i < columnsToSearch.length; i++) {
try {
metaDataToCheck.getColumnIndex(columnsToSearch[i].getColumnName());
}
catch(NoSuchColumnException e) {
columnsNotFound.add(columnsToSearch[i]);
}
}
Column[] result = (Column[]) columnsNotFound.toArray(new Column[]{});
return result;
}
/**
* @return true
if there is a difference in the columns given in the constructor
*/
public boolean hasDifference()
{
return this.expected.length > 0 || this.actual.length > 0;
}
/**
* @return The columns that exist in the expected result but not in the actual
*/
public Column[] getExpected() {
return expected;
}
/**
* @return The columns that exist in the actual result but not in the expected
*/
public Column[] getActual() {
return actual;
}
/**
* @return The value of {@link #getExpected()} as formatted string
* @see #getExpected()
*/
public String getExpectedAsString() {
return Columns.getColumnNamesAsString(expected);
}
/**
* @return The value of {@link #getActual()} as formatted string
* @see #getActual()
*/
public String getActualAsString() {
return Columns.getColumnNamesAsString(actual);
}
/**
* @return A pretty formatted message that can be used for user information
* @throws DataSetException
*/
public String getMessage() throws DataSetException
{
logger.debug("getMessage() - start");
if(!this.hasDifference())
{
return NO_DIFFERENCE;
}
else
{
Column[] allExpectedCols = expectedMetaData.getColumns();
Column[] allActualCols = actualMetaData.getColumns();
String expectedTableName = expectedMetaData.getTableName();
String message;
if(allExpectedCols.length != allActualCols.length)
{
message = "column count (table=" + expectedTableName + ", " +
"expectedColCount=" + allExpectedCols.length + ", actualColCount=" + allActualCols.length + ")";
}
else
{
message = "column mismatch (table=" + expectedTableName + ")";
}
return message;
}
}
// /**
// * @return A pretty formatted message that shows up the difference
// */
// private String toMessage()
// {
// StringBuffer sb = new StringBuffer();
// sb.append("column-diffs (expected <-> actual): ");
// if(this.hasDifference())
// {
// sb.append(getExpectedAsString());
// sb.append(" <-> ");
// sb.append(getActualAsString());
// }
// else
// {
// sb.append(NO_DIFFERENCE);
// }
// return sb.toString();
// }
public String toString()
{
StringBuffer sb = new StringBuffer();
sb.append(getClass().getName()).append("[");
sb.append("expected=").append(Arrays.asList(expected).toString());
sb.append(", actual=").append(Arrays.asList(actual).toString());
sb.append("]");
return sb.toString();
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy