Está en la página 1de 125

índice general_

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
índice_ 1 Introducción

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

1
1 Introducción

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.

3
1 Introducción

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.

4
1 Introducción

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.

5
1 Introducción

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();

6
1 Introducción

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" />

7
1 Introducción

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

8
1 Introducción

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.

9
1 Introducción

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).

10
1 Introducción

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).

11
1 Introducción

− JSF es un framework estándar Java para el desarrollo de aplicaciones Web


recuerde_
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.

12
índice_ 2 Creación de una
aplicación web con JSF

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

13
2 Creación de una
aplicación web con JSF

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:

15
2 Creación de una
aplicación web con JSF

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

16
2 Creación de una
aplicación web con JSF

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”.

17
2 Creación de una
aplicación web con JSF

5. Pulsamos Add Entry y en la ventana de explorador que se abre seleccionamos el


archivo jar de la librería.

18
2 Creación de una
aplicación web con JSF

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.

19
2 Creación de una
aplicación web con JSF

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.

20
2 Creación de una
aplicación web con JSF

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”.

21
2 Creación de una
aplicación web con JSF

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.

22
2 Creación de una
aplicación web con JSF

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.

23
2 Creación de una
aplicación web con JSF

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;

24
2 Creación de una
aplicación web con JSF

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.

25
2 Creación de una
aplicación web con JSF

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);

26
2 Creación de una
aplicación web con JSF

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)

27
2 Creación de una
aplicación web con JSF

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);

28
2 Creación de una
aplicación web con JSF

insert into domicilio(iddomicilio, direccion, provincia, municipio, codigopostal,


idcontacto)
values(15,"C\ Larios nº4 3ºB", "Malaga", "Malaga","44700",14);

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].

29
2 Creación de una
aplicación web con JSF

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.

30
2 Creación de una
aplicación web con JSF

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.

31
2 Creación de una
aplicación web con JSF

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á.

32
2 Creación de una
aplicación web con JSF

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.

33
2 Creación de una
aplicación web con JSF

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.

34
2 Creación de una
aplicación web con JSF

2. En el menú, elegimos Business Tier, EJB, CMP Entity Beans from Tables y
pulsamos Aceptar.

35
2 Creación de una
aplicación web con JSF

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.

36
2 Creación de una
aplicación web con JSF

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.

37
2 Creación de una
aplicación web con JSF

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.

38
2 Creación de una
aplicación web con JSF

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.

39
2 Creación de una
aplicación web con JSF

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.

40
2 Creación de una
aplicación web con JSF

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á.

41
2 Creación de una
aplicación web con JSF

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.

42
2 Creación de una
aplicación web con JSF

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.

43
2 Creación de una
aplicación web con JSF

− Es necesario incluir en Jdeveloper la librería del driver de conexión a la base


recuerde_
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.

44
índice_ 3 Usando ADF
Faces Tables

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

45
3 Usando ADF
Faces Tables

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.

47
3 Usando ADF
Faces Tables

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.

48
3 Usando ADF
Faces Tables

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.

49
3 Usando ADF
Faces Tables

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.

50
3 Usando ADF
Faces Tables

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:

plantilla.marca=JSF
plantilla.marcaAplicacion= Agenda Contactos
plantilla.sobre=Curso JSF

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.

51
3 Usando ADF
Faces Tables

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.

52
3 Usando ADF
Faces Tables

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

53
3 Usando ADF
Faces Tables

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”.

54
3 Usando ADF
Faces Tables

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”.

55
3 Usando ADF
Faces Tables

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:

@NamedQuery(name="findAllContacto", query="select object(o) from Contacto o")

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:

@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")})

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.

56
3 Usando ADF
Faces Tables

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.

57
3 Usando ADF
Faces Tables

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:

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

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.

58
3 Usando ADF
Faces Tables

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.

59
3 Usando ADF
Faces Tables

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”.

60
3 Usando ADF
Faces Tables

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.

61
3 Usando ADF
Faces Tables

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.

62
3 Usando ADF
Faces Tables

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.

63
3 Usando ADF
Faces Tables

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.

// Preparación de los parámetros de búsqueda


nombre = nombre!=null?nombre!=""?"%"+nombre+"%":"%":"%";
apellido1 = apellido1!=null?apellido1!=""?"%"+apellido1+"%":"%":"%";
idtipocontacto = idtipocontacto!=null?idtipocontacto!=""?idtipocontacto:"%":"%";

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

64
3 Usando ADF
Faces Tables

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:

65
3 Usando ADF
Faces Tables

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:

@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")})

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.

66
3 Usando ADF
Faces Tables

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

67
3 Usando ADF
Faces Tables

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:

${bindings.findContactoByParametersIter.currentRow.dataProvider.idcontacto}

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.

68
3 Usando ADF
Faces Tables

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.

69
3 Usando ADF
Faces Tables

− Se debe definir una plantilla para proporcionar un aspecto estándar a todas


recuerde_
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.

70
índice_ 4 Usando ADF
Faces Tree

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

71
4 Usando ADF
Faces Tree

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.

73
4 Usando ADF
Faces Tree

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.

74
4 Usando ADF
Faces Tree

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).

75
4 Usando ADF
Faces Tree

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”.

76
4 Usando ADF
Faces Tree

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:

@NamedQuery(name = "findContactoByIdContacto", query = "select object(o) from


Contacto o where o.idcontacto = :idcontacto")

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.

77
4 Usando ADF
Faces Tree

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}

78
4 Usando ADF
Faces Tree

6. Abrimos el fichero UIResource.properties y añadimos:

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

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:

#{res['edicionContactos.formulario.nombre']}

Debemos repetir el proceso para el resto de af:inputText.

79
4 Usando ADF
Faces Tree

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();

80
4 Usando ADF
Faces Tree

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:

#{res['edicionContacto.formulario.tipoContacto']}

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.

81
4 Usando ADF
Faces Tree

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.

82
4 Usando ADF
Faces Tree

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 :

#{res['edicionContacto.formulario.botonGrabar']}

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:

#{res['edicionContacto.formulario.botonVolver']}

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.

83
4 Usando ADF
Faces Tree

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:

#{res['buscadorContactos.tablaContactos.botonEditar']}

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:

${!adfFacesContext.postback}

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.

84
4 Usando ADF
Faces Tree

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.

85
4 Usando ADF
Faces Tree

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”.

86
4 Usando ADF
Faces Tree

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.

87
4 Usando ADF
Faces Tree

1. Abrimos el fichero UIResources.properties y añadimos:

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

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:

#{res['nuevoContacto.formulario.nombre']}

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();

88
4 Usando ADF
Faces Tree

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.

89
4 Usando ADF
Faces Tree

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:

#{res['nuevoContacto.formulario.tipoContacto']}

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.

90
4 Usando ADF
Faces Tree

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 :

#{res['nuevoContacto.formulario.botonGrabar']}

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']}

91
4 Usando ADF
Faces Tree

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:

#{res['buscadorContactos.tablaContactos.botonNuevo']}

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.

92
4 Usando ADF
Faces Tree

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.

93
4 Usando ADF
Faces Tree

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:

${bindings.findContactoByParametersIter.currentRow.dataProvider}

5. Pulsamos Aceptar.

6. En la paleta de propiedades establecemos el valor de la propiedad Label a:

#{res['buscadorContactos.tablaContactos.botonEliminar']}

7. Para terminar ponemos el valor de la propiedad Action a “buscadorGlobal”.

94
4 Usando ADF
Faces Tree

− Las reglas de navegación (JSF Navigation Case) nos permiten definir el


recuerde_
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.

95
índice_ 5 Menús

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

97
5 Menús

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}”.

99
5 Menús

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:

100
5 Menús

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:

navegacion.paginaBuscador=Buscador Contactos
navegacion.paginaRelaciones=Relaciones Contactos
relacionesContactos.botonRelacionar=Relacionar

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.

101
5 Menús

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.

102
5 Menús

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).

103
5 Menús

− 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;
}

104
5 Menús

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.

105
5 Menús

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;
}

106
5 Menús

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;
}

107
5 Menús

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:

private TreeModel treemodel;

3. Pulsamos el botón derecho del ratón y seleccionamos Generate Accessors. En la


ventana emergente marcamos treemodel y pulsamos Aceptar.

108
5 Menús

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());

109
5 Menús

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);

110
5 Menús

}
}

return new ChildPropertyTreeModel(nodos, "hijos");


}

5. Importamos las clases necesarias para compilar:

import agenda.model.Contacto;
import agenda.view.NodoArbol;

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:

public String commandButtonRelacionar_action() {

OperationBinding operationBinding =
bindings.getOperationBinding("relacionarContactos");
operationBinding.execute();
getTreemodel();
return null;
}

Con este paso finalizamos nuestro desarrollo en la clase del backing de la página de
relaciones de contactos.

111
5 Menús

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”.

112
5 Menús

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.

113
5 Menús

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.

114
5 Menús

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:

“${bindings.findAllContactoIter.currentRow.dataProvider.idcontacto}”

Como segundo parámetro introducimos el siguiente código:

“${bindings.findAllContactoIter.currentRow.dataProvider.idcontacto}”

Por último, pulsamos Aceptar.

115
5 Menús

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.

116
5 Menús

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:

117
5 Menús

− Para acceder al bindings de las páginas se publica el objeto bindings de la


recuerde_
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.

118
A
glosario_
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).

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.

Data Source. Interfaz que se utiliza para acceder de manera transparente a


una fuente de datos.

Framework. Estructura de soporte definida en la cual otro proyecto de software


puede ser organizado y desarrollado.

HTTP. Protocolo de Internet (Hyper Text Tranfer Protocol) que permite el envío
y la recepción de datos.

IDE. Entorno Integrado de Desarrollo

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.

119
JSF. Conjunto de componentes de usuario (UI) que permiten construir la capa
glosario_
de vista de las aplicaciones Web
JSR. Java Specification Request. Petición de especificación Java.

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.

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.

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).

UI. User Interface. Interfaz de usuario.

View. Representación del modelo en un formato adecuado para interactuar.


Elemento de interfaz de usuario.

Workspace. Espacio de trabajo donde se agrupan todos los ficheros que


componen el desarrollo de una aplicación.

120
Oracle Application Development Framework Tutorial:
referencias web_
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/

121
Oracle® Application Development Framework. Developer’s Guide. 10g
bibliografía_
Release 3 (10.1.3)

123

También podría gustarte