UDA-Componentes RUP. Jerarquía (v2.1.1 deprecado)

21
UDA – Utilidades de desarrollo de aplicaciones by EJIE is licensed under a Creative Commons Reconocimiento- NoComercial-CompartirIgual 3.0 Unported License . UDA - Utilidades de desarrollo de aplicaciones Componentes RUP – Jerarquía Fecha: 07/11/2012 Referencia: EJIE S.A. Mediterráneo, 14 Tel. 945 01 73 00* Fax. 945 01 73 01 01010 Vitoria-Gasteiz Posta-kutxatila / Apartado: 809 01080 Vitoria-Gasteiz www.ejie.es

description

UDA-Utilidades de desarrollo de aplicaciones • UDA-Componentes RUP. Jerarquía http://code.google.com/p/uda/

Transcript of UDA-Componentes RUP. Jerarquía (v2.1.1 deprecado)

Page 1: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

UDA – Utilidades de desarrollo de aplicaciones by EJIE is licensed under a Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 Unported License.

UDA - Utilidades de desarrollo de aplicaciones

Componentes RUP – Jerarquía

Fecha: 07/11/2012 Referencia:

EJIE S.A.

Mediterráneo, 14

Tel. 945 01 73 00*

Fax. 945 01 73 01

01010 Vitoria-Gasteiz

Posta-kutxatila / Apartado: 809

01080 Vitoria-Gasteiz

www.ejie.es

Page 2: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía ii/21

Control de documentación

Título de documento: Componentes RUP – Jerarquía

Histórico de versiones

Código: Versión: Fecha: Resumen de cambios:

1.0.0 17/12/2012 Primera versión.

Cambios producidos desde la última versión

Control de difusión

Responsable: Ander Martínez

Aprobado por:

Firma: Fecha:

Distribución:

Referencias de archivo

Autor:

Nombre archivo:

Localización:

Page 3: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía iii/21

Contenido

Capítulo/sección Página

1. Introducción 5

2. Ejemplo 5

3. Casos de uso 5

4. Infraestructura 5

4.1. Ficheros 6

4.2. Dependencias 6

5. Invocación 7

6. Propiedades 7

7. Sobreescritura del theme 9

8. Requisitos (Base de Datos) 9

9. Integración con UDA 10

9.1. Modelo 10

9.2. Acceso a datos 10

9.2.1. Consulta 10

9.2.2. Consulta con filtro 12

9.2.3. Consulta elementos contraídos 13

9.3. Mapeador de datos [RowMapper] 13

9.4. Controlador 14

9.5. Serialización de datos 15

9.6. Presentación 15

10. Jerarquía con selección múltiple 15

10.1. Menú desplegable 16

10.2. Edición múltiple / Eliminación múltiple 17

Page 4: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía iv/21

10.2.1. Acceso a datos 17

10.2.2. Consulta 18

10.2.3. Controlador 19

10.2.4. Presentación 19

11. Integración con x38 19

11.1. Pagination 19

11.2. Jerarquía 21

Page 5: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 5/21

1. Introducción

La descripción del Componente Jerarquía , visto desde el punto de vista de RUP, es la siguiente:

El objetivo principal del componente Jerarquía es la presentación de un conjunto de datos (tabla) ordenados jerárquicamente en base a una relación existente entre ellos.

NOTA: Este no es un componente como tal, si no una mejora aplicable sobre el componente tabla.

2. Ejemplo

Se presentan a continuación un ejemplo de este componente:

3. Casos de uso

Se recomienda el uso del componente:

• Cuando se desea estructurar los datos para facilitar su visualización por parte del usuario.

• Cuando se desea navegar por niveles para buscar un determinado dato.

• Cuando se desea obtener un elemento en concreto y conocer sus ancestros/niveles superiores.

4. Infraestructura

A continuación se comenta la infraestructura necesaria para el correcto funcionamiento del componente.

• Se necesita que la entidad a mostrar contenga en la Base de Datos una columna por la que se interrelaciones las filas. Es decir, una columna “Padre” que indique el nivel superior de cada elemento si lo tuviera (si no el valor del campo sería null).

Page 6: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 6/21

• Requiere un tratamiento especial en el DAO para lanzar unas determinadas sentencias SQL para recuperar datos adicionales a los relativos a la entidad. Las modificaciones serán tanto a nivel de método como de mapeador de datos de Base de Datos a datos de presentación. Para facilitar la labor se incluyen ciertas clases y funcionalidades en x38.

• Se requiere la inclusión de los ficheros que implementan el componente (js y css) comentados en los apartados Ficheros y Dependencias.

• Se necesitan realizar algunas modificaciones sobre la tabla original para que se muestre correctamente la jerarquía.

4.1. Ficheros

Ruta Javascript: rup/scripts/

Fichero de plugin: rup.grid.jerarquia-x.y.z.js

Ruta theme: rup/basic-theme/

Fichero CSS del theme: theme.rup.grid.jerarquia- x.y.z.css

4.2. Dependencias

Por la naturaleza de desarrollo de los componentes (patrones) como plugins basados en la librería JavaScript jQuery , es necesaria la inclusión del esta. La versión elegida para el desarrollo ha sido la versión 1.8.0.

• jQuery 1.8.0: http://jquery.com/

La gestión de la ciertas partes visuales de los componentes, se han realizado mediante el plugin jQuery UI que se basa en jQuery y se utiliza para construir aplicaciones web altamente interactivas. Este plugin, proporciona abstracciones de bajo nivel de interacción y animación, efectos avanzados de alto nivel, componentes personalizables (estilos) ente otros. La versión utilizada en el desarrollo ha sido la 1.8.23.

• jQuery UI 1.8.23: http://jqueryui.com/

La visualización de los datos en pantalla se realiza a través del plugin jqGrid basado en jQuery. La versión empleada para la jerarquización de datos ha sido la 4.4.1:

• jqGrid 4.4.1: http://www.trirand.com/blog/

Los ficheros necesarios para el correcto funcionamiento del componente son:

• jquery-1.8.0.js

• jquery-ui-1.8.23.custom.js

• jquery-ui-1.8.23.custom.css

• jqGrid-4.4.1.js

• rup.base-x.y.z.js

• rup.grid.jerarquia-x.y.z.js

Page 7: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 7/21

• theme.rup.grid.jerarquia-z.y.z.css

5. Invocación

Este componente se invocará sobre un elemento al que anteriormente se le haya aplicado el componente rup.grid. Por ejemplo:

$( "#id_elemento" ).rup_grid(properties);

...

$( "#id_elemento" ).rup_grid_jerarquia(properties);

Donde el parámetro “properties” es un objeto ( var properties = {}; ) o bien directamente la declaración de lo valores directamente. Sus posibles valores se detallan en el siguiente apartado.

6. Propiedades

A continuación se muestran los posibles parámetros de configuración que recibe el componente.

• expandColName: Nombre de la columna en la que será la que se contraiga/expanda. Puede definirse una columna que ya exista o una vacía para este propósito si así se desea:

• relatedColName: Nombre de la columna que marca la relación. Deberá ser la clave primaria de la tabla en Base de Datos.

• expandedClass: Clase de los elementos expandidos. Valor por defecto ui-icon-triangle-se. La imagen es

• unExpandedClass: Clase de los elementos contraídos. Valor por defecto ui-icon-triangle-e. La imagen es

• noChildClass: Clase de los elementos sin hijos. Valor por defecto ui-icon-none.

Page 8: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 8/21

• filterClass: Clase de los elementos que cumplen el filtro. Valor por defecto ui-icon-star. La imagen es

• resetEvents: Mapa en el que se indica en qué evento sobre qué objeto se invocará la función de reiniciar los valores de los elementos expandios La key del mapa será el evento en el que se produce y el value será un array con los identificadores de los objetos sobre los que se produce el evento. En el caso de que se desee ejecutar una función antes del evento esta deberá ir como primer elemento del array de objetos. Ejemplo:

resetEvents: { click: [ "bt_search_usuarioJerarquia" ,

"clean_search_usuarioJerarquia" ], keydown : [ function (event){ if (event.keyCode === 13) {

return false ; } }, "searchForm" ]

}

• resetMultiEvents: Mapa en el que se indica en qué evento sobre qué objeto se invocará la función de reiniciar los valores de los elementos seleccionados (cuando se utiliza la multiselección). La key del mapa será el evento en el que se produce y el value será un array con los identificadores de los objetos sobre los que se produce el evento. En el caso de que se desee ejecutar una función antes del evento esta deberá ir como primer elemento del array de objetos. Ejemplo:

resetMultiEvents: {

click: [ "bt_search_usuarioJerarquia" , "clean_search_usuarioJerarquia" ],

keydown : [ function (event){ if (event.keyCode === 13) { return false ; } }, "searchForm" ]

}

• parentNodesTooltip: Determina que se cree un tooltip con los diferentes nodos sobre la columna que se utiliza para la jerraquía de los elementos. Valor por defecto true. Ejemplo:

• parentNodesTooltipFnc: Permite sobrescribir la función que genera el tooltip con los diferentes nodos. Valor por defecto null.

• tooltipDelay: Tiempo en milisegundos que tarda el tooltip en aparecer. Valor por defecto 500.

• multiMenu: Determina el menú desplegable a mostrar junto a cada checkbox en el caso de la multiselección. Se recibe un JSON como parámetro indicando que opciones se mostrarán y cuales no.

o hijos: Permite seleccionar los hijos directos.

o descendientes: Permite seleccionar todos los hijos, independientemente del nivel al que pertenezcan.

Page 9: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 9/21

Su valor por defecto es:

multiMenu : { hijos : true , descendientes : true

}

• multiMenuDisabled: En la multiselección determina si se deshabilitan los menús desplegables de los elementos que no lo requieran (true) o si directamente no aparece el icono para desplegarlo (false). Valor por defecto true.

• multiboxonly: Determina, en caso afimativo, que para seleccionar una fila se debe pulsar en el checkbox. Si no, se podrá pulsar en cualquier celda para seleccionar la fila. Valor por defecto false.

7. Sobreescritura del theme

El componente aplica los estilos definidos en el fichero de estilos theme.rup.grid.jerarquia-x.y.z.css .

Sobre cada elemento que compone la jerarquía, se aplican los estilos:

.rup-grid-jerarquia

.rup-grid-jerarquia_level_X

La X indica el nivel dentro de la jerarquía comenzando por 1. El fichero de estilos define 10 estilos en los que la tabulación va aumentando progresivamente. Si se necesita cambiar estos estilos bastará con sobrescribirlos en un fichero propio de la aplicación.

Adicionalmente se pueden modificar los iconos mostrados para indicar si el nodo contiene hijos y está expandido o contraído, o si por el contrario el nodo no tiene hijos (ver apartado “6. Propiedades”).

Para aquellos elementos que cumplen el criterio de búsqueda introducido, existe un estilo (uno por nivel) para definir su posicionamiento: .rup-grid-jerarquia_filter_X

Adicionalmente existen ciertos estilos para el menú que se muestra en la selección múltiple que en caso de necesidad podrían ser sobrescritos aunque no se recomienda.

8. Requisitos (Base de Datos)

La relación de jerarquía se define a través de una columna adicional definida en la tabla cuyos elementos se quieren presentar en “forma de árbol”. La nueva columna tendrá como valor un dato que identificará inequívocamente a su padre, que podría ser su clave primaria (se recomienda el uso de claves subrogadas ya que dichos datos se enviarán como parámetro).

A continuación se muestra un ejemplo:

Page 10: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 10/21

9. Integración con UDA

En el apartado que nos ocupa, se explican la manera en que el componente se integra con UDA y con las diferentes capas.

9.1. Modelo

Se deberá añadir el atributo correspondiente a la columna que indica quien es su padre, si es que no se tiene ya (ver apartado “8. Requisitos (Base de Datos)”).

9.2. Acceso a datos

El tipo de retorno del método para la obtención de datos será List<Jerarquia< Model>> (salvo en el caso del conteo de datos que devolverá un Long ). Más adelante se explicará la manera de mapear los datos.

Primero definiremos la leyenda de los elementos empleados para detallar de manera genérica las diferentes implementaciones:

• columna � columna que se usa para la referencia (ej. id)

• columnaPadre � columna que define el elemento con el que se relaciona, es decir, su padre. Será nulo en los casos que no tenga padre [nivel 1] (ej. manager_id).

• columnaParentNode � columna que se utilizará para representar la estructura en el tooltip.

• tabla � tabla en la que se basa la jerarquía (ej. employee)

• aliasTabla � alias que se le dará a la la tabla en la parte from de la query (ej. … from employee e …)

9.2.1. Consulta

Para obtener los datos de la jerarquía se requiere una query que tenga la siguiente forma (se simplifica para facilitar la comprensión):

select …, -- Campos JERARQUIA level , decode ( select count (1) from [tabla] subquery where

subquery.[columnaPadre]= [aliasTabla].[columnaPadre ]), 0, 'false' , 'true' ) as HASCHILDREN,

Page 11: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 11/21

sys_connect_by_path(NOMBRE, '/' ) as PARENTNODES, sys_connect_by_path(ID, '/' ) as TREENODES, case when ( 1=0) then 'true' end as FILTER

from [tabla] [aliasTabla] where 1=1 -- Condiciones NEGOCIO and condiciones -- Relacion JERARQUIA start with [columnaPadre] is null connect by prior [columna] = [columnaPadre] order siblings by nombreColumna asc/desc

- El elemento condiciones se refiere a condiciones para la relación de tablas como a condiciones propias del negocio. Se puede utilizar para filtrar ciertos elementos siempre . Es opcional.

- Los elementos destacados en rojo corresponden a elementos propios del negocio, pasados como parámetros desde el controlador y por tanto variables.

- Los elementos que aparecen dentro de corchetes son datos requeridos por la jerarquía y se pasarán como parámetros.

Se han creado diversas funciones en el objeto Pagination de x38 para facilitar la gestión de queries.

A continuación se muestra un ejemplo del código que se debería implementar (destacados en negrita los elementos más importantes) para la obtención de los elementos jerarquizados:

//SELECT

StringBuilder sbSQL = new StringBuilder( "SELECT ..." ); //CONDICIONES (negocio) [OPCIONAL] StringBuilder businessFilters = new StringBuilder(); List<Object> businessParams = new ArrayList<Object>(); businessFilters.append( "AND xxx = ?" ); businessParams.add( "1" ); //FILTRO Map<String, ?> mapaWhere = this .getWhereLikeMap( model, false ); //JERARQUIA

sbSQL = pagination.getQueryJerarquia(sbSQL, mapaWhe re "COLUMNA", "COLUMNA_PADRE", "COLUMNA_PARENT_NODE", "TABLA" , "ALIAS_TABLA", businessFilters, businessParams);

//PAGINACIÓN if (pagination != null ) { sbSQL = pagination. getPaginationQueryJerarquia (sbSQL); } List<?> params = (List<?>) mapaWhere.get( "params" );

return this . jdbcTemplate .query(sbSQL.toString(), this . rwMapJerarquia , params.toArray());

La función que obtiene el número de elementos de la jerarquía (dato necesario para que el grid funcione correctamente) se obtendrá de una función idéntica a la expuesta salvo que:

1. La parte de la select sólo deberá tener “select count(1)”.

Page 12: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 12/21

sbSQL.append( "SELECT COUNT(1)" );

2. Se debe omitir la parte de paginación ya que se deben obtener todos los elementos

posibles. Este es el código a omitir:

//PAGINACIÓN if (pagination != null ) {

sbSQL = pagination.getPaginationQueryJerarquia(sbSQ L); }

3. El tipo de retorno será un número por lo que el retorno será:

return this . jdbcTemplate . queryForLong ( sbSQL.toString(), params.toArray());

En el caso de que no se necesiten condiciones de negocio bastará con obviar esas líneas e invocar a la función getQueryJerarquia del objeto Pagination sin los parámetros finales. Estas condiciones de negocio se incluirán en un StringBuilder comenzando directamente con un AND o un OR y los parámetros correspondientes en un List

9.2.2. Consulta con filtro

En los casos en los que se lance una búsqueda con ciertos criterios de filtrado la query se modifica y pasa a tener la siguiente estructura (se simplifica para facilitar la comprensión):

select …, -- Campos JERARQUIA level , decode ( select count (1) from [tabla] subquery where

subquery.[columnaPadre]= [aliasTabla].[columnaPadre ]), 0, 'false' , 'true' ) as HASCHILDREN,

sys_connect_by_path(NOMBRE, '/' ) as PARENTNODES, sys_connect_by_path(ID, '/' ) as TREENODES, case when ( 1=0) then 'true' end as FILTER

from [tabla] [aliasTabla] where 1=1 -- Condiciones NEGOCIO and condiciones -- Condiciones FILTRO and filtro -- Subquery PADRES or (

select count (1) from [tabla] where 1=1 -- Condiciones FILTRO

and filtro -- Condiciones NEGOCIO

and condiciones connect by prior [columna] = [columnaPadre] ) > 0 -- Subquery HIJOS

or [columna] in (

Page 13: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 13/21

select substr(sys_connect_by_path([columna], '/' ), INSTR(sys_connect_by_path([columna], '/' ), '/' ,-1)+1)

from [tabla] where 1=1 -- Condiciones NEGOCIO

and condiciones start with [columna] in ( select ID from [tabla]

where 1=1 -- Condiciones FILTRO

and filtro )

connect by prior [columna] = [columnaPadre] ) -- Relacion JERARQUIA start with [columnaPadre] is null connect by prior [columna] = [columnaPadre] order siblings by nombreColumna asc/desc

El código a implementar es el mismo que en el caso de que no haya filtro.

9.2.3. Consulta elementos contraídos

Cuando se contrae alguno de los elementos para que no se muestren sus hijos la query a ejecutarse varía levemente. Simplemente se añade una condición extra a la parte de “Relación JERARQUIA”. El propio componente se encarga de enviar el dato requerido como parámetro de la query. A continuación se detalla la condición que se añade:

-- Relacion JERARQUIA start with [columnaPadre] is null connect by prior [columna] = [columnaPadre] and [columnaPadre] not in (?) order siblings by nombreColumna asc/desc

9.3. Mapeador de datos [RowMapper]

Se deberá modificar el RowMapper generado por UDA para la conversión del modelo de BD (ResultSet) a un Bean (POJO), para acomodarse a los nuevos atributos necesarios. Se utilizará la clase Jerarquia <T> incluida en x38.

Se adjunta un ejemplo en el que se utiliza la clase Model como ejemplo:

private RowMapper<Jerarquia< Model>> rowMapper = new RowMapper< Jerarquia< Model>>() {

public Jerarquia<Model> mapRow(ResultSet resultSet, int rowNum) throws SQLException {

Model model = new Model();

Page 14: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 14/21

//setters del negocio (generados por UDA) Jerarquia<Model> j = new Jerarquia<Model>(); j.setModel(model); j.setLevel(resultSet.getBigDecimal( "LEVEL" ).intValue()); j.setHasChildren(

Boolean. parseBoolean(resultSet.getString( "HASCHILDREN")) ); j.setParentNodes(resultSet.getString( "PARENTNODES")); j.setFilter(Boolean. parseBoolean(resultSet.getString( "FILTER" )));

return j; }

};

9.4. Controlador

La jerarquía normal permite navegar por los diferentes niveles de manera descendente. Por defecto, en la primera búsqueda se obtendrán los elementos del nivel 1. Aquellos elementos que tengan hijos tendrán un elemento diferenciador del resto. Dependiendo de la declaración del componente, al pinchar en dicho elemento se contraerá/expandirá ocultando/mostrando sus elementos “hijo”.

La gestión de los elementos a expandir, se realiza mediante el envío automático de un parámetro tree con los identificadores de los elementos que se deben expandir que envía automáticamente el componente y se gestiona mediante el objeto Pagination de x38.

Para versiones antiguas de aplicaciones de UDA en las que los parámetros del Pagination se obtenían de la request se debería hacer lo siguiente:

Pagination pagination = new Pagination(); pagination.setPage(

Long. valueOf(request.getParameter( "page" ))); pagination.setRows(

Long. valueOf(request.getParameter( "rows" ))); pagination.setSort(request.getParameter( "sidx" )); pagination.setAscDsc(request.getParameter( "sord" )); pagination.setTree(request.getParameter( "tree" ));

Para versiones nuevas de aplicaciones de UDA la gestión del parámetro es automática ya que Spring realiza el setter de la propiedad siempre que en la declaración del método se reciba el parámetro de la siguiente manera:

public @ResponseBody JQGridJSONModel getAllJQGrid( @ModelAttribute Model filterModel, @ModelAttribute Pagination pagination )

La gestión correcta de los elementos mostrados en pantalla por el componente grid requiere de una modificación en el Controller generado por defecto por UDA destacado en negrita:

@RequestMapping (method = RequestMethod. GET, headers={ "JQGridModel=true" }) public @ResponseBody JQGridJSONModel getAllJQGrid( @ModelAttribute Model

filterModel, @ModelAttribute Pagination pagination){

List< Jerarquia <Model>> listModel = this .modelService .findAllLike

Page 15: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 15/21

(filterModelJerarquia, pagination); Long recordNum = this . modelService .findAllLikeCount (filterModel,

pagination); ModelController. logger.info( "[GET - jqGrid] : Obtener Jerarquia" ); return new JQGridJSONModel(pagination, recordNum,

listModelJerarquia); }

9.5. Serialización de datos

El correcto funcionamiento de la jerarquía requiere que se incluya el objeto Jerarquia de x38 dentro de los elementos a procesar con el serializador de UDA.

Para ello en el fichero jackson-config.xml se deberá incluir la siguiente entrada:

<entry key ="#{T(com.ejie.x38.dto.Jerarquia)}" value-ref ="customSerializer" />

9.6. Presentación

Las modificaciones a realizar en la capa de presentación se limitan a añadir ciertas columnas nuevas al grid sobre el que se quiere generar una jerarquía:

colNames: [ ..., "level" , "hasChildren" , "parentNodes" , "filter" ], colModel: [ ..., {name: "level" , hidden: true },

{name: "hasChildren" , hidden: true }, {name: "parenNodes" , hidden: true }, {name: "filter" , hidden: true }

]

Una vez acabada la declaración del grid se realizará la declaración de la jerarquía:

$( "#NOMBRE_GRID").rup_grid_jerarquia({ expandColName : "numexpediente" , parentColName : "numexpediente" ,

resetEvents: { click: [ "bt_search_expedientes" ,

"clean_search_expedientes" ], keydown : [ "searchForm" ]

} });

10. Jerarquía con selección múltiple

El componente jerarquía permite la selección múltiple para facilitar la gestión de los elementos. A continuación de muestra una captura:

Page 16: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 16/21

A continuación se detallan los cambios necesarios para que la jerarquía incluya selección múltiple:

1. Indicar que el grid deberá tener selección múltiple:

multiselect: true ,

2. Se incluirá el tratamiento de la nueva columna en el maleador de datos [RowMapper]:

jerarquia.setTreeNodes(resultSet.getString( "TREENODES"));

3. Tratamiento del nuevo parámetro para aplicaciones de UDA antiguas:

Pagination pagination = new Pagination(); ... pagination.setMult(request.getParameter( "mult" ));

NOTA: Si el objeto Pagination se utiliza con la anotación @ModelAttribute este paso no es necesario.

4. Se añadirá una columna más en el grid:

colNames: [ ..., "treeNodes" ], colModel: [ ..., {name: "treeNodes" , hidden: true } ]

10.1. Menú desplegable

En la jerarquía con multiselección se muestra un menú desplegable en cada una de las filas de la tabla para realizar operaciones a partir de ese punto en la jerarquía y un menú desplegable general a aplicar a todos los elementos de la tabla:

• Menú por fila:

Page 17: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 17/21

Las opciones podrán variar en función del contexto. Por ejemplo no se mostrarán las opciones de “desmarcar” si previamente no se han “marcado“.

En aquellos elementos que no tengan hijos no podrá desplegarse el menú y por defecto saldrá deshabilitado, aunque puede configurarse para que ni siquiera se muestre el icono de despliegue (ver atributo multiMenu).

Ejemplo de menú deshabilitado

A continuación se hace un resumen de las funcionalidades:

o Marcar hijos: Selecciona los hijos directos (nivel directamente inferior) del elemento sobre el que se despliega el menú.

o Marcar descendientes: Selecciona todos los hijos del elemento sobre el que se despliega independiente del nivel al que pertenezcan.

o Desmarcar hijos: Deselecciona los hijos directos (nivel directamente inferior) del elemento sobre el que se despliega el menú.

o Desmarcar descendientes: Deselecciona todos los hijos del elemento sobre el que se despliega independiente del nivel al que pertenezcan.

• Menú general:

El menú desplegable sirve para seleccionar todas las filas de la tabla. En el caso de que todas estén seleccionadas, la opción a mostrar será “Desmarcar todos”.

10.2. Edición múltiple / Eliminación múltiple

El soporte de la edición múltiple y la eliminación múltiple cuando se utiliza la jerarquía depende de la implementación de un método que gestione internamente la paginación de la selección. A continuación se detallan los pasos para implementar dicho método.

10.2.1. Acceso a datos

El tipo de retorno del método para la obtención de datos será TreeMap<String, TreeMap<String, String>>.

Primero definiremos la leyenda de los elementos empleados para detallar de manera genérica las diferentes implementaciones:

Page 18: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 18/21

• columna � columna que se usa para la referencia (ej. id)

• columnaPadre � columna que define el elemento con el que se relaciona, es decir, su padre. Será nulo en los casos que no tenga padre [nivel 1] (ej. manager_id).

• tabla � tabla en la que se basa la jerarquía (ej. employee)

• aliasTabla � alias que se le dará a la la tabla en la parte from de la query (ej. … from employee e …)

10.2.2. Consulta

Para obtener los datos de la jerarquía se requiere una query que tenga la siguiente forma:

select * from ( select [columna] as pk, ceil( rownum/?) page, case when ( mod( rownum,?)= 0 ) then ? else TO_CHAR(mod( rownum,?)) end as line

from ( select [columna], [columaPadre], nombreColumna , rownum from [tabla]

-- Relacion JERARQUIA start with [columnaPadre] is null connect by prior [columna] = [columnaPadre] order siblings by nombreColumna asc/desc

) [aliasTabla]

where 1=1 -- Relacion JERARQUIA start with [columnaPadre] is null connect by prior [columna] = [columnaPadre] order siblings by nombreColumna asc/desc

) -- Registros SELECCIONADOS where ( 1,pk) in (( 1,?),( 1,?),...)

NOTA: Por simplificar la query no se ha incluido el ejemplo en el que existen criterios de filtrado y/o negocio.

- Los elementos destacados en rojo corresponden a elementos propios del negocio, pasados como parámetros desde el controlador y por tanto variables.

- Los elementos que aparecen dentro de corchetes son datos requeridos por la jerarquía y se pasarán como parámetros.

Se han creado diversas funciones en el objeto Pagination de x38 para facilitar la gestión de queries.

A continuación se muestra un ejemplo del código que se debería implementar (destacados en negrita los elementos más importantes) para la obtención de los elementos jerarquizados:

//SELECT StringBuilder sbSQL = new StringBuilder( "" ); //CONDICIONES (negocio) [OPCIONAL] StringBuilder businessFilters = new StringBuilder(); List<Object> businessParams = new ArrayList<Object>();

Page 19: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 19/21

List<String> businessNames = new ArrayList<String>(); businessFilters.append( "AND t1.EJIE = ?" ); businessParams.add( "1" ); businessNames.add( "EJIE" ); //FILTRO

Map<String, ?> mapaWhere = this .getWhereLikeMap(usuarioJerarquia, false ); //SELECTED sbSQL = pagination.getQuerySelectedGrid(sbSQL, mapa Where, model "COLUMNA", "COLUMNA_PADRE", "TABLA" , "ALIAS_TABLA", businessFilters, businessParams);

List<?> params = (List<?>) mapaWhere.get( "params" );

return this . jdbcTemplate .query(sbSQL.toString(), pagination. selectedExtractorGrid , params.toArray());

10.2.3. Controlador

La gestión de los elementos seleccionados requiere el siguiente método:

@RequestMapping (method = RequestMethod. GET, headers={ "JQGridModel_selected=true" })

public @ResponseBody TreeMap<String, TreeMap<String, String>> getAllJQGridSelected ( @ModelAttribute UsuarioJerarquia

filterUsuarioJerarquia, @ModelAttribute Pagination pagination){

return this . usuarioJerarquiaService .findAllLikeSelected( filterUsuarioJerarquia, pagination);

}

10.2.4. Presentación

No se requiere de ningún cambio y/o implementación ya que es interno de la jerarquía.

11. Integración con x38

En este apartado se comentan los cambios más destacados en la librería x38 para incluir funciones que faciliten la integración de la jerarquía en UDA.

11.1. Pagination

A continuación se detallan los métodos del bean Pagination para facilitar la creación de las queries relativas a la jerarquía.

• public StringBuilder getPaginationQueryJerarquia (StringBuilder query)

Page 20: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 20/21

Modifica la query recibida como parámetro para filtrar los elementos según los criterios de paginación.

• public StringBuilder getQueryJerarquia (StringBuilder query, Map<String, ?> mapaWhere, String columna, String columnaPadre, String columnaParentNodes, String tabla, String aliasTabla )

Modifica la query recibida como parámetro y añade los parámetros de la query a la referencia mapaWhere.

� query � Comienzo de la query (Ej. “select xxx, yyyy “). � mapaWhere � Mapa con las condiciones de filtrado (generado por UDA). � columna � Nombre de la columna que se relaciona. � columnaPadre � Nombre de la columna con la que se relaciona. � columnaParentNodes � Nombre de la columna para mostrar en el tooltip. � tabla � Nombre de la tabla que implementa la relación. � aliasTabla � Alias asociado a la tabla en la query.

• public StringBuilder getQueryJerarquia (StringBuilder query, Map<String, ?> mapaWhere, String columna, String columnaPadre, String columnaParentNodes, String tabla, String aliasTabla , StringBuilder joins)

Modifica la query recibida como parámetro y añade los parámetros de la query a la referencia mapaWhere.

� joins � Relación entre tablas.

• public StringBuilder getQueryJerarquia (StringBuilder query, Map<String, ?> mapaWhere, String columna, String columnaPadre, String columnaParentNodes, String tabla, String aliasTabla , StringBuilder joins, StringBuilder businessFilters, List<?> busin essParams)

Modifica la query recibida como parámetro y añade los parámetros de la query a la referencia mapaWhere cuando se requieren condiciones de negocio.

� businessFilters � Literal con las condiciones. � businessParam s� Parámetros (datos) de las condiciones.

• public StringBuilder getQueryJerarquiaCount (StringBuilder query, Map<String, ?> mapaWhere, String columna, String co lumnaPadre, String columnaParentNodes, String tabla, String aliasTabla )

Modifica la query recibida como parámetro y añade los parámetros de la query a la referencia mapaWhere para el recuento de elementos.

• public StringBuilder getQueryJerarquiaCount (StringBuilder query, Map<String, ?> mapaWhere, String columna, String co lumnaPadre, String columnaParentNodes, String tabla, String aliasTabla , StringBuilder businessFilters, List<?> businessParams)

Page 21: UDA-Componentes RUP. Jerarquía  (v2.1.1 deprecado)

Componentes RUP – Jerarquía 21/21

Modifica la query recibida como parámetro y añade los parámetros de la query a la referencia mapaWhere para el recuento de elementos cuando se requieren condiciones de negocio.

• public StringBuilder getQuerySelectedGrid (StringBuilder query, Map<String, ?> mapaWhere, Object bean, String colum na, String columnaPadre, String columnaParentNodes, String tab la, String aliasTabla)

Crea una query para la obtención de la estructura necesaria para soportar la edición múltiple y el borrado múltiple en la jerarquía.

• public StringBuilder getQuerySelectedGrid (StringBuilder query, Map<String, ?> mapaWhere, Object bean, String colum na, String columnaPadre, String columnaParentNodes, String tab la, String aliasTabla, StringBuilder businessFilters, List<?> businessParams, List<?> businessNames)

Crea una query para la obtención de la estructura necesaria para soportar la edición múltiple y el borrado múltiple en la jerarquía cuando se requieren condiciones de negocio.

• public ResultSetExtractor<TreeMap<String, TreeMap<String, String>>> selectedExtractorGrid = new ResultSetExtractor<TreeMap<String, TreeMap<String, String>>>(){ ... }

Clase que gestiona el resultado de la query para la obtención de la estructura necesaria para soportar la edición múltiple y el borrado múltiple en la jerarquía que requiere la presentación.

11.2. Jerarquía

A continuación se detallan los campos del bean Jerarquía para la transmisión de los datos de la jerarquía.

@JsonUnwrapped private T model ; private int level ; private boolean hasChildren ; private String parentNodes ;

private String treeNodes ; private boolean filter ;

model � Bean utilizado para el Modelo de datos. Contiene los datos del negocio.

level � Nivel dentro de la jerarquía. hasChildren � Indicador de si contiene hijos o no. parentNodes � Lista de los padres hasta el nodo actual (literal para el tooltip). treeNodes � Lista de los padres hasta el nodo actual (valor para la selección múltiple). filter � Indicador de si el elemento cumple el filtro o no.