package reportgen.ren.report.extendedformat.cell;
import java.util.ArrayList;
import reportgen.ren.report.extendedformat.range.ColRowRangeList;
import reportgen.ren.report.extendedformat.range.cross.CrossReport;
import reportgen.ren.report.extendedformat.range.ColRowRange;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.jdom.Element;
import reportgen.prototype.context.Context;
import reportgen.utils.ReportException;
import reportgen.prototype.utils.ItemListSingle;
/**
* COLUMN SELECTOR CLASS
*/
public class CellValueList
extends ItemListSingle<CellValue, Context> implements CellContainer {
private final static String TAG = "cells";
private final ColRowRangeList rows;
private final ColRowRangeList cols;
private Map<Key, CellValue> map;
public CellValueList(ColRowRangeList rows, ColRowRangeList cols) {
assert cols.size() == 0;
assert rows.size() == 0;
this.cols = cols;
this.rows = rows;
map = new HashMap<Key, CellValue>();
rows.setCellContainer(this);
cols.setCellContainer(this);
}
public CellValueList(Element root, Context context,
ColRowRangeList rows, ColRowRangeList cols) throws ReportException {
super(root, context);
this.cols = cols;
this.rows = rows;
for(ColRowRange r: rows.getFlat(new ArrayList<ColRowRange>())) {
for(ColRowRange c: cols.getFlat(new ArrayList<ColRowRange>())) {
Key key = new Key(c, r);
if(!map.containsKey(key)) {
throw new ReportException("Отсутствует ячейка таблицы col:"
+ c.getAtom() + ", row:" + r.getAtom());
}
}
}
rows.setCellContainer(this);
cols.setCellContainer(this);
}
@Override
protected CellValue loadChild(Element root, Context context) throws ReportException {
return new CellValue(root, context);
}
@Override
public String getRootTag() {
return TAG;
}
public CellValue get(ColRowRange col, ColRowRange row) {
Key key = new Key(col, row);
CellValue value = map.get(key);
if(value == null) {
value = new CellValue(col, row);
add(value);
}
return value;
}
@Override
protected void onRemove(CellValue cell) throws ReportException {
super.onRemove(cell);
ColRowRange col = cell.getColReference();
ColRowRange row = cell.getRowReference();
Key key = new Key(col, row);
map.remove(key);
}
@Override
protected void onAdd(CellValue cell) {
super.onAdd(cell);
if(map == null) {
map = new HashMap<Key, CellValue>();
}
ColRowRange col = cell.getColReference();
ColRowRange row = cell.getRowReference();
map.put(new Key(col, row), cell);
}
@Override
public boolean canRemoveCrossReport(CrossReport report) {
return !isContain(report);
}
@Override
protected boolean isItemContains(CellValue item, Object obj) {
return item.isContain(obj);
}
@Override
protected void validateItem(CellValue item) throws ReportException {
item.validate();
}
@Override
public void onAddCol(ColRowRange parent, ColRowRange newRange) {
List<CellValue> newCells = new LinkedList<CellValue>();
if(parent != null
&& parent.getInner().size() == 0) {
//if really splitted, move affected cells
/*
Iterator<CellValue> it = getList().iterator();
while(it.hasNext()) {
CellValue cell = it.next();
CellValue newCell = null;
if(cell.getColReference() == parent) {
newCell = cell.cloneCell(newRange, cell.getRowReference());
newCells.add(newCell);
} else if(cell.getRowReference() == parent) {
newCell = cell.cloneCell(cell.getColReference(), newRange);
newCells.add(newCell);
}
}
*/
try {
onRangeRemove(parent);
} catch (ReportException ex) {
throw new RuntimeException("Попытка удаления ячейки таблицы не удалась", ex);
}
} else {
//not splitted, just added new range
//do nothing
}
for(CellValue cell :newCells) {
add(cell);
}
}
/**
*
* @param parent
* @param range
*/
@Override
public void removedRange(ColRowRange parent, ColRowRange range) {
try {
onRangeRemove(range);
} catch (ReportException ex) {
throw new RuntimeException("Попытка удаления ячейки таблицы не удалась", ex);
}
}
/**
*
* @param range
*/
private void onRangeRemove(ColRowRange range) throws ReportException {
Iterator<CellValue> it = getList().iterator();
List<CellValue> toRemove = new LinkedList<CellValue>();
while(it.hasNext()) {
CellValue cell = it.next();
if(cell.getColReference() == range
|| cell.getRowReference() == range) {
toRemove.add(cell);
}
}
for(CellValue cell: toRemove) {
remove(cell);
}
}
private static class Key {
private ColRowRange col;
private ColRowRange row;
public Key(ColRowRange col, ColRowRange row) {
this.col = col;
this.row = row;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Key other = (Key) obj;
if (this.col != other.col || this.row != other.row) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 5;
hash = 59 * hash + (this.col != null ? this.col.hashCode() : 0);
hash = 59 * hash + (this.row != null ? this.row.hashCode() : 0);
return hash;
}
}
}