package com.daveoxley.cnery.factories;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import javax.faces.context.FacesContext;
import org.ajax4jsf.model.DataVisitor;
import org.ajax4jsf.model.ExtendedDataModel;
import org.ajax4jsf.model.Range;
import org.ajax4jsf.model.SequenceRange;
/**
*
* @author dave
*/
public abstract class CNeryDataModel<K,V> extends ExtendedDataModel<V> {
private K current_key = null;
private List<V> wrappedData;
private Map<K,V> cache = new HashMap<K, V>();
CNeryDataModel(List<V> wrappedData) {
setWrappedData(wrappedData);
}
abstract K getKey(V value);
@Override
public void setRowKey(Object o) {
this.current_key = (K)o;
}
@Override
public Object getRowKey() {
return current_key;
}
@Override
public void walk(FacesContext fc, DataVisitor dv, Range range, Object argument) {
int firstRow = ((SequenceRange)range).getFirstRow();
int numberOfRows = ((SequenceRange)range).getRows();
int lastRow = numberOfRows > 0 ? firstRow + numberOfRows : wrappedData.size();
if (lastRow > wrappedData.size())
lastRow = wrappedData.size();
for (V v : wrappedData.subList(firstRow, lastRow)) {
K key = getKey(v);
cache.put(key, v);
dv.process(fc, key, argument);
}
}
@Override
public boolean isRowAvailable() {
return current_key != null;
}
@Override
public int getRowCount() {
return wrappedData.size();
}
@Override
public V getRowData() {
if (current_key == null)
return null;
V cachedValue = cache.get(current_key);
if (cachedValue != null)
return cachedValue;
for (V value : wrappedData) {
K key = getKey(value);
if (key.equals(current_key)) {
cache.put(key, value);
return value;
}
}
return null;
}
@Override
public int getRowIndex() {
V value = getRowData();
if (value == null)
return -1;
return wrappedData.indexOf(value);
}
@Override
public void setRowIndex(int rowIndex) {
V value = wrappedData.get(rowIndex);
if (value != null)
this.current_key = getKey(value);
}
@Override
public Object getWrappedData() {
return wrappedData;
}
@Override
public void setWrappedData(Object data) {
wrappedData = (List<V>)data;
}
}