Herramientas de usuario

Herramientas del sitio


plugins:ejemplopluginlp

Ejemplo de implementación de plugin con ampliaciones en tablas/columnas en el diccionario de datos

Introducción

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.

Ejemplo de uso de GenerateModel en cada caso

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:

  • org.openXpertya.model.X_C_Invoice, que extiende de org.openXpertya.model.PO
  • ar.com.disytel.plugin.model.LP_C_Invoice, que extiende de org.openXpertya.model.MInvoice si existe, o de org.openXpertya.model.X_C_Invoice en caso contrario.

Las clases generadas para la segunda tabla serán:

  • ar.com.disytel.plugin.model.LP_C_Example, que extiende de org.openXpertya.model.PO
  • ar.com.other.plugin.model.LP_C_Example, que extiende de ar.com.disytel.plugin.model.LP_C_Example.

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:

  1. Tablas de Core: El owner de la tabla es el Core, y se desea implementar lógica para dicha tabla, dentro del core de la aplicación.
  2. Tablas de Plugin: En este caso el owner de la tabla es un plugin, y se desea implementar lógica para dicha tabla, dentro del plugin en desarrollo.
  3. Plugin para tablas de Core: Para una tabla de core, redefinir su lógica por un plugin que incluso podría haber modificado su estructura.
  4. Plugin para tablas de Plugin: Para una tabla plugin, redefinir su lógica por un plugin que incluso podría haber modificado su estructura.

1 - Uso de clases LP_ sobre tablas exclusivas de Core en lógica de persistencia y/o documentos

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.

2 - Uso de clases LP_ sobre tablas exclusivas de un plugin en lógica de persistencia y/o documentos

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:

  • La clase ar.com.disytel.plugin.model.LP_C_Example, que extiende de org.openXpertya.model.PO
  • La clase ar.com.disytel.plugin.model.MExample, que extiende de ar.com.disytel.plugin.model.LP_C_Example

3 - Uso de clases LP_ sobre tablas de Core ya existente en lógica de persistencia y/o documentos

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;
	}
 
}

4 - Uso de clases LP_ sobre tablas de otro plugin ya existente en lógica de persistencia y/o documentos

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:

  • Plugin1:
    • La clase ar.com.disytel.plugin.model.LP_C_Example, que extiende de org.openXpertya.model.PO
    • La clase ar.com.disytel.plugin.model.MExample, que extiende de ar.com.disytel.plugin.model.LP_C_Example
  • Plugin2:
    • La clase ar.com.other.plugin.model.LP_C_Example, que extiende de ar.com.disytel.plugin.model.LP_C_Example.
    • La clase ar.com.other.plugin.model.MExample, que extiende de org.openXpertya.plugin.MPluginPO.

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.

plugins/ejemplopluginlp.txt · Última modificación: 2021/04/30 19:19 (editor externo)