From 095cb327c0b952bb734e1ce1bfa1da41abc69426 Mon Sep 17 00:00:00 2001 From: Matthias Metzger Date: Sun, 24 Apr 2016 20:37:44 +0200 Subject: [PATCH 1/4] fix formatting in IModel --- .../java/org/apache/wicket/model/IModel.java | 83 ++++++++++++------- 1 file changed, 55 insertions(+), 28 deletions(-) diff --git a/wicket-core/src/main/java/org/apache/wicket/model/IModel.java b/wicket-core/src/main/java/org/apache/wicket/model/IModel.java index eef15e150e2..fe17b26806a 100644 --- a/wicket-core/src/main/java/org/apache/wicket/model/IModel.java +++ b/wicket-core/src/main/java/org/apache/wicket/model/IModel.java @@ -91,13 +91,17 @@ default void detach() {} * @param predicate a predicate to be used for testing the contained object * @return a new IModel */ - default IModel filter(WicketFunction predicate) { - return (IModel) () -> { + default IModel filter(WicketFunction predicate) + { + return (IModel) () -> + { T object = IModel.this.getObject(); - if (object != null && predicate.apply(object)) { + if (object != null && predicate.apply(object)) + { return object; } - else { + else + { return null; } }; @@ -111,13 +115,17 @@ default IModel filter(WicketFunction predicate) { * @param mapper a mapper, to be applied to the contained object * @return a new IModel */ - default IModel map(WicketFunction mapper) { - return (IModel) () -> { + default IModel map(WicketFunction mapper) + { + return (IModel) () -> + { T object = IModel.this.getObject(); - if (object == null) { + if (object == null) + { return null; } - else { + else + { return mapper.apply(object); } }; @@ -134,14 +142,18 @@ default IModel map(WicketFunction mapper) { * @param other another model to be combined with this one * @return a new IModel */ - default IModel mapWith(WicketBiFunction combine, IModel other) { - return (IModel) () -> { + default IModel mapWith(WicketBiFunction combine, IModel other) + { + return (IModel) () -> + { T t = IModel.this.getObject(); U u = other.getObject(); - if (t != null && u != null) { + if (t != null && u != null) + { return combine.apply(t, u); } - else { + else + { return null; } }; @@ -155,8 +167,9 @@ default IModel mapWith(WicketBiFunction combi * @param mapper a mapper, to be applied to the contained object * @return a new IModel */ - default IModel flatMap(WicketFunction> mapper) { - T object = IModel.this.getObject(); + default IModel flatMap(WicketFunction> mapper) + { + T object = IModel.this.getObject(); return mapper.apply(object); } @@ -169,14 +182,18 @@ default IModel flatMap(WicketFunction> mapper) { * to the contained model object. * @return a new IModel */ - default IModel apply(IModel> mapper) { - return (IModel) () -> { + default IModel apply(IModel> mapper) + { + return (IModel) () -> + { T object = IModel.this.getObject(); WicketFunction f = mapper.getObject(); - if (object == null || f == null) { + if (object == null || f == null) + { return null; } - else { + else + { return f.apply(object); } }; @@ -190,13 +207,17 @@ default IModel apply(IModel> mapper) { * @param other a default value * @return a new IModel */ - default IModel orElse(T other) { - return (IModel) () -> { + default IModel orElse(T other) + { + return (IModel) () -> + { T object = IModel.this.getObject(); - if (object == null) { + if (object == null) + { return other; } - else { + else + { return object; } }; @@ -210,12 +231,15 @@ default IModel orElse(T other) { * @return a new IModel */ default IModel orElseGet(WicketSupplier other) { - return (IModel) () -> { + return (IModel) () -> + { T object = IModel.this.getObject(); - if (object == null) { + if (object == null) + { return other.get(); } - else { + else + { return object; } }; @@ -229,7 +253,8 @@ default IModel orElseGet(WicketSupplier other) { * @param object an object to be lifted into a IModel * @return a new IModel */ - static IModel of(T object) { + static IModel of(T object) + { return of((WicketSupplier) () -> object); } @@ -241,7 +266,8 @@ static IModel of(T object) { * @param supplier a supplier, to be used to get a value * @return a new IModel */ - static IModel of(WicketSupplier supplier) { + static IModel of(WicketSupplier supplier) + { return (IModel) () -> supplier.get(); } @@ -253,7 +279,8 @@ static IModel of(WicketSupplier supplier) { * @param model a model, * @return a new IModel */ - static IModel of(IModel model) { + static IModel of(IModel model) + { return (IModel) () -> model.getObject(); } } From 4348962480949f61574a5172ca6b7f7749ddc5ff Mon Sep 17 00:00:00 2001 From: Matthias Metzger Date: Sun, 24 Apr 2016 20:42:40 +0200 Subject: [PATCH 2/4] implement idea for lazy flatMap in IModel This approach has two problems though: 1. For every call of getObject, setObject and detach the whole model chain will be evaluated again. 2. It's the same problem like with the implementation before. When the setObject is called and any value in the retrieval has been null, no object will be set, which is unlike the PropertyModel, which would initialize any values being null. --- .../java/org/apache/wicket/model/IModel.java | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/wicket-core/src/main/java/org/apache/wicket/model/IModel.java b/wicket-core/src/main/java/org/apache/wicket/model/IModel.java index fe17b26806a..d26036083a0 100644 --- a/wicket-core/src/main/java/org/apache/wicket/model/IModel.java +++ b/wicket-core/src/main/java/org/apache/wicket/model/IModel.java @@ -169,8 +169,47 @@ default IModel mapWith(WicketBiFunction combi */ default IModel flatMap(WicketFunction> mapper) { - T object = IModel.this.getObject(); - return mapper.apply(object); + return new IModel() + { + + @Override + public R getObject() + { + T object = IModel.this.getObject(); + if (object != null) + { + return mapper.apply(object).getObject(); + } + else + { + return null; + } + } + + @Override + public void setObject(R object) + { + T modelObject = IModel.this.getObject(); + if (modelObject != null) + { + mapper.apply(modelObject).setObject(object); + } + } + + @Override + public void detach() + { + T object = IModel.this.getObject(); + if (object != null) + { + IModel model = mapper.apply(object); + if (model != null) + { + model.detach(); + } + } + } + }; } /** From 3719da912cea48e2a9f8ec4de4672379a93954de Mon Sep 17 00:00:00 2001 From: Matthias Metzger Date: Sun, 24 Apr 2016 20:58:58 +0200 Subject: [PATCH 3/4] fix wrong formatting --- .../java/org/apache/wicket/model/IModel.java | 295 +++++++++--------- 1 file changed, 153 insertions(+), 142 deletions(-) diff --git a/wicket-core/src/main/java/org/apache/wicket/model/IModel.java b/wicket-core/src/main/java/org/apache/wicket/model/IModel.java index d26036083a0..a85365c4b18 100644 --- a/wicket-core/src/main/java/org/apache/wicket/model/IModel.java +++ b/wicket-core/src/main/java/org/apache/wicket/model/IModel.java @@ -73,253 +73,264 @@ public interface IModel extends IDetachable * * @param object * The model object - * @throws UnsupportedOperationException unless overridden + * @throws UnsupportedOperationException + * unless overridden */ default void setObject(final T object) { - throw new UnsupportedOperationException("Override this method to support setObject(Object)"); + throw new UnsupportedOperationException( + "Override this method to support setObject(Object)"); } @Override - default void detach() {} + default void detach() + { + } /** - * Returns a IModel checking whether the predicate holds for the - * contained object, if it is not null. If the predicate doesn't evaluate - * to true, the contained object will be null. + * Returns a IModel checking whether the predicate holds for the contained object, if it is not + * null. If the predicate doesn't evaluate to true, the contained object will be null. * - * @param predicate a predicate to be used for testing the contained object + * @param predicate + * a predicate to be used for testing the contained object * @return a new IModel */ - default IModel filter(WicketFunction predicate) - { - return (IModel) () -> - { + default IModel filter(WicketFunction predicate) + { + return (IModel)() -> { T object = IModel.this.getObject(); - if (object != null && predicate.apply(object)) - { + if (object != null && predicate.apply(object)) + { return object; } - else - { + else + { return null; } }; } /** - * Returns a IModel applying the given mapper to - * the contained object, if it is not NULL. + * Returns a IModel applying the given mapper to the contained object, if it is not NULL. * - * @param the new type of the contained object - * @param mapper a mapper, to be applied to the contained object + * @param + * the new type of the contained object + * @param mapper + * a mapper, to be applied to the contained object * @return a new IModel */ - default IModel map(WicketFunction mapper) - { - return (IModel) () -> - { + default IModel map(WicketFunction mapper) + { + return (IModel)() -> { T object = IModel.this.getObject(); - if (object == null) - { + if (object == null) + { return null; } - else - { + else + { return mapper.apply(object); } }; } /** - * Returns a IModel applying the given combining function to - * the contained object of this and the given other model, if they are not null. + * Returns a IModel applying the given combining function to the contained object of this and + * the given other model, if they are not null. * - * @param the resulting type - * @param the other models type - * @param combine a function combining this and the others object to - * a result. - * @param other another model to be combined with this one + * @param + * the resulting type + * @param + * the other models type + * @param combine + * a function combining this and the others object to a result. + * @param other + * another model to be combined with this one * @return a new IModel */ - default IModel mapWith(WicketBiFunction combine, IModel other) - { - return (IModel) () -> - { + default IModel mapWith(WicketBiFunction combine, + IModel other) + { + return (IModel)() -> { T t = IModel.this.getObject(); U u = other.getObject(); - if (t != null && u != null) - { + if (t != null && u != null) + { return combine.apply(t, u); } - else - { + else + { return null; } }; } /** - * Returns a IModel applying the given mapper to the contained - * object, if it is not NULL. + * Returns a IModel applying the given mapper to the contained object, if it is not NULL. * - * @param the new type of the contained object - * @param mapper a mapper, to be applied to the contained object + * @param + * the new type of the contained object + * @param mapper + * a mapper, to be applied to the contained object * @return a new IModel */ - default IModel flatMap(WicketFunction> mapper) - { - return new IModel() - { + default IModel flatMap(WicketFunction> mapper) + { + return new IModel() + { - @Override - public R getObject() - { - T object = IModel.this.getObject(); - if (object != null) - { - return mapper.apply(object).getObject(); - } - else - { - return null; - } - } + @Override + public R getObject() + { + T object = IModel.this.getObject(); + if (object != null) + { + return mapper.apply(object).getObject(); + } + else + { + return null; + } + } - @Override - public void setObject(R object) - { - T modelObject = IModel.this.getObject(); - if (modelObject != null) - { - mapper.apply(modelObject).setObject(object); - } - } + @Override + public void setObject(R object) + { + T modelObject = IModel.this.getObject(); + if (modelObject != null) + { + mapper.apply(modelObject).setObject(object); + } + } - @Override - public void detach() - { - T object = IModel.this.getObject(); - if (object != null) - { - IModel model = mapper.apply(object); - if (model != null) - { - model.detach(); - } - } - } - }; + @Override + public void detach() + { + T object = IModel.this.getObject(); + if (object != null) + { + IModel model = mapper.apply(object); + if (model != null) + { + model.detach(); + } + } + } + }; } /** - * Returns a IModel applying the {@link WicketFunction} contained - * inside the given model to the object contained inside this model. + * Returns a IModel applying the {@link WicketFunction} contained inside the given model to the + * object contained inside this model. * - * @param the type of the new contained object - * @param mapper an {@link IModel} containing a function to be applied - * to the contained model object. + * @param + * the type of the new contained object + * @param mapper + * an {@link IModel} containing a function to be applied to the contained model + * object. * @return a new IModel */ - default IModel apply(IModel> mapper) - { - return (IModel) () -> - { + default IModel apply(IModel> mapper) + { + return (IModel)() -> { T object = IModel.this.getObject(); WicketFunction f = mapper.getObject(); - if (object == null || f == null) - { + if (object == null || f == null) + { return null; } - else - { + else + { return f.apply(object); } }; } /** - * Returns a IModel, returning either the contained object - * or the given default value, depending on the nullness of the - * contained object. + * Returns a IModel, returning either the contained object or the given default value, depending + * on the nullness of the contained object. * - * @param other a default value + * @param other + * a default value * @return a new IModel */ - default IModel orElse(T other) - { - return (IModel) () -> - { + default IModel orElse(T other) + { + return (IModel)() -> { T object = IModel.this.getObject(); - if (object == null) - { + if (object == null) + { return other; } - else - { + else + { return object; } }; } /** - * Returns a IModel, returning either the contained object - * or invoking the given supplier to get a default value. + * Returns a IModel, returning either the contained object or invoking the given supplier to get + * a default value. * - * @param other a supplier to be used as a default + * @param other + * a supplier to be used as a default * @return a new IModel */ - default IModel orElseGet(WicketSupplier other) { - return (IModel) () -> - { + default IModel orElseGet(WicketSupplier other) + { + return (IModel)() -> { T object = IModel.this.getObject(); - if (object == null) - { + if (object == null) + { return other.get(); } - else - { + else + { return object; } }; } /** - * Returns a IModel lifting the given object into the - * Model. + * Returns a IModel lifting the given object into the Model. * - * @param the type of the given object - * @param object an object to be lifted into a IModel + * @param + * the type of the given object + * @param object + * an object to be lifted into a IModel * @return a new IModel */ - static IModel of(T object) - { - return of((WicketSupplier) () -> object); + static IModel of(T object) + { + return of((WicketSupplier)() -> object); } /** - * Returns a IModel applying the given supplier to - * get the object. + * Returns a IModel applying the given supplier to get the object. * - * @param the type of the given object - * @param supplier a supplier, to be used to get a value + * @param + * the type of the given object + * @param supplier + * a supplier, to be used to get a value * @return a new IModel */ - static IModel of(WicketSupplier supplier) - { - return (IModel) () -> supplier.get(); + static IModel of(WicketSupplier supplier) + { + return (IModel)() -> supplier.get(); } /** - * Returns a IModel using the getObject() method - * of the given model. + * Returns a IModel using the getObject() method of the given model. * - * @param the type of the contained object - * @param model a model, + * @param + * the type of the contained object + * @param model + * a model, * @return a new IModel */ - static IModel of(IModel model) - { - return (IModel) () -> model.getObject(); + static IModel of(IModel model) + { + return (IModel)() -> model.getObject(); } } From a68dc57a801628c455d0aa4efc61a0b474f3bdf2 Mon Sep 17 00:00:00 2001 From: Matthias Metzger Date: Sun, 24 Apr 2016 21:22:35 +0200 Subject: [PATCH 4/4] check mapper result in #flatMap in get- and setObject --- .../java/org/apache/wicket/model/IModel.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/wicket-core/src/main/java/org/apache/wicket/model/IModel.java b/wicket-core/src/main/java/org/apache/wicket/model/IModel.java index a85365c4b18..8f86030a016 100644 --- a/wicket-core/src/main/java/org/apache/wicket/model/IModel.java +++ b/wicket-core/src/main/java/org/apache/wicket/model/IModel.java @@ -185,7 +185,15 @@ public R getObject() T object = IModel.this.getObject(); if (object != null) { - return mapper.apply(object).getObject(); + IModel model = mapper.apply(object); + if (model != null) + { + return model.getObject(); + } + else + { + return null; + } } else { @@ -199,7 +207,11 @@ public void setObject(R object) T modelObject = IModel.this.getObject(); if (modelObject != null) { - mapper.apply(modelObject).setObject(object); + IModel model = mapper.apply(modelObject); + if (model != null) + { + model.setObject(object); + } } }