Escolar Documentos
Profissional Documentos
Cultura Documentos
pages.xml
Concepto de template
R
Concepto de template:
x pantalla base que define estructura comn de las pantallas reales x contiene partes fijas y partes que deben ser redefinidas por cada pantalla x ejemplo de estructura de pantalla:
banner
sidebar
content footer
8
<!-- librerias de etiquetas --> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:s="http://jboss.com/products/seam/taglib" xmlns:t="http://myfaces.apache.org/tomahawk"> <!-- referencia al archivo que define estilos de los div --> <head> <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1" /> <title>Hotels reservation system</title> <link href="../css/screen.css" rel="stylesheet" type="text/css"/> </head>
<body> <!-- div que define estructura global de toda pantalla --> <div id="document" > <!-- toda pantalla tiene un banner fijo --> <div id="headerMenu"> <div id="titleMenu"><h4>CincoSOFT framework</h4></div> <div id="statusMenu"> <t:jscookMenu layout="hbr" theme="ThemeIE"> <t:navigationMenuItems value="#{login.menu}" /> </t:jscookMenu> </div> </div> <!-- toda pantalla tiene un contenido variable: partes sidebar y content deben ser definidos por c/pantalla --> <div id="container"> <div id="sidebar" style=" width : 150px;"> <ui:insert name="sidebar"/> </div> <div id="content" style="width : 500px;"> <ui:insert name="content"/> <ui:include src="footer.xhtml" /> </div> </div> </div> </body> </html>
10
<!-- librerias de etiquetas; template utilizado --> <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:t="http://myfaces.apache.org/tomahawk" xmlns:s="http://jboss.com/products/seam/taglib" template="../common/template.xhtml"> <!-- definicion de la parte content --> <ui:define name="content"> <div class="section"> <h1>Change Your Password</h1> </div> <div class="section"> ... </div> </ui:define> <!-- definicion de la parte content --> <ui:define name="sidebar"> <h1>changePassword use case</h1> </ui:define> </ui:composition>
11
/* para la parte content dentro del contenido variable */ #content { float: left; width: 548px; margin-top: 75px; padding-top: 5px; background: #fff url(../img/cnt.bg.gif) 0 0 repeat-x; } /* para un div section dentro de content */ #content .section { float: left; width: 518px; padding: 15px 15px 0 15px; } /* redefine h1 dentro de div section dentro de content */ #content .section h1 { font-family: "Trebuchet MS", Arial, sans-serif; line-height: normal; font-weight: normal; font-size: large; } ...
13
x dentro de <f:view> utilizar: botones <h:commandButton action="main" value="Go Login" styleClass="button" /> enlaces <s:link id="register" action="register" value="Register new user" />
14
15
elementos estndares h: y f:
x xmlns:h="http://java.sun.com/jsf/html x xmlns:f="http://java.sun.com/jsf/core"
16
17
18
Invocar acciones con o sin validacin previa: elementos <t:commandButton>, <s:button> y <s:link>
Invocar una accin enviando en una forma los datos suministrados por el usuario, previa validacin
x usar botn <t:commandButton> <h:form> ... <t:commandButton value="Proceed" action="#{hotelInscription.verifyNewHotel}" styleClass="button /> </h:form>
20
Invocar una accin sin requerir validar ni enviar los datos suministrados por el usuario
x usar <s:button> que no requiere campos validados antes de invocar la accin, por ej:
<s:button value="Cancel" action="#{hotelBooking.cancel}" styleClass="button"/>
22
23
R elementos <s:decorate>, <a:support>, <a:outputPanel> <s:validateAll> <!-- imagen para mostrar junto a campo invalido --> <f:facet name="beforeInvalidField" > <h:graphicImage value="../../public/img/error.gif" /> </f:facet> <!-- estilo para resaltar campo invalido --> <f:facet name="aroundInvalidField"> <s:span styleClass="errors"/> </f:facet> ... <div class="entry"> <div class="label">
<h:outputLabel for="creditCard">Credit Card #: </h:outputLabel>
</div> <div class="input"> <s:decorate> <h:inputText id="creditCard" value="#{booking.creditCard}" required="true"> <a:support event="onblur" reRender="creditCardErrors"/> </h:inputText> <br/> <a:outputPanel id="creditCardErrors"> <s:message/> </a:outputPanel> </s:decorate> </div> </div> ... </s:validateAll>
24
25
x Ejemplo: pantalla confirm.xhtml, mostrar campo checkoutDate : ... <div class="entry"> <div class="label">Check Out Date:</div> <div class="output"> <t:outputText value="#{booking.checkoutDate}"> <f:convertDateTime type="date"/> </t:outputText> </div> </div>
26
27
28
29
30
x Ejemplo: pantalla book.xhtml, edicin del campo checkinDate con validacin y campo de error:
... <s:validateAll> <f:subview> ... <div class="entry"> <div class="label">Check In Date:</div> <div class="input"> <t:inputCalendar id="checkinDate" renderAsPopup="true" value="#{booking.checkinDate} popupDateFormat="dd-MM-yyyy" renderPopupButtonAsImage="true" popupWeekString="Semana" popupTodayString="Hoy es" /> <br/> <span class="errors"> <h:message for="checkinDate" /> </span> </div> </div> ...
31
32
Listas de Seleccin
33
<h:selectOneMenu id="beds" value="#{booking.beds}"> <f:selectItem itemLabel="One king-size bed itemValue="1"/> <f:selectItem itemLabel="Two double beds" itemValue="2"/> <f:selectItem itemLabel="Three beds" itemValue="3"/> </h:selectOneMenu>
34
<h:form> ... <h:selectOneListbox id="systemProfiles" value="#{userGestion.systemProfile}" size="10" styleClass="selectOneListbox"> <f:selectItems value="#{userGestion.systemProfiles}"/> </h:selectOneListbox> </h:form>
35
public List<SelectItem> getSystemProfiles() { List<SelectItem> selectItems = new ArrayList<SelectItem>(); for (Profile p : systemProfiles){ . . . // value, display selectItems.add(new SelectItem(p.getId(), p.getName())); } return selectItems; }
36
invocado en value="#{userGestion.systemProfile}"
public Long getSystemProfile() { // return item value return ((Profile)systemProfiles.get(0)).getId(); }
38
39
@In(required=false) @Out private Hotel hotel; @DataModel private List<Atraction> atractions; public void selectHotel(Hotel selectedHotel) { hotel = em.merge(selectedHotel); atractions = hotel.getAtractions(); }
41
42
Operadores de comparacin:
> gt < lt >= ge <= le == eq != ne
Operadores lgicos:
and && or || not !
Operadores aritmticos:
+ * / div % mod ?
43
Ejemplos de Expresiones EL
R
45
elemento <t:dataTable>
46
R Pantalla main.xhtml: elemento <t:dataTable> <f:subview rendered="#{hotels.rowCount>0}"> <div id="scroll"> <h:form> <t:dataTable value="#{hotels}" var="hot" sortColumn="#{hotelSearching.column}" sortAscending="#{hotelSearching.ascending}" preserveSort="false" preserveDataModel="false" renderedIfEmpty="false">
<h:column> <f:facet name="header"> <t:commandSortHeader columnName="name" arrow="true"> <h:outputText value="Name" /> </t:commandSortHeader> </f:facet> <h:outputText value="#{hot.name}" /> </h:column> ... </t:dataTable> </h:form> </div> </f:subview>
47
Observar en la pantalla:
x el scroll es posible gracias al div que encierra el datatable: <div id="scroll">: est asociado al siguiente estilo en screen.css:
#scroll { height: 400px; overflow: auto; }
x en el encabezado de <t:datatable> se indican acciones asociadas a ordenar una columna y cambiar el modo de ordenamiento (ascendente o descendente)
se invocan mtodos setColumn() y setAscending() del EJB hotelSearching
x para cada columna ordenable, se indica con elemento <t:commandSortHeader> el nombre de la columna
se tendr para esa columna un criterio de ordenamiento en el EJB hotelSearching
48
51
52
x Se puede agregar una imagen "status" que se mueve mientras se completa una bsqueda:
<a:status> <f:facet name="start"> <h:graphicImage value="../../public/img/spinner.gif" /> </f:facet> </a:status>
53
54
55
56
EJB HotelSearching
x Servicio pblico find() invoca un query por lotes
public String find(){ page = 0; queryHotels(); return "main"; } private void queryHotels(){ String searchPattern = searchString==null ? "%" : '%' + searchString.toLowerCase().replace('*', '%') + '%'; hotels = em.createQuery ("select h from Hotel h where (lower(h.name) like :search " + " or lower(h.city) like :search " + " or lower(h.zip) like :search " + " or lower(h.address) like :search)" + " and h.status = :status " + " order by h.name ") .setParameter("search", searchPattern) .setParameter("status", Status.ACTIVE) .setMaxResults(pageSize) .setFirstResult( page * pageSize ) .getResultList(); }
57
x Servicios para obtener el siguiente lote (pantallazo) public boolean isNextPageAvailable(){ return hotels!=null && hotels.size()== pageSize; } public void nextPage() { page++; queryHotels(); }
59
60
62
EJB BookingList
x Nuevos servicios
update: para cada elemento booking de la lista que se muestra en la tabla, valida que la fecha checking sea anterior a checkout; si es correcto actualiza la BD con el nuevo valor del elemento:
public String update() { for (int i=0; i < bookings.size(); i++) { Booking b1 = (Booking)bookings.get(i); if (!b1.getCheckinDate().before( b1.getCheckoutDate() ) ) { FacesMessages.instance().add ("Check out date must be later than check in date for" + + " booking with number " + b1.getId()); return null; } Booking b2 = em.merge(b1); } getBookings(); return "main"; }
63
64
Tablas anidadas
65
66
... <!-- tabla mas externa de modulos --> <t:dataTable value="#{modules}" var="module" styleClass="standardTable"
columnClasses="standardTable_Column,standardTable_ColumnCentered"
/> </h:column> <h:column> <f:facet name="header">use case</f:facet> <!-- tabla intermedia de usecases de cada modulo --> <t:dataTable value="#{module.usecases}" var="usecase" styleClass="standardTable_ColumnCentered" columnClasses="nestedColumn1,nestedColumn2" rowClasses="standardTable_Row1,standardTable_Row2" >
67
<t:dataTable value="#{usecase.services}" var="service" styleClass="nestedColumn2" columnClasses= "moreNestedColumn1,moreNestedColumn2"> <h:column> <t:outputText value="#{service.display}"/> </h:column> <h:column> <h:selectBooleanCheckbox value="#{service.activeInProfile}" /> </h:column> </t:dataTable> </h:column> </t:dataTable> </h:column> <f:facet name="footer"> <h:panelGroup> <t:commandButton value="Update" . . ./> </h:panelGroup> </f:facet> </t:dataTable>
68
69
elemento <t:jscookMenu>
70
Entidad Menu
R
/* elemento submenu */ insert into menu (id, display, icon, action, usecase_id, module_id, parent_id) values (nextval('hibernate_sequence'), 'Security actions', 'playBlue.jpg', NULL, NULL, (select id from module where name = 'security'),NULL ); /* elemento terminal correspondiente a un caso de uso */ insert into menu (id, display, icon, action, usecase_id, module_id, parent_id) values ( nextval('hibernate_sequence'), NULL, 'playOrange.jpg', 'password', (select id from usecase where name = 'changePassword'), (select id from module where name = 'security'), (select id from menu where display = 'Security actions') ); ...
73
obtiene los submenus de cada elemento para calcular nmero de hijos (numChilds) elimina cada elemento terminal correspondient a un caso de uso no permitido al usuario, actualizando numChilds de su elemento padre elimina elementos no terminales con 0 hijos (numChilds == 0) 74
x mtodo getMenu() invocado cada vez que una pantalla requiere el men (elemento <t:jscookmenu>): construye recursivamente la estructura del menu contruye un objeto NavigationMenuItem para cada elemento del men si un elemento tiene hijos, se le asocia un arreglo NavigationMenuItem[] donde cada elemento corresponde a un hijo
75
Internacionalizacin en JSF
76
Objetivos:
x x x x el usuario debe poder escoger el idioma de su preferencia existe idioma por defecto segn localizacin del usuario los letreros de las pantallas deben salir en el idioma vigente los mensajes de errores de validacin tambin deben salir en el idioma vigente
Letreros de pantallas deben registrarse en archivos de propiedades para los diferentes idiomas
x Archivo messages.properties: contiene el valor de los letreros de las pantallas en el idioma por defecto (ubicado bajo WEB-INF/classes) x Archivos messages_xx.properties:
c/u contiene el valor de los letreros en un determinado idioma valor de xx corresponde a un idioma ms opcionalmente un pas: en, en_US, en_AU, de, fr, es, es_CO, ja, it, ca, pt, ru, zh, ... cuando el usuario selecciona un idioma, se debe establecer cul es el archivo de propiedades vigente
77
x en los diferentes archivos de propiedades de idiomas debe existir el valor de la propiedad GoLogin, por ejemplo en el archivo messages_es.properties:
GoLogin=Entrar
78
JSF selecciona como idioma vigente (locale) el correspondiente al browser Si no se puede deducir del browser: se usa el idioma default indicado en faces-config.xml:
<application> ... <locale-config> <default-locale>en</default-locale> <supported-locale>fr</supported-locale> <supported-locale>es_CO</supported-locale> </locale-config> </application>
Si faces-config-xml no indica idioma default: se usa el idioma asociado al servidor Los letreros de las pantallas que usen propiedades messages extraern los valores del archivo messages_xx.properties asociado al idioma vigente xx
x si no existe el archivo messages_xx.properties : se utiliza el archivo messages.properties 79
En la pantalla de entrada (home) agregar lista de seleccin con los idiomas ofrecidos
x la lista de seleccin se apoya componente interno de seam localeSelector que captura el idioma seleccionado por el usuario y lo asigna como idioma de la sesin: <h:outputText value="#{messages.SelectLanguage}(select)" /> <h:selectOneMenu value="#{localeSelector.localeString}"> <f:selectItems value="#{localeSelector.supportedLocales}"/> </h:selectOneMenu> <h:commandButton value="#{messages.ChangeLanguage}(change)" action="#{localeSelector.select}" styleClass="button" />
80
x faces-config.xml debera restringir los idiomas soportados a solamente los que tienen archivo messages_xx.properties asociado, y solamente esos idiomas saldrn en la lista de seleccin x cuando el usuario selecciona un idioma, este se vuelve el vigente para la sesion
si no existe el archivo messages_xx.properties correspondiente, entonces se usar el archivo asociado al browser si tampoco existe ste, entonces se usara el archivo default messages.properties
81
El atributo required="true" implica validacion JSF con mensaje de error traducido al idioma vigente:
<h:inputText id="name" value="#{hotel.name} required="true" > <s:validate /> </h:inputText> <br/> <span class="errors"> <h:message for="name" /> </span>
Cuando el usuario no suministra ningn valor, sale mensaje de error construido por JSF en el idioma vigente, ejemplo:
"name": Value is required. "name": Valor requerido. "name": Une donne est requise. "name": Il valore obbligatorio "name": Um valor requerido. "name": Eingabe erforderlich.
El atributo id debe usar una propiedad de idioma para mostrarse en el idioma vigente:
cambiar id="name" por id="#{messages.name}
82
83
x Se recomienda dar valor en los archivos messages_xx.properties a las propiedades asociadas a anotaciones de validacion de entidades:
por ej: en messages_en.properties # para anotaciones @AssertFalse y @AssertTrue validator.assertFalse=assertion failed validator.assertTrue=assertion failed # para anotaciones @Future y @Past validator.future=must be a future date validator.past=must be a past date # anotaciones @Length(min=, max=)y @Range(min=, max=) validator.length=length must be between {min} and {max} validator.range=must be between {min} and {max} # para anotacion @Max(value=) y @Min(value=) validator.max=must less than or equal to {value} validator.min=must greater than or equal to {value} # para anotacion @NotNull validator.notNull=may not be null # para anotacion @Pattern(regex="", flag=) validator.pattern=must match "{regex}" # para anotacion @Size(min=, max=) validator.size=size must be between {min} and {max} # para anotacion @Email validator.email=not a well-formed email address
84
queda en result: "At 12:30 PM on Jul 3, 2053, there was a disturbance 85 in the Force on planet 7. "
x Propiedades usadas en la validacin de elementos Myfaces Tomahawk (como ej. de librera de elementos JSF):
vienen en el jar correspondiente a la librera: myfaces-impl-1.1.4.jar hay un archivo por cada idioma soportado usan en general parmetros, ej en Messages_fr.properties del jar: org.apache.myfaces.Date.INVALID_detail = The given value ({0}) is not a correct date se pueden redefinir y es recomendable agregar las propiedades faltantes, por ej en messages_fr.properties de la aplicacin: org.apache.myfaces.calendar.CONVERSION_detail = "{0}"\: La donn\u00E9e "{1}" ne peut pas etre convertie a une date.
Consulta desde los EJBs a propiedades del archivo asociado al idioma vigente
R