Java Server Faces
Transcript of Java Server Faces
1. INTRODUCCIÓN ...............................................................................1
2. CREACIÓN DE UNA APLICACIÓN WEB CON JSF ...............................13
3. USANDO ADF FACES TABLES...........................................................45
4. USANDO ADF FACES TREE ..............................................................71
5. MENÚS ...........................................................................................97
GLOSARIO .........................................................................................119
REFERENCIAS WEB ............................................................................121
BIBLIOGRAFÍA ..................................................................................123
índi
ce g
ener
al_
1
Introducción 1
1.1. ¿QUÉ ES JSF? ...............................................................................3
1.2. JSF VS STRUTS .............................................................................4
1.2.1. Escalabilidad .....................................................................5
1.2.2. Controlador .......................................................................5
1.2.3. Navegación .......................................................................6
1.2.4. Conclusiones .....................................................................8
1.3. IMPLEMENTACIÓN DE JSF: ADF FACES .........................................9
1.4. ENTORNO DE DESARROLLO DEL CURSO ......................................11
índi
ce_
3
Introducción 1
1.1. ¿QUÉ ES JSF?
JavaServer Faces (JSF) es un framework estándar Java que permite construir aplicaciones
Web. Se define por las especificaciones JSR 127, JSR 252 y JSR 276 e implementa el
patrón Modelo-Vista-Controlador (MVC).
Dicho modelo MVC es un patrón de arquitectura de desarrollo software que separa las
aplicaciones en tres capas diferenciadas: datos (Modelo), interfaz de usuario (Vista) y lógica
de control (Controlador). Esto permite una separación entre la interfaz de usuario y la lógica
que hace que el mantenimiento de las aplicaciones JSF sea sencillo.
JSF es un conjunto de componentes de usuario (UI) que permite construir la capa de vista
de las aplicaciones Web. Así, proporciona un conjunto de APIs para desarrollar estos
componentes UI y gestionar su funcionamiento mediante el tratamiento de eventos, la
validaciones de entrada, la definición de la navegación entre páginas y el soporte de
accesibilidad.
Asimismo, JSF trata el interfaz de usuario (Vista) de una forma parecida al estilo de Swing o
Visual Basic, realizando su programación a través de componentes y basada en eventos.
Además, las clases de componentes UI incluidas en JSF encapsulan su funcionalidad y no la
presentación en un tipo de cliente específico por lo que esto permite poder ser pintados en
distintos clientes.
Por otro lado, JSF permite también la creación de nuestros propios componentes UI
personalizados a partir de la extensión de los ya existentes e incluye la propiedad de
“render” para pintarlos según nos convenga.
4
Introducción 1
Además, la tecnología JSF ha sido diseñada para ser flexible al contrario que otras
tecnologías actuales que exigen la utilización de lenguajes de marcadores, protocolos o el
uso de determinados clientes.
Por todo esto, JSF es fácil de usar, su arquitectura define claramente una separación entre
las capas de lógica y presentación permitiendo que la conexión entre ambas sea sencilla.
Este diseño posibilita a cada miembro del equipo de desarrollo centrarse en la parte de la
aplicación que le corresponde desarrollar, proporcionando además un modelo de
programación sencilla que simplifica la posterior unión de todos los módulos. De esta forma,
desarrolladores Web sin experiencia pueden utilizar componentes UI de JSF en sus páginas
Web sin escribir apenas código.
Por último, destacar que JSF resulta atractivo tanto para desarrolladores noveles como
expertos. Los primeros podrán comprobar cómo se añaden componentes a una página con
un simple “drag and drop” (es fácil de usar y muy visual) mientras que los segundos
encontrarán un estándar robusto que les ofrece mucho potencial y flexibilidad para
programar.
1.2. JSF VS STRUTS
En este apartado describiremos las principales características de JSF frente a uno de los
framework de desarrollo más extendidos (Struts), con el objeto de obtener una regla de
valoración en cuanto a qué nos aporta JSF.
Debido a que Struts es un framework mucho más maduro que JSF (éste tan sólo lleva dos
años utilizándose), en principio, puede parecer mucho más seguro y rentable abordar el
desarrollo de una aplicación utilizándolo. No obstante, como veremos, esto no tiene por qué
ser así en todos los casos, ya que, JSF además de ser un framework con mucho potencial,
presenta ventajas sobre Struts como por ejemplo, que JSF proporciona la capacidad de
construir componentes desde distintas tecnologías por lo que se presta a ser desarrollado
desde una amplia variedad de herramientas.
Por otra parte, aunque Struts se diseñó inicialmente para ser independiente de la capa del
modelo, normalmente los datos de las páginas deben pasar al ActionForm siguiendo un
modelo específico de entrada, lo que requiere realizar codificación manual. JSF, sin embargo,
oculta los detalles de los datos dentro del árbol componentes, permitiendo vincular a
cualquier clase Java componentes ricos como rejillas de datos.
5
Introducción 1
1.2.1. Escalabilidad
Tanto Struts como JSF proporcionan un nivel de escalabilidad tal que les permite satisfacer
futuros requerimientos. Así, una de las características de Struts es poseer una clase
RequestProcessor que tiene varios métodos para recuperar información a lo largo de todo
el ciclo de vida de la petición. Podemos extender esta clase con el objetivo de reemplazar o
mejorar el framework.
Asimismo, JSF proporciona una funcionalidad equivalente permitiéndonos extender
determinadas interfaces del ciclo de vida. Además, JSF desacopla totalmente el pintado del
Controlador permitiendo a los desarrolladores proporcionar sus propias herramientas de
pintado para construir componentes personalizados. Ésta es una de las características más
potentes de JSF que no proporciona Struts.
1.2.2. Controlador
Podemos considerar que las características más importantes de un framework son el
controlador y la navegación. Struts utiliza para la capa del controlador los patrones Front
Controller y Command Patterm. Así, la forma de trabajar es la siguiente: un servlet
realiza una solicitud, transforma los parámetros http en un Java ActionForm y éste en una
clase Action (un comando). El framework de Struts utiliza sólo un manejador de eventos
para las peticiones http de tal forma que, una vez satisfecha la petición, el ActionForm
devuelve el resultado al Controlador que lo utiliza para seleccionar la navegación siguiente.
JSF, sin embargo, utiliza el patrón Page Controller. Aunque sólo dispone de un único
servlet para recibir página con componentes, se ejecutarán distintos eventos por cada uno
de ellos, traduciéndolos gracias a un traductor de componentes.
Asimismo, los componentes también pueden vincularse a los datos desde el Modelo. De esta
forma, JSF añade más ventajas al Controlador y, al mismo tiempo, proporciona toda la
flexibilidad del patrón Page Controller.
Como hemos indicado, JSF puede tener varios manejadores de eventos en una sola página
mientras que Struts sólo es capaz de procesar un evento por petición. Además, con Struts el
ActionForm debe extender clases creando así otra capa de código engorroso y con
posibilidad de diseñarse mal, forzando de esta forma a la capa de modelo a ser un
ActionForm. Sin embargo, en JSF esta capa es totalmente independiente.
6
Introducción 1
1.2.3. Navegación
Respecto a la navegación, tanto Struts como JSF se basan en un modelo declarativo,
definiéndola mediante el uso de reglas en ficheros de configuración XML (struts-config.xml,
faces-config.xml). Ambos soportan tanto la navegación estática (cuando de una página se
navega directamente a la siguiente), como la dinámica (cuando es una acción o lógica la que
determina a qué página se navega).
Struts utiliza el concepto de forwards para definir la navegación. Basándose en cadenas el
framework de Struts decide qué página es la siguiente y la traduce. De esta forma, para
definirla, se puede utilizar un Action tal y como mostramos a continuación:
<action path="/myForward" forward="/target.jsp"> </action>
Struts soporta la navegación dinámica mediante la definición de especificaciones en la
definición de un Action, permitiendo tener múltiples forwards en un mismo Action:
<action-mappings>
<action name="myForm" path="/myACtion" scope="request"
type="strutsnav.actions.MyAction">
<forward name="success" path="./target.jsp">
</forward>
<forward name="error" path="./error.jsp">
</forward>
</action>
</action-mappings>
Siendo posible programar qué forward devolver:
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
ActionErrors errors = new ActionErrors();
7
Introducción 1
ActionForward forward = new ActionForward(); // return value
MyForm myForm = (MyForm) form;
try {
// …
} catch (Exception e) {
// Error
errors.add("name", new ActionError("id"));
forward = mapping.findForward("success");
return (forward);
}
forward = mapping.findForward("success");
return (forward);
}
Sin embargo, en JSF la navegación estática se soporta gracias a la definición de reglas de
navegación en el fichero de configuración de las faces(faces-config.xml). En el siguiente
ejemplo, mostramos en una regla de navegación cómo navegar de una página a la siguiente:
<navigation-rule>
<from-view-id>/FromPage.jsp</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/ToPage.jsp</to-view-id>
</navigation-case>
</navigation-rule>
A diferencia de Struts, la navegación en JSF se aplica a nivel de página y puede ser
independiente de la acción. Ésta hay que especificarla implícitamente en el componente,
permitiendo de esta forma un control de grano más fino en la página. Es posible, además,
tener varios componentes en una página definiendo distintas acciones y compartiendo las
mismas reglas de navegación tal y como podemos observar en el siguiente ejemplo:
<af:commandButton type="submit" value="Submit"
styleClass="commandExButton" id="button1" action="success" />
8
Introducción 1
Con respecto a la navegación dinámica, JSF la soporta permitiendo a los componentes
comportarse como un manejador de acciones:
<af:commandButton type="submit" value="Submit"
styleClass="commandExButton" id="button1" action="#
{pc_FromPage.doButton1Action}" />
Asimismo, es posible codificar manejadores de acciones en cualquier clase implementando
así la navegación dinámica:
public String doButton1Action() {
return "success";
}
Aunque para soportar la navegación dinámica las reglas de navegación no necesitan
especificar la acción, JSF nos permite definir la acción en la regla de navegación. De esta
forma, estamos obligando a una regla de navegación específica a realizar una acción:
<navigation-rule>
<from-view-id>/FromPage.jsp</from-view-id>
<navigation-case>
<from-action>#{pc_FromPage.doButton1Action}</from-action>
<from-outcome>success</from-outcome>
<to-view-id>/ToPage.jsp</to-view-id>
</navigation-case>
</navigation-rule>
1.2.4. Conclusiones
Como hemos podido observar, aunque tanto Struts como JSF son suficientemente flexibles
desde el punto de vista de la navegación, JSF permite una mayor flexibilidad y un mejor
diseño de las reglas. Además, es mucho más sencillo en JSF tener una página con varias
reglas de navegación sin necesidad de codificar un montón de lógica del tipo if-else. Por
todo ello, es posible preveer que JSF superará a Struts debido a la flexibilidad de su
controlador y a la navegación.
Como hemos podido ver, en general, JSF es mucho más flexible que Struts (que no deja de
ser un framework robusto que funciona bien). Volviendo al principio de este punto, en el que
9
Introducción 1
indicábamos que a priori por ser más maduro parecía más rentable el uso de Struts,
debemos decir que cuando se piensa en abordar un nuevo proyecto hay que considerar
muchos factores. Así, por ejemplo, si estamos limitados por un calendario ajustado y sin
tiempo para evaluar diferentes proveedores que nos den soporte de implementaciones de
JSF, lo más conservador es decantarse por el uso de Struts.
Sin embargo, para seguir una dirección estratégica y un modelo de programación, la opción
seleccionada para el desarrollo de nuevas aplicaciones debería ser JSF. Es por todo esto que
merece la pena que los desarrolladores inviertan tiempo en aprender JSF y se utilice. JSF es
más sencillo que Struts cuando se desarrolla manualmente, incrementándose de manera
notable la productividad al utilizar un IDE de Desarrollo de Aplicaciones como Jdeveloper.
1.3. IMPLEMENTACIÓN DE JSF: ADF FACES
Oracle ha realizado la implementación de JSF a partir de directrices como el diseño de
patrones e infraestructuras de aplicaciones en un framework al que ha denominado ADF
(Application Development Framework). Una de las ventajas de ADF es que es una
plataforma independiente que corre en cualquier servidor J2EE, proporcionando opciones
para cada capa y desarrollando todas las fases del ciclo de vida sin obligarnos a usarlas
todas.
Por otra parte, ADF Faces es la implementación que Oracle hace de JSF y se basa en el
patrón MVC. Nos centraremos en presentar la capa de la Vista que proporciona la interfaz de
usuario de la aplicación. Comprobaremos que la ventaja principal de ADF Faces es la gran
cantidad de componentes que proporciona. La idea es no tener que escribir la funcionalidad
de las Interfaces de Usuario (UI) cada vez que las necesitamos. Así, bastaría con usar el
componente adecuado, evitando de esta forma el desorden en el código de los lenguajes de
marcadores y abstrayéndonos del http.
Escribir componentes JSF quizás no sea una tarea sencilla, pero usarlos es tan simple como
una llamada a una etiqueta. Ésta es precisamente la fortaleza de ADF Faces. Imaginemos
que existe una comunidad de personas que contribuyen a crear componentes y añadirles
cualquier funcionalidad que sea posible. De esta forma, no tendríamos que escribir más
código UI, simplemente usaríamos componentes ADF Faces.
Los componentes ADF Faces tienen una arquitectura interesante que está basada en una
clara división de responsabilidades. De esta forma, el componente define su propio
comportamiento o funcionalidad y el pintado que describe la presentación.
10
Introducción 1
Por ejemplo, podemos tener un componente que define cómo un usuario selecciona una
única opción; y en el pintado, definir cómo se hace por un botón de tipo radio o una lista
desplegable.
Asimismo, es posible agrupar distintas formas de pintado en un kit de pintado, lo que nos
permite disponer de un kit para HTML y otro para WML (teléfonos móviles). De esta forma, la
lógica del componente queda separada e independiente del dispositivo en el que se muestra.
ADF Faces incluye más de 100 componentes que nos proporcionan un gran potencial. Hay
componentes del tipo selectores de color, listas de valores y calendarios que pueden
utilizarse de formas distintas. También proporciona componentes más complejos como tablas
que permiten la ordenación por columnas y la capacidad de mostrarlas u ocultarlas, o
componentes de tipo árbol que pueden mostrar datos de un modo jerárquico.
Por otro lado, no todos los componentes que proporciona ADF son gráficos, dispone de otros
más orientados a realizar interacciones con el usuario, como el componente que permite la
subida de ficheros. También hay otro componente diseñado para establecer diálogos con
usuarios y tener la capacidad de devolver el foco al punto donde se inició el diálogo (algo no
siempre sencillo de realizar).
En la actualidad, todos estos componentes usan HTML y WML como lenguajes de
marcadores, por lo que pueden usarse indistintamente en navegadores comunes, teléfonos
móviles o PDA. Oracle está modernizando el pintado de estos componentes añadiendo una
combinación de DHTML y JavaScript que proporcionarán cada vez más experiencia en
clientes ricos e incluyendo el pintado parcial de páginas. Este nuevo kit de pintado será más
potente que cualquier implementación Swing.
Además, y dado que un gran número de fábricas y almacenes utilizan dispositivos telnet,
ADF proporciona un kit de pintado para este tipo de dispositivos.
Como hemos podido ver, ADF Faces nos proporciona un interesante y completo conjunto de
componentes para comenzar a desarrollar aplicando JSF.
Además de esta implementación, existe una versión open source a partir de código
proporcionado por Oracle a Apache. El nombre inicial de este proyecto era ADF Faces,
aunque ha pasado a denominarse Trinidad (según ha determinado la comunidad de Apache
MyFaces).
11
Introducción 1
El desarrollo de ADF Faces comenzó en 2001 y tuvo lugar fuera de la Apache Software
Foundation.
Los componentes actuales de Trinidad tienen licencia ASF y pueden usarse públicamente.
1.4. ENTORNO DE DESARROLLO DEL CURSO
El objetivo establecido en el presente curso es iniciar al desarrollo de Aplicaciones Web con
tecnología JSF. Para cumplir con este objetivo, debemos acercarnos lo máximo posible a lo
que sería el desarrollo de un proyecto real, teniendo, por tanto, una base de datos donde
almacenar la información y una capa de Modelo para implementar la persistencia y definir la
lógica de negocio.
Por ello, antes de iniciar el curso necesitaremos instalar una base de datos MySql 5.0. MySql
es una base de datos ligera y muy extendida que podremos obtener página oficial de MySql e
instalar siguiendo un simple Wizard.
Como framework de desarrollo de aplicaciones nos hemos decantado por JDeveloper
10.1.3 que incorpora la implementación ADF Faces de JSF y que podremos descargar de la
página oficial de Oracle (http://www.oracle.com/tools/jdev_home.html).
12
Introducción 1
− JSF es un framework estándar Java para el desarrollo de aplicaciones Web
basado en el patrón MVC y constituido por una serie de Componentes de
Usuario (UI).
− JSF realiza su programación a través de componentes y está basado en
eventos.
− JSF es totalmente independiente de la Capa del Modelo.
− JSF separa el pintado de los componentes del Controlador.
− En JSF la navegación se aplica a nivel de página por lo que puede ser
independiente de la acción.
recu
erde
_
13
Creación de una aplicación web con JSF 2
2.1. ANÁLISIS ...................................................................................15
2.1.1. Modelo físico de datos .....................................................15
2.2. CONSTRUCCIÓN .........................................................................16 2.2.1. JDeveloper ......................................................................16
2.2.1.1. Incluir la librería de conexión con MySql
en JDeveloper.....................................................16
2.2.1.2. Creación de la conexión con la base de datos
Test de Mysql .....................................................19
2.2.1.3. Creación del Data Source Test para el servidor
de aplicaciones embebido de Jdeveloper.............23
2.2.1.4. Creación de las tablas del esquema en la base
de datos Test......................................................24
2.2.1.5. Creación una aplicación JSF en JDeveloper .........29
2.2.1.6. Propiedades de los proyectos .............................31
2.2.2. Preparación del Modelo ...................................................34
2.2.2.1. Creación de los Objetos de Dominio ....................34
2.2.2.2. Creación del EJB de Sesión .................................39
2.2.2.3. Creación del Data Control ...................................43
índi
ce_
15
Creación de una aplicación web con JSF 2
2.1. ANÁLISIS
En este apartado vamos a presentar un análisis de la aplicación web que desarrollaremos
durante el curso.
El problema que vamos a resolver es la gestión de una agenda de contactos, la cual tiene
que cumplir los siguientes objetivos:
− Gestión de la información de los contactos.
− Clasificación de los contactos por tipo.
− Gestión de la información relacionada con los domicilios de los contactos.
− Gestión de las relaciones entre los distintos contactos almacenados en la agenda.
Para satisfacer los objetivos establecidos anteriormente será necesario implementar las
siguientes acciones:
− Listado de los contactos de la agenda.
− Formulario de alta de un contacto.
− Formulario de edición de los datos de un contacto.
− Operación de borrado de un contacto.
− Listado de los domicilios de un contacto.
− Operación para relacionar los contactos de la agenda.
− Árbol para mostrar las relaciones entre los contactos.
2.1.1. Modelo físico de datos
El Modelo de datos físico para almacenar la información que gestiona la agenda de contactos
es el siguiente:
16
Creación de una aplicación web con JSF 2
El esquema está compuesto por tres tablas que se especifican a continuación:
− Contacto: esta tabla almacena la información de los contactos y está compuesta por
el nombre, los apellidos, el teléfono, el tipo de contacto y si está relacionado con otro
contacto de la agenda (“idcontactorelacionado”).
− Tipocontacto: contiene la información de los tipos de contactos que establece la
agenda. Las descripciones que tiene almacenadas son: 'Amigos', 'Familia' y 'Trabajo'.
− Domicilio: en esta tabla se almacena la información de los domicilios de los
contactos. Se guardará la dirección, la provincia, el municipio, código postal y el
identificador del contacto al que pertenece el domicilio.
2.2. CONSTRUCCIÓN
Vamos a comenzar con la construcción del sistema que hemos descrito en el apartado
anterior. Para ello, tendremos que realizar una serie de pasos previos para preparar el
entorno de desarrollo.
2.2.1. JDeveloper
Durante el curso utilizaremos el IDE de desarrollo para aplicaciones J2EE de Oracle, que
como se ha descrito en la Introducción, es un framework para el desarrollo de aplicaciones
Java que aumenta notablemente el nivel de productividad y ofrece un elevado número de
componentes UI.
2.2.1.1. Incluir la librería de conexión con MySql en JDeveloper
Para poder conectarnos con una base de datos MySql necesitaremos dar de alta la librería de
conexión en el IDE de desarrollo. Estos son los pasos que debemos seguir:
1. Primero guardamos el archivo .jar con la librería que contiene el driver de conexión en
la carpeta de la instalación de JDeveloper “j22e\home\applib”. Todas las librerías
almacenadas en esta carpeta podrán ser utilizadas por cualquier aplicación que
desarrollemos con JDeveloper.
2. Iniciamos JDeveloper
17
Creación de una aplicación web con JSF 2
3. A continuación, damos de alta la librería en JDeveloper. Para ello, seleccionamos en el
menú Tools, Manage Libraries. Se abre la siguiente ventana:
4. Pulsamos el botón New, y en la ventana que se abre introducimos el nombre de la
librería “mysql-connector-java-3.1.7-bin”.
18
Creación de una aplicación web con JSF 2
5. Pulsamos Add Entry y en la ventana de explorador que se abre seleccionamos el
archivo jar de la librería.
19
Creación de una aplicación web con JSF 2
6. Para finalizar, pulsamos Aceptar para completar la operación.
2.2.1.2. Creación de la conexión con la base de datos Test de Mysql
Vamos a dar de alta una conexión con la base de datos Test de Mysql que será la que
utilicemos para crear nuestro esquema de tablas para la Aplicación Web de Agenda.
1. Pulsamos sobre la pestaña Connections, marcamos Database, y pulsamos sobre el
botón derecho del ratón, en el menú que aparece seleccionamos New Database
Connection.
20
Creación de una aplicación web con JSF 2
2. Pulsamos Siguiente, indicamos el nombre de la conexión “Test” y seleccionamos
como tipo de conexión Controlador JDBC de Terceros.
3. Pulsamos Siguiente e introducimos el nombre del usuario y la contraseña de la base
de datos MySql. El usuario por defecto usado es “root” y la contraseña la que
hayamos establecido en la instalación de MySql.
21
Creación de una aplicación web con JSF 2
4. Pulsamos Siguiente. A continuación pulsamos New, e introducimos la clase del driver
“com.mysql.jdbc.Driver”.
5. Pulsamos Browse y seleccionamos la librería de usuario mysql-connector-java-
3.1.7-bin.
6. Una vez seleccionados la clase del driver de conexión y la librería indicamos la cadena
de conexión “jdbc:mysql://localhost:3306/test”.
22
Creación de una aplicación web con JSF 2
7. Para finalizar, podemos realizar un test a la conexión que acabamos de dar de alta
pulsando Siguiente, Test Connection. Si la prueba de conexión es satisfactoria,
pulsamos Terminar para almacenar los datos de la conexión.
23
Creación de una aplicación web con JSF 2
2.2.1.3. Creación del Data Source Test para el servidor de aplicaciones embebido de
Jdeveloper
Vamos a definir el DataSource o la fuente de datos a partir de la conexión de la base de
datos Test que hemos dado de alta en el apartado anterior.
1. Seleccionamos en el menú Tools, Embedded OC4J Server Preferences.
2. Seleccionamos en el menú de árbol Data Sources y pulsamos sobre el botón Refresh
Now.
24
Creación de una aplicación web con JSF 2
3. Con esta operación hemos creado el Data Source para la conexión de Base de Datos
Test. El nombre que se utiliza para referirse al Data Source es el especificado por el
campo JNDI Name. En este caso jdbc/TestDS.
2.2.1.4. Creación de las tablas del esquema en la base de datos Test
En este apartado vamos a crear las tablas en el esquema Test de la Base de Datos MySql. El
script de creación de las tablas es el siguiente:
CREATE TABLE `test`.`tipocontacto` (
`idtipocontacto` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`tipocontacto` VARCHAR(45) NOT NULL,
PRIMARY KEY (`idtipocontacto`)
)
ENGINE = InnoDB;
CREATE TABLE `test`.`contacto` (
`idcontacto` INT NOT NULL AUTO_INCREMENT,
`nombre` VARCHAR(45) NOT NULL,
`apellido1` VARCHAR(45) NOT NULL,
`apellido2` VARCHAR(45) NOT NULL,
`telefono` VARCHAR(9) NOT NULL,
`idcontactorelacionado` INT NULL,
`idtipocontacto` INT NOT NULL,
PRIMARY KEY (`idcontacto`))
ENGINE = InnoDB;
CREATE TABLE `test`.`domicilio` (
`iddomicilio` INT NOT NULL AUTO_INCREMENT,
`direccion` VARCHAR(100) NOT NULL,
`provincia` VARCHAR(45) NOT NULL,
`municipio` VARCHAR(45) NOT NULL,
`codigopostal` VARCHAR(5) NOT NULL,
`idcontacto` INT NOT NULL,
PRIMARY KEY (`iddomicilio`))
ENGINE = InnoDB;
25
Creación de una aplicación web con JSF 2
Para crear las tablas realizamos los pasos siguientes:
1. Copiamos de este documento el código del script de creación de las tablas.
2. Seleccionamos en el menú Tools, SQL Worksheet. En el campo Connection
marcamos la conexión que hemos dado de alta “Test” y pulsamos aceptar.
3. Después de pulsar Aceptar, se abrirá una pestaña con el nombre de la conexión y un
área de texto Enter SQL Statement. Pegamos sobre esta área el código de creación
de las tablas del esquema y con el ratón seleccionamos el código de creación de la
primera tabla.
26
Creación de una aplicación web con JSF 2
4. Si pulsamos sobre el botón con forma triangular de color verde se ejecutará el código
seleccionado. Si todo es correcto obtendremos un mensaje de confirmación en el área
de resultados.
5. A continuación, seleccionamos el código de la siguiente tabla y pulsamos el botón de
ejecución. Así hasta completar el proceso para las tres tablas que conforman el
esquema.
Una vez hemos cargado el esquema completo de la aplicación, realizaremos una inserción de
datos para mostrar información inicial cuando comencemos el desarrollo.
El código con los datos iniciales es el siguiente:
insert into tipocontacto(idtipocontacto, tipocontacto) values(1, "Amigos");
insert into tipocontacto(idtipocontacto, tipocontacto) values(2, "Familia");
insert into tipocontacto(idtipocontacto, tipocontacto) values(3, "Trabajo");
insert into contacto(idcontacto, nombre, apellido1, apellido2, telefono,
idtipocontacto)
values(1, "Antonio", "Fernandez", "Díaz", "954545454", 1);
insert into contacto(idcontacto, nombre, apellido1, apellido2, telefono,
idtipocontacto, idcontactorelacionado)
values(2, "Mariana", "Cornejo", "Manovel", "954525252", 3, 1);
insert into contacto(idcontacto, nombre, apellido1, apellido2, telefono,
idtipocontacto, idcontactorelacionado)
values(3, "Maria", "Fernández", "Castizo", "954515151", 2, 1);
insert into contacto(idcontacto, nombre, apellido1, apellido2, telefono,
idtipocontacto)
values(4, "Patricia", "Roca", "Castizo", "954515151", 1);
27
Creación de una aplicación web con JSF 2
insert into contacto(idcontacto, nombre, apellido1, apellido2, telefono,
idtipocontacto, idcontactorelacionado)
values(5, "Antonio", "Fernández", "Reina", "957600000", 3, 4);
insert into contacto(idcontacto, nombre, apellido1, apellido2, telefono,
idtipocontacto, idcontactorelacionado)
values(6, "Javier", "Aguilar", "Garrido", "95644550", 3, 4);
insert into contacto(idcontacto, nombre, apellido1, apellido2, telefono,
idtipocontacto)
values(7, "Manuel", "Arteaga", "Alvarez", "95544550", 1);
insert into contacto(idcontacto, nombre, apellido1, apellido2, telefono,
idtipocontacto)
values(8, "Francisco", "Ruiz", "Castro", "95644550", 3);
insert into contacto(idcontacto, nombre, apellido1, apellido2, telefono,
idtipocontacto)
values(9, "Diego", "Ruiz", "Ruiz", "95244551", 2);
insert into contacto(idcontacto, nombre, apellido1, apellido2, telefono,
idtipocontacto, idcontactorelacionado)
values(10, "Maribel", "Leal", "Ruiz", "95848550", 1, 8);
insert into contacto(idcontacto, nombre, apellido1, apellido2, telefono,
idtipocontacto)
values(11, "Raquel", "Ruiz", "Mellado", "95144650", 1);
insert into contacto(idcontacto, nombre, apellido1, apellido2, telefono,
idtipocontacto)
values(12, "Miguel", "Carmona", "García", "95744650", 3);
insert into contacto(idcontacto, nombre, apellido1, apellido2, telefono,
idtipocontacto, idcontactorelacionado)
values(13, "Ana María", "Delgado", "Sierra", "95744650", 2, 5);
insert into contacto(idcontacto, nombre, apellido1, apellido2, telefono,
idtipocontacto)
values(14, "Rosalía", "Millán", "Alpresa", "95744650", 2);
insert into domicilio(iddomicilio, direccion, provincia, municipio, codigopostal,
idcontacto)
values(1,"C\ Manuel del Valle nº1", "Sevilla", "Sevilla","41008",1);
insert into domicilio(iddomicilio, direccion, provincia, municipio, codigopostal,
idcontacto)
values(2,"C\ Jose Luís de Caso nº1", "Sevilla", "Sevilla","41005",1);
insert into domicilio(iddomicilio, direccion, provincia, municipio, codigopostal,
idcontacto)
28
Creación de una aplicación web con JSF 2
values(3,"C\ José Luís de Caso nº2", "Sevilla", "Sevilla","41005",2);
insert into domicilio(iddomicilio, direccion, provincia, municipio, codigopostal,
idcontacto)
values(4,"C\ Jose Luís de Caso nº78", "Sevilla", "Sevilla","41005",3);
insert into domicilio(iddomicilio, direccion, provincia, municipio, codigopostal,
idcontacto)
values(5,"Avenida Resolana nº78", "Sevilla", "Sevilla","41004",4);
insert into domicilio(iddomicilio, direccion, provincia, municipio, codigopostal,
idcontacto)
values(6,"Avenida Carlos III sn", "Sevilla", "Sevilla","41004",5);
insert into domicilio(iddomicilio, direccion, provincia, municipio, codigopostal,
idcontacto)
values(7,"Avenida de los Descubrimientos sn", "Sevilla",
"Sevilla","41001",6);
insert into domicilio(iddomicilio, direccion, provincia, municipio, codigopostal,
idcontacto)
values(8,"C\ María Auxiliadora n4 Bloque 1 5ºB", "Sevilla",
"Sevilla","41002",7);
insert into domicilio(iddomicilio, direccion, provincia, municipio, codigopostal,
idcontacto)
values(9,"C\ República Argentina", "Córdoba", "Córdoba","14600",8);
insert into domicilio(iddomicilio, direccion, provincia, municipio, codigopostal,
idcontacto)
values(10,"C\Susana Benítez nº 23 portal B, 2ºA", "Córdoba",
"Córdoba","14700",9);
insert into domicilio(iddomicilio, direccion, provincia, municipio, codigopostal,
idcontacto)
values(11,"Avenida Álvaro Domecq nº1 ", "Jerez", "Cádiz","24700",10);
insert into domicilio(iddomicilio, direccion, provincia, municipio, codigopostal,
idcontacto)
values(12,"C\ Mercader sn", "Granada", "Granada","44700",11);
insert into domicilio(iddomicilio, direccion, provincia, municipio, codigopostal,
idcontacto)
values(13,"C\ Recaredo nº1 n", "Granada", "Granada","44700",12);
insert into domicilio(iddomicilio, direccion, provincia, municipio, codigopostal,
idcontacto)
values(14,"C\ Vela nº 2 2º A", "Granada", "Granada","44700",13);
29
Creación de una aplicación web con JSF 2
Este script lo ejecutaremos en la misma ventana donde realizamos la carga de las tablas
siguiendo el mismo procedimiento: seleccionamos el código a ejecutar y pulsamos el botón
verde con forma triangular.
2.2.1.5. Creación una aplicación JSF en JDeveloper
En este apartado vamos a crear una aplicación en JDeveloper donde trabajaremos para
realizar el desarrollo de la agenda.
1. Seleccionamos en el menú File, New y en la ventana emergente General,
Application.
2. Indicamos el nombre de la aplicación “Agenda”, el prefijo del paquete de la aplicación
“agenda” y seleccionamos como plantilla de aplicación Web Application [JSF, EJB].
insert into domicilio(iddomicilio, direccion, provincia, municipio, codigopostal,
idcontacto)
values(15,"C\ Larios nº4 3ºB", "Malaga", "Malaga","44700",14);
30
Creación de una aplicación web con JSF 2
3. Para finalizar, pulsamos Aceptar y tendremos creada la aplicación con dos proyectos,
uno para la parte del modelo de la aplicación Model y otro para la parte del
controlador y la vista ViewController.
31
Creación de una aplicación web con JSF 2
2.2.1.6. Propiedades de los proyectos
En las propiedades de los proyectos se define información relativa al mismo, como las
carpetas en las que se almacenan los fuentes y las clases, las librerías que incluye, etc. Para
acceder a las propiedades de los proyectos de la aplicación de Agenda:
1. Marcamos con el ratón por ejemplo el proyecto de Model, pulsamos el botón derecho
del ratón y seleccionamos Proyect Properties.
2. En la pestaña Proyect Content se definen: las capetas que contienen las fuentes
Java, el directorio con las clases, la lista de subcarpetas incluidas o excluidas y el
paquete por defecto. Para nuestra aplicación Agenda.
32
Creación de una aplicación web con JSF 2
3. La pestaña Compiler contiene las propiedades del compilador.
4. Si pulsamos sobre la pestaña J2EE Application podemos modificar el nombre por
defecto de la aplicación web y el contexto con el que se desplegará.
33
Creación de una aplicación web con JSF 2
5. La pestaña JSP Tag Libraries muestra las librerías de etiquetas que tenemos dadas
de alta en el proyecto. El proyecto Model no debe tener incluidas librerías de etiquetas
debido a que, es un proyecto para la capa de Modelo siguiendo el paradigma de
desarrollo J2EE. Para ver las librerías de etiquetas podemos acceder a las propiedades
del proyecto ViewController.
6. Como podemos observar, por defecto el proyecto de ViewController tiene dadas de
alta las librerías de JSF de la implementación de SUN. Para añadir las librerías de JSF
de la implementación de Oracle pulsamos el botón Add y seleccionamos ADF Faces
Components y ADF Faces HTML.
34
Creación de una aplicación web con JSF 2
7. Para ver las librerías que tenemos incluidas en el proyecto pulsamos sobre la opción
Libraries.
2.2.2. Preparación del Modelo
En este apartado vamos a preparar la capa de modelo. Como hemos mencionado antes, la
tecnología que se usará será CMP Entity Beans y EJB.
La mayoría de las aplicaciones J2EE requieren servicios transaccionales, los EJB Session
Bean ofrecen este servicio de lógica de negocio transaccional. Los EJB Session Bean trabajan
con objetos del dominio del negocio. Estos objetos de dominio se representas en el sistema
por los CMP (Container-Managed Persistence) Entity Beans.
2.2.2.1. Creación de los Objetos de Dominio
Vamos a crear los objetos de dominio a partir de las tablas de datos de la Base de Datos
Test:
1. Seleccionamos el proyecto Model, pulsamos el botón derecho del ratón y New.
35
Creación de una aplicación web con JSF 2
2. En el menú, elegimos Business Tier, EJB, CMP Entity Beans from Tables y
pulsamos Aceptar.
36
Creación de una aplicación web con JSF 2
3. Después de la ventana de bienvenida, seleccionamos la versión de los Enterprise
JavaBeans 3.0 (J2EE 5.0).
4. A continuación, seleccionamos el nombre de la conexión de la Base de Datos Test.
37
Creación de una aplicación web con JSF 2
5. Pulsamos Siguiente, marcamos Auto-Query y como tipos de objetos Tables.
Pasamos al área de Selected las tres tablas que conforman el esquema de la Agenda
(Contacto, Domicilio y TipoContacto).
6. Pulsamos Siguiente, indicamos el nombre del paquete donde se crearán los Entity
Beans. Seleccionamos como tipo de acceso PROPERTY, marcamos implementación
de la interfaz java.io.Serializable. Usaremos la clase java.util.List como tipo de
colección.
38
Creación de una aplicación web con JSF 2
7. La siguiente pantalla nos muestra el nombre de los beans para cada una de las tablas
del esquema. En esta pantalla podemos cambiar los nombres de los Entity Beans que
se van a generar.
8. La pantalla final muestra un resumen. Pulsamos Terminar para generar las clases
Java de las entidades.
39
Creación de una aplicación web con JSF 2
Como resultado de este proceso hemos creado las clases Java de los Entity Beans. Pulsamos
en el menú File, Save All para guardar todo el trabajo.
Si desplegamos el proyecto de model, abrimos la carpeta de Application Sources y
expandimos el paquete agenda.model podemos ver los nuevos Entity Beans.
Si seleccionamos y hacemos doble click con el ratón sobre la clase Contacto podemos ver
que tenemos un atributo por cada campo de la tabla contacto.
2.2.2.2. Creación del EJB de Sesión
A continuación, vamos a crear el EJB de Sesión para encapsular la lógica de negocio de la
aplicación. La capa de Modelo, como mencionábamos, está compuesta por CMP Entity
Beans como tecnología de persistencia y EJB para la implementar la lógica de negocio.
1. Marcamos con el ratón el proyecto Model y pulsamos botón derecho New como
hicimos anteriormente.
40
Creación de una aplicación web con JSF 2
2. En el menú en forma de árbol seleccionamos Business Tier, EJB, Session Bean.
3. En el primer paso, indicamos el nombre del EJB de sesión “AgendaSessionEJB”, tipo
de sesión Stateless y tipo de transacción Container. Marcamos Generate Session
Facade Methods e implementación de las entidades EJB 3.0 Entities.
41
Creación de una aplicación web con JSF 2
4. El siguiente paso muestra los métodos que se generan automáticamente para las
entidades que tenemos en el proyecto de model (Contacto, Domicilio y
Tipocontacto) además de los métodos de fachada. Marcamos todos para crearlos en
el Data Control.
5. En el siguiente paso indicamos el nombre de la clase del EJB de sesión
agenda.model.AgendaSessionEJBBean y la carpeta del proyecto donde se creará.
42
Creación de una aplicación web con JSF 2
6. Por último, indicamos el nombre de las interfaces Local que implementará el EJB. Para
desarrollar con JSF sólo necesitaremos implementar la interfaz Local.
7. Para concluir el proceso, pulsamos Finalizar y en el menú File, Save para guardar los
cambios. En el paquete agenda.model tenemos la clase Java con el EJB de sesión.
43
Creación de una aplicación web con JSF 2
2.2.2.4. Creación del Data Control
En este apartado vamos a crear el Data Control a partir del EJB de Sesión que encapsula la
lógica de negocio de la aplicación. El Data Control es una interfaz para blindar el modelo con
la capa cliente de la aplicación J2EE en este caso las páginas Web JSF.
Para crear el Data Control:
− Marcamos con el ratón el EJB AgendaSessionEJBBean, pulsamos el botón derecho y
Create Data Control.
Como resultado de esta operación tendremos:
• Un fichero Xml para cada CMP Entity Bean donde se describen los atributos, los
parámetros y los métodos de acceso.
• Un fichero UpdateableSingleValue.xml donde se describen las operaciones de
control sobre objetos con valores simples.
• Un fichero UpdateableCollection.xml donde se especifican las operaciones de
control sobre los objetos con valores múltiples.
• El fichero DataControls.dcx que define la interfaz del Data Control.
44
Creación de una aplicación web con JSF 2
− Es necesario incluir en Jdeveloper la librería del driver de conexión a la base
de datos MySql (“mysql-connector-java-3.1.7-bin.jar”).
− Tendremos que dar de alta la conexión con la Base de Datos Test en la
paleta de conexiones.
− Además, deberemos crear el DataSource jdbc/TestDS.
− El tipo de aplicación que crearemos será Web Application [JSF, EJB].
− Para la Capa de Modelo, los objetos de dominio del sistema de la agenda se
representarán por medio de CMP (Container-Managed Persistence)
Entity Beans.
− Usamos un EJB de sesión 3.0 para implementar la lógica de negocio.
− El Data Control es una interfaz que se genera a partir del EJB de sesión y que
sirve para relacionar el modelo con los componentes UI. Esta interfaz hace
posible el pintado mediante “drag-and-drop” lo que hace muy productivo el
entorno de desarrollo.
recu
erde
_
45
Usando ADF Faces Tables 3
3.1. CAPA DE PRESENTACIÓN DE DATOS ADF FACES, JSF ..................47
3.2. PREPARACIÓN DE UNA PLANTILLA .............................................47
3.3. PÁGINA DE BÚSQUEDA DE CONTACTOS ......................................53
3.3.1. Navegación .....................................................................53
3.3.2. Aplicando la plantilla definida..........................................55
3.3.3. Definición de la consulta de búsqueda .............................56
3.3.4. Desarrollo del formulario de búsqueda ............................57
3.3.5. Tabla de resultados de la página de búsqueda .................61
3.3.6. Implementación de la lógica de negocio de la búsqueda ..64
3.3.7. Ejecución de la página de búsqueda.................................64
3.3.8. Tabla detalle de los Domicilios de los Contactos...............66
índi
ce_
47
Usando ADF Faces Tables 3
3.1. CAPA DE PRESENTACIÓN DE DATOS ADF FACES, JSF
En el capítulo anterior preparamos la Capa del Modelo para poder acceder a los datos y
establecer la lógica de negocio de la aplicación de la agenda.
En los sucesivos capítulos y apartados nos centraremos en la capa del controlador y la vista
que implementa JSF.
3.2. PREPARACIÓN DE UNA PLANTILLA
En la gran mayoría de los desarrollos Web, se hace uso de la definición de una plantilla para
conseguir un aspecto similar en todas las páginas de la aplicación. Nuestra primera página
JSF será una plantilla para definir un aspecto común para todas nuestras páginas.
Para crear la página JSF que nos servirá como plantilla vamos a seguir los siguientes pasos:
1. Marcamos con el ratón el proyecto ViewController, pulsamos botón derecho, New.
2. Seleccionamos en el menú de la ventana desplegada Web Tier, JSF, JSF JSP y
pulsamos Aceptar.
3. Pulsamos Siguiente en la ventana de bienvenida para la creación de páginas JSF JSP.
4. A continuación indicamos en nombre de la página “template”, marcamos la opción de
JSP Document (*.jspx) y pulsamos Siguiente.
48
Usando ADF Faces Tables 3
5. En el siguiente paso se especifica si queremos publicar de forma automática, métodos
de acceso a los componentes de nuestra página en una clase Java que se denomina
Backing. Por defecto el nombre de estas clases será “backing_” seguido del nombre
de la página JSF. A esta clase, Java la dará de alta en el controlador como un
Managed Bean.
Para la plantilla seleccionamos la opción de Do Not Automatically Expose UI
Component s in a Managed Bean y pulsamos Siguiente.
6. A continuación debemos elegir qué librería de etiquetas añadimos a la página. Por
defecto aparecen seleccionadas siempre las del núcleo JSF de SUN. Nosotros
añadiremos ADF Faces Components 10_1_3_0_4 y ADF Faces HTML
10_1_3_0_4.
49
Usando ADF Faces Tables 3
7. En el paso siguiente vamos a indicar el título de la página y a definir aspectos visuales
tales como incluir las hojas de estilo. Pulsamos Terminar.
Finalizado el wizard, tendremos la página “template.jspx” dentro de la carpeta Web
Content del proyecto ViewController.
Vamos a añadir componentes a nuestra página que servirá de plantilla, para ello debemos
acceder a la paleta de Componentes situada en la esquina superior derecha de JDeveloper.
Si no está visible pulsamos en el menú View, Component Palette.
50
Usando ADF Faces Tables 3
El combo de selección superior nos permite elegir de qué librería de etiquetas queremos usar
un componente. Seleccionamos la librería de etiquetas “ADF Faces Core” y arrastramos el
componente Panel Page a la página de plantilla. El resultado es el siguiente:
Si queremos ver el código fuente basta con que pulsemos en la pestaña Source situada en
la parte inferior de la ventana.
Vamos a cambiar el título de la ventana para dejarlo vacío, para ello accedemos a la paleta
de propiedades. Si no está visible pulsamos View, Property Inspector.
51
Usando ADF Faces Tables 3
Hacemos clic con el ratón sobre el campo que contiene el valor de la propiedad Title y
borramos el contenido.
A continuación, vamos a crear un fichero de recursos en el proyecto para permitir el soporte
multilenguaje. Seleccionamos el proyecto ViewController con el ratón, pulsamos botón
derecho, seleccionamos New, General, File, Aceptar. En la ventana emergente
introducimos el nombre del fichero “UIResources.properties” y pulsamos de nuevo
Aceptar.
Vamos a añadir una propiedad al fichero de recursos para hacer uso de ella en la plantilla.
Abrimos el fichero “UIResources.properties” que hemos creado e introducimos:
Ahora vamos a declarar en la plantilla el fichero de recursos:
1. Abrimos la página de la plantilla.
2. Pulsamos en el menú View, Structure para ver la estructura de la página.
plantilla.marca=JSF
plantilla.marcaAplicacion= Agenda Contactos
plantilla.sobre=Curso JSF
52
Usando ADF Faces Tables 3
3. Accedemos a la Paleta de Componentes, desplegamos la lista de componentes de la
librería “JSF Core” y arrastramos a la etiqueta afh:head en la Paleta de Estructura el
componente LoadBundle.
4. En la ventana emergente pulsamos el botón que contiene tres puntos, elegimos la
opción de Properties File, marcamos el fichero “UIResources.properties” y
pulsamos Aceptar.
53
Usando ADF Faces Tables 3
Para terminar indicamos el nombre de la variable que usaremos para acceder al fichero de
recursos “res” y pulsamos aceptar.
Una vez registrado el acceso al fichero de recursos en nuestra plantilla, vamos a hacer uso
de las propiedades que definimos anteriormente.
En la Paleta de Estructura abrimos el componente af:PanelPage que ya habíamos
arrastrado, marcamos con el ratón branding, pulsamos botón derecho, Insert inside
branding, ADF Faces Core y seleccionamos el componente OutputText.
A continuación, en la Paleta de Propiedades cambiamos el valor de la propiedad Value por
#{res['plantilla.marca']}.
Repetimos el proceso anterior para los elementos brandingApp y appAbout. El valor de la
propiedad Value será #{res['plantilla.marcaAplicacion']} y #{res['plantilla.sobre']}
respectivamente.
3.3. PÁGINA DE BÚSQUEDA DE CONTACTOS
En este apartado vamos a desarrollar una página que mostrará el listado de los contactos de
la agenda. Esta página tendrá un buscador para poder filtrar el contenido de la lista de los
contactos.
3.3.1. Navegación
Vamos a comenzar dando de alta la nueva página:
1. Desplegamos el contenido de la carpeta Web Content, WEB-INF y abrimos el archivo
faces-config.xml. En este fichero se define todo el flujo de la navegación entre las
54
Usando ADF Faces Tables 3
páginas mediante la definición de reglas de navegación y se dan de alta los Backings
de las páginas como Managed Beans, tal y como mencionamos anteriormente.
2. En la Paleta de Componentes seleccionamos JSF Navigation Diagram y arrastramos
JSF Page al diagrama.
3. Cambiamos el nombre de la página por “buscadorContactos.jspx”.
4. A continuación, hacemos doble clic el diagrama de la página para iniciar el wizard de
creación.
5. Pulsamos siguiente hasta llegar al paso 2, donde marcamos Automatically Expose
UI Components in a New Managed Bean y pulsamos Siguiente. El nombre del
Managed Bean debe ser “backing_buscadorContactos”, la clase
“BuscadorContactos” y el paquete “agenda.view.backing”.
55
Usando ADF Faces Tables 3
6. Pulsamos Siguiente y debemos tener seleccionadas las librerías de etiquetas ADF
Faces Components 10_1_3_0_4, ADF Faces HTML 10_1_3_0_4, JSF Core 1.0 y
JSF HTML 1.0. Si todo es correcto pulsamos Terminar y se abrirá en modo diseño la
página buscadorContactos.jspx que acabamos de dar de alta.
3.3.2. Aplicando la plantilla definida
Para aplicar la plantilla a la página para buscar contactos que acabamos de dar de alta,
debemos seguir lo siguientes pasos:
1. Abrimos plantilla.jspx, accedemos a la Paleta de Estructura, seleccionamos adf:html y
pulsamos botón derecho Copiar.
2. Volvemos a la página buscadorContactos.jspx, nos situamos en la Paleta de Estructura
y eliminamos la etiqueta adf:html.
3. Pegamos la etiqueta adf:html que copiamos de la plantilla y guardamos los cambios.
4. Seleccionamos la etiqueta af:panelPage y accedemos a la Paleta de Propiedades para
establecer la propiedad Title a “Buscador Contactos”.
56
Usando ADF Faces Tables 3
Si todo el proceso ha concluido satisfactoriamente, pulsamos en Source para ver el código
fuente de la página del buscador. En la esquina superior derecha aparecerá un recuadro
verde.
3.3.3. Definición de la consulta de búsqueda
Vamos a definir una consulta para poder filtrar los contactos por nombre, primer apellido y
tipo de contacto. Para realizarlo, accedemos al proyecto Model y abrimos la Entity Bean de
los contactos (Contacto.java).
Podemos observar que por defecto tiene definida inicialmente una consulta para obtener
todos los contactos:
Nosotros vamos a añadir la nueva consulta parametrizada de la siguiente forma:
1. Importamos la clase NamedQueries del paquete javax.persistence añadiendo
“import javax.persistence.NamedQueries;”.
2. Eliminamos la consulta para obtener todos los contactos.
3. Añadimos el siguiente conjunto de consultas:
Hemos mantenido la anterior y añadido una nueva “findContactoByParameters”.
4. Recompilamos la clase para verificar que no hay ningún error de sintaxis.
5. A continuación, seleccionamos con el ratón la clase del EJB de Session
“AgendaSessionEJBBeanBean”, pulsamos botón derecho Edit Session Facade.
@NamedQuery(name="findAllContacto", query="select object(o) from Contacto o")
@NamedQueries({
@NamedQuery(name="findAllContacto", query="select object(o) from
Contacto o"),
@NamedQuery(name="findContactoByParameters", query="select object(o)
from Contacto o where o.nombre like :nombre and o.apellido1 like :apellido1 and
o.idtipocontacto like :idtipocontacto")})
57
Usando ADF Faces Tables 3
6. En la ventana emergente desplegamos la clase de la entidad Contacto y marcamos la
query que acabamos de añadir “findContactoByParameters”.
7. Como último paso volvemos a seleccionar el EJB de Session, pulsamos botón derecho,
Create Data Control. Con esta operación refrescamos el Data Control para que añada
la nueva consulta y poder utilizarla desde las páginas JSF.
De igual forma, cada vez que modifiquemos o incluyamos nuevos métodos en el EJB
deberemos generar el Data Control para que los cambios aplicados sean visibles
durante el desarrollo de las páginas Web.
3.3.4. Desarrollo del formulario de búsqueda
Volvemos al proyecto ViewController y a la página del buscador. Para desarrollar el
formulario seguiremos los siguientes pasos:
1. Accedemos a la Paleta de Componentes y arrastramos el componente PanelBox de la
librería de etiquetas ADF Faces Core a la etiqueta af:PanelPage que podremos ver
con claridad en la paleta de Estructura.
58
Usando ADF Faces Tables 3
2. En la Paleta de Propiedades editamos el valor de la propiedad Id y la establecemos a
“panelBoxBuscador”.
Esta propiedad hace referencia al identificador que tendrá el componente en la clase
Java del backing. Así, después de realizar este cambio tenemos un atributo en la clase
agenda.view.backing.BuscadorContactos de tipo CorePanelBox con el nombre
“panelBoxBuscador”.
Es importante renombrar los componentes que iremos añadiendo a las páginas para
poder localizarlos con mayor facilidad en el backing. Para no extender demasiado la
descripción del desarrollo vamos a asumir que estamos renombrando los componentes
con el siguiente formato: “nombre_componente + nombre_descriptivo”. Por
ejemplo “panelBoxBuscador”.
3. A continuación, arrastramos cuatro componentes de tipo PanelHorizontal sobre la
etiqueta af:PanelBox.
4. Modificamos la propiedad Haling de los tres primeros componentes de tipo panel
horizontal y la establecemos a “right”.
5. Abrimos el fichero de recurso que creamos para el proyecto
“UIResources.properties” y añadimos:
6. En la paleta Data Control desplegamos el método
findContactoByParameters(Object, Object, Object) y arrastramos el parámetro
nombre sobre la etiqueta af:PanelHorizontal. Se abrirá una pequeña ventana
emergente donde seleccionaremos Text, ADF InputText w/Label.
buscadorContactos.formulario.nombre= Nombre
buscadorContactos.formulario.apellido1=Primer Apellido
buscadorContactos.formulario.tipoContacto=Tipo de Contacto
buscadorContactos.tablaContactos.nombre=Nombre
buscadorContactos.tablaContactos.apellido1=Primer Apellido
buscadorContactos.tablaContactos.apellido2=Segundo Apellido
buscadorContactos.tablaContactos.telefono=Telefono
59
Usando ADF Faces Tables 3
7. Seguidamente, cambiamos la propiedad Label por la referencia al fichero de recursos.
Introduciremos: “#{res['buscadorContactos.formulario.nombre']}”.
8. A continuación, arrastramos desde la paleta de Data Control el parámetro apellido1
hasta el segundo panel horizontal como TextInput. De igual forma cambiamos el
valor de la propiedad Label por
“#{res['buscadorContactos.formulario.apellido1']}”.
9. Volvemos de nuevo a la paleta de Data Control para arrastrar el parámetro que hace
referencia al tipo de contacto. Cuando lo arrastremos sobre el tercer panel horizontal
los haremos como Single Selections, ADF Select One Choice.
10. Una vez arrastrado se abrirá una ventana emergente para editar el binding del
componente. El campo Base Data Source indica donde se recogerá el valor del
componente, en este caso en la variable del parámetro idtipocontacto. La fuente de
los datos de la lista se define en List Data Source. Pulsamos Add, marcamos la lista
TipoContacto resultante de la query findAllTipoContacto y pulsamos Aceptar.
60
Usando ADF Faces Tables 3
11. Indicamos la relación de los atributos que queremos establecer. En este caso el
parámetro idtipocontacto se relaciona con la propiedad idtipocontacto.
Para concluir, indicamos que el atributo tipocontacto es el que se muestra en el
combo de selección y el texto de la opción de no selección es “Todos”.
61
Usando ADF Faces Tables 3
12. En este punto, vamos a arrastrar un componente commandButton sobre el último
panel horizontal. Editamos el valor de la propiedad Text e introducimos el valor
“#{res['buscadorContactos.formulario.botonBuscar']}”.
Con este paso hemos terminado de desarrollar el formulario de búsqueda. En el apartado
siguiente introduciremos un componente de tipo tabla para mostrar el resultado de la
búsqueda.
3.3.5. Tabla de resultados de la página de búsqueda
Vamos a incluir nuestro primer componente de tipo tabla que nos servirá para mostrar el
resultado de la consulta que realicemos mediante el formulario de búsqueda.
El componente Table es uno de los más destacados de la implementación de ADF Faces de
JSF. Es un componente muy versátil y personalizable que permite mostrar información
organizada en filas y columnas.
Alguna de las características que presenta son:
1. Dispone de un componente de selección simple o múltiple por filas.
2. Realiza una paginación automática.
3. Incluye ordenación por columnas.
4. Establece bandeo por filas y columnas.
A lo largo del desarrollo de la tabla para presentar los resultados de la búsqueda, iremos
aplicando cada una de las características que acabamos de comentar.
Para crear la tabla de resultados seguiremos los siguientes pasos:
1. Abrimos la página buscadorContactos.jspx si no la tenemos abierta.
2. Accedemos a la paleta de Data Control y desplegamos el método
finContactoByParameters(Object, Object, Object). Marcamos con el ratón la lista
de objetos Contacto que aparece como resultado de este método y la arrastramos
sobre la etiqueta af:panelPage.
3. Se abrirá una ventana emergente y seleccionamos Tables, ADF Read-only Table.
62
Usando ADF Faces Tables 3
4. Una vez hemos seleccionado la opción de ADF Read-only Table, se abre una ventana
donde podremos elegir qué columnas mostramos en nuestra tabla, si incluimos
selección por filas y si queremos activar la opción de ordenación por columnas.
Eliminamos las columnas referentes a los atributos de identificador de contacto,
identificador de tipo contacto y identificador del contacto relacionado.
5. Ya tenemos el componente creado en la página. Accedemos a la paleta de Propiedades
y cambiamos la propiedad Id del componente por el valor “TableResultados”.
6. En la paleta de Estructura desplegamos el componente af:table, marcamos la tercera
columna que contiene la propiedad del nombre del contacto y la arrastramos para
colocarla como la primera columna de la tabla.
63
Usando ADF Faces Tables 3
7. Editamos el valor de la propiedad HeaderText de cada una de las columnas y le
asignamos la referencia correspondiente al fichero de recursos. Por ejemplo, el valor
de la propiedad HeaderText para la columna que muestra el nombre de los contactos
es “#{res[buscadorContactos.tablaContactos.nombre]}”.
8. Eliminamos el botón de Submit del componente table.
9. En la paleta de Estructura hacemos doble clic sobre la etiqueta af:table. En la ventana
emergente, pulsamos sobre la pestaña Formating, marcamos la opción de Include
Range Navigation y establecemos el valor del campo Rows a “5”. Con esto
paginaremos los resultados de cinco en cinco filas.
Marcamos Include Table Banding, seleccionamos Rows y establecemos el valor de
Banding Interval a “1”. Este parámetro indica que bandearemos los resultados por
filas y de uno en uno.
10. Para finalizar pulsamos Aceptar.
64
Usando ADF Faces Tables 3
3.3.6. Implementación de la lógica de negocio de la búsqueda
Ya tenemos pintado el formulario de búsqueda y la tabla para presentar los resultados. A
continuación, vamos a especificar la lógica de negocio de la consulta:
1. Abrimos la clase del EJB de sesión que tenemos en el proyecto Model y que hemos
denominado AgendaSessionEJBBeanBean.
2. Editamos el método public List<Contacto> findContactoByParameters(Object
nombre, Object apellido1, Object idtipocontacto) que es el encargado de realizar
la consulta y añadimos el siguiente código antes de la llamada a return.
Con este código estamos indicando que si no se especifica el valor de algunos de los
parámetros, debe buscar por todo. Además, se buscará dentro del contenido de
los campos de tipo texto como son nombre y apellidos, si se encuentra la cadena
introducida como parámetro. Por ejemplo, si introducimos en la condición de
búsqueda el valor “nt” como nombre, el resultado debe presentar todo los contactos
cuyo nombre contenga la cadena “nt”.
3.3.7. Ejecución de la página de búsqueda
Vamos a ver a continuación como ejecutar una página JSF y como establecer una página
como inicial a la hora de arrancar el Servidor de Aplicaciones OC4J embebido que incluye
JDeveloper.
Seguimos los siguientes pasos:
1. Marcamos el proyecto ViewController, botón derecho del ratón, y seleccionamos
Run.
2. Como es la primera vez que ejecutamos el proyecto, se abrirá una ventana emergente
donde se nos pregunta cual es el objetivo de la ejecución. Nosotros estableceremos
como objetivo nuestra página buscadorContactos.jspx. Pulsamos el botón de
// Preparación de los parámetros de búsqueda
nombre = nombre!=null?nombre!=""?"%"+nombre+"%":"%":"%";
apellido1 = apellido1!=null?apellido1!=""?"%"+apellido1+"%":"%":"%";
idtipocontacto = idtipocontacto!=null?idtipocontacto!=""?idtipocontacto:"%":"%";
65
Usando ADF Faces Tables 3
Browse, accedemos a la carpeta de ficheros public_html y seleccionamos nuestra
página de búsqueda. Una vez terminado pulsamos Aceptar.
Después de realizar estos pasos, el servidor comienza y iniciarse. Se abrirá una ventana de
Internet Explorer y nos mostrará la página solicitada. El resultado deber ser muy parecido al
siguiente:
66
Usando ADF Faces Tables 3
3.3.8. Tabla detalle de los Domicilios de los Contactos
Para finalizar la página del buscador, vamos a incluir una tabla más para mostrar los
domicilios de los contactos. Cada vez que seleccionemos un contacto, se recargará la tabla
de los domicilios del nuevo contacto seleccionado.
Vamos a seguir los siguientes pasos para presentar el detalle de los domicilios:
1. En el proyecto Model, desplegamos el paquete agenda.model y abrimos la clase
Domicilio.
2. A continuación, sustituimos la siguiente línea de código donde se especifica la consulta
de todos los domicilios (“@NamedQuery(name = "findAllDomicilio", query =
"select object(o) from Domicilio o")”) por el siguiente código:
Para poder compilar la clase de Domicilio debemos importa
javax.persistence.NamedQueries. Con este código hemos añadido una consulta
para buscar los domicilios de un contacto.
3. A continuación pulsamos botón derecho del ratón sobre la clase del EJB de sesión y
seleccionamos Edit Session Facade, desplegamos la entidad Domicilio y marcamos
el nuevo método de consulta que hemos creado.
@NamedQueries( { @NamedQuery(name = "findAllDomicilio", query = "select
object(o) from Domicilio o"), @NamedQuery(name ="findDomicilioByIdContacto",
query = "select object(o) from Domicilio o where o.idcontacto like :idcontacto")})
67
Usando ADF Faces Tables 3
4. Por último, generamos el DataControl del EJB de sesión para poder trabajar en el
proyecto de la vista con el nuevo método de consulta de domicilios. Para realizar
esta operación, pulsamos botón derecho del ratón sobre la clase del EJB y
seleccionamos Create Data Control.
5. Volvemos al proyecto ViewControler y abrimos la página
“buscadorContactos.jspx”
6. Accedemos a la paleta de DataControl y pulsamos botón derecho, Refresh. Después
de realizar esta operación debemos tener el nuevo método publicado.
7. Seleccionamos con el ratón a lista de tipo Domicilio que nos devuelve el método
findDomicilioByIdContacto(Object) y la arrastramos a la Paleta de Estructura
sobre la etiqueta ad:panelPage. Seleccionamos Tables, ADF Read-only Table.
8. Se abre una ventana emergente donde tenemos que indicar el origen del parámetro de
idcontacto del método. Pulsamos con el ratón sobre el campo Value, hasta que
68
Usando ADF Faces Tables 3
aparece un botón con tres puntos, lo pulsamos. Se volverá a abrir otra ventana
emergente y en el campo de Expression introduciremos lo siguiente:
Con esto estamos indicando que obtenga el valor del identificador de contacto del
iterador de la tabla de contactos. Pulsamos Aceptar y volvemos a pulsar Aceptar.
9. En la siguiente ventana eliminamos las columnas que muestran los atributos de
idcontacto, idcomicilio. Marcamos la opción de Enable sorting.
10. Accedemos a la paleta de Propiedades y cambiamos la propiedad Id asignándole el
nuevo valor “tableDomicilios”. Accedemos a la propiedad PartialTriggers, pulsamos el
botón con tres puntos. En la ventana emergente pulsamos New, marcamos con el
ratón sobre la nueva fila donde nos aparecerá una lista con los componentes de la
página. Seleccionamos tableResultados y pulsamos Aceptar. Con esto hemos
especificado que cada vez que se recargue la tabla de los contactos se recargará la
tabla con los domicilios.
11. Eliminamos el botón de Submit de la tabla de domicilios.
12. Accedemos a la etiqueta af:tableSelectOne de la tabla de resultados que muestra los
contactos y ponemos la propiedad AutoSubmit de este componente a true.
${bindings.findContactoByParametersIter.currentRow.dataProvider.idcontacto}
69
Usando ADF Faces Tables 3
Después de realizar estos pasos hemos finalizado el desarrollo de la tabla de detalle de los
domicilios de los contactos.
Si ejecutamos el proyecto ViewController este es el resultado:
Podemos observar que el título de las columnas de la tabla de los domicilios no tiene el texto
a partir de propiedades definidas en el fichero de recursos. Proponemos como ejercicio
definirlas en el fichero de recursos y utilizarlas en las propiedades HeaderText de cada
columna.
70
Usando ADF Faces Tables 3
− Se debe definir una plantilla para proporcionar un aspecto estándar a todas
las páginas de nuestras aplicaciones.
− La página de la plantilla no publica sus componentes en un Managed Bean.
− Las librerías de componentes JSF que utilizamos son ADF Faces
Components 10_1_3_0_4 y ADF Faces HTML 10_1_3_0_4 además de
las del núcleo de JSF de SUN.
− Las clases java donde se publican los métodos de acceso de a los
componentes de la página reciben el nombre de Backing. Los backing de las
páginas se publican en el fichero faces-config.xml del Controlador como
Managed Bean.
− Debemos renombrar la propiedad Id de los componentes que añadimos a
nuestras páginas con objeto de localizar los métodos de acceso publicados en
el Backing con mayor facilidad.
− El componente Table de ADF Faces es uno de los componentes más
destacados y permite introducir selección simple o múltiple por filas, realizar
paginación, ordenación por columnas y bandeo por filas y columnas.
− La propiedad AutoSubmit de un componente indica que si se modifica el
valor del componente, éste hace submit de forma automática.
− La propiedad partialTrigger provoca un refresco del propio componente en
función del identificador del componente a quien referencia. Es decir, si el
componente referenciado cambia, el componente que define el
partialTrigger refresca.
recu
erde
_
71
Usando ADF Faces Tree 4
4.1. FORMULARIOS DE ALTA Y EDICIÓN DE CONTACTOS ...................73
4.2. NAVEGACIÓN .............................................................................73
4.3. PÁGINA DE EDICIÓN DE CONTACTOS .........................................75
4.3.1. Nueva consulta para la entidad de contacto .....................77
4.3.2. Construcción del formulario.............................................78
4.3.3. Botón de Grabar para actualizar los datos del contacto ....82
4.3.4. Botón de Volver...............................................................83
4.3.5. Botón Editar en la página de búsqueda de contactos........83
4.3.6. Ejecución de la página para la edición de contactos .........85
4.4. PÁGINA DE ALTA DE CONTACTOS ...............................................86
4.4.1. Creamos la página nuevoContacto.jspx............................86
4.4.2. Aplicamos la plantilla a la página de nuevo contacto........86
4.4.3. Construcción del formulario.............................................87
4.4.4. Botón Grabar ...................................................................90
4.4.5. Botón Cancelar ................................................................91
4.4.6. Enlace en la página del buscador .....................................92
4.4.7. Ejecución de la página para el alta de contactos ..............92
4.5. BOTÓN PARA ELIMINAR CONTACTOS..........................................93
índi
ce_
73
Usando ADF Faces Tree 4
4.1. FORMULARIOS DE ALTA Y EDICIÓN DE CONTACTOS
En este tema vamos a realizar el desarrollo de los formularios para dar de alta contactos en
la agenda y poder editar los ya existentes.
4.2. NAVEGACIÓN
Vamos a comenzar dando de alta las páginas en el fichero del controlador:
1. En el proyecto ViewController, abrimos la carpeta WEB Content, WEB-INF y
abrimos el fichero faces-config.xml como hicimos en el tema anterior. Pulsamos la
pestaña de Diagram si no vemos el fichero en forma de diagrama. Como podemos
ver, tenemos ya la página buscadorContactos.jspx que es la página inicial de la
agenda.
2. Accedemos a la paleta de componentes, arrastramos JSF Page al diagrama y
cambiamos el nombre de la página por el de “edicionContacto.jspx”.
3. A continuación, vamos a establecer una regla de navegación desde la página de
búsqueda de contactos hasta la página que utilizaremos para editar los datos de un
contacto. En la paleta de componentes seleccionamos JSF Navigation Case,
pulsamos con el ratón sobre la página buscadorContactos.jspx y volvemos a pulsar
sobre la página edicionContacto.jspx.
Por defecto, el nombre de las reglas de navegación es success. Para cambiar el
nombre de la regla que acabamos de añadir, hacemos doble clic sobre success e
introducimos “editar”.
4. Volvemos a la paleta de componentes, seleccionamos JSF Page y arrastramos al
diagrama otra página. Esta página será la encargada de dar de alta nuevos contactos y
la nombraremos “nuevoContacto.jspx”.
5. Para navegar a la página de alta de contactos necesitaremos crear una nueva regla de
navegación desde buscadorContactos.jspx hasta nuevoContacto.jspx. Para hacer
esto arrastraremos JSF Navegation Case hasta la página del buscador y volvemos a
pulsar con el botón derecho del ratón cuando flecha esté encima de la página del
nuevo contacto. Renombraremos la regla de navegación con el nombre nuevo.
74
Usando ADF Faces Tree 4
En este punto el diagrama debe presentar un aspecto similar al siguiente:
Hasta ahora tenemos establecidas las reglas de navegación para ir desde la página del
buscador hasta las páginas de edición y alta. Para volver desde cada una de éstas al
buscador sería necesario establecer reglas de navegación en ambas páginas. En estos casos,
cuando se tiene una página que tiene que ser navegable desde otras páginas, lo más
indicado es establecer una regla de navegación global.
Para establecer una regla de navegación global a la página budcadorContactos.jspx
seguiremos los siguientes pasos.
1. Pulsamos en la pestaña OverView.
2. Seleccionamos Navigation Rules y pulsamos New en el recuadro de Navigation
Rules.
3. En la ventana emergente, en el campo From View ID introducimos “*” y pulsamos
Aceptar.
75
Usando ADF Faces Tree 4
4. En el recuadro de Navigation Cases pulsamos New. En la ventana emergente,
seleccionamos buscadorContactos.jspx en el campo To View ID, establecemos el
valor del campo From Outcome a “buscadorGlobal” y pulsamos Aceptar.
Finalizado el punto cuatro tendremos definida una regla de navegación global sobre la
página del buscador útil para todas las páginas de la agenda.
4.3. PÁGINA DE EDICIÓN DE CONTACTOS
Vamos a desarrollar el formulario de la página para la edición de los contactos de la agenda.
En primer lugar, tendremos que dar de alta la página y aplicar la plantilla que definimos en el
tema 3.
Para dar de alta la página en el proyecto seguiremos los siguientes pasos:
1. En el fichero del controlador faces-config.xml, pulsamos sobre la pestaña de
Diagram para volver a ver el diagrama.
2. Hacemos doble clic con el ratón sobre la página de ediciónContactos.jspx para
iniciar el wizard de creación de las paginas JSF.
3. En el paso 1 verificamos que la opción marcada es JSP Document (*.jspx).
76
Usando ADF Faces Tree 4
4. En el paso 4 publicamos automáticamente los componentes UI en un Managed Bean
marcando sobre Automatically Expose UI Components in a New Magnaged
Bean.
5. En el siguiente paso, si no están incluidas las librerías de ADF Faces las añadimos y
pulsamos Terminar.
Finalizado este punto, tenemos creada la página en el proyecto. Podemos observar que
ahora el diagrama del controlador no muestra un símbolo de advertencia en la página de
edición, al contrario que en la página de nuevo contacto. Esto indica que el componente JSP
Page que representa la página en el diagrama no tiene asociado ninguna página en el
proyecto.
Lo siguiente será aplicar la plantilla:
1. Abrimos la página de la plantilla y en la paleta de estructura copiamos la etiqueta
afh:html.
2. Abrimos la página edicionContacto.jspx si no está abierta y, en la paleta de
estructura eliminamos la etiqueta afh:html y pegamos sobre la etiqueta view.
3. Desplegamos la etiqueta afh:html hasta llegar a la etiqueta del componente
af:panelPage donde estableceremos el valor de la propiedad Title a “Edición
Contactos”.
77
Usando ADF Faces Tree 4
Ya tenemos lista la página de edición para empezar a añadir los componentes UI necesarios.
4.3.1. Nueva consulta para la entidad de contacto
Para implementar el formulario de edición necesitaremos crear una nueva consulta en la
entidad Contacto para poder localizar un contacto en la agenda por su identificador.
Para añadir el nuevo método de consulta por el identificador de contacto, seguiremos los
siguientes puntos:
1. En el proyecto Model, abrimos la clase agenda.model.Contacto.
2. Añadimos la nueva query dentro del bloque de código donde se declaran todas las
consultas. El código de la nueva consulta es:
3. Compilamos la clase para verificar que no contiene errores.
4. Seleccionamos la clase del EJB, pulsamos botón derecho, Edit Session Facade y en la
ventana emergente marcamos el método findContactoByIdContacto perteneciente
a la clase Contacto y pulsamos Aceptar.
5. Pulsamos de nuevo botón derecho sobre la clase del EJB y seleccionamos Create Data
Control.
@NamedQuery(name = "findContactoByIdContacto", query = "select object(o) from
Contacto o where o.idcontacto = :idcontacto")
78
Usando ADF Faces Tree 4
Una vez generado el Data Control tenemos disponible el método
findContactoByIdContacto para poder utilizarlo en las páginas JSF.
4.3.2. Construcción del formulario
En este punto vamos a realizar la construcción del formulario que nos permitirá modificar la
información de un contacto. Para crear el formulario realizaremos los siguientes pasos:
1. Accedemos a la paleta de Data Control.
2. Seleccionamos la lista de tipo Contacto que nos devuelve el método
findContactoByIdContacto(Object) y lo arrastramos hasta la paleta de estructura
sobre la etiqueta af:panelPage.
3. En el menú de la ventana emergente seleccionamos Forms, ADF Forms.
4. Una vez seleccionamos Forms, ADF Forms, se abre una ventana emergente donde
determinamos que campos van a componer el formulario. Nosotros eliminamos los
campos idcontacto, idcontactorelacionado e idtipocontacto.
5. En la siguiente ventana debemos introducir la fuente del parámetro con el que la
consulta nos devolverá el contacto que queremos editar. Hacemos doble clic sobre el
campo Valor y pulsamos el botón que tiene tres puntos. Seleccionamos ADF
Bindings, data, buscadorContactosPageDef, findContactoByParametersIter,
currentRow, dataProvider y hacemos doble clic. El área Expression, añadiremos
después de dataProvider “.idcontacto”. La expresión debe quedar de tal y como esta:
${data.buscadorContactosPageDef.findContactoByParametersIter.currentRow.dataProvide
r.idcontacto}
79
Usando ADF Faces Tree 4
6. Abrimos el fichero UIResource.properties y añadimos:
7. En este punto vamos a aplicar las propiedades que hemos añadido al fichero de
recursos a cada una de las propiedades Label de los componentes InputText que
contiene la etiqueta af:panelPage. Por ejemplo, seleccionamos la etiqueta
af:inputText del atributo nombre, hacemos doble clic y cambiamos el valor del
atributo Label por:
Debemos repetir el proceso para el resto de af:inputText.
buscadorContactos.tablaContactos.botonEditar=Editar
buscadorContactos.tablaContactos.botonNuevo=Nuevo
buscadorContactos.tablaContactos.botonEliminar=Eliminar
edicionContacto.formulario.nombre=Nombre
edicionContacto.formulario.apellido1=Primer Apellido
edicionContacto.formulario.apellido2=Segundo Apellido
edicionContacto.formulario.telefono=Teléfono
edicionContacto.formulario.tipoContacto=Tipo de Contacto
edicionContacto.formulario.botonGrabar=Grabar
edicionContacto.formulario.botonVolver=Volver
#{res['edicionContactos.formulario.nombre']}
80
Usando ADF Faces Tree 4
8. En la paleta de Data Control seleccionamos la lista de objetos de tipo Contacto que
devuelve el método findContactoByIdContacto(Object) y la desplegamos. Marcamos
idtipocontacto y lo arrastramos sobre la etiqueta af:panelForm en la paleta de
estructura.
9. En el menú de la ventana emergente seleccionamos Sigle Selections, ADF Select
One Choice.
10. En la siguiente ventana emergente, pulsamos Add para añadir un valor a la propiedad
List Data Source y seleccionamos la lista de tipo TipoContacto que devuelve el
método findAllTipocontacto();
81
Usando ADF Faces Tree 4
11. Pulsamos Aceptar y verificamos el que atributo idtipocontacto de la entidad que
vamos a actualizar está relacionado con el atributo idtipocontacto del valor de List
Data Source. En el valor del campo Display Attribute seleccionamos tipocontacto
y pulsamos Aceptar.
12. Hacemos doble clic sobre la etiqueta af:selectOneChoice del componente de
selección que acabamos de añadir y cambiamos el valor de la propiedad Label de la
pestaña de propiedades comunes por:
Hasta aquí hemos concluido el pintado del formulario. En el siguiente apartado añadiremos
los botones necesarios para poder grabar los cambios y volver a la página del buscador de
contactos.
#{res['edicionContacto.formulario.tipoContacto']}
82
Usando ADF Faces Tree 4
4.3.3. Botón de Grabar para actualizar los datos del contacto
En este apartado vamos a incluir el botón para grabar los cambios realizados en el
formulario. Los pasos a seguir, serán los siguientes:
1. Accedemos a la paleta de Data Control, seleccionamos el método
mergeEntity(Object) y lo arrastramos sobre la etiqueta af:panelForm en la paleta
de Estructura. Este método es un método general para actualizar los cambios en una
entidad.
2. En el menú de la ventana emergente seleccionamos Methods, ADF Command
Button.
3. Una vez hemos seleccionado el componente de botón se abre un nueva ventana
emergente donde se establece el valor del parámetro del método mergeEntity(Object).
Hacemos doble clic sobre el campo Value y pulsamos el botón con los tres puntos.
4. En la ventana emergente desplegamos el contenido de ADF Bindings , bindings,
findContactoByIdContactoIter, currentRow y hacemos doble clic sobre
dataProvider. Con esto hemos indicado que la entidad a guardar los cambios es la
fila actual del iterador del método de consulta findContactoByIdContacto.
83
Usando ADF Faces Tree 4
5. Pulsamos Aceptar, y de nuevo Aceptar en la ventana de Action Binding Editor.
6. Hacemos doble clic sobre la etiqueta af:commandButton que acabamos de crear y
cambiamos el valor de la propiedad Text por :
Finalizado el punto seis tenemos completado la definición del botón para grabar los cambios
de los contactos.
4.3.4. Botón de Volver
Vamos a incluir un botón para volver a la página del buscador de contactos. Para ello,
seguiremos los pasos que a continuación se describen.
1. Accedemos a la paleta de componentes, seleccionamos commandButton de la
librería de etiquetas ADF Faces Core y lo arrastramos sobre la etiqueta
af:panelForm en la paleta de estructura.
2. En la paleta de propiedades, cambiamos el valor de la propiedad Text por:
3. Establecemos el valor de la propiedad Action a “buscadorGlobal”.
4.3.5. Botón Editar en la página de búsqueda de contactos
En este apartado vamos a incluir el botón de editar en la tabla de resultados de la búsqueda
de contactos y vamos a definir una condición de refresco sobre esta tabla.
Para introducir el botón de editar en la tabla de resultados de la búsqueda haremos lo
siguiente:
1. Abrimos la página buscadorContactos.jspx si no está abierta.
2. En la paleta de estructura, buscamos la etiqueta af:tableSelectionOne del
componente con identificador tableResultados.
#{res['edicionContacto.formulario.botonGrabar']}
#{res['edicionContacto.formulario.botonVolver']}
84
Usando ADF Faces Tree 4
3. Una vez localizado, lo seleccionamos, pulsamos botón derecho, Insert inside
af:tableSelectionOne, CommandButton.
4. En la paleta de propiedades, cambiamos la propiedad Text del nuevo botón por:
5. Establecemos el valor de la propiedad Action a “editar”.
Lo siguiente que haremos será establecer la condición de refresco:
1. Sobre la vista de diseño de la página del buscador pulsamos botón derecho del ratón y
seleccionamos Go to Page Definition.
2. En la paleta de estructura seleccionamos con el ratón executables, pulsamos botón
derecho y elegimos Insert inside executables, invokeAction.
3. En la ventana emergente asignamos el campo Id el valor “refreshResults” y en el
campo Binds seleccionamos finContactoByParameters.
4. Pulsamos la pestaña de opciones avanzadas y en el campo RefreshCondition pegamos
el siguiente código:
Con esta condición estamos indicando que se ejecute la operación de refresco sobre la
consulta que genera los resultados cada vez que volvemos de otra página.
#{res['buscadorContactos.tablaContactos.botonEditar']}
${!adfFacesContext.postback}
85
Usando ADF Faces Tree 4
4.3.6. Ejecución de la página para la edición de contactos
Vamos a ejecutar el proyecto para ver que todo funciona como cabe de esperar.
Seleccionamos el proyecto ViewController, botón derecho del ratón, Run.
En la ventana del buscador, pulsamos el botón Editar y accedemos a la página para la
edición de contactos que debe parecerse a la que muestra la imagen siguiente:
Podemos realizar un cambio en cualquiera de los campos, pulsamos Grabar y al volver a la
página del buscador pulsando el botón Volver veremos la modificación aplicada.
86
Usando ADF Faces Tree 4
4.4. PÁGINA DE ALTA DE CONTACTOS
En este apartado vamos a detallar los pasos a seguir para construir la página de alta de los
contactos de la agenda.
4.4.1. Creamos la página nuevoContacto.jspx
Para crear la página de alta de contactos seguiremos los siguientes pasos:
1. Abrimos el fichero del controlador faces-config.xml, pulsamos sobre la pestaña de
Diagram para volver a ver el diagrama.
2. Hacemos doble clic con el ratón sobre la página de nuevoContactos.jspx para iniciar
el wizard de creación de las paginas JSF.
3. En el paso 1 del wizard verificamos que la opción marcada es JSP Document
(*.jspx).
4. En el paso 4 del wizard publicamos automáticamente los componentes UI en un
Managed Bean marcando sobre Automatically Expose UI Components in a New
Magnaged Bean.
5. En el siguiente paso, si no están incluidas las librerías de ADF Faces las añadimos y
pulsamos Terminar.
4.4.2. Aplicamos la plantilla a la página de nuevo contacto
Como hemos hecho para las anteriores páginas, aplicamos la plantilla:
1. Abrimos la página de la plantilla y en la paleta de estructura copiamos la etiqueta
afh:html.
2. Abrimos la página nuevoContacto.jspx si no está abierta y en la paleta de estructura
eliminamos la etiqueta afh:html y pegamos sobre la etiqueta view.
3. Desplegamos la etiqueta afh:html hasta llegar a la etiqueta del componente
af:panelPage donde estableceremos el valor de la propiedad Title a “Nuevo
Contacto”.
87
Usando ADF Faces Tree 4
4.4.3. Construcción del formulario
En este punto vamos a realizar la construcción del formulario que nos permitirá dar de alta
nuevos contactos. Seguiremos los puntos que a continuación se describen:
1. Accedemos a la paleta de Data Control.
2. Seleccionamos la lista de tipo Contacto que nos devuelve el método
findAllContacto() y lo arrastramos hasta la paleta de estructura sobre la etiqueta
af:panelPage.
3. En el menú de la ventana emergente seleccionamos Forms, ADF Creation Forms.
4. Una vez seleccionamos Forms, ADF Creation Forms, se abre una ventana
emergente donde determinamos que campos van a componer el formulario. Nosotros
eliminamos los campos idcontacto, idcontactorelacionado e idtipocontacto.
88
Usando ADF Faces Tree 4
1. Abrimos el fichero UIResources.properties y añadimos:
2. Aplicamos las propiedades que hemos añadido al fichero de recursos, a cada una de
las propiedades Label de los componentes InputText que contiene la etiqueta
af:panelPage. Por ejemplo, seleccionamos la etiqueta af:inputText del atributo
nombre, hacemos doble clic y cambiamos el valor del atributo Label por:
Debemos repetir el proceso para el resto de af:inputText.
3. En la paleta de Data Control seleccionamos la lista de objetos de tipo Contacto que
devuelve el método findAllContacto() y la desplegamos. Marcamos idtipocontacto
y lo arrastramos sobre la etiqueta af:panelForm en la paleta de estructura.
4. En el menú de la ventana emergente seleccionamos Sigle Selections, ADF Select
One Choice.
5. En la siguiente ventana emergente, pulsamos Add para añadir un valor a la propiedad
List Data Source y seleccionamos la lista de tipo TipoContacto que devuelve el
método findAllTipocontacto();
nuevoContacto.formulario.nombre=Nombre
nuevoContacto.formulario.apellido1=Primer Apellido
nuevoContacto.formulario.apellido2=Segundo Apellido
nuevoContacto.formulario.telefono=Teléfono
nuevoContacto.formulario.tipoContacto=Tipo de Contacto
nuevoContacto.formulario.botonGrabar=Grabar
nuevoContacto.formulario.botonCancelar=Cancelar
#{res['nuevoContacto.formulario.nombre']}
89
Usando ADF Faces Tree 4
6. Pulsamos Aceptar y verificamos el que atributo idtipocontacto de la entidad que
vamos a actualizar está relacionado con el atributo idtipocontacto del valor de List
Data Source. En el valor del campo Display Attribute seleccionamos tipocontacto
y pulsamos Aceptar.
90
Usando ADF Faces Tree 4
7. Hacemos doble clic sobre la etiqueta af:selectOneChoice del componente de selección
que acabamos de añadir y cambiamos el valor de la propiedad Label de la pestaña de
propiedades comunes por:
4.4.4. Botón Grabar
En este apartado vamos a incluir el botón para grabar los cambios realizados en el
formulario. Los pasos a seguir, serán los siguientes:
1. Accedemos a la paleta de Data Control, seleccionamos el método
persistEntity(Object) y lo arrastramos sobre la etiqueta af:panelForm en la paleta
de Estructura. Este método es general para crear una entidad.
2. En el menú de la ventana emergente seleccionamos Methods, ADF Command
Button.
3. Una vez hemos seleccionado el componente de botón, se abre un nueva ventana
emergente donde se establece el valor del parámetro del método
persistEntity(Object). Hacemos doble clic sobre el campo Value y pulsamos el
botón con los tres puntos.
4. En la ventana emergente desplegamos el contenido de ADF Bindings , bindings,
findAllContactoIter, currentRow y hacemos doble clic sobre dataProvider. Con
esto hemos indicado que la entidad a guardar los cambios es la fila actual del iterador
del método de consulta findAllContacto.
#{res['nuevoContacto.formulario.tipoContacto']}
91
Usando ADF Faces Tree 4
5. Pulsamos Aceptar, y de nuevo Aceptar en la ventana de Action Binding Editor.
6. Hacemos doble clic sobre la etiqueta af:commandButton que acabamos de crear y
cambiamos el valor de la propiedad Text por :
7. Le asignamos a la propiedad Action el valor “buscadorGlobal”.
4.4.5. Botón Cancelar
Para finalizar, sólo nos queda añadir un botón para cancelar la operación de alta de un nuevo
contacto.
1. Desde la paleta de componentes arrastramos commanButton sobre la etiqueta
af:panelForm en la paleta de estructura.
2. En la paleta de estructura hacemos doble clic sobre la etiqueta af:commandButton
del nuevo botón que hemos añadido y establecemos el valor de la propiedad Text a:
#{res['nuevoContacto.formulario.botonCancelar']}
#{res['nuevoContacto.formulario.botonGrabar']}
92
Usando ADF Faces Tree 4
3. En la paleta de propiedades establecemos el valor de la propiedad Action a
“buscadorGlobal”.
4.4.6. Enlace en la página del buscador
Para introducir el botón de nuevo en la tabla de resultados de la búsqueda haremos lo
siguiente:
1. Abrimos la página buscadorContactos.jspx si no está abierta.
2. En la paleta de estructura, buscamos la etiqueta af:tableSelectionOne del
componente con identificador tableResultados.
3. Una vez localizado, lo seleccionamos, pulsamos botón derecho, Insert inside
af:tableSelectionOne, CommandButton.
4. En la paleta de propiedades cambiamos la propiedad Text del nuevo botón por:
5. Establecemos el valor de la propiedad Action a “nuevo”.
4.4.7. Ejecución de la página para el alta de contactos
Vamos a ejecutar el proyecto para ver que todo funciona como cabe esperar. Seleccionamos
el proyecto ViewController, botón derecho del ratón, Run.
En la ventana del buscador, pulsamos el botón Nuevo y accedemos a la página para la
edición de contactos que debe parecerse a la que se muestra a continuación.
#{res['buscadorContactos.tablaContactos.botonNuevo']}
93
Usando ADF Faces Tree 4
Podemos probar a dar de alta un nuevo contacto y ver como se añade a la lista de los
contactos en la página del buscador.
4.5. BOTÓN PARA ELIMINAR CONTACTOS
Para finalizar este tema, vamos a incluir un botón para eliminar contactos de la agenda en la
página de búsqueda de contactos.
A continuación se detallan los pasos a seguir:
1. Abrimos la página buscadorContactos.jspx si no está abierta.
2. En la paleta Data Control arrastramos el método removeEntity(Object) sobre la
etiqueta af:tableSelectOne de la tabla de resultados.
3. Seleccionamos Methods, ADF Command Button.
94
Usando ADF Faces Tree 4
4. En la ventana emergente especificamos el valor del parámetro entidad que queremos
eliminar. Hacemos doble clic sobre el campo Value e introducimos la siguiente
cadena:
5. Pulsamos Aceptar.
6. En la paleta de propiedades establecemos el valor de la propiedad Label a:
7. Para terminar ponemos el valor de la propiedad Action a “buscadorGlobal”.
${bindings.findContactoByParametersIter.currentRow.dataProvider}
#{res['buscadorContactos.tablaContactos.botonEliminar']}
95
Usando ADF Faces Tree 4
− Las reglas de navegación (JSF Navigation Case) nos permiten definir el
flujo de navegación entras las páginas de la aplicación.
− Las reglas de navegación globales se definen sobre páginas que deben ser
accedidas desde muchas páginas del resto de la aplicación.
− Cada vez que añadimos una consulta en una entidad, como por ejemplo
agenda.model.contacto, debemos añadirla al EJB mediante Edit Session
Facade y crear de nuevo el Data Control.
− El componente que nos permite construir combos de selección que
utilizaremos en cualquier formulario es ADF Select One Choice.
− El método mergeEntity(Object) es el encargado de aplicar las
modificaciones que realizamos sobre un objeto y aplicarlos en la base de
datos.
− El método persistEntity(Object) es el encargado de dar de alta los objetos
que manejamos en la aplicación y crearlos en la base de datos.
recu
erde
_
97
Menús 5
5.1. MENÚS Y ÁRBOLES .....................................................................99
5.2. NAVEGACIÓN .............................................................................99
5.3. MENÚS .....................................................................................101
5.3.1. Añadir un menú a la página de búsqueda de contactos ..101
5.3.2. Añadir un menú a la página que presenta las relaciones
de los contactos ............................................................103
5.4. RELACIONES ENTRE LOS CONTACTOS.........................................103
5.4.1. Nuevo método en el EJB para relacionar Contactos ........104
5.4.2. Creamos la clase Nodo Contacto ....................................105
5.4.3. Clase backing de la página de relaciones de contactos ...108
5.4.4. RelacionesContactosPageDef.........................................112
5.3.4. Añadimos los componentes a la página..........................116
5.3.5. Ejecución de la página de relaciones..............................117
índi
ce_
99
Menús 5
5.1. MENÚS Y ÁRBOLES
En este tema vamos a crear diferentes menús para movernos por la agenda y veremos la
representación de la información de la relación de los contactos en forma de estructura de
árbol.
5.2. NAVEGACIÓN
Vamos a comenzar dando de alta una nueva página para la gestión de la relación entre los
contactos en el fichero del controlador:
1. En el proyecto ViewController, abrimos la carpeta WEB Content, WEB-INF y
abrimos el fichero faces-config.xml como hicimos en el tema anterior. Pulsamos la
pestaña de Diagram si no vemos el fichero en forma de diagrama.
2. Accedemos a la paleta de componentes, arrastramos JSF Page al diagrama y
cambiamos el nombre de la página por el de “relacionesContactos.jspx”.
3. A continuación, vamos a establecer una regla de navegación desde la página de
búsqueda de contactos hasta la página de relación de contactos. En la paleta de
componentes seleccionamos JSF Navigation Case, pulsamos con el ratón sobre la
página buscadorContactos.jspx y volvemos a pulsar sobre la página
relacionesContactos.jspx.
Por defecto, el nombre de las reglas de navegación es success. Para cambiar el
nombre de la regla que acabamos de añadir hacemos doble click sobre success e
introducimos “relaciones”.
4. Pulsamos la pestaña Overview, seleccionamos Managed Beans y marcamos el
beans backing_relacionesContactos.
5. En la caja de Managed Properties pulsamos el botón New, indicamos el nombre de
la propiedad “bindings”, la clase oracle.adf.model.BindingContainer y pulsamos
Aceptar.
6. Editamos la nueva propiedad y le asignamos el valor “#{bindings}”.
100
Menús 5
Con esto hemos hecho accesibles los elementos del bindings desde la clase backing de la
página de las relaciones entre los contactos.
Después de realizar todos los pasos anteriormente descritos, el diagrama debe quedar de
forma similar al que se muestra a continuación:
101
Menús 5
5.3. MENÚS
Vamos a aplicar menús a las páginas de buscador de contactos y relaciones de los contactos
para poder navegar de una a otra por medio de las opciones del menú.
5.3.1. Añadir un menú a la página de búsqueda de contactos
Para añadir el menú a la página seguiremos los siguientes pasos:
1. Abrimos el fichero de recursos UIResources.properties si no está abierto y
añadimos:
2. Abrimos la página buscadorContactos.jspx si no está abierta.
3. En la paleta de estructura, seleccionamos la etiqueta af:panelPage y desplegamos
PanelPage facets. Seleccionamos menu1, pulsamos el botón derecho del ratón,
Insert inside menu1, Menu Tabs.
4. Seleccionamos la etiqueta af:menuTabs del componente que acabamos de crear y
pulsamos botón derecho, Insert inside menu Tabs, CommandMenuItem.
navegacion.paginaBuscador=Buscador Contactos
navegacion.paginaRelaciones=Relaciones Contactos
relacionesContactos.botonRelacionar=Relacionar
102
Menús 5
5. En la paleta de propiedades establecemos la propiedad Text a
“#{res['navegacion.paginaBuscador']}”. La propiedad Action a
“buscadorGlobal” y Selected a “true”.
6. De nuevo seleccionamos la etiqueta af:menuTabs y añadimos otro componente de
tipo CommandMenuItem. Accedemos a la paleta de propiedades y establecemos
Text a “#{res['navegacion.paginaRelaciones']}”y Action a “relaciones”.
7. En la paleta de estructura, pulsamos el botón derecho sobre la etiqueta menu2 del
componente panelPage, insert inside menu2, MenuBar.
8. Repetimos los pasos 3, 4 y 5.
9. Pulsamos el botón derecho sobre la etiqueta menu3, insert inside menu3,
MenuList.
103
Menús 5
10. Repetimos los pasos 3, 4 y 5.
Finalizado el paso nueve, hemos añadido tres tipos de menú a nuestra página para buscar
contactos. Hemos introducido un menú lateral en el paso 8, un menú de pestañas en el paso
2 y una barra de menú en el paso 6.
5.3.2. Añadir un menú a la página que presenta las relaciones de los contactos
Para introducir los menús en la página de relaciones sólo tenemos que seguir los pasos
descritos en el punto 5.4.1 de este capítulo, con la salvedad de que la propiedad Selected a
true se establecerá esta vez en la página de las relaciones.
5.4. RELACIONES ENTRE LOS CONTACTOS
Vamos a desarrollar la página que muestra las relaciones que existen entre los distintos
contactos de la agenda. Añadiremos un pequeño formulario para modificar estas relaciones.
Los siguientes pasos nos muestran como dar de alta la página en el proyecto:
− En el fichero del controlador faces-config.xml, hacemos doble clic sobre la página de
ediciónContactos.jspx para iniciar el wizard de creación de las paginas JSF.
− En el paso 1 del wizard verificamos que la opción marcada es JSP Document
(*.jspx).
104
Menús 5
− En el paso 4 del wizard publicamos automáticamente los componentes UI en un
Managed Bean marcando sobre Automatically Expose UI Components in a New
Magnaged Bean.
− En el siguiente paso, si no están incluidas las librerías de ADF Faces las añadimos y
pulsamos Terminar.
A continuación aplicamos la plantilla:
1. Abrimos la página de la plantilla y en la paleta de estructura copiamos la etiqueta
afh:html.
2. Abrimos la página edicionContacto.jspx si no está abierta y en la paleta de
estructura eliminamos la etiqueta afh:html y la pegamos sobre la etiqueta view.
3. Desplegamos la etiqueta afh:html hasta llegar a la etiqueta del componente
af:panelPage donde estableceremos el valor de la propiedad Title a “Relaciones
Contactos”.
Ya tenemos lista la página de edición para empezar a añadir los componentes UI necesarios.
5.4.1. Nuevo método en el EJB para relacionar Contactos
Para implementar la operación de relacionar Contactos añadimos el siguiente método al EJB:
1. En el proyecto Model abrimos la clase AgendaSessionEJBBeanBean del paquete
agenda.model.
2. Pegamos el siguiente código:
public Object relacionarContactos(Object entity, Object entity2) {
Contacto contacto = (Contacto)
findContactoByIdContacto(entity.toString()).get(0);
contacto.setIdcontactorelacionado(entity2.toString());
Object obj = em.merge(contacto);
return obj;
}
105
Menús 5
3. En la paleta estructura seleccionamos el método public Object
relacionarContactos(Object entity, Object entity2) que hemos añadido,
pulsamos botón derecho, Properties. Marcamos la opción Expose through Local
interface y pulsamos Aceptar.
4. Seleccionamos la clase AgendaSessionEJBBeanBean del EJB, pulsamos el botón
derecho del ratón, Create Data Control.
5.4.2. Creamos la clase Nodo Contacto
Cada uno de los nodos del árbol representará un contacto de la agenda. Crearemos la clase
nodo en el proyecto ViewController siguiendo los pasos que se describen a continuación:
1. Seleccionamos en el proyecto ViewController el paquete agenda.view, pulsamos
el botón derecho, New, General, Java Class y pulsamos Aceptar.
106
Menús 5
2. Sobrescribimos el código:
}
public String getApellido2() {
return apellido2;
}
public void setIdcontacto(String idcontacto) {
this.idcontacto = idcontacto;
}
public String getIdcontacto() {
return idcontacto;
}
public void setIdcontactorelacionado(String idcontactorelacionado) {
this.idcontactorelacionado = idcontactorelacionado;
}
public String getIdcontactorelacionado() {
return idcontactorelacionado;
}
public void setIdtipocontacto(String idtipocontacto) {
this.idtipocontacto = idtipocontacto;
}
public String getIdtipocontacto() {
return idtipocontacto;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getNombre() {
return nombre;
}
107
Menús 5
public class NodoArbol {
public NodoArbol() {
}
}
por:
import java.util.ArrayList;
import java.util.Collection;
public class NodoArbol {
private String apellido1;
private String apellido2;
private String idcontacto;
private String idcontactorelacionado;
private String idtipocontacto;
private String nombre;
private String telefono;
private Collection hijos;
public NodoArbol() {
hijos = new ArrayList();
}
public void setApellido1(String apellido1) {
this.apellido1 = apellido1;
}
public String getApellido1() {
return apellido1;
}
public void setApellido2(String apellido2) {
this.apellido2 = apellido2;
public String getTelefono() {
return telefono;
}
108
Menús 5
public void setHijos(Collection hijos) {
this.hijos = hijos;
}
public Collection getHijos() {
return hijos;
}
}
3. Para finalizar compilamos la clase para verificar que la operación se ha realizado
correctamente.
5.4.3. Clase backing de la página de relaciones de contactos
En este apartado vamos a añadir un método en la clase backing de la página
relacionesContactos.jspx que será el encargado de construir un objeto de la clase
TreeModel donde se almacenan los nodos estructurados en forma de árbol.
Para implementar este método seguiremos los pasos que se describen a continuación:
1. Abrimos la clase RelacionesContactos del paquete agenda.view.backing.
2. Añadimos dos nuevos atributos:
3. Pulsamos el botón derecho del ratón y seleccionamos Generate Accessors. En la
ventana emergente marcamos treemodel y pulsamos Aceptar.
private TreeModel treemodel;
109
Menús 5
4. Copiamos el siguiente código con el método que devuelve la clase TreeModel:
private TreeModel construyeArbol(List listaContactos){
List aux = new ArrayList();
// Lista de Nodos
Iterator it = listaContactos.iterator();
Contacto contacto = null;
NodoArbol nodoa = new NodoArbol();
while(it.hasNext()){
contacto = (Contacto) it.next();
nodoa = new NodoArbol();
// Asignación
nodoa.setIdcontacto(contacto.getIdcontacto());
nodoa.setNombre(contacto.getNombre());
nodoa.setApellido1(contacto.getApellido1());
nodoa.setApellido2(contacto.getApellido2());
110
Menús 5
nodoa.setIdtipocontacto(contacto.getIdtipocontacto());
nodoa.setIdcontactorelacionado(contacto.getIdcontactorelacionado());
nodoa.setTelefono(contacto.getTelefono());
aux.add(nodoa);
}
// Mapa Contactos
it = aux.iterator();
nodoa = null;
Map mapa = new HashMap();
while(it.hasNext()){
nodoa = (NodoArbol) it.next();
mapa.put(nodoa.getIdcontacto(),nodoa);
}
// Estructura del árbol
List nodos = new ArrayList();
it = mapa.keySet().iterator();
nodoa = null;
while(it.hasNext()){
nodoa = (NodoArbol) mapa.get(it.next());
// Si es un hijo
if (nodoa.getIdcontactorelacionado() != null) {
NodoArbol nodoPadre =
(NodoArbol)mapa.get(nodoa.getIdcontactorelacionado());
nodoPadre.getHijos().add(nodoa);
} else {
nodos.add(nodoa);
111
Menús 5
5. Importamos las clases necesarias para compilar:
6. Sobrescribimos el método public TreeModel getTreemodel():
public TreeModel getTreemodel() {
List resultado = new ArrayList();
OperationBinding operationBinding =
bindings.getOperationBinding("findAllContacto");
resultado = (List) operationBinding.execute();
return construyeArbol(resultado);
}
7. Introducimos el método acción para relacionar dos contactos:
Con este paso finalizamos nuestro desarrollo en la clase del backing de la página de
relaciones de contactos.
}
}
return new ChildPropertyTreeModel(nodos, "hijos");
}
import agenda.model.Contacto;
import agenda.view.NodoArbol;
public String commandButtonRelacionar_action() {
OperationBinding operationBinding =
bindings.getOperationBinding("relacionarContactos");
operationBinding.execute();
getTreemodel();
return null;
}
112
Menús 5
5.4.4. RelacionesContactosPageDef
Vamos a crear todos lo elementos necesarios para facilitar los datos a los componentes de la
página de contactos. Daremos de alta la consulta de los contactos, los iteradores y los
componentes de tipo lista tal y como se describe en los siguientes pasos:
1. Abrimos la página de relacionesContactos.jspx si no la tenemos abierta y
pulsamos sobre el botón derecho, Go to Page Definition.
2. En la paleta de estructura marcamos executables, pulsamos el botón derecho,
Insert Inside Executables, methodIterator.
3. Desplegamos los métodos del EJB AgendaSessionEJBBeanLocal, seleccionamos la
lista de tipo Contacto que devuelve el método findAllContacto() y establecemos el
nombre del método del iterador a “findAllContactoIter”.
113
Menús 5
4. Repetimos los pasos 2 y 3 para crear otro método iterador con el nombre
“findAllContactoIterR”.
5. Después de crear los métodos de los iteradores, los seleccionamos con el ratón y en
la ventana de propiedades establecemos RangeSize a “-1”. Con esto el iterador no
paginará los contactos sino que lo traerá todos.
6. Pulsamos el botón derecho del ratón sobre bindings, Insert inside bindings,
methodAction.
7. En la ventana emergente, marcamos el EJB AgendaSessionEJBBeanLocal y en
Select and Action elegimos el método findAllContacto() y pulsamos Aceptar.
114
Menús 5
8. Repetimos los pasos 6 y 7 para crear otro metodoAction que renombraremos a
“findAllContactoR”.
9. Seleccionamos el método de iterador “findAllContactoIterR” y en el código fuente
establecemos Binds a “findAllContactoR.result”.
10. Volvemos a pulsar el botón derecho del ratón sobre bindings y seleccionamos
Insert inside bindings, list.
11. En la ventana emergente elegimos Create Navigation List Binding y pulsamos
Aceptar. En la siguiente ventana, en el combo de selección Select an Interator
seleccionamos findAllContactoIter y establecemos como atributos de display
nombre, apellido1 y apellido2.
115
Menús 5
12. Después de pulsar Aceptar, renombramos el nuevo objeto de tipo list por
“findAllContactosList”.
13. Repetimos los pasos 7, 8 y 9 seleccionando el método iterador
“findAllContactoIterR” en el paso 8 y estableciendo el nombre del nuevo objeto de
tipo lista a “findAllContactosListR”.
14. En este punto vamos a introducir el método para relacionar los contactos. Sobre
bindings pulsamos botón derecho, Insert inside bindings, methodAction. En la
ventana emergente, pulsamos sobre el EJB y seleccionamos el método
relacionarContactos(Object , Object). El primer parámetro los establecemos a:
Como segundo parámetro introducimos el siguiente código:
Por último, pulsamos Aceptar.
“${bindings.findAllContactoIter.currentRow.dataProvider.idcontacto}”
“${bindings.findAllContactoIter.currentRow.dataProvider.idcontacto}”
116
Menús 5
Concluido el paso 12, tenemos creados todos los elementos necesarios para el desarrollo de
la página.
5.3.4. Añadimos los componentes a la página
Para completar el desarrollo de la página de relaciones, vamos a añadir los componentes que
necesitamos para presentar los contactos y establecer nuevas relaciones.
Seguiremos los puntos que a continuación se detallan:
1. En la paleta de componentes seleccionamos el componente SelectOneChoice de la
librería de etiquetas ADF Faces Core y lo arrastramos a la paleta de estructura sobre
la etiqueta af:panelPage.
2. En la ventana emergente introducimos el valor
“#{bindings.findAllContactoList.items}” en el campo Value. Pulsamos sobre la
pestaña Common Properties, dejamos vacío el atributo Label y en el campo Value
copiamos “#{bindings.findAllContactoList.inputValue}”.
3. Repetimos la operación especificada en los puntos 1 y 2 para incluir otro componente
SelectOneChoice pero cambiaremos la lista por esta otra “findAllContactoListR”.
4. Vamos a añadir el botón para dar de alta las relaciones que indiquemos en los combos
que hemos introducido en la página. En la paleta de componentes, seleccionamos
CommandButton y lo arrastramos a la paleta de estructura sobre la etiqueta
af:panelPage.
5. En la paleta de propiedades, establecemos Text a
“#{res['relacionesContactos.botonRelacionar']}”, como Id
“commandButtonRelacionar” y el Action al método
“commandButtonRelacionar_action()” que añadimos a la clase backing de la
página.
6. Para terminar el desarrollo agregamos el componente árbol. En la paleta de
componentes seleccionamos Tree lo arrastramos hasta la paleta de estructura sobre la
etiqueta af:panelPage. En la ventana emergente establecemos la propiedad Value a
“#{backing_relacionesContactos.treemodel}”, Var como “nodo” y pulsamos
Aceptar.
117
Menús 5
7. Ahora añadimos los nodos. En la paleta de estructura, desplegamos la etiqueta del
componente af:tree. En nodeStamp, seleccionamos la etiqueta h:outputText y
hacemos doble click. Establecemos la propiedad Value de la ventana emergente a
“#{nodo.nombre}”.
8. Añadimos a nodeStamp dos componentes mas de tipo outputText con propiedad
Value a “#{nodo.apellido1}” y “#{nodo.apellido2}” respectivamente.
5.3.5. Ejecución de la página de relaciones
Para ver el resultado del desarrollo que hemos realizado seleccionamos el proyecto
ViewController y pulsamos el botón derecho Run.
El resultado debe ser similar al que presentamos en la siguiente imagen:
118
Menús 5
− Para acceder al bindings de las páginas se publica el objeto bindings de la
clase oracle.adf.model.BindingContainer como Managed Property.
− La clase que implementa los menús en forma de pestañas es MenuTabs.
− La clase que implementa los menús de barras es MenuBar.
− La clase que implementa los menús de tipo lista es MenuList.
− Todos los métodos que implementan lógica de negocio de la aplicación
deberán ser introducidos en el EJB, tal y como se ha hecho en este capitulo
con el método para relacionar los contactos relacionarContactos(Object
entity, Object entity2).
− La clase NodoArbol es la encargada de implementar los nodos que
representan los contactos en el árbol.
− La clase TreeModel es la encargada de almacenar la información de la
estructura del árbol.
− EL método private TreeModel construyeArbol(List listaContactos) de la
clase RelacionesContactos es la encargada de devolver una instancia de
TreeModel que contiene la información sobre la estructura de árbol de los
contactos.
− Para utilizar componentes de tipo SelectOneChoice en la página de
relaciones se definen Navigation List, tales como findAllContactoList y
findAllContactoListR.
recu
erde
_
119
A
ADF. Application Development Framework. Estructura de soporte para el
desarrollo de aplicaciones.
ADF FACES. Conjunto de componentes de interfaces de usuario basados en
Java Server Faces (JSR-127).
C
Classpath. Variable de entorno que determina donde buscar tanto las clases o
librerías de Java (el API de Java) como otras clases de usuario.
Controller. Controlador. Responde a eventos del usuario e invoca cambios en el
modelo y probablemente en la vista.
D
Data Source. Interfaz que se utiliza para acceder de manera transparente a
una fuente de datos.
F
Framework. Estructura de soporte definida en la cual otro proyecto de software
puede ser organizado y desarrollado.
H
HTTP. Protocolo de Internet (Hyper Text Tranfer Protocol) que permite el envío
y la recepción de datos.
I
IDE. Entorno Integrado de Desarrollo
J
JDBC. Java Database Connectivity. API que permite la ejecución de operaciones
sobre bases de datos desde el lenguaje de programación Java.
JNDI. Java Naming and Directory Interfaces.
glos
ario
_
120
JSF. Conjunto de componentes de usuario (UI) que permiten construir la capa
de vista de las aplicaciones Web
JSR. Java Specification Request. Petición de especificación Java.
L
Lógica de negocio. Parte de un sistema que se encarga de las tareas
relacionadas con los procesos de negocio tales como ventas, inventario,
contabilidad, etc.
M
Model. Modelo. Representación específica del dominio de la información sobre la
cual que funciona la aplicación.
MVC. Modelo Vista Controlador. Patrón de arquitectura de software que separa
los datos de una aplicación, la interfaz de usuario y la lógica de control en tres
componentes distintos.
MySql. Sistema de Gestión de Base de Datos multihilo y multiusuario.
P
Patrón de diseño. Solución a un problema de diseño no trivial que es efectiva
(ya se resolvió el problema satisfactoriamente en ocasiones anteriores) y
reusable (se puede aplicar a diferentes problemas de diseño en distintas
circunstancias).
U
UI. User Interface. Interfaz de usuario.
V
View. Representación del modelo en un formato adecuado para interactuar.
Elemento de interfaz de usuario.
W
Workspace. Espacio de trabajo donde se agrupan todos los ficheros que
componen el desarrollo de una aplicación.
glos
ario
_
121
Oracle Application Development Framework Tutorial:
http://www.oracle.com/technology/obe/ADF_tutorial_1013/index.htm
JSF versus Struts:
http://websphere.sys-con.com/read/46516.htm?CFID= 61124&CFTOKEN=FD559D82-
11F9- B3B2-738E901F37DDB4DE
Java Server Faces Technology Overview:
http://java.sun.com/javaee/javaserverfaces/overview.html
Getting Started with JavaServer Faces:
http://www.oracle.com/technology/tech/java/jsf.html
Development Guidelines for Oracle ADF Faces Applications:
http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/js
f/doc/devguide/index.html
Apache MyFaces:
http://myfaces.apache.org/
refe
renc
ias
web
_
123
Oracle® Application Development Framework. Developer’s Guide. 10g
Release 3 (10.1.3)
bibl
iogr
afía
_