jsr344-experts@javaserverfaces-spec-public.java.net

[jsr344-experts] Re: [SPEC-901] PROPOSAL: Close 901, fix 755

From: Leonardo Uribe <lu4242_at_gmail.com>
Date: Thu, 21 Jul 2011 23:15:21 -0500

Hi

Sorry for the late response. I did not read the ACTION section (maybe
I should say didn't understand the question and its consequences) ,
because my intention at start was provided the solution for:

http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-755

and on the way I forgot this issue, because Jakob already worked on
this one and provided a patch. I think that part is still incomplete,
but I can rework the patch if it is needed.

I'm a fan of "targets" concept. I think it is nice and simple to
undestand. But the point of this issue is there is a flaw on "targets"
attribute design. Suppose you have a composite component with this
cc:interface declaration:

okCancelPanel.xhtml

<cc:interface>
    <cc:actionSource name="okButton"/>
    <cc:actionSource name="cancelButton"/>
</cc:interface>

And now another composite component decorating the previous one:

loginPanel.xhtml

<cc:interface>
    <cc:actionSource name="loginButton" targets="panel otherActionSource"/>
    <cc:actionSource name="cancelButton" targets="panel"/>
</cc:interface>
<cc:implementation>
    <test:okCancelPanel id="panel">
        <!-- .... some stuff here ... -->
    </test:okCancelPanel>
    <yy:otherActionSourceComponent />
</cc:implementation>

and on the declaration you have something like this:

<test:loginPanel>
   <f:actionListener for="loginButton" ... />
   <f:actionListener for="cancelButton" ... />
</test:loginPanel>

The previous example has something missing. Cancel button will work,
because the name used in "for" does not change ("cancelButton")
between the nested composite components, but you can't redirect
loginButton to okButton. Note "targets" points to two components. Note
in this case, we can't add any attribute on cc:actionSource to rename
the attribute, like we did on cc:attribute targetAttributeName,
remember? What can we do in this case? Based on the latest discussion
the idea was do this:


<cc:interface>
    <cc:actionSource name="loginButton" targets="otherActionSource"/>
    <cc:actionSource name="cancelButton" targets="panel"/>
</cc:interface>
<cc:implementation>
    <test:okCancelPanel id="panel">
        <cc:implementActionSource name="loginButton" for="okButton"/>
        <!-- .... some stuff here ... -->
    </test:okCancelPanel>
    <yy:otherActionSourceComponent />
</cc:implementation>

cc:implementActionSource (or maybe cc:bind, I don't know a better
name, is up to you to define that) works just like "targets", but
since it is a tag defined "in site", it can rename the value used in a
outside "for" attribute and make this abstraction work. In theory this
tag could be used with/without define "for" attribute, so in practice
it is a replacement for "targets" attribute. But to be more specific,
the intention is use it only in this specific use case. Unfortunately
a tag like this one cannot be done outside the spec.

I believe with this description it is clear the intention of this
issue and the difference with JAVASERVERFACES_SPEC_PUBLIC-755, which
was already solved in MyFaces 2.0 / 2.1. Please reconsider this issue
for JSF 2.2 or at least reopen this issue, because anyway it is clear
the flaw is there.

regards,

Leonardo Uribe

2011/6/2 Ed Burns <edward.burns_at_oracle.com>:
> I have gone through the archives for this issue and cite below the
> relevant discussion to bring us all back up to speed on this issue.
>
> Please read through and look for ACTION.
>
>>>>>> On Fri, 29 Oct 2010 21:06:31 -0600, David Geary <clarity.training_at_gmail.com> said:
>
> DG> 2010/10/29 Jakob Korherr <jakob.korherr_at_gmail.com>
>
> JK> Thanks, Andy! Frankly I also do not really like the term "insert"
> JK> here, because - as you said - it just does not fit that well. However
> JK> I really, really like "implements" - this is just soo much better :)
> JK>
> JK> <h:commandButton ....>
> JK> <cc:implementsActionSource name="myActionSource" />
> JK> </h:commandButton>
> JK>
> JK> Really beautiful!
>
>>>>>> On Fri, 29 Oct 2010 21:06:31 -0600, David Geary <clarity.training_at_gmail.com> said:
>
> DG> It seems that I am perhaps the only dissenting voice here, but I
> DG> don't care for this solution.
>
> DG> To those of us that understand the rationale for removing targets
> DG> and adding these cc:implements... tags, the new tags make perfect
> DG> sense. But to the uninitiated, they will be bewildering. What does
> DG> it mean for a button to "implements action source"? Buttons already
> DG> implement action source. IMO, targets are much easier to understand,
> DG> and to explain.
>
> DG> I understand the urge to remove the targets attribute based on their
> DG> OO impurity, but I think the solution could use some more
> DG> thought. There are already too many arcane oddities in JSF, whose
> DG> rationale is only intuited by high priests, and I hate to see us
> DG> adding more.
>
>>>>>> On Sat, 30 Oct 2010 10:33:37 -0400, Andy Schwartz <andy.schwartz_at_oracle.com> said:
>
> AS> Ed also raised this concern. If we are going to continue on with
> AS> this approach (and I hope that we do), perhaps we need to come up
> AS> with less ambiguous names for these tags.
>
> JK> To wrap this up again, I'd propose to add these tags for JSF 2.1 in
> JK> order to make the life of our users a lot easier:
>
> JK> <cc:implementsActionSource name="XXX" />
> JK> <cc:implementsEditableValueHolder name="XXX" />
> JK> <cc:implementsValueHolder name="XXX" />
> JK> <cc:insertClientBehavior name="XXX" />
>
> DG> Is it just possible to do this with component ids, and forgo the extra tag
> DG> altogether?
>
> DG> <composite:interface>
> DG>   <composite:actionSource name="loginButton"/>
> DG>  </composite:interface>
>
> DG>  <composite:implementation>
> DG>   <h:commandButton id="loginButton">
> DG>   </h:commandButton>
> DG>  </composite:implementation>
>
> In fact, this is how it works already.  Consider the docs for the "name attribute in cc:actionSource. [1]
>
>  The value of this attribute maps back to the "for" attribute on an
>  attachable object nested within a composite component. If the
>  "targets" attribute is not specified, this value also represents the
>  component ID of the target component within the that the
>  <composite:implementation> ActionListener should be mapped to.
>
>>>>>> On Thu, 4 Nov 2010 12:34:24 +0100, Jakob Korherr <jakob.korherr_at_gmail.com> said:
>
> JK> Actually, this is already possible in JSF 2.0, but - as Andy pointed
> JK> out earlier - it packs a lot of information into the name attribute
> JK> and furthermore you can't apply the same actionSource (or valueHolder
> JK> or..) multiple times.
>
> Jakob or Martin, ignoring OO purity for the moment, is the inability to
> apply the same actionSource (or valueHolder, etc.) multiple times the
> only functional problem with the current approach?
>
>>>>>> On Thu, 4 Nov 2010 09:53:05 +0100, Martin Marinschek <mmarinschek_at_apache.org> said:
>
> MM> As long as we can pass multiple actions to a composite component and
> MM> pass actionListeners, etc. to a nested composite component I am ok
> MM> with waiting for the rest, as I said before.
>
> MM> But please make sure these two things are in - we cannot continue
> MM> using composite components without this!
>
> This comment indicates that this inability is indeed the most pressing
> problem.
>
> Leonardo points out that there is a patch for this particular problem at
> <http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-755>.
>
> DG> Finally, perhaps I missed this in the thread, but does this solution
> DG> let a composite component author bind multiple targets (sorry) to a
> DG> single source?
>
> DG> Again, I agree with the problems that Andy so eloquently
> DG> described. I'd just like to see us take a little more time to think
> DG> through the solution.
>
>>>>>> On Mon, 1 Nov 2010 20:07:00 +0100, Jakob Korherr <jakob.korherr_at_gmail.com> said:
>
> JK> @David: OK, sorry I misunderstood your mail. Please take a look at the
> JK> patch and also the usage examples in the systest. IMHO "implements"
> JK> (or "insert" in the case of clientBehavior) fits really, really well
> JK> here, because it tells us that the surrounding button implements the
> JK> action source with the name XXX of the composite component. And yes,
> JK> multiple action source implementations are possible. However we most
> JK> certainly can discuss this ;)
>
>>>>>> On Tue, 2 Nov 2010 08:03:51 +0100, Martin Marinschek <mmarinschek_at_apache.org> said:
>
> MM> - I think that all of us should carefully think about David's
> MM> proposition to have only one tag which defines a component as the
> MM> interface implementation. Is there anything which speaks against this?
> MM> Why do we need multiple tags? We already define what the name is
> MM> supposed to be referring to in the interface, right? Also the names he
> MM> suggested seem reasonable to me.
>
> I did not detect an actual proposal from David.  Did I miss it?
>
> MM> - As for 2.1 versus 2.2: I think that the basic fixes need to be in
> MM> 2.1 - so that people can pass in multiple actions, and use actions,
> MM> actionListeners, etc. independent of needing to provide references to
> MM> the implementation - which just not work, as we have seen trying out
> MM> this approach in the real world. The rest could also be in 2.2 - I
> MM> would still be in favor of having this in 2.1, but of course all of
> MM> the timing is entirely Ed's decision.
>
> Well, we missed 2.1 and I'm trying to reach a resolution on this for
> 2.2.
>
>>>>>> On Thu, 4 Nov 2010 12:34:24 +0100, Jakob Korherr <jakob.korherr_at_gmail.com> said:
>
> JK> To wrap this up again, we have had the following ideas for tag names
> JK> already:
>
> JK> - cc:insertXXX
> JK> - cc:implementsXXX
> JK> - cc:exposesXXX
> JK> - cc:referencesXXX
> JK> - cc:refersToXXX
> JK> - cc:bindXXX
> JK> - cc:wireXXX
>
> JK> I still like "implements" best, but I guess every tag of the above
> JK> will do the job.
>
>>>>>> On Tue, 02 Nov 2010 10:24:03 -0400, Andy Schwartz <andy.schwartz_at_oracle.com> said:
>
> AS> Another name that keeps popping up in my head is:
>
> AS> - <composite:bind>
>
> AS> I like the idea that we are binding the implementation component to a
> AS> piece of interface metadata via the name that they both reference.  Of
> AS> course, there is possible confusion with the "binding" attribute, though
> AS> even so I like the sound of this:
>
> AS> <composite:interface>
> AS>   <composite:actionSource name="loginEvent"/>
> AS> </composite:interface>
>
> AS> <composite:implementation>
> AS>   <h:commandButton>
> AS>     <composite:bind name="loginEvent"/>
> AS>   </h:commandButton>
> AS> </composite:implementation>
>
> AS> My take is that the context is sufficiently different from the "binding"
> AS> use case that user should not have trouble distinguishing between these
> AS> two.  This name also has the benefit that it is short and sweet: single
> AS> syllable FTW! :-)
>
> LU> To be more explicit, this is the example that should fail:
>
> I took this example and coded it up as a war and attached it to issue 901.
>
> I'm not sure if I've got it right or not.  Please take a look at the example.
>
> SECTION: Using page:
>
>      <ez:cc id="loginPanel" model="#{bean}">
>        <f:actionListener for="loginEvent" binding="#{bean.loginEventListener}" />
>        <f:actionListener for="loginEvent" binding="#{bean.loginEventListener2}" />
>        <f:actionListener for="cancelEvent" binding="#{bean.cancelEventListener}" />
>      </ez:cc>
>
> SECTION: cc.xhtml:
>
> <cc:interface name="cc">
>  <cc:actionSource name="loginEvent" />
>  <cc:actionSource name="cancelEvent" />
> </cc:interface>
>
> <cc:implementation>
>  <h:commandButton id="loginEvent" value="buttonInCc">
>  </h:commandButton>
>  <ez:cc2 id="cancelEvent">
>    <f:actionListener binding="#{cc.actionSource.cancelEvent}" for="someOtherEvent"/>
>  </ez:cc2>
> </cc:implementation>
>
> SECTION: cc2.xhtml:
>
> <cc:interface name="cc2">
>  <cc:actionSource name="someOtherEvent" />
> </cc:interface>
>
> <cc:implementation>
>  <h:commandButton id="someOtherEvent" value="buttonInCc2" />
> </cc:implementation>
>
> SECTION: UserBean.java
>
> @ManagedBean(name="bean")
> @SessionScoped
> public class UserBean {
>
>    protected ActionListenerImpl a, b, c;
>
>    public UserBean() {
>        a = new ActionListenerImpl("a called ");
>        b = new ActionListenerImpl("b called ");
>        c = new ActionListenerImpl("c called ");
>    }
>
>    public ActionListener getLoginEventListener() {
>        return a;
>    }
>
>    public ActionListener getLoginEventListener2() {
>        return b;
>    }
>
>    public ActionListener cancelEventListener(ActionEvent e) {
>        return c;
>    }
>
>    private void appendMessage(String message) {
>        FacesContext context = FacesContext.getCurrentInstance();
>        Map<String, Object> requestMap = context.getExternalContext().getRequestMap();
>        StringBuilder builder;
>        builder = (StringBuilder) requestMap.get("builder");
>        if (null == builder) {
>            builder = new StringBuilder();
>            requestMap.put("builder", builder);
>        }
>        builder.append(message);
>    }
>
>    public String getMessage() {
>        FacesContext context = FacesContext.getCurrentInstance();
>        Map<String, Object> requestMap = context.getExternalContext().getRequestMap();
>        String result = (requestMap.containsKey("builder")) ? ((StringBuilder)requestMap.get("builder")).toString() : "no message";
>
>        return result;
>    }
>
>    private class ActionListenerImpl implements ActionListener {
>
>        private String message;
>
>        private ActionListenerImpl(String message) {
>            this.message = message;
>        }
>
>        @Override
>        public void processAction(ActionEvent event) throws AbortProcessingException {
>            UserBean.this.appendMessage(message);
>
>        }
>
>
>    }
> }
>
> SECTION: Notes
>
> Pressing "buttonInCc" shows Message: a called b called.
>
> Pressing "buttonInCc2" gives an error. /resources/i_spec_901_cc/cc.xhtml @59,86 binding="#{cc.actionSource.cancelEvent}": The class 'javax.faces.component.UINamingContainer' does not have the property 'actionSource'.
>
> I think this is the expected behavior, and is what we need to implement
> to close this out.
>
> ACTION: Can we all agree that the reall problem here is the need to
> solve 755 [3]?  David Geary and I seem to be in agreement that we really
> should not introduce any other tags and I'd like to close 901 as
> WONTFIX.
>
>
> [1] http://javaserverfaces.java.net/nonav/docs/2.0/pdldocs/facelets/composite/actionSource.html
>
> [2] http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-901
>
> [3] http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-755
>
> --
> | edward.burns_at_oracle.com | office: +1 407 458 0017
> | homepage:               | http://ridingthecrest.com/
> | 10 Business Days til JSF 2.2 Early Draft Review
> | 46 Business Days til JSF 2.2 Public Review
> | 134 Business Days til JSF 2.2 Proposed Final Draft
>