2006년 1월 2일 월요일

AJAX-JSF Framework

logo
My Cat
Home:Projects Russian About Author
Cocoon Java Sserver Faces AJAX-JSF Framework Asterisk IP-PBX  

Abstract


Goals for this project - create framework for building light-weight clients for applications like ERP, CMS, Mail ( like Gmail ) etc. with AJAX technology, based on Java Server Faces.  It designed for maximal compability with standard JSF lifecicle, and can use any existing JSF components. Since JSF support most of capability desctop application like SWING ( MVC, events, validation, converters ) such client may be designed ( and work ) same as non-web desktop application.

In short, base idea very simple :

In JSF application, we have tree of components, wich rendered ( at render responce phase ) to HTML code. This tree have good navigation with unique ID's path's. This ID's having a single meaning to convert as HTML element ID ( clientID ). On other hand, on client side we have DOM tree, builded from HTML code. This tree reflect view tree on server side. Role of AJAX framevork - send user input information to server, render ONLY changed components and update client DOM tree with this changes. To set up a correspondence between rendered component and element in DOM tree used clientID. In resault, we have two - way communication between client and server, what keep same both tree. You can see process on UML sequence diagram. For some reasons, list of components, rendered at current response, must be builded by application author. I assume, what it must be more effectively, when automatic comparison.

Realisation

link to code repository  http://svn.demi.spb.ru/repository/myfaces-ajax/src/ . 

Also, You can see JavaDoc at http://smirnov.org.ru/api/

3 main parts of code :

  1. AjaxContainer - interface for controlled component. At most, all HTML code ( may be except html/body tags ) must  be generated inside of component, implemented this interface. Such component must have rendersChildren property set to "true", and maintain parts of view Tree, rendered at current request. Most of methods in interface targeted to maintain list of such parts. Activity diagramm for this component.

    I have two implementations - UIAjaxViewComponent for usual JSF applications, and JabberClient , for in-page instant messaging client. JabberClient designed for render necessary parts in PhaseListener, and set responseComplete in FacesContext. Activity diagramm for this component.

    Crazy idea - make subclass From UIViewRoot, what implements interface and replace class for UIViewRoot in FacesConfig ... You can convert any JSF page to AJAX without any modifications ...

    Since all children components of AjaxConteainer renders in usual render response phase, we don't need any modifications to components. In any cases, may be used custom renderer. For maintain rendered parts , was created special Listener and JSP tag for it - <ajax:update> for Action or DataChange Events. If event occurs, Id's targets, updated in current request, appended to list of rendered areas in AjaxContainer ( in format of findComponent method ). At most cases, we need only 2 custom tags and renderers - CommandButton and CommandLink. For data components, <ajax:update> tag must add correspondence JavaScript code to on... events.

  2. Second part - filter Servlet, maintained format of information, sent to client. In case of simple http request, filter do nothing. In case of AJAX request, filter parse output html with nekkoHtml parser, and serialize to client as valid XML ( in case of request produced by XmlHttpRequest or Microsoft ActiveX XMLHTTP ), or , as JSON - like javascript text for "JavaScript"HttpRequest - reserved technology for case if native xml objects don't supported .

  3. Third part - client _javascript_ code. For special AJAX requests, script imitate normal form submit ( build  application/x-www-form-urlencoded request string ), create supported version of request object ( xmlhttpRequest, MS ActiveX, for browser independensy I use Sarissa JavaScript Library, or special dynamic JavaScript Request, code based by Dmitry Koterov JSHttpRequesthttp://forum.dklab.ru/users/DmitryKoterov/  ) and send information to server. On completed request, onreadystate handler get from response id's of rendered elements, find appropriate in DOM tree and replace it content by new information from response. Other parts of _javascript_ code - error and request status handling.

As result, we have two-way communications between client DOM Tree and Java Server Faces View tree. 

Worked sample

You can see worked sample at my server.  On left side of page - MyFaces Tomahawk  TabbedPane component, with custom tag and custom renderer. On change tab, only content of pane updated. First tab - MyFaces Tomahawk Tree2 component, with same tag but little changed renderer. It not modification, but any bug correction ( changed 4 lines of original code ). On expand-collapse leaf, only content of tree updated. On item, only updated content of box on right side page.
Second tab - any input-output components. Third tab - x:DataTable component with DataScpoller. Usual Components, with original tags and renderers. On scrolling, only content of table updated.
Right side of page - standard SelectOne component, with custom onchange JavaScript code. On select item, changed visible panel of PanelStack below.
Bottom of page - request status indicator. On start request, color changed to red. After last request completed, color change to green.
Cocoon Java Server Faces AJAX-JSF Framework Asterisk IP-PBX  
Copyright 2005. All rights reserved.
Contact: Webmaster

댓글 없음:

댓글 쓰기