Recorrido de vectores y bucle condicional con tags de Struts2

Cuando se utiliza Struts2 para la parte de pintado de datos con ficheros JSP se puede hacer del modo Java (metiendo snippets de código Java entre las etiquetas JSP), que es poco recomendable, o utilizar los tags de Struts2 para JSP, que es una opción más recomendable.

Desgraciadamente el uso de los tags de Struts2 requiere conocer un poco la sintáxis que utilizan y cómo acceder a los valores con sintaxis OGNL en cada momento.

En este ejemplo tendremos dos ArrayList diferentes que queremos pintar alternativamente, decidiendo en cada momento si tenemos que pintar uno u otro. Es decir, la concatenación de los bucles es lo que vamos a pintar, pero intercalados, aunque manteniendo el orden. Es decir:

Vector1: 1; 2 ; 3 ;4
Vector 2: a; b; c; d
Resultado: 1;2;a;b;c;3;d;4 (u otras combinaciones)

Básicamente el algoritmo consiste en:

  • Tomar la longitud del vector1 y del vector 2
  • Hacer un bucle que tenga como iteraciones la suma de ambos vectores.
  • Por cada iteración decidir qué elemento se pinta, si el que toque del vector 1 o el del vector 2.
  • Si se pinta el vector 1, pintar el valor al que apunta su contador e incrementar 1
  • Si se pinta el vector 2, pintar el valor al que apunta su contador e incrementar 1

Para ello vamos a crear las siguientes variables utilizando el tag “s:set” un contador para el vector 1 y otro contador para el vector 2; también guardaremos la longitud total del bucle, es decir, la suma de la longitud de ambos vectores.

Para el bucle usaremos el tag s:iterator , que irá desde el valor 1 hasta la suma de los vectores.

Dentro del bucle simplemente tendremos una condición que nos indicará si debemos pintar valores del vector 1 o del 2. La condición es lo de menos. En nuestro caso los contenidos del vector comprueba un valor que define el orden en el que se tiene que pintar los elementos del vector 1 en el total: si el elemento n-ésimo tiene el orden coincidente con el bucle lo pinta, de otro modo pinta el vector de datos.

Lo más importante es ver el acceso a las variables definidas en s:set, indicando a través del attr. Y cómo se puede indicar que el puntero de un vector puede estar basado en el valor de una variable.
Los pasos son los siguientes:

1. Definimos las variables que contienen los índices de los vectores. Los inicializamos a 0, como no podría ser de otro modo:

<s:set var ="contador_vector1" value="%{0}" scope="page" />
<s:set var ="contador_vector2" value="%{0}" scope="page" />

2. Calculamos el recorrido que tiene que hacer el bucle como suma de las longitudes. Hay que saber también la longitud del vector 1 para no salir de los límites en la comparación.

<s:set var="elementos_totales" value="vector1.size+vector2.size" scope = "page"></s:set>
<s:set var="elementos_totales_vector1" value ="syllabus.bloquesList.size" scope = "page" />

3. Comenzamos el bucle. El bucle va desde el elemento 1 al número de elementos totales. Ojo, comenzamos en el valor 1 porque vamos a contar el orden de aparición de elementos para la condición de pintar uno u otro. Se podría haber comenzado en el valor 0

<s:iterator begin="1" end="%{#attr.elementos_totales}">

Lo más destacable es el acceso a la variable creada mediante el tag set. Se hace usando la sintaxis: %{#attr.nombre_variable}

6. Condición en el bucle para saber si tenemos que pintar en la iteración los valores de un vector o los valores de otro:

<s:if test="(#attr.contador_vector1<#attr.elementos_totales_vector1)&&(vector1[#attr.contador_vector1].orden == top)">

Nótese que el valor con el que se hace la comparación usando el tag if es el valor top, que contiene el valor del contador del bucle en ese momento.
También es destacable la forma de acceder al vector utilizando la sintaxis vector[#attr.contador]

7. Empujamos al tope de la pila OGNL el valor del vector mediante el tag push

<s:push value="vector1[#attr.contador_vector1]">

8. Se acceden a las propiedades del valor empujado normalmente:

<li>Valor:<s:property value="pk1" /></li>

9. Se incrementa el puntero del vector que hemos pintado. Es muy importante dejar espacios entre el signo de suma y los valores para que el parser interprete una suma de enteros y no una cadena referida a una variable.

<s:set var="contador_vector1" value="%{1 + #attr.contador_vector1}"/>

Se procede de la misma manera para el otro vector en el caso de que la sentencia if de Struts2 de como resultado false y vaya por el camino del s:else.

En definitiva mediante este ejemplo se han visto algunos detalles intersantes de cómo hacer con tags de Struts2 las clásicas operaciones de recorrido de vectores usando bucles con contador e índices para acceder.

Código fuente completo:

<s:set var ="contador_vector1" value="%{0}" scope="page" />
<s:set var ="contador_vector2" value="%{0}" scope="page" />

<s:set var="elementos_totales" value="vector1.size+vector2.size" scope = "page"></s:set>
<s:set var="elementos_totales_vector1" value ="syllabus.bloquesList.size" scope = "page" />

<s:iterator begin="1" end="%{#attr.elementos_totales}">
     <s:if test="(#attr.contador_vector1<#attr.elementos_totales_vector1)&&(vector1[#attr.contador_vector1].orden == top)">
          <s:push value="vector1[#attr.contador_vector1]">
               <li>Valor:<s:property value="pk1" /></li>
          </s:push>
          <s:set var="contador_vector1" value="%{1 + #attr.contador_vector1}"/>
      </s:if>
      <s:else>
           <s:push value="vector2[#attr.contador_vector2]">
                <li>Valor:<s:property value="pk1" /></li>
           </s:push>
           <s:set var="contador_vector2" value="%{1 + #attr.contador_vector2}"/>
      </s:else>
 <s:iterator>

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s