jueves, 25 de abril de 2013

ADF 11g: Importación y exportación de ficheros CSV

Una de las funcionalidades requeridas suele ser la importación/exportación de información de base de datos en un archivo CSV.

Link to english version.
Link to download sample application. (Broken Link)

CSV Sample file
En esta solución se hace uso de un código sencillo y genérico usando cualquier iterador (DCIteratorBinding) configurado en la vista para extraer/importar información independientemente de el número y nombre de las columnas de la tabla de base de datos sobre la que itera.

El ejemplo contiene la siguiente configuración:
  • Esta preparado y habilitada la carga de ficheros. Esta configuración  se consigue configurando Trinidad en web.xml y habilitando la subida de ficheros en el tag af:form.

    Configuración: web.xml
    Habilitar la subida de ficheros.
  • El Task Flow contiene un Manage Bean (CSVProcessor) encargado de la gestión de los ficheros CSV y de los mecanismos de importación/exportación:
    • Posee una variable inyectada y configurable para establecer el nombre del DCIteratorBinding.
      Inyección del iterador a usar
    • El método de carga del fichero genera un objeto de tipo CSVFile que se usará más adelante para la importación. Usa oracle.adf.model.adapter.dataformat.CSVHandler para la lectura y escritura en la estructura de datos que se desee. En este caso un Map<String,String>
      Fragmento del CSVHandler para leer CSV files
    • El método de export es usado por af:fileDownloadActionListener. Genera un fichero CSV en el siguiente formato:

      Fragmento de la exportación
      • La primera fila se corresponde con el nombre de las columnas definidas en la tabla.
      • Las demás filas contienen la información separadas por un carácter especial . En el caso del ejemplo "|".
    • El método import realiza una limpieza total y carga de los datos procedentes del fichero. Ayudándose de que la primera fila son exáctamente los nombres de las columnas de la tabla vuelve a cargar los datos a través del DCIteratorBinding y persistirlos en base de datos.

      Fragmento de código de la importación
  • La UI permite usar el API de manera intuitiva. Cargar el fichero a través del inputFile, exportar la tabla e importar los datos a través del fichero.

    Interfaz del sample
El ejemplo solo es una ayuda para el tratamiento de ficheros CSV, no incluye tratamiento de errores o comportamientos inesperados.
Además, el ejemplo usa su propio esquema y tabla de base de datos llamada Samples la cual es facilmente reproducible en una base de datos Oracle XE mediante JDeveloper.

martes, 23 de abril de 2013

BUG: WebCenter Spaces MDS vs Custom Task Flow

El otro día encontré un error muy curioso durante el despliegue y configuración de un Custom Task Flow en una plataforma WebCenter Portal : Spaces 11.1.1.6.

Enlace versión inglés
Link to english version

Durante la configuración de los parámetros del Custom Task Flow y al hacer click en Save de Oracle Composer NO persistía los cambios en el MDS. Es más, el Task Flow ni se registraba en la página.

En las trazas de WC_Spaces me encontré el siguiente error:

java.lang.IllegalArgumentException: Invalid UUID string: df
    at java.util.UUID.fromString(UUID.java:204)
    at oracle.mds.internal.persistence.MDSGUIDImpl.<init>(MDSGUIDImpl.java:51)


Probando en una Custom Portal Application verifiqué que todo funcionaba de manera correcta.
Haciendo mas pruebas encontré que si el Task Flow se encontraba en una view diferente a la principal los parámetros eran registrados correctamente en el MDS.

El problema se acotaba a la view principal del Task Flow. Por alguna razón, en la página principal del Task Flow los cambios en Oracle Composer no eran persistidos.


Habilitando las trazas a nivel DEBUG del MDSSandBox de WebCenter Spaces se observa que la etiqueta que utiliza y genera para cuando se adhiere el Task Flow contenia por medio la ruta de una imagen PNG que estaba en el código de la view.

[2013-04-11T19:21:25.364+01:00] [WC_Spaces] [TRACE:32] [] [oracle.mds.sandbox] [tid: [ACTIVE].ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'] [userId: wbdevadmin] [ecid: 62340e71fac4a771:-495fe158:13dfa480d34:-8000-0000000000000e2d,0] [APP: webcenter#11.1.1.4.0] SandboxHelper.listSandboxes(); Namespace:/oracle/webcenter/doclib/view/jsf CUSTOMIZATIONS; SandboxNamePattern:WCFOWPSSLadfSLimagesSLpmp-mid.pngWCSEPwbdevadminWCRAN%; List of sandboxes:

Justamente esta imágen se corresponde con un background:url que hay en un inlineStyle del código. 

<af:panelGroupLayout id="pgl1" layout="vertical"
                         inlineStyle="background:url('../adf/images/pmp-mid.png') repeat-y white;">


Al eliminar el inlineStyle y sustituirlo por un styleClass el error desapareció y el Task Flow se registraba en MDS correctamente.