/* * RHQ Management Platform * Copyright (C) 2005-2010 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.helpers.perftest.support.dbunit; import java.util.ArrayList; import java.util.List; import java.util.Set; import org.dbunit.dataset.DataSetException; import org.dbunit.dataset.ITable; import org.dbunit.dataset.ITableIterator; import org.dbunit.dataset.ITableMetaData; import org.dbunit.dataset.RowOutOfBoundsException; import org.rhq.helpers.perftest.support.jpa.ColumnValues; import org.rhq.helpers.perftest.support.jpa.mapping.ColumnValuesTableMap; /** * This is a table iterator able to filter out rows with disallowed primary key values. * * @author Lukas Krejci */ public class EntityRelationshipTableIterator implements ITableIterator { private ITableIterator wrappedIterator; private ColumnValuesTableMap allowedPks; public EntityRelationshipTableIterator(ITableIterator wrappedIterator, ColumnValuesTableMap allowedPks) { this.wrappedIterator = wrappedIterator; this.allowedPks = allowedPks; } public boolean next() throws DataSetException { while (wrappedIterator.next()) { if (allowedPks.containsKey(wrappedIterator.getTableMetaData().getTableName().toUpperCase())) { return true; } } return false; } public ITableMetaData getTableMetaData() throws DataSetException { return wrappedIterator.getTableMetaData(); } public ITable getTable() throws DataSetException { String tableName = getTableMetaData().getTableName().toUpperCase(); Set<ColumnValues> pks = allowedPks.get(tableName); ITable wrappedTable = wrappedIterator.getTable(); if (pks == null) { //no filtering return wrappedTable; } else if (pks.isEmpty()) { return new EmptyTable(wrappedTable.getTableMetaData()); } else { return new FilteredTable(wrappedTable, pks); } } private static class EmptyTable implements ITable { private ITableMetaData metadata; public EmptyTable(ITableMetaData metadata) { this.metadata = metadata; } public ITableMetaData getTableMetaData() { return metadata; } public int getRowCount() { return 0; } public Object getValue(int row, String column) throws DataSetException { throw new RowOutOfBoundsException("This table is always empty."); } } private class FilteredTable implements ITable { private ITable wrappedTable; private List<Integer> allowedRowNumbers; public FilteredTable(ITable wrappedTable, Set<ColumnValues> allowedPks) throws DataSetException { this.wrappedTable = wrappedTable; this.allowedRowNumbers = getRowNumbers(wrappedTable, allowedPks); } public ITableMetaData getTableMetaData() { return wrappedTable.getTableMetaData(); } public int getRowCount() { return allowedRowNumbers.size(); } public Object getValue(int row, String column) throws DataSetException { if (row >= allowedRowNumbers.size()) { throw new RowOutOfBoundsException(); } return wrappedTable.getValue(allowedRowNumbers.get(row), column); } private List<Integer> getRowNumbers(ITable table, Set<ColumnValues> pks) throws DataSetException { List<Integer> ret = new ArrayList<Integer>(); if (pks.isEmpty()) { return ret; } //now this is extremely inefficient, but retains the order of the pks //as defined in the pks set (which is a linked hash set) for (ColumnValues pk : pks) { for (int i = 0; i < table.getRowCount(); ++i) { boolean add = true; for (ColumnValues.Column c : pk) { Object val = table.getValue(i, c.getName()); if (c.getValue() == null ? val != null : !c.getValue().equals(val)) { add = false; break; } } if (add) { ret.add(i); } } } return ret; } } }