Instrumentación Hoy_ INTERPRETAR EL DIAGRAMA UNIFILAR GENERAL DE UNA PLANTA I...
UDA-Componentes RUP. Jerarquía (v2.1.1 deprecado)
1. 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
2. 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:
3. 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
5. 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).
6. 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
7. 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.
8. 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.
9. 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:
10. 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,
11. 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, mapaWhere
"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)”.
12. 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(sbSQL);
}
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 (
13. 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();
14. 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
15. 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:
16. 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:
17. 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:
18. 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>();
19. 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, mapaWhere, 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)
20. 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<?> businessParams)
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 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 para el recuento de elementos.
• public StringBuilder getQueryJerarquiaCount(StringBuilder query,
Map<String, ?> mapaWhere, String columna, String columnaPadre, String
columnaParentNodes, String tabla, String aliasTabla, StringBuilder
businessFilters, List<?> businessParams)
21. 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 columna, String
columnaPadre, String columnaParentNodes, String tabla, 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 columna, String
columnaPadre, String columnaParentNodes, String tabla, 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.