Component Framework Primer for JSF Users Andy Schwartz | Oracle Corporation
What? <ul><li>What are we doing? </li></ul><ul><ul><li>Comparing server-side component-centric frameworks </li></ul></ul><...
Why? <ul><li>JSF has historically been a target of criticism </li></ul><ul><li>Often compared to related frameworks </li><...
Why Wicket and Tapestry? <ul><li>Similar in scope to JSF </li></ul><ul><li>Popular choices </li></ul><ul><li>Many areas of...
Who? <ul><li>User Interface Technology Architect, Oracle </li></ul><ul><li>Developing user interface frameworks since 1993...
Agenda <ul><li>Hello, Frameworks! </li></ul><ul><li>Event Handling </li></ul><ul><li>Ajax </li></ul><ul><li>Navigation </l...
<ul><li>Hello, JSF! </li></ul>
JSF History <ul><li>Originally standardized under JSR-127, 2004. </li></ul><ul><li>Standard piece of Java EE platform (Web...
JSF Vision <ul><li>Swing-like component/event model </li></ul><ul><li>Declarative component tree specification </li></ul><...
What is a Page? <ul><li>Legacy: Each page defined by a JSP (JSPX) </li></ul><ul><li>Now: Facelets standardized, preferred ...
<ul><li>Saying Hello </li></ul><ul><li>(JSF) </li></ul>
Grunge: web.xml <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class> javax.faces.webapp.FacesServlet </ser...
My First JSF Page <html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xmlns:h=&quot;http://java.sun.com/jsf/html&quot;> <...
JSF Rendering <ul><li>Page definition drives component tree creation </li></ul><ul><li>Component tree contains UIComponent...
What Happens After Rendering? <ul><li>Component tree state saved via StateManager </li></ul><ul><li>State stored in sessio...
Bindings <ul><li>Component attributes can be bound </li></ul><ul><li>Allows components to access dynamic data </li></ul><u...
A Simple Binding <h:outputText  value=&quot;#{sessionScope.user.firstName}&quot;/>
Implicit Objects <ul><li>Bindings have access implicit objects/scopes </li></ul><ul><li>Servlet-related scopes: </li></ul>...
Managed Beans <ul><li>POJOs </li></ul><ul><li>Named </li></ul><ul><li>Scoped </li></ul><ul><li>Container-managed </li></ul>
Managed Bean Registration <faces-config> <managed-bean> <managed-bean-name>user</managed-bean-name> <managed-bean-class>de...
Managed Bean Registration @ManagedBean @SessionScoped public class User { public String getFirstName() { … } }
Managed Bean Reference <!-- Instead of this: --> <h:outputText value=&quot;#{sessionScope.user.firstName}&quot;/> <!-- We ...
<ul><li>Hello, Wicket! </li></ul>
Wicket Quick History <ul><li>Founded by Johnathan Locke, 2005 </li></ul><ul><li>Originally hosted at SourceForge </li></ul...
Wicket Vision <ul><li>Complete separation of markup and logic </li></ul><ul><li>Web designers do HTML </li></ul><ul><li>Ap...
What is a Page? <ul><li>Markup lives in a .html file </li></ul><ul><li>Code/components live in a .java file </li></ul><ul>...
<ul><li>Saying Hello </li></ul><ul><li>(Wicket) </li></ul>
Grunge: web.xml <filter> <filter-name>wicket</filter-name> <filter-class> org.apache.wicket.protocol.http.WicketFilter </f...
Grunge: web.xml <init-param> <param-name> applicationClassName </param-name> <param-value> org.demo.wicket.HelloApplicatio...
My First Wicket Application public class HelloApplication extends WebApplication { @Override public Class<Hello> getHomePa...
My First Wicket Page (HTML) <html xmlns:wicket=&quot;…&quot;> <head><title>Hello, Wicket!</title></head> <body> <!-- My fi...
My First Wicket Page (Java) public class Hello extends WebPage { public Hello() { // My first Wicket component (Java) add(...
Wicket Rendering <ul><li>Markup exposed via MarkupStream </li></ul><ul><ul><li>MarkupElements: RawText, ComponentTag </li>...
What Happens After Rendering? <ul><li>Page state stored in page store </li></ul><ul><li>Pluggable page store behavior </li...
What is a Wicket Model? <ul><li>Wicket models bind domain layer objects to components. </li></ul><ul><li>(Similar to EL Va...
IModel Contract T getObject() void setObject(T object)
Components and Models <ul><li>IModel<?> getDefaultModel() </li></ul><ul><li>Most components read from model. </li></ul><ul...
Simple Model <ul><li>Model class implements IModel </li></ul><ul><li>Stores model object locally </li></ul><ul><li>We have...
Simple Model Sample // This: add(new Label(&quot;name&quot;, &quot;World&quot;); // Is shorthand for: add(new Label(&quot;...
Static Model <ul><li>Simple Models are static. </li></ul>// This is static: add(new Label(&quot;random&quot;,  new Model<D...
Dynamic Model <ul><li>Override getObject() for dynamic. </li></ul>// This is dynamic: add(new Label(&quot;reallyRandom&quo...
Some More Models <ul><li>PropertyModel </li></ul><ul><li>CompoundPropertyModel </li></ul><ul><li>LoadableDetachableModel <...
<ul><li>Hello, Tapestry! </li></ul>
Tapestry Quick History <ul><li>Founded by Howard Lewis Ship, 2000 </li></ul><ul><li>Hosted at Apache </li></ul><ul><li>Gra...
Tapestry Vision <ul><li>Similar separation of markup/logic </li></ul><ul><li>Convention over Configuration </li></ul><ul><...
What is a Page? <ul><li>Markup lives in a .tml file </li></ul><ul><li>Code/components live in a .java file </li></ul><ul><...
<ul><li>Saying Hello </li></ul><ul><li>(Tapestry) </li></ul>
Grunge: web.xml <filter> <filter-name>tapestry</filter-name> <filter-class> org.apache.tapestry5.TapestryFilter </filter-c...
Grunge: web.xml <context-param> <param-name> tapestry.app-package </param-name> <param-value> org.example.tapestry </param...
My First Tapestry Page (TML) <html xmlns:t=&quot;…&quot;> <head><title>Hello, Tapestry!</title></head> <body> <!-- My firs...
My First Tapestry Page (Java) public class Index { @Property private String name; }
Tapestry Rendering <ul><li>State machine/queue-based rendering </li></ul><ul><ul><li>No recursive component tree traversal...
What Happens After Rendering? <ul><li>Persistent properties are state saved </li></ul><ul><ul><li>@Persist annotation iden...
<ul><li>Take 2: t:id </li></ul>
Take 2: TML <html xmlns:t=&quot;…&quot;> <head><title>Hello, Tapestry!</title></head> <body> <!-- Does this seem familiar?...
Take 2: Java public class Index { @Property private String name; @Component( parameters={&quot;value=name&quot;}) private ...
<ul><li>Take 3: t:type </li></ul>
Take 3: TML <html xmlns:t=&quot;…&quot;> <head><title>Hello, Tapestry!</title></head> <body> Hello,   <span  t:type=&quot;...
Facelets Flashback <!-- Remember this? --> <span jsfc=&quot;h:outputText&quot;  value=&quot;#{name}&quot;>Foo</span>!
Tapestry Property Expressions <ul><li>String notations for specifying object paths </li></ul><ul><li>Similar to EL </li></...
Property Expressions <!-- Component parameter --> <div><t:textoutput t:value=&quot;user.name&quot;/></div> <!-- Template e...
Binding Expressions <ul><li>Parameters can bind to other types of values </li></ul><ul><li>Prefix identifies binding type:...
Binding Expressions <!-- Property Binding--> Hello, <t:textoutput t:value=&quot;name&quot;/>! <!-- Literal Binding--> Hell...
Some Initial Thoughts <ul><li>Key difference: declarative vs programmatic component tree specification </li></ul><ul><li>J...
Some More Thoughts <ul><li>Implicit per-page Java object is convenient </li></ul><ul><li>Possible to simulate with JSF (vi...
<ul><li>Event Handling </li></ul>
JSF Event Handling <ul><li>Inspired by Swing Event Model </li></ul><ul><li>Listeners registered on components </li></ul><u...
JSF Event Handling <h:form> <h:commandButton value=&quot;Increment&quot; actionListener=&quot;#{counter.increment}&quot;/>...
JSF Event Handling @ManagedBean @SessionScoped public class Counter { public int getCount() { return count; } public void ...
Wicket Event Handling <ul><li>Components expose event-specific hooks </li></ul><ul><li>Subclasses override to receive noti...
Wicket Event Handling <form wicket:id=&quot;form&quot;> <input type=&quot;submit&quot; value=&quot;Increment&quot; wicket:...
Wicket Event Handling public class EventsPage extends WebPage { public EventsPage() { Button button = new Button(&quot;but...
Wicket Event Handling <ul><li>onSubmit() exposed at both Button and Form level </li></ul><ul><li>Button onSubmit() called ...
Tapestry Event Handling <ul><li>Naming Conventions </li></ul><ul><li>Annotations </li></ul>
Tapestry Event Handling <t:form t:id=&quot;form1&quot;> <input type=&quot;submit&quot; value=&quot;Increment&quot; t:type=...
Tapestry Event Handling public class Events { @Persist @Property private int count; // Called when any form is submitted v...
Tapestry Event Handling // All of these work too! // Called when form 1 is submitted void onSubmitFromForm1() { count++ } ...
Tapestry Event Handling // And these too @OnEvent(value=&quot;selected&quot;, component=&quot;button1&quot;) void incremen...
Tapestry Event Handling <ul><li>Component-specific events before form </li></ul><ul><li>Global events before component-spe...
Event Handling Wrap Up <ul><li>Three very different approaches </li></ul><ul><li>Managed bean annotations simplify JSF app...
<ul><li>Ajax </li></ul>
JSF Ajax <ul><li>Before: Take your pick </li></ul><ul><ul><li>ADF/Ice/Rich/Prime/Trinidad </li></ul></ul><ul><li>Now: Stan...
JSF Ajax <ul><li><h:form> </li></ul><ul><li><h:commandButton value=&quot;Increment&quot; </li></ul><ul><li>actionListener=...
JSF Ajax <f:ajax render=&quot;count&quot;/> <h:commandButton value=&quot;Increment&quot; actionListener=&quot;#{counter.in...
JSF Ajax <ul><li>All standard components support behaviors </li></ul><ul><li>Attach points are component-specific </li></u...
Wicket Ajax <ul><li>Ajax Components </li></ul><ul><li>Behaviors </li></ul>
Wicket Ajax AjaxButton button = new AjaxButton(&quot;button&quot;) { @Override public void onSubmit( AjaxRequestTarget tar...
Wicket Ajax label = new Label(&quot;count&quot;, …); label. setOutputMarkupId(true);
Wicket Ajax <ul><li>Many convenience components, behaviors </li></ul><ul><li>Fallback behavior: AjaxFallbackLink </li></ul...
Tapestry Ajax <ul><li>Ajax Zones </li></ul><ul><li>Mixins </li></ul>
Tapestry Ajax <t:form t:id=&quot;form1&quot;  zone=&quot;countZone&quot; > <input type=&quot;submit&quot; value=&quot;Incr...
Tapestry Ajax public class Ajax { @InjectComponent private Zone countZone; Object onSubmitFromForm1() { return countZone.g...
Tapestry Ajax <ul><li>Zone supported by Form, ActionLink, EventLink </li></ul><ul><li>MultiZoneUpdate </li></ul><ul><li>Mi...
Ajax Wrap Up <ul><li>JSF 2.0 Ajax is competitive with other solutions </li></ul><ul><li>Wicket Ajax debug window is nice <...
<ul><li>Navigation </li></ul>
JSF Navigation <ul><li>Traditional: POST-based navigation </li></ul><ul><li>POST triggers action </li></ul><ul><li>Action ...
JSF Navigation <h:commandButton action=&quot;#{nav.goToPageB}&quot;/> @ManagedBean(name=&quot;nav&quot;) @RequestScoped pu...
JSF Navigation <navigation-rule> <from-view-id>/pageA.xhtml</from-view-id> <navigation-case> <from-outcome>success</from-o...
JSF Implicit Navigation <ul><li>Declarative navigation is good for many cases </li></ul><ul><li>Perhaps too verbose for si...
JSF Implicit Navigation <h:commandButton action=&quot;#{nav.goToPageB}&quot;/> @ManagedBean(name=&quot;nav&quot;) @Request...
JSF Pre-Emptive Navigation <ul><li>Implict navigation simplifies, but still POST-only </li></ul><ul><li>Not GET/bookmark-f...
JSF Pre-Emptive Navigation <!-- Use navigation rules to determine  &quot;success&quot; outcome target --> <h:button outcom...
Wicket Navigation <ul><li>Programmatic navigation: setResponsePage() </li></ul><ul><li>Class vs. instance  </li></ul>
Wicket Navigation Button button1 = new Button(&quot;button1&quot;) { public void onSubmit() { setResponsePage(PageB.class)...
Wicket Navigation Button button1 = new Button(&quot;button1&quot;) { public void onSubmit() { PageB pageB = new PageB(); /...
Wicket Navigation <ul><li>Direct navigation also supported </li></ul><ul><li>BookmarkablePageLink </li></ul><ul><li>wicket...
Wicket Navigation <!-- HTML --> <a wicket:id=&quot;bookmarkable&quot; href=&quot;PageB.html&quot;>Navigate To Page B</a> /...
Wicket Navigation <!-- No Java code required. --> <wicket:link> <ul> <li><a href=&quot;PageA.html&quot;>Page A</a></li> <l...
Tapestry Navigation <ul><li>Programmatic navigation: onSubmit() return </li></ul><ul><li>Like Wicket, navigate to class or...
Tapestry Navigation public class PageA { Object onSubmitFromForm1() { return PageB.class; } }
Tapestry Navigation public class PageA { @InjectPage private PageB pageB; Object onSubmitFromForm1() { // Configure pageB ...
Tapestry Navigation <ul><li>Direct navigation also supported </li></ul><ul><li>t:pageLink </li></ul>
Tapestry Navigation <t:pagelink t:page=&quot;PageB&quot;>Go</t:pagelink>
Navigation Wrap Up <ul><li>JSF 2.0 enhancements simplify navigation </li></ul><ul><li>String outcomes vs. class/instance <...
<ul><li>Input Processing </li></ul>
JSF Input Processing <ul><li>EditableValueHolder lifecycle </li></ul><ul><ul><li>Decode </li></ul></ul><ul><ul><li>Convers...
JSF Input Processing <h:inputText value=&quot;#{user.name}&quot;/> @ManagedBean public class User { public String getName(...
JSF Conversion <ul><li>Converters control transformation to/from string </li></ul><ul><li>Attached to EditableValueHolder ...
JSF Conversion <h:inputText value=&quot;#{user.age}&quot;> <f:convertNumber integerOnly=&quot;true&quot;/> </h:inputText>
JSF Validation <ul><li>Validators verify converted value </li></ul><ul><li>Attached to EditableValueHolder components </li...
JSF Validation <h:inputText value=&quot;#{user.age}&quot;> <f:validateLongRange minimum=&quot;18&quot;/> </h:inputText>
More JSF Validation <ul><li>Feedback </li></ul><ul><ul><li>Typically displayed via <h:messages>/<h:message> </li></ul></ul...
Wicket Input Processing <ul><li>Similar lifecycle to JSF </li></ul><ul><ul><li>Required field validation </li></ul></ul><u...
Wicket Input Processing <!-- HTML --> <input type=&quot;text&quot; wicket:id=&quot;firstName&quot;/> // Java User user = g...
Wicket Conversion <ul><li>IConverter contract, similar to JSF Converter </li></ul><ul><li>Converts to/from string </li></u...
Wicket Validation <ul><li>IValidator, similar to JSF Validator </li></ul><ul><li>Validators attached programmatically </li...
Wicket Validation <!-- HTML --> <input type=&quot;text&quot; wicket:id=&quot;age&quot;/> // Java add(new TextField(&quot;a...
More Wicket Validation <ul><li>Feedback </li></ul><ul><ul><li>FeedbackPanel (like h:messages) </li></ul></ul><ul><ul><li>F...
Tapestry Input Processing <ul><li>Similar lifecycle to JSF, Wicket </li></ul><ul><ul><li>Conversion </li></ul></ul><ul><ul...
Tapestry Input Processing <!-- TML --> <input type=&quot;text&quot; t:type=&quot;textfield&quot; t:value=&quot;user.name&q...
Tapestry Conversion <ul><li>FieldTranslator, similar to Converter/IConverter </li></ul><ul><li>Event-based conversion </li...
Tapestry Conversion Events public class Input { String onToClientFromAge() { // Return String representation of age } Obje...
Tapestry Validation <ul><li>FieldValidator, similar to Validator/Ivalidator </li></ul><ul><li>Constraints attached via com...
Parameter-Based Validation <input type=&quot;text&quot; t:type=&quot;textfield&quot; t:value=&quot;user.age&quot; t:valida...
Event-Based Validation void onValidateFromAge(Integer value) throws ValidationException { if (value < 18)  throw new Valid...
Anntation-Based Validation public class Input { @Property @Validate(&quot;required,min=18&quot;) private int age; }
More Tapestry Validation <ul><li>Feedback </li></ul><ul><ul><li>Border highlight, hover text </li></ul></ul><ul><ul><li><t...
Input Processing Wrap Up <ul><li>Similar input processing across frameworks </li></ul><ul><ul><li>Surprise? </li></ul></ul...
<ul><li>Custom Components </li></ul>
JSF: Old School (Java) <ul><li>Java class (extends UIComponent) </li></ul><ul><li>Renderer class </li></ul><ul><li>Tag cla...
JSF: New School (Java) <ul><li>Annotations replace faces-cofig.xml </li></ul><ul><li>Default Facelets handlers replace Tag...
JSF: New School (Composite) <ul><li>Single Facelets file defines composite component </li></ul><ul><li>Installed in resour...
resources/demo/titleBorder.xhtml <html ... ><body> <composite:implementation> <div class=&quot;tb-root&quot;> <div class=&...
Composite Interface <composite:interface> <composite:attribute name=&quot;title&quot; required=&quot;true&quot;/> </compos...
Component Usage <html … xmlns:demo= &quot;http://java.sun.com/jsf/composite/demo&quot;> <body> <demo:titleBorder title=&qu...
Wicket Custom Components <ul><li>We have already seen several custom components </li></ul><ul><ul><li>Think event handling...
TitleBorder.html <html ... ><body> <wicket:border> <div class=&quot;tb-root&quot;> <div class=&quot;tb-title&quot;  wicket...
TitleBorder.java public class TitleBorder extends Border { public TitleBorder(String id) { super(id); add(new Label(&quot;...
Component Usage <!-- HTML --> <div wicket:id=&quot;titleBorder&quot;> Hello, World! </div> // Java add(new TitleBorder(&qu...
Tapestry Custom Components <ul><li>Again, similar to page </li></ul><ul><li>TML/Java split </li></ul><ul><li>Java componen...
TitleBorder.tml <div class=&quot;tb-root&quot; ... > <div class=&quot;tb-title&quot;> ${title} </div> <div class=&quot;tb-...
TitleBorder.java public class TitleBorder { @Property @Parameter(required=true, defaultPrefix=BindingConstants.LITERAL) pr...
Component Usage <t:titleborder t:title=&quot;My Favorite Greeting&quot;> Hello, World! </t:titleborder>
Custom Component Wrap Up <ul><li>JSF custom component development became much, much simpler in 2.0 </li></ul><ul><li>Compo...
<ul><li>Wrap Up </li></ul>
So Much To Do, So Little Time <ul><li>Many other possible points of comparison </li></ul><ul><ul><li>Performance </li></ul...
Conclusion <ul><li>Some differences are fundamental </li></ul><ul><li>Interesting to see many similarities too </li></ul><...
Upcoming SlideShare
Loading in...5
×

Component Framework Primer for JSF Users

4,404

Published on

JSF Summit 2009 presentation covering three component-centric web frameworks: JSF, Wicket and Tapestry.

Published in: Technology, Education
1 Comment
2 Likes
Statistics
Notes
No Downloads
Views
Total Views
4,404
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
173
Comments
1
Likes
2
Embeds 0
No embeds

No notes for slide

Component Framework Primer for JSF Users

  1. 1. Component Framework Primer for JSF Users Andy Schwartz | Oracle Corporation
  2. 2. What? <ul><li>What are we doing? </li></ul><ul><ul><li>Comparing server-side component-centric frameworks </li></ul></ul><ul><ul><li>Understanding approaches to common problems </li></ul></ul><ul><li>What is a server-side component-centric framework? </li></ul><ul><ul><li>User interface component model defined on server </li></ul></ul><ul><ul><li>Components hold properties, children, fire events </li></ul></ul><ul><ul><li>Swing-like approach for web content </li></ul></ul><ul><li>What frameworks? </li></ul><ul><ul><li>JSF, Wicket and Tapestry </li></ul></ul><ul><li>What else is there? </li></ul><ul><ul><li>Client-side (jQuery, Dojo) </li></ul></ul><ul><ul><li>Hybrid (GWT) </li></ul></ul><ul><ul><li>MVC (Struts, RoR) </li></ul></ul>
  3. 3. Why? <ul><li>JSF has historically been a target of criticism </li></ul><ul><li>Often compared to related frameworks </li></ul><ul><li>Important to understand JSF’s limitations </li></ul><ul><li>JSF 2 addresses many of these issues </li></ul><ul><li>Still room for improvement </li></ul><ul><li>We can learn from other frameworks </li></ul><ul><li>We can continue to evolve/improve JSF </li></ul>
  4. 4. Why Wicket and Tapestry? <ul><li>Similar in scope to JSF </li></ul><ul><li>Popular choices </li></ul><ul><li>Many areas of overlap </li></ul><ul><li>Different approaches </li></ul><ul><li>Interesting comparisons </li></ul><ul><li>Plenty of lessons to learn </li></ul>
  5. 5. Who? <ul><li>User Interface Technology Architect, Oracle </li></ul><ul><li>Developing user interface frameworks since 1993 </li></ul><ul><li>JSR-314/JSF 2.0 Expert Group Representative </li></ul><ul><li>Wicket/Tapestry Student </li></ul><ul><li>Biased, but honest :-) </li></ul>
  6. 6. Agenda <ul><li>Hello, Frameworks! </li></ul><ul><li>Event Handling </li></ul><ul><li>Ajax </li></ul><ul><li>Navigation </li></ul><ul><li>Input Processing </li></ul><ul><li>Custom components </li></ul><ul><li>Wrap up </li></ul>
  7. 7. <ul><li>Hello, JSF! </li></ul>
  8. 8. JSF History <ul><li>Originally standardized under JSR-127, 2004. </li></ul><ul><li>Standard piece of Java EE platform (Web Profile) </li></ul><ul><li>Sun serves as spec lead (Ed Burns, Roger Kitain) </li></ul><ul><li>JSR-252/JSF 1.2 enhancements, 2006 </li></ul><ul><li>JSR-314/JSF 2.0 major release, 2009 </li></ul><ul><li>Two widely used implementations </li></ul><ul><ul><li>Mojarra (Reference Implementation) </li></ul></ul><ul><ul><li>MyFaces </li></ul></ul>
  9. 9. JSF Vision <ul><li>Swing-like component/event model </li></ul><ul><li>Declarative component tree specification </li></ul><ul><li>Integration with existing standards </li></ul><ul><li>Split logical (components) and physical (markup) </li></ul><ul><li>Tooling </li></ul><ul><li>Extensibility </li></ul>
  10. 10. What is a Page? <ul><li>Legacy: Each page defined by a JSP (JSPX) </li></ul><ul><li>Now: Facelets standardized, preferred over JSP </li></ul><ul><li>Combines XHTML and component tags </li></ul><ul><li>Component tree definition specified via tags </li></ul><ul><li>Other view declaration languages (VDLs) available </li></ul><ul><ul><li>JSF Templating, Gracelets </li></ul></ul>
  11. 11. <ul><li>Saying Hello </li></ul><ul><li>(JSF) </li></ul>
  12. 12. Grunge: web.xml <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class> javax.faces.webapp.FacesServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping>
  13. 13. My First JSF Page <html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xmlns:h=&quot;http://java.sun.com/jsf/html&quot;> <head><title>My First JSF Page</title></head> <body> <!-- Our first JSF component usage --> Hello, <h:outputText value=&quot;World&quot;/>! </body> </html>
  14. 14. JSF Rendering <ul><li>Page definition drives component tree creation </li></ul><ul><li>Component tree contains UIComponent instances </li></ul><ul><li>UIComponents delegate to Renderers </li></ul><ul><li>Response produced by traversing component tree </li></ul><ul><li>UIComponents/Renderers generate markup </li></ul><ul><li>Markup written via ResponseWriter </li></ul>
  15. 15. What Happens After Rendering? <ul><li>Component tree state saved via StateManager </li></ul><ul><li>State stored in session or client </li></ul><ul><li>Component tree restored on postback </li></ul><ul><li>JSF 2.0 optimization: partial state saving </li></ul>
  16. 16. Bindings <ul><li>Component attributes can be bound </li></ul><ul><li>Allows components to access dynamic data </li></ul><ul><li>Specified via Unified Expression Language (EL) </li></ul><ul><li>Bindings used for both reading and writing </li></ul>
  17. 17. A Simple Binding <h:outputText value=&quot;#{sessionScope.user.firstName}&quot;/>
  18. 18. Implicit Objects <ul><li>Bindings have access implicit objects/scopes </li></ul><ul><li>Servlet-related scopes: </li></ul><ul><ul><li>applicationScope </li></ul></ul><ul><ul><li>sessionScope </li></ul></ul><ul><ul><li>requestScope </li></ul></ul><ul><li>JSF-specific scopes </li></ul><ul><ul><li>viewScope </li></ul></ul><ul><ul><li>flash </li></ul></ul><ul><ul><li>component </li></ul></ul><ul><li>Many more objects exposed </li></ul>
  19. 19. Managed Beans <ul><li>POJOs </li></ul><ul><li>Named </li></ul><ul><li>Scoped </li></ul><ul><li>Container-managed </li></ul>
  20. 20. Managed Bean Registration <faces-config> <managed-bean> <managed-bean-name>user</managed-bean-name> <managed-bean-class>demo.User</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> </faces-config>
  21. 21. Managed Bean Registration @ManagedBean @SessionScoped public class User { public String getFirstName() { … } }
  22. 22. Managed Bean Reference <!-- Instead of this: --> <h:outputText value=&quot;#{sessionScope.user.firstName}&quot;/> <!-- We can now do this: --> <h:outputText value=&quot;#{user.firstName}&quot;/>
  23. 23. <ul><li>Hello, Wicket! </li></ul>
  24. 24. Wicket Quick History <ul><li>Founded by Johnathan Locke, 2005 </li></ul><ul><li>Originally hosted at SourceForge </li></ul><ul><li>Moved to Apache, 2007 </li></ul><ul><li>Graduated to top level project, June 2007 </li></ul><ul><li>Current version: 1.4.3 (as of November 2009) </li></ul>
  25. 25. Wicket Vision <ul><li>Complete separation of markup and logic </li></ul><ul><li>Web designers do HTML </li></ul><ul><li>Application developers do Java </li></ul><ul><li>Designers benefit from previewability </li></ul><ul><li>Developers benefit from type-safety </li></ul><ul><li>No special tooling required </li></ul>
  26. 26. What is a Page? <ul><li>Markup lives in a .html file </li></ul><ul><li>Code/components live in a .java file </li></ul><ul><li>Properties/messages in a .properties file </li></ul><ul><li>All files live on the class path </li></ul><ul><li>All files for a page share a name </li></ul><ul><li>Components correlated across html/java by id </li></ul>
  27. 27. <ul><li>Saying Hello </li></ul><ul><li>(Wicket) </li></ul>
  28. 28. Grunge: web.xml <filter> <filter-name>wicket</filter-name> <filter-class> org.apache.wicket.protocol.http.WicketFilter </filter-class> <filter-mapping> <filter-name>wicket</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </filter>
  29. 29. Grunge: web.xml <init-param> <param-name> applicationClassName </param-name> <param-value> org.demo.wicket.HelloApplication </param-value> </init-param>
  30. 30. My First Wicket Application public class HelloApplication extends WebApplication { @Override public Class<Hello> getHomePage() { return Hello.class; } }
  31. 31. My First Wicket Page (HTML) <html xmlns:wicket=&quot;…&quot;> <head><title>Hello, Wicket!</title></head> <body> <!-- My first Wicket component (html) --> Hello, <span wicket:id=&quot;name&quot; >Foo</span>! </body> </html>
  32. 32. My First Wicket Page (Java) public class Hello extends WebPage { public Hello() { // My first Wicket component (Java) add(new Label( &quot;name&quot; , &quot;World&quot;)); } }
  33. 33. Wicket Rendering <ul><li>Markup exposed via MarkupStream </li></ul><ul><ul><li>MarkupElements: RawText, ComponentTag </li></ul></ul><ul><li>ComponentTags correlated with Components </li></ul><ul><li>onRender() called for each component </li></ul><ul><li>onComponentTag(): modify/render start tag </li></ul><ul><li>onComponentBodyTag(): modify/render body </li></ul><ul><li>MarkupElements written to response. </li></ul>
  34. 34. What Happens After Rendering? <ul><li>Page state stored in page store </li></ul><ul><li>Pluggable page store behavior </li></ul><ul><ul><li>DiskPageStore leverages file system for old pages </li></ul></ul><ul><li>Page restored on postback </li></ul>
  35. 35. What is a Wicket Model? <ul><li>Wicket models bind domain layer objects to components. </li></ul><ul><li>(Similar to EL ValueExpressions in JSF) </li></ul>
  36. 36. IModel Contract T getObject() void setObject(T object)
  37. 37. Components and Models <ul><li>IModel<?> getDefaultModel() </li></ul><ul><li>Most components read from model. </li></ul><ul><li>Some components write to model. </li></ul>
  38. 38. Simple Model <ul><li>Model class implements IModel </li></ul><ul><li>Stores model object locally </li></ul><ul><li>We have been using it already </li></ul>
  39. 39. Simple Model Sample // This: add(new Label(&quot;name&quot;, &quot;World&quot;); // Is shorthand for: add(new Label(&quot;name&quot;, new Model(&quot;World&quot;)));
  40. 40. Static Model <ul><li>Simple Models are static. </li></ul>// This is static: add(new Label(&quot;random&quot;, new Model<Double>(Math.random()) ));
  41. 41. Dynamic Model <ul><li>Override getObject() for dynamic. </li></ul>// This is dynamic: add(new Label(&quot;reallyRandom&quot;, new Model<Double>() { public Double getObject() { return Math.random(); } }));
  42. 42. Some More Models <ul><li>PropertyModel </li></ul><ul><li>CompoundPropertyModel </li></ul><ul><li>LoadableDetachableModel </li></ul><ul><li>ResourceModel </li></ul>
  43. 43. <ul><li>Hello, Tapestry! </li></ul>
  44. 44. Tapestry Quick History <ul><li>Founded by Howard Lewis Ship, 2000 </li></ul><ul><li>Hosted at Apache </li></ul><ul><li>Graduated to top level project, June 2006 </li></ul><ul><li>Current release: 5.1 (as of November 2009) </li></ul>
  45. 45. Tapestry Vision <ul><li>Similar separation of markup/logic </li></ul><ul><li>Convention over Configuration </li></ul><ul><li>Inversion of Control </li></ul><ul><li>POJOs/annotations </li></ul><ul><li>Performance </li></ul>
  46. 46. What is a Page? <ul><li>Markup lives in a .tml file </li></ul><ul><li>Code/components live in a .java file </li></ul><ul><li>Properties/messages in a .properties file </li></ul><ul><li>TML files live in web root </li></ul><ul><li>Other files on the class path </li></ul><ul><li>All files for a page share a name </li></ul>
  47. 47. <ul><li>Saying Hello </li></ul><ul><li>(Tapestry) </li></ul>
  48. 48. Grunge: web.xml <filter> <filter-name>tapestry</filter-name> <filter-class> org.apache.tapestry5.TapestryFilter </filter-class> </filter> <filter-mapping> <filter-name>tapestry</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
  49. 49. Grunge: web.xml <context-param> <param-name> tapestry.app-package </param-name> <param-value> org.example.tapestry </param-value> </context-param>
  50. 50. My First Tapestry Page (TML) <html xmlns:t=&quot;…&quot;> <head><title>Hello, Tapestry!</title></head> <body> <!-- My first Tapestry component. --> <!-- Note: We don't really need a component. --> Hello, <t:textoutput t:value=&quot;name&quot;/>! </body> </html>
  51. 51. My First Tapestry Page (Java) public class Index { @Property private String name; }
  52. 52. Tapestry Rendering <ul><li>State machine/queue-based rendering </li></ul><ul><ul><li>No recursive component tree traversal </li></ul></ul><ul><li>Components hook into rendering phases </li></ul><ul><ul><li>SetupRender, BeginRender, BeforeRenderBody, etc. </li></ul></ul><ul><li>Specified via annotations or naming conventions </li></ul><ul><li>Hooks write response to MarkupWriter </li></ul><ul><ul><li>Streaming API with access to DOM-like structure </li></ul></ul>
  53. 53. What Happens After Rendering? <ul><li>Persistent properties are state saved </li></ul><ul><ul><li>@Persist annotation identifes properties to persist </li></ul></ul><ul><li>Page is cleaned up and returned to pool </li></ul><ul><li>On postback, page instance retrieved from pool </li></ul><ul><li>Persistent property values are restored </li></ul><ul><li>Pooling is for performance (smaller footprint) </li></ul><ul><li>Implies mostly static page structures </li></ul>
  54. 54. <ul><li>Take 2: t:id </li></ul>
  55. 55. Take 2: TML <html xmlns:t=&quot;…&quot;> <head><title>Hello, Tapestry!</title></head> <body> <!-- Does this seem familiar? --> Hello, <span t:id=&quot;nameOutput&quot; >Foo</span>! </body> </html>
  56. 56. Take 2: Java public class Index { @Property private String name; @Component( parameters={&quot;value=name&quot;}) private TextOutput nameOutput; }
  57. 57. <ul><li>Take 3: t:type </li></ul>
  58. 58. Take 3: TML <html xmlns:t=&quot;…&quot;> <head><title>Hello, Tapestry!</title></head> <body> Hello, <span t:type=&quot;textoutput&quot; t:value=&quot;name&quot;>Foo</span>! </body> </html>
  59. 59. Facelets Flashback <!-- Remember this? --> <span jsfc=&quot;h:outputText&quot; value=&quot;#{name}&quot;>Foo</span>!
  60. 60. Tapestry Property Expressions <ul><li>String notations for specifying object paths </li></ul><ul><li>Similar to EL </li></ul><ul><li>Supports referencing properties and methods </li></ul><ul><li>Used for parameters and template expansions </li></ul><ul><li>Compiled to Java classes (no reflection) </li></ul>
  61. 61. Property Expressions <!-- Component parameter --> <div><t:textoutput t:value=&quot;user.name&quot;/></div> <!-- Template expansion --> <div>${user.name}</div>
  62. 62. Binding Expressions <ul><li>Parameters can bind to other types of values </li></ul><ul><li>Prefix identifies binding type: </li></ul><ul><ul><li>prop </li></ul></ul><ul><ul><li>literal </li></ul></ul><ul><ul><li>asset </li></ul></ul><ul><ul><li>context </li></ul></ul><ul><ul><li>component </li></ul></ul><ul><ul><li>message </li></ul></ul>
  63. 63. Binding Expressions <!-- Property Binding--> Hello, <t:textoutput t:value=&quot;name&quot;/>! <!-- Literal Binding--> Hello, <t:textoutput t:value=&quot;literal:World&quot;/>!
  64. 64. Some Initial Thoughts <ul><li>Key difference: declarative vs programmatic component tree specification </li></ul><ul><li>JSF favors declarative approach </li></ul><ul><li>Wicket requires programmatic approach </li></ul><ul><li>Tapestry is somewhere in the middle </li></ul><ul><li>Component abstraction vs. direct access to HTML </li></ul>
  65. 65. Some More Thoughts <ul><li>Implicit per-page Java object is convenient </li></ul><ul><li>Possible to simulate with JSF (viewScope bean) </li></ul><ul><li>Consider formalizing this in JSF? </li></ul>
  66. 66. <ul><li>Event Handling </li></ul>
  67. 67. JSF Event Handling <ul><li>Inspired by Swing Event Model </li></ul><ul><li>Listeners registered on components </li></ul><ul><li>Components fire events </li></ul><ul><li>Declarative: listeners referenced via EL </li></ul>
  68. 68. JSF Event Handling <h:form> <h:commandButton value=&quot;Increment&quot; actionListener=&quot;#{counter.increment}&quot;/> <h:outputText value=&quot;#{counter.count}&quot;/> </h:form>
  69. 69. JSF Event Handling @ManagedBean @SessionScoped public class Counter { public int getCount() { return count; } public void increment() { count++; } private int count; }
  70. 70. Wicket Event Handling <ul><li>Components expose event-specific hooks </li></ul><ul><li>Subclasses override to receive notifications </li></ul>
  71. 71. Wicket Event Handling <form wicket:id=&quot;form&quot;> <input type=&quot;submit&quot; value=&quot;Increment&quot; wicket:id=&quot;button&quot;/> <span wicket:id=&quot;count&quot;>count</span> </form>
  72. 72. Wicket Event Handling public class EventsPage extends WebPage { public EventsPage() { Button button = new Button(&quot;button&quot;) { @Override public void onSubmit() { count++; } }; } private int count; }
  73. 73. Wicket Event Handling <ul><li>onSubmit() exposed at both Button and Form level </li></ul><ul><li>Button onSubmit() called first </li></ul><ul><li>Link component provides form/POST-free events </li></ul><ul><li>onClick() vs. onSubmit() </li></ul>
  74. 74. Tapestry Event Handling <ul><li>Naming Conventions </li></ul><ul><li>Annotations </li></ul>
  75. 75. Tapestry Event Handling <t:form t:id=&quot;form1&quot;> <input type=&quot;submit&quot; value=&quot;Increment&quot; t:type=&quot;submit&quot; t:id=&quot;button1&quot;/> ${count} </t:form>
  76. 76. Tapestry Event Handling public class Events { @Persist @Property private int count; // Called when any form is submitted void onSubmit() { count++; } }
  77. 77. Tapestry Event Handling // All of these work too! // Called when form 1 is submitted void onSubmitFromForm1() { count++ } // Called when any button is selected void onSelected() { count++; } // Called when button1 is selected void onSelectedFromButton1() { count++; }
  78. 78. Tapestry Event Handling // And these too @OnEvent(value=&quot;selected&quot;, component=&quot;button1&quot;) void increment() { count++ } @OnEvent(value=&quot;submit&quot;, component=&quot;form&quot;) void foo() { count++ }
  79. 79. Tapestry Event Handling <ul><li>Component-specific events before form </li></ul><ul><li>Global events before component-specific </li></ul><ul><li>ActionLink provides form/POST-free events </li></ul>
  80. 80. Event Handling Wrap Up <ul><li>Three very different approaches </li></ul><ul><li>Managed bean annotations simplify JSF approach </li></ul><ul><li>Possible to add a Tapestry-like solution to JSF? </li></ul><ul><li>Possible to add Wicket-like solution to JSF? </li></ul><ul><ul><li>Programmatic component creation cases, yes. </li></ul></ul><ul><ul><li>What about other cases? </li></ul></ul><ul><li>Form-level submit hook is nice </li></ul>
  81. 81. <ul><li>Ajax </li></ul>
  82. 82. JSF Ajax <ul><li>Before: Take your pick </li></ul><ul><ul><li>ADF/Ice/Rich/Prime/Trinidad </li></ul></ul><ul><li>Now: Standard Ajax APIs/implementation </li></ul><ul><li>Ajax behaviors attached to components </li></ul><ul><li>Primarily declarative solution </li></ul><ul><li>Programmatic APIs available too </li></ul>
  83. 83. JSF Ajax <ul><li><h:form> </li></ul><ul><li><h:commandButton value=&quot;Increment&quot; </li></ul><ul><li>actionListener=&quot;#{counter.increment}&quot;> </li></ul><ul><li><f:ajax render=&quot;count&quot;/> </li></ul><ul><li></h:commandButton> </li></ul><ul><li><h:outputText value=&quot;#{counter.count}&quot; </li></ul><ul><li>id=&quot;count&quot; /> </li></ul><ul><li></h:form> </li></ul>
  84. 84. JSF Ajax <f:ajax render=&quot;count&quot;/> <h:commandButton value=&quot;Increment&quot; actionListener=&quot;#{counter.increment}&quot;> <h:commandButton value=&quot;Reset&quot; actionListener=&quot;#{counter.reset}&quot;> </f:ajax>
  85. 85. JSF Ajax <ul><li>All standard components support behaviors </li></ul><ul><li>Attach points are component-specific </li></ul><ul><ul><li>Action, valueChange, focus, blur, mouse over, etc… </li></ul></ul><ul><li>Behavior mechanism is extensible </li></ul><ul><li>Not specific to Ajax </li></ul>
  86. 86. Wicket Ajax <ul><li>Ajax Components </li></ul><ul><li>Behaviors </li></ul>
  87. 87. Wicket Ajax AjaxButton button = new AjaxButton(&quot;button&quot;) { @Override public void onSubmit( AjaxRequestTarget target , Form form) { count++; if (target != null) { target.addComponent(label); } }});
  88. 88. Wicket Ajax label = new Label(&quot;count&quot;, …); label. setOutputMarkupId(true);
  89. 89. Wicket Ajax <ul><li>Many convenience components, behaviors </li></ul><ul><li>Fallback behavior: AjaxFallbackLink </li></ul><ul><li>setOutputMarkupPlaceholderTag() </li></ul><ul><li>Ajax debug window </li></ul>
  90. 90. Tapestry Ajax <ul><li>Ajax Zones </li></ul><ul><li>Mixins </li></ul>
  91. 91. Tapestry Ajax <t:form t:id=&quot;form1&quot; zone=&quot;countZone&quot; > <input type=&quot;submit&quot; value=&quot;Increment&quot; t:type=&quot;submit&quot; t:id=&quot;button1&quot;/> <t:zone t:id=&quot;countZone&quot;> Hello, ${count} </t:zone> </t:form>
  92. 92. Tapestry Ajax public class Ajax { @InjectComponent private Zone countZone; Object onSubmitFromForm1() { return countZone.getBody(); } }
  93. 93. Tapestry Ajax <ul><li>Zone supported by Form, ActionLink, EventLink </li></ul><ul><li>MultiZoneUpdate </li></ul><ul><li>Mixins: autocomplete </li></ul>
  94. 94. Ajax Wrap Up <ul><li>JSF 2.0 Ajax is competitive with other solutions </li></ul><ul><li>Wicket Ajax debug window is nice </li></ul><ul><ul><li>JSF implementations could provide equivalent </li></ul></ul><ul><li>Improve JSF's fallback story? </li></ul><ul><li>Resolve (or document) rendered toggling behavior </li></ul>
  95. 95. <ul><li>Navigation </li></ul>
  96. 96. JSF Navigation <ul><li>Traditional: POST-based navigation </li></ul><ul><li>POST triggers action </li></ul><ul><li>Action determines outcome </li></ul><ul><li>Outcome mapped to target view </li></ul>
  97. 97. JSF Navigation <h:commandButton action=&quot;#{nav.goToPageB}&quot;/> @ManagedBean(name=&quot;nav&quot;) @RequestScoped public class Navigation { public String goToPageB() { return &quot;success&quot;; } }
  98. 98. JSF Navigation <navigation-rule> <from-view-id>/pageA.xhtml</from-view-id> <navigation-case> <from-outcome>success</from-outcome> <to-view-id>/pageB.xhtml</to-view-id> <redirect/> </navigation-case> </navigation-rule>
  99. 99. JSF Implicit Navigation <ul><li>Declarative navigation is good for many cases </li></ul><ul><li>Perhaps too verbose for simple cases </li></ul><ul><li>Implicit navigation simplifies simple cases </li></ul><ul><li>Outcome implicitly treated as view id </li></ul><ul><li>Bypasses faces-config.xml </li></ul>
  100. 100. JSF Implicit Navigation <h:commandButton action=&quot;#{nav.goToPageB}&quot;/> @ManagedBean(name=&quot;nav&quot;) @RequestScoped public class Navigation { public String goToPageB() { // No faces-config entry required return &quot;pageB&quot; ; } }
  101. 101. JSF Pre-Emptive Navigation <ul><li>Implict navigation simplifies, but still POST-only </li></ul><ul><li>Not GET/bookmark-friendly </li></ul><ul><li>Pre-emptive navigation: best of both worlds </li></ul><ul><li>Navigation rules aggressively evaluated </li></ul><ul><li><h:link>/<h:button> produce GET requests </li></ul>
  102. 102. JSF Pre-Emptive Navigation <!-- Use navigation rules to determine &quot;success&quot; outcome target --> <h:button outcome=&quot;success&quot;/> <!-- Both pre-emptive and implicit. No faces-config needed. --> <h:button outcome=&quot;pageB&quot;/>
  103. 103. Wicket Navigation <ul><li>Programmatic navigation: setResponsePage() </li></ul><ul><li>Class vs. instance </li></ul>
  104. 104. Wicket Navigation Button button1 = new Button(&quot;button1&quot;) { public void onSubmit() { setResponsePage(PageB.class); } };
  105. 105. Wicket Navigation Button button1 = new Button(&quot;button1&quot;) { public void onSubmit() { PageB pageB = new PageB(); // Configure PageB instance… setResponsePage(pageB); } }; Wicket Navigation
  106. 106. Wicket Navigation <ul><li>Direct navigation also supported </li></ul><ul><li>BookmarkablePageLink </li></ul><ul><li>wicket:link </li></ul>
  107. 107. Wicket Navigation <!-- HTML --> <a wicket:id=&quot;bookmarkable&quot; href=&quot;PageB.html&quot;>Navigate To Page B</a> // Java form.add( new BookmarkablePageLink(&quot;bookmarkable&quot;, PageB.class));
  108. 108. Wicket Navigation <!-- No Java code required. --> <wicket:link> <ul> <li><a href=&quot;PageA.html&quot;>Page A</a></li> <li><a href=&quot;PageB.html&quot;>Page B</a></li> <li><a href=&quot;PageC.html&quot;>Page C</a></li> <li><a href=&quot;PageD.html&quot;>Page D</a></li> </ul> </wicket:link>
  109. 109. Tapestry Navigation <ul><li>Programmatic navigation: onSubmit() return </li></ul><ul><li>Like Wicket, navigate to class or instance </li></ul><ul><li>Instance page injected </li></ul>
  110. 110. Tapestry Navigation public class PageA { Object onSubmitFromForm1() { return PageB.class; } }
  111. 111. Tapestry Navigation public class PageA { @InjectPage private PageB pageB; Object onSubmitFromForm1() { // Configure pageB instance... return pageB; } }
  112. 112. Tapestry Navigation <ul><li>Direct navigation also supported </li></ul><ul><li>t:pageLink </li></ul>
  113. 113. Tapestry Navigation <t:pagelink t:page=&quot;PageB&quot;>Go</t:pagelink>
  114. 114. Navigation Wrap Up <ul><li>JSF 2.0 enhancements simplify navigation </li></ul><ul><li>String outcomes vs. class/instance </li></ul><ul><li>Introduce class/instance support in JSF? </li></ul><ul><li>Redirect defaults </li></ul>
  115. 115. <ul><li>Input Processing </li></ul>
  116. 116. JSF Input Processing <ul><li>EditableValueHolder lifecycle </li></ul><ul><ul><li>Decode </li></ul></ul><ul><ul><li>Conversion </li></ul></ul><ul><ul><li>Validation </li></ul></ul><ul><ul><li>Update model </li></ul></ul><ul><li>Value referenced via value expression </li></ul>
  117. 117. JSF Input Processing <h:inputText value=&quot;#{user.name}&quot;/> @ManagedBean public class User { public String getName() { return name; } public void setName(String name) { this.name = name; } private String name; }
  118. 118. JSF Conversion <ul><li>Converters control transformation to/from string </li></ul><ul><li>Attached to EditableValueHolder components </li></ul><ul><li>Default conversion for most types </li></ul><ul><li>Date/time and number converters for more control </li></ul><ul><li>Custom converters </li></ul>
  119. 119. JSF Conversion <h:inputText value=&quot;#{user.age}&quot;> <f:convertNumber integerOnly=&quot;true&quot;/> </h:inputText>
  120. 120. JSF Validation <ul><li>Validators verify converted value </li></ul><ul><li>Attached to EditableValueHolder components </li></ul><ul><li>Various standard validators provided with JSF </li></ul><ul><li>Also possible to implement custom validators </li></ul><ul><li>JSF 2.0 also applies JSR-303 validation constraints </li></ul>
  121. 121. JSF Validation <h:inputText value=&quot;#{user.age}&quot;> <f:validateLongRange minimum=&quot;18&quot;/> </h:inputText>
  122. 122. More JSF Validation <ul><li>Feedback </li></ul><ul><ul><li>Typically displayed via <h:messages>/<h:message> </li></ul></ul><ul><ul><li>More interesting feedback possible </li></ul></ul><ul><li>Multi-component validation </li></ul><ul><ul><li>Historically very tricky </li></ul></ul><ul><ul><li>PostValidate system event makes this much easier </li></ul></ul><ul><li>Client-side validation </li></ul><ul><ul><li>No out-of-box support </li></ul></ul><ul><ul><li>3rd party solutions available (Trinidad/ADF Faces) </li></ul></ul><ul><li>Ajax Validation </li></ul><ul><ul><li>Facilitated by <f:ajax> </li></ul></ul>
  123. 123. Wicket Input Processing <ul><li>Similar lifecycle to JSF </li></ul><ul><ul><li>Required field validation </li></ul></ul><ul><ul><li>Conversion </li></ul></ul><ul><ul><li>Validation </li></ul></ul><ul><ul><li>Push to model </li></ul></ul><ul><ul><li>onSubmit/onError </li></ul></ul><ul><li>Value referenced via Model contract </li></ul>
  124. 124. Wicket Input Processing <!-- HTML --> <input type=&quot;text&quot; wicket:id=&quot;firstName&quot;/> // Java User user = getUser(); form.add(new TextField(&quot;firstName&quot;, new PropertyModel(user, &quot;name&quot;)));
  125. 125. Wicket Conversion <ul><li>IConverter contract, similar to JSF Converter </li></ul><ul><li>Converts to/from string </li></ul><ul><li>Default converters </li></ul><ul><li>Type derived or hinted </li></ul><ul><li>Custom converters </li></ul><ul><ul><li>Override getConverter() </li></ul></ul>
  126. 126. Wicket Validation <ul><li>IValidator, similar to JSF Validator </li></ul><ul><li>Validators attached programmatically </li></ul>
  127. 127. Wicket Validation <!-- HTML --> <input type=&quot;text&quot; wicket:id=&quot;age&quot;/> // Java add(new TextField(&quot;age&quot;, new PropertyModel(getUser(), &quot;age&quot;)) .add(NumberValidator.minimum(18)));
  128. 128. More Wicket Validation <ul><li>Feedback </li></ul><ul><ul><li>FeedbackPanel (like h:messages) </li></ul></ul><ul><ul><li>FormComponentFeedbackBorder </li></ul></ul><ul><li>Multi-component validation </li></ul><ul><ul><li>IFormValidator </li></ul></ul><ul><li>Client-side validation </li></ul><ul><ul><li>No out-of-box support </li></ul></ul><ul><ul><li>Ajax validation preferred </li></ul></ul><ul><li>Ajax Validation </li></ul><ul><ul><li>AjaxFormValidatingBehavior </li></ul></ul>
  129. 129. Tapestry Input Processing <ul><li>Similar lifecycle to JSF, Wicket </li></ul><ul><ul><li>Conversion </li></ul></ul><ul><ul><li>Validation </li></ul></ul><ul><ul><li>Push to model </li></ul></ul><ul><ul><li>onSuccess/onFailure </li></ul></ul><ul><li>Value referenced via property expressions </li></ul>
  130. 130. Tapestry Input Processing <!-- TML --> <input type=&quot;text&quot; t:type=&quot;textfield&quot; t:value=&quot;user.name&quot;/> // Java public class Input { @Property private User user; }
  131. 131. Tapestry Conversion <ul><li>FieldTranslator, similar to Converter/IConverter </li></ul><ul><li>Event-based conversion </li></ul><ul><ul><li>toclient </li></ul></ul><ul><ul><li>parseclient </li></ul></ul>
  132. 132. Tapestry Conversion Events public class Input { String onToClientFromAge() { // Return String representation of age } Object onParseClientFromAge(String input) { // Return converted representation of age } }
  133. 133. Tapestry Validation <ul><li>FieldValidator, similar to Validator/Ivalidator </li></ul><ul><li>Constraints attached via component parameters </li></ul><ul><li>Event and annotation-based validation </li></ul>
  134. 134. Parameter-Based Validation <input type=&quot;text&quot; t:type=&quot;textfield&quot; t:value=&quot;user.age&quot; t:validate=&quot;required,min=18&quot;/>
  135. 135. Event-Based Validation void onValidateFromAge(Integer value) throws ValidationException { if (value < 18) throw new ValidationException(&quot;Too young!&quot;); }
  136. 136. Anntation-Based Validation public class Input { @Property @Validate(&quot;required,min=18&quot;) private int age; }
  137. 137. More Tapestry Validation <ul><li>Feedback </li></ul><ul><ul><li>Border highlight, hover text </li></ul></ul><ul><ul><li><t:errors> </li></ul></ul><ul><li>Multi-component validation </li></ul><ul><ul><li>onValidateForm() </li></ul></ul><ul><li>Client-side validation </li></ul><ul><ul><li>Provided automatically for standard validators </li></ul></ul><ul><li>Ajax Validation </li></ul><ul><ul><li>Client-side validation preferred </li></ul></ul>
  138. 138. Input Processing Wrap Up <ul><li>Similar input processing across frameworks </li></ul><ul><ul><li>Surprise? </li></ul></ul><ul><li>Pull client-side validation into JSF? </li></ul><ul><li>Improve feedback reporting </li></ul><ul><li>Encourage use of PostValidate system event for multi-component validation </li></ul>
  139. 139. <ul><li>Custom Components </li></ul>
  140. 140. JSF: Old School (Java) <ul><li>Java class (extends UIComponent) </li></ul><ul><li>Renderer class </li></ul><ul><li>Tag class </li></ul><ul><li>faces-config.xml </li></ul><ul><li>tld </li></ul>
  141. 141. JSF: New School (Java) <ul><li>Annotations replace faces-cofig.xml </li></ul><ul><li>Default Facelets handlers replace Tag class </li></ul><ul><li>taglib.xml replaces tld </li></ul>
  142. 142. JSF: New School (Composite) <ul><li>Single Facelets file defines composite component </li></ul><ul><li>Installed in resources directory </li></ul><ul><li>Component namespace/name derived </li></ul><ul><li>No external configuration </li></ul><ul><li>Optional Java component class </li></ul><ul><li>Optional properties file </li></ul>
  143. 143. resources/demo/titleBorder.xhtml <html ... ><body> <composite:implementation> <div class=&quot;tb-root&quot;> <div class=&quot;tb-title&quot;> #{cc.attrs.title} </div> <div class=&quot;tb-body&quot;> <composite:insertChildren/> </div> </div> </composite:implementation> </body></html>
  144. 144. Composite Interface <composite:interface> <composite:attribute name=&quot;title&quot; required=&quot;true&quot;/> </composite:interface>
  145. 145. Component Usage <html … xmlns:demo= &quot;http://java.sun.com/jsf/composite/demo&quot;> <body> <demo:titleBorder title=&quot;My Favorite Greeting&quot;> Hello, World! </demo:titleBorder> </body> </html>
  146. 146. Wicket Custom Components <ul><li>We have already seen several custom components </li></ul><ul><ul><li>Think event handling </li></ul></ul><ul><li>Can also define components with custom markup </li></ul><ul><li>Very similar to page </li></ul><ul><li>HTML/Java split </li></ul><ul><li>Java extends Panel or Border (not WebPage) </li></ul>
  147. 147. TitleBorder.html <html ... ><body> <wicket:border> <div class=&quot;tb-root&quot;> <div class=&quot;tb-title&quot; wicket:id=&quot;titleLabel&quot;>Title</div> <div class=&quot;tb-body&quot;> <wicket:body/> </div> </div> </wicket:border> </body></html>
  148. 148. TitleBorder.java public class TitleBorder extends Border { public TitleBorder(String id) { super(id); add(new Label(&quot;titleLabel&quot;, new PropertyModel(this, &quot;title&quot;))); } // Accessors private String title; }
  149. 149. Component Usage <!-- HTML --> <div wicket:id=&quot;titleBorder&quot;> Hello, World! </div> // Java add(new TitleBorder(&quot;titleBorder&quot;));
  150. 150. Tapestry Custom Components <ul><li>Again, similar to page </li></ul><ul><li>TML/Java split </li></ul><ul><li>Java component is a POJO </li></ul><ul><li>Located in app-package/components directory </li></ul>
  151. 151. TitleBorder.tml <div class=&quot;tb-root&quot; ... > <div class=&quot;tb-title&quot;> ${title} </div> <div class=&quot;tb-body&quot;> <t:body/> </div> </div>
  152. 152. TitleBorder.java public class TitleBorder { @Property @Parameter(required=true, defaultPrefix=BindingConstants.LITERAL) private String title; }
  153. 153. Component Usage <t:titleborder t:title=&quot;My Favorite Greeting&quot;> Hello, World! </t:titleborder>
  154. 154. Custom Component Wrap Up <ul><li>JSF custom component development became much, much simpler in 2.0 </li></ul><ul><li>Composite components provide ease of use previously only available in other frameworks </li></ul><ul><li>Further simplifications possible? </li></ul><ul><ul><li>Composite components </li></ul></ul><ul><ul><li>Java-based components </li></ul></ul>
  155. 155. <ul><li>Wrap Up </li></ul>
  156. 156. So Much To Do, So Little Time <ul><li>Many other possible points of comparison </li></ul><ul><ul><li>Performance </li></ul></ul><ul><ul><li>Tooling </li></ul></ul><ul><ul><li>Testing </li></ul></ul><ul><ul><li>I18N </li></ul></ul><ul><ul><li>Persistence </li></ul></ul><ul><ul><li>REST </li></ul></ul><ul><ul><li>Extensions </li></ul></ul><ul><ul><li>Community </li></ul></ul><ul><li>Other interesting frameworks too! </li></ul><ul><li>Presentation 2.0 :-) </li></ul>
  157. 157. Conclusion <ul><li>Some differences are fundamental </li></ul><ul><li>Interesting to see many similarities too </li></ul><ul><li>Looking outward: good exercise </li></ul><ul><li>Good to see historical areas of difficulty addressed by JSF 2.0. </li></ul><ul><li>JSF2.next: Keep the progress coming! </li></ul>
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×