Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.richfaces.model.ArrangeableModel Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
* Copyright ${year}, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.richfaces.model;
import static org.richfaces.application.configuration.ConfigurationServiceHelper.getBooleanConfigurationValue;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.el.ValueExpression;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModelListener;
import org.ajax4jsf.model.DataVisitResult;
import org.ajax4jsf.model.DataVisitor;
import org.ajax4jsf.model.ExtendedDataModel;
import org.ajax4jsf.model.Range;
import org.ajax4jsf.model.SequenceRange;
import org.richfaces.application.IterationComponentsConfiguration;
import org.richfaces.component.SortOrder;
/**
* @author Konstantin Mishin
*
*/
public class ArrangeableModel extends ExtendedDataModel implements Arrangeable {
private ArrangeableState state;
private List rowKeys;
private ExtendedDataModel> originalModel;
private String var;
private String filterVar;
private Comparator super String> stringComparator;
public ArrangeableModel(ExtendedDataModel> originalModel, String var, String filterVar) {
this.originalModel = originalModel;
this.var = var;
this.filterVar = filterVar;
}
public void addDataModelListener(DataModelListener listener) {
originalModel.addDataModelListener(listener);
}
public void removeDataModelListener(DataModelListener listener) {
originalModel.removeDataModelListener(listener);
}
public DataModelListener[] getDataModelListeners() {
return originalModel.getDataModelListeners();
}
/*
* (non-Javadoc)
*
* @see org.ajax4jsf.model.ExtendedDataModel#getRowKey()
*/
public Object getRowKey() {
return originalModel.getRowKey();
}
/*
* (non-Javadoc)
*
* @see org.ajax4jsf.model.ExtendedDataModel#setRowKey(java.lang.Object)
*/
public void setRowKey(Object key) {
originalModel.setRowKey(key);
}
/*
* (non-Javadoc)
*
* @see org.ajax4jsf.model.ExtendedDataModel#walk(javax.faces.context.FacesContext, org.ajax4jsf.model.DataVisitor,
* org.ajax4jsf.model.Range, java.lang.Object)
*/
public void walk(FacesContext context, DataVisitor visitor, Range range, Object argument) {
final SequenceRange seqRange = (SequenceRange) range;
int rows = seqRange.getRows();
int rowCount = getRowCount();
int currentRow = seqRange.getFirstRow();
if (rows > 0) {
rows += currentRow;
rows = Math.min(rows, rowCount);
} else {
rows = rowCount;
}
for (; currentRow < rows; currentRow++) {
visitor.process(context, rowKeys.get(currentRow), argument);
}
}
/*
* (non-Javadoc)
*
* @see javax.faces.model.DataModel#getRowCount()
*/
public int getRowCount() {
if (rowKeys == null) {
return -1;
} else {
return rowKeys.size();
}
}
/*
* (non-Javadoc)
*
* @see javax.faces.model.DataModel#getRowData()
*/
public Object getRowData() {
return originalModel.getRowData();
}
/*
* (non-Javadoc)
*
* @see javax.faces.model.DataModel#getRowIndex()
*/
public int getRowIndex() {
return rowKeys.indexOf(originalModel.getRowKey());
}
/*
* (non-Javadoc)
*
* @see javax.faces.model.DataModel#getWrappedData()
*/
public Object getWrappedData() {
return originalModel.getWrappedData();
}
/*
* (non-Javadoc)
*
* @see javax.faces.model.DataModel#isRowAvailable()
*/
public boolean isRowAvailable() {
return originalModel.isRowAvailable();
}
/*
* (non-Javadoc)
*
* @see javax.faces.model.DataModel#setRowIndex(int)
*/
public void setRowIndex(int rowIndex) {
Object originalKey = null;
if (rowIndex >= 0 && rowIndex < rowKeys.size()) {
originalKey = rowKeys.get(rowIndex);
}
originalModel.setRowKey(originalKey);
}
/*
* (non-Javadoc)
*
* @see javax.faces.model.DataModel#setWrappedData(java.lang.Object)
*/
public void setWrappedData(Object data) {
originalModel.setWrappedData(data);
}
/*
* (non-Javadoc)
*
* @see org.richfaces.model.Modifiable#modify(org.richfaces.model.ModifiableState)
*/
public void arrange(FacesContext context, ArrangeableState state) {
initializeRowKeys(context);
if (state != null) {
this.state = state;
Map map = context.getExternalContext().getRequestMap();
Object value = null;
Object filterValue = null;
if (var != null && var.length() > 0) {
value = map.get(var);
}
if (filterVar != null && filterVar.length() > 0) {
filterValue = map.get(filterVar);
}
filter(context);
sort(context);
if (var != null && var.length() > 0) {
map.put(var, value);
}
if (filterVar != null && filterVar.length() > 0) {
map.put(filterVar, filterValue);
}
}
}
private void initializeRowKeys(FacesContext context) {
int rowCount = originalModel.getRowCount();
if (rowCount > 0) {
rowKeys = new ArrayList(rowCount);
} else {
rowKeys = new ArrayList();
}
Object rowKey = originalModel.getRowKey();
originalModel.walk(context, new DataVisitor() {
public DataVisitResult process(FacesContext context, Object rowKey, Object argument) {
originalModel.setRowKey(rowKey);
if (originalModel.isRowAvailable()) {
rowKeys.add(rowKey);
}
return DataVisitResult.CONTINUE;
}
}, new SequenceRange(0, -1), null);
originalModel.setRowKey(rowKey);
}
private void filter(FacesContext context) {
List filterFields = state.getFilterFields();
if (filterFields != null && !filterFields.isEmpty()) {
List filteredCollection = new ArrayList();
for (Object rowKey : rowKeys) {
if (accept(context, rowKey)) {
filteredCollection.add(rowKey);
}
}
rowKeys = filteredCollection;
}
}
private void sort(final FacesContext context) {
List sortFields = state.getSortFields();
if (sortFields != null && !sortFields.isEmpty()) {
Collections.sort(rowKeys, new Comparator() {
public int compare(Object rowKey1, Object rowKey2) {
return ArrangeableModel.this.compare(context, rowKey1, rowKey2);
}
});
}
}
private boolean accept(FacesContext context, Object rowKey) {
originalModel.setRowKey(rowKey);
Object object = originalModel.getRowData();
updateVar(context, var, object);
for (FilterField filterField : state.getFilterFields()) {
Filter filter = filterField.getFilter();
if (filter != null && !filter.accept(object)) {
return false;
} else {
ValueExpression filterExpression = filterField.getFilterExpression();
if (filterExpression != null) {
updateVar(context, filterVar, filterField.getFilterValue());
if (Boolean.FALSE.equals(filterExpression.getValue(context.getELContext()))) {
return false;
}
}
}
}
return true;
}
private int compare(FacesContext context, Object rowKey1, Object rowKey2) {
originalModel.setRowKey(rowKey1);
Object object1 = originalModel.getRowData();
originalModel.setRowKey(rowKey2);
Object object2 = originalModel.getRowData();
int result = 0;
for (Iterator iterator = state.getSortFields().iterator(); iterator.hasNext() && result == 0;) {
SortField sortField = iterator.next();
SortOrder sortOrder = sortField.getSortOrder();
if (sortOrder != null && !SortOrder.unsorted.equals(sortOrder)) {
Comparator comparator = sortField.getComparator();
if (comparator != null) {
result = comparator.compare(object1, object2);
} else {
ValueExpression sortBy = sortField.getSortBy();
if (sortBy != null) {
updateVar(context, var, object1);
Object value1 = sortBy.getValue(context.getELContext());
updateVar(context, var, object2);
Object value2 = sortBy.getValue(context.getELContext());
result = compareSortByValues(context, value1, value2);
}
}
if (SortOrder.descending.equals(sortOrder)) {
result = -result;
}
}
}
return result;
}
private int compareSortByValues(FacesContext context, Object value1, Object value2) {
int result = 0;
if (value1 instanceof String && value2 instanceof String) {
if (stringComparator == null) {
stringComparator = createStringComparator(context);
}
result = stringComparator.compare(((String) value1).trim(), ((String) value2).trim());
} else if (value1 == null && value2 != null) {
result = -1;
} else if (value2 == null && value1 != null) {
result = 1;
} else if (value1 instanceof Comparable>) {
result = ((Comparable) value1).compareTo(value2);
}
return result;
}
private Comparator super String> createStringComparator(FacesContext context) {
Comparator super String> comparator = null;
Locale locale = state.getLocale();
if (locale != null
&& getBooleanConfigurationValue(context, IterationComponentsConfiguration.Items.datatableUsesViewLocale)) {
comparator = Collator.getInstance(locale);
} else {
comparator = new Comparator() {
public int compare(String o1, String o2) {
return o1.compareToIgnoreCase(o2);
}
};
}
return comparator;
}
private void updateVar(FacesContext context, String var, Object value) {
if (var != null && var.length() > 0) {
context.getExternalContext().getRequestMap().put(var, value);
}
}
}