Archivo
ADF tips: Control de cambios pendientes

El control de cambios pendientes cuando el usuario abandona una página es siempre un problema muy a tener en cuenta, sobretodo cuando el usuario utiliza formas de navegación no controladas por la aplicación (como el botón atrás, cerrar el navegador, refrescar la página…).
ADF ofrece una manera muy sencilla de alertar al usuario cuando tiene cambios pendientes, simplemente debemos añadir el atributo uncommittedDataWarning dentro del tag af:document; como se muestra en la imagen.
Esta nueva propiedad provoca que cuando el usuario intenta cerrar el navegador, refrescar la página, ir atrás o una acción similar, salte un popup genérico que le alerte de que si continua puede perder sus cambios.
Además es posible forzar a que este aviso sea lanzado cuando se haga uso de algún elemento de navegación dentro de la propia pantalla, por ejemplo al pulsar un botón o hacer un cambio de pestaña. Para ello debemos añadir el atributo af:checkUncommittedDataBehavior dentro del componente deseado.
Aunque es una solución válida para evitar salidas descontroladas del navegador, en algunos casos puede que necesitemos personalizar este popup de alerta. Por ejemplo para ofrecerle al usuario la opción de guardar sus cambios desde el propio popup, forzar a deshacer todos los cambios antes de permitir la navegación o tal vez darle un aspecto más amigable al aviso. Para ello podemos acceder a la comprobación que internamente el framework ejecuta por nosotros para saber cuándo debe mostrar el mensaje de aviso; teniendo la opción de por ejemplo abrir un popup de aviso propio.
En resumen, gracias a la opción de uncommittedDataWarning podemos alertar al usuario de una forma rápida y eficaz de que va a perder los cambios pendientes, y en caso de que el aviso genérico no cumpla con todos nuestros requisitos, existe una forma alternativa de hacer la misma comprobación y controlar manualmente todas las opciones que el usuario tendrá disponibles.
ADF tips: Refinando el “Failed to validate all rows in transaction”

En este tip explicaremos cómo ampliar de forma sencilla y útil la conocida excepción de “Failed to validate all rows in transaction“.
Todo proyecto una vez pasa la fase de desarrollo necesita buenas trazas de log, sobretodo en casos de error. En el momento que una entidad no cumple todas sus validaciones lanza una excepción en el método validateEntity del tipo ValidationException. En las trazas de log por defecto no veremos demasiada información acerca del error, lo que siempre nos complica la resolución del mismo.
Para tener algo más de información podemos crear una entidad genérica de la que hereden el resto de entidades de nuestro proyecto; esto se configura desde las propiedades del proyecto en la opción Business Components:
ADF tips: Validadores personalizados

En este tip explicaremos cómo se puede crear un validador personalizado en la capa de vista utilizando una clase java propia, siendo reutilizable en tantas páginas como queramos.
ADF permite validaciones desde nivel de entity hasta nivel de vista; en este caso nos centraremos en la parte de vista, heredada de JSF. El primer paso es crear la clase Java que implemente la interfaz de javax.faces.validator.Validator; lo que nos obliga a implementar su método abstracto validate:
Una vez creada la clase, debemos registrarla en el fichero faces-config.xml de nuestro proyecto utilizando el wizard:
Ahora sólo queda hacer uso de este validador en una de nuestras páginas. Para ello hay que añadir el tag de <af:validator> dentro de uno de nuestros inputText:
ADF tips: Redirección dinámica de task-flows

En este tip explicaremos cómo definir el destino de una acción en un task-flow en tiempo de ejecución.
En la capa controller, ADF permite definir una serie de acciones estáticas en tiempo de diseño. En algunos casos esto puede limitar el diseño y obliga al programador a hacer uso de elementos como routers o regiones dinámicas.
Si decidimos utilizar un router para definir todas las posibilidades de navegación puede elevar la complejidad del task-flow, lo que hace difícil su lectura; además de la pérdida de rendimiento que puede ocasionar.
Si por el contrario mantenemos un task-flow sencillo con una única navegación y hacemos uso de regiones dinámicas solventamos el problema de complejidad en el task-flow, pero cargaremos demasiado la aplicación. Además de hacer menos mantenible esta parte del código.
Sin embargo, desde hace varias versiones de ADF (11.1.1.2) podemos definir la navegación en tiempo de ejecución. Esto quiere decir que sólo debemos indicarle al task-flow que la navegación será de tipo dinámica y introducir una expresión EL con la que obtendrá el objeto TaskFlowId que será interpretado para obtener el task-flow destino.
La expresión EL debe retornar un objeto TaskFlowId creado previamente, por ejemplo:
ADF tips: Método rápido y sencillo para incorporar Google Maps a nuestra aplicación

Todos sabemos que la mejor forma de localizar una dirección es acceder mediante nuestro navegador a https://maps.google.es/ y teclear el nombre de la vía y de la localidad.
Google proporciona un servicio gratuito (disponible para cualquier sitio web que sea a su vez gratuito para el consumidor) para acceder a sus mapas, haciendo uso de la versión 3 de su API JavaScript.
Os voy a mostrar como podéis usar esta API desde una página JSF. En unos pocos pasos conseguiremos una aplicación que nos permitirá, a partir de los atributos dirección y población de una tabla en pantalla y mediante la pulsación de un botón de comando, lanzar un pop-up, donde ver la localización exacta del lugar.
Mantenimiento de una tabla n:m en ADF con SelectManyShuttle
Un ejemplo de cómo hacer un mantenimiento de una tabla de forma usable para el usuario seria utilizar el componente SelectManyShuttle. Uno de los casos que podemos utilizarlo es cuando tenemos una tabla que sale de una relación n:m, por ejemplo:
Tenemos la tabla de usuarios, roles y ahora queremos guardar en la tabla usuarioRoles los roles asignados aún usuario. Para realizar esto crearemos una pantalla donde tendremos la tabla de usuarios y seleccionaremos uno de los usuarios y con el componente SelectManyShuttle le asignaremos los roles. En la pantalla también pondremos la tabla UsuariosRoles para ver los cambios.
Pasos a seguir
Creamos una aplicación Fusion Web Application (ADF) y creamos los business components desde nuestra base de datos: nos pedirá la conexión a la base de datos y elegiremos las entidades que queremos utilizar. En este ejemplo: Usuario, Roles y UsuarioRoles. Obtendremos los siguientes business components:
Oracle ADF Faces Components Demo actualizada a versión 11gR2
La demo de ADF Faces Components ha sido revisada y actualizada con las nuevas funcionalidades de JDeveloper 11.1.2. Han aumentando hasta 169 los componentes disponibles.

La demo puede descargarse desde este link y desplegarse sobre Oracle JDeveloper o sobre Oracle WebLogic Server.
Demo Source Code: The war file also contains the demo source files for developers to study and learn from. All JSPX files and Java sources can be looked at in the Oracle JDeveloper project that is created when importing the WAR file. Note that the ADF Faces component demo does not contain the ADF Faces RC sources and ADF binding sources. These can be request from customer support, requiring a customer support contract for ADF.
También puede ejecutarse online desde aquí.

En la sección Tab Guide aparecen todos los componentes ordenados de diferentes formas. Al probar cada uno de ellos se dispone de un editor que permite comprobar cómo afectan los valores de cada atributo al componente.

Un poco de formación ADF online (ampliación)
Hace un año publicamos este post con links a vídeo-cursos de formación sobre Oracle Application Framework (ADF).
Desde entonces hemos añadido más de 50 vídeos en nuestro canal de YouTube:
avanttic vídeo – Oracle Fusion Development
Como complemento, en este fantástico post de John Brunswick encontrarás multitud de material para aprender o profundizar en ADF: blogs, tutoriales, demos, maquinas virtuales, links de descarga y libros. Es la recopilación más interesante que hemos encontrado durante este último año y fue publicada hace sólo 3 semanas.
Y si quieres estar al día de novedades relacionadas con ADF y con otras tecnologías Oracle, nos puedes seguir en avanttic twitter.
Piensa en Web, pantallas ligeras y rápidas
Para aquellos equipos acostumbrados al desarrollo en entornos cliente-servidor, el paso al desarrollo de aplicaciones web no debería únicamente implicar el cambio de herramientas y tecnología a usar por parte del equipo de programación. Es tarea del equipo de analistas funcionales entender los cambios en la interficie de usuario, o a nivel transaccional que el paradigma web conlleva. Debemos tener en cuenta que un diseño funcional donde en una pantalla ponemos dos o tres relaciones maestro-detalle con multitud de ítems, si bien será implementable en web, su rendimiento será muy pobre, y además estaremos mareando al usuario llenando su navegador con una cantidad excesiva de información.
En un caso como el planteado, si realmente el usuario va a tener que rellenar toda esa información, lo más indicado sería presentarle la información en bloques (como en un wizard, con botones de “anterior” y “siguiente”; en cambio, si los datos a introducir or modificar es una parte del total, lo mejor sería que el usuario pudiera navegar a los diferentes bloques que él seleccione.
Cito un par de factores importantes que deberían ser tenidos en cuenta:
- Layout: En un entorno tipo Cliente-Servidor (como Oracle Forms) disponemos de un runtime propietario y controlado que nos permite entre otras cosas el posicionamiento absoluto de items. En cambio en el entorno web no sabemos a priori sobre qué navegador va a correr nuestra aplicación. Incluso diferentes versiones del mismo navegador (léase MS Explorer) tienen comportamientos diferentes. Debemos asegurarnos que nuestra aplicación sea capaz de mostrarse correctamente en cualquier navegador. El uso de componentes estándar de ADF 11g simplifica en gran medida este punto.
- Simplicidad: El tráfico que genera una aplicación web es significativamente mayor que el generado por una aplicación Cliente-Servidor ejecutada en un entorno de tres capas (con servidor de aplicaciones), y además la representación es más lenta (el navegador debe interpretar el código html, javascript, css, etc que le llega). Para no penalizar el rendimiento de la aplicación, es aconsejable “aligerar” al máximo las pantallas. Al mismo tiempo estaremos generando pantallas más “atómicas”, y por tanto, más fáciles de reutilizar desde diferentes puntos de la aplicación. Frameworks como ADF 11g facilitan este tipo de diseños, mediante el uso de task flows.
ADF 11g: Simplificar invocación métodos del Application Module desde ViewController
Invocar métodos de un Application Module desde las pantallas de nuestra aplicación (por ejemplo, como respuesta a que el usuario haya pulsado un botón) es una tarea habitual en nuestras aplicaciones desarrolladas con ADF 11g.
La forma más adecuada de hacer estas llamadas es utilizando los bindings. Si esta es nuestra manera de trabajar, es posible desarrollar un par de clases auxiliares en la capa de vista para que nos faciliten las cosas.
La primera clase nos encapsula la respuesta del método, dándonos acceso a la lista de errores que se hayan producido en el método invocado, y al retorno del método (si lo hay):
Una vez tenemos esta clase, la usaremos en la llamada al Application Module para almacenar la respuesta
Leer más…















