From 36ca02f16d64c8c27aaf42767325f628556d58cb Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Wed, 13 Nov 2019 11:36:21 +0100 Subject: [PATCH] IDEMPIERE-4097 AD_Reference Caching validation --- .../src/org/compiere/model/MColumn.java | 6 +- .../src/org/compiere/model/MProcessPara.java | 6 +- .../src/org/compiere/model/MRefTable.java | 27 +++++- .../src/org/compiere/model/MReference.java | 82 +++++++++++++++++++ .../src/test/functional/TrifonTest.java | 4 +- .../handler/ReferenceElementHandler.java | 32 ++++---- .../handler/ReferenceTableElementHandler.java | 8 +- .../adinterface/ModelADServiceImpl.java | 32 ++------ 8 files changed, 141 insertions(+), 56 deletions(-) create mode 100644 org.adempiere.base/src/org/compiere/model/MReference.java diff --git a/org.adempiere.base/src/org/compiere/model/MColumn.java b/org.adempiere.base/src/org/compiere/model/MColumn.java index 2f3b3f5045..c190e52b5c 100644 --- a/org.adempiere.base/src/org/compiere/model/MColumn.java +++ b/org.adempiere.base/src/org/compiere/model/MColumn.java @@ -797,11 +797,11 @@ public class MColumn extends X_AD_Column if (DisplayType.TableDir == refid || (DisplayType.Search == refid && getAD_Reference_Value_ID() == 0)) { foreignTable = getColumnName().substring(0, getColumnName().length()-3); } else if (DisplayType.Table == refid || DisplayType.Search == refid) { - X_AD_Reference ref = new X_AD_Reference(getCtx(), getAD_Reference_Value_ID(), get_TrxName()); - if (X_AD_Reference.VALIDATIONTYPE_TableValidation.equals(ref.getValidationType())) { + MReference ref = MReference.get(getCtx(), getAD_Reference_Value_ID()); + if (MReference.VALIDATIONTYPE_TableValidation.equals(ref.getValidationType())) { int cnt = DB.getSQLValueEx(get_TrxName(), "SELECT COUNT(*) FROM AD_Ref_Table WHERE AD_Reference_ID=?", getAD_Reference_Value_ID()); if (cnt == 1) { - MRefTable rt = new MRefTable(getCtx(), getAD_Reference_Value_ID(), get_TrxName()); + MRefTable rt = MRefTable.get(getCtx(), getAD_Reference_Value_ID()); if (rt != null) foreignTable = rt.getAD_Table().getTableName(); } diff --git a/org.adempiere.base/src/org/compiere/model/MProcessPara.java b/org.adempiere.base/src/org/compiere/model/MProcessPara.java index 0451b51724..efcdfc111d 100644 --- a/org.adempiere.base/src/org/compiere/model/MProcessPara.java +++ b/org.adempiere.base/src/org/compiere/model/MProcessPara.java @@ -297,9 +297,9 @@ public class MProcessPara extends X_AD_Process_Para || (DisplayType.Search == getAD_Reference_ID() && getAD_Reference_Value_ID() == 0)) { foreignTable = getColumnName().substring(0, getColumnName().length()-3); } else if (DisplayType.Table == getAD_Reference_ID() || DisplayType.Search == getAD_Reference_ID()) { - X_AD_Reference ref = new X_AD_Reference(getCtx(), getAD_Reference_Value_ID(), get_TrxName()); - if (X_AD_Reference.VALIDATIONTYPE_TableValidation.equals(ref.getValidationType())) { - MRefTable rt = new MRefTable(getCtx(), getAD_Reference_Value_ID(), get_TrxName()); + MReference ref = MReference.get(getCtx(), getAD_Reference_Value_ID()); + if (MReference.VALIDATIONTYPE_TableValidation.equals(ref.getValidationType())) { + MRefTable rt = MRefTable.get(getCtx(), getAD_Reference_Value_ID()); if (rt != null) foreignTable = rt.getAD_Table().getTableName(); } diff --git a/org.adempiere.base/src/org/compiere/model/MRefTable.java b/org.adempiere.base/src/org/compiere/model/MRefTable.java index 10a75c8d03..1350982c9b 100644 --- a/org.adempiere.base/src/org/compiere/model/MRefTable.java +++ b/org.adempiere.base/src/org/compiere/model/MRefTable.java @@ -19,13 +19,15 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; +import org.compiere.util.CCache; + public class MRefTable extends X_AD_Ref_Table { /** * */ - private static final long serialVersionUID = 380648726485603193L; + private static final long serialVersionUID = -699466856436251075L; /** * Standard Constructor @@ -62,5 +64,26 @@ public class MRefTable extends X_AD_Ref_Table MTable table = MTable.get(getCtx(), getAD_Table_ID(), get_TrxName()); return table; } - + + /** Ref Table Cache */ + private static CCache s_cache = new CCache(Table_Name, 20); + + /** + * Get from Cache + * @param ctx context + * @param AD_Reference_ID id + * @return category + */ + public static MRefTable get (Properties ctx, int AD_Reference_ID) + { + Integer ii = Integer.valueOf(AD_Reference_ID); + MRefTable retValue = (MRefTable)s_cache.get(ii); + if (retValue != null) + return retValue; + retValue = new MRefTable (ctx, AD_Reference_ID, null); + if (retValue.get_ID () != 0) + s_cache.put (AD_Reference_ID, retValue); + return retValue; + } // get + } // MRefTable diff --git a/org.adempiere.base/src/org/compiere/model/MReference.java b/org.adempiere.base/src/org/compiere/model/MReference.java new file mode 100644 index 0000000000..372f8cc5ac --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/MReference.java @@ -0,0 +1,82 @@ +/********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - Carlos Ruiz * + **********************************************************************/ +package org.compiere.model; + +import java.sql.ResultSet; +import java.util.Properties; + +import org.compiere.util.CCache; + +public class MReference extends X_AD_Reference { + /** + * + */ + private static final long serialVersionUID = 119105464164520763L; + + /** + * Standard Constructor + * @param ctx context + * @param AD_Reference_ID id + * @param trxName trx + */ + public MReference (Properties ctx, int AD_Reference_ID, String trxName) { + super (ctx, AD_Reference_ID, trxName); + if (AD_Reference_ID == 0) { + setEntityType (ENTITYTYPE_UserMaintained); // U + } + } // MReference + + /** + * Load Constructor + * @param ctx context + * @param rs result set + * @param trxName trx + */ + public MReference (Properties ctx, ResultSet rs, String trxName) { + super (ctx, rs, trxName); + } // MReference + + /** Reference Cache */ + private static CCache s_cache = new CCache(Table_Name, 20); + + /** + * Get from Cache + * @param ctx context + * @param AD_Reference_ID id + * @return category + */ + public static MReference get (Properties ctx, int AD_Reference_ID) + { + Integer ii = Integer.valueOf(AD_Reference_ID); + MReference retValue = (MReference)s_cache.get(ii); + if (retValue != null) + return retValue; + retValue = new MReference (ctx, AD_Reference_ID, null); + if (retValue.get_ID () != 0) + s_cache.put (AD_Reference_ID, retValue); + return retValue; + } // get + +} // MReference diff --git a/org.adempiere.extend/src/test/functional/TrifonTest.java b/org.adempiere.extend/src/test/functional/TrifonTest.java index 52ff02f939..2baa807b5f 100644 --- a/org.adempiere.extend/src/test/functional/TrifonTest.java +++ b/org.adempiere.extend/src/test/functional/TrifonTest.java @@ -2,8 +2,8 @@ package test.functional; import org.compiere.model.MColumn; import org.compiere.model.MInvoice; +import org.compiere.model.MReference; import org.compiere.model.MTable; -import org.compiere.model.X_AD_Reference; import org.compiere.util.Env; import test.AdempiereTestCase; @@ -27,7 +27,7 @@ public class TrifonTest extends AdempiereTestCase { System.out.println("Desc............ is: " + mcolumn[i].getDescription()); System.out.println("Length.......... is: " + mcolumn[i].getFieldLength()); System.out.println("Reference_ID.... is: " + mcolumn[i].getAD_Reference_ID()); - X_AD_Reference reference = new X_AD_Reference(Env.getCtx(), mcolumn[i].getAD_Reference_ID(), getTrxName()); + MReference reference = new MReference(Env.getCtx(), mcolumn[i].getAD_Reference_ID(), getTrxName()); System.out.println("ReferenceName... is: " + reference.getName()); System.out.println(".............................."); } diff --git a/org.adempiere.pipo.handlers/src/org/adempiere/pipo2/handler/ReferenceElementHandler.java b/org.adempiere.pipo.handlers/src/org/adempiere/pipo2/handler/ReferenceElementHandler.java index 4be2a8b67b..a726169cc8 100644 --- a/org.adempiere.pipo.handlers/src/org/adempiere/pipo2/handler/ReferenceElementHandler.java +++ b/org.adempiere.pipo.handlers/src/org/adempiere/pipo2/handler/ReferenceElementHandler.java @@ -26,19 +26,19 @@ import java.util.logging.Level; import javax.xml.transform.sax.TransformerHandler; import org.adempiere.pipo2.AbstractElementHandler; -import org.adempiere.pipo2.PIPOContext; -import org.adempiere.pipo2.PoExporter; import org.adempiere.pipo2.Element; +import org.adempiere.pipo2.PIPOContext; import org.adempiere.pipo2.PackOut; +import org.adempiere.pipo2.PoExporter; import org.adempiere.pipo2.PoFiller; import org.adempiere.pipo2.exception.DatabaseAccessException; import org.adempiere.pipo2.exception.POSaveFailedException; import org.compiere.model.I_AD_Reference; +import org.compiere.model.MReference; import org.compiere.model.X_AD_Package_Exp_Detail; import org.compiere.model.X_AD_Package_Imp_Detail; import org.compiere.model.X_AD_Ref_List; import org.compiere.model.X_AD_Ref_Table; -import org.compiere.model.X_AD_Reference; import org.compiere.util.DB; import org.compiere.util.Env; import org.xml.sax.SAXException; @@ -57,11 +57,11 @@ public class ReferenceElementHandler extends AbstractElementHandler { if (isProcessElement(ctx.ctx, entitytype)) { - X_AD_Reference mReference = findPO(ctx, element); + MReference mReference = findPO(ctx, element); if (mReference == null) { - mReference = new X_AD_Reference(ctx.ctx, 0, getTrxName(ctx)); + mReference = new MReference(ctx.ctx, 0, getTrxName(ctx)); } - List excludes = defaultExcludeList(X_AD_Reference.Table_Name); + List excludes = defaultExcludeList(MReference.Table_Name); PoFiller filler = new PoFiller(ctx, mReference, element, this); List notfounds = filler.autoFill(excludes); if (notfounds.size() > 0) { @@ -71,15 +71,15 @@ public class ReferenceElementHandler extends AbstractElementHandler { } element.recordId = mReference.getAD_Reference_ID(); if (mReference.is_new() || mReference.is_Changed()) { - X_AD_Package_Imp_Detail impDetail = createImportDetail(ctx, element.qName, X_AD_Reference.Table_Name, - X_AD_Reference.Table_ID); + X_AD_Package_Imp_Detail impDetail = createImportDetail(ctx, element.qName, MReference.Table_Name, + MReference.Table_ID); String action = null; if (!mReference.is_new()) { if (references.contains(mReference.getAD_Reference_ID())) { element.skip = true; return; } - backupRecord(ctx, impDetail.getAD_Package_Imp_ID(), X_AD_Reference.Table_Name, mReference); + backupRecord(ctx, impDetail.getAD_Package_Imp_ID(), MReference.Table_Name, mReference); action = "Update"; } else { action = "New"; @@ -106,18 +106,18 @@ public class ReferenceElementHandler extends AbstractElementHandler { public void create(PIPOContext ctx, TransformerHandler document) throws SAXException { int Reference_id = Env.getContextAsInt(ctx.ctx, - X_AD_Reference.COLUMNNAME_AD_Reference_ID); - if (ctx.packOut.isExported(X_AD_Reference.COLUMNNAME_AD_Reference_ID+"|"+Reference_id)) + MReference.COLUMNNAME_AD_Reference_ID); + if (ctx.packOut.isExported(MReference.COLUMNNAME_AD_Reference_ID+"|"+Reference_id)) return; AttributesImpl atts = new AttributesImpl(); - X_AD_Reference m_Reference = new X_AD_Reference(ctx.ctx, Reference_id, getTrxName(ctx)); + MReference m_Reference = new MReference(ctx.ctx, Reference_id, getTrxName(ctx)); boolean createElement = isPackOutElement(ctx, m_Reference); PackOut packOut = ctx.packOut; - packOut.getCtx().ctx.put("Table_Name",X_AD_Reference.Table_Name); + packOut.getCtx().ctx.put("Table_Name",MReference.Table_Name); if (createElement) { verifyPackOutRequirement(m_Reference); addTypeName(atts, "table"); @@ -164,7 +164,7 @@ public class ReferenceElementHandler extends AbstractElementHandler { } if (createElement) { - document.endElement("", "", X_AD_Reference.Table_Name); + document.endElement("", "", MReference.Table_Name); } } @@ -185,8 +185,8 @@ public class ReferenceElementHandler extends AbstractElementHandler { } private void createReferenceBinding(PIPOContext ctx, TransformerHandler document, - X_AD_Reference m_Reference) { - List excludes = defaultExcludeList(X_AD_Reference.Table_Name); + MReference m_Reference) { + List excludes = defaultExcludeList(MReference.Table_Name); PoExporter filler = new PoExporter(ctx, document, m_Reference); if (m_Reference.getAD_Reference_ID() <= PackOut.MAX_OFFICIAL_ID) filler.add("AD_Reference_ID", new AttributesImpl()); diff --git a/org.adempiere.pipo.handlers/src/org/adempiere/pipo2/handler/ReferenceTableElementHandler.java b/org.adempiere.pipo.handlers/src/org/adempiere/pipo2/handler/ReferenceTableElementHandler.java index 65498fda72..1af577d58e 100644 --- a/org.adempiere.pipo.handlers/src/org/adempiere/pipo2/handler/ReferenceTableElementHandler.java +++ b/org.adempiere.pipo.handlers/src/org/adempiere/pipo2/handler/ReferenceTableElementHandler.java @@ -24,17 +24,17 @@ import java.util.logging.Level; import javax.xml.transform.sax.TransformerHandler; import org.adempiere.pipo2.AbstractElementHandler; -import org.adempiere.pipo2.PIPOContext; -import org.adempiere.pipo2.PoExporter; import org.adempiere.pipo2.Element; +import org.adempiere.pipo2.PIPOContext; import org.adempiere.pipo2.PackOut; +import org.adempiere.pipo2.PoExporter; import org.adempiere.pipo2.PoFiller; import org.adempiere.pipo2.ReferenceUtils; import org.adempiere.pipo2.exception.DatabaseAccessException; import org.compiere.model.I_AD_Ref_Table; +import org.compiere.model.MReference; import org.compiere.model.X_AD_Package_Imp_Detail; import org.compiere.model.X_AD_Ref_Table; -import org.compiere.model.X_AD_Reference; import org.compiere.util.DB; import org.compiere.util.Env; import org.xml.sax.SAXException; @@ -82,7 +82,7 @@ public class ReferenceTableElementHandler extends AbstractElementHandler { X_AD_Ref_Table.Table_ID); int AD_Reference_ID = refTable.getAD_Reference_ID(); - X_AD_Reference adReference = new X_AD_Reference(ctx.ctx, AD_Reference_ID, getTrxName(ctx)); + MReference adReference = new MReference(ctx.ctx, AD_Reference_ID, getTrxName(ctx)); logImportDetail(ctx, impDetail, 1, adReference.getName(), refTable.getAD_Reference_ID(), action); } } else { diff --git a/org.idempiere.webservices/WEB-INF/src/org/idempiere/adinterface/ModelADServiceImpl.java b/org.idempiere.webservices/WEB-INF/src/org/idempiere/adinterface/ModelADServiceImpl.java index fadceba4b3..303228d9e2 100644 --- a/org.idempiere.webservices/WEB-INF/src/org/idempiere/adinterface/ModelADServiceImpl.java +++ b/org.idempiere.webservices/WEB-INF/src/org/idempiere/adinterface/ModelADServiceImpl.java @@ -50,12 +50,12 @@ import org.compiere.model.MColumn; import org.compiere.model.MLookup; import org.compiere.model.MLookupFactory; import org.compiere.model.MRefTable; +import org.compiere.model.MReference; import org.compiere.model.MRole; import org.compiere.model.MTable; import org.compiere.model.MWebServiceType; import org.compiere.model.PO; import org.compiere.model.POInfo; -import org.compiere.model.X_AD_Reference; import org.compiere.model.X_WS_WebServiceFieldInput; import org.compiere.model.X_WS_WebService_Para; import org.compiere.util.CLogger; @@ -460,14 +460,14 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic Properties ctx = m_cs.getCtx(); - X_AD_Reference ref = new X_AD_Reference(ctx, ref_id, null); + MReference ref = MReference.get(ctx, ref_id); String sql = null; ArrayList listColumnNames = new ArrayList(); PreparedStatement pstmt = null; ResultSet rs = null; MWebServiceType m_webservicetype= getWebServiceType(); - if (X_AD_Reference.VALIDATIONTYPE_ListValidation.equals(ref.getValidationType())) { + if (MReference.VALIDATIONTYPE_ListValidation.equals(ref.getValidationType())) { // Fill List Reference String ad_language = Env.getAD_Language(ctx); boolean isBaseLanguage = Env.isBaseLanguage(ad_language, "AD_Ref_List"); @@ -503,31 +503,11 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic throw new IdempiereServiceFault(e.getClass().toString() + " " + e.getMessage() + " sql=" + sql, e.getCause(), new QName("getList")); } - } else if (X_AD_Reference.VALIDATIONTYPE_TableValidation.equals(ref.getValidationType())) { + } else if (MReference.VALIDATIONTYPE_TableValidation.equals(ref.getValidationType())) { // Fill values from a reference table MRole role = new MRole(ctx, roleid, null); - String sqlrt = "SELECT * FROM AD_Ref_Table WHERE AD_Reference_ID=?"; - MRefTable rt = null; - PreparedStatement pstmtrt = null; - ResultSet rsrt = null; - try - { - pstmtrt = DB.prepareStatement (sqlrt, null); - pstmtrt.setInt (1, ref_id); - rsrt = pstmtrt.executeQuery (); - if (rsrt.next ()) - rt = new MRefTable(ctx, rsrt, null); - } - catch (Exception e) - { - // ignore this exception - } - finally - { - DB.close(rsrt, pstmtrt); - rsrt = null; pstmtrt = null; - } - if (rt == null) + MRefTable rt = MRefTable.get(ctx, ref_id); + if (rt == null || rt.get_ID() == 0) throw new IdempiereServiceFault("Web service type " + m_webservicetype.getValue() + ": reference table " + ref_id + " not found",