I think that you may be hit by some type erasure on the map. That said
Tapestry also has some correctness issues with some generic constructs
where it detects a too generic type in some complex cases.

We are overriding the GenericsUtils class with an implementation that uses
Guava's TypeToken for most of its generics work - That improves the
situation a lot, but if your example code is what you actually use, then
that is probably not the issue here.

In this case I think that you would be best off setting up the eventlink
context in java code. IMO it is better style to have all but the most
simple expressions in the Java class and if you build the Object[]  (the
entire parameter value, not its "parts") in Java, this is not an issue to
begin with.

-- 
Chris

On Tue, Oct 2, 2018 at 4:48 PM D. R. <d.re...@googlemail.com.invalid> wrote:

> Hi @all,
>
> I am confused about calling a java method with an eventlink and multiple
> context parameters:
> t:context="[account.get('test').userUuid, friend]" does not work, see
> below please.
>
> Following stuff is in my Java class:
>
> @Property(write = false)
> private final String friend = "friend";
> public AbstractMap<String, UserAccount> getAccount() {
>      UserAccount userAcc = userAccounts.get(loopContactIndex);
>      AbstractMap<String, UserAccount> test = new HashMap<String,
> UserAccount>();
>      test.put("test", userAcc);
>      return test;
> }
>
> void onChangeRelation(final String uuid, final String relation) {
>      // no chance to come inside here...
> }
>
>
> void onForget(final String uuid) {
>         // everything ok here...
> }
>
> It is no problem to call "onForget" with this eventlink:
>      <t:eventlink t:event="forget" t:async="true"
> t:context="account.get('test').userUuid"> Forget </t:eventlink>
>
> But if I try to call an eventlink like:
>      <t:eventlink t:event="changeRelation" t:async="true"
> t:context="[account.get('test').userUuid, friend]"> Change Relation
> </t:eventlink>
>
> then I get following exception:
>
> Exception assembling root component of page profile/User: Exception
> assembling embedded component 'usercontactlist' (of type
> com.myapp.t5.components.profile.UserContactList, within profile/User):
> Could not convert '[account.get('test').userUuid, friend]' into a
> component parameter binding: Exception generating conduit for expression
> '[account.get('test').userUuid, friend]': Class java.lang.Object does
> not contain a property (or public field) named 'userUuid'.
>
> Now I tried this eventlink:
>      <t:eventlink t:event="changeRelation" t:async="true"
> t:context="[${account.get('test').userUuid}, friend]"> Change Relation
> </t:eventlink>
> And the page loads successful.
>
> But a click on this eventlink, calls the wrong method with only one
> parameter which is converted to java.lang.String:
>
> void onChangeRelation(final Object param) {
>      System.out.println(param.getClass().getName() + ": " + param);
> }
>
> Console --> java.lang.String: [018260e7-844c-44a5-aefc-12faa80de42c,
> friend]
>
> means t:context="[${account.get('test').userUuid}, friend]" is
> interpreted as a String.
>
> if I remove the Map and return UserAccount directly in "getAccount()"
> the code works great:
>      <t:eventlink t:event="changeRelation" t:async="true"
> t:context="[account.userUuid, friend]"> Change Relation </t:eventlink>
>
> Furthermore I tried to replace the AbstractMap with Optional class:
>      <t:eventlink t:event="changeRelation" t:async="true"
> t:context="[account.get().userUuid, friend]"> Change Relation
> </t:eventlink>
>
> With this I get the same exception:
>
> Exception assembling root component of page profile/User: Exception
> assembling embedded component 'usercontactlist' (of type
> com.myapp.t5.components.profile.UserContactList, within profile/User):
> Could not convert '[account.get().userUuid, friend]' into a component
> parameter binding: Exception generating conduit for expression
> '[account.get().userUuid, friend]': Class java.lang.Object does not
> contain a property (or public field) named 'userUuid'.
>
> Why the second level is treated as Object, if i want to get a value in
> the third level?
> (i know, we could solve that by providing another getter in the java
> class, but this violates "code less, deliver more" :-)
> Why does this occur only in case of an eventlink with multiple parameters?
> What i am doing wrong?
>
> Thanks for help!
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>

Reply via email to