package fr.openwide.core.wicket.more.model;
import java.util.List;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.javatuples.Pair;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import fr.openwide.core.commons.util.functional.SerializableSupplier;
import fr.openwide.core.wicket.more.condition.Condition;
public class JoinerModel extends LoadableDetachableModel<String> {
private static final long serialVersionUID = -1202031311993202356L;
private static final IModel<?> NULL_MODEL = new AbstractReadOnlyModel<Object>() {
private static final long serialVersionUID = 1L;
@Override
public Object getObject() {
return null;
}
};
private SerializableSupplier<Joiner> joinerSupplier;
private final List<Pair<IModel<?>, Condition>> conditionnalModels = Lists.newLinkedList();
private JoinerModel(SerializableSupplier<Joiner> joinerSupplier) {
this.joinerSupplier = joinerSupplier;
}
public static JoinerModel on(final String separator) {
return new JoinerModel(new SerializableSupplier<Joiner>() {
private static final long serialVersionUID = 1L;
@Override
public Joiner get() {
return Joiner.on(separator);
}
});
}
public JoinerModel skipNulls() {
final SerializableSupplier<Joiner> joinerSupplier = this.joinerSupplier;
this.joinerSupplier = new SerializableSupplier<Joiner>() {
private static final long serialVersionUID = 1L;
@Override
public Joiner get() {
return joinerSupplier.get().skipNulls();
}
};
return this;
}
public JoinerModel useForNull(final String nullText) {
final SerializableSupplier<Joiner> joinerSupplier = this.joinerSupplier;
this.joinerSupplier = new SerializableSupplier<Joiner>() {
private static final long serialVersionUID = 1L;
@Override
public Joiner get() {
return joinerSupplier.get().useForNull(nullText);
}
};
return this;
}
@SafeVarargs
public final JoinerModel join(IModel<?> firstModel, IModel<?>... otherModels) {
return join(Condition.alwaysTrue(), firstModel, otherModels);
}
@SafeVarargs
public final <T> JoinerModel join(Condition condition, IModel<?> firstModel, IModel<?>... otherModels) {
for (IModel<?> model : Lists.asList(firstModel, otherModels)) {
join(condition, model);
}
return this;
}
@SafeVarargs
public final <T> JoinerModel join(Predicate<? super T> predicate, IModel<? extends T> firstModel, IModel<? extends T>... otherModels) {
for (IModel<? extends T> model : Lists.asList(firstModel, otherModels)) {
join(Condition.predicate(model, predicate), model);
}
return this;
}
public final JoinerModel join(Condition condition, IModel<?> model) {
conditionnalModels.add(Pair.<IModel<?>, Condition>with(model != null ? model : NULL_MODEL, condition));
return this;
}
@Override
protected String load() {
if (joinerSupplier == null || joinerSupplier.get() == null) {
return null;
}
List<Object> values = Lists.newLinkedList();
for (Pair<IModel<?>, Condition> conditionnalModel : conditionnalModels) {
if (conditionnalModel.getValue1() == null || conditionnalModel.getValue1().applies()) {
values.add(conditionnalModel.getValue0().getObject());
}
}
return joinerSupplier.get().join(values);
}
@Override
protected void onDetach() {
super.onDetach();
for (Pair<IModel<?>, Condition> conditionnalModel : conditionnalModels) {
if (conditionnalModel != null && conditionnalModel.getValue0() != null) {
conditionnalModel.getValue0().detach();
conditionnalModel.getValue1().detach();
}
}
}
}