/** * Copyright 2012 Universitat Pompeu Fabra. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * */ package org.onexus.website.api.widgets.tableviewer; import org.apache.wicket.extensions.markup.html.repeater.data.sort.ISortState; import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder; import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider; import org.apache.wicket.model.IModel; import org.apache.wicket.model.LoadableDetachableModel; import org.onexus.collection.api.ICollectionManager; import org.onexus.collection.api.IEntityTable; import org.onexus.collection.api.query.OrderBy; import org.onexus.collection.api.query.Query; import org.onexus.resource.api.Progress; import org.onexus.website.api.WebsiteApplication; import org.onexus.website.api.widgets.tableviewer.headers.FieldHeader; import javax.inject.Inject; import java.util.Iterator; public class EntitiesRowProvider implements ISortableDataProvider<IEntityTable, String> { @Inject private ICollectionManager collectionManager; private IModel<TableViewerStatus> statusModel; private transient EntitiesRow rows; private SortState sortState = new SortState(); private int rowsPerPage; private long knownSize; private long realSize; private Query query; public EntitiesRowProvider(IModel<TableViewerStatus> status, int rowsPerPage) { WebsiteApplication.inject(this); this.statusModel = status; this.rowsPerPage = rowsPerPage; this.knownSize = rowsPerPage + 2; this.realSize = -1; } public EntitiesRowProvider(Query query, IModel<TableViewerStatus> status, int rowsPerPage) { this(status, rowsPerPage); this.query = query; } protected TableViewerStatus getTableViewerStatus() { return statusModel.getObject(); } public void close() { if (rows != null) { rows.close(); } } @Override public Iterator<IEntityTable> iterator(long first, long total) { Query query = getQuery(); query.setOffset(first); query.setCount(total); return new SpyIterator<IEntityTable>(first, total, loadIterator(query)); } @Override public long size() { if (realSize != -1) { return realSize; } return knownSize; } public void clearCount() { this.realSize = -1; this.knownSize = rowsPerPage + 2; } public void forceCount() { if (realSize == -1) { Query query = getQuery(); IEntityTable entityTable = collectionManager.load(query); Progress progress = entityTable.getProgress(); if (progress != null && !progress.isDone()) { addTaskStatus(entityTable.getProgress()); } this.realSize = entityTable.size(); this.knownSize = this.realSize; } } public long getRealSize() { return realSize; } public void setRealSize(long realSize) { this.realSize = realSize; } public long getKnownSize() { return knownSize; } public void setKnownSize(long knownSize) { this.knownSize = knownSize; } protected Query getQuery() { return this.query; } protected void addTaskStatus(Progress progressStatus) { } private Iterator<IEntityTable> loadIterator(Query query) { if (rows == null) { //TODO IEntityTable entityTable = ProgressBar.show(collectionManager.load(query)); IEntityTable entityTable = collectionManager.load(query); Progress progress = entityTable.getProgress(); if (progress != null && !progress.isDone()) { addTaskStatus(entityTable.getProgress()); } rows = new EntitiesRow(entityTable); } return rows; } @Override public IModel<IEntityTable> model(IEntityTable object) { return new EntityMatrixModel(object); } @Override public void detach() { if (rows != null) { statusModel.detach(); rows = null; } } @Override public ISortState getSortState() { return sortState; } @Deprecated public class EntityMatrixModel extends LoadableDetachableModel<IEntityTable> { private Query query; public EntityMatrixModel(IEntityTable matrix) { super(matrix); this.query = matrix.getQuery(); } @Override protected IEntityTable load() { return collectionManager.load(query); } } public class SortState implements ISortState<String> { @Override public void setPropertySortOrder(String property, SortOrder order) { String[] values = property .split(FieldHeader.SORT_PROPERTY_SEPARATOR); String collectionId = values[0]; String fieldName = values[1]; EntitiesRowProvider.this.realSize = -1; EntitiesRowProvider.this.knownSize = EntitiesRowProvider.this.rowsPerPage + 2; getTableViewerStatus().setOrder(new OrderBy(collectionId, fieldName, order == SortOrder.ASCENDING)); } @Override public SortOrder getPropertySortOrder(String property) { String[] values = property.split(FieldHeader.SORT_PROPERTY_SEPARATOR); String collectionId = values[0]; String fieldId = values[1]; OrderBy order = getTableViewerStatus().getOrder(); if (order != null && collectionId.endsWith(order.getCollection()) && order.getField().equals(fieldId)) { return order.isAscendent() ? SortOrder.ASCENDING : SortOrder.DESCENDING; } return SortOrder.NONE; } } public class SpyIterator<T> implements Iterator<T> { private long first, total; private Iterator<T> it; private long currentPos; public SpyIterator(long first, long total, Iterator<T> it) { this.first = first; this.it = it; this.total = total; this.currentPos = first - 1; } @Override public boolean hasNext() { boolean hasNext = it.hasNext(); if (!hasNext && (currentPos - first < total)) { EntitiesRowProvider.this.knownSize = currentPos + 1; EntitiesRowProvider.this.realSize = currentPos + 1; } return hasNext; } @Override public T next() { currentPos++; return it.next(); } @Override public void remove() { it.remove(); } } }