/**
*
*/
package org.richfaces.model;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModelListener;
import org.ajax4jsf.model.DataVisitor;
import org.ajax4jsf.model.ExtendedDataModel;
import org.ajax4jsf.model.Range;
import org.ajax4jsf.model.SequenceRange;
import org.ajax4jsf.model.SerializableDataModel;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.richfaces.model.FilterField;
import org.richfaces.model.SortField2;
import org.richfaces.model.impl.expressive.JavaBeanWrapper;
import org.richfaces.model.impl.expressive.ObjectWrapperFactory;
import org.richfaces.model.impl.expressive.WrappedBeanComparator2;
import org.richfaces.model.impl.expressive.WrappedBeanFilter;
/**
* @author pawelgo
*
*/
public class ExtendedDataTableModifiableModel<T> extends ExtendedDataModel {
private static final Log log = LogFactory.getLog(ExtendedDataTableModifiableModel.class);
private ExtendedDataModel delegate;
private ExtendedTableDataModel<T> originalModel;
private ExtendedDataModel modifiedModel;
private String var;
private List<FilterField> filterFields;
private List<SortField2> sortFields;
/**
* @param originalModel
* @param var
* @param filterFields
* @param sortFields
*/
public ExtendedDataTableModifiableModel(ExtendedTableDataModel<T> originalModel,
String var, List<FilterField> filterFields,
List<SortField2> sortFields) {
this.originalModel = originalModel;
this.delegate = originalModel;
this.var = var;
this.filterFields = filterFields;
this.sortFields = sortFields;
}
public void addDataModelListener(DataModelListener listener) {
originalModel.addDataModelListener(listener);
}
public DataModelListener[] getDataModelListeners() {
return originalModel.getDataModelListeners();
}
public int getRowCount() {
return delegate.getRowCount();
}
public Object getRowData() {
return delegate.getRowData();
}
public int getRowIndex() {
return delegate.getRowIndex();
}
public Object getRowKey() {
return delegate.getRowKey();
}
public SerializableDataModel getSerializableModel(Range range) {
return delegate.getSerializableModel(range);
}
public Object getWrappedData() {
return delegate.getWrappedData();
}
public boolean isRowAvailable() {
return delegate.isRowAvailable();
}
public void removeDataModelListener(DataModelListener listener) {
delegate.removeDataModelListener(listener);
}
public void setRowIndex(int rowIndex) {
delegate.setRowIndex(rowIndex);
}
public void setRowKey(Object key) {
delegate.setRowKey(key);
}
public void setWrappedData(Object data) {
delegate.setWrappedData(data);
}
@SuppressWarnings("unchecked")
public void walk(FacesContext context, DataVisitor visitor, Range range,
Object argument) throws IOException {
if (shouldSort() || shouldFilter()) {
if (modifiedModel == null) {
modifiedModel = new ExtendedTableDataModelWrapper<T>(originalModel.getDataProvider(), (List<T>) prepareCollection());
}
delegate = modifiedModel;
} else {
delegate = originalModel;
}
delegate.walk(context, visitor, range, argument);
}
private boolean shouldSort() {
return sortFields != null && !sortFields.isEmpty();
}
private boolean shouldFilter() {
return filterFields != null && !filterFields.isEmpty();
}
private List<?> prepareCollection() {
int rowCount = originalModel.getRowCount();
final List<Object> collection;
if (rowCount > 0) {
collection = new ArrayList<Object>(rowCount);
} else {
collection = new ArrayList<Object>();
}
FacesContext context = FacesContext.getCurrentInstance();
try {
originalModel.walk(context, new DataVisitor() {
public void process(FacesContext context, Object rowKey,
Object argument) throws IOException {
originalModel.setRowKey(rowKey);
if (originalModel.isRowAvailable()) {
collection.add(originalModel.getRowData());
}
}
}, new SequenceRange(0, -1),
null);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
List<Object> modifedcollection = collection;
if (shouldFilter()) {
List <Object> filteredCollection = new ArrayList<Object>();
ObjectWrapperFactory wrapperFactory = new ObjectWrapperFactory(
context, var, filterFields);
WrappedBeanFilter wrappedBeanFilter = new WrappedBeanFilter(filterFields);
wrapperFactory.wrapList(modifedcollection);
for (Object object : modifedcollection) {
if(wrappedBeanFilter.accept((JavaBeanWrapper)object)) {
filteredCollection.add(object);
}
}
modifedcollection = filteredCollection;
wrapperFactory.unwrapList(modifedcollection);
}
if (shouldSort()) {
ObjectWrapperFactory wrapperFactory = new ObjectWrapperFactory(
context, var, sortFields);
WrappedBeanComparator2 wrappedBeanComparator = new WrappedBeanComparator2(
sortFields);
wrapperFactory.wrapList(modifedcollection);
Collections.sort(modifedcollection, wrappedBeanComparator);
wrapperFactory.unwrapList(modifedcollection);
}
return modifedcollection;
}
}