the reason i did not provide this when i wrote the repeaters package is that
it can lead down some pretty awful roads. an easy example where this goes
totally wrong is when you use detachable models for the items. if you use
this decorator all models from the previous page will be loaded because they
will all be compared - but in case of the detachable model it is not
necesary to load the object, it is enough to only compare the id.

so while this makes it easy it also makes it easy to make something
inefficient because you dont have to think about it.

+0

-igor


On 8/26/07, Eelco Hillenius <[EMAIL PROTECTED]> wrote:
>
> Hi,
>
> For Wicket In Action in converted an example from a ListView to a
> RepeatingView. This example has to function in a form, so I set the
> 'ReuseIfModelsEqualStrategy'. Overriding hashCode (and equals) on the
> model however results in quite a bit of code bloat, while my hunch is
> that comparing the model values is actually a pretty common use case.
>
> So, in my quest to cut down a few lines, I would basically have two
> choices: implement a reuse strategy that does this, or implement a
> model wrapper that implements hashCode and equals in a generic
> fashion. I choose the latter, and would like to hear your opinions
> whether this is something we could add to the project (I think the use
> case for it should be common enough, especially since I would mention
> it in the book), or whether you would prefer to have a reuse strategy
> that does this.
>
> I'd really like to see one of these in the project, as otherwise I
> would have to either include the equals/ hashCode implementation
> inline, which bloats the example, or I would have to give the code in
> the book as people will want to play with it. Both would suck.
>
> Cheers,
>
> Eelco
>
> My implementation (no javadocs):
>
> package wicket.in.action.common;
>
> import java.io.ObjectStreamException;
> import java.io.Serializable;
> import java.lang.reflect.InvocationHandler;
> import java.lang.reflect.Method;
> import java.lang.reflect.Proxy;
>
> import org.apache.wicket.model.IModel;
> import org.apache.wicket.util.lang.Objects;
>
> public final class EqualsDecorator {
>
>   private EqualsDecorator() {
>   }
>
>   public static IModel decorate(final IModel model) {
>     return (IModel) Proxy.newProxyInstance(model.getClass()
>         .getClassLoader(), model.getClass().getInterfaces(),
>         new Decorator(model));
>   }
>
>   private static class Decorator implements InvocationHandler,
>       Serializable {
>
>     private final IModel model;
>
>     Decorator(IModel model) {
>       this.model = model;
>     }
>
>     public Object invoke(Object proxy, Method method, Object[] args)
>         throws Throwable {
>       String methodName = method.getName();
>       if (methodName.equals("equals")) {
>         if (args[0] instanceof IModel) {
>           return Objects.equal(model.getObject(), ((IModel) args[0])
>               .getObject());
>         }
>       } else if (methodName.equals("hashCode")) {
>         Object val = model.getObject();
>         return 37 + (val != null ? val.hashCode() : 0);
>       } else if (methodName.equals("writeReplace")) {
>         return new SerializableReplacement(model);
>       }
>       return method.invoke(model, args);
>     }
>   }
>
>   private static class SerializableReplacement implements
>       Serializable {
>     private final IModel model;
>
>     SerializableReplacement(IModel model) {
>       this.model = model;
>     }
>
>     private Object readResolve() throws ObjectStreamException {
>       return decorate(model);
>     }
>   }
> }
>

Reply via email to