package fr.openwide.core.wicket.more.markup.html.collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.apache.wicket.Component; import org.apache.wicket.markup.repeater.AbstractPageableView; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.ReuseIfModelsEqualStrategy; import org.apache.wicket.model.IModel; import com.google.common.collect.UnmodifiableIterator; import fr.openwide.core.wicket.more.markup.html.model.ListItemModel; public abstract class IndexedItemListView<T> extends AbstractPageableView<T> { // Does not implement IGenericComponent<C> in order to allow using IModel<? extends List<T>>, not only IModel<List<T>> private static final long serialVersionUID = 6410475416792396400L; public IndexedItemListView(String id, IModel<? extends List<T>> model) { super(id, model); } @SuppressWarnings("unchecked") public IModel<? extends List<T>> getModel() { return (IModel<List<T>>) getDefaultModel(); } @SuppressWarnings("unchecked") public List<T> getModelObject() { return (List<T>) getDefaultModelObject(); } private ListItemModel<T> newItemModel(int index) { return new ListItemModel<T>(getModel(), index); } @Override protected Iterator<IModel<T>> getItemModels(final long offset, final long size) { final List<T> list = getModelObject(); if (list == null) { return Collections.emptyIterator(); } return new UnmodifiableIterator<IModel<T>>() { private int index = (int) offset; private final int end = (int) (offset + size); @Override public boolean hasNext() { return index < end && index < internalGetItemCount(); } @Override public IModel<T> next() { return newItemModel(index++); } }; } @Override protected long internalGetItemCount() { return getModelObject().size(); } /** * Useful when using a {@link ReuseIfModelsEqualStrategy} : removes the item from the underlying model AND the view * and reorganizes the other items so that their respective indices are up-to-date. */ public final void removeItem(Item<T> item) { removeItemFromView(item); removeItemFromModel(item); } /** * Useful when using a {@link ReuseIfModelsEqualStrategy} : removes the item from the view (not the model) and reorganizes * the other items so that their respective indices are up-to-date. */ protected final void removeItemFromView(Item<T> item) { item.remove(); for (Component child : this) { @SuppressWarnings("unchecked") Item<T> childItem = (Item<T>) child; int childIndex = childItem.getIndex(); if (childIndex > item.getIndex()) { --childIndex; childItem.setIndex(childIndex); ((ListItemModel<?>)childItem.getModel()).getIndexModel().setObject(childIndex); } } } protected void removeItemFromModel(Item<T> item) { getModelObject().remove(item.getIndex()); } }