Guía de referencia: Modelo | Vista | Datos tabulares | Mapeo objeto/relacional | Controladores | Aplicación | Personalización

Aplicación

Una aplicación es el software que el usuario final puede usar. Hasta ahora hemos visto como definir las piezas que forman una aplicación (los componentes y las acciones principalmente), ahora vamos a ver como ensamblarlas para crear aplicaciones.
La definición de una aplicación OpenXava se hace en el archivo aplicacion.xml que encontramos en el directorio xava de nuestro proyecto.
La sintaxis de este archivo es:
<aplicacion
    nombre="nombre"                   <!-- 1 -->
    etiqueta="etiqueta"               <!-- 2 -->
>
    <modulo-defecto ... /> ...        <!-- 3  Nuevo en v2.2.2 -->
    <modulo ... /> ...                <!-- 4 -->
</aplicacion>
  1. nombre (obligado): Nombre de la aplicación.
  2. etiqueta (opcional): Mucho mejor usar archivos i18n.
  3. modulo-defecto (uno, opcional): Nuevo en v2.2.2. Para definir los controladores para los módulos por defecto (generados automáticamente para cada componentes).
  4. modulo (varios, opcionales): Cada módulo es ejecutable directamente por el usuario final.
Se ve claramente que una aplicación es un conjunto de módulos. Vamos a ver como se define un módulo:
<modulo
    nombre="nombre"                  <!--  1 -->
    carpeta="carpeta"                <!--  2 -->
    etiqueta="etiqueta"              <!--  3 -->
    descripcion="descripcion"        <!--  4 -->
>
    <var-entorno ... /> ...          <!--  5 -->
    <modelo ... />                   <!--  6 -->
    <vista ... />                    <!--  7 -->
    <vista-web ... />                <!--  8 -->
    <tab ... />                      <!--  9 -->
    <controlador ... /> ...          <!-- 10 -->
    <controlador-modo ... />         <!-- 11 -->
    <doc ... />                      <!-- 12 -->
</modulo>
  1. nombre (obligado): Identificador único del módulo dentro de esta aplicación.
  2. carpeta (opcional): Carpeta en la cual residirá el módulo. Es una sugerencia para clasificar los módulos. De momento es usado para generar la estructura de carpetas para JetSpeed2 pero su uso puede ser ampliado en el futuro. Podemos usar / o . para indicar subcarpetas (por ejemplo, "facturacion/informes" o "facturacion.informes").
  3. etiqueta (opcional): Nombre corto que se visualizará al usuario. Mucho mejor usar archivos i18n.
  4. descripcion (opcional): Descripción larga que se visualizará al usuario.
  5. var-entorno (varias, opcional): Permite definir una variable con un valor que podrán ser accedidos posteriormente desde las acciones. Así podemos tener acciones configurables según el módulo.
  6. modelo (uno, opcional): Indica el nombre de componente usado en este módulo. Si no lo ponemos estamos obligados a usar vista-web.
  7. vista (una, opcional): El nombre de la vista que se va a usar para dibujar el detalle. Si no lo ponemos usará la vista por defecto para ese modelo.
  8. vista-web (una, opcional): Nos permite indicar nuestro propia página JSP que será usada como vista.
  9. tab (uno, opcional): El nombre del tab que usará la el modo lista. Si no lo ponemos usará el tab por defecto.
  10. controlador (varios, opcional): Controladores con las acciones que aparecen en el módulo al iniciarse.
  11. controlador-modo (uno, opcional): Permite definir el comportamiento para pasar de detalle a lista, o bien definir un módulo que no tenga detalle y lista. Nuevo en v4m5: Hay un nuevo modo, split. A partir de v4m5 los modos disponible son Mode (detalle - lista - split), DetailList, DetailOnly, ListOnly y SplitOnly.
  12. doc (uno, opcional): Es exclusivo con todos los demás elementos. Permite definir módulos que solo contienen documentación, no lógica. Útil para generar portlets informativos para nuestras aplicaciones.

Un módulo típico

Definir un módulo sencillo puede ser como sigue:
<aplicacion nombre="Gestion">
    <modulo nombre="Almacen" carpeta="almacen">
        <modelo nombre="Almacen"/>
        <controlador nombre="Typical"/>
        <controlador nombre="Almacen"/>
    </modulo>
    ...
</aplicacion>
En este caso tenemos un módulo que nos permite hacer altas, bajas modificaciones, consultas, listados en PDF y exportación a Excel de los datos de los almacenes (gracias a Typical) y acciones propias que aplican solo a almacenes (gracias al controlador Almacen). En el caso en que el sistema genere una estructura de módulos (actualmente no soportado) este módulo estará en la carpeta "almacen".
Para ejecutar este módulo podemos desde nuestro navegador escribir:
http://localhost:8080/Gestion/modules/Almacen
También se genera un portlet para poder desplegar el módulo como un portlet JSR-168/286 en un portal Java.
Puedes ver la definición del controlador Typical en OpenXava/xava/default-controllers.xml, donde también puedes encontrar otros controladores útiles tal como TypicalNotResetOnSave, TypicalNewOnInit o TypicalRealExcel con un comportamiento ligeramente diferente.

Módulos por defecto (nuevo en v2.2.2)

OpenXava asume un módulo por defecto para cada componente en la aplicación, aunque el módulo no se defina explícitamente en aplicacion.xml.
Es decir, si definimos un componente Factura.java, podemos abrir nuestro navegador e ir a:
http://localhost:8080/Gestion/modules/Factura
También un portlet es generado para permitir desplegar el módulo como un portlet JSR-168 en un portal Java.
Y todo esto sin necesidad de definirlo en aplicacion.xml.
El controlador para estos módulos por defecto será Typical, pero podemos cambiar este valor por defecto usando el elemento modulo-defecto en aplicacion.xml, de esta manera:
<aplicacion nombre="Gestion">
 
    <modulo-defecto>
        <controlador nombre="MantenimientoGestion"/>
    </modulo-defecto>
 
</aplicacion>
En este caso todos los módulos por defecto de la aplicación Gestion tendrán el controlador MantenimientoGestion asignado a ellos.
Si queremos que cierto módulo no use estos controladores por defecto, tenemos dos opciones:
  1. Definir un controlador en nuestro controladores.xml con el mismo nombre que el componente.
  2. Definir explícitamente el módulo en aplicacion.xml, tal y como se explica arriba.
Resumiendo, si definimos un componente, llamado Cliente por ejemplo, entonces tenemos un módulo llamado Cliente, y también un portlet. Este módulo se definirá de una de la siguiente formas:
  1. Si definimos un módulo llamado Cliente en aplicacion.xml entonces este módulo será el válido, si no...
  2. Si definimos un controlador llamado Cliente en controlladores.xml un módulo será generado usando el controlador Cliente como controlador y el componente Cliente como modelo, si no...
  3. Si definimos un elemento modulo-defecto en nuestro aplicacion.xml entonces un modulo se generará usando los controladores en modulo-defecto y el componente Cliente como modelo, si no ...
  4. un módulo con Typical como controlador y Cliente como modelo se asumirá en última instancia.

Módulo con solo detalle

Un módulo con solo modo detalle, sin lista se define así (nuevo en v4m5):
<modulo nombre="FacturaSinLista">
    <modelo nombre="Factura"/>
    <controlador nombre="Typical"/>
    <controlador-modo nombre="DetailOnly"/>    <!-- 1 -->
</modulo>
Simplemente usa DetailOnly (1) como mode-controller.
Si estás usando una versión anterior a v4m5 has de definir los módulos de solo detalle de esta forma:
<modulo nombre="FacturaSinLista">
    <modelo nombre="Factura"/>
    <controlador nombre="Typical"/>
    <controlador-modo nombre="Void"/>    <!-- 1 -->
</modulo>
El controlador de modo Void (1) es para que no aparezcan los vínculos "detalle – lista"; en esta caso el módulo usa por defecto el modo detalle únicamente. Aunque obsoleta esta forma todavía está soportada.

Módulo con solo lista

Un módulo con solo modo lista, sin detalle se define así (nuevo en 4m5):
<modulo nombre="FamiliaSoloLista">
    <var-entorno nombre="XAVA_LIST_ACTION" valor=""/>    <!-- 1  Nuevo en v2.0.4 -->
    <modelo nombre="Familia"/>
    <controlador nombre="Typical"/>
    <controlador-modo nombre="ListOnly"/>               <!-- 2 -->
</modulo>
El controlador de modo ListOnly (2) es para que no aparezcan los vínculos "detalle – lista" e inicializar el módulo en modo detalle. Poniendo XAVA_LIST_ACTION a cadena vacía (1) el vínculo de detalle en cada fila no aparece (nuevo en v2.0.4).
Si estás usando una versión anterior a v4m5 has de definir los módulos de solo lista de esta forma:
<modulo nombre="FamiliaSoloLista">
    <var-entorno nombre="XAVA_LIST_ACTION" valor=""/>
    <modelo nombre="Familia"/>
    <controlador nombre="Typical"/>
    <controlador nombre="ListOnly"/>                     <!-- 1 -->
    <controlador-modo nombre="Void"/>                   <!-- 2 -->
</modulo>
El controlador de modo Void (2) es para que no aparezcan los vínculos "detalle – lista". Además al definir ListOnly (1) como controlador el módulo cambia a modo lista al iniciar, por lo tanto éste es un módulo de solo lista. Aunque obsoleta esta forma todavía está soportada.

Módulo de documentación

Un módulo de documentación solo visualiza un documento HTML. Es fácil de definir:
<modulo nombre="Descripcion">
    <doc url="doc/descripcion" idiomas="es,en"/>
</modulo>
Este módulo muestra el documento web/doc/descripcion_en.html o web/doc/descripcion_es.html según el idioma del navegador. Si el idioma del navegador no es inglés o español entonces asume español (el primer idioma especificado). Si no especificamos idioma entonces el documento a visualizar será web/doc/descripcion.html.
Esto es útil para portlets informativos. Este tipo de módulos no tiene efecto fuera de un portal.

Módulo de solo lectura

Un módulo de solo lectura, es decir solo para consultar no para modificar, puede ser definido como sigue:
<modulo nombre="ConsultaClientes">
    <var-entorno nombre="XAVA_SEARCH_ACTION" valor="CRUD.searchReadOnly"/>  <!-- 1 -->
    <modelo nombre="Cliente"/>
    <controlador nombre="Print"/>                                           <!-- 2 -->
</modulo>
Usando CRUD.searchReadOnly (1) el usuario no puede editar los datos, y usando solo el controlador Print(2) (o
(o ExtendedPrint a partir de v4.6)
), sin CRUD ni Typical, las acciones para grabar, borrar, etc. no están presentes. Esto es un simple módulo de consulta.

La sintaxis de aplicacion.xml no tiene mucha complicación. Podemos ver más ejemplos en OpenXavaTest/xava/application.xml.