rsf programmers café and orm in sakai with rsf and hibernate antranig basman, caret, university of...

21
RSF Programmers’ Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

Upload: gerald-mark

Post on 31-Mar-2015

217 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

RSF Programmers’ Caféand

ORM in Sakai with RSF and Hibernate

Antranig Basman,

CARET, University of Cambridge

Page 2: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

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

Page 3: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

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

– Output is GUARANTEED valid XML

– IoC throughout the framework means application fragility does not increase with size, testability &c.

Page 4: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

Café “TaskList” app• 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

Page 5: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

JSF Tasklist App Structure

TaskList.jsp

TaskListBean.java

DataModel

TaskBeanWrapper.java

TaskList.java

TaskListServiceImpl.java

TaskListService.java TaskListManager.java

Page 6: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

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.

Page 7: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

JSF Tasklist App Structure 2

TaskList.jsp

TaskListBean.java

DataModel

TaskBeanWrapper.java

TaskList.java

TaskListServiceImpl.java

TaskListService.java TaskListManager.java

Page 8: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

RSF Tasklist App Structure

TaskListBean.java

TaskList.java

TaskListManager.java

TaskListProducer.javaTaskList.html

Page 9: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

Timeline 1

• Run the JSF app, and save the HTML it produces (take a look at this as TaskList-originalJSF.html)

• Clean up the HTML (considerably) and annotate with rsf:id

• Take faces-config.xml and convert into the equivalent Spring declarations– Message bundle -> Spring MessageSource (remember

to convert . to / in path)

– TaskListBean.java -> RSAC requestContext.xml

– NavigationCase -> return from TaskListProducer

Page 10: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

Timeline 2

• Deal with web.xml– Spring listener declaration is unchanged– FacesServlet -> ReasonableSakaiServlet– Remove JSF context params– Add RSF context param “resourceurlbase”

= context name– Alter Sakai Request Filter mapping to ONLY

apply to path faces/ (no flexibility here with current SakaiRSF – but who cares – noone should see tool URLs anyway)

Page 11: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

Timeline 3

• Deal with project.xml– A mess, as with all Maven stuff– Basically, remove JSF dependencies (JSF and

commons-X stuff) and add RSF dependencies (Spring, CGLib, XPP, ServletUtil and PonderUtilCore)

• NB this project does not use Sakai master project but has hard-coded version numbers

Page 12: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

Timeline 4

• Write the ViewProducer!– In this case, virtually all the logic ended up in this file. – Made more sense to inject most “leaf” dependencies

into the TaskListBean (e.g. siteId)– This isn’t quite the “expected” effect, since all this code

actually has framework dependence– But there is much less of it in total, and what there is is

more straightforward– And in truth this actually *is* view logic. There is just

a lot less “business” logic in this app than appears at first sight.

– Talk about LocaleGetter

Page 13: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

ORM with RSF (OTP style)

• This app used Hibernate ORM, but did not use the RSFHibernate integration library

• Demonstrates the “broad church” approach of RSF

• Basically, if it a Spring bean already, you can just use it in RSF without any problems

• RSF ORM enables us to destroy yet more code from this app.

Page 14: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

RSF Tasklist App Structure with OTP

TaskListBean.java

TaskList.java

TaskListManager.java

TaskListProducer.javaTaskList.html

Page 15: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

“Nearly”

• Actually “TaskListManager” is serving a dual purpose in our refactored RSF app

• Not only is it the app’s interface to its storage, it is also Sakai’s interface to the app

• This only happens because the app is essentially just a CRUD app. For more complex apps these interfaces would diverge.

• RSF only lets you get rid of internal APIs, not external ones!

• So in fact we would need to preserve TaskListManager for this app for its external function

Page 16: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

Transit Beans

• Also, this app does indeed contain one line of actual business logic.

if (newtask.getTask() == null || newtask.getTask().equals("")) { return "error"; }

• This is essentially validation logic. In RSF, this belongs in “Transit Beans”

• A POJO with a setter, and a getter, which throws an exception if value is invalid.

• Use request-scope IoC to wire it into the setter chain

Page 17: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

How does RSF OTP work?• Assigns a unique EL path to each Entity managed

by ORM• This is why returning a Map from the RSF version

of TaskListManager is the beginning of OTP• The EL path for the TaskList with Id of 5 is

#{TaskList.5}• Add new entities with the special id form

#{TaskList.new 1}• 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

Page 18: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

OTP result

• The TaskListBean disappears entirely!!

• TaskListManager disappears entirely (except for external function)

• Issue: We can’t do this in RSF right now, since there is no deletion binding form for issuing multiple deletes

• Will be fixed in RSF 0.6.4

Page 19: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

Working example: HibernateCookbook• Look at “javacategory” version at

http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=HibernateCookBook_4

• Syntax for a Command link operating a deletion binding:

UICommand destroy = UICommand.make(reciperow, "recipe-destroy"); destroy.parameters.add( new UIDeletionBinding("#{Recipe." + id +"}"));

• Isn’t this cool?• Brings Java that much closer to the “convention

over configuration” scriptaculous scumbag crowd

Page 20: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

What OTP requires• If you have your own SessionFactory, just point

RSF at it and it will manage all the entities in it• By default, just define a bean called

“sessionFactory”• If you are sharing a SessionFactory (e.g. Sakai

GlobalSessionFactory), need to list the entities you want managed

• You don’t have to use Hibernate to use OTP – All that’s required is:– An “AlterationWrapper” to enclose the action logic

which needs to be transactional– A set of “BeanLocators” which expose the entities at

their root paths

Page 21: RSF Programmers Café and ORM in Sakai with RSF and Hibernate Antranig Basman, CARET, University of Cambridge

Takehome Message

• There will always need to be external APIs• But internally you can do away with boring DAOs

and action beans, for all basic CRUD functionality• For some apps, the external API is as wide as the

data model, so this is not so much benefit• OTP is just another RSF design option, the first

version of the app worked just fine and was probably quite enough of an improvement on the JSF version.

• If you are still dealing with Hibernate under the covers, you still need to watch out!