Hi Matthias,

Thanks for sharing your ideas! They sound very interesting!
I'll take a deeper look this weekend!

Martin Grigorov
Wicket Training and Consulting
https://twitter.com/mtgrigorov

On Thu, Apr 21, 2016 at 10:19 PM, Matthias Metzger <
[email protected]> wrote:

> Hello everyone,
> I just saw yesterday, that the IModel became/will become a
> @FunctionalInterface in Wicket 8 and was very happy about it. I am also
> very happy about the ongoing implementations and discussions around lambda
> usage in Wicket, because it simplifies a lot of code.
> Now, one thing I have been working on, is implementing some of the now
> known methods of Stream<T> for a AbstractReadOnlyModel and also for other
> things - like columns. I have not seen such discussions on here, please
> forgive me if I missed that. If it has indeed not been discussed and you
> find the idea useful, you can take a look at an implementation in the
> following repository:
> https://github.com/noobymatze/lambdawicket-model/blob/master/src/main/java/com/github/noobymatze/lambdawicket/model/ReadOnlyModel.java
>
> What might we be able to do with that?
> Consider a Person containing an Address, containing a Street with a name.
> Now I want to display the name of the street. How would I go about that?new
> Label("streetName", () -> person.getAddress().getStreet().getName());
> This is one approach, but it completely ignores the possibility of null
> values and a default value for such cases. I could wrap the above in an
> Optional or create a method in the Person class like 'Optional<String>
> getStreetName() {...}'.
>
> With the proposed ReadOnlyModel I could also do it in the following way:
> new Label("streetName", ReadOnlyModel.of(person).
> map(Person::getAddress).  map(Address::getStreet).  map(Street::getName).
> orElse("n/a"));
> But that's not all. Imagine we would need to dynamically truncate the
> streetName based on user input:
> IModel<WicketFunction<String, String>> truncate = () -> str ->
> str.length() > 10 ? str.substring(0, 10) + "..." : str;
> IModel<String> truncatedStreetName = ReadOnlyModel.of(person).
> map(Person::getAddress).    map(Address::getStreet).
> map(Street::getName).    apply(truncate).    orElse("n/a");
> Now we could switch the truncate Model using a
> DropDownChoice<WicketFunction<String, String>> or by just setting the
> contained function somewhere.truncate.setObject(str -> str.substring(0,
> 20));
>
> The whole approach is - if I am not mistaken - heavier on memory, because
> instead of one IModel<String> we now have 5 or 6 Models, that cannot be
> garbage collected, because they are all needed to perform the computation.
>
> This doesn't apply for mapping over an IColumn though, because it doesn't
> need to rely on the laziness, like the ReadOnlyModel does (otherwise a
> change in truncate wouldn't mean a change in the final value), so:new
> LambdaColumn(of("Name"), Person::getAddress).  map(Address::getStreet).
> map(Street::getName).  orElse("n/a"));
> would create 4 new instances of the LambdaColumn, but 3 of them could be
> gc'd more or less the second they were created - like I said, if I am not
> mistaken.
> If this is at all an approach you think might be useful, I would be happy
> to provide the implementation of the LambdaColumn. Otherwise just ignore my
> message. :)
> Have a nice day,Matthias
>

Reply via email to