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; } }