All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.dbunit.dataset.Columns Maven / Gradle / Ivy

/*
 *
 * 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