
org.dbunit.dataset.SortedTable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xmlc Show documentation
Show all versions of xmlc Show documentation
old 2002 version of xmlc
The newest version!
/*
*
* 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.Arrays;
import java.util.Comparator;
import org.dbunit.DatabaseUnitRuntimeException;
import org.dbunit.dataset.datatype.DataType;
import org.dbunit.dataset.datatype.TypeCastException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This is a ITable decorator that provide a sorted view of the decorated table.
* This implementation does not keep a separate copy of the decorated table
* data.
*
* @author Manuel Laflamme
* @author Last changed by: $Author$
* @version $Revision$ $Date: 2009-05-01 02:56:07 -0500 (Fri, 01 May 2009)
* $
* @since Feb 19, 2003
*/
public class SortedTable extends AbstractTable {
/**
* Logger for this class
*/
private static final Logger logger =
LoggerFactory.getLogger(SortedTable.class);
private final ITable _table;
private final Column[] _columns;
private Integer[] _indexes;
/**
* The row comparator which is used for sorting
*/
private Comparator rowComparator;
/**
* Sort the decorated table by specified columns order.
*
* @param table
* decorated table
* @param columns
* columns to be used for sorting
* @throws DataSetException
*/
public SortedTable(ITable table, Column[] columns) throws DataSetException {
_table = table;
_columns = validateAndResolveColumns(columns);
initialize();
}
/**
* Sort the decorated table by specified columns order.
*
* @param table
* decorated table
* @param columnNames
* names of columns to be used for sorting
* @throws DataSetException
*/
public SortedTable(ITable table, String[] columnNames)
throws DataSetException {
_table = table;
_columns = validateAndResolveColumns(columnNames);
initialize();
}
/**
* Sort the decorated table by specified metadata columns order. All
* metadata columns will be used.
*
* @param table
* The decorated table
* @param metaData
* The metadata used to retrieve all columns which in turn are
* used for sorting the table
* @throws DataSetException
*/
public SortedTable(ITable table, ITableMetaData metaData)
throws DataSetException {
this(table, metaData.getColumns());
}
/**
* Sort the decorated table by its own columns order which is defined by
* {@link ITable#getTableMetaData()}. All table columns will be used.
*
* @param table
* The decorated table
* @throws DataSetException
*/
public SortedTable(ITable table) throws DataSetException {
this(table, table.getTableMetaData());
}
/**
* Verifies that all given columns really exist in the current table and
* returns the physical {@link Column} objects from the table.
*
* @param columns
* @return
* @throws DataSetException
*/
private Column[] validateAndResolveColumns(Column[] columns)
throws DataSetException {
ITableMetaData tableMetaData = _table.getTableMetaData();
Column[] resultColumns =
Columns.findColumnsByName(columns, tableMetaData);
return resultColumns;
}
/**
* Verifies that all given columns really exist in the current table and
* returns the physical {@link Column} objects from the table.
*
* @param columnNames
* @return
* @throws DataSetException
*/
private Column[] validateAndResolveColumns(String[] columnNames)
throws DataSetException {
ITableMetaData tableMetaData = _table.getTableMetaData();
Column[] resultColumns =
Columns.findColumnsByName(columnNames, tableMetaData);
return resultColumns;
}
private void initialize() {
logger.debug("initialize() - start");
// The default comparator is the one that sorts by string - for
// backwards compatibility
this.rowComparator =
new RowComparatorByString(this._table, this._columns);
}
/**
* @return The columns that are used for sorting the table
*/
public Column[] getSortColumns() {
return this._columns;
}
private int getOriginalRowIndex(int row) throws DataSetException {
if (logger.isDebugEnabled()) {
logger.debug("getOriginalRowIndex(row={}) - start", Integer
.toString(row));
}
if (_indexes == null) {
Integer[] indexes = new Integer[getRowCount()];
for (int i = 0; i < indexes.length; i++) {
indexes[i] = new Integer(i);
}
try {
Arrays.sort(indexes, rowComparator);
} catch (DatabaseUnitRuntimeException e) {
throw (DataSetException) e.getCause();
}
_indexes = indexes;
}
return _indexes[row].intValue();
}
/**
* Whether or not the comparable interface should be used of the compared
* columns instead of the plain strings Default value is false
* for backwards compatibility Set whether or not to use the Comparable
* implementation of the corresponding column DataType for comparing values
* or not. Default value is false
which means that the old
* string comparison is used.
*
* @param useComparable
* @since 2.3.0
*/
public void setUseComparable(boolean useComparable) {
if (logger.isDebugEnabled()) {
logger.debug("setUseComparable(useComparable={}) - start", Boolean
.valueOf(useComparable));
}
if (useComparable) {
setRowComparator(new RowComparator(this._table, this._columns));
} else {
setRowComparator(new RowComparatorByString(this._table,
this._columns));
}
}
/**
* Sets the comparator to be used for sorting the table rows.
*
* @param comparator
* that sorts the table rows
* @since 2.4.2
*/
public void setRowComparator(Comparator comparator) {
if (logger.isDebugEnabled()) {
logger.debug("setRowComparator(comparator={}) - start", comparator);
}
if (_indexes != null) {
// TODO this is an ugly design to avoid increasing the number of
// constructors from 4 to 8. To be discussed how to implement it the
// best way.
throw new IllegalStateException(
"Do not use this method after the table has been used (i.e. #getValue() has been called). "
+ "Please invoke this method immediately after the intialization of this object.");
}
this.rowComparator = comparator;
}
// //////////////////////////////////////////////////////////////////////////
// ITable interface
public ITableMetaData getTableMetaData() {
logger.debug("getTableMetaData() - start");
return _table.getTableMetaData();
}
public int getRowCount() {
logger.debug("getRowCount() - start");
return _table.getRowCount();
}
public Object getValue(int row, String columnName) throws DataSetException {
if (logger.isDebugEnabled()) {
logger.debug("getValue(row={}, columnName={}) - start", Integer
.toString(row), columnName);
}
assertValidRowIndex(row);
return _table.getValue(getOriginalRowIndex(row), columnName);
}
// //////////////////////////////////////////////////////////////////////////
// Comparator interface
/**
* Abstract class for sorting the table rows of a given table in a specific
* order
*/
public static abstract class AbstractRowComparator implements Comparator {
/**
* Logger for this class
*/
private final Logger logger =
LoggerFactory.getLogger(AbstractRowComparator.class);
private final ITable _table;
private final Column[] _sortColumns;
/**
* @param table
* The wrapped table to be sorted
* @param sortColumns
* The columns to be used for sorting in the given order
*/
public AbstractRowComparator(ITable table, Column[] sortColumns) {
this._table = table;
this._sortColumns = sortColumns;
}
public int compare(Object o1, Object o2) {
logger.debug("compare(o1={}, o2={}) - start", o1, o2);
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
try {
for (int i = 0; i < _sortColumns.length; i++) {
String columnName = _sortColumns[i].getColumnName();
Object value1 = _table.getValue(i1.intValue(), columnName);
Object value2 = _table.getValue(i2.intValue(), columnName);
if (value1 == null && value2 == null) {
continue;
}
if (value1 == null && value2 != null) {
return -1;
}
if (value1 != null && value2 == null) {
return 1;
}
// Compare the two values with each other for sorting
int result = compare(_sortColumns[i], value1, value2);
if (result != 0) {
return result;
}
}
} catch (DataSetException e) {
throw new DatabaseUnitRuntimeException(e);
}
return 0;
}
/**
* @param column
* The column to be compared
* @param value1
* The first value of the given column
* @param value2
* The second value of the given column
* @return 0 if both values are considered equal.
* @throws TypeCastException
*/
protected abstract int compare(Column column, Object value1,
Object value2) throws TypeCastException;
}
/**
* Compares the rows with each other in order to sort them in the correct
* order using the data type and the Comparable implementation the current
* column has.
*/
protected static class RowComparator extends AbstractRowComparator {
/**
* Logger for this class
*/
private final Logger logger =
LoggerFactory.getLogger(RowComparator.class);
public RowComparator(ITable table, Column[] sortColumns) {
super(table, sortColumns);
}
protected int compare(Column column, Object value1, Object value2)
throws TypeCastException {
if (logger.isDebugEnabled()) {
logger.debug(
"compare(column={}, value1={}, value2={}) - start",
new Object[] {column, value1, value2});
}
DataType dataType = column.getDataType();
int result = dataType.compare(value1, value2);
return result;
}
}
/**
* Compares the rows with each other in order to sort them in the correct
* order using the string value of both values for the comparison.
*/
protected static class RowComparatorByString extends AbstractRowComparator {
/**
* Logger for this class
*/
private final Logger logger =
LoggerFactory.getLogger(RowComparatorByString.class);
public RowComparatorByString(ITable table, Column[] sortColumns) {
super(table, sortColumns);
}
protected int compare(Column column, Object value1, Object value2)
throws TypeCastException {
if (logger.isDebugEnabled()) {
logger.debug(
"compare(column={}, value1={}, value2={}) - start",
new Object[] {column, value1, value2});
}
// Default behavior since ever
String stringValue1 = DataType.asString(value1);
String stringValue2 = DataType.asString(value2);
int result = stringValue1.compareTo(stringValue2);
return result;
}
}
/**
* {@inheritDoc}
*/
public String toString() {
StringBuilder sb = new StringBuilder(2000);
sb.append(getClass().getName()).append("[");
sb.append("_columns=[").append(Arrays.toString(_columns)).append("], ");
sb.append("_indexes=[").append(_indexes).append("], ");
sb.append("_table=[").append(_table).append("]");
sb.append("]");
return sb.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy