En el artículo anterior se detalló cómo implementar una serie componentes a fin de incorporar lógica de persistencia o de documentos. Sin embargo, se presenta la problemática de que para el plugin en desarrollo sea necesario incorporar nuevas tablas o columnas a una tabla existente al diccionario de datos.
Será necesario contemplar en estos casos, la utilización de la clase GenerateModel, a fin de crear los componentes Java correspondientes. Según la definición del campo Version de Componente en tabla y en columna, se crearán clases X_ (core Libertya) o LP_ (Libertya Plugin) con el fin de permitir el acceso a los campos desde la clase M del plugin (siguiendo el ejemplo anterior: ar.com.disytel.plugin.model.MInvoice).
La siguiente tabla detalla la lógica para la creación de clases utilizando el GenerateModel, en función de la especificación del campo Versión de Componente, tanto en definición de tabla como de columna:
Si la tabla es de System Core, se genera el X_ correspondiente, conteniendo los getters y setters correspondientes a las columnas System Core de la tabla. Esta clase extiende de PO. Esta es la generación normal de componentes X_. |
Si la tabla es de System Core, y existen columnas de Plugin para dicha tabla, se genera además un LP_ conteniendo únicamente los getters y setters correspondientes a las columnas Plugin de la tabla. Esta clase extiende de la clase M o X_ de System Core, según la existencia de la primera. |
Si la tabla es de Plugin, se genera el LP_ correspondiente, conteniendo los getters y setters correspondientes a las columnas Plugin de la tabla. Esta clase extiende de PO. |
Si la tabla es de Plugin1, y existen columnas de otro Plugin2 para dicha tabla, se genera un LP_ conteniendo únicamente los getters y setters correspondientes a las columnas del otro Plugin2 de la tabla. Esta clase extiende de la clase LP_ del primer plugin Plugin1. |
De esta manera, en función de las modificaciones creadas en el diccionario de datos para la definición del plugin, se podrá acceder desde el código a los componentes correspondientes de cada tabla/clase del plugin.
A continuación se detalla un ejemplo a fin de comprender el impacto en el uso de esta funcionalidad. Supongamos que para el plugin DISY (package (package ar.com.disytel.plugin), es necesario incorporar una nueva columna aNewColumn a la tabla C_Invoice, y crear además una nueva tabla C_Example. Existe además otro plugin OTHERPLUGIN (package ar.com.other.plugin) que extiende el previo, para el cual se requiere incorporar una columna anotherColumn en la tabla C_Example.
Componente | Valor | Versión del Componente |
---|---|---|
Tabla | C_Invoice | System Core |
Columna | (columnas de C_Invoice) | System Core |
Columna | aNewColumn | DISY |
Componente | Valor | Versión del Componente |
---|---|---|
Tabla | C_Example | DISY |
Columna | (columnas de C_Example) | DISY |
Columna | anotherColumn | OTHERPLUGIN |
Las clases generadas para la primer tabla serán:
Las clases generadas para la segunda tabla serán:
Las clases LP_ deberán almacenarse en el directorio model de la estructura de directorios especificada en el artículo anterior.
IMPORTANTE! A fin de evitar sobreescrituras de archivos (notar en el ejemplo que existen dos clases LP_C_Example), las clases LP_ generadas serán creadas con el package como parte del nombre de archivo. Es necesario quitar este prefijo luego de mover el componente al directorio model correspondiente.
Se puede dividir la metodología de implementación de clases de persistencia/documentos M, X, LP_ en cuatro categorías generales:
Este es el caso general de desarrollo de core, en donde se tiene la jerarquía PO → X_ → M. Obviaremos detalles en el presente documento ya que excede la finalidad del mismo.
Dado que es una tabla exclusiva de un plugin, la implementación de lógica de persistencia/documentos en este caso es igual al desarrollo de clases M de core, sin la utilización de métodos pre y post. En este caso se tiene la jerarquía PO → LP_ → M.
La clase M a implementar deberá extender de la clase LP_ correspondiente. Siguiendo el ejemplo previo, para la tabla C_Example, tendremos las siguientes clases:
Siguiendo el ejemplo anterior, supongamos una validación en el preBeforeSave de la tabla C_Invoice que requiere leer el campo exclusivo del plugin aNewColumn. En este caso es posible castear el PO recibido a LP_C_Invoice a fin de obtener el campo aNewColumn. Es posible incluso setear campos de C_Invoice pertenecientes al core, como se muestra en el siguiente ejemplo.
IMPORTANTE! Es necesario comprender que en este caso se está recibiendo una copia del objeto a persistir, dado que el objeto instanciado inicialmente sigue siendo org.openXpertya.model.MInvoice. Las modificaciones realizadas en el preBeforeSave() luego serán propagadas a dicha instancia, con lo cual NO ES CORRECTO FORZAR UN SAVE() DE LAS CLASES RECIBIDAS EN LOS METODOS Pre y Post.
package ar.com.disytel.plugin.model; import java.util.Properties; import org.openXpertya.model.PO; import org.openXpertya.plugin.MPluginPO; import org.openXpertya.plugin.MPluginStatusPO; public class MInvoice extends MPluginPO { public MInvoice(PO po, Properties ctx, String trxName, String aPackage) { super(po, ctx, trxName, aPackage); } public MPluginStatusPO preBeforeSave(PO po, boolean newRecord) { LP_C_Invoice invoice = (LP_C_Invoice)po; if (invoice.getANewColumn() == null || invoice.getANewColumn().length() == 0) { status_po.setContinueStatus(MPluginStatusPO.STATE_FALSE); status_po.setErrorMessage("Campo aNewColumn es obligatorio!"); } invoice.setDescription(invoice.getANewColumn()); return status_po; } }
De igual manera, es posible realizar procesamiento en lógica de documentos:
package ar.com.disytel.plugin.model; import java.util.Properties; import org.openXpertya.model.PO; import org.openXpertya.plugin.MPluginDocAction; import org.openXpertya.plugin.MPluginStatusDocAction; import org.openXpertya.process.DocAction; public class MInvoice extends MPluginDocAction { public MInvoice(PO po, Properties ctx, String trxName, String aPackage) { super(po, ctx, trxName, aPackage); } public MPluginStatusDocAction prePrepareIt(DocAction document) { LP_C_Invoice invoice = (LP_C_Invoice)document; if (invoice.getANewColumn() == null || invoice.getANewColumn().length() == 0) { status_docAction.setContinueStatus(MPluginStatusDocAction.STATE_FALSE); status_docAction.setDocStatus(DocAction.STATUS_Invalid); status_docAction.setProcessMsg("Debe completar el dato correspondiente"); } invoice.setDescription(invoice.getANewColumn()); return status_docAction; } }
En este caso la metodología es similar a la anterior, se presenta una dependencia de plugins. La diferencia en este caso radica en que en lugar de ser dependencia Core - Plugin, es una dependencia Plugin - Plugin.
Para una tabla cuyo propietario es el plugin Plugin1, y dado un plugin Plugin2 que contiene campos exclusivos, se podrá realizar el casteo correspondiente desde la invocación a métodos pre y post en el Plugin2.
Siguiendo el ejemplo previo sobre la tabla C_Example, tendremos las clases:
La clase MExample de Plugin2 recibirá en sus métodos pre y post, una copia de la instancia del Plugin1 de MExample o de LP_C_Example si la primera no fue implementada. Esta instancia puede ser casteada según sea necesario de la misma manera que en el ejemplo anterior.