19 August 2012

Pasando información de ADF Faces a un AM

Casi siempre en toda aplicación es necesario pasar algun tipo de información almacenada en la vista hacia el modelo (ya sea el usuario logado, el departamento actual ...) ya que esta informacion afecta directamente los datos a filtrar o procesar o a los cuales aplicar algun tipo de comprobación dependiendo de la pagina en la que se este.

ADF ofrece diversos mecanismos para acceder desde el modelo a la vista utilizando clases estaticas o expresiones groovy, pero esto, no hace otra cosa que crear una referencia circular entre las dos capas, cosa que es posible, pero no es correcta.

Para evitar esto, la cuestión o el secreto radica básicamente en inyectar al AM los datos ubicados en la parte de ADF Faces, desde un punto central y transparente al desarrollo de la aplicación; y para hacer esto me base en un artículo del Sr. Andrejus Baranovskis, al cual hago referencia en este post.

En este artículo básicamente se explica como utilizar una factoría propia para los Data Contols y una clase Data Control personalizada, la cual se encarga de hacer la mágia; pero a diferencia de este artículo, Yo no utilizo el método setSessionCookie por que este solo se invoca una vez; es decir que si los datos que tengo almacenados en la session cambian, estos no se ven reflejados en el AM, por tanto en su lugar utilizo el método setDataProvider, el cual me permite introducir siempre los datos actuales.

Pero que tipos de datos puedo inyectar? básicamente cualquiera que este en la parte de faces, por ejemplo:
  • Datos almacenados en la session ( usuario, idioma y departamento actual de trabajo )
  • La página que se esta ejecutando.
  • El taskflow que se esta ejecutando.
  • El fragmento del TaskFlow que se esta ejecutando.
  • ...
Quedando el método setDataProvider de una forma similar a esta forma:
protected void setDataProvider(Object object) {
    super.setDataProvider(object);
    try{
        String page = ControllerContext.getInstance().getCurrentRootViewPort().getViewId();
        String fragment = ControllerContext.getInstance().getCurrentViewPort().getViewId();  
        String department = ADFUtils.getSessionScope().get("currentDep").toString();

        //se obtiene el AM
        CustomApplicationModule am = (CustomApplicationModule)object;

        //se insertan los datos
        am.setUserDataEntry("currentPage", page);
        am.setUserDataEntry("currentFragment", fragment);
        am.setUserDataEntry("currentDepartment", department);

    }catch(Throwable t){
        logger.fine(t);
    }
}

Con esta sencilla implementación, evitariamos las referencias circulares entre capas, ya que estamos inyectando los datos necesarios en los datos de usuario de la session del AM actual, quedando los datos insertados disponibles para el resto de los elementos que contiene el AM (VO's, ...).

Enlaces relacionados:
Solution for Sharing Global User Data in ADF BC

- FIN -

1 comment:

Juan said...

Cool! Buen consejo.