/*
Copyright (C) 2010 maik.jablonski@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package jfix.zk;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import jfix.search.FullTextIndex;
import org.zkoss.zul.AbstractListModel;
import org.zkoss.zul.ListModelExt;
import org.zkoss.zul.event.ListDataEvent;
public abstract class ObjectTableModel<E> extends AbstractListModel implements
ListModelExt, Refreshable {
private List<E> allElements;
private List<E> filteredElements;
private String search;
private FullTextIndex<E> fullTextIndex;
private Comparator comparator;
public abstract E newObject();
public abstract String[] getColumns();
public abstract Object getValue(E object, int column);
public abstract List<E> getList();
public boolean isSortable() {
return true;
}
public int[] getProportions() {
int[] props = new int[getColumns().length];
for (int i = 0; i < props.length; i++) {
props[i] = 1;
}
return props;
}
public Object[] getSearchValues(E object) {
return null;
}
public ObjectTableModel() {
allElements = new ArrayList<E>();
filteredElements = new ArrayList<E>();
}
public List<E> getElements() {
return filteredElements;
}
public Object getElementAt(int i) {
if (i < filteredElements.size()) {
return filteredElements.get(i);
} else {
return null;
}
}
public int getSize() {
return filteredElements.size();
}
public Object getCheckedValue(E object, int column) {
if (object == null) {
return "";
}
try {
return getValue(object, column);
} catch (NullPointerException e) {
return "";
}
}
public void refresh() {
fullTextIndex = null;
allElements = getList();
setSearch(search);
}
public void setSearch(String searchStr) {
try {
search = searchStr;
if (search != null && !"".equals(search.trim())) {
if (fullTextIndex == null) {
buildFullTextIndex(allElements);
}
filteredElements = new ArrayList<E>();
for (E entity : fullTextIndex.search(search)) {
filteredElements.add(entity);
}
} else {
if (allElements != null) {
filteredElements = new ArrayList<E>(allElements);
} else {
filteredElements = new ArrayList<E>();
}
}
sort(comparator, true);
} catch (Exception e) {
e.printStackTrace();
search = null;
Modal.error(e.getMessage());
}
}
public String getSearch() {
return search;
}
private void buildFullTextIndex(List<E> elements) {
fullTextIndex = new FullTextIndex();
int columnCount = getColumns().length;
for (E entity : elements) {
StringBuilder fulltext = new StringBuilder(256);
Object[] searchValues = getSearchValues(entity);
if (searchValues != null) {
fulltext.append(ObjectConverter.convert(searchValues));
fulltext.append("\t");
}
for (int column = 0; column < columnCount; column++) {
fulltext.append(ObjectConverter.convert(getCheckedValue(entity,
column)));
fulltext.append("\t");
}
fullTextIndex.add(entity, fulltext.toString());
}
fullTextIndex.commit();
}
public void sort(Comparator cmp, boolean ascending) {
if (cmp != null) {
this.comparator = cmp;
}
if (this.comparator != null) {
Collections.sort(filteredElements, comparator);
}
fireEvent(ListDataEvent.CONTENTS_CHANGED, -1, -1);
}
public String[][] getDataArray() {
String[] cols = getColumns();
String[][] data = new String[getSize() + 1][cols.length];
for (int col = 0; col < cols.length; col++) {
data[0][col] = cols[col];
}
for (int row = 0; row < getSize(); row++) {
for (int col = 0; col < cols.length; col++) {
data[row + 1][col] = String
.valueOf(ObjectConverter.convert((getCheckedValue(
(E) getElementAt(row), col))));
}
}
return data;
}
}