Title: Introducing RSF Reasonable Server Faces
1Introducing RSF(Reasonable Server Faces)
Aaron Zeckoski Centre for Applied Research in
Educational Technologies, University of Cambridge
(UK)
2Overview
- RSF Goals and Strategies
- Simple templating example
- XHTML and Java
- Basic application structure
- Spring contexts and Producers
- Case studies of components
- Reorderer, Date widget - Demo
- Brief overview of some more advanced features
- Validation, I18N, OTP
- Integration with Spring Web
- Demo
3Why RSF?
- RSF was designed with several special
requirements of large scale development
communities in mind - Decouple the workflows of developers and
designers/UX experts, and allow them to work
independently - Full IoC throughout the design powered by Spring,
from the view layer down to the model - Enable universal portability of apps to whatever
environments may arise, without requiring code
changes
4Designers and Coders
RSF
Markup (XHTML) CSS Images AJAX / Javascript
Java / ? SQL XML AJAX / Javascript
5RSF is for Coders and Designers
- RSF is easy for coders since it is built out of
Spring components - Can always extend/modify the framework if needed
- Once you get the pattern, it is possible to build
very powerful components and apps that require a
lot more custom/stovepipe work in other
frameworks - RSF is easy for designers since they can just
work with plain HTML and hand it over the fence
to coders who can start working with it directly - Designers can continue to update templates while
developers work without disrupting each other
6RSF and Fluid
- RSF is closely involved with the Fluid Flexible
UI project now running from UToronto and other
key institutions - http//www.fluidproject.org/
- Harness the power of designers and accessibility
experts to create inclusive designs
7Why use RSF?
- Core RSF Values
- Completely pure HTML templating
- Roundtrip with designers without loss
- Preview behaviour as well as appearance from the
file system (demo later) - Templates can be reloaded on a live server just
by dropping in files - IoC is built-in
- No need to "integrate with" Spring, RSF is built
from Spring - IoC in the request scope "refreshes the parts
other IoC cannot reach" (universal portability
without code changes)
8Three Levels of RSF
- On the design side, completely pure (X)HTML
templates, previewability of appearance AND
behaviour (IKAT renderer) - On the code side, an unintrusive binding to an
application model (EL) - Portability of applications assured through
request-scope IoC (RSAC) using Spring context
definitions - Statelessness and transparency of application
behaviour through request cycle and
ViewParameters - In between, a completely technology-neutral and
behaviour-free representation of the function
of a user interface (component tree)
9RSF structure
- The template (XHTML) defines the interface
- The producer (Java or XML) defines the view,
populates the template, and handles navigation - ViewParams define the values passed between views
(GET) - The requestContext defines producer and backing
beans - The applicationContext defines app scope beans
and handles RSF app config (via Spring) - Backing beans handle action processing
- Logic layer beans can be injected as defined in
the context XML files - Model is basic data POJO or richer domain
Template (XHTML)
ViewParams (Java)
Producer (Java)
requestContext (XML)
Backing bean (Java)
applicationContext (XML)
Logic layer (rest of app)
Model (Java)
10XHTML in RSF
Template (XHTML)
- Here is some real XHTML
- It is also an RSF template!
- To make a template, you simply add the rsfid
attribute to tags which might have their content
replaced when the app runs, or might need to be
copied or moved about
lthtmlgt ltheadgtlttitlegtRSF samplelt/titlegtlt/headgt ltbod
ygt lth1gtHello ltspan rsfiduser-namegtUser
Namelt/spangtlt/h1gt Today is ltspan
rsfidcurrent-dategt1/1/2006lt/spangtltbr/gt lttable
gt lttr rsfiditem-rowgt lttd
rsfiditem-valuegtitem value herelt/tdgt
lt/trgt lt/tablegt lt/bodygt lt/htmlgt
11RSF Templates
- The template will load and preview fine in any
browser or editor - Properly, we will always give RSF templates a
proper XHTML doctype, and namespace for the
rsfid attribute - The rsfid attribute is the ONLY addition to the
schema - RSF can actually render with any kind of XML
template, not just XHTML - Processed using the RSF IKAT renderer
lt!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Transitional//EN" "http//www.w3.org/TR/xhtml
1/DTD/xhtml1-transitional.dtd"gt lthtml
xmlnsrsf"http//ponder.org.uk/rsf"
xmlns"http//www.w3.org/1999/xhtml"gt
12Using the Template - Producers
Producer (Java)
- Everything in RSF is a Spring-configured bean of
some kind - A special kind of bean called a Producer (or View
Producer) is responsible for rendering a page
from a template - The same Producer can render from many different
templates, as long as the rsfids agree - The purpose of a Producer is to create a
Component Tree of RSF Primitive Components
which will get paired up with the template by the
RSF renderer (IKAT) - The component tree is created at the beginning,
and destroyed at the end of every render request
13View Producer
public class ItemsProducer implements
ViewComponentProducer, DefaultView ...
private CrudPlusLogic logic public void
setLogic(CrudPlusLogic logic) this.logic
logic public void fillComponents(UIContaine
r tofill, ViewParameters viewparams,
ComponentChecker checker)
UIOutput.make(tofill, "user-name",
logic.getUserName()) for (CrudPlusItem item
logic.getAllVisibleItems().iterator())
UIBranchContainer itemrow
UIBranchContainer.make(listform, "item-row",
item.getId()) UIOutput.make(itemrow,
item-value, item.getValue())
UIOutput.make(itemrow, current-date", new
Date().toString() )
- A Spring bean which defines what appears in the
view - Equivalent to its serialized form could also be
defined in XML etc. - UIOutput and UIBranchContainer are primitive RSF
components - The 2nd arguments to the make() calls match up
with the rsfids written in the template
14ViewParameters
ViewParams (Java)
- Contains all the information required to locate a
view - Is an abstract summary of the information held in
a URL (query parameters and trunk) - Should be the primary route for passing
information from view to view - Since ViewParameters contents are properly typed,
it forms a miniature "bean container" - The key to implementing RESTful "URL flows" based
on cloning - Can be reused on multiple pages
15Sample ViewParams
public class ItemViewParameters extends
SimpleViewParameters public Long id // an
identifier for an item public ItemViewParameters(
) public ItemViewParameters(String viewID,
Long id) this.id id this.viewID
viewID
- Is a "Pea" (uses public fields rather than
getters/setters) - Can override getParseSpec method to gain fine
control over URL structure
16Registering a Producer
- RSF Producers are typically declared as Spring
beans at request scope - Can be at application scope if they have no
request scope dependencies - In WEB-INF/requestContext.xml
ltbean class"org.sakaiproject.crudplus.tool.produc
ers.ItemsProducer"gt ltproperty
name"logic" ref"org.sakaiproject.crudplus.logic
.CrudPlusLogic" /gt lt/beangt
17RSAC for the request scope
requestContext (xml)
- RSF extends Spring with a fast request-scope
implementation called RSAC - All RSAC beans are lazy loaded by default
- Request-scope beans go into requestContext.xml
rather than applicationContext.xml, but the file
format is the same - Parts of the "backing model" can also be injected
into producers - Avoids framework dependencies by "fetch" with
weak typing - Backing model is marked as addressible (via EL)
over the request using a declarative syntax with
wildcards
18EL in RSF
model (Java)
- VERY lightweight version of JSF/JSP EL
- Just a dot-separated path of bean names and
properties (or 0-arg method for a method binding) - No logic allowed
- Binds component tree to the model without
polluting it - Works for any bean in request/application context
- Example UIInput accepting form input with binding
EL Reference
Bean ID
Initial value
UIInput.make(addupdateitem, "item-title",
"itemsBean.newItem.title",
DEFAULT_TITLE )
19Component Case Studies
20Component case study Reorderer
- Allows users to directly move around and
re-arrange content on the page - The content type is extremely flexible (can be
any markup or other RSF components) - Allow full accessibility via screen readers (ARIA
markup roles), and keyboard shortcuts - Developed as part of the Fluid Project
- http//wiki.fluidproject.org/display/fluid/Reorder
er
21Reorderer design workflow
- Reorderer is developed as a pure client-side
component - JSUnit tests run from the filesystem to verify
Javascript behaviour - Drag-and-drop and accessibility behaviour can be
previewed without a server - The same XHTML template functions directly as the
component definition for RSF at runtime
22Demo of Reorderer from Filesystem and Live
23Component case study Date widget
- Requirements
- Complete internationalisation support
- Accessible markup, together with good use of
screen estate and rapid use by expert users - Uses an AJAX strategy to make use of reliable
server-side date and timezone processing logic - Uses RSF's DWR-like "Universal View Bus" (UVB)
- this AJAX works fine from within a Spring Web
Flow also - As for the reorderer, markup and behaviour can be
previewed and tested in the filesystem - http//www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page
BuildingRSFComponents
24More Advanced RSF Topics
25Internationalization (I18N)
ltb rsfidremove-item"gtAre you sure you want to
remove item (title)?lt/bgt
UIMessage.make(tofill, remove-item",
"remove.item.text", new Object
item.getTitle() )
remove.item.textAre you sure you want to remove
item (0)?
- Well supported with UIMessage concrete class
- Also MessageLocator as a service
- Simple cases can be handled in the template with
rsfid"msgkey" - Takes advantage of the standard Java language
properties bundle handling - Uses Spring MessageSource for resource
(properties file) loading - Configurable in application context
URL http//www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?
pageI18N
26User-directed Messages
- Messages are held in a request-scope bean named
targettedMessageList - Propagated to the following view in a mini-flow
scope - Inject it where you want (also has a standard
proxy for use in application scope) - Messages appear in the template at the tag marked
rsfidmessage-for - Messages widget can be reskinned through
messageTemplateContributor
messages.addMessage(new TargettedMessage("item_upd
ated", new Object item.getTitle(),
TargettedMessage.SEVERITY_INFO))
27BeanGuards for Validation
- A declarative strategy for attaching rules to
modifications of the bean container - Similar to, for example, Springs declarative
transaction demarcation, or Spring Security/Acegi
declarative rules - Key functionality is to provide guaranteed
execution of logic without intruding either on
the target, or on the validation code with
framework code
28BeanGuards
- Two main styles of BeanGuards
- The Spring Validator interface is supported
directly - Also supports pure POJO validators (validation
triggered via setter) - Both of these are simply declared as beans (at
either request or application scope)
_at_author Rod Johnson public interface
Validator boolean supports(Class clazz)
void validate(Object obj, Errors errors)
29One True Path (OTP)
- RSF ORM idiom rather than library
- OTP assigns preferred EL path to each entity of
data model - Referential transparency for EL expressions
applied to persistence
30How does RSF OTP work?
- Assigns a unique EL path to each Entity managed
by ORM, where read/write of the EL is directly
bound to read/write of the model - The EL path for the Person with ID of 5 is
Person.5 - Add new entities with the special id form
- Person.new 1
- Following two points are useful optional
extensions to the model - Issue special binding type (UIDeletionBinding) to
unlink or delete an existing entity - If the request concludes normally, commit if
any kind of exception propagates out, rollback. - Not tied to any particular flavour or even use of
ORM EL paths are completely generic
31RSF and Web MVC
- RSF renderer (IKAT) can be used to form a Spring
Web MVC View - A couple caveats
- You lose the URL abstraction provided by RSF and
have to manage your navigation yourself - You also lose the nice widgets in RSF
- However
- You keep the IKAT pure XHTML rendering
- "Spring MVC Step by Step" sample treated on the
wiki - http//www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page
SpringMVCStep
32RSF and Spring Web Flow
- RSF integrates cleanly with both Web Flow 1.x and
2.x (tracking trunk and milestones) - All RSF widgets and evolvers naturally supported,
even those transparently using AJAX - Launch flows with special ViewParams
SWFLaunchViewParams and binding bean
SWFLaunchBean - Fire flow events with special ViewParams
SWFEventViewParams and binding bean SWFEventBean - Can support both old "MVC"-style flows (with
FormAction binding) and new "JSF"-style flows
(with framework binding) in the same environment!
33Producer interacting with Spring Web Flow
for (Person colleague person.getColleagues())
UIInternalLink.make(tofill, "colleague",
colleague.getFirstName() " "
colleague.getLastName(), new
SWFEventViewParams("select", new
PersonViewParams(colleague.getId())))
UIForm form UIForm.make(tofill, "form")
UICommand.make(form, "back", "SWFEventBean.back")
34Web Flow Samples
- The majority of "out of the box" SWF samples have
been ported to RSF including recent 2.x "Hotel
Booking Sample" - Sample code and live demos available online
- All apps are "click-through-able" in the
filesystem, unlike the non-RSF originals
35(Spring Web Flow Samples Demo)
36Questions?
- RSF wiki, forums and JIRA
- http//www2.caret.cam.ac.uk/rsfwiki
- Spring framework
- http//www.springframework.org/
- Demos
- http//ponder.org.uk/RSFSamplesIntro/faces/main