Issue Details (XML | Word | Printable)

Key: JAVASERVERFACES_SPEC_PUBLIC-145
Type: New Feature New Feature
Status: Resolved Resolved
Resolution: Fixed
Priority: Critical Critical
Assignee: Ed Burns
Reporter: Ed Burns
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
javaserverfaces-spec-public

invokeOnComponent: a new way to find a node in a UIComponent tree.

Created: 08/Feb/06 02:04 PM   Updated: 04/Mar/10 02:09 PM   Resolved: 04/Mar/10 02:09 PM
Component/s: Uncategorized
Affects Version/s: 1.1
Fix Version/s: 1.2

Time Tracking:
Not Specified

File Attachments: 1. GZip Archive jsf-api-145.tar.gz (32 kB) 09/Feb/06 03:52 PM - Ed Burns
2. Text File message.txt (89 kB) 13/Feb/06 07:08 AM - Ed Burns
3. Text File message.txt (25 kB) 10/Feb/06 06:51 AM - Ed Burns

Environment:

Operating System: All
Platform: Sun


Issuezilla Id: 145
Tags:
Participants: Ed Burns, rogerk and Ryan Lubke


 Description  « Hide

Summary:
========

a new way to find a node in a UIComponent tree.

Perception Problems solved by this proposal
===========================================

JSF is just starting to win over people as a good AJAX solution, as
evidenced by discussion on about the Blueprints JSF AJAXs components on
TheServerSide.com. Having this level of support in the Core API will
demonstrate that the JSF development team is showing thought leadership
in the AJAX area.

Technical Problems solved by this proposal
==========================================

Here are just a few of the problems solved by this proposal.

1. the "findComponent" problem.

Several people on the external forums and mailing lists, as well as
people inside of Sun, including the Braveheart team, have pointed out
the problems with our existing implementation of
UIComponent.findComponent(). This method does fulfill the contract in
its javadoc, but that contract doesn't always fulfill the user's
expectations of a findComponent() type method.

2. The "find component while preserving context" problem

Currently there is no way to find a specific component nested within
an iterating component, such as UIData, while preserving the state of
that component relative to its parent. For example. If we have a
UIData that points at a database table with 10,000 rows, and, for some
reason, we want the third colum of the 1972nd row, we have no way to
get that component with the proper data.

3. Run the JSF lifecycle just on a part of the component tree.

One approach for doing AJAX with JSF is to render the tree once using
the full HTTP/Request Response and JSF lifecycle, and then render
changes to subtrees over AJAX.

Technical Details of the Proposal
=================================

1. Add new method to UIComponent:

/**
*

  • <p>This method is similar to {@link #findComponent} but it doesn't
  • take {@link NamingContainer}s into account. It just literally
  • searches through the children of this node looking for a match to
  • the argument clientId.</p>
    *
  • <p>The default implementation will first check if
  • this.getClientId() is equal to the argument clientId. If so, call
  • the {@link Callback#invoke} method on the argument callback,
  • passing through the FacesContext argument and passing this as the
  • component argument. If an Exception is thrown by the callback,
  • wrap it in a FacesException and re-throw it. Otherwise, return
  • true.</p>
    *
  • <p>Otherwise, for each component returned by {@link * #getFacetsAndChildrenIterator}, call invokeOnComponent() passing
  • the arguments to this method, in order. The first time
  • invokeOnComponent() returns true, abort traversing the rest of the
  • iterator and return true.</p>
    *
  • <p>If none of the UIComponent elements of the Iterator returned
  • true from invokeOnComponent(), return false.</p>
    *
  • @since 1.2
    *
  • @param context the {@link FacesContext} for the current request
    *
  • @param clientId the client identifier of the component to be passed
  • to the argument callback.
    *
  • @param callback an implementation of the Callback interface.
    *
  • @throws NullPointerException if any of the arguments are null
    *
  • @throws FacesException if the argument Callback throws an
  • Exception, it is wrapped in a FacesException and re-thrown.
    *
  • @returns true if the a component with the given clientId is found,
  • the callback method was sucessfully invoked passing that component
  • as an argument, and no Exception was thrown. Returns false if no
  • component with the given clientId is found.
    *
    */

boolean invokeOnComponent(FacesContext context, String clientId, Callback
callback) throws FacesException;

2. Add an implementation of this method to UIComponentBase.

boolean invokeOnComponent(FacesContext context, String clientId,
Callback callback) {
if (clientId.equals(this.getClientId(faces)) {
try { callback.invoke(context, this); return true; }
catch (Exception e) { throw new FacesException(e); }
} else {
Iterator<UIComponent> itr = this.getFacetsAndChildrenIterator();
boolean found = false;
while (itr.hasNext() & !found) { found = itr.next().invokeOnComponent(context, clientId, callback); }
}
return false;
}

3. Add new interface javax.faces.component.ComponentCallback:

/**

  • <p>A simple callback interace that enables taking action on a
  • specific UIComponent (either facet or child) in the view while
  • preserving any contextual state for that component instance in the
  • view.</p>
    *
    */

public interface ComponentCallback { public void invoke(FacesContext faces, UIComponent component); }



Ed Burns added a comment - 08/Feb/06 02:05 PM

Moving to p2


Ed Burns added a comment - 09/Feb/06 08:40 AM

accept, posted to EG.


Ed Burns added a comment - 09/Feb/06 03:52 PM

Created an attachment (id=80)
Snapshot of fix for posterity. Core function works, adding corner case tests.


Ed Burns added a comment - 10/Feb/06 06:51 AM

Created an attachment (id=81)
Fix for this issue, version 1


rogerk added a comment - 10/Feb/06 07:17 AM

r=rogerk


Ed Burns added a comment - 10/Feb/06 08:02 AM

Ok, I'm checking in this version, but not closing until the EG review period ends.


Ed Burns added a comment - 13/Feb/06 07:08 AM

Created an attachment (id=82)
Fix for this issue, version 2, includes UIData change.


Ryan Lubke added a comment - 13/Feb/06 08:10 AM

Ensure invokeOnComponent honors NPE contract for all implementations of the
method as well as tests validating the NPE is thrown.

Other than that, r=rlubke.


Ed Burns added a comment - 13/Feb/06 08:11 AM

Ok, thanks for the review. I have done so.

Upon checkin, I'll send an email to Nick including the test code to ease the TCK
process.

Ed


Ed Burns added a comment - 13/Feb/06 08:30 AM

Fix checked in.


Ed Burns added a comment - 03/Mar/06 09:29 AM

Fix checked in.


Ed Burns added a comment - 24/Nov/09 07:48 AM

Prepare to delete "spec" subcomponent.


Ed Burns added a comment - 04/Mar/10 02:09 PM

Move all to 1.2