dev@jsf-extensions.java.net

Re: [JSF-EXT] Avatar Status (Jacob, Dan and Craig, please read)

From: <jacob_at_hookom.net>
Date: Mon, 19 Jun 2006 15:07:17 -0400

I don't think we can have a single spot for specifying the collection ids to process-- that's why I had Update vs. Encode, you don't want to update a chunk of the page that you want to re-render in all cases.



>Ed Burns wrote:
>> Here is a status report on Avatar. It's coming along. I hope to have
>> the first milestone release on the 30th.
>>
>>
>https://jsf-extensions.dev.java.net/files/documents/4613/36314/20060617-avatar-
>plan.html
>>
>> Attached for your convenience and discussion.
>>
>> I have just checked in a major change to the avatar code in
>> jsf-extensions. I'm using some ideas from Jacob's JavaOne demo as a
>> starting point. Here's what I have.
>>
>> 1.
>>
>> AjaxLifecycle
>> Description of new Avatar Implementation
>>
>> The AjaxLifecycle is now the main lifecycle for Avatar enabled
>> apps. This replaces the custom UIViewRoot approach and decorates
>> the default Lifecycle. All one need change in their web.xml is to
>> add an init-param to their Faces Servlet mapping.
>>
>>
>> <!-- Faces Servlet -->
>> <servlet>
>> <servlet-name>Faces Servlet</servlet-name>
>> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
>> <init-param>
>> <param-name>javax.faces.LIFECYCLE_ID</param-name>
>> <param-value>com.sun.faces.lifecycle.AJAX</param-value>
>> </init-param>
>> <load-on-startup>1</load-on-startup>
>> </servlet>
>>
>> <!-- Faces Servlet Mapping -->
>> <servlet-mapping>
>> <servlet-name>Faces Servlet</servlet-name>
>> <url-pattern>/faces/*</url-pattern>
>> </servlet-mapping>
>>
>> This approach has the benefit of not requiring mounting any
>> additional FacesServlet instances, nor filters or phaseListeners,
>> not to mention it frees up the UIViewRoot for others to sub-class
>> and replace if necessary.
>
>+1 - a good approach!
>
>> 2.
>>
>> Use request headers to convey ajax metadata.
>>
>> The following headers are currenty supported in the AjaxLifecycle
>>
>> com.sun.faces.Async
>>
>> If this header is present, the AjaxLifecycle treats this
>> request as an AJAX request.
>
>Could we get an extra layer of packaging under "com.sun.faces"?
>Also, "async" vs. "sync" isn't a relevant distinction here -
>a client is free to issue a synchronous XMLHttpRequest request
>(in some cases, a good idea). The distinction should be "full page"
>vs. not (aka "PartialRequest").
>
>> com.sun.faces.Subtrees
>>
>> This is a comma separated list of clientIds against which the
>> lifecycle should be run. Each lifecycle phase is run on each
>> clientId using invokeOnComponent() to ensure proper context.
>
>If absent, the entire tree should be executed. Is that how it works?
>I'd prefer the name "TargetIds", but "Subtrees" is OK.
>
>> com.sun.faces.lifecycle.RunThru
>>
>> This header gives the name of the request processing lifecycle
>> phase through which the lifecycle should be run. For example, the
>> replacement for Jacob's javax.faces.Update parameter is to define
>> the RunThru header with the value of UPDATE_MODEL_VALUES. The
>> response generated when running a partial lifecycle will be
>> described below.
>
>-0.5. Why is this set on the client? This should be determined by the
>renderer, or component, or event listener IMO. More generally, it's
>of critical importance that everything should be extensible
>programatically on the client; for instance, you have to be able to
>indicate on the server that an additional target ID needs to be
>processed. This lets you send across simple requests that only a button
>was pressed, but on the server decide that additional regions of the
>page need to be processed.
>
>Also, we have to separate two concepts:
>
> 1. Components that need to be processed (ARV through Invoke
> Application, but *not* Render Response)
> 2. Components that need to be rendered (Render Response only)
>
>Inclusion in #1 does not require inclusion in #2. For
>example, if I have a button click that re-renders a table
>via Avatar, the button gets processed (but not re-rendered),
>and the table gets re-rendered (but not processed). This isn't
>just an optimization - re-rendering components unnecessarily
>has a major negative accessibility impact.
>
>> I have the following header also in-mind, but not yet implemented:
>>
>> com.sun.faces.lifecycle.<LIFECYCLE_PHASE>
>>
>> If defined, this is a comma separated list of client ids to be
>> used for that specific lifecycle phase. This value overrides the
>> value of com.sun.faces.Subtrees for that specific phase.
>
>-1. I'd like a use case, especially before letting this be
>driven by the client.
>
>> 3.
>>
>> New XML application for AJAX responses from avatar server.
>>
>> If the request has the com.sun.faces.Async and
>> com.sun.faces.Subtrees headers, with valid values, but no
>> com.sun.faces.lifecycle.RunThru header, request will look
>> something like this:
>>
>>
>> POST http://localhost:8080/jsf-extensions/faces/result-set.jsp
>HTTP/1.1
>> Host: localhost:8080
>> User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US;
>rv:1.8.0.4) Gecko/20060508 Firefox/1.5.0.4
>> Accept: text/javascript, text/html, application/xml, text/xml, */*
>> Accept-Language: en-us,en;q=0.5
>> Accept-Encoding: gzip,deflate
>> Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
>> Keep-Alive: 300
>> Proxy-Connection: keep-alive
>> X-Requested-With: XMLHttpRequest
>> X-Prototype-Version: 1.5.0_rc0
>> Content-Type: application/x-www-form-urlencoded
>> Connection: close
>> com.sun.faces.Async: true
>> com.sun.faces.Subtrees: form:table,form:subview2
>> Content-Length: 277
>> Cookie: com.sun.faces.extensions.flashPostbackRequest=8.0;
>JSESSIONID=33ab516de8b10090a6e8c9f604f4
>> Pragma: no-cache
>> Cache-Control: no-cache
>>
>>
>options=%5Bobject%20Object%5D&form%3Ascroller_action=10&form%3Ascroller_curPage
>=1&javax.faces.ViewState=j_id3%3Aj_id4&form=form&http%3A%2F%2Flocalhost%3A8080%
>2Fjsf-extensions%2Ffaces%2Fresult-set.jsp%23=http%3A%2F%2Flocalhost%3A8080%2Fjs
>f-extensions%2Ffaces%2Fresult-set.jsp%23
>>
>>
>> And the response like this:
>>
>>
>>
>> HTTP/1.1 200 OK
>> X-Powered-By: Servlet/2.5
>> Cache-Control: no-cache
>> Content-Type: text/xml;charset=ISO-8859-1
>> Date: Sat, 17 Jun 2006 18:23:28 GMT
>> Server: Sun Java System Application Server Platform Edition 9.1
>> Connection: close
>>
>> <async-response>
>
><partial-response> would be better, as noted above.
>
>> <render id="form:table">
>> <![CDATA[<table id="form:table" class="list-background">
>> <thead>
>> <tr>
>> <th class="list-header" scope="col">Account Id</th>
>> <th class="list-header" scope="col">Customer Name</th>
>> <th class="list-header" scope="col">Symbol</th>
>> <th class="list-header" scope="col">Total Sales</th>
>> </tr>
>> </thead>
>> <tbody>
>> <tr class="list-row-even">
>> <td class="list-column-center"><span
>id="form:table:180:accountId">180</span></td>
>> <td class="list-column-center"><script type="text/javascript"
>src="http://localhost:8080/jsf-extensions/jmaki.js"></script>
>> <script
>type="text/javascript">jmaki.webRoot='http://localhost:8080/jsf-extensions';</s
>cript>
>> <script type="text/javascript"
>src="http://localhost:8080/jsf-extensions/resources/scriptaculous/prototype.js"
>></script>
>> <script type="text/javascript"
>src="http://localhost:8080/jsf-extensions/resources/scriptaculous/scriptaculous
>.js"></script>
>> <link rel="stylesheet" type="text/css"
>href="http://localhost:8080/jsf-extensions/inplace/component.css"></link>
>> <a id="form:table:180:j_id_id52" href="#">name_180</a>
>> <script type="text/javascript">
>>
>jmaki.addWidget({service:'http://localhost:8080/jsf-extensions/faces/result-set
>.jsp',script:'http://localhost:8080/jsf-extensions//inplace/component.js',uuid:
>'form:table:180:j_id_id52',name:'inplace',id:'form:table:180:j_id_id52'});</scr
>ipt>
>> </td>
>> <td class="list-column-center"><span
>id="form:table:180:symbol">symbol_180</span></td>
>> <td class="list-column-center"><span
>id="form:table:180:totalSales">180.0</span></td>
>> </tr>
>>
>> <-- additional rows omitted -->]]></render>
>> <render id="form:subview2">
>> <![CDATA[<div id="form:subview2"><table border="0" cellpadding="0"
>align="center"><tr align="center" valign="top"><td><font size="-1">Result
>Page: </font></td><td>
>> <a href="#"
>onmousedown="document.forms[0]['form:scroller_action'].value='-2';
>document.forms[0]['form:scroller_curPage'].value='10';
>document.forms[0].submit()">Previous<img
>src="/jsf-extensions/images/arrow-left.gif" alt="" /><br /></a></td><td>
>> <a href="#"
>onmousedown="document.forms[0]['form:scroller_action'].value='1';
>document.forms[0]['form:scroller_curPage'].value='10';
>document.forms[0].submit()">1</a></td>
>>
>> <!-- additional cells omitted -->
>> </tr><input type="hidden" name="form:scroller_action"/>
>> <input type="hidden" name="form:scroller_curPage"/></table>
>>
>> <script type='text/javascript'>
>> document.forms[0].submit = function() {};
>> var a = $('form:subview2').getElementsByTagName('a');
>> $A(a).each(function(e) {
>> new Faces.Command(e, 'mousedown', { subtrees:
>'form:table,form:subview2' });
>> });
>> </script>
>> </div>]]></render>
>> <state>
>> <![CDATA[j_id3:j_id4]]>
>> </state>
>> </async-response>
>>
>> To support simple updating (with validation and conversion properly
>handled) of one or more values in the component tree, use the RunThru header
>with a value of UPDATE_MODEL_VALUES. A request with this header looks like
>this:
>
>I don't much like this; it requires the client has knowledge of what's
>meant by "setting the value" of a particular component on a client,
>which requires deep markup knowledge once you get past basic input
>components.
>
>> POST http://localhost:8080/jsf-extensions/faces/result-set.jsp
>HTTP/1.1
>> Host: localhost:8080
>> User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US;
>rv:1.8.0.4) Gecko/20060508 Firefox/1.5.0.4
>> Accept: text/javascript, text/html, application/xml, text/xml, */*
>> Accept-Language: en-us,en;q=0.5
>> Accept-Encoding: gzip,deflate
>> Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
>> Keep-Alive: 300
>> Proxy-Connection: keep-alive
>> X-Requested-With: XMLHttpRequest
>> X-Prototype-Version: 1.5.0_rc0
>> Content-Type: application/x-www-form-urlencoded
>> Connection: close
>> com.sun.faces.Async: true
>> com.sun.faces.Subtrees: form:table:181:j_id_id52
>> com.sun.faces.lifecycle.RunThru: UPDATE_MODEL_VALUES
>> Content-Length: 163
>> Cookie: com.sun.faces.extensions.flashPostbackRequest=8.0;
>JSESSIONID=33ab516de8b10090a6e8c9f604f4
>> Pragma: no-cache
>> Cache-Control: no-cache
>>
>>
>form%3Atable%3A181%3Aj_id_id52=181&form%3Atable%3A181%3Aj_id_id52-inplaceeditor
>=form%3Atable%3A181%3Aj_id_id52-inplaceeditor&javax.faces.ViewState=j_id3%3Aj_i
>d4&_=
>>
>> And the response will look like this:
>>
>>
>> HTTP/1.1 200 OK
>> X-Powered-By: Servlet/2.5
>> Cache-Control: no-cache
>> Content-Type: text/xml;charset=ISO-8859-1
>> Content-Length: 133
>> Date: Sat, 17 Jun 2006 18:29:42 GMT
>> Server: Sun Java System Application Server Platform Edition 9.1
>> Connection: close
>>
>> <async-response><update
>id="form:table:181:j_id_id52"><![CDATA[181]]></update><state><![CDATA[j_id3:j_i
>d4]]></state></async-response>
>>
>> The values returned is subject to conversion and validation with
>> any converters or validators that are attached to the component.
>>
>> This implementation also supports updating multiple components in
>> the tree with a single transaction.
>
>Additional feature that would be very useful: return any
>FacesMessages in XML blocks, then call a user-defined callback
>with an array of those messages.
>
>> Next Steps - Concrete Tasks
>>
>> Currently, the result-set.jsp example, in the run-time-test
>> module, is the only one that works. My next step is to take
>> Jacob's JavaOne demo and move it into our repo and make it work
>> with the avatar impl. This will require support for Jacob's
>> javax.faces.Event header, which I don't think will be too hard to
>> add, but we'll see.
>>
>> After that, I want to get the ajaxZones implementation updated to
>> use the new framework, and remove as much of my old procedural
>> JavaScript code from com_sun_faces_ajax.js as possible. In concert
>> with this task, I will make the jsf-ajax-carstore example work
>> again. This will prove out the fully functional ajaxZone concept.
>
>Why do we need any AJAX zones? -1 on any solution that requires
>explicitly marking zones. It should be sufficient to have an "id"
>set on any JSF component.
>
>-- Adam
>
>
>> Next Steps - Concepts
>>
>> You can see where I'm going with this lifecycle idea. I'd like to
>> expose the JSF lifecycle easily to AJAX. One interesting idea is
>> to pass up a chunk of JavaScript in the AJAX request, along with
>> processing instructions about it, that will cause the JavaScript
>> to be executed on the server to help serv up the response. We'd
>> need Phobos to do this, but I think having the ability for the
>> client to send up JavaScript to the server to be executed in the
>> context of the JSF lifecycle is a powerful feature.
>>
>> Another idea is to make the rendering of the response pluggable so
>> that one could send the response back in JSON instead of hard
>> coded XML. Perhaps Dan Labreque can help with this.
>>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: dev-unsubscribe_at_jsf-extensions.dev.java.net
>For additional commands, e-mail: dev-help_at_jsf-extensions.dev.java.net
>