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

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

From: Ed Burns <edward.burns_at_oracle.com>
Date: Thu, 2 Jun 2011 14:57:25 -0700

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