package fr.openwide.core.wicket.more.util.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.wicket.markup.repeater.data.IDataProvider;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import com.google.common.collect.ImmutableList;
import fr.openwide.core.wicket.more.markup.repeater.collection.IItemModelAwareCollectionModel;
import fr.openwide.core.wicket.more.markup.repeater.sequence.ISequenceProvider;
public final class SequenceProviders {
private SequenceProviders() {
}
/**
* @return A read-only model representing a list of each model object, in the same order.
*/
public static <T, M extends IModel<T>> IItemModelAwareCollectionModel<T, List<T>, M> fromItemModels(
Collection<? extends M> models) {
return new ConstantCollectionModel<>(models);
}
public static class ConstantCollectionModel<T, M extends IModel<T>>
extends LoadableDetachableModel<List<T>>
implements IItemModelAwareCollectionModel<T, List<T>, M> {
private static final long serialVersionUID = 1L;
private final Collection<M> models;
public ConstantCollectionModel(Collection<? extends M> models) {
super();
this.models = ImmutableList.copyOf(models);
}
@Override
public void detach() {
Detachables.detach(models);
}
@Override
public Iterator<M> iterator(long offset, long limit) {
return Models.collectionModelIterator(models, offset, limit);
}
@Override
public long size() {
return models.size();
}
@Override
protected List<T> load() {
List<T> result = new ArrayList<>(models.size());
for (M model : models) {
result.add(model.getObject());
}
return Collections.unmodifiableList(result);
}
@Override
public void setObject(List<T> object) {
throw new UnsupportedOperationException("This model is read-only");
}
@Override
public Iterator<M> iterator() {
return Models.collectionModelIterator(models);
}
@Override
public void add(T item) {
throw new UnsupportedOperationException("This model is read-only");
}
@Override
public void remove(T item) {
throw new UnsupportedOperationException("This model is read-only");
}
@Override
public void clear() {
throw new UnsupportedOperationException("This model is read-only");
}
}
public static <T> ISequenceProvider<T> forDataProvider(IDataProvider<T> dataProvider) {
return new DataProviderSequenceProviderAdapter<T>(dataProvider);
}
public static class DataProviderSequenceProviderAdapter<T> implements ISequenceProvider<T> {
private static final long serialVersionUID = 1L;
private final IDataProvider<T> dataProvider;
public DataProviderSequenceProviderAdapter(IDataProvider<T> dataProvider) {
this.dataProvider = dataProvider;
}
@Override
public void detach() {
dataProvider.detach();
}
@Override
public Iterator<? extends IModel<T>> iterator(final long offset, final long limit) {
return new Iterator<IModel<T>>() {
private Iterator<? extends T> dataIterator = dataProvider.iterator(offset, limit);
@Override
public boolean hasNext() {
return dataIterator.hasNext();
}
@Override
public IModel<T> next() {
return dataProvider.model(dataIterator.next());
}
@Override
public void remove() {
dataIterator.remove();
}
};
}
@Override
public long size() {
return dataProvider.size();
}
}
}