sakai programmer's café introduction to rsf — ii. el, scopes and the request cycle antranig...
TRANSCRIPT
Sakai Programmer's Café
Introduction to RSF — II. EL, Scopes and the
Request Cycle
Antranig [email protected]
2
Recap of RSF Structure
• An “RSF’s eye view” of the application
• Component tree is the core junction point that ties everything together
• It is as slim and behaviour-free as possible
Template(X(H)TML)
“The Model”(request/application scope)
Producer(Java/XML)
Component Tree Produces
Fetches values from
Renders
Fetches values from
= Framework action
3
RSF cycles
• RSF separates the Render Cycle from the Action Cycle
• Not only crucial for new Portlet idioms (and WSRP) but also correct for the web.
• For normal webapps, Render = HTTP GET, Action = HTTP POST
• Look at the render cycle first.
4
public class MainProducer implements ViewComponentProducer, DefaultView { public static final String VIEW_ID = "main"; public String getViewID() { return VIEW_ID; }
public void fillComponents(UIContainer tofill, ViewParameters origviewparams, ComponentChecker checker) { UIOutput.make(tofill, "messagefield", null, "#{hellobean.message}"); } }
RSF Producer• Virtually all RSF-dependent code goes in here• Determines the structure and contents of the view,
separate from any particular rendering• Works by constructing a tree of simple objects (in fact,
records) called components
RSF ID – must agree with template
View ID – determines
template name
EL Reference – fetches from
model
5
RSF Template• MUST be a kind of XML (generally XHTML)• Purest kinds of template known to man – one
extra id attribute rsf:id
• Is “fused” with the component tree during rendering – rsf:id corresponds from template to tree
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns:rsf="http://ponder.org.uk/rsf"> <head> <title>Almost the simplest possible RSF application</title> </head> <body> <div rsf:id="messagefield">This field will be rewritten by the renderer</div> </body></html> RSF ID matches
Component ID
6
RSF Templates• Nothing particularly smart about this example• Lots of templating languages now with roughly this
kind of capability• Powerful aspect of RSF templating is how it
encodes complex looping and branching munging of the template without messing it up with logic – see next talk (Githens)
• Needn’t be HTML – very suitable and easy for rendering AJAX responses.
7
RSF Component Trees
• Full of “primitive records” (“components”) with names like UIOutput, UILink, UICommand
• Completely tech-neutral• Have no behaviour, and do NOT last longer
than one request cycle• DIRECT equivalent to XML representation –
many powerful applications with portalisation, XML pipeline apps, etc. (come and see main RSF talks)
8
EL in RSF• VERY lightweight• Just a dot-separated path of bean names and
properties (or 0-arg method for a method binding)• Binds component tree to the model without
polluting it• No logic allowed• Example from CRUD tool – an input field from
AddItemProducer.java:
UIInput.make(addupdateitem, "item-title", "#{itemsBean.newItem.title}", DEFAULT_TITLE );
Component class
EL Reference
Initial value
9
EL References• Are generally bidirectional (at least for input
components) – if an initial value is not supplied, will fetch it from the model NOW (that is, as soon as your producer finishes)
• Are encoded into the rendered view as bindings, to apply to the model LATER (that is, on the next cycle)
• Refer into the MODEL (via reflection)• What is the model in RSF?
“EL is about the Future”
10
“The Model” in RSF• The RSF “Model” (= representation of your entire
app!) is much smarter than in other frameworks• RSF is built on Spring• As well as traditional application-scope Spring,
RSF makes heavy use of request-scope beans – Spring also allows this as of 2.0, but the
implementation is too slow
• RSF’s use of the request scope with IoC is key to its “nice” features – low session state requirements, portability and proper HTTP behaviour
11
Quick recap of Spring• A Spring bean has no framework
dependencies (in Spring, as in RSF)
• Is configured in an XML file, which specifies bean class, bean properties and other dependencies (other beans)
• Here is the itemsBean we referred to earlier:
<bean id="itemsBean" class="org.sakaiproject.crudplus.tool.ItemsBean" init-method="init"> <property name="logic" ref="org.sakaiproject.crudplus.logic.CrudPlusLogic" /> <property name="messages" ref="infoMessages" /></bean>
Bean name
Injected Dependency
12
ItemsBean definition
public class ItemsBean { public CrudPlusItem newItem = new CrudPlusItem(); public Map selectedIds = new HashMap();
private CrudPlusLogic logic; public void setLogic(CrudPlusLogic logic) { this.logic = logic; } private StringList messages; public void setMessages(StringList messages) { this.messages = messages; }...
• Initial section of ItemsBean– Recall that our EL was {itemsBean.newItem.title}
• Classic example of the “captive entity pattern”– Halfway towards to OTP (see main RSF talks)
13
Request scope beans
• In Spring, this is “unusual”• Typically a Spring bean is at “application
scope” – has lifetime roughly equal to the application (webapp, or container)
• This bean is good just for a single request, for a single user
• Becoming more popular in Spring (since 2.0)• Offers extremely powerful abstraction
capability, and consistency across your design
14
Scopes in RSF• RSF beans essentially live at one of two scopes –
application or session• Request beans may be “preserved” by copying them to
some kinds of longer scope – e.g. session scopes or flow scopes
http://bugs.sakaiproject.org/confluence/display/BOOT/RSF+and+Spring+Contexts
Application Scope
appLogicBean appDaoBean appServiceBean
SessionA Scope
RequestY Scope
SessionB Scope
RequestX Scope
requestBean5-X
requestBean6-X
requestBean5-Y
sessionBean1-A sessionBean1-B
RequestZ Scope
requestBean6-Z
requestBean7-Z
sessionBean2-B
15
Declaring a Session Scope in RSF• Done with a Spring definition at application scope:
• Declares that the following request bean will be “preserved” to session scope:<bean id="messageBeanScope" parent="beanScopeParent"> <property name="copyPreservingBeans" value="infoMessages"/> <property name="exclusive" value="true" /></bean>
<bean id="infoMessages" class="uk.org.ponder.stringutil.StringList" />
16
Cleaning up a Session Scope• Scope bean itself can be injected as a
“BeanDestroyer” which can deallocate the scope:
• In code:
<bean class="org.sakaiproject.crudplus.tool.producers.ItemsProducer"> <property name="logic" ref="org.sakaiproject.crudplus.logic.CrudPlusLogic" /> <property name="localeGetter" ref="sakai-LocaleProxy" /> <property name="messages" ref="infoMessages" /> <property name="messageScopeDestroyer" ref="messageBeanScope"/></bean>
public class ItemsProducer implements ViewComponentProducer, DefaultView { private BeanDestroyer messageScopeDestroyer; public void setMessageScopeDestroyer(BeanDestroyer messageScopeDestroyer) { this.messageScopeDestroyer = messageScopeDestroyer; } public void fillComponents(UIContainer tofill, ViewParameters viewparams, ComponentChecker checker) { ... messageScopeDestroyer.destroy();
THIS IS THE ONLY KIND OF MODIFICATION OF THE APPLICATION STATE THAT IS PERMISSIBLE DURING A RENDER CYCLE!!!
17
Statelessness I• I’ve spent a long time on the “session scope”
• DO NOT USE IT!– In RSF 0.7, all this message handling
functionality is handled in the framework, this is just an example
• RSF’s design is to allow as much as possible of your work to be done in the request scope.
• This is quite different to other Java frameworks, especially the more recent ones – Although many non-Java frameworks (PHP,
Ruby, &c) are still fairly stateless
18
Statelessness II• Use “RESTful” flows as defined by
ViewParameters rather than session-based flows
• This is better for users as well as admins – better app behaviour as well as lower resource usage
• Use OTP/Transit beans rather than storing model state in session.
• Come to the main RSF talks!
19
RSF Highlights• BeanGuards for expressing validation rules (both
Spring Validator and POJO)• OTP for easy (codeless) ORM of “big-schema”
apps• Reusable components using pure HTML (multi-file
templates)• Localisation and accessibility comes nearly for
free (once the designers have done their work)• Previewable behaviour as well as markup• Totally transparent and automatic AJAX support
using UVB (Universal View Bus)
20
I
Idempotency
One for Steve: