package fr.openwide.core.wicket.more.link.descriptor.mapper; import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.IModel; import org.javatuples.Pair; import org.javatuples.Triplet; import com.google.common.base.Function; import fr.openwide.core.wicket.more.model.ReadOnlyModel; import fr.openwide.core.wicket.more.util.model.Models; public abstract class AbstractThreeParameterLinkDescriptorMapper<L, T1, T2, T3> implements IThreeParameterLinkDescriptorMapper<L, T1, T2, T3> { private static final long serialVersionUID = 1993813798185549585L; @Override public void detach() { } @Override public abstract L map(Triplet<? extends IModel<T1>, ? extends IModel<T2>, ? extends IModel<T3>> param); @Override public final L map(IModel<T1> model1, IModel<T2> model2, IModel<T3> model3) { return map(Triplet.with(model1, model2, model3)); } private static final class DerivingModel<U1, U2, U> extends AbstractReadOnlyModel<U> { private static final long serialVersionUID = 1L; private final Pair<? extends IModel<U1>, ? extends IModel<U2>> models; private final Function<Pair<U1, U2>, U> function; public DerivingModel(Pair<? extends IModel<U1>, ? extends IModel<U2>> models, Function<Pair<U1, U2>, U> function) { super(); this.models = models; this.function = function; } @Override public U getObject() { return function.apply(Pair.with(models.getValue0().getObject(), models.getValue1().getObject())); } } @Override public ITwoParameterLinkDescriptorMapper<L, T2, T3> setParameter1(final IModel<T1> model1) { return new AbstractTwoParameterLinkDescriptorMapper<L, T2, T3>() { private static final long serialVersionUID = 1L; @Override public L map(Pair<? extends IModel<T2>, ? extends IModel<T3>> param) { return AbstractThreeParameterLinkDescriptorMapper.this.map(param.addAt0(model1)); } @Override public void detach() { super.detach(); model1.detach(); AbstractThreeParameterLinkDescriptorMapper.this.detach(); } }; } @Override public ITwoParameterLinkDescriptorMapper<L, T2, T3> setParameter1(final Function<Pair<T2, T3>, T1> function) { return new AbstractTwoParameterLinkDescriptorMapper<L, T2, T3>() { private static final long serialVersionUID = 1L; @Override public L map(Pair<? extends IModel<T2>, ? extends IModel<T3>> param) { return AbstractThreeParameterLinkDescriptorMapper.this.map(param.addAt0(new DerivingModel<>(param, function))); } @Override public void detach() { super.detach(); AbstractThreeParameterLinkDescriptorMapper.this.detach(); } }; } @Override public <U1 extends T1> IThreeParameterLinkDescriptorMapper<L, U1, T2, T3> castParameter1() { return new AbstractThreeParameterLinkDescriptorMapper<L, U1, T2, T3>() { private static final long serialVersionUID = 1L; @Override public L map(Triplet<? extends IModel<U1>, ? extends IModel<T2>, ? extends IModel<T3>> param) { return AbstractThreeParameterLinkDescriptorMapper.this.map(param.setAt0(ReadOnlyModel.<T1>of(param.getValue0()))); } @Override public void detach() { super.detach(); AbstractThreeParameterLinkDescriptorMapper.this.detach(); } }; } @Override public ITwoParameterLinkDescriptorMapper<L, T2, T3> ignoreParameter1() { return setParameter1(Models.<T1>placeholder()); } @Override public ITwoParameterLinkDescriptorMapper<L, T1, T3> setParameter2(final IModel<T2> model2) { return new AbstractTwoParameterLinkDescriptorMapper<L, T1, T3>() { private static final long serialVersionUID = 1L; @Override public L map(Pair<? extends IModel<T1>, ? extends IModel<T3>> param) { return AbstractThreeParameterLinkDescriptorMapper.this.map(param.addAt1(model2)); } @Override public void detach() { super.detach(); model2.detach(); AbstractThreeParameterLinkDescriptorMapper.this.detach(); } }; } @Override public ITwoParameterLinkDescriptorMapper<L, T1, T3> setParameter2(final Function<Pair<T1, T3>, T2> function) { return new AbstractTwoParameterLinkDescriptorMapper<L, T1, T3>() { private static final long serialVersionUID = 1L; @Override public L map(Pair<? extends IModel<T1>, ? extends IModel<T3>> param) { return AbstractThreeParameterLinkDescriptorMapper.this.map(param.addAt1(new DerivingModel<>(param, function))); } @Override public void detach() { super.detach(); AbstractThreeParameterLinkDescriptorMapper.this.detach(); } }; } @Override public <U2 extends T2> IThreeParameterLinkDescriptorMapper<L, T1, U2, T3> castParameter2() { return new AbstractThreeParameterLinkDescriptorMapper<L, T1, U2, T3>() { private static final long serialVersionUID = 1L; @Override public L map(Triplet<? extends IModel<T1>, ? extends IModel<U2>, ? extends IModel<T3>> param) { return AbstractThreeParameterLinkDescriptorMapper.this.map(param.setAt1(ReadOnlyModel.<T2>of(param.getValue1()))); } @Override public void detach() { super.detach(); AbstractThreeParameterLinkDescriptorMapper.this.detach(); } }; } @Override public ITwoParameterLinkDescriptorMapper<L, T1, T3> ignoreParameter2() { return setParameter2(Models.<T2>placeholder()); } @Override public ITwoParameterLinkDescriptorMapper<L, T1, T2> setParameter3(final IModel<T3> model3) { return new AbstractTwoParameterLinkDescriptorMapper<L, T1, T2>() { private static final long serialVersionUID = 1L; @Override public L map(Pair<? extends IModel<T1>, ? extends IModel<T2>> param) { return AbstractThreeParameterLinkDescriptorMapper.this.map(param.addAt2(model3)); } @Override public void detach() { super.detach(); model3.detach(); AbstractThreeParameterLinkDescriptorMapper.this.detach(); } }; } @Override public ITwoParameterLinkDescriptorMapper<L, T1, T2> setParameter3(final Function<Pair<T1, T2>, T3> function) { return new AbstractTwoParameterLinkDescriptorMapper<L, T1, T2>() { private static final long serialVersionUID = 1L; @Override public L map(Pair<? extends IModel<T1>, ? extends IModel<T2>> param) { return AbstractThreeParameterLinkDescriptorMapper.this.map(param.addAt2(new DerivingModel<>(param, function))); } @Override public void detach() { super.detach(); AbstractThreeParameterLinkDescriptorMapper.this.detach(); } }; } @Override public <U3 extends T3> IThreeParameterLinkDescriptorMapper<L, T1, T2, U3> castParameter3() { return new AbstractThreeParameterLinkDescriptorMapper<L, T1, T2, U3>() { private static final long serialVersionUID = 1L; @Override public L map(Triplet<? extends IModel<T1>, ? extends IModel<T2>, ? extends IModel<U3>> param) { return AbstractThreeParameterLinkDescriptorMapper.this.map(param.setAt2(ReadOnlyModel.<T3>of(param.getValue2()))); } @Override public void detach() { super.detach(); AbstractThreeParameterLinkDescriptorMapper.this.detach(); } }; } @Override public ITwoParameterLinkDescriptorMapper<L, T1, T2> ignoreParameter3() { return setParameter3(Models.<T3>placeholder()); } }