Training: Day Four - Struts, Tiles, Renders and Faces

42
Presentation Layer Sérgio Silva October 2013

description

This is the fourth in our four part training sessions introducing FenixEdu development for new collaborators. In this last session, we introduce our two presentation frameworks present in fenix, Struts and Faces, the presentation plugin Tiles and our rendering library Renders

Transcript of Training: Day Four - Struts, Tiles, Renders and Faces

Page 1: Training: Day Four - Struts, Tiles, Renders and Faces

Presentation Layer

Sérgio Silva October 2013

Page 2: Training: Day Four - Struts, Tiles, Renders and Faces

Fenix Architecture

MYSQL

Application Container (Tomcat, Jetty)

Fenix Framework(STM)

DomainModel

JSPsrenderers

Struts

Faces

Jersey(REST API)

Page 3: Training: Day Four - Struts, Tiles, Renders and Faces

Today

MYSQL

Application Container (Tomcat, Jetty)

Fenix Framework(STM)

DomainModel

JSPsrenderers

Struts

Faces

Jersey(REST API)

Page 4: Training: Day Four - Struts, Tiles, Renders and Faces

StrutsControl Layer

● open-source web application framework

● uses and extends the Java Servlet API

● model–view–controller (MVC) architecture

● version 1.2.7

● http://struts.apache.org/release/1.2.x/

Page 5: Training: Day Four - Struts, Tiles, Renders and Faces

StrutsControl Layer

Page 6: Training: Day Four - Struts, Tiles, Renders and Faces

StrutsControl Layer

Page 7: Training: Day Four - Struts, Tiles, Renders and Faces

Struts Dispatching

fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

Page 8: Training: Day Four - Struts, Tiles, Renders and Faces

Struts DispatchingModule

Semantic division in modules

● struts-publico.xml

● .do maps to Struts Servlet (JavaServlet API)

○ src/main/resources/web.xml

fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

Page 9: Training: Day Four - Struts, Tiles, Renders and Faces

Struts DispatchingMapping

Mapping between path and action

● The path is a string

○ “/executionCourse”

● Where is the mapping ?

○ Mapping with annotations (what you should use)

@Mapping(module="publico" path="/executionCourse")

○ struts-publico.xml (read-only, don’t create things here)<action type="n.s.f.p.A.p.ExecutionCourseDA" parameter="method" path="/executionCourse">

fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

Page 10: Training: Day Four - Struts, Tiles, Renders and Faces

Struts DispatchingMapping

Mapping between path and action● Action Class ( ExecutionCourseDA.java)

● each action is module aware

● usually extends FenixDispatchAction (check outline on eclipse)

○ helper methods■ getFromRequest

■ redirect

■ getLoggedPerson

■ getDomainObject(request,parameter)

● method execute runs always

DEMO

fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

Page 11: Training: Day Four - Struts, Tiles, Renders and Faces

ExecutionCourseDA.java

public ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { final String executionCourseOID = request.getParameter("executionCourseID"); final ExecutionCourse executionCourse = FenixFramework.getDomainObject(executionCourseOID); Map<> attendsMap = getAttendsMap(executionCourse); request.setAttribute("executionCourse", executionCourse); request.setAttribute("attendsMap", attendsMap); request.setAttribute("dont-cache-pages-in-search-engines", Boolean.TRUE); return mapping.findForward("execution-course-marks");}

● Parameters○ get values on query string

● Attributes○ get or set state on request

Struts @ FenixActionfenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

Page 12: Training: Day Four - Struts, Tiles, Renders and Faces

StrutsWrapping Up

Page 13: Training: Day Four - Struts, Tiles, Renders and Faces

JSPsPresentation Layer

Page 14: Training: Day Four - Struts, Tiles, Renders and Faces

StrutsPresentation Layer

● Tiles○ templating system○ create a common look and feel for a web application○ create reusable view components○ bridge to JSPs○ module aware

● tiles-<module>-definitions.xml○ template definitions

● tiles-<module>-pages-definitions.xml○ fill in the template

Page 15: Training: Day Four - Struts, Tiles, Renders and Faces

ExecutionCourseDA.java

public ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { final String executionCourseOID = request.getParameter("executionCourseID"); final ExecutionCourse executionCourse = FenixFramework.getDomainObject(executionCourseOID); Map<> attendsMap = getAttendsMap(executionCourse); request.setAttribute("executionCourse", executionCourse); request.setAttribute("attendsMap", attendsMap); request.setAttribute("dont-cache-pages-in-search-engines", Boolean.TRUE); return mapping.findForward("execution-course-marks");}

Struts @ FenixForwards

Page 16: Training: Day Four - Struts, Tiles, Renders and Faces

ExecutionCourseDA.java

public ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { final String executionCourseOID = request.getParameter("executionCourseID"); final ExecutionCourse executionCourse = FenixFramework.getDomainObject(executionCourseOID); Map<> attendsMap = getAttendsMap(executionCourse); request.setAttribute("executionCourse", executionCourse); request.setAttribute("attendsMap", attendsMap); request.setAttribute("dont-cache-pages-in-search-engines", Boolean.TRUE); return mapping.findForward("execution-course-marks");}

● What is mapping.findForward(..) ?

Struts @ FenixForwards

Page 17: Training: Day Four - Struts, Tiles, Renders and Faces

ExecutionCourseDA.java

public ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { final String executionCourseOID = request.getParameter("executionCourseID"); final ExecutionCourse executionCourse = FenixFramework.getDomainObject(executionCourseOID); Map<> attendsMap = getAttendsMap(executionCourse); request.setAttribute("executionCourse", executionCourse); request.setAttribute("attendsMap", attendsMap); request.setAttribute("dont-cache-pages-in-search-engines", Boolean.TRUE); return mapping.findForward("execution-course-marks");}

● Forwards annotation (what you should use)@Forwards({ @Forward(name = "execution-course-marks", path = "/publico/executionCourse/marks.jsp") })public class ExecutionCourseDA extends FenixDispatchAction { … }

● name - forward name● path - logic name for tiles

Struts @ FenixForwards

Page 18: Training: Day Four - Struts, Tiles, Renders and Faces

ExecutionCourseDA.java

public ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { final String executionCourseOID = request.getParameter("executionCourseID"); final ExecutionCourse executionCourse = FenixFramework.getDomainObject(executionCourseOID); Map<> attendsMap = getAttendsMap(executionCourse); request.setAttribute("executionCourse", executionCourse); request.setAttribute("attendsMap", attendsMap); request.setAttribute("dont-cache-pages-in-search-engines", Boolean.TRUE); return mapping.findForward("execution-course-marks");}

● struts-publico.xml<action type="n.s.f.p.A.p.ExecutionCourseDA" parameter="method" path="/executionCourse"> <forward path="execution-course-marks" name="execution-course-marks"></forward> …………………………………………………</action>

● name - forward name● path - logic name for tiles

Struts @ FenixForwards (Deprecated)

Page 19: Training: Day Four - Struts, Tiles, Renders and Faces

● tiles-public-definitions.xml<definition name="execution-course-marks" extends="definition.public.executionCourse"> <put name="body" value="/publico/executionCourse/marks.jsp"/></definition>

● tiles-public-pages-definitions.xml<definition name="definition.public.executionCourse" page="/layout/istLayout.jsp"> <put name="title" value="/commons/functionalities/courseTitle.jsp" /> <put name="hideLanguage" value="true"/> <put name="symbols_row" value="/publico/degreeSite/symbolsRow.jsp" /> <put name="profile_navigation" value="/publico/degreeSite/profileNavigation.jsp" /> <put name="main_navigation" value="/publico/executionCourse/mainNavigation.jsp" /> <put name="body_header" value="/publico/executionCourse/executionCourseHeader.jsp" /> <put name="body" value="/commons/blank.jsp" /> <put name="footer" value="/publico/degreeSite/footer.jsp" /> <put name="rss" value="/messaging/announcements/rssHeader.jsp"/> <put name="keywords" value="/messaging/announcements/keywordsHeader.jsp"/></definition>

● istLayout.jsp<tiles:insert attribute="body" ignore="true"/><tiles:insert attribute="footer" ignore="true"/>

Struts @ FenixForwards (Deprecated)

Page 20: Training: Day Four - Struts, Tiles, Renders and Faces

JSPs

● JavaServer Pages (JSP)

● create dynamically generated web pages

based on HTML

● HTML with behaviour

DEMO

publico/executionCourse/marks.jsp

Page 21: Training: Day Four - Struts, Tiles, Renders and Faces

● publico/executionCourse/marks.jsp

<logic:iterate id="evaluation" name="executionCourse" property="orderedAssociatedEvaluations">

● ExecutionCourseDA.javapublic ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { final String executionCourseOID = request.getParameter("executionCourseID"); final ExecutionCourse executionCourse = FenixFramework.getDomainObject(executionCourseOID); Map<Attends, Map<Evaluation, Mark>> attendsMap = getAttendsMap(executionCourse); request.setAttribute("executionCourse", executionCourse); request.setAttribute("attendsMap", attendsMap); request.setAttribute("dont-cache-pages-in-search-engines", Boolean.TRUE); return mapping.findForward("execution-course-marks");}

JSPswithout renderers

Page 22: Training: Day Four - Struts, Tiles, Renders and Faces

● publico/executionCourse/marks.jsp

<logic:iterate id="evaluation" name="executionCourse" property="orderedAssociatedEvaluations">

● ExecutionCourseDA.javapublic ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { final String executionCourseOID = request.getParameter("executionCourseID"); final ExecutionCourse executionCourse = FenixFramework.getDomainObject(executionCourseOID); Map<Attends, Map<Evaluation, Mark>> attendsMap = getAttendsMap(executionCourse); request.setAttribute("executionCourse", executionCourse); request.setAttribute("attendsMap", attendsMap); request.setAttribute("dont-cache-pages-in-search-engines", Boolean.TRUE); return mapping.findForward("execution-course-marks");}

● name - get from request attribute or parameter with that name● property - get property from object

○ executionCourse.getOrderedAssociatedEvaluations ()

● uses Java Bean conventions● id - defines bean in jsp scope

JSPswithout renderers

Page 23: Training: Day Four - Struts, Tiles, Renders and Faces

● simple bean example

<h3><bean:write name="executionCourse" property="name"></h3>

● executionCourse.getName()

● Tag libs○ <bean:*>○ <logic:*>○ <html:*>○ http://struts.apache.org/release/1.2.x/userGuide/

JSPswithout renderers

Page 24: Training: Day Four - Struts, Tiles, Renders and Faces

● integration with domain model and fenix-

framework

● our taglib <fr:*>○ fr:view - display domain objects

○ fr:create - create domain objects

○ fr:edit - edit domain objects

● renderers-config.xml

○ All renderers definitions

JSPsRenderers

Page 25: Training: Day Four - Struts, Tiles, Renders and Faces

● What is a renderer ?○ java class used to produce HTML○ Properties

■ layout● logical name for renderer definition

■ mode ● input● output

■ class● rendered type

○ String○ ExecutionCourse○ int

■ properties● render specific properties

JSPsRenderers

Page 26: Training: Day Four - Struts, Tiles, Renders and Faces

● output renderer

<renderer type="java.util.Collection" layout="contact-list" class="n.s.f.p.r.ContactListRenderer"> <property name="bundle" value="APPLICATION_RESOURCES"/> <property name="defaultLabel" value="label.partyContacts.defaultContact"/></renderer>

● input renderer<renderer mode="input" type="j.u.Collection" layout="option-select" class="p.i.fr.InputCheckBoxListRenderer"> <property name="eachClasses" value="dinline" /></renderer>

JSPsrenderers-config.xml

Page 27: Training: Day Four - Struts, Tiles, Renders and Faces

● manageApplications.jsp

<fr:view name="appsOwned" schema="oauthapps.view.apps"> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter"/> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..."/> </fr:layout></fr:view>

● renderers-config.xml

<renderer type="java.util.Collection" layout="tabular" class="p.i.f.r.CollectionRenderer"> <property name="groupLinks" value="true"/> <property name="linkGroupSeparator" value=", "/></renderer>

JSPsRenderers

Page 28: Training: Day Four - Struts, Tiles, Renders and Faces

● manageApplications.jsp

<fr:view name="appsOwned" schema="oauthapps.view.apps"> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter"/> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..."/> </fr:layout></fr:view>

● renderers-config.xml

<renderer type="java.util.Collection" layout="tabular" class="p.i.f.r.CollectionRenderer"> <property name="groupLinks" value="true"/> <property name="linkGroupSeparator" value=", "/></renderer>

JSPsRenderers

Page 29: Training: Day Four - Struts, Tiles, Renders and Faces

JSPsRenderers

Page 30: Training: Day Four - Struts, Tiles, Renders and Faces

JSPsRenderers

Page 31: Training: Day Four - Struts, Tiles, Renders and Faces

● manageApplications.jsp

<fr:view name="appsOwned" schema="oauthapps.view.apps"> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter"/> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..."/> </fr:layout></fr:view>

Renderers(reusable) Schemas

Page 32: Training: Day Four - Struts, Tiles, Renders and Faces

● manageApplications.jsp

<fr:view name="appsOwned" schema="oauthapps.view.apps"> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter"/> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..."/> </fr:layout></fr:view>

Renderers(reusable) Schemas

Page 33: Training: Day Four - Struts, Tiles, Renders and Faces

● Schemas

<fr:view name="appsOwned" schema="oauthapps.view.apps"> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter"/> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..."/> </fr:layout></fr:view>

● specify how object’s slots are rendered

● schemas-config.xml

● *-schemas.xml

○ logical separation

Renderers(reusable) Schemas

Page 34: Training: Day Four - Struts, Tiles, Renders and Faces

● personnelSection-schemas.xml

<schema name="oauthapps.view.apps" type="net.sourceforge.fenixedu.domain.ExternalApplication" bundle="APPLICATION_RESOURCES"> <slot name="name" key="oauthapps.label.app.name" /> <slot name="description" layout="longText" key="oauthapps.label.app.description"/> <slot name="scopes" layout="flowLayout"> <property name="eachLayout" value="values"></property> <property name="eachSchema" value="oauthapps.view.scope.name"></property> <property name="htmlSeparator" value=", "></property> </slot> <slot name="siteUrl" key="oauthapps.label.app.site.url" /></schema>

● name ○ unique identifier

● type○ schema target type

● slot○ object slot to render

Renderers(reusable) Schemas

Page 35: Training: Day Four - Struts, Tiles, Renders and Faces

<fr:view name="appsOwned" schema="oauthapps.view.apps"> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter"/> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..."/> </fr:layout></fr:view>

Renderers(inline) Schemas

Page 36: Training: Day Four - Struts, Tiles, Renders and Faces

<fr:view name="appsOwned"> <fr:schema type="net.sourceforge.fenixedu.domain.ExternalApplication" bundle="APPLICATION_RESOURCES"> <fr:slot name="name" key="oauthapps.label.app.name" /> <fr:slot name="description" layout="longText" key="oauthapps.label.app.description"/> <fr:slot name="scopes" layout="flowLayout"> <fr:property name="eachLayout" value="values"></property> <fr:property name="eachSchema" value="oauthapps.view.scope.name"></property> <fr:property name="htmlSeparator" value=", "></property> </fr:slot> <fr:slot name="siteUrl" key="oauthapps.label.app.site.url" /> </fr:schema> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter"/> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..."/> </fr:layout></fr:view>

Renderers(inline) Schemas

Page 37: Training: Day Four - Struts, Tiles, Renders and Faces

Resource Bundles

<fr:view name="appsOwned"> <fr:schema type="net.sourceforge.fenixedu.domain.ExternalApplication" bundle="APPLICATION_RESOURCES"> <fr:slot name="name" key="oauthapps.label.app.name" /> <fr:slot name="description" layout="longText" key="oauthapps.label.app.description"/> <fr:slot name="scopes" layout="flowLayout"> <fr:property name="eachLayout" value="values"></property> <fr:property name="eachSchema" value="oauthapps.view.scope.name"></property> <fr:property name="htmlSeparator" value=", "></property> </fr:slot> <fr:slot name="siteUrl" key="oauthapps.label.app.site.url" /> </fr:schema> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter"/> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..."/> </fr:layout></fr:view>

● src/main/resources/resources/ApplicationResources_pt.properties○ oauthapps.label.app.name="Nome Aplicação"

● src/main/resources/resources/ApplicationResources_en.properties○ oauthapps.label.app.name="Application Name"

Page 38: Training: Day Four - Struts, Tiles, Renders and Faces

JavaServer Faces

● JavaServer Faces○ version 1.1

● component-based user interfaces for web

apps

● servlet mapping *.faces

● faces-config.xml

Page 39: Training: Day Four - Struts, Tiles, Renders and Faces

https://fenix.ist.utl.pt/publico/degreeSite/viewCurricularCourse.faces?degreeID=2761663971474

JavaServer Faces

Page 40: Training: Day Four - Struts, Tiles, Renders and Faces

● publico/degreeSite/viewCurricularCourse.jsp

<h:outputFormat value="<h1>#{CurricularCourseManagement.degreePresentationName}</h1>" escape="false"/>

● Backing Bean

○ name - CurricularCourseManagement

● faces-config.xml

<managed-bean> <description>ManagerCurricularCourseManagementBackingBean</description> <managed-bean-name>ManagerCurricularCourseManagement</managed-bean-name> <managed-bean-class>n.s.f.p.b.m.c.ManagerCurricularCourseManagementBackingBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope></managed-bean>

DEMO

https://fenix.ist.utl.pt/publico/degreeSite/viewCurricularCourse.faces?degreeID=2761663971474

JavaServer Faces

Page 41: Training: Day Four - Struts, Tiles, Renders and Faces

Golden Rules

● don’t create stuff in struts-*.xml○ use annotations

■ @Mapping■ @Forwards

● @Forward

● renderers-config.xml○ read-only (unless you are going to create a new renderer)

● read renderers docs○ Administrador > Frameworks > Renderers > Exemplos Renderers

● install resource bundle editor○ https://fenix-ashes.ist.utl.pt/fenixWiki/I18NConventions

Page 42: Training: Day Four - Struts, Tiles, Renders and Faces

Q & A ?