====== Creación del Bean de respaldo del maestro y clases necesarias ====== --- //[[pedrody@um.es|PEDRO DELGADO YARZA]] 2014/03/11 12:42// El modelo Maestro-Detalle propuesto hace uso de un mecanismo de paginación dinámico, es decir, en la aplicación sólo se cargan los registros que se visualizan y cuando se pagina se obtienen los nuevos. Esta manera de proceder ha sido viable gracias a la mejora de rendimiento de JSF 2 y a las utilidades que Primefaces nos provee para mejorar esta faceta. Así pues necesitamos dos clases Java para gestionar el maestro, una el propio Bean de respaldo del Maestro y otra para gestionar la tabla. ===== Bean de respaldo del maestro ===== El bean de respaldo que tendrá la pantalla del maestro, tiene como función principal la gestión del control de la aplicación en esa página junto con la coordinación con los Beans de gestión de la persistencia para la obtención y serialización de los datos. Deberá tener especificado un nombre (anotación **@Name**) de bean para que pueda ser accedido por la vista, así como también un scope (anotacion **@Scope**) que indicará cuanto tiempo ha de mantener en memoria su información lo que implica, a su vez, que este Bean debe implementar la interfaz Serializable. @Name("manejadorAnuncios") @Scope(ScopeType.CONVERSATION) public class ManejadorAnuncios implements Serializable { .... .... } Una vez creado el Bean, deberemos incluir los Beans o EJB externos que utilicemos, haciendo uso de la anotación **@In**. Es importante recordar que el **Log** también debe importarse. @Logger private Log log; @In (value="org.jboss.seam.security.identity") private UmuIdentity identiy; En caso de no estar seguros de si los Beans que importamos estarán o no creados, añadimos el parámetro **create = true** a nuestras anotaciones @In. @In(create = true) private ServicioAnuncios servicioAnuncios; Una vez incluidos los Beans que necesitaremos importar, declaramos las variables que usaremos para dar servicio con nuestro Bean. Una vez creadas **debemos crear un método get y otro set** para cada una de ellas. Estos métodos tienen que tener una sintaxis concreta ya que Seam usa esta sintaxis para poder obtener los valores en la parte de la vista. Para generar los get y set correspondientes de acuerdo como Seam los quiere tan solo debemos hacer clic derecho dentro del fichero que estamos editando y en el menú contextual que aparece hacer clic en **Source >> Generate Getters and Setters** y en el menú contextual que aparece, marcar las variables que hemos declarado. {{ :fdw2.0:fundeweb2.0:gt:md0.png |}} Una vez definidas las variables de las que haremos uso debemos preparar nuestro manejador, para ello haciendo uso de la anotación **@Create** sobre un método //public void//, estableceremos los valores por defecto que ha de tener el bean cuando se cree. @Create public void inicializaBuscador() { refrescarAnuncios(); buscadorAnuncios = new AnuncioLazyDataModel(); buscadorComentarios = new ComentarioLazyDataModel(); } ===== Clase gestora de la tabla del maestro ===== Como mencionamos en la introducción, Primefaces provee de una infraestructura para mostrar tablas optimizadas, para ello debemos crear una clase que será el gestor de la tabla. Dicha clase estará incluida dentro del Maestro, que deberá inicializarla y será usada directamente por la tabla incluida en la vista para paginar y cargar los nuevos datos. Esta clase, que es una clase simple java debe extender la clase abstracta **//FundeWebLazyDataModel//** pasando como parámetro el tipo de objeto sobre el que se actuará. Los métodos más destacados son: * **loadPage( first, pageSize, multiSortMeta,filters )**: Carga la lista de los siguientes objetos a visualizar a partir de los parámetros pasados en su cabecera. public class AnuncioLazyDataModel extends FundeWebLazyDataModel { @Override protected List loadPage( int first, int pageSize, List multiSortMeta, Map filters ) { ResultQuery resultQuery = getServicioAnuncios().obtenerComunicacionesDto( filters, first, pageSize, PrimeFacesUtils.sortMetaToString(multiSortMeta) ); setRowCount( resultQuery.getResultCount().intValue() ); return resultQuery.getResultList(); } private ServicioAnuncios getServicioAnuncios() { return (ServicioAnuncios) Component.getInstance( ServicioAnuncios.NAME, ScopeType.STATELESS ); } } En las clases //Lazy//, como manera excepcional, podemos utilizar el //DAS// directamente si queremos, en lugar del servicio. La clase //FundeWebLazyDataModel// ya tiene implementaciones de los métodos: * //**public List load( int first, int pageSize, String sortField, SortOrder sortOrder, Map filters )**// * //**public List load( int first, int pageSize, List multiSortMeta, Map filters )**// * //**public T getRowData( String rowKey )**// * //**public Object getRowKey( T object )**// Estos métodos son los que se suelen implementar a la hora de trabajar con los //Lazy// de //PrimeFaces//. Permitiendo trabajar tanto con DTOs (POJOs) como con beans de entidad. Los métodos //load// de la clase //LazyDataModel// llaman internamente al método //loadPage// de //FundeWebLazyDataModel// que es el que tenemos que implementar. También permite establecer filtros (parámetros) externos, si no se utiliza [[https://www.primefaces.org/showcase/ui/data/datatable/filter.xhtml|el filtrado de columna del DataTable]], utilizando los siguientes métodos: /** * Obtiene los filtros (parametros) externos, cuando no se utiliza el filtrado de columna incluido en el componente * DataTable. * * @return Map * - Los filtros externos. */ public Map getExternalFilters() { return externalFilters; } /** * Establece los filtros (parametros) externos, cuando no se utiliza el filtrado de columna incluido en el componente * DataTable. * * @param externalFilters - un Map con los filtros externos. */ public void setExternalFilters( Map externalFilters ) { this.externalFilters = externalFilters; } ===== Modificación en el POM del Módulo Web ===== Si la version del //// en el POM principal, es anterior a la version **2.0.30** (o **2.0.30-primefaces6** si estamos en PrimeFaces 6), tendremos fallos de compilación con Maven, indicando que falta la clase //org.jboss.seam.ui.AbstractEntityLoader//. Para solucionarlo, hay dos alternativas, actualizar la version del //// en el POM principal o modificar el //// de la dependencia //jboss-seam-ui// en el POM del modulo WEB. Para esta ultima opción, tenemos que realizar los siguientes pasos: * Abrimos el fichero //pom.xml// del módulo y buscamos la dependencia //jboss-seam-ui//. * Cambios el //scope// a //compile//. Quedando: org.jboss.seam jboss-seam-ui compile