lunes, 7 de mayo de 2012

ADF 11g: Paso de parámetros entre llamadas a Task Flows

Es muy común dividir los Task Flows en más Task Flows para facilitar el mantenimiento de los mismos. Esto hace que en numerosas ocasiones sea necesario pasar parámetros entre el Task Flow que actúa de Llamador y el Task Flow que actúa de Llamado.

Enlace a descarga del Ejemplo: EjemploParamTaskFlows.

Por ello traigo un ejemplo sencillo y explicativo de como se realiza el paso de parámetros entre Task Flows.

Para comenzar, tenemos 2 Task Flows:

  • El Llamador: Es una Bounded Task Flow basada en fragmentos que contiene una única vista encargada de realizar la llamada a otro Task Flow. Está basada en fragmentos dado que lo incrustaremos en una página de prueba llamada startApplication.jspx.
    Task Flow Llamador
  • El Llamado: Es una Bounded Task Flow basada en páginas puesto que será ejecutada por el Llamador en modo "diálog / inline-popup". Contendrá una lógica inicial basada en el parámetro consumido de entrada que decidirá a qué página de la Task Flow se va a navegar.
    Task Flow Llamado
Dado el escenario principal, estos son los pasos importantes a la hora de pasar parámetros entre Task Flows:
  • En la definición del Task Flow Llamado se debe configurar un parámetro de entrada requerido. Por ello, en la configuración propia del Task Flow en la zona de configuración de Parameters registrar un nuevo parámetro con los siguientes valores:
    Registro del parámetro de entrada del Task Flow Llamado
    • Name: Es el nombre del parámetro. En el caso del ejemplo "accion".
    • Class: Es la clase Java que define el tipo del parámetro. En el caso del ejemplo String.
    • Value: Es donde será almacenado el valor. En este caso en la pageFlowScope en una variable llamada accion.
    • Required: Marca la obligatoriedad del parámetro. En caso de ser requerido, al realizar una Task-Flow-Call nos obligará a dar un valor a dicho parámetro.
  • En el propio Task Flow Llamado existe la implementación de una lógica en base al parámetro recibido apoyada en un af:router para decidir sobre la navegación a usar. 
    Configuración de af:router de entrada basado en el parámetro de entrada
  • En el Task Flow Llamador se tiene la Task Flow Call del Task Flow. Al añadir este Task Flow Call se solicitará el parámetro configurado en el Llamado. Por ello configuraremos que dicho parámetro recoja el valor de la pageFlowScope del Llamador de una variable llamada "valor pulsado". También recordar que, como se va a realizar la llamada en modo "dialog / inline-popup", hay que configurar esto mismo en la llamada.
    Configuración de la llamada al Task Flow Llamado (Task Flow Call)
  • Únicamente faltaría cargar el dato en la variable de la pageFlowScope llamada botonPulsado. Para ello se utilizará una Operation de ADF. Concretamente af:setActionListener. Para que, cuando se pulse uno de los botones de la vista, se cargue el valor correspondiente en la variable.
    Configuración de un Set Action Listener arrastrado al botón de "editar"
      Action Listener's configurados para todos los botones. Cargando la variable botonPulsado
  • También recordar que en los botones es imprescindible establecer el atributo useWindow = true dado que estamos ejecutando la llamada en modo "dialog / inline-popup".
  • Finalmente adherir el Task Flow llamador a una página de prueba y ejecutar.
    Task Flow Llamado, pulsar en Añadir
      Ejecución en diálogo al dar al botón añadir.
Ejemplo desarrollado con JDeveloper 11.1.1.4

sábado, 5 de mayo de 2012

ADF 11g: Eventos Contextuales

La comunicación entre regiones (Bounded Task Flows) en una página es posible gracias al framework de Contextual Events (Eventos Contextuales) de ADF.

Enlace a descarga del ejemplo: Ejemplo de Eventos Contextuales

Este framework se basa en un concepto sencillo: Productor - Consumidor

En muchas ocasiones cuesta entender el concepto básico y los pasos a seguir para conseguir transmitir información de una región a otra. Por ello en este ejemplo trato de detallar minuciosamente los pasos a seguir y por qué de dichos pasos.

En el siguiente ejemplo tenemos dos Bounded Task Flows:

  • Consumidor-TF: Es un sencillo Task Flow que únicamente se encargará de consumir los valores recibidos del evento disparado por el Productor.
  • Productor-TF: Es un Task Flow con una navegación sobre la vista de la tabla Departaments del esquema de BBDD, HR. Por ello se hace necesario tener una Oracle XE instalada para poder ejecutar el ejemplo. Además, este Task Flow será el encargado de publicar el evento al que se suscribirá el Consumidor.
Para conseguir la comunicación entre las dos regiones seguir los siguientes pasos que explican como crear un sencillo ejemplo de uso de los eventos contextuales:
  • Crear una aplicación Fusion Web Application (ADF).
    Creación de Fusion Web Application
  • Crear una conexión de base de datos al esquema HR de la BBDD de Oracle XE.
    Creación de conexión JDBC a HR
  • En el proyecto Model crear los ADF BC que se usarán en el Productor-TF. Para ello hacer click derecho en el proyecto y seleccionar Business Components From Tables.
    Creación de ADF BC desde Tablas del esquema HR
  • En el Wizard de creación de los ADF BC, solo seleccionar la tabla Departaments para las Entity Objects, View Objects.
    Proyecto Model con las EO, VO, VOR y AM.
  • Lo siguiente es la creación de los dos Bounded Tasks Flow: Consumidor-TF y Productor-TF
    Task Flow Consumidor y Productor
  • En el Task Flow Consumidor-TF solamente se tendrá una view con un layout simple que contendrá un af:outputText.
    Vista de la única página del Consumidor-TF
  • Generar un Backing Bean para el manejo de esta vista, para ello lo más sencillo es seleccionar directamente el af:outputText y, en el Property Inspector, desde la propiedad Binding editar y generar directamente el Backing Bean.
    Creando el Backing Bean de manejo de la página
  • Además del Binding generado de la caja de texto con el Backing Bean, generar manualmente un atributo más al que realizar el "binding" con el valor actual que tendrá la caja de texto.
    Backing Bean con Binding al componente y a su valor

  • Enlazar la nueva propiedad del Backing Bean con el atributo value de la caja de texto.
    Valor del af:outputText enlazado con el Backing Bean
  • Generar una clase que tendrá el método encargado de manejar el evento y establecer el nuevo valor en la caja de texto. Tener en cuenta que dependiendo del evento que vayamos a manejar, el parámetro de entrada es de un tipo y otro. Por ejemplo, se podría pasar directamente el valor de tipo String en vez de todo el evento.
    Método manejador de eventos del Consumidor-TF
  • Crear un Data Control a partir de esta clase recién generada. Esto se realiza porque es necesario poder hacer accesible desde la Binding Layer de la página el método recientemente creado para poder usarlo como consumidor de eventos. Para crear el Data Control solamente hay que hacer click derecho en la clase y seleccionar create Data Control.
    Creación del Data Control de la clase manejadora de eventos
  • Con el Data Control creado, es necesario hacer realmente accesible este método desde la Binding Layer. Por ello debemos ir a la vista de Bindings de la view y crear un Binding de tipo method action seleccionando como método en el Wizard el método del Data Control que se ha creado.
    Creación de un binding, methodAction al método manejador

      Binding realizado
  • Por parte del Task Flow Consumidor-TF está todo configurado. Para resumir, el Task Flow consumidor lo que tienen básicamente es:
    • Un Backing Bean para el manejo y acceso a los componentes que se modificarán desde el manejador de eventos.
    • Una clase para manejar los eventos que recibirá el Task Flow a través de los cuales actualizará los componentes visuales gracias al Backing Bean.
    • Un Data Control del manejador de eventos para poder crear un Binding de tipo methodAction en la vista para poder hacer accesible el método consumidor a los demás Task Flow.
  • En el Task Flow Productor-TF. En su página principal vamos a arrastrar desde el DataControl que se generó al crear los ADF BC la vista de departamentos y generar a partir de ella una ADF Form con botones de navegación.
  • Seleccionar el campo DepartamentName y en el Property Inspector navegar hasta Published Events para generar un nuevo evento disparado por este campo. En este caso, se lanzará un evento de cambio de valor por lo que al generar el evento no es necesario dar más información que el nombre del evento.
    Crearción de un Evento disparado por el componente
  • Para comodidad del ejemplo, establecer el atributo AutoSubmit del campo DepartamentName a true. Con ello se logrará que cuando perdamos el foco de este campo se haga un submit permitiendo al otro Task Flow consumir el valor inmediatamente.
    autosubmit a true
  • Llegados a este punto, ya se tienen los dos Task Flow independientes configurados. Por parte del Consumidor ya está preparado para recibir la información y por parte del Productor.
  • Crear una página en la que situar los dos Task Flow.
    Página con los 2 Task Flow añadidos
  • Finalmente realizar el enlace entre el evento productor y el método consumidor. Por ello navegar hasta la pageDef de la página contenedora de los dos Task Flow y, llegados a este punto, a gusto del desarrollador se puede realizar el enlace desde dos sitios:
    • Directamente desde la pestaña de ContextualEvents. Seleccionar el evento que se dispara y, en la pestaña Subscribers seleccionar el Task Flow que se va a suscribir a ese evento y el método encargado de recibir la información. Se debe tener en cuenta que los parámetros que se configuran su nombre debe coincidir con el que se puso en el  evento de manejo de eventos del consumidor.
      Y como valor recibido usamos el #{payLoad}, que no es más que el evento producido por el campo del Productor. En este punto podríamos pasar otros valores distintos procedentes de distintos lugares.
      Suscripción a un evento desde la interfaz visual de la pageDefinition

      Suscripción al evento disparado por parte del Consumidor
    • Abrir la vista de JDeveloper Structure. Hacer click derecho en la pageDef y seleccionar Edit Event Map. Rellenar el Wizard con los valores correspondientes de quién es el Productor, qué evento dispara y quién es el que lo consume. Además, tener en cuenta que los parámetros su nombre debe coincidir con el nombre del parámetro esperado por el método consumidor.
      Suscripción a un evento desde la vista Structure
  • Ejecutar la página JSPX creada y veréis que cuando se modifique el campo DepartamentName y se pierda el foco sobre el mismo, el Task Flow Consumidor-TF recibirá el nombre que se haya puesto en dicho campo.
    Comunicación entre las dos regiones
Ejemplo desarrollado en JDeveloper 11.1.1.6, con una base de datos Oracle XE y el esquema HR que trae por defecto.