Portable Portlet Development with RSF Antranig Basman, CARET, University of Cambridge

advertisement
Portable Portlet Development
with RSF
Antranig Basman,
CARET, University of Cambridge
Introducing RSF
• What is it, Doctor??
RSF is a Java web programming framework, with roughly the
same scope as Sun’s JSF – it takes care of:
• Locating and rendering views
• Managing server-side and client-side state
• Handling and abstracting the request cycle
It does NOT take care of:
• What lies behind your data model (ORM)
Hibernate & co are highly developed solutions to this which
RSF aims to facilitate, not replace.
Why (YET) another web framework?
• There are now over two dozen open source Java web
frameworks out there (many probably moribund/defunct)
• Would properly need pretty good reason to create
another
• RSF grew out of work with JSF and preserves all of its
key value points
• JSF suffers from numerous architectural, practical and
philosophical problems
• Also, JSF is not adapted for lifecycles/environments
typically found in academic institutional development
– long maintenance lifetimes
– perpetual reskinning/branding
– interface aggregation/flexible delivery engines (accessibility
vs. AJAX flashiness, thin/thick clients)
RSF from JSF I
• JSF core value points:
– JSF is portable1 – can target the same code at
portlet/servlet environments,
– as well as different markup dialects
– JSF features a bean line – communication from
view layer to model is only via EL expressions,
reflectively evaluating value bindings and method
bindings
*nearly* - after 3 years and despite both being Sun standards, JSF  JSR-168
integration is still incomplete (portal modes &c)
1
RSF from JSF II
• JSF core deficits:
– Neither JSF inputs nor outputs are any kind of
XML (by default crummy taglibs as input, halfassed, Javascript-laden HTML as output)
– Does not properly separate logic from presentation
(even with Facelets, input “templates” contain
iteration and model logic and are NOT safe to give
to designers)
– Makes heavyweight use of session state, destroys
server efficiency, breaks URL idioms and browser
forking
RSF from JSF III
• JSF core deficits II
– Lack of support for many core pieces of the browser
idiom (bookmarkability, back button, browser forking,
POST->GET, GET forms &c &c)
– Fragile request lifecycle (“Phase” system) behaves
erratically in presence of exceptions, is generally
monolithic and uncontrollable
– IoC integration is at best awkward (JSF-Spring)
– Is simply in general a pain to work with – taglibs are
hard to write, framework is highly intrusive, stateful
and heavyweight (FacesContext)
– Could go on much longer! (see RSF wiki)
Architectural Snapshots #1: JSF
Haunted House
• Designed on a grand scale
• Lots of thought to
architecture, ambitious
reach
• Large, complex
• Lots of strange noises and
inexplicable phenomena
Quick Recap of RSF Points
• The key RSF features are:
– Pure (REALLY pure) HTML templating
– Zero server state processing
– Built ENTIRELY of a set of Spring contexts,
rather than merely “integrating” with Spring
– Request-scope IoC container, RSAC
– RSAC leads to straightforward and slick
integration even with extremely peculiar
environments (JSR-168, Cocoon, Hibernate,
Sakai are all in the bag – IChannel is coming)
• Integrations are always only a few hundred LOC
• JSF  JSR-168 is thousands
RSF compared to JSF
• RSF preserves all the “key value points” of JSF
– Abstract “component tree” isolates you from view technology
– EL bindings system isolates the data model from the view layer
– Abstract dispatching procedure isolates you from the hosting
environment (Servlets, Portlets, Sakai – IChannel?)
• But delivers on all its promises and more
–
–
–
–
–
Free of “model” classes coupling you to the framework
“Speak like a native” approach to HTML – anything is possible
Test your UI in the filesystem, full previewability
Output is GUARANTEED valid XML
IoC throughout the framework means application fragility does
not increase with size, testability &c.
State in RSF
• The key difference for folks coming from JSF is that
RSF holds zero server state by default
• Not only the component tree, but also the entire client
model are thrown away at the end of every request
• Server resource are precious, and the “time between
requests” for a particular user is very large in server
terms – why keep around something you could easily
regenerate (your app has its own model)?
• A better fit for HTTP which is a stateless protocol. RSF
apps are very URL-response, and much more amenable
to HTTP tools such as caches, proxies &c
Case Study I : Sakai TaskList App
• Part of the Sakai “Programmers’ Cafe” exercise at
Sakai Vancouver Conference June 2006
• The simplest app that could be useful
• Demonstrates most of the key requirements on a
Sakai app
– ORM using standard Sakai SessionFactory (as well as
other approaches, abstracted behind a DAO interface)
– Rendering compliant with Sakai Style Guide
– Exposing a Sakai-wide service API
• Written in JSF
– Easily the most problematic aspect of the whole tool
JSF Tasklist App Structure
TaskList.jsp
TaskListBean.java
DataModel
TaskListServiceImpl.java
TaskListService.java
TaskBeanWrapper.java
TaskList.java
TaskListManager.java
Thinking
• Looking at the TaskListService API in detail, it becomes clear that
it only really has value *within* the app
• This API was created because it is awkward to deliver enough of
the Sakai and other Spring dependencies to a JSF-managed bean
• This API and Impl can be destroyed completely in the RSF
version
• We know that in the RSF version, the view logic in the JSP will be
placed into a ViewProducer, TaskListProducer
• The ViewProducer is *already* a Spring-configured bean, so the
dependencies which used to be delivered to TaskListServiceImpl
will be transferred onto TaskListProducer
• Since the Producer is normal Java code which has full access to
the application state, the “Wrapper” class is also unnecessary.
• The presence of the DataModel in what should be the business
layer of the app was an unconditional excrescence.
JSF Tasklist App Structure 2
TaskList.jsp
TaskListBean.java
DataModel
TaskListServiceImpl.java
TaskListService.java
TaskBeanWrapper.java
TaskList.java
TaskListManager.java
RSF Tasklist App Structure
TaskList.html
TaskListProducer.java
TaskListBean.java
TaskListManager.java
TaskList.java
It doesn’t stop there
• RSF ORM “idiom” rather than “library”
• OTP (= “One True Path”) assigns unique
EL path to each entity of data model
• RSF “EL” is slimmed down so much
(only elementary reads/writes permitted)
that it is safe to address arbitrarily nasty
“POJO” models, even those managed by
Hibernate
• Abolition of “DAO”s
RSF Tasklist App Structure with OTP
TaskList.html
TaskListProducer.java
TaskListBean.java
TaskListManager.java
TaskList.java
Result:
• A Sakai app free of ANY SAKAI CODE
• A Hibernate app free of ANY HIBERNATE CODE
• Pure HTML templating makes app effortlessly
reskinnable by anyone armed with a copy of
Dreamweaver
• Portable to any environment (where the functionality is
relevant) – could become a JSR-168 app with no code
changes
• This is impossible with any other framework
NB – could have tried this with interfaces, but this tends to create a fragile design – need to
anticipate all design points up front, rather than “abstraction on demand” through requestscope IoC. This approach leads to defining an entire “abstraction platform” covering all
cases with “kitchen-sink” type interfaces.
Case Study II: Spring MVC “Step
by Step” Product sample
• Thomas Risberg’s very useful walkthrough of a
SpringMVC app
http://www.springframework.org/docs/MVC-step-by-step/Spring-MVC-step-by-step.html
• SpringMVC is worthy but modest
• Hampered by “Lowest Common Denominator” of
existing view technologies
• Spring philosophy of “work what what is there
already, do not implement”
• Is NOT portable (Servlet and Portlet packages are
named similarly, but are not interchangeable)
Architectural Snapshots #2: SpringMVC
Bungalow
• Modest, competent
• Works fairly well for everyone
• Doesn’t get you very high off the ground (in
terms of abstraction)
1. SpringMVC integration
• The IKAT renderer from RSF has been ported to
SpringMVC
• Can be used as “just another SpringMVC rendering
technology”, along with Velocity, FreeMarker and
JSPs
• Creates some duplication (Controllers/Producers), but
highly useful for making reskinnable apps
• “Step by Step” rewritten with drop-in replacement for
JSPs, no other code changed
• Resulting app is reskinnable, but still not portable
2. SpringMVC replacement
• Entire app rewritten using RSF
• Much code disappears, increased level of abstraction
• Preserves ALL non-SpringMVC code with no changes
– Business model/“manager”
– DAOs
– Spring Validation
• Resulting app *IS* portable to JSR-168, as a result of
destroying SpringMVC “Controller” layer
• Not only is the Controller unit testable, but the
renderer is as well!! First closed-loop UI testing.
RSF and AJAX
• Everyone talks about this, so I’d better
• Since RSF preserves complete autonomy on the
client (*pure* HTML templates), all native clientside AJAX libraries integrate naturally – no need
for AJAX “components” in the framework
• Lots of success with
– Prototype.js
– Script.aculo.us
– Rico
• RSF renderer is markup agnostic, no problem
rendering XML for AJAX tables (Rico), HTML
fragments for divs (Ajax.Update) or full pages
with embedded AJAX calls.
• Ask Steve Githens (on the RSF forums)
RSF Timeline
July 2005
“JSFUtil” destroyed
September 2005
RSF 0.5 demonstrated at Developers’ Meeting, Cambridge –
UIOutput and UIInput only
December 2005
RSF 0.6 – UIType system stabilised, Flow “Lite”
April 2006
RSF 0.6.1 – Reformed build system, Hibernate support, full
XML component serialisability, UISelect – First public
release, JIRA, forums
May 2006
RSF 0.6.3 – Complete set of HTML components, non-HTML
ContentTypes (XUL, RSS, AJAX), JSR-168
August 2006
RSF 0.6.4 – SpringMVC integration, support for Sakai 2.2,
Hibernate 3 (IChannel?). Last 0.6 release
September 2006
RSF 0.7 – Multi-file templates, custom components,
“Renderer reform”
Early 2007
RSF 1.0 – General shakedown, acceptance testing, load
testing, beginnings of GWT-style integration
The future
RSF 2.0 – AutoAJAX, Differential IKAT and the Bean
Invalidation Model…. leading to “Snooze”
Acknowledgements
The CARET Team
Raymond Chan
Andrew Thornton
Dan Sheppard
Ian Boston
and
John Norman
RSF
http://www2.caret.cam.ac.uk/rsfwiki
Download