diff --git a/org.adempiere.base.process/src/org/adempiere/process/InitialClientSetup.java b/org.adempiere.base.process/src/org/adempiere/process/InitialClientSetup.java index bcea7c54a9..f1e8fa3232 100644 --- a/org.adempiere.base.process/src/org/adempiere/process/InitialClientSetup.java +++ b/org.adempiere.base.process/src/org/adempiere/process/InitialClientSetup.java @@ -172,6 +172,7 @@ public class InitialClientSetup extends SvrProcess */ protected String doIt () throws Exception { + boolean isDryRun = "Y".equalsIgnoreCase(Env.getContext(Env.getCtx(), Env.RUNNING_UNIT_TESTING_TEST_CASE)); StringBuilder msglog = new StringBuilder("InitialClientSetup") .append(": ClientName=").append(p_ClientName) @@ -261,7 +262,7 @@ public class InitialClientSetup extends SvrProcess throw new AdempiereException(Msg.getMsg(Env.getCtx(), "CoaFile") + " " + p_CoAFile + " " + Msg.getMsg(Env.getCtx(), "is empty")); // Process - MSetup ms = new MSetup(Env.getCtx(), WINDOW_THIS_PROCESS); + MSetup ms = new MSetup(Env.getCtx(), WINDOW_THIS_PROCESS, isDryRun); try { if (! ms.createClient(p_ClientName, p_OrgValue, p_OrgName, p_AdminUserName, p_NormalUserName , p_Phone, p_Phone2, p_Fax, p_EMail, p_TaxID, p_AdminUserEmail, p_NormalUserEmail, p_IsSetInitialPassword)) { @@ -289,7 +290,9 @@ public class InitialClientSetup extends SvrProcess addLog(ms.getInfo()); // Create Print Documents - PrintUtil.setupPrintForm(ms.getAD_Client_ID()); + PrintUtil.setupPrintForm(ms.getAD_Client_ID(), isDryRun ? ms.getTrxName() : null); + if (isDryRun) + ms.rollback(); } catch (Exception e) { ms.rollback(); throw e; diff --git a/org.adempiere.base.process/src/org/compiere/process/ConvertLead.java b/org.adempiere.base.process/src/org/compiere/process/ConvertLead.java index 0a7394c48d..feb2c271d5 100644 --- a/org.adempiere.base.process/src/org/compiere/process/ConvertLead.java +++ b/org.adempiere.base.process/src/org/compiere/process/ConvertLead.java @@ -59,8 +59,7 @@ public class ConvertLead extends SvrProcess { if (p_AD_User_ID <= 0) throw new FillMandatoryException("AD_User_ID"); - MUser lead = MUser.get(getCtx(), p_AD_User_ID); - lead.set_TrxName(get_TrxName()); + MUser lead = new MUser(getCtx(), p_AD_User_ID, get_TrxName()); if (!lead.isSalesLead() && lead.getC_BPartner_ID() != 0) throw new AdempiereUserError("Lead already converted"); diff --git a/org.adempiere.base.process/src/org/compiere/process/ImportAccount.java b/org.adempiere.base.process/src/org/compiere/process/ImportAccount.java index 24933b2775..f18e6f6f30 100644 --- a/org.adempiere.base.process/src/org/compiere/process/ImportAccount.java +++ b/org.adempiere.base.process/src/org/compiere/process/ImportAccount.java @@ -29,6 +29,7 @@ import org.compiere.model.MColumn; import org.compiere.model.MElementValue; import org.compiere.model.X_I_ElementValue; import org.compiere.util.DB; +import org.compiere.util.Env; /** * Import Accounts from I_ElementValue @@ -605,7 +606,7 @@ public class ImportAccount extends SvrProcess { if (m_createNewCombination) { - MAccount acct = MAccount.get(getCtx(), C_ValidCombination_ID); + MAccount acct = new MAccount(Env.getCtx(), C_ValidCombination_ID, (String)null); acct.setAccount_ID(C_ElementValue_ID); if (acct.save()) { diff --git a/org.adempiere.base.process/src/org/compiere/process/UserPassword.java b/org.adempiere.base.process/src/org/compiere/process/UserPassword.java index 3af1564faf..ad823373e4 100644 --- a/org.adempiere.base.process/src/org/compiere/process/UserPassword.java +++ b/org.adempiere.base.process/src/org/compiere/process/UserPassword.java @@ -79,8 +79,7 @@ public class UserPassword extends SvrProcess { if (log.isLoggable(Level.INFO)) log.info ("AD_User_ID=" + p_AD_User_ID + " from " + getAD_User_ID()); - MUser user = MUser.get(getCtx(), p_AD_User_ID); - user.load(get_TrxName()); + MUser user = new MUser(getCtx(), p_AD_User_ID, get_TrxName()); MUser operator = MUser.get(getCtx(), getAD_User_ID()); if (log.isLoggable(Level.FINE)) log.fine("User=" + user + ", Operator=" + operator); diff --git a/org.adempiere.base.process/src/org/idempiere/process/MigrateStorageProvider.java b/org.adempiere.base.process/src/org/idempiere/process/MigrateStorageProvider.java index e020afa3fb..9633a927d6 100644 --- a/org.adempiere.base.process/src/org/idempiere/process/MigrateStorageProvider.java +++ b/org.adempiere.base.process/src/org/idempiere/process/MigrateStorageProvider.java @@ -157,7 +157,7 @@ public class MigrateStorageProvider extends SvrProcess { // for each client for (int clientid : clients) { idxClient++; - MClientInfo clientInfo = MClientInfo.get(getCtx(), clientid); + MClientInfo clientInfo = MClientInfo.getCopy(getCtx(), clientid, (String)null); MClient client = MClient.get(getCtx(), clientid); int odometer = 10; diff --git a/org.adempiere.base/META-INF/MANIFEST.MF b/org.adempiere.base/META-INF/MANIFEST.MF index ade265dc40..8c1e25b017 100644 --- a/org.adempiere.base/META-INF/MANIFEST.MF +++ b/org.adempiere.base/META-INF/MANIFEST.MF @@ -50,6 +50,7 @@ Export-Package: bsh, org.compiere.wf, org.eevolution.model, org.idempiere.broadcast, + org.idempiere.cache, org.idempiere.distributed, org.idempiere.fa.service.api, org.idempiere.model diff --git a/org.adempiere.base/src/org/adempiere/model/MBroadcastMessage.java b/org.adempiere.base/src/org/adempiere/model/MBroadcastMessage.java index 7dbe1287ac..8c88f1aecf 100644 --- a/org.adempiere.base/src/org/adempiere/model/MBroadcastMessage.java +++ b/org.adempiere.base/src/org/adempiere/model/MBroadcastMessage.java @@ -17,9 +17,10 @@ import java.sql.ResultSet; import java.util.Properties; import org.compiere.model.X_AD_BroadcastMessage; -import org.compiere.util.CCache; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * @@ -27,14 +28,14 @@ import org.compiere.util.Env; * @author Deepak Pansheriya * */ -public class MBroadcastMessage extends X_AD_BroadcastMessage +public class MBroadcastMessage extends X_AD_BroadcastMessage implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 1908264699133879072L; + private static final long serialVersionUID = -5402131480890468471L; - static private CCache s_cache = new CCache("AD_BroadcastMessage", 30, 60); + static private ImmutableIntPOCache s_cache = new ImmutableIntPOCache("AD_BroadcastMessage", 30, 60); public MBroadcastMessage(Properties ctx, int AD_BroadcastMessage_ID, String trxName) @@ -47,16 +48,67 @@ public class MBroadcastMessage extends X_AD_BroadcastMessage { super(ctx, rs, trxName); } - + + /** + * + * @param copy + */ + public MBroadcastMessage(MBroadcastMessage copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MBroadcastMessage(Properties ctx, MBroadcastMessage copy) + { + this(ctx, copy, (String)null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MBroadcastMessage(Properties ctx, MBroadcastMessage copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + /** + * Get MBroadcastMessage from cache (immutable) + * @param AD_BroadcastMessage_ID + * @return MBroadcastMessage or null + */ + public static MBroadcastMessage get (int AD_BroadcastMessage_ID) + { + return get(Env.getCtx(), AD_BroadcastMessage_ID); + } + + /** + * Get MBroadcastMessage from cache (immutable) + * @param ctx + * @param AD_BroadcastMessage_ID + * @return MBroadcastMessage or null + */ public static MBroadcastMessage get (Properties ctx, int AD_BroadcastMessage_ID) { Integer key = Integer.valueOf(AD_BroadcastMessage_ID); - MBroadcastMessage retValue = (MBroadcastMessage)s_cache.get(key); + MBroadcastMessage retValue = s_cache.get(ctx, key, e -> new MBroadcastMessage(ctx, e)); if (retValue == null) { - retValue = new MBroadcastMessage (ctx, AD_BroadcastMessage_ID, null); - - s_cache.put(key, retValue); + retValue = new MBroadcastMessage (ctx, AD_BroadcastMessage_ID, (String)null); + if (retValue.get_ID() == AD_BroadcastMessage_ID) + { + s_cache.put(key, retValue, e -> new MBroadcastMessage(Env.getCtx(), e)); + return retValue; + } + return null; } return retValue; } // get @@ -116,4 +168,12 @@ public class MBroadcastMessage extends X_AD_BroadcastMessage return true; } + @Override + public MBroadcastMessage markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } } diff --git a/org.adempiere.base/src/org/compiere/model/MAccount.java b/org.adempiere.base/src/org/compiere/model/MAccount.java index 80e094e48d..cedd78efd8 100644 --- a/org.adempiere.base/src/org/compiere/model/MAccount.java +++ b/org.adempiere.base/src/org/compiere/model/MAccount.java @@ -22,9 +22,10 @@ import java.util.List; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Account Object Entity to maintain all segment values. @@ -35,14 +36,14 @@ import org.compiere.util.Env; *
  • RF [ 2214883 ] Remove SQL code and Replace for Query http://sourceforge.net/tracker/index.php?func=detail&aid=2214883&group_id=176962&atid=879335 * @version $Id: MAccount.java,v 1.4 2006/07/30 00:58:04 jjanke Exp $ */ -public class MAccount extends X_C_ValidCombination +public class MAccount extends X_C_ValidCombination implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 7980515458720808532L; + private static final long serialVersionUID = 1927316490582718406L; - private static final CCache s_cache = new CCache(Table_Name, 100); + private static final ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 100); /* * Deprecated - use the same method with trxName instead @@ -359,29 +360,35 @@ public class MAccount extends X_C_ValidCombination return vc; } // getDefault - /** - * Get Account - * @param ctx context + * Get Account from cache (immutable) * @param C_ValidCombination_ID combination * @return Account */ + public static MAccount get (int C_ValidCombination_ID) + { + return get(Env.getCtx(), C_ValidCombination_ID); + } + + /** + * Get Account from cache (immutable) + * @param ctx context + * @param C_ValidCombination_ID combination + * @return Immutable instance of Account + */ public static MAccount get (Properties ctx, int C_ValidCombination_ID) { - MAccount account = s_cache.get(C_ValidCombination_ID); - if (account != null && account.getCtx() == ctx) + MAccount account = s_cache.get(ctx, C_ValidCombination_ID, e -> new MAccount(ctx, e)); + if (account != null) return account; - - account = new MAccount(ctx, C_ValidCombination_ID, null); + + account = new MAccount(ctx, C_ValidCombination_ID, (String)null); if (account.getC_ValidCombination_ID() == C_ValidCombination_ID) { - s_cache.put(C_ValidCombination_ID, account); + s_cache.put(C_ValidCombination_ID, account, e -> new MAccount(Env.getCtx(), e)); return account; } - else - { - return null; - } + return null; } // getAccount /** @@ -447,6 +454,38 @@ public class MAccount extends X_C_ValidCombination setC_AcctSchema_ID(as.getC_AcctSchema_ID()); } // Account + /** + * + * @param copy + */ + public MAccount(MAccount copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MAccount(Properties ctx, MAccount copy) + { + this(ctx, copy, (String)null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MAccount(Properties ctx, MAccount copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_accountEV = copy.m_accountEV != null ? new MElementValue(ctx, copy.m_accountEV, trxName) : null; + } + /** Account Segment */ private MElementValue m_accountEV = null; @@ -521,7 +560,11 @@ public class MAccount extends X_C_ValidCombination if (m_accountEV == null) { if (getAccount_ID() != 0) + { m_accountEV = new MElementValue(getCtx(), getAccount_ID(), get_TrxName()); + if (is_Immutable()) + m_accountEV.markImmutable(); + } } return m_accountEV; } // setAccount @@ -838,6 +881,17 @@ public class MAccount extends X_C_ValidCombination } // beforeSave + @Override + public MAccount markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_accountEV != null) + m_accountEV.markImmutable(); + return this; + } + /** * Test * @param args diff --git a/org.adempiere.base/src/org/compiere/model/MAcctSchema.java b/org.adempiere.base/src/org/compiere/model/MAcctSchema.java index 842b88c744..a6335c4a65 100644 --- a/org.adempiere.base/src/org/compiere/model/MAcctSchema.java +++ b/org.adempiere.base/src/org/compiere/model/MAcctSchema.java @@ -18,13 +18,17 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.logging.Level; import org.compiere.report.MReportTree; import org.compiere.util.CCache; +import org.compiere.util.Env; import org.compiere.util.KeyNamePair; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Accounting Schema Model (base) @@ -34,26 +38,37 @@ import org.compiere.util.KeyNamePair; *
  • RF [ 2214883 ] Remove SQL code and Replace for Query http://sourceforge.net/tracker/index.php?func=detail&aid=2214883&group_id=176962&atid=879335 * @version $Id: MAcctSchema.java,v 1.4 2006/07/30 00:58:04 jjanke Exp $ */ -public class MAcctSchema extends X_C_AcctSchema +public class MAcctSchema extends X_C_AcctSchema implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 8940388112876468770L; + private static final long serialVersionUID = 405097978362430053L; + /** - * Get AccountSchema of Client + * Get AccountSchema + * @param C_AcctSchema_ID schema id + * @return Accounting schema + */ + public static MAcctSchema get (int C_AcctSchema_ID) + { + return get(Env.getCtx(), C_AcctSchema_ID); + } + + /** + * Get AccountSchema * @param ctx context * @param C_AcctSchema_ID schema id * @return Accounting schema */ public static MAcctSchema get (Properties ctx, int C_AcctSchema_ID) { - return get(ctx, C_AcctSchema_ID, null); + return get(ctx, C_AcctSchema_ID, (String)null); } // get /** - * Get AccountSchema of Client + * Get AccountSchema * @param ctx context * @param C_AcctSchema_ID schema id * @param trxName optional trx @@ -63,15 +78,34 @@ public class MAcctSchema extends X_C_AcctSchema { // Check Cache Integer key = Integer.valueOf(C_AcctSchema_ID); - MAcctSchema retValue = (MAcctSchema)s_cache.get(key); + MAcctSchema retValue = s_cache.get(ctx, key, e -> new MAcctSchema(ctx, e)); if (retValue != null) return retValue; + retValue = new MAcctSchema (ctx, C_AcctSchema_ID, trxName); - if (trxName == null) - s_cache.put(key, retValue); - return retValue; + if (retValue.get_ID() == C_AcctSchema_ID) + { + s_cache.put(key, retValue, e -> new MAcctSchema(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MAcctSchema from cache + * @param ctx + * @param C_AcctSchema_ID + * @param trxName + * @return MAcctSchema + */ + public static MAcctSchema getCopy(Properties ctx, int C_AcctSchema_ID, String trxName) + { + MAcctSchema as = get(ctx, C_AcctSchema_ID, trxName); + if (as != null) + as = new MAcctSchema(ctx, as, trxName); + return as; + } + /** * Get AccountSchema of Client * @param ctx context @@ -95,7 +129,12 @@ public class MAcctSchema extends X_C_AcctSchema // Check Cache Integer key = Integer.valueOf(AD_Client_ID); if (s_schema.containsKey(key)) - return (MAcctSchema[])s_schema.get(key); + { + if (ctx == Env.getCtx()) + return s_schema.get(key); + else + return Arrays.stream(s_schema.get(key)).map(e -> { return new MAcctSchema(ctx, e).markImmutable(); }).toArray(MAcctSchema[]::new); + } // Create New ArrayList list = new ArrayList(); @@ -124,22 +163,27 @@ public class MAcctSchema extends X_C_AcctSchema { if (acctschema.get_ID() != info.getC_AcctSchema1_ID()) // already in list { - if (acctschema.get_ID() != 0) + if (acctschema.get_ID() != 0) + { + acctschema.markImmutable(); list.add(acctschema); + } } } // Save MAcctSchema[] retValue = new MAcctSchema [list.size()]; list.toArray(retValue); - if (trxName == null) + if (ctx == Env.getCtx()) s_schema.put(key, retValue); + else + s_schema.put(key, Arrays.stream(retValue).map(e -> {return new MAcctSchema(Env.getCtx(), e).markImmutable();}).toArray(MAcctSchema[]::new)); return retValue; } // getClientAcctSchema /** Cache of Client AcctSchema Arrays **/ private static CCache s_schema = new CCache(I_AD_ClientInfo.Table_Name, I_AD_ClientInfo.Table_Name+"|MAcctSchema[]", 3, 120, true); // 3 clients /** Cache of AcctSchemas **/ - private static CCache s_cache = new CCache(Table_Name, 3, 120, true); // 3 accounting schemas + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 3, 120, true); // 3 accounting schemas /************************************************************************** @@ -200,6 +244,46 @@ public class MAcctSchema extends X_C_AcctSchema setName (msgset.toString()); } // MAcctSchema + /** + * + * @param copy + */ + public MAcctSchema(MAcctSchema copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MAcctSchema(Properties ctx, MAcctSchema copy) + { + this(ctx, copy, (String)null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MAcctSchema(Properties ctx, MAcctSchema copy, String trxName) + { + super(ctx, 0, trxName); + copyPO(copy); + this.m_gl = copy.m_gl != null ? new MAcctSchemaGL(ctx, copy.m_gl) : null; + this.m_default = copy.m_default != null ? new MAcctSchemaDefault(ctx, copy.m_default) : null; + this.m_SuspenseError_Acct = copy.m_SuspenseError_Acct != null ? new MAccount(ctx, copy.m_SuspenseError_Acct) : null; + this.m_CurrencyBalancing_Acct = copy.m_CurrencyBalancing_Acct != null ? new MAccount(ctx, copy.m_CurrencyBalancing_Acct) : null; + this.m_DueTo_Acct = copy.m_DueTo_Acct != null ? new MAccount(ctx, copy.m_DueTo_Acct) : null; + this.m_DueFrom_Acct = copy.m_DueFrom_Acct != null ? new MAccount(ctx, copy.m_DueFrom_Acct) : null; + this.m_stdPrecision = copy.m_stdPrecision; + this.m_costPrecision = copy.m_costPrecision; + this.m_onlyOrg = copy.m_onlyOrg != null ? new MOrg(ctx, copy.m_onlyOrg) : null; + this.m_onlyOrgs = copy.m_onlyOrgs; + } /** GL Info */ private MAcctSchemaGL m_gl = null; @@ -261,7 +345,11 @@ public class MAcctSchema extends X_C_AcctSchema public MAcctSchemaGL getAcctSchemaGL() { if (m_gl == null) + { m_gl = MAcctSchemaGL.get(getCtx(), getC_AcctSchema_ID()); + if (m_gl != null && is_Immutable()) + m_gl.markImmutable(); + } if (m_gl == null) throw new IllegalStateException("No GL Definition for C_AcctSchema_ID=" + getC_AcctSchema_ID()); return m_gl; @@ -274,7 +362,11 @@ public class MAcctSchema extends X_C_AcctSchema public MAcctSchemaDefault getAcctSchemaDefault() { if (m_default == null) + { m_default = MAcctSchemaDefault.get(getCtx(), getC_AcctSchema_ID()); + if (m_default != null && is_Immutable()) + m_default.markImmutable(); + } if (m_default == null) throw new IllegalStateException("No Default Definition for C_AcctSchema_ID=" + getC_AcctSchema_ID()); return m_default; @@ -314,7 +406,7 @@ public class MAcctSchema extends X_C_AcctSchema if (m_gl == null) getAcctSchemaGL(); int C_ValidCombination_ID = m_gl.getSuspenseBalancing_Acct(); - m_SuspenseError_Acct = MAccount.get(getCtx(), C_ValidCombination_ID); + m_SuspenseError_Acct = MAccount.get(C_ValidCombination_ID); return m_SuspenseError_Acct; } // getSuspenseBalancing_Acct @@ -340,7 +432,7 @@ public class MAcctSchema extends X_C_AcctSchema if (m_gl == null) getAcctSchemaGL(); int C_ValidCombination_ID = m_gl.getCurrencyBalancing_Acct(); - m_CurrencyBalancing_Acct = MAccount.get(getCtx(), C_ValidCombination_ID); + m_CurrencyBalancing_Acct = MAccount.get(C_ValidCombination_ID); return m_CurrencyBalancing_Acct; } // getCurrencyBalancing_Acct @@ -357,7 +449,7 @@ public class MAcctSchema extends X_C_AcctSchema if (m_gl == null) getAcctSchemaGL(); int C_ValidCombination_ID = m_gl.getIntercompanyDueTo_Acct(); - m_DueTo_Acct = MAccount.get(getCtx(), C_ValidCombination_ID); + m_DueTo_Acct = MAccount.get(C_ValidCombination_ID); return m_DueTo_Acct; } // getDueTo_Acct @@ -373,7 +465,7 @@ public class MAcctSchema extends X_C_AcctSchema if (m_gl == null) getAcctSchemaGL(); int C_ValidCombination_ID = m_gl.getIntercompanyDueFrom_Acct(); - m_DueFrom_Acct = MAccount.get(getCtx(), C_ValidCombination_ID); + m_DueFrom_Acct = MAccount.get(C_ValidCombination_ID); return m_DueFrom_Acct; } // getDueFrom_Acct @@ -416,7 +508,7 @@ public class MAcctSchema extends X_C_AcctSchema if (getAD_OrgOnly_ID() == AD_Org_ID) return false; if (m_onlyOrg == null) - m_onlyOrg = MOrg.get(getCtx(), getAD_OrgOnly_ID()); + m_onlyOrg = MOrg.get(getAD_OrgOnly_ID()); // Not Summary Only - i.e. skip it if (!m_onlyOrg.isSummary()) return true; @@ -625,4 +717,18 @@ public class MAcctSchema extends X_C_AcctSchema return true; } // beforeSave + @Override + public MAcctSchema markImmutable() + { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_gl != null) + m_gl.markImmutable(); + if (m_default != null) + m_default.markImmutable(); + return this; + } + } // MAcctSchema diff --git a/org.adempiere.base/src/org/compiere/model/MAcctSchemaDefault.java b/org.adempiere.base/src/org/compiere/model/MAcctSchemaDefault.java index 5927a786e7..2d12ef951f 100644 --- a/org.adempiere.base/src/org/compiere/model/MAcctSchemaDefault.java +++ b/org.adempiere.base/src/org/compiere/model/MAcctSchemaDefault.java @@ -21,7 +21,9 @@ import java.util.ArrayList; import java.util.Properties; import org.compiere.util.CLogger; +import org.compiere.util.Env; import org.compiere.util.KeyNamePair; +import org.idempiere.cache.ImmutablePOSupport; /** * Default Accounts for MAcctSchema @@ -31,14 +33,13 @@ import org.compiere.util.KeyNamePair; *
  • RF [ 2214883 ] Remove SQL code and Replace for Query http://sourceforge.net/tracker/index.php?func=detail&aid=2214883&group_id=176962&atid=879335 * @version $Id: MAcctSchemaDefault.java,v 1.3 2006/07/30 00:58:37 jjanke Exp $ */ -public class MAcctSchemaDefault extends X_C_AcctSchema_Default +public class MAcctSchemaDefault extends X_C_AcctSchema_Default implements ImmutablePOSupport { - - /** - * - */ - private static final long serialVersionUID = 199959007595802866L; + /** + * + */ + private static final long serialVersionUID = -7966846617443248102L; /** * Get Accounting Schema Default Info @@ -79,6 +80,37 @@ public class MAcctSchemaDefault extends X_C_AcctSchema_Default super(ctx, rs, trxName); } // MAcctSchemaDefault + /** + * + * @param copy + */ + public MAcctSchemaDefault(MAcctSchemaDefault copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MAcctSchemaDefault(Properties ctx, MAcctSchemaDefault copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MAcctSchemaDefault(Properties ctx, MAcctSchemaDefault copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Get Realized Gain Acct for currency * @param C_Currency_ID currency @@ -152,4 +184,13 @@ public class MAcctSchemaDefault extends X_C_AcctSchema_Default return true; } // beforeSave + @Override + public MAcctSchemaDefault markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MAcctSchemaDefault diff --git a/org.adempiere.base/src/org/compiere/model/MAcctSchemaElement.java b/org.adempiere.base/src/org/compiere/model/MAcctSchemaElement.java index 6b8f22cd6e..1e23776a1a 100644 --- a/org.adempiere.base/src/org/compiere/model/MAcctSchemaElement.java +++ b/org.adempiere.base/src/org/compiere/model/MAcctSchemaElement.java @@ -28,6 +28,7 @@ import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Language; import org.compiere.util.Msg; +import org.idempiere.cache.ImmutablePOSupport; /** * Account Schema Element Object @@ -38,15 +39,15 @@ import org.compiere.util.Msg; * @author victor.perez@e-evolution.com, www.e-evolution.com *
  • RF [ 2214883 ] Remove SQL code and Replace for Query http://sourceforge.net/tracker/index.php?func=detail&aid=2214883&group_id=176962&atid=879335 */ -public class MAcctSchemaElement extends X_C_AcctSchema_Element +public class MAcctSchemaElement extends X_C_AcctSchema_Element implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -4642928142654938659L; + private static final long serialVersionUID = -747934131394469553L; /** - * Factory: Return ArrayList of Account Schema Elements + * Get ArrayList of Account Schema Elements from cache * @param as Accounting Schema * @return ArrayList with Elements */ @@ -71,12 +72,13 @@ public class MAcctSchemaElement extends X_C_AcctSchema_Element if (s_log.isLoggable(Level.FINE)) s_log.fine(" - " + ase); if (ase.isMandatory() && ase.getDefaultValue() == 0) s_log.log(Level.SEVERE, "No default value for " + ase.getName()); + ase.markImmutable(); list.add(ase); } retValue = new MAcctSchemaElement[list.size()]; list.toArray(retValue); - s_cache.put (key, retValue); + s_cache.put(key, retValue); return retValue; } // getAcctSchemaElements @@ -238,6 +240,38 @@ public class MAcctSchemaElement extends X_C_AcctSchema_Element } // MAcctSchemaElement + /** + * + * @param copy + */ + public MAcctSchemaElement(MAcctSchemaElement copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MAcctSchemaElement(Properties ctx, MAcctSchemaElement copy) + { + this(ctx, copy, (String)null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MAcctSchemaElement(Properties ctx, MAcctSchemaElement copy, String trxName) + { + super(ctx, 0, trxName); + copyPO(copy); + this.m_ColumnName = copy.m_ColumnName; + } + /** User Element Column Name */ private String m_ColumnName = null; @@ -538,5 +572,14 @@ public class MAcctSchemaElement extends X_C_AcctSchema_Element s_cache.clear(); return success; } // afterDelete - + + @Override + public MAcctSchemaElement markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // AcctSchemaElement diff --git a/org.adempiere.base/src/org/compiere/model/MAcctSchemaGL.java b/org.adempiere.base/src/org/compiere/model/MAcctSchemaGL.java index 63cf00d25e..ff1c0a0af4 100644 --- a/org.adempiere.base/src/org/compiere/model/MAcctSchemaGL.java +++ b/org.adempiere.base/src/org/compiere/model/MAcctSchemaGL.java @@ -21,7 +21,9 @@ import java.util.ArrayList; import java.util.Properties; import org.compiere.util.CLogger; +import org.compiere.util.Env; import org.compiere.util.KeyNamePair; +import org.idempiere.cache.ImmutablePOSupport; @@ -33,15 +35,13 @@ import org.compiere.util.KeyNamePair; * @author victor.perez@e-evolution.com, www.e-evolution.com *
  • RF [ 2214883 ] Remove SQL code and Replace for Query http://sourceforge.net/tracker/index.php?func=detail&aid=2214883&group_id=176962&atid=879335 */ -public class MAcctSchemaGL extends X_C_AcctSchema_GL +public class MAcctSchemaGL extends X_C_AcctSchema_GL implements ImmutablePOSupport { - - /** - * - */ - private static final long serialVersionUID = 5303102649110271896L; - + /** + * + */ + private static final long serialVersionUID = -53120274583638950L; /** * Get Accounting Schema GL Info @@ -89,6 +89,37 @@ public class MAcctSchemaGL extends X_C_AcctSchema_GL super(ctx, rs, trxName); } // MAcctSchemaGL + /** + * + * @param copy + */ + public MAcctSchemaGL(MAcctSchemaGL copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MAcctSchemaGL(Properties ctx, MAcctSchemaGL copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MAcctSchemaGL(Properties ctx, MAcctSchemaGL copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Get Acct Info list * @return list @@ -131,4 +162,13 @@ public class MAcctSchemaGL extends X_C_AcctSchema_GL return true; } // beforeSave + @Override + public MAcctSchemaGL markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MAcctSchemaGL diff --git a/org.adempiere.base/src/org/compiere/model/MActivity.java b/org.adempiere.base/src/org/compiere/model/MActivity.java index 0cfa7e8af8..9023ae69c0 100644 --- a/org.adempiere.base/src/org/compiere/model/MActivity.java +++ b/org.adempiere.base/src/org/compiere/model/MActivity.java @@ -19,7 +19,9 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** @@ -31,18 +33,28 @@ import org.compiere.util.CCache; * @author Teo Sarca, www.arhipac.ro *
  • FR [ 2736867 ] Add caching support to MActivity */ -public class MActivity extends X_C_Activity +public class MActivity extends X_C_Activity implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 3014706648686670575L; + private static final long serialVersionUID = -5939026057597689130L; /** Static Cache */ - private static CCache s_cache = new CCache(Table_Name, 30); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 30); /** - * Get/Load Activity [CACHED] + * Get/Load Activity [CACHED] (immutable) + * @param C_Activity_ID + * @return activity or null + */ + public static MActivity get(int C_Activity_ID) + { + return get(Env.getCtx(), C_Activity_ID); + } + + /** + * Get/Load Activity [CACHED] (immutable) * @param ctx context * @param C_Activity_ID * @return activity or null @@ -54,22 +66,19 @@ public class MActivity extends X_C_Activity return null; } // Try cache - MActivity activity = s_cache.get(C_Activity_ID); + MActivity activity = s_cache.get(ctx, C_Activity_ID, e -> new MActivity(ctx, e)); if (activity != null) { return activity; } // Load from DB - activity = new MActivity(ctx, C_Activity_ID, null); + activity = new MActivity(ctx, C_Activity_ID, (String)null); if (activity.get_ID() == C_Activity_ID) { - s_cache.put(C_Activity_ID, activity); + s_cache.put(C_Activity_ID, activity, e -> new MActivity(Env.getCtx(), e)); + return activity; } - else - { - activity = null; - } - return activity; + return null; } /** @@ -94,6 +103,36 @@ public class MActivity extends X_C_Activity super(ctx, rs, trxName); } // MActivity + /** + * + * @param copy + */ + public MActivity(MActivity copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MActivity(Properties ctx, MActivity copy) + { + this(ctx, copy, (String)null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MActivity(Properties ctx, MActivity copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } /** * After Save. @@ -131,4 +170,13 @@ public class MActivity extends X_C_Activity return success; } // afterDelete + @Override + public MActivity markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MActivity diff --git a/org.adempiere.base/src/org/compiere/model/MAlertProcessor.java b/org.adempiere.base/src/org/compiere/model/MAlertProcessor.java index 2c172a86ff..f538ca73d6 100644 --- a/org.adempiere.base/src/org/compiere/model/MAlertProcessor.java +++ b/org.adempiere.base/src/org/compiere/model/MAlertProcessor.java @@ -21,7 +21,6 @@ import java.sql.Timestamp; import java.util.List; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; @@ -82,8 +81,8 @@ public class MAlertProcessor extends X_AD_AlertProcessor super(ctx, rs, trxName); } // MAlertProcessor - /** Cache: AD_AlertProcessor -> Alerts array */ - private static CCache s_cacheAlerts = new CCache(I_AD_Alert.Table_Name, "AD_Alert|AlertProcessor", 10, false); + /** Cache: Alerts array */ + private MAlert[] m_alerts = null; /** * Get Server ID @@ -145,9 +144,8 @@ public class MAlertProcessor extends X_AD_AlertProcessor */ public MAlert[] getAlerts (boolean reload) { - MAlert[] alerts = s_cacheAlerts.get(get_ID()); - if (alerts != null && !reload) - return alerts; + if (m_alerts != null && !reload) + return m_alerts; final String whereClause ="AD_AlertProcessor_ID=?"; List list = new Query(getCtx(), I_AD_Alert.Table_Name, whereClause, null) @@ -156,10 +154,9 @@ public class MAlertProcessor extends X_AD_AlertProcessor .list(); // - alerts = new MAlert[list.size ()]; - list.toArray (alerts); - s_cacheAlerts.put(get_ID(), alerts); - return alerts; + m_alerts = new MAlert[list.size ()]; + list.toArray (m_alerts); + return m_alerts; } // getAlerts /** diff --git a/org.adempiere.base/src/org/compiere/model/MAsset.java b/org.adempiere.base/src/org/compiere/model/MAsset.java index ed65eb442c..fc2dc004fc 100644 --- a/org.adempiere.base/src/org/compiere/model/MAsset.java +++ b/org.adempiere.base/src/org/compiere/model/MAsset.java @@ -262,6 +262,38 @@ public class MAsset extends X_A_Asset } + /** + * + * @param copy + */ + public MAsset(MAsset copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MAsset(Properties ctx, MAsset copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MAsset(Properties ctx, MAsset copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_DateAcct = copy.m_DateAcct; + } + /** * Set Asset Group; also it sets other default fields * @param assetGroup @@ -278,7 +310,7 @@ public class MAsset extends X_A_Asset } public MAssetGroup getAssetGroup() { - return MAssetGroup.get(getCtx(), getA_Asset_Group_ID()); + return MAssetGroup.getCopy(getCtx(), getA_Asset_Group_ID(), get_TrxName()); } /** diff --git a/org.adempiere.base/src/org/compiere/model/MAssetAcct.java b/org.adempiere.base/src/org/compiere/model/MAssetAcct.java index cc7cfa8ead..f29753f427 100644 --- a/org.adempiere.base/src/org/compiere/model/MAssetAcct.java +++ b/org.adempiere.base/src/org/compiere/model/MAssetAcct.java @@ -6,20 +6,22 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.Env; import org.compiere.util.TimeUtil; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Asset Acct Model * @author Teo Sarca, SC ARHIPAC SERVICE SRL */ -public class MAssetAcct extends X_A_Asset_Acct +public class MAssetAcct extends X_A_Asset_Acct implements ImmutablePOSupport { + /** * */ - private static final long serialVersionUID = -3919172418904053712L; + private static final long serialVersionUID = -8898773839204909595L; /** * DO NOT USE DIRECTLY @@ -38,32 +40,69 @@ public class MAssetAcct extends X_A_Asset_Acct super (ctx, rs, trxName); } - /** Static Cache: A_Asset_Acct_ID -> MAssetAcct */ - private static CCache s_cache = new CCache(Table_Name, 5); + /** + * + * @param copy + */ + public MAssetAcct(MAssetAcct copy) + { + this(Env.getCtx(), copy); + } /** - * Get Asset Accounting (from cache) + * + * @param ctx + * @param copy + */ + public MAssetAcct(Properties ctx, MAssetAcct copy) + { + this(ctx, copy, (String)null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MAssetAcct(Properties ctx, MAssetAcct copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + /** Static Cache: A_Asset_Acct_ID -> MAssetAcct */ + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 5); + + /** + * Get Asset Accounting (from cache) (immutable) + * @param A_Asset_Acct_ID asset accounting id + * @return asset accounting or null if not found + */ + public static MAssetAcct get (int A_Asset_Acct_ID) + { + return get(Env.getCtx(), A_Asset_Acct_ID); + } + + /** + * Get Asset Accounting (from cache) (immutable) * @param ctx context * @param A_Asset_Acct_ID asset accounting id * @return asset accounting or null if not found */ public static MAssetAcct get (Properties ctx, int A_Asset_Acct_ID) { - MAssetAcct acct = s_cache.get(A_Asset_Acct_ID); + MAssetAcct acct = s_cache.get(ctx, A_Asset_Acct_ID, e -> new MAssetAcct(ctx, e)); if (acct != null) + return acct; + + acct = new MAssetAcct(ctx, A_Asset_Acct_ID, (String)null); + if (acct.get_ID() == A_Asset_Acct_ID) { + s_cache.put(A_Asset_Acct_ID, acct, e -> new MAssetAcct(Env.getCtx(), e)); return acct; } - acct = new MAssetAcct(ctx, A_Asset_Acct_ID, null); - if (acct.get_ID() > 0) - { - addToCache(acct); - } - else - { - acct = null; - } - return acct; + return null; } /** @@ -91,22 +130,13 @@ public class MAssetAcct extends X_A_Asset_Acct .setParameters(params) .setOrderBy(COLUMNNAME_ValidFrom+" DESC NULLS LAST") .first(); - if (trxName == null) + if (acct.get_ID() > 0) { - addToCache(acct); + s_cache.put(acct.get_ID(), acct, e -> new MAssetAcct(Env.getCtx(), e)); } return acct; } - private static void addToCache(MAssetAcct acct) - { - if (acct == null || acct.get_ID() <= 0) - { - return; - } - s_cache.put(acct.get_ID(), acct); - } - /** * Create new asset accounting from asset group accounting * @param asset asset @@ -143,7 +173,7 @@ public class MAssetAcct extends X_A_Asset_Acct public MAcctSchema getC_AcctSchema() { - return MAcctSchema.get(getCtx(), getC_AcctSchema_ID()); + return MAcctSchema.getCopy(getCtx(), getC_AcctSchema_ID(), get_TrxName()); } public MAccount getP_Asset_Acct(int M_Product_ID) @@ -162,5 +192,13 @@ public class MAssetAcct extends X_A_Asset_Acct return true; } - + @Override + public MAssetAcct markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // class MAssetAcct diff --git a/org.adempiere.base/src/org/compiere/model/MAssetClass.java b/org.adempiere.base/src/org/compiere/model/MAssetClass.java index 7b602a8bce..c069e6696f 100644 --- a/org.adempiere.base/src/org/compiere/model/MAssetClass.java +++ b/org.adempiere.base/src/org/compiere/model/MAssetClass.java @@ -6,21 +6,23 @@ import java.util.Calendar; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.Env; import org.compiere.util.TimeUtil; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; import org.idempiere.fa.feature.UseLifeImpl; /** Asset Class * @author Teo Sarca, SC Arhipac SRL * @version $Id$ */ -public class MAssetClass extends X_A_Asset_Class +public class MAssetClass extends X_A_Asset_Class implements ImmutablePOSupport { + /** * */ - private static final long serialVersionUID = -6526341869523579715L; + private static final long serialVersionUID = -7805056592418891872L; /** * @@ -40,12 +42,51 @@ public class MAssetClass extends X_A_Asset_Class super (ctx, rs, trxName); } // MAssetClass + /** + * + * @param copy + */ + public MAssetClass(MAssetClass copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MAssetClass(Properties ctx, MAssetClass copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MAssetClass(Properties ctx, MAssetClass copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); + /** Get Asset Class from cache + * @param id A_Asset_Class_ID + * @return MAssetClass or null if not found + */ + public static MAssetClass get(int id) { + return get(Env.getCtx(), id); + } + /** Get Asset Class from cache * @param ctx context - * @param id A_Asset_Class_ID + * @param id A_Asset_Class_ID * @return MAssetClass or null if not found */ public static MAssetClass get(Properties ctx, int id) { @@ -53,14 +94,16 @@ public class MAssetClass extends X_A_Asset_Class return null; } - MAssetClass assetClass = s_cache.get(id); + MAssetClass assetClass = s_cache.get(ctx, id, e -> new MAssetClass(ctx, e)); if (assetClass == null) { - assetClass = new MAssetClass(ctx, id, null); - } - if (assetClass.get_ID() != id) { + assetClass = new MAssetClass(ctx, id, (String)null); + if (assetClass.get_ID() == id) { + s_cache.put(id, assetClass, e -> new MAssetClass(Env.getCtx(), e)); + return assetClass; + } return null; - } - s_cache.put(id, assetClass); + } + return assetClass; } // get @@ -209,4 +252,14 @@ public class MAssetClass extends X_A_Asset_Class } return true; } + + @Override + public MAssetClass markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } diff --git a/org.adempiere.base/src/org/compiere/model/MAssetGroup.java b/org.adempiere.base/src/org/compiere/model/MAssetGroup.java index a7429ca6c3..b954a037f8 100644 --- a/org.adempiere.base/src/org/compiere/model/MAssetGroup.java +++ b/org.adempiere.base/src/org/compiere/model/MAssetGroup.java @@ -3,22 +3,25 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Asset Group Model * @author Teo Sarca, SC ARHIPAC SERVICE SRL */ -public class MAssetGroup extends X_A_Asset_Group +public class MAssetGroup extends X_A_Asset_Group implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -173157506404569463L; + private static final long serialVersionUID = 2605166916393528396L; + /** Cache: ID -> MAssetGroup */ - private static CCache s_cache = new CCache(Table_Name, 10, 0); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 10, 0); /** * Default Constructor @@ -40,6 +43,47 @@ public class MAssetGroup extends X_A_Asset_Group super (ctx, rs, trxName); } // MAssetGroup + /** + * + * @param copy + */ + public MAssetGroup(MAssetGroup copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MAssetGroup(Properties ctx, MAssetGroup copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MAssetGroup(Properties ctx, MAssetGroup copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + /** + * Get Asset Group [CACHE] + * @param A_Asset_Group_ID asset group id + * @return asset group or null + */ + public static MAssetGroup get(int A_Asset_Group_ID) + { + return get(Env.getCtx(), A_Asset_Group_ID); + } + /** * Get Asset Group [CACHE] * @param ctx context @@ -51,17 +95,32 @@ public class MAssetGroup extends X_A_Asset_Group if (A_Asset_Group_ID <= 0) return null; // Try cache - MAssetGroup ag = s_cache.get(A_Asset_Group_ID); + MAssetGroup ag = s_cache.get(ctx, A_Asset_Group_ID, e -> new MAssetGroup(ctx, e)); if (ag != null) return ag; // Load - ag = new MAssetGroup(ctx, A_Asset_Group_ID, null); - if (ag != null && ag.get_ID() != A_Asset_Group_ID) - ag = null; - else - s_cache.put(A_Asset_Group_ID, ag); - // - return ag; + ag = new MAssetGroup(ctx, A_Asset_Group_ID, (String)null); + if (ag.get_ID() == A_Asset_Group_ID) + { + s_cache.put(A_Asset_Group_ID, ag, e -> new MAssetGroup(Env.getCtx(), e)); + return ag; + } + return null; + } + + /** + * Get updateable copy of MAssetGroup from cache + * @param ctx + * @param A_Asset_Group_ID + * @param trxName + * @return MAssetGroup + */ + public static MAssetGroup getCopy(Properties ctx, int A_Asset_Group_ID, String trxName) + { + MAssetGroup grp = get(A_Asset_Group_ID); + if (grp != null) + grp = new MAssetGroup(ctx, grp, trxName); + return grp; } /** @@ -170,5 +229,15 @@ public class MAssetGroup extends X_A_Asset_Group // return true; } + + @Override + public MAssetGroup markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MAssetGroup diff --git a/org.adempiere.base/src/org/compiere/model/MAssetGroupAcct.java b/org.adempiere.base/src/org/compiere/model/MAssetGroupAcct.java index a79471e561..804d1b1353 100644 --- a/org.adempiere.base/src/org/compiere/model/MAssetGroupAcct.java +++ b/org.adempiere.base/src/org/compiere/model/MAssetGroupAcct.java @@ -73,14 +73,7 @@ public class MAssetGroupAcct extends X_A_Asset_Group_Acct if (m_parent == null) { int A_Asset_Group_ID = getA_Asset_Group_ID(); - if (is_new()) - { - m_parent = new MAssetGroup(getCtx(), A_Asset_Group_ID, get_TrxName()); - } - else - { - m_parent = MAssetGroup.get(getCtx(), A_Asset_Group_ID); - } + m_parent = MAssetGroup.getCopy(getCtx(), A_Asset_Group_ID, get_TrxName()); } return m_parent; } diff --git a/org.adempiere.base/src/org/compiere/model/MAssetType.java b/org.adempiere.base/src/org/compiere/model/MAssetType.java index 34448fd8b4..bcbe58cf11 100644 --- a/org.adempiere.base/src/org/compiere/model/MAssetType.java +++ b/org.adempiere.base/src/org/compiere/model/MAssetType.java @@ -4,19 +4,20 @@ import java.sql.ResultSet; import java.util.Properties; import org.compiere.util.ArhRuntimeException; -import org.compiere.util.CCache; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Asset Type * @author Teo Sarca, SC ARHIPAC SERVICE SRL */ -public class MAssetType extends X_A_Asset_Type +public class MAssetType extends X_A_Asset_Type implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -1371478760221357780L; + private static final long serialVersionUID = -5511421754249363729L; private static final String A_ASSET_TYPE_MFX = "MFX"; // HARDCODED - you must create a Asset Type with Value=MFX to indicate is Fixed Asset private static final String A_ASSET_TYPE_INV = "INV"; // HARDCODED - you must create a Asset Type with Value=MFX to indicate is Inventory Object @@ -36,9 +37,20 @@ public class MAssetType extends X_A_Asset_Type }; /** Static Cache: A_Asset_Type.A_Asset_Type_ID-> MAssetType */ - private static CCache s_cache = new CCache(Table_Name, 10, 0); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 10, 0); - /** Get Asset Type + /** + * Get Asset Type from cache (immutable) + * @param A_Asset_Type_ID + * @return asset type object + */ + public static MAssetType get (int A_Asset_Type_ID) + { + return get(Env.getCtx(), A_Asset_Type_ID); + } + + /** + * Get Asset Type from cache (immutable) * @param ctx context * @param A_Asset_Type_ID * @return asset type object @@ -47,29 +59,17 @@ public class MAssetType extends X_A_Asset_Type { if (A_Asset_Type_ID <= 0) return null; - MAssetType o = s_cache.get(A_Asset_Type_ID); + MAssetType o = s_cache.get(ctx, A_Asset_Type_ID, e -> new MAssetType(ctx, e)); if (o != null) return o; - o = new MAssetType(ctx, A_Asset_Type_ID, null); - if (o.get_ID() > 0) { - s_cache.put(A_Asset_Type_ID, o); + o = new MAssetType(ctx, A_Asset_Type_ID, (String)null); + if (o.get_ID() == A_Asset_Type_ID) { + s_cache.put(A_Asset_Type_ID, o, e -> new MAssetType(Env.getCtx(), e)); return o; } return null; } - /** Get Asset Type - * @param ctx context - * @param id id as Number - * @return asset type object - */ - public static MAssetType get (Properties ctx, Object id) - { - if (id == null) - return null; - return get(ctx, ((Number)id).intValue()); - } - /** Standard Constructor */ public MAssetType (Properties ctx, int A_Asset_Type_ID, String trxName) { @@ -82,6 +82,37 @@ public class MAssetType extends X_A_Asset_Type super (ctx, rs, trxName); } + /** + * + * @param copy + */ + public MAssetType(MAssetType copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MAssetType(Properties ctx, MAssetType copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MAssetType(Properties ctx, MAssetType copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** Is Fixed Asset */ public boolean isFixedAsset() @@ -197,6 +228,15 @@ public class MAssetType extends X_A_Asset_Type return true; } + @Override + public MAssetType markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + /** Callout Class */ public static class Callout extends CalloutEngine { diff --git a/org.adempiere.base/src/org/compiere/model/MAttribute.java b/org.adempiere.base/src/org/compiere/model/MAttribute.java index 7b56e68840..333c1cdd5e 100644 --- a/org.adempiere.base/src/org/compiere/model/MAttribute.java +++ b/org.adempiere.base/src/org/compiere/model/MAttribute.java @@ -20,6 +20,7 @@ import java.math.BigDecimal; import java.sql.ResultSet; import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.logging.Level; @@ -27,6 +28,7 @@ import java.util.logging.Level; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; /** * Product Attribute @@ -34,13 +36,12 @@ import org.compiere.util.Env; * @author Jorg Janke * @version $Id: MAttribute.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $ */ -public class MAttribute extends X_M_Attribute +public class MAttribute extends X_M_Attribute implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 7869800574413317999L; - + private static final long serialVersionUID = 7513117649181926813L; /** * Get Attributes Of Client @@ -112,6 +113,38 @@ public class MAttribute extends X_M_Attribute super(ctx, rs, trxName); } // MAttribute + /** + * + * @param copy + */ + public MAttribute(MAttribute copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MAttribute(Properties ctx, MAttribute copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MAttribute(Properties ctx, MAttribute copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_values = copy.m_values != null ? Arrays.stream(copy.m_values).map(e -> {return new MAttributeValue(ctx, e, trxName);}).toArray(MAttributeValue[]::new) : null; + } + /** Values */ private MAttributeValue[] m_values = null; @@ -127,7 +160,7 @@ public class MAttribute extends X_M_Attribute List list = new ArrayList(); if (!isMandatory()) list.add (null); - list = new Query(getCtx(),I_M_AttributeValue.Table_Name,whereClause,null) + list = new Query(getCtx(),I_M_AttributeValue.Table_Name,whereClause,get_TrxName()) .setParameters(getM_Attribute_ID()) .setOrderBy("Value") .list(); @@ -270,4 +303,13 @@ public class MAttribute extends X_M_Attribute return success; } // afterSave + @Override + public MAttribute markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MAttribute diff --git a/org.adempiere.base/src/org/compiere/model/MAttributeSet.java b/org.adempiere.base/src/org/compiere/model/MAttributeSet.java index a03dd23c34..8de2c4d4c9 100644 --- a/org.adempiere.base/src/org/compiere/model/MAttributeSet.java +++ b/org.adempiere.base/src/org/compiere/model/MAttributeSet.java @@ -20,12 +20,15 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Properties; import org.adempiere.exceptions.DBException; -import org.compiere.util.CCache; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Product Attribute Set @@ -36,13 +39,23 @@ import org.compiere.util.DB; * @author Teo Sarca, www.arhipac.ro *
  • FR [ 2214883 ] Remove SQL code and Replace for Query */ -public class MAttributeSet extends X_M_AttributeSet +public class MAttributeSet extends X_M_AttributeSet implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -187568054160926817L; + private static final long serialVersionUID = -6570475541239019293L; + /** + * Get MAttributeSet from Cache + * @param M_AttributeSet_ID id + * @return MAttributeSet + */ + public static MAttributeSet get (int M_AttributeSet_ID) + { + return get(Env.getCtx(), M_AttributeSet_ID); + } + /** * Get MAttributeSet from Cache * @param ctx context @@ -52,18 +65,35 @@ public class MAttributeSet extends X_M_AttributeSet public static MAttributeSet get (Properties ctx, int M_AttributeSet_ID) { Integer key = Integer.valueOf(M_AttributeSet_ID); - MAttributeSet retValue = (MAttributeSet) s_cache.get (key); + MAttributeSet retValue = s_cache.get (ctx, key, e -> new MAttributeSet(ctx, e)); if (retValue != null) return retValue; - retValue = new MAttributeSet (ctx, M_AttributeSet_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MAttributeSet (ctx, M_AttributeSet_ID, (String)null); + if (retValue.get_ID () == M_AttributeSet_ID) + { + s_cache.put (key, retValue, e -> new MAttributeSet(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MAttributeSet from cache + * @param ctx + * @param M_AttributeSet_ID + * @return MAttributeSet + */ + public static MAttributeSet getCopy(Properties ctx, int M_AttributeSet_ID, String trxName) + { + MAttributeSet mas = get(M_AttributeSet_ID); + if (mas != null) + mas = new MAttributeSet(ctx, mas, trxName); + return mas; + } + /** Cache */ - private static CCache s_cache - = new CCache (Table_Name, 20); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache (Table_Name, 20); /** @@ -100,17 +130,53 @@ public class MAttributeSet extends X_M_AttributeSet super(ctx, rs, trxName); } // MAttributeSet + /** + * + * @param copy + */ + public MAttributeSet(MAttributeSet copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MAttributeSet(Properties ctx, MAttributeSet copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MAttributeSet(Properties ctx, MAttributeSet copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_instanceAttributes = copy.m_instanceAttributes != null ? Arrays.stream(copy.m_instanceAttributes).map(e -> {return new MAttribute(ctx, e, trxName);}).toArray(MAttribute[]::new) : null; + this.m_productAttributes = copy.m_productAttributes != null ? Arrays.stream(copy.m_productAttributes).map(e -> {return new MAttribute(ctx, e, trxName);}).toArray(MAttribute[]::new) : null; + this.m_excludes = copy.m_excludes != null ? Arrays.copyOf(copy.m_excludes, copy.m_excludes.length) : null; + this.m_excludeLots = copy.m_excludeLots != null ? Arrays.copyOf(copy.m_excludeLots, copy.m_excludeLots.length) : null; + this.m_excludeSerNos = copy.m_excludeSerNos != null ? Arrays.copyOf(copy.m_excludeSerNos, copy.m_excludeSerNos.length) : null; + } + /** Instance Attributes */ private MAttribute[] m_instanceAttributes = null; /** Instance Attributes */ private MAttribute[] m_productAttributes = null; /** Entry Exclude */ - private X_M_AttributeSetExclude[] m_excludes = null; + private MAttributeSetExclude[] m_excludes = null; /** Lot create Exclude */ - private X_M_LotCtlExclude[] m_excludeLots = null; + private MLotCtlExclude[] m_excludeLots = null; /** Serial No create Exclude */ - private X_M_SerNoCtlExclude[] m_excludeSerNos = null; + private MSerNoCtlExclude[] m_excludeSerNos = null; /** * Get Attribute Array @@ -158,11 +224,15 @@ public class MAttributeSet extends X_M_AttributeSet { m_instanceAttributes = new MAttribute[list.size()]; list.toArray (m_instanceAttributes); + if (m_instanceAttributes.length > 0 && is_Immutable()) + Arrays.stream(m_instanceAttributes).forEach(e -> e.markImmutable()); } else { m_productAttributes = new MAttribute[list.size()]; list.toArray (m_productAttributes); + if (m_productAttributes.length > 0 && is_Immutable()) + Arrays.stream(m_productAttributes).forEach(e -> e.markImmutable()); } } // @@ -245,12 +315,12 @@ public class MAttributeSet extends X_M_AttributeSet private void loadExcludes() { if (m_excludes == null) { - final String whereClause = X_M_AttributeSetExclude.COLUMNNAME_M_AttributeSet_ID+"=?"; - List list = new Query(getCtx(), X_M_AttributeSetExclude.Table_Name, whereClause, null) + final String whereClause = MAttributeSetExclude.COLUMNNAME_M_AttributeSet_ID+"=?"; + List list = new Query(getCtx(), MAttributeSetExclude.Table_Name, whereClause, null) .setParameters(get_ID()) .setOnlyActiveRecords(true) .list(); - m_excludes = new X_M_AttributeSetExclude[list.size ()]; + m_excludes = new MAttributeSetExclude[list.size ()]; list.toArray (m_excludes); } } @@ -267,12 +337,12 @@ public class MAttributeSet extends X_M_AttributeSet return true; if (m_excludeLots == null) { - final String whereClause = X_M_LotCtlExclude.COLUMNNAME_M_LotCtl_ID+"=?"; - List list = new Query(getCtx(), X_M_LotCtlExclude.Table_Name, whereClause, null) + final String whereClause = MLotCtlExclude.COLUMNNAME_M_LotCtl_ID+"=?"; + List list = new Query(getCtx(), MLotCtlExclude.Table_Name, whereClause, null) .setParameters(getM_LotCtl_ID()) .setOnlyActiveRecords(true) .list(); - m_excludeLots = new X_M_LotCtlExclude[list.size ()]; + m_excludeLots = new MLotCtlExclude[list.size ()]; list.toArray (m_excludeLots); } // Find it @@ -301,12 +371,12 @@ public class MAttributeSet extends X_M_AttributeSet return true; if (m_excludeSerNos == null) { - final String whereClause = X_M_SerNoCtlExclude.COLUMNNAME_M_SerNoCtl_ID+"=?"; - List list = new Query(getCtx(), X_M_SerNoCtlExclude.Table_Name, whereClause, null) + final String whereClause = MSerNoCtlExclude.COLUMNNAME_M_SerNoCtl_ID+"=?"; + List list = new Query(getCtx(), MSerNoCtlExclude.Table_Name, whereClause, null) .setParameters(getM_SerNoCtl_ID()) .setOnlyActiveRecords(true) .list(); - m_excludeSerNos = new X_M_SerNoCtlExclude[list.size ()]; + m_excludeSerNos = new MSerNoCtlExclude[list.size ()]; list.toArray (m_excludeSerNos); } // Find it @@ -442,4 +512,17 @@ public class MAttributeSet extends X_M_AttributeSet return success; } // afterSave + @Override + public MAttributeSet markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_instanceAttributes != null && m_instanceAttributes.length > 0) + Arrays.stream(m_instanceAttributes).forEach(e -> e.markImmutable()); + if (m_productAttributes != null && m_productAttributes.length > 0) + Arrays.stream(m_productAttributes).forEach(e -> e.markImmutable()); + return this; + } + } // MAttributeSet diff --git a/org.adempiere.base/src/org/compiere/model/MAttributeSetExclude.java b/org.adempiere.base/src/org/compiere/model/MAttributeSetExclude.java new file mode 100644 index 0000000000..c03cd3103d --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/MAttributeSetExclude.java @@ -0,0 +1,89 @@ +/********************************************************************** +* 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: * +* - Trek Global Corporation * +* - Heng Sin Low * +**********************************************************************/ +package org.compiere.model; + +import java.sql.ResultSet; +import java.util.Properties; + +import org.compiere.util.Env; + +/** + * @author hengsin + * + */ +public class MAttributeSetExclude extends X_M_AttributeSetExclude { + + /** + * + */ + private static final long serialVersionUID = -2977401481745176882L; + + /** + * @param ctx + * @param M_AttributeSetExclude_ID + * @param trxName + */ + public MAttributeSetExclude(Properties ctx, int M_AttributeSetExclude_ID, String trxName) { + super(ctx, M_AttributeSetExclude_ID, trxName); + } + + /** + * @param ctx + * @param rs + * @param trxName + */ + public MAttributeSetExclude(Properties ctx, ResultSet rs, String trxName) { + super(ctx, rs, trxName); + } + + /** + * + * @param copy + */ + public MAttributeSetExclude(MAttributeSetExclude copy) { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MAttributeSetExclude(Properties ctx, MAttributeSetExclude copy) { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MAttributeSetExclude(Properties ctx, MAttributeSetExclude copy, String trxName) { + this(ctx, 0, trxName); + copyPO(copy); + } +} diff --git a/org.adempiere.base/src/org/compiere/model/MAttributeValue.java b/org.adempiere.base/src/org/compiere/model/MAttributeValue.java index e8c70d96eb..620f2e30f6 100644 --- a/org.adempiere.base/src/org/compiere/model/MAttributeValue.java +++ b/org.adempiere.base/src/org/compiere/model/MAttributeValue.java @@ -19,6 +19,8 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; +import org.compiere.util.Env; + /** * Product Attribute Value * @@ -62,6 +64,36 @@ public class MAttributeValue extends X_M_AttributeValue super(ctx, rs, trxName); } // MAttributeValue + /** + * + * @param copy + */ + public MAttributeValue(MAttributeValue copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MAttributeValue(Properties ctx, MAttributeValue copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MAttributeValue(Properties ctx, MAttributeValue copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } /** * String Representation * @return info diff --git a/org.adempiere.base/src/org/compiere/model/MBOM.java b/org.adempiere.base/src/org/compiere/model/MBOM.java index e2ccd91c9e..c8ff99a0ef 100644 --- a/org.adempiere.base/src/org/compiere/model/MBOM.java +++ b/org.adempiere.base/src/org/compiere/model/MBOM.java @@ -20,25 +20,36 @@ import java.sql.ResultSet; import java.util.List; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.CLogger; +import org.compiere.util.Env; import org.compiere.util.Msg; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * BOM Model * @author Jorg Janke * @version $Id: MBOM.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $ */ -public class MBOM extends X_M_BOM +public class MBOM extends X_M_BOM implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -8885316310068284701L; - + private static final long serialVersionUID = -6311001492891936078L; /** - * Get BOM from Cache + * Get BOM from Cache (immutable) + * @param M_BOM_ID id + * @return MBOM + */ + public static MBOM get (int M_BOM_ID) + { + return get(Env.getCtx(), M_BOM_ID); + } + + /** + * Get BOM from Cache (immutable) * @param ctx context * @param M_BOM_ID id * @return MBOM @@ -46,15 +57,33 @@ public class MBOM extends X_M_BOM public static MBOM get (Properties ctx, int M_BOM_ID) { Integer key = Integer.valueOf(M_BOM_ID); - MBOM retValue = (MBOM) s_cache.get (key); + MBOM retValue = (MBOM) s_cache.get (ctx, key, e -> new MBOM(ctx, e)); if (retValue != null) return retValue; - retValue = new MBOM (ctx, M_BOM_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MBOM (ctx, M_BOM_ID, (String)null); + if (retValue.get_ID () == M_BOM_ID) + { + s_cache.put (key, retValue, e -> new MBOM(Env.getCtx(), e)); + return retValue.markImmutable(); + } + return null; } // get + /** + * Get updateable copy of MBOM from cache + * @param ctx + * @param M_BOM_ID + * @param trxName + * @return MBOM + */ + public static MBOM getCopy(Properties ctx, int M_BOM_ID, String trxName) + { + MBOM bom = get(M_BOM_ID); + if (bom != null) + bom = new MBOM(ctx, bom, trxName); + return bom; + } + /** * Get BOMs Of Product * @param ctx context @@ -80,8 +109,8 @@ public class MBOM extends X_M_BOM } // getOfProduct /** Cache */ - private static CCache s_cache - = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache(Table_Name, 20); /** Logger */ @SuppressWarnings("unused") private static CLogger s_log = CLogger.getCLogger (MBOM.class); @@ -116,6 +145,37 @@ public class MBOM extends X_M_BOM super (ctx, rs, trxName); } // MBOM + /** + * + * @param copy + */ + public MBOM(MBOM copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MBOM(Properties ctx, MBOM copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MBOM(Properties ctx, MBOM copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Before Save * @param newRecord new @@ -161,4 +221,12 @@ public class MBOM extends X_M_BOM return true; } // beforeSave + @Override + public MBOM markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } } // MBOM diff --git a/org.adempiere.base/src/org/compiere/model/MBOMProduct.java b/org.adempiere.base/src/org/compiere/model/MBOMProduct.java index bbde8c3dbd..7a11eaad78 100644 --- a/org.adempiere.base/src/org/compiere/model/MBOMProduct.java +++ b/org.adempiere.base/src/org/compiere/model/MBOMProduct.java @@ -113,7 +113,7 @@ public class MBOMProduct extends X_M_BOMProduct private MBOM getBOM() { if (m_bom == null && getM_BOM_ID() != 0) - m_bom = MBOM.get(getCtx(), getM_BOM_ID()); + m_bom = MBOM.getCopy(getCtx(), getM_BOM_ID(), get_TrxName()); return m_bom; } // getBOM diff --git a/org.adempiere.base/src/org/compiere/model/MBPBankAccount.java b/org.adempiere.base/src/org/compiere/model/MBPBankAccount.java index 042e6d1c5f..bc1ffa62a9 100644 --- a/org.adempiere.base/src/org/compiere/model/MBPBankAccount.java +++ b/org.adempiere.base/src/org/compiere/model/MBPBankAccount.java @@ -115,6 +115,38 @@ public class MBPBankAccount extends X_C_BP_BankAccount setA_Country(location.getCountryName()); } // MBP_BankAccount + /** + * + * @param copy + */ + public MBPBankAccount(MBPBankAccount copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MBPBankAccount(Properties ctx, MBPBankAccount copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MBPBankAccount(Properties ctx, MBPBankAccount copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_bank = copy.m_bank != null ? new MBank(ctx, copy.m_bank, trxName) : null; + } + /** Bank Link */ private MBank m_bank = null; diff --git a/org.adempiere.base/src/org/compiere/model/MBPGroup.java b/org.adempiere.base/src/org/compiere/model/MBPGroup.java index 74581087eb..6353b93838 100644 --- a/org.adempiere.base/src/org/compiere/model/MBPGroup.java +++ b/org.adempiere.base/src/org/compiere/model/MBPGroup.java @@ -23,11 +23,12 @@ import java.sql.ResultSet; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; -import org.compiere.util.Util; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.IntPOCopyCache; /** * Business Partner Group Model @@ -35,33 +36,36 @@ import org.compiere.util.Util; * @author Jorg Janke * @version $Id: MBPGroup.java,v 1.4 2006/09/23 15:54:22 jjanke Exp $ */ -public class MBPGroup extends X_C_BP_Group +public class MBPGroup extends X_C_BP_Group implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 8897399796117872715L; + private static final long serialVersionUID = 1155912422087010656L; /** - * Get MBPGroup from Cache + * Get MBPGroup from Cache (immutable) + * @param C_BP_Group_ID id + * @return MBPGroup + */ + public static MBPGroup get (int C_BP_Group_ID) + { + return get(Env.getCtx(), C_BP_Group_ID); + } + + /** + * Get MBPGroup from Cache (immutable) * @param ctx context * @param C_BP_Group_ID id * @return MBPGroup */ public static MBPGroup get (Properties ctx, int C_BP_Group_ID) { - Integer key = Integer.valueOf(C_BP_Group_ID); - MBPGroup retValue = (MBPGroup) s_cache.get (key); - if (retValue != null) - return retValue; - retValue = new MBPGroup (ctx, C_BP_Group_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + return get(ctx, C_BP_Group_ID, (String)null); } // get /** - * + * Get MBPGroup from cache (immutable) * @param ctx * @param C_BP_Group_ID * @param trxName @@ -69,10 +73,32 @@ public class MBPGroup extends X_C_BP_Group */ public static MBPGroup get (Properties ctx, int C_BP_Group_ID, String trxName) { - if (Util.isEmpty(trxName, true)) - return get(ctx, C_BP_Group_ID); - else - return new MBPGroup (ctx, C_BP_Group_ID, trxName); + Integer key = Integer.valueOf(C_BP_Group_ID); + MBPGroup retValue = s_cache.get (ctx, key, e -> new MBPGroup(ctx, e)); + if (retValue != null) + return retValue; + retValue = new MBPGroup (ctx, C_BP_Group_ID, trxName); + if (retValue.get_ID () == C_BP_Group_ID) + { + s_cache.put (key, retValue, e -> new MBPGroup(Env.getCtx(), e)); + return retValue; + } + return null; + } + + /** + * Get updateable copy of MBPGroup from cache + * @param ctx + * @param C_BP_Group_ID + * @param trxName + * @return MBPGroup + */ + public static MBPGroup getCopy(Properties ctx, int C_BP_Group_ID, String trxName) + { + MBPGroup group = get(ctx, C_BP_Group_ID, trxName); + if (group != null) + group = new MBPGroup(ctx, group, trxName); + return group; } /** @@ -84,7 +110,7 @@ public class MBPGroup extends X_C_BP_Group { int AD_Client_ID = Env.getAD_Client_ID(ctx); Integer key = Integer.valueOf(AD_Client_ID); - MBPGroup retValue = (MBPGroup) s_cacheDefault.get (key); + MBPGroup retValue = s_cacheDefault.get (key, e -> new MBPGroup(ctx, e)); if (retValue != null) return retValue; @@ -100,9 +126,11 @@ public class MBPGroup extends X_C_BP_Group rs = pstmt.executeQuery (); if (rs.next ()) { - retValue = new MBPGroup (ctx, rs, null); - if (retValue.get_ID () != 0) - s_cacheDefault.put (key, retValue); + retValue = new MBPGroup (ctx, rs, (String)null); + if (retValue.get_ID () != 0) + { + s_cacheDefault.put (key, retValue, e -> new MBPGroup(Env.getCtx(), e)); + } } } catch (Exception e) @@ -162,11 +190,11 @@ public class MBPGroup extends X_C_BP_Group } // getOfBPartner /** Cache */ - private static CCache s_cache - = new CCache(Table_Name, 10); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache(Table_Name, 10); /** Default Cache */ - private static CCache s_cacheDefault - = new CCache(Table_Name, MBPGroup.class.getName()+".Default", 5); + private static IntPOCopyCache s_cacheDefault + = new IntPOCopyCache(Table_Name, MBPGroup.class.getName()+".Default", 5); /** Logger */ private static CLogger s_log = CLogger.getCLogger (MBPGroup.class); @@ -200,6 +228,36 @@ public class MBPGroup extends X_C_BP_Group super(ctx, rs, trxName); } // MBPGroup + /** + * + * @param copy + */ + public MBPGroup(MBPGroup copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MBPGroup(Properties ctx, MBPGroup copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MBPGroup(Properties ctx, MBPGroup copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } /** * Get Credit Watch Percent @@ -246,4 +304,12 @@ public class MBPGroup extends X_C_BP_Group return success; } // afterSave + @Override + public MBPGroup markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } } // MBPGroup diff --git a/org.adempiere.base/src/org/compiere/model/MBPartner.java b/org.adempiere.base/src/org/compiere/model/MBPartner.java index 4e00562582..535867e181 100644 --- a/org.adempiere.base/src/org/compiere/model/MBPartner.java +++ b/org.adempiere.base/src/org/compiere/model/MBPartner.java @@ -21,6 +21,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Arrays; import java.util.Properties; import java.util.logging.Level; @@ -28,6 +29,7 @@ import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; +import org.idempiere.cache.ImmutablePOSupport; /** * Business Partner Model @@ -42,12 +44,12 @@ import org.compiere.util.Msg; *
  • BF [ 2041226 ] BP Open Balance should count only Completed Invoice *
  • BF [ 2498949 ] BP Get Not Invoiced Shipment Value return null */ -public class MBPartner extends X_C_BPartner +public class MBPartner extends X_C_BPartner implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 5534148976588041343L; + private static final long serialVersionUID = 2256035503713773448L; /** * Get Empty Template Business Partner @@ -323,7 +325,43 @@ public class MBPartner extends X_C_BPartner setC_BP_Group_ID(impBP.getC_BP_Group_ID()); } // MBPartner - + /** + * + * @param copy + */ + public MBPartner(MBPartner copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MBPartner(Properties ctx, MBPartner copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MBPartner(Properties ctx, MBPartner copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_contacts = copy.m_contacts != null ? Arrays.stream(copy.m_contacts).map(e -> {return new MUser(ctx, e, trxName);}).toArray(MUser[]::new) : null; + this.m_locations = copy.m_locations != null ? Arrays.stream(copy.m_locations).map(e -> {return new MBPartnerLocation(ctx, e, trxName);}).toArray(MBPartnerLocation[]::new) : null; + this.m_accounts = copy.m_accounts != null ? Arrays.stream(copy.m_accounts).map(e -> {return new MBPBankAccount(ctx, e, trxName);}).toArray(MBPBankAccount[]::new) : null; + this.m_primaryC_BPartner_Location_ID = copy.m_primaryC_BPartner_Location_ID; + this.m_primaryAD_User_ID = copy.m_primaryAD_User_ID; + this.m_group = copy.m_group != null ? new MBPGroup(ctx, copy.m_group, trxName) : null; + } + /** Users */ protected MUser[] m_contacts = null; /** Addressed */ @@ -843,7 +881,7 @@ public class MBPartner extends X_C_BPartner if (getC_BP_Group_ID() == 0) m_group = MBPGroup.getDefault(getCtx()); else - m_group = MBPGroup.get(getCtx(), getC_BP_Group_ID(), get_TrxName()); + m_group = MBPGroup.getCopy(getCtx(), getC_BP_Group_ID(), get_TrxName()); } return m_group; } // getBPGroup @@ -994,4 +1032,13 @@ public class MBPartner extends X_C_BPartner return true; } + @Override + public MBPartner markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MBPartner diff --git a/org.adempiere.base/src/org/compiere/model/MBPartnerLocation.java b/org.adempiere.base/src/org/compiere/model/MBPartnerLocation.java index dc3866976c..8562d64405 100644 --- a/org.adempiere.base/src/org/compiere/model/MBPartnerLocation.java +++ b/org.adempiere.base/src/org/compiere/model/MBPartnerLocation.java @@ -20,6 +20,8 @@ import java.sql.ResultSet; import java.util.List; import java.util.Properties; +import org.compiere.util.Env; + /** * Partner Location Model * @@ -122,6 +124,40 @@ public class MBPartnerLocation extends X_C_BPartner_Location { super(ctx, rs, trxName); } // MBPartner_Location + /** + * + * @param copy + */ + public MBPartnerLocation(MBPartnerLocation copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MBPartnerLocation(Properties ctx, MBPartnerLocation copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MBPartnerLocation(Properties ctx, MBPartnerLocation copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_location = copy.m_location != null ? new MLocation(ctx, copy.m_location, trxName) : null; + this.m_uniqueName = copy.m_uniqueName; + this.m_unique = copy.m_unique; + } + /** Cached Location */ private MLocation m_location = null; /** Unique Name */ @@ -136,7 +172,7 @@ public class MBPartnerLocation extends X_C_BPartner_Location { */ public MLocation getLocation(boolean requery) { if (requery || m_location == null) - m_location = MLocation.get(getCtx(), getC_Location_ID(), get_TrxName()); + m_location = MLocation.getCopy(getCtx(), getC_Location_ID(), get_TrxName()); return m_location; } // getLocation diff --git a/org.adempiere.base/src/org/compiere/model/MBank.java b/org.adempiere.base/src/org/compiere/model/MBank.java index 93e3c4ec04..817de502cd 100644 --- a/org.adempiere.base/src/org/compiere/model/MBank.java +++ b/org.adempiere.base/src/org/compiere/model/MBank.java @@ -19,7 +19,9 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Bank Model @@ -27,16 +29,25 @@ import org.compiere.util.CCache; * @author Jorg Janke * @version $Id: MBank.java,v 1.2 2006/07/30 00:51:05 jjanke Exp $ */ -public class MBank extends X_C_Bank -{ +public class MBank extends X_C_Bank implements ImmutablePOSupport +{ /** * */ - private static final long serialVersionUID = 3459010882027283811L; - + private static final long serialVersionUID = 5093713970786841175L; /** - * Get MBank from Cache + * Get MBank from Cache (immutable) + * @param C_Bank_ID id + * @return MBank + */ + public static MBank get (int C_Bank_ID) + { + return get(Env.getCtx(), C_Bank_ID); + } + + /** + * Get MBank from Cache (immutable) * @param ctx context * @param C_Bank_ID id * @return MBank @@ -44,18 +55,36 @@ public class MBank extends X_C_Bank public static MBank get (Properties ctx, int C_Bank_ID) { Integer key = Integer.valueOf(C_Bank_ID); - MBank retValue = (MBank)s_cache.get (key); + MBank retValue = s_cache.get (ctx, key, e -> new MBank(ctx, e)); if (retValue != null) return retValue; - retValue = new MBank (ctx, C_Bank_ID, null); - if (retValue.get_ID() != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MBank (ctx, C_Bank_ID, (String)null); + if (retValue.get_ID() == C_Bank_ID) + { + s_cache.put (key, retValue, e -> new MBank(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MBank from cache + * @param ctx + * @param C_Bank_ID + * @param trxName + * @return MBank + */ + public static MBank getCopy(Properties ctx, int C_Bank_ID, String trxName) + { + MBank bank = get(C_Bank_ID); + if (bank != null) + bank = new MBank(ctx, bank, trxName); + return bank; + } + /** Cache */ - private static CCache s_cache = - new CCache (Table_Name, 3); + private static ImmutableIntPOCache s_cache = + new ImmutableIntPOCache (Table_Name, 3); /************************************************************************** @@ -80,6 +109,46 @@ public class MBank extends X_C_Bank super (ctx, rs, trxName); } // MBank + /** + * + * @param copy + */ + public MBank(MBank copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MBank(Properties ctx, MBank copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MBank(Properties ctx, MBank copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + @Override + public MBank markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + /** * String Representation * @return info diff --git a/org.adempiere.base/src/org/compiere/model/MBankAccount.java b/org.adempiere.base/src/org/compiere/model/MBankAccount.java index 086ef6f5b6..b6eaa53d0f 100644 --- a/org.adempiere.base/src/org/compiere/model/MBankAccount.java +++ b/org.adempiere.base/src/org/compiere/model/MBankAccount.java @@ -19,11 +19,12 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.Env; import org.compiere.util.IBAN; import org.compiere.util.Msg; import org.compiere.util.Util; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** @@ -32,15 +33,25 @@ import org.compiere.util.Util; * @author Jorg Janke * @version $Id: MBankAccount.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $ */ -public class MBankAccount extends X_C_BankAccount +public class MBankAccount extends X_C_BankAccount implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -110709935374907275L; + private static final long serialVersionUID = -3792366454862697171L; /** - * Get BankAccount from Cache + * Get BankAccount from Cache (immutable) + * @param C_BankAccount_ID id + * @return MBankAccount + */ + public static MBankAccount get (int C_BankAccount_ID) + { + return get(Env.getCtx(), C_BankAccount_ID); + } + + /** + * Get BankAccount from Cache (immutable) * @param ctx context * @param C_BankAccount_ID id * @return MBankAccount @@ -48,18 +59,36 @@ public class MBankAccount extends X_C_BankAccount public static MBankAccount get (Properties ctx, int C_BankAccount_ID) { Integer key = Integer.valueOf(C_BankAccount_ID); - MBankAccount retValue = (MBankAccount) s_cache.get (key); + MBankAccount retValue = s_cache.get (ctx, key, e -> new MBankAccount(ctx, e)); if (retValue != null) return retValue; - retValue = new MBankAccount (ctx, C_BankAccount_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MBankAccount (ctx, C_BankAccount_ID, (String)null); + if (retValue.get_ID () == C_BankAccount_ID) + { + s_cache.put (key, retValue, e -> new MBankAccount(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MBankAccount from cache + * @param ctx + * @param C_BankAccount_ID + * @param trxName + * @return MBankAccount + */ + public static MBankAccount getCopy(Properties ctx, int C_BankAccount_ID, String trxName) + { + MBankAccount mba = get(C_BankAccount_ID); + if (mba != null) + mba = new MBankAccount(ctx, mba, trxName); + return mba; + } + /** Cache */ - private static CCache s_cache - = new CCache(Table_Name, 5); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache(Table_Name, 5); /** * Bank Account Model @@ -92,6 +121,37 @@ public class MBankAccount extends X_C_BankAccount super(ctx, rs, trxName); } // MBankAccount + /** + * + * @param copy + */ + public MBankAccount(MBankAccount copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MBankAccount(Properties ctx, MBankAccount copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MBankAccount(Properties ctx, MBankAccount copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * String representation * @return info @@ -111,7 +171,7 @@ public class MBankAccount extends X_C_BankAccount */ public MBank getBank() { - return MBank.get(getCtx(), getC_Bank_ID()); + return MBank.getCopy(getCtx(), getC_Bank_ID(), get_TrxName()); } // getBank /** @@ -159,4 +219,13 @@ public class MBankAccount extends X_C_BankAccount return success; } // afterSave + @Override + public MBankAccount markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MBankAccount diff --git a/org.adempiere.base/src/org/compiere/model/MBankStatement.java b/org.adempiere.base/src/org/compiere/model/MBankStatement.java index cebdf7a44d..ccd1053237 100644 --- a/org.adempiere.base/src/org/compiere/model/MBankStatement.java +++ b/org.adempiere.base/src/org/compiere/model/MBankStatement.java @@ -180,7 +180,7 @@ public class MBankStatement extends X_C_BankStatement implements DocAction */ public MBankAccount getBankAccount() { - return MBankAccount.get(getCtx(), getC_BankAccount_ID()); + return MBankAccount.getCopy(getCtx(), getC_BankAccount_ID(), (String)null); } // getBankAccount /** diff --git a/org.adempiere.base/src/org/compiere/model/MCalendar.java b/org.adempiere.base/src/org/compiere/model/MCalendar.java index 34f149e340..6cd87dabce 100644 --- a/org.adempiere.base/src/org/compiere/model/MCalendar.java +++ b/org.adempiere.base/src/org/compiere/model/MCalendar.java @@ -20,9 +20,10 @@ import java.sql.ResultSet; import java.util.Locale; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.Env; import org.compiere.util.Msg; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Calendar Model @@ -30,16 +31,25 @@ import org.compiere.util.Msg; * @author Jorg Janke * @version $Id: MCalendar.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $ */ -public class MCalendar extends X_C_Calendar +public class MCalendar extends X_C_Calendar implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 7721451326626542420L; - + private static final long serialVersionUID = 6036302512252100576L; /** - * Get MCalendar from Cache + * Get MCalendar from Cache (immutable) + * @param C_Calendar_ID id + * @return MCalendar + */ + public static MCalendar get (int C_Calendar_ID) + { + return get(Env.getCtx(), C_Calendar_ID); + } + + /** + * Get MCalendar from Cache (immutable) * @param ctx context * @param C_Calendar_ID id * @return MCalendar @@ -47,15 +57,33 @@ public class MCalendar extends X_C_Calendar public static MCalendar get (Properties ctx, int C_Calendar_ID) { Integer key = Integer.valueOf(C_Calendar_ID); - MCalendar retValue = (MCalendar) s_cache.get (key); + MCalendar retValue = s_cache.get (ctx, key, e -> new MCalendar(ctx, e)); if (retValue != null) return retValue; - retValue = new MCalendar (ctx, C_Calendar_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MCalendar (ctx, C_Calendar_ID, (String)null); + if (retValue.get_ID () == C_Calendar_ID) + { + s_cache.put (key, retValue, e -> new MCalendar(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MCalendar from cache + * @param ctx + * @param C_Calendar_ID + * @param trxName + * @return MCalendar + */ + public static MCalendar getCopy(Properties ctx, int C_Calendar_ID, String trxName) + { + MCalendar calendar = get(C_Calendar_ID); + if (calendar != null) + calendar = new MCalendar(ctx, calendar, trxName); + return calendar; + } + /** * Get Default Calendar for Client * @param ctx context @@ -65,7 +93,7 @@ public class MCalendar extends X_C_Calendar public static MCalendar getDefault (Properties ctx, int AD_Client_ID) { MClientInfo info = MClientInfo.get(ctx, AD_Client_ID); - return get (ctx, info.getC_Calendar_ID()); + return getCopy(ctx, info.getC_Calendar_ID(), (String)null); } // getDefault /** @@ -79,8 +107,8 @@ public class MCalendar extends X_C_Calendar } // getDefault /** Cache */ - private static CCache s_cache - = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache(Table_Name, 20); /************************************************************************* @@ -117,6 +145,31 @@ public class MCalendar extends X_C_Calendar setName(msgset.toString()); } // MCalendar + /** + * + * @param copy + */ + public MCalendar(MCalendar copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MCalendar(Properties ctx, MCalendar copy) + { + this(ctx, copy, (String) null); + } + + public MCalendar(Properties ctx, MCalendar copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Create (current) Calendar Year * @param locale locale @@ -133,4 +186,13 @@ public class MCalendar extends X_C_Calendar return year; } // createYear + @Override + public MCalendar markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MCalendar diff --git a/org.adempiere.base/src/org/compiere/model/MCash.java b/org.adempiere.base/src/org/compiere/model/MCash.java index 71c8b29225..4e05479f29 100644 --- a/org.adempiere.base/src/org/compiere/model/MCash.java +++ b/org.adempiere.base/src/org/compiere/model/MCash.java @@ -237,7 +237,7 @@ public class MCash extends X_C_Cash implements DocAction public MCashBook getCashBook() { if (m_book == null) - m_book = MCashBook.get(getCtx(), getC_CashBook_ID()); + m_book = MCashBook.getCopy(getCtx(), getC_CashBook_ID(), get_TrxName()); return m_book; } // getCashBook diff --git a/org.adempiere.base/src/org/compiere/model/MCashBook.java b/org.adempiere.base/src/org/compiere/model/MCashBook.java index 1a02dece78..011c49bba0 100644 --- a/org.adempiere.base/src/org/compiere/model/MCashBook.java +++ b/org.adempiere.base/src/org/compiere/model/MCashBook.java @@ -17,11 +17,12 @@ package org.compiere.model; import java.sql.ResultSet; -import java.util.Iterator; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.CLogger; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Cash Book Model @@ -30,43 +31,71 @@ import org.compiere.util.CLogger; * @version $Id: MCashBook.java,v 1.3 2006/07/30 00:51:02 jjanke Exp $ * @author red1 - FR: [ 2214883 ] Remove SQL code and Replace for Query */ -public class MCashBook extends X_C_CashBook +public class MCashBook extends X_C_CashBook implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 3991585668643587699L; + private static final long serialVersionUID = -743516751730874877L; /** - * Get MCashBook from Cache + * Get MCashBook from Cache (immutable)) + * @param C_CashBook_ID id + * @return MCashBook + */ + public static MCashBook get (int C_CashBook_ID) + { + return get(Env.getCtx(), C_CashBook_ID); + } + + /** + * Get MCashBook from Cache (immutable) * @param ctx context * @param C_CashBook_ID id * @return MCashBook */ public static MCashBook get (Properties ctx, int C_CashBook_ID) { - return get(ctx, C_CashBook_ID, null); + return get(ctx, C_CashBook_ID, (String)null); } // get /** - * Gets MCashBook from Cache under transaction scope + * Gets MCashBook from Cache (immutabble) * @param ctx context * @param C_CashBook_ID id of cashbook to load - * @param trxName transaction name + * @param trxName transaction to load mcashbook if it is not in cache * @return Cashbook */ public static MCashBook get(Properties ctx, int C_CashBook_ID, String trxName) { Integer key = Integer.valueOf(C_CashBook_ID); - MCashBook retValue = (MCashBook) s_cache.get (key); + MCashBook retValue = s_cache.get (ctx, key, e -> new MCashBook(ctx, e)); if (retValue != null) return retValue; retValue = new MCashBook (ctx, C_CashBook_ID, trxName); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + if (retValue.get_ID () == C_CashBook_ID) + { + s_cache.put (key, retValue, e -> new MCashBook(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MCashBook from cache + * @param ctx + * @param C_CashBook_ID + * @param trxName + * @return MCashBook + */ + public static MCashBook getCopy(Properties ctx, int C_CashBook_ID, String trxName) + { + MCashBook cb = get(ctx, C_CashBook_ID, trxName); + if (cb != null) + cb = new MCashBook(ctx, cb, trxName); + return cb; + } + /** * Get CashBook for Org and Currency * @param ctx context @@ -77,12 +106,11 @@ public class MCashBook extends X_C_CashBook public static MCashBook get (Properties ctx, int AD_Org_ID, int C_Currency_ID) { // Try from cache - Iterator it = s_cache.values().iterator(); - while (it.hasNext()) + MCashBook[] it = s_cache.values().toArray(new MCashBook[0]); + for (MCashBook cb : it) { - MCashBook cb = (MCashBook)it.next(); if (cb.getAD_Org_ID() == AD_Org_ID && cb.getC_Currency_ID() == C_Currency_ID) - return cb; + return new MCashBook(ctx, cb); } // Get from DB @@ -92,17 +120,17 @@ public class MCashBook extends X_C_CashBook .setOrderBy("IsDefault DESC") .first(); if (retValue!=null) - { - Integer key = Integer.valueOf(retValue.getC_CashBook_ID()); - s_cache.put (key, retValue); - } + { + Integer key = Integer.valueOf(retValue.getC_CashBook_ID()); + s_cache.put (key, new MCashBook(Env.getCtx(), retValue)); + } return retValue; } // get /** Cache */ - private static CCache s_cache - = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache(Table_Name, 20); /** Static Logger */ @SuppressWarnings("unused") private static CLogger s_log = CLogger.getCLogger (MCashBook.class); @@ -129,6 +157,37 @@ public class MCashBook extends X_C_CashBook super(ctx, rs, trxName); } // MCashBook + /** + * + * @param copy + */ + public MCashBook(MCashBook copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MCashBook(Properties ctx, MCashBook copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MCashBook(Properties ctx, MCashBook copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * After Save * @param newRecord new @@ -143,4 +202,13 @@ public class MCashBook extends X_C_CashBook return success; } // afterSave + @Override + public MCashBook markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MCashBook diff --git a/org.adempiere.base/src/org/compiere/model/MCashLine.java b/org.adempiere.base/src/org/compiere/model/MCashLine.java index 67f81c9cb5..7cc24d726e 100644 --- a/org.adempiere.base/src/org/compiere/model/MCashLine.java +++ b/org.adempiere.base/src/org/compiere/model/MCashLine.java @@ -86,13 +86,10 @@ public class MCashLine extends X_C_CashLine setClientOrg(cash); setC_Cash_ID(cash.getC_Cash_ID()); m_parent = cash; - m_cashBook = m_parent.getCashBook(); } // MCashLine /** Parent */ protected MCash m_parent = null; - /** Cash Book */ - protected MCashBook m_cashBook = null; /** Bank Account */ protected MBankAccount m_bankAccount = null; /** Invoice */ @@ -241,9 +238,7 @@ public class MCashLine extends X_C_CashLine */ public MCashBook getCashBook() { - if (m_cashBook == null) - m_cashBook = MCashBook.get(getCtx(), getParent().getC_CashBook_ID()); - return m_cashBook; + return getParent().getCashBook(); } // getCashBook /** @@ -253,7 +248,7 @@ public class MCashLine extends X_C_CashLine public MBankAccount getBankAccount() { if (m_bankAccount == null && getC_BankAccount_ID() != 0) - m_bankAccount = MBankAccount.get(getCtx(), getC_BankAccount_ID()); + m_bankAccount = MBankAccount.getCopy(getCtx(), getC_BankAccount_ID(), get_TrxName()); return m_bankAccount; } // getBankAccount diff --git a/org.adempiere.base/src/org/compiere/model/MCharge.java b/org.adempiere.base/src/org/compiere/model/MCharge.java index 9b3133053e..dc29995547 100644 --- a/org.adempiere.base/src/org/compiere/model/MCharge.java +++ b/org.adempiere.base/src/org/compiere/model/MCharge.java @@ -20,10 +20,11 @@ import java.math.BigDecimal; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Charge Model @@ -34,12 +35,12 @@ import org.compiere.util.Env; * @author Teo Sarca, www.arhipac.ro *
  • FR [ 2214883 ] Remove SQL code and Replace for Query */ -public class MCharge extends X_C_Charge +public class MCharge extends X_C_Charge implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -4628105180010713510L; + private static final long serialVersionUID = 1978008783808254164L; /** * Get Charge Account @@ -80,7 +81,17 @@ public class MCharge extends X_C_Charge } // getAccount /** - * Get MCharge from Cache + * Get MCharge from Cache (immutable) + * @param C_Charge_ID id + * @return MCharge + */ + public static MCharge get (int C_Charge_ID) + { + return get(Env.getCtx(), C_Charge_ID); + } + + /** + * Get MCharge from Cache (immutable) * @param ctx context * @param C_Charge_ID id * @return MCharge @@ -88,18 +99,36 @@ public class MCharge extends X_C_Charge public static MCharge get (Properties ctx, int C_Charge_ID) { Integer key = Integer.valueOf(C_Charge_ID); - MCharge retValue = (MCharge)s_cache.get (key); + MCharge retValue = (MCharge)s_cache.get (ctx, key, e -> new MCharge(ctx, e)); if (retValue != null) return retValue; - retValue = new MCharge (ctx, C_Charge_ID, null); - if (retValue.get_ID() != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MCharge (ctx, C_Charge_ID, (String)null); + if (retValue.get_ID() == C_Charge_ID) + { + s_cache.put (key, retValue, e -> new MCharge(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MCharge from cache + * @param ctx + * @param C_Charge_ID + * @param trxName + * @return MCharge + */ + public static MCharge getCopy(Properties ctx, int C_Charge_ID, String trxName) + { + MCharge charge = get(C_Charge_ID); + if (charge != null) + charge = new MCharge(ctx, charge, trxName); + return charge; + } + /** Cache */ - private static CCache s_cache - = new CCache (Table_Name, 10); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache (Table_Name, 10); /** Static Logger */ private static CLogger s_log = CLogger.getCLogger (MCharge.class); @@ -136,6 +165,37 @@ public class MCharge extends X_C_Charge super(ctx, rs, trxName); } // MCharge + /** + * + * @param copy + */ + public MCharge(MCharge copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MCharge(Properties ctx, MCharge copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MCharge(Properties ctx, MCharge copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * After Save * @param newRecord new @@ -150,4 +210,13 @@ public class MCharge extends X_C_Charge return success; } // afterSave + @Override + public MCharge markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MCharge diff --git a/org.adempiere.base/src/org/compiere/model/MChatType.java b/org.adempiere.base/src/org/compiere/model/MChatType.java index d942ac8fd0..7144a9d949 100644 --- a/org.adempiere.base/src/org/compiere/model/MChatType.java +++ b/org.adempiere.base/src/org/compiere/model/MChatType.java @@ -19,7 +19,9 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Chat Type Model @@ -27,15 +29,25 @@ import org.compiere.util.CCache; * @author Jorg Janke * @version $Id: MChatType.java,v 1.2 2006/07/30 00:51:03 jjanke Exp $ */ -public class MChatType extends X_CM_ChatType +public class MChatType extends X_CM_ChatType implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -7933150405119053730L; + private static final long serialVersionUID = 973259852970379643L; /** - * Get MChatType from Cache + * Get MChatType from Cache (immutable) + * @param CM_ChatType_ID id + * @return MChatType + */ + public static MChatType get (int CM_ChatType_ID) + { + return get(Env.getCtx(), CM_ChatType_ID); + } + + /** + * Get MChatType from Cache (immutable) * @param ctx context * @param CM_ChatType_ID id * @return MChatType @@ -43,18 +55,21 @@ public class MChatType extends X_CM_ChatType public static MChatType get (Properties ctx, int CM_ChatType_ID) { Integer key = Integer.valueOf(CM_ChatType_ID); - MChatType retValue = (MChatType)s_cache.get (key); + MChatType retValue = s_cache.get (ctx, key, e -> new MChatType(ctx, e)); if (retValue != null) return retValue; - retValue = new MChatType (ctx, CM_ChatType_ID, null); - if (retValue.get_ID () != CM_ChatType_ID) - s_cache.put (key, retValue); - return retValue; + retValue = new MChatType (ctx, CM_ChatType_ID, (String)null); + if (retValue.get_ID () == CM_ChatType_ID) + { + s_cache.put (key, retValue, e -> new MChatType(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private static CCache s_cache - = new CCache (Table_Name, 20); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache (Table_Name, 20); /** * Standard Constructor @@ -80,4 +95,44 @@ public class MChatType extends X_CM_ChatType super (ctx, rs, trxName); } // MChatType + /** + * + * @param copy + */ + public MChatType(MChatType copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MChatType(Properties ctx, MChatType copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MChatType(Properties ctx, MChatType copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + @Override + public MChatType markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MChatType diff --git a/org.adempiere.base/src/org/compiere/model/MCity.java b/org.adempiere.base/src/org/compiere/model/MCity.java index 0cb3c8701c..572bb0bb6d 100644 --- a/org.adempiere.base/src/org/compiere/model/MCity.java +++ b/org.adempiere.base/src/org/compiere/model/MCity.java @@ -22,8 +22,10 @@ import java.text.Collator; import java.util.Comparator; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.CLogger; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Location City Model (Value Object) @@ -31,15 +33,25 @@ import org.compiere.util.CLogger; * @author Mario Calderon / Carlos Ruiz */ public class MCity extends X_C_City - implements Comparator, Serializable + implements Comparator, Serializable, ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -8905525315954621942L; + private static final long serialVersionUID = -3716470269471334172L; /** - * Get City (cached) + * Get City (cached) (immutable) + * @param C_City_ID ID + * @return City + */ + public static MCity get (int C_City_ID) + { + return get(Env.getCtx(), C_City_ID); + } + + /** + * Get City (cached) (immutable) * @param ctx context * @param C_City_ID ID * @return City @@ -47,20 +59,20 @@ public class MCity extends X_C_City public static MCity get (Properties ctx, int C_City_ID) { Integer key = Integer.valueOf(C_City_ID); - MCity r = s_Cities.get(key); + MCity r = s_Cities.get(ctx, key, e -> new MCity(ctx, e)); if (r != null) return r; - r = new MCity (ctx, C_City_ID, null); + r = new MCity (ctx, C_City_ID, (String)null); if (r.getC_City_ID() == C_City_ID) { - s_Cities.put(key, r); + s_Cities.put(key, r, e -> new MCity(Env.getCtx(), e)); return r; } return null; } // get /** City Cache */ - private static CCache s_Cities = new CCache(Table_Name, 20);; + private static ImmutableIntPOCache s_Cities = new ImmutableIntPOCache(Table_Name, 20);; /** Static Logger */ @SuppressWarnings("unused") private static CLogger s_log = CLogger.getCLogger (MCity.class); @@ -105,6 +117,36 @@ public class MCity extends X_C_City setName(cityName); } // MCity + /** + * + * @param copy + */ + public MCity(MCity copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MCity(Properties ctx, MCity copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MCity(Properties ctx, MCity copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } /** * Return Name * @return Name @@ -132,4 +174,13 @@ public class MCity extends X_C_City return collator.compare(s1, s2); } // compare + @Override + public MCity markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MCity diff --git a/org.adempiere.base/src/org/compiere/model/MClient.java b/org.adempiere.base/src/org/compiere/model/MClient.java index 20f2e6b630..f0e32a804b 100644 --- a/org.adempiere.base/src/org/compiere/model/MClient.java +++ b/org.adempiere.base/src/org/compiere/model/MClient.java @@ -32,12 +32,13 @@ import java.util.logging.Level; import javax.mail.internet.InternetAddress; import org.compiere.db.CConnection; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.EMail; import org.compiere.util.Env; import org.compiere.util.Language; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Client Model @@ -51,15 +52,25 @@ import org.compiere.util.Language; * @author Teo Sarca, SC ARHIPAC SERVICE SRL *
  • BF [ 1886480 ] Print Format Item Trl not updated even if not multilingual */ -public class MClient extends X_AD_Client -{ +public class MClient extends X_AD_Client implements ImmutablePOSupport +{ /** * */ - private static final long serialVersionUID = 8418331925351272377L; + private static final long serialVersionUID = 1820358079361924020L; /** - * Get client + * Get client from cache (immutable) + * @param AD_Client_ID id + * @return client + */ + public static MClient get (int AD_Client_ID) + { + return get(Env.getCtx(), AD_Client_ID); + } + + /** + * Get client from cache (immutable) * @param ctx context * @param AD_Client_ID id * @return client @@ -67,11 +78,11 @@ public class MClient extends X_AD_Client public static MClient get (Properties ctx, int AD_Client_ID) { Integer key = Integer.valueOf(AD_Client_ID); - MClient client = (MClient)s_cache.get(key); + MClient client = (MClient)s_cache.get(ctx, key, e -> new MClient(ctx, e)); if (client != null) return client; - client = new MClient (ctx, AD_Client_ID, null); - s_cache.put (key, client); + client = new MClient (ctx, AD_Client_ID, (String)null); + s_cache.put (key, client, e -> new MClient(Env.getCtx(), e)); return client; } // get @@ -93,11 +104,11 @@ public class MClient extends X_AD_Client */ public static MClient[] getAll (Properties ctx, String orderBy) { - List list = new Query(ctx,I_AD_Client.Table_Name,null,null) + List list = new Query(ctx,I_AD_Client.Table_Name,(String)null,(String)null) .setOrderBy(orderBy) .list(); for(MClient client:list ){ - s_cache.put (Integer.valueOf(client.getAD_Client_ID()), client); + s_cache.put (Integer.valueOf(client.getAD_Client_ID()), client, e -> new MClient(Env.getCtx(), e)); } MClient[] retValue = new MClient[list.size ()]; list.toArray (retValue); @@ -118,7 +129,7 @@ public class MClient extends X_AD_Client @SuppressWarnings("unused") private static CLogger s_log = CLogger.getCLogger (MClient.class); /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 3, 120, true); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 3, 120, true); /************************************************************************** @@ -185,6 +196,40 @@ public class MClient extends X_AD_Client this (ctx, Env.getAD_Client_ID(ctx), trxName); } // MClient + /** + * + * @param copy + */ + public MClient(MClient copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MClient(Properties ctx, MClient copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MClient(Properties ctx, MClient copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_info = copy.m_info != null ? new MClientInfo(ctx, copy.m_info, trxName) : null; + this.m_AD_Tree_Account_ID = copy.m_AD_Tree_Account_ID; + this.m_fieldAccess = copy.m_fieldAccess != null ? new ArrayList(copy.m_fieldAccess) : null; + } + /** Client Info */ private MClientInfo m_info = null; /** Language */ @@ -201,7 +246,12 @@ public class MClient extends X_AD_Client public MClientInfo getInfo() { if (m_info == null) - m_info = MClientInfo.get (getCtx(), getAD_Client_ID(), get_TrxName()); + { + if (is_Immutable()) + m_info = MClientInfo.get (getCtx(), getAD_Client_ID(), get_TrxName()); + else + m_info = MClientInfo.getCopy(getCtx(), getAD_Client_ID(), get_TrxName()); + } return m_info; } // getMClientInfo @@ -437,7 +487,7 @@ public class MClient extends X_AD_Client { int C_AcctSchema_ID = m_info.getC_AcctSchema1_ID(); if (C_AcctSchema_ID != 0) - return MAcctSchema.get(getCtx(), C_AcctSchema_ID); + return MAcctSchema.getCopy(getCtx(), C_AcctSchema_ID, get_TrxName()); } return null; } // getMClientInfo @@ -1141,6 +1191,17 @@ public class MClient extends X_AD_Client return s; } // getSMTPHost + @Override + public MClient markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_info != null) + m_info.markImmutable(); + return this; + } + // IDEMPIERE-722 private static final String MAIL_SEND_CREDENTIALS_USER = "U"; private static final String MAIL_SEND_CREDENTIALS_CLIENT = "C"; diff --git a/org.adempiere.base/src/org/compiere/model/MClientInfo.java b/org.adempiere.base/src/org/compiere/model/MClientInfo.java index 9e1fe9f94b..46c9b41288 100644 --- a/org.adempiere.base/src/org/compiere/model/MClientInfo.java +++ b/org.adempiere.base/src/org/compiere/model/MClientInfo.java @@ -22,10 +22,11 @@ import java.sql.SQLException; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Client Info Model @@ -33,16 +34,25 @@ import org.compiere.util.Env; * @author Jorg Janke * @version $Id: MClientInfo.java,v 1.2 2006/07/30 00:58:37 jjanke Exp $ */ -public class MClientInfo extends X_AD_ClientInfo +public class MClientInfo extends X_AD_ClientInfo implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 4861006368856890116L; - + private static final long serialVersionUID = 4707948832203223893L; /** - * Get Client Info + * Get Client Info from cache (immutable) + * @param AD_Client_ID id + * @return Client Info + */ + public static MClientInfo get (int AD_Client_ID) + { + return get(Env.getCtx(), AD_Client_ID); + } + + /** + * Get Client Info from cache (immutable) * @param ctx context * @param AD_Client_ID id * @return Client Info @@ -53,7 +63,7 @@ public class MClientInfo extends X_AD_ClientInfo } // get /** - * Get Client Info + * Get Client Info from cache (immutable) * @param ctx context * @param AD_Client_ID id * @param trxName optional trx @@ -62,7 +72,7 @@ public class MClientInfo extends X_AD_ClientInfo public static MClientInfo get (Properties ctx, int AD_Client_ID, String trxName) { Integer key = Integer.valueOf(AD_Client_ID); - MClientInfo info = (MClientInfo)s_cache.get(key); + MClientInfo info = s_cache.get(ctx, key, e -> new MClientInfo(ctx, e)); if (info != null) return info; // @@ -76,9 +86,8 @@ public class MClientInfo extends X_AD_ClientInfo rs = pstmt.executeQuery (); if (rs.next ()) { - info = new MClientInfo (ctx, rs, null); - if (trxName == null) - s_cache.put (key, info); + info = new MClientInfo (ctx, rs, trxName); + s_cache.put (key, info, e -> new MClientInfo(Env.getCtx(), e)); } } catch (SQLException ex) @@ -95,6 +104,15 @@ public class MClientInfo extends X_AD_ClientInfo return info; } // get + /** + * Get optionally cached client + * @return client + */ + public static MClientInfo get () + { + return get(Env.getCtx()); + } + /** * Get optionally cached client * @param ctx context @@ -105,8 +123,23 @@ public class MClientInfo extends X_AD_ClientInfo return get (ctx, Env.getAD_Client_ID(ctx), null); } // get + /** + * Get updateable copy of MClientInfo from cache + * @param ctx + * @param AD_Client_ID + * @param trxName + * @return MClientInfo + */ + public static MClientInfo getCopy(Properties ctx, int AD_Client_ID, String trxName) + { + MClientInfo ci = get(ctx, AD_Client_ID, trxName); + if (ci != null) + ci = new MClientInfo(ctx, ci, trxName); + return ci; + } + /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 2); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 2); /** Logger */ private static CLogger s_log = CLogger.getCLogger (MClientInfo.class); @@ -169,6 +202,37 @@ public class MClientInfo extends X_AD_ClientInfo m_createNew = true; } // MClientInfo + /** + * + * @param copy + */ + public MClientInfo(MClientInfo copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MClientInfo(Properties ctx, MClientInfo copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MClientInfo(Properties ctx, MClientInfo copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_acctSchema = copy.m_acctSchema != null ? new MAcctSchema(ctx, copy.m_acctSchema, trxName) : null; + } /** Account Schema */ private MAcctSchema m_acctSchema = null; @@ -182,7 +246,11 @@ public class MClientInfo extends X_AD_ClientInfo public MAcctSchema getMAcctSchema1() { if (m_acctSchema == null && getC_AcctSchema1_ID() != 0) - m_acctSchema = new MAcctSchema (getCtx(), getC_AcctSchema1_ID(), null); + { + m_acctSchema = new MAcctSchema (getCtx(), getC_AcctSchema1_ID(), get_TrxName()); + if (is_Immutable()) + m_acctSchema.markImmutable(); + } return m_acctSchema; } // getMAcctSchema1 @@ -214,4 +282,15 @@ public class MClientInfo extends X_AD_ClientInfo return saveUpdate(); } // save + @Override + public MClientInfo markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_acctSchema != null) + m_acctSchema.markImmutable(); + return this; + } + } // MClientInfo diff --git a/org.adempiere.base/src/org/compiere/model/MClientShare.java b/org.adempiere.base/src/org/compiere/model/MClientShare.java index 69f0cf8c2e..2464670ea1 100644 --- a/org.adempiere.base/src/org/compiere/model/MClientShare.java +++ b/org.adempiere.base/src/org/compiere/model/MClientShare.java @@ -24,6 +24,7 @@ import java.util.logging.Level; import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; +import org.compiere.util.Env; /** * Client Share Info @@ -142,6 +143,38 @@ public class MClientShare extends X_AD_ClientShare super (ctx, rs, trxName); } // MClientShare + /** + * + * @param copy + */ + public MClientShare(MClientShare copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MClientShare(Properties ctx, MClientShare copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MClientShare(Properties ctx, MClientShare copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_table = copy.m_table != null ? new MTable(ctx, copy.m_table, trxName) : null; + } + /** The Table */ private MTable m_table = null; @@ -170,7 +203,7 @@ public class MClientShare extends X_AD_ClientShare public MTable getTable() { if (m_table == null) - m_table = MTable.get(getCtx(), getAD_Table_ID()); + m_table = MTable.getCopy(getCtx(), getAD_Table_ID(), get_TrxName()); return m_table; } // getTable diff --git a/org.adempiere.base/src/org/compiere/model/MColorSchema.java b/org.adempiere.base/src/org/compiere/model/MColorSchema.java index 79521528a1..0d0d0a4930 100644 --- a/org.adempiere.base/src/org/compiere/model/MColorSchema.java +++ b/org.adempiere.base/src/org/compiere/model/MColorSchema.java @@ -23,8 +23,9 @@ import java.sql.ResultSet; import java.util.Properties; import org.compiere.print.MPrintColor; -import org.compiere.util.CCache; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Performance Color Schema @@ -32,12 +33,12 @@ import org.compiere.util.Env; * @author Jorg Janke * @version $Id: MColorSchema.java,v 1.2 2006/07/30 00:51:02 jjanke Exp $ */ -public class MColorSchema extends X_PA_ColorSchema +public class MColorSchema extends X_PA_ColorSchema implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 4645092884363283719L; + private static final long serialVersionUID = -3730457542399382168L; /** * Get Color @@ -74,6 +75,15 @@ public class MColorSchema extends X_PA_ColorSchema return cs.getColor(percent); } // getColor + /** + * Get MColorSchema from Cache + * @param PA_ColorSchema_ID id + * @return MColorSchema + */ + public static MColorSchema get (int PA_ColorSchema_ID) + { + return get(Env.getCtx(), PA_ColorSchema_ID); + } /** * Get MColorSchema from Cache @@ -90,18 +100,36 @@ public class MColorSchema extends X_PA_ColorSchema return retValue; } Integer key = Integer.valueOf(PA_ColorSchema_ID); - MColorSchema retValue = (MColorSchema)s_cache.get (key); + MColorSchema retValue = s_cache.get (ctx, key, e -> new MColorSchema(ctx, e)); if (retValue != null) return retValue; - retValue = new MColorSchema (ctx, PA_ColorSchema_ID, null); - if (retValue.get_ID() != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MColorSchema (ctx, PA_ColorSchema_ID, (String)null); + if (retValue.get_ID() == PA_ColorSchema_ID) + { + s_cache.put (key, retValue, e -> new MColorSchema(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MColorSchema from cache + * @param ctx + * @param PA_ColorSchema_ID + * @param trxName + * @return MColorSchema + */ + public static MColorSchema getCopy(Properties ctx, int PA_ColorSchema_ID, String trxName) + { + MColorSchema cs = get(PA_ColorSchema_ID); + if (cs != null) + cs = new MColorSchema(ctx, cs, trxName); + return cs; + } + /** Cache */ - private static CCache s_cache - = new CCache (Table_Name, 20); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache (Table_Name, 20); /** * Standard Constructor @@ -133,6 +161,37 @@ public class MColorSchema extends X_PA_ColorSchema super (ctx, rs, trxName); } // MColorSchema + /** + * + * @param copy + */ + public MColorSchema(MColorSchema copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MColorSchema(Properties ctx, MColorSchema copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MColorSchema(Properties ctx, MColorSchema copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Set Default. * Red (50) - Yellow (100) - Green @@ -210,4 +269,13 @@ public class MColorSchema extends X_PA_ColorSchema return sb.toString (); } // toString + @Override + public MColorSchema markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MColorSchema diff --git a/org.adempiere.base/src/org/compiere/model/MColumn.java b/org.adempiere.base/src/org/compiere/model/MColumn.java index 052bcc8199..b281d5ca1b 100644 --- a/org.adempiere.base/src/org/compiere/model/MColumn.java +++ b/org.adempiere.base/src/org/compiere/model/MColumn.java @@ -34,13 +34,14 @@ import java.util.logging.Level; import org.adempiere.exceptions.DBException; import org.compiere.db.AdempiereDatabase; import org.compiere.db.Database; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.Util; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Persistent Column Model @@ -48,20 +49,36 @@ import org.compiere.util.Util; * @author Jorg Janke * @version $Id: MColumn.java,v 1.6 2006/08/09 05:23:49 jjanke Exp $ */ -public class MColumn extends X_AD_Column +public class MColumn extends X_AD_Column implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 5934334786732835926L; + private static final long serialVersionUID = -1841918268550762201L; + /** + * Get MColumn from Cache (immutable) + * @param AD_Column_ID id + * @return MColumn + */ + public static MColumn get (int AD_Column_ID) + { + return get(Env.getCtx(), AD_Column_ID); + } + + /** + * Get MColumn from Cache (immutable) + * @param ctx context + * @param AD_Column_ID id + * @return MColumn + */ public static MColumn get (Properties ctx, int AD_Column_ID) { return get(ctx, AD_Column_ID, null); } /** - * Get MColumn from Cache + * Get MColumn from Cache (immutable) * @param ctx context * @param AD_Column_ID id * @param trxName trx @@ -70,17 +87,34 @@ public class MColumn extends X_AD_Column public static MColumn get(Properties ctx, int AD_Column_ID, String trxName) { Integer key = Integer.valueOf(AD_Column_ID); - MColumn retValue = (MColumn) s_cache.get (key); - if (retValue != null) { - retValue.set_TrxName(trxName); + MColumn retValue = (MColumn) s_cache.get (ctx, key, e -> new MColumn(ctx, e)); + if (retValue != null) + return retValue; + + retValue = new MColumn (ctx, AD_Column_ID, trxName); + if (retValue.get_ID () == AD_Column_ID) + { + s_cache.put (key, retValue, e -> new MColumn(Env.getCtx(), e)); return retValue; } - retValue = new MColumn (ctx, AD_Column_ID, trxName); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + return null; } // get + /** + * Get updateable copy of MColumn from cache + * @param ctx + * @param AD_Column_ID + * @param trxName + * @return MColumn + */ + public static MColumn getCopy(Properties ctx, int AD_Column_ID, String trxName) + { + MColumn column = get(ctx, AD_Column_ID, trxName); + if (column != null) + column = new MColumn(ctx, column, trxName); + return column; + } + /** * Get MColumn given TableName and ColumnName * @param ctx context @@ -115,7 +149,7 @@ public class MColumn extends X_AD_Column } // getColumnName /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** Static Logger */ private static CLogger s_log = CLogger.getCLogger (MColumn.class); @@ -172,7 +206,36 @@ public class MColumn extends X_AD_Column setEntityType(parent.getEntityType()); } // MColumn - + /** + * + * @param copy + */ + public MColumn(MColumn copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MColumn(Properties ctx, MColumn copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MColumn(Properties ctx, MColumn copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } /** * Is Standard Column * @return true for AD_Client_ID, etc. @@ -867,7 +930,7 @@ public class MColumn extends X_AD_Column @Override public I_AD_Table getAD_Table() throws RuntimeException { - MTable table = MTable.get(getCtx(), getAD_Table_ID(), get_TrxName()); + MTable table = MTable.getCopy(getCtx(), getAD_Table_ID(), get_TrxName()); return table; } @@ -1195,4 +1258,13 @@ public class MColumn extends X_AD_Column return rvalue + " - " + sql; } + @Override + public MColumn markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MColumn diff --git a/org.adempiere.base/src/org/compiere/model/MContactInterest.java b/org.adempiere.base/src/org/compiere/model/MContactInterest.java index dcc02997f7..7c7424c85f 100644 --- a/org.adempiere.base/src/org/compiere/model/MContactInterest.java +++ b/org.adempiere.base/src/org/compiere/model/MContactInterest.java @@ -112,6 +112,37 @@ public class MContactInterest extends X_R_ContactInterest super(ctx, rs, trxName); } // MContactInterest + /** + * + * @param copy + */ + public MContactInterest(MContactInterest copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MContactInterest(Properties ctx, MContactInterest copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MContactInterest(Properties ctx, MContactInterest copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** Static Logger */ private static CLogger s_log = CLogger.getCLogger (MContactInterest.class); diff --git a/org.adempiere.base/src/org/compiere/model/MConversionType.java b/org.adempiere.base/src/org/compiere/model/MConversionType.java index 1fc540b595..bb0a010473 100644 --- a/org.adempiere.base/src/org/compiere/model/MConversionType.java +++ b/org.adempiere.base/src/org/compiere/model/MConversionType.java @@ -21,6 +21,7 @@ import java.util.Properties; import org.compiere.util.CCache; import org.compiere.util.DB; +import org.compiere.util.Env; /** * Currency Conversion Type Model @@ -95,4 +96,34 @@ public class MConversionType extends X_C_ConversionType super(ctx, rs, trxName); } // MConversionType + /** + * + * @param copy + */ + public MConversionType(MConversionType copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MConversionType(Properties ctx, MConversionType copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MConversionType(Properties ctx, MConversionType copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } } // MConversionType diff --git a/org.adempiere.base/src/org/compiere/model/MCost.java b/org.adempiere.base/src/org/compiere/model/MCost.java index 47e262bb52..c2127e714c 100644 --- a/org.adempiere.base/src/org/compiere/model/MCost.java +++ b/org.adempiere.base/src/org/compiere/model/MCost.java @@ -1639,7 +1639,7 @@ public class MCost extends X_M_Cost int M_CostElement_ID = getM_CostElement_ID(); if (M_CostElement_ID == 0) return null; - return MCostElement.get(getCtx(), M_CostElement_ID); + return MCostElement.getCopy(getCtx(), M_CostElement_ID, get_TrxName()); } // getCostElement /** diff --git a/org.adempiere.base/src/org/compiere/model/MCostElement.java b/org.adempiere.base/src/org/compiere/model/MCostElement.java index f5ee4f7620..0809ca5f6d 100644 --- a/org.adempiere.base/src/org/compiere/model/MCostElement.java +++ b/org.adempiere.base/src/org/compiere/model/MCostElement.java @@ -21,11 +21,12 @@ import java.util.List; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Cost Element Model @@ -38,14 +39,12 @@ import org.compiere.util.Msg; * @author red1 *
  • FR: [ 2214883 ] Remove SQL code and Replace for Query -- JUnit tested */ -public class MCostElement extends X_M_CostElement +public class MCostElement extends X_M_CostElement implements ImmutablePOSupport { - /** * */ - private static final long serialVersionUID = 3423495977508725440L; - + private static final long serialVersionUID = 4914952212171251715L; /** * Get Material Cost Element or create it @@ -179,7 +178,17 @@ public class MCostElement extends X_M_CostElement // end MZ /** - * Get Cost Element from Cache + * Get Cost Element from Cache (immutable) + * @param M_CostElement_ID id + * @return Cost Element + */ + public static MCostElement get (int M_CostElement_ID) + { + return get(Env.getCtx(), M_CostElement_ID); + } + + /** + * Get Cost Element from Cache (immutable) * @param ctx context * @param M_CostElement_ID id * @return Cost Element @@ -187,15 +196,32 @@ public class MCostElement extends X_M_CostElement public static MCostElement get (Properties ctx, int M_CostElement_ID) { Integer key = Integer.valueOf(M_CostElement_ID); - MCostElement retValue = (MCostElement) s_cache.get (key); + MCostElement retValue = s_cache.get (ctx, key, e -> new MCostElement(ctx, e)); if (retValue != null) return retValue; - retValue = new MCostElement (ctx, M_CostElement_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MCostElement (ctx, M_CostElement_ID, (String)null); + if (retValue.get_ID () == M_CostElement_ID) + { + s_cache.put (key, retValue, e -> new MCostElement(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MCostElement from cache + * @param ctx + * @param M_CostElement_ID + * @param trxName + * @return MCostElement + */ + public static MCostElement getCopy(Properties ctx, int M_CostElement_ID, String trxName) + { + MCostElement ce = get(M_CostElement_ID); + if (ce != null) + ce = new MCostElement(ctx, ce, trxName); + return ce; + } /** * Get All Cost Elements for current AD_Client_ID @@ -232,7 +258,7 @@ public class MCostElement extends X_M_CostElement } /** Cache */ - protected static CCache s_cache = new CCache(Table_Name, 20); + protected static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** Logger */ private static CLogger s_log = CLogger.getCLogger (MCostElement.class); @@ -266,6 +292,37 @@ public class MCostElement extends X_M_CostElement super (ctx, rs, trxName); } // MCostElement + /** + * + * @param copy + */ + public MCostElement(MCostElement copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MCostElement(Properties ctx, MCostElement copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MCostElement(Properties ctx, MCostElement copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Before Save * @param newRecord new @@ -472,4 +529,13 @@ public class MCostElement extends X_M_CostElement return sb.toString (); } // toString + @Override + public MCostElement markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MCostElement diff --git a/org.adempiere.base/src/org/compiere/model/MCountry.java b/org.adempiere.base/src/org/compiere/model/MCountry.java index 80244437c9..a902ccdae6 100644 --- a/org.adempiere.base/src/org/compiere/model/MCountry.java +++ b/org.adempiere.base/src/org/compiere/model/MCountry.java @@ -23,15 +23,18 @@ import java.sql.ResultSet; import java.text.Collator; import java.util.Arrays; import java.util.Comparator; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.Env; import org.compiere.util.Language; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Location Country Model (Value Object) @@ -43,29 +46,39 @@ import org.compiere.util.Language; *
  • BF [ 2695078 ] Country is not translated on invoice */ public class MCountry extends X_C_Country - implements Comparator, Serializable + implements Comparator, Serializable, ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -4966707939803861163L; + private static final long serialVersionUID = 6102749517340832365L; /** - * Get Country (cached) - * @param ctx context + * Get Country (cached) (immutable) + * @param C_Country_ID ID + * @return Country + */ + public static MCountry get (int C_Country_ID) + { + return get(Env.getCtx(), C_Country_ID); + } + + /** + * Get Country (Immutable, cached) + * @param ctx context * @param C_Country_ID ID * @return Country */ public static MCountry get (Properties ctx, int C_Country_ID) { - loadAllCountriesIfNeeded(ctx); - MCountry c = s_countries.get(C_Country_ID); + loadAllCountriesIfNeeded(); + MCountry c = s_countries.get(ctx, C_Country_ID, e -> new MCountry(ctx, e)); if (c != null) return c; - c = new MCountry (ctx, C_Country_ID, null); + c = new MCountry (ctx, C_Country_ID, (String)null); if (c.getC_Country_ID() == C_Country_ID) { - s_countries.put(C_Country_ID, c); + s_countries.put(C_Country_ID, c, e -> new MCountry(Env.getCtx(), e)); return c; } return null; @@ -73,54 +86,72 @@ public class MCountry extends X_C_Country /** * Get Default Country - * @param ctx context + * @param ctx ignore * @return Country + * @deprecated */ public static MCountry getDefault (Properties ctx) { - int clientID = Env.getAD_Client_ID(ctx); + return getDefault(); + } + + /** + * Get Default Country (immutable) + * @return Country + */ + public static MCountry getDefault () + { + int clientID = Env.getAD_Client_ID(Env.getCtx()); MCountry c = s_default.get(clientID); if (c != null) return c; - loadDefaultCountry(ctx); + loadDefaultCountry(); c = s_default.get(clientID); return c; } // get /** * Return Countries as Array - * @param ctx context + * @param ctx ignore * @return MCountry Array + * @deprecated */ public static MCountry[] getCountries(Properties ctx) { - loadAllCountriesIfNeeded(ctx); - MCountry[] retValue = new MCountry[s_countries.size()]; - s_countries.values().toArray(retValue); - Arrays.sort(retValue, new MCountry(ctx, 0, null)); + return getCountries(); + } + + /** + * Return Countries as Array + * @return MCountry Array + */ + public static MCountry[] getCountries() + { + loadAllCountriesIfNeeded(); + MCountry[] retValue = s_countries.values().toArray(new MCountry[0]); + Arrays.sort(retValue, new MCountry(Env.getCtx(), 0, null)); return retValue; } // getCountries - private static synchronized void loadAllCountriesIfNeeded(Properties ctx) { + private static synchronized void loadAllCountriesIfNeeded() { if (s_countries == null || s_countries.isEmpty()) { - loadAllCountries(ctx); + loadAllCountries(); } } /** * Load Countries. * Set Default Language to Client Language - * @param ctx context */ - private static synchronized void loadAllCountries (Properties ctx) + private static synchronized void loadAllCountries () { - MClient client = MClient.get (ctx); - MLanguage lang = MLanguage.get(ctx, client.getAD_Language()); + MClient client = MClient.get (Env.getCtx()); + MLanguage lang = MLanguage.get(Env.getCtx(), client.getAD_Language()); // if (s_countries == null) - s_countries = new CCache(Table_Name, 250); - List countries = new Query(ctx, Table_Name, "", null) + s_countries = new ImmutableIntPOCache(Table_Name, 250); + List countries = new Query(Env.getCtx(), Table_Name, "", null) .setOnlyActiveRecords(true) .list(); for (MCountry c : countries) { @@ -135,19 +166,20 @@ public class MCountry extends X_C_Country /** * Load Default Country for actual client on context - * @param ctx */ - private static void loadDefaultCountry(Properties ctx) { - loadAllCountriesIfNeeded(ctx); - MClient client = MClient.get (ctx); + private static void loadDefaultCountry() { + loadAllCountriesIfNeeded(); + MClient client = MClient.get (Env.getCtx()); MCountry found = s_default.get(client.getAD_Client_ID()); if (found != null) return; - MLanguage lang = MLanguage.get(ctx, client.getAD_Language()); + MLanguage lang = MLanguage.get(Env.getCtx(), client.getAD_Language()); MCountry usa = null; - for (Entry cachedEntry : s_countries.entrySet()) { + //create local instance to avoid concurrent modification exception + Map countries = new HashMap(s_countries); + for (Entry cachedEntry : countries.entrySet()) { MCountry c = cachedEntry.getValue(); // Country code of Client Language if (lang != null && lang.getCountryCode().equals(c.getCountryCode())) { @@ -161,7 +193,7 @@ public class MCountry extends X_C_Country s_default.put(client.getAD_Client_ID(), found); else s_default.put(client.getAD_Client_ID(), usa); - if (s_log.isLoggable(Level.FINE)) s_log.fine("#" + s_countries.size() + if (s_log.isLoggable(Level.FINE)) s_log.fine("#" + countries.size() + " - Default=" + s_default); } @@ -182,9 +214,9 @@ public class MCountry extends X_C_Country private static String s_AD_Language = null; /** Country Cache */ - private static CCache s_countries = null; + private static ImmutableIntPOCache s_countries = null; /** Default Country */ - private static CCache s_default = new CCache(Table_Name, Table_Name+"|Default", 3); + private static ImmutableIntPOCache s_default = new ImmutableIntPOCache(Table_Name, Table_Name+"|Default", 3); /** Static Logger */ private static CLogger s_log = CLogger.getCLogger (MCountry.class); // Default DisplaySequence */ @@ -223,6 +255,37 @@ public class MCountry extends X_C_Country super(ctx, rs, trxName); } // MCountry + /** + * + * @param copy + */ + public MCountry(MCountry copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MCountry(Properties ctx, MCountry copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MCountry(Properties ctx, MCountry copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Return Name - translated if DisplayLanguage is set. * @return Name @@ -306,7 +369,7 @@ public class MCountry extends X_C_Country || getC_Country_ID() == 0 || !isHasRegion()) return false; - MRegion[] regions = MRegion.getRegions(getCtx(), getC_Country_ID()); + MRegion[] regions = MRegion.getRegions(getC_Country_ID()); for (int i = 0; i < regions.length; i++) { if (C_Region_ID == regions[i].getC_Region_ID()) @@ -315,6 +378,15 @@ public class MCountry extends X_C_Country return false; } // isValidRegion + @Override + public MCountry markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + /************************************************************************** * Insert Countries * @param args none diff --git a/org.adempiere.base/src/org/compiere/model/MCountryGroup.java b/org.adempiere.base/src/org/compiere/model/MCountryGroup.java index eda5c247a6..a7c1777994 100644 --- a/org.adempiere.base/src/org/compiere/model/MCountryGroup.java +++ b/org.adempiere.base/src/org/compiere/model/MCountryGroup.java @@ -27,42 +27,54 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Country Group Model */ -public class MCountryGroup extends X_C_CountryGroup +public class MCountryGroup extends X_C_CountryGroup implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 4986629677773273899L; + private static final long serialVersionUID = 8489673276196368210L; /** - * Get Country Group (cached) + * Get Country Group (cached) (immutable) + * @param C_CountryGroup_ID ID + * @return Country Group + */ + public static MCountryGroup get (int C_CountryGroup_ID) + { + return get(Env.getCtx(), C_CountryGroup_ID); + } + + /** + * Get Country Group (cached) (immutable) * @param ctx context * @param C_CountryGroup_ID ID * @return Country Group */ public static MCountryGroup get (Properties ctx, int C_CountryGroup_ID) { - MCountryGroup c = s_cache.get(C_CountryGroup_ID); + MCountryGroup c = s_cache.get(ctx, C_CountryGroup_ID, e -> new MCountryGroup(ctx, e)); if (c != null) return c; - c = new MCountryGroup (ctx, C_CountryGroup_ID, null); + c = new MCountryGroup (ctx, C_CountryGroup_ID, (String)null); if (c.getC_CountryGroup_ID() == C_CountryGroup_ID) { - s_cache.put(C_CountryGroup_ID, c); + s_cache.put(C_CountryGroup_ID, c, e -> new MCountryGroup(Env.getCtx(), e)); return c; } return null; } // get /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 5); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 5); /** Static Logger */ @SuppressWarnings("unused") private static CLogger s_log = CLogger.getCLogger (MCountryGroup.class); @@ -89,6 +101,46 @@ public class MCountryGroup extends X_C_CountryGroup super(ctx, rs, trxName); } // MCountryGroup + /** + * + * @param copy + */ + public MCountryGroup(MCountryGroup copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MCountryGroup(Properties ctx, MCountryGroup copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MCountryGroup(Properties ctx, MCountryGroup copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + @Override + public MCountryGroup markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + public static boolean countryGroupContains(int c_CountryGroup_ID, int c_Country_ID) { if (c_CountryGroup_ID == 0 || c_Country_ID == 0) diff --git a/org.adempiere.base/src/org/compiere/model/MCtxHelpMsg.java b/org.adempiere.base/src/org/compiere/model/MCtxHelpMsg.java index 9681933991..a62df1353d 100644 --- a/org.adempiere.base/src/org/compiere/model/MCtxHelpMsg.java +++ b/org.adempiere.base/src/org/compiere/model/MCtxHelpMsg.java @@ -29,26 +29,26 @@ import java.sql.ResultSet; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.ImmutablePOCache; /** * Context Help Message Model * * @author Carlos Ruiz */ -public class MCtxHelpMsg extends X_AD_CtxHelpMsg { +public class MCtxHelpMsg extends X_AD_CtxHelpMsg implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -7208965344525556184L; - + private static final long serialVersionUID = 3148838750037103261L; /** Logging */ private static CLogger s_log = CLogger.getCLogger(MCtxHelpMsg.class); /** Context Help Message Cache */ - private static CCache s_cache = new CCache(Table_Name, 10); + private static ImmutablePOCache s_cache = new ImmutablePOCache(Table_Name, 10); /** * Standard Constructor @@ -71,12 +71,49 @@ public class MCtxHelpMsg extends X_AD_CtxHelpMsg { } // MCtxHelpMsg /** - * Get the context help message defined for the type, recordid, client, org + * + * @param copy + */ + public MCtxHelpMsg(MCtxHelpMsg copy) { + this(Env.getCtx(), copy); + } + + /** + * * @param ctx + * @param copy + */ + public MCtxHelpMsg(Properties ctx, MCtxHelpMsg copy) { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MCtxHelpMsg(Properties ctx, MCtxHelpMsg copy, String trxName) { + this(ctx, 0, trxName); + copyPO(copy); + } + + /** + * Get the context help message defined for the type, recordid, client, org (immutable) * @param ctxtype * @param recordId * @return the context message record */ + public static MCtxHelpMsg get(String ctxType, int recordId) { + return get(Env.getCtx(), ctxType, recordId); + } + + /** + * Get the context help message defined for the type, recordid, client, org (immutable) + * @param ctxtype + * @param recordId + * @return an immutable instance of context message record (if any) + */ public static MCtxHelpMsg get(Properties ctx, String ctxType, int recordId) { StringBuilder key = new StringBuilder() .append(ctxType).append("|") @@ -85,7 +122,7 @@ public class MCtxHelpMsg extends X_AD_CtxHelpMsg { .append(Env.getAD_Org_ID(ctx)); MCtxHelpMsg retValue = null; if (s_cache.containsKey(key.toString())) { - retValue = s_cache.get(key.toString()); + retValue = s_cache.get(ctx, key.toString(), e -> new MCtxHelpMsg(ctx, e)); if (s_log.isLoggable(Level.FINEST)) s_log.finest("Cache: " + retValue); return retValue; } @@ -97,7 +134,7 @@ public class MCtxHelpMsg extends X_AD_CtxHelpMsg { .setParameters(Env.getAD_Client_ID(ctx), Env.getAD_Org_ID(ctx), AD_CtxHelp_ID) .first(); } - s_cache.put(key.toString(), retValue); + s_cache.put(key.toString(), retValue, e -> new MCtxHelpMsg(Env.getCtx(), e)); return retValue; } @@ -159,5 +196,13 @@ public class MCtxHelpMsg extends X_AD_CtxHelpMsg { super.setClientOrg(AD_Client_ID, AD_Org_ID); } - + @Override + public MCtxHelpMsg markImmutable() { + if (is_Immutable()) + return this; + + super.makeImmutable(); + return this; + } + } // MCtxHelpMsg diff --git a/org.adempiere.base/src/org/compiere/model/MCurrency.java b/org.adempiere.base/src/org/compiere/model/MCurrency.java index efae23d85f..3a973abcdb 100644 --- a/org.adempiere.base/src/org/compiere/model/MCurrency.java +++ b/org.adempiere.base/src/org/compiere/model/MCurrency.java @@ -19,19 +19,22 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.ImmutablePOCache; /** * Currency Model. * * @author Jorg Janke */ -public class MCurrency extends X_C_Currency +public class MCurrency extends X_C_Currency implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 2262097171335518186L; + private static final long serialVersionUID = 4325153934518648373L; /** * Currency Constructor @@ -85,14 +88,54 @@ public class MCurrency extends X_C_Currency setIsEuro (false); } // MCurrency - - /** Store System Currencies **/ - private static CCache s_currencies = new CCache(Table_Name, 50); - /** Cache System Currencies by using ISO code as key **/ - private static CCache s_currenciesISO = new CCache(Table_Name, "C_CurrencyISO", 50); + /** + * + * @param copy + */ + public MCurrency(MCurrency copy) + { + this(Env.getCtx(), copy); + } /** - * Get Currency using ISO code + * + * @param ctx + * @param copy + */ + public MCurrency(Properties ctx, MCurrency copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MCurrency(Properties ctx, MCurrency copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + /** Store System Currencies **/ + private static ImmutableIntPOCache s_currencies = new ImmutableIntPOCache(Table_Name, 50); + /** Cache System Currencies by using ISO code as key **/ + private static ImmutablePOCache s_currenciesISO = new ImmutablePOCache(Table_Name, "C_CurrencyISO", 50); + + /** + * Get Currency using ISO code from cache (immutable) + * @param ISOcode Iso code + * @return MCurrency + */ + public static MCurrency get (String ISOcode) + { + return get(Env.getCtx(), ISOcode); + } + + /** + * Get Currency using ISO code from cache (immutable) * @param ctx Context * @param ISOcode Iso code * @return MCurrency @@ -100,24 +143,34 @@ public class MCurrency extends X_C_Currency public static MCurrency get (Properties ctx, String ISOcode) { // Try Cache - MCurrency retValue = (MCurrency)s_currenciesISO.get(ISOcode); + MCurrency retValue = (MCurrency)s_currenciesISO.get(ctx, ISOcode, e -> new MCurrency(ctx, e)); if (retValue != null) return retValue; // Try database - Query query = new Query(ctx, I_C_Currency.Table_Name, "ISO_Code=?", null); + Query query = new Query(ctx, I_C_Currency.Table_Name, "ISO_Code=?", (String)null); query.setParameters(ISOcode); retValue = (MCurrency)query.firstOnly(); // Save - if (retValue!=null) - s_currenciesISO.put(ISOcode, retValue); + if (retValue!=null) { + s_currenciesISO.put(ISOcode, retValue, e -> new MCurrency(Env.getCtx(), e)); + } return retValue; } - /** - * Get Currency + * Get Currency (immutable) + * @param C_Currency_ID currency + * @return ISO Code + */ + public static MCurrency get (int C_Currency_ID) + { + return get(Env.getCtx(), C_Currency_ID); + } + + /** + * Get Currency (immutable) * @param ctx Context * @param C_Currency_ID currency * @return ISO Code @@ -126,16 +179,20 @@ public class MCurrency extends X_C_Currency { // Try Cache Integer key = Integer.valueOf(C_Currency_ID); - MCurrency retValue = (MCurrency)s_currencies.get(key); + MCurrency retValue = s_currencies.get(ctx, key, e -> new MCurrency(ctx, e)); if (retValue != null) return retValue; // Create it - retValue = new MCurrency(ctx, C_Currency_ID, null); + retValue = new MCurrency(ctx, C_Currency_ID, (String)null); // Save in System - if (retValue.getAD_Client_ID() == 0) - s_currencies.put(key, retValue); - return retValue; + if (retValue.get_ID() == C_Currency_ID) + { + if (retValue.getAD_Client_ID() == 0) + s_currencies.put(key, retValue, e -> new MCurrency(Env.getCtx(), e)); + return (MCurrency) retValue.markImmutable(); + } + return null; } // get /** @@ -194,6 +251,15 @@ public class MCurrency extends X_C_Currency return c.getCostingPrecision(); } + @Override + public MCurrency markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + /*************************************************************************/ diff --git a/org.adempiere.base/src/org/compiere/model/MDepreciation.java b/org.adempiere.base/src/org/compiere/model/MDepreciation.java index 759ad9f1e0..082632faa3 100644 --- a/org.adempiere.base/src/org/compiere/model/MDepreciation.java +++ b/org.adempiere.base/src/org/compiere/model/MDepreciation.java @@ -7,10 +7,12 @@ import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; -import org.compiere.util.CCache; import org.compiere.util.CLogMgt; import org.compiere.util.CLogger; import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.IntPOCopyCache; +import org.idempiere.cache.POCopyCache; import org.idempiere.fa.exceptions.AssetNotImplementedException; import org.idempiere.fa.exceptions.AssetNotSupportedException; import org.idempiere.fa.service.api.DepreciationDTO; @@ -21,13 +23,12 @@ import org.idempiere.fa.service.api.IDepreciationMethod; * Depreciation Engine (eg. SL, ARH_VAR ...) * @author Teo Sarca, SC ARHIPAC SERVICE SRL */ -public class MDepreciation extends X_A_Depreciation +public class MDepreciation extends X_A_Depreciation implements ImmutablePOSupport { - /** * */ - private static final long serialVersionUID = -632058079835100100L; + private static final long serialVersionUID = -4366354698409595086L; /** Standard Constructor */ public MDepreciation (Properties ctx, int A_Depreciation_ID, String trxName) @@ -45,12 +46,43 @@ public class MDepreciation extends X_A_Depreciation super (ctx, rs, trxName); } // MDepreciation + /** + * + * @param copy + */ + public MDepreciation(MDepreciation copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MDepreciation(Properties ctx, MDepreciation copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MDepreciation(Properties ctx, MDepreciation copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** Cache */ - private static CCache - s_cache = new CCache(Table_Name, 5); + private static IntPOCopyCache + s_cache = new IntPOCopyCache(Table_Name, 5); /** Cache for type */ - private static CCache - s_cache_forType = new CCache(Table_Name, Table_Name+"_DepreciationType", 5); + private static POCopyCache + s_cache_forType = new POCopyCache(Table_Name, Table_Name+"_DepreciationType", 5); /** Static logger */ private static Logger s_log = CLogger.getCLogger(MDepreciation.class); /** The accuracy of calculation on depreciation */ @@ -66,37 +98,51 @@ public class MDepreciation extends X_A_Depreciation return ; } - s_cache.put(depr.get_ID(), depr); + s_cache.put(depr.get_ID(), depr, e -> new MDepreciation(Env.getCtx(), e)); String key = "" + depr.getAD_Client_ID() + "_" + depr.getDepreciationType(); - s_cache_forType.put(key, depr); + s_cache_forType.put(key, depr, e -> new MDepreciation(Env.getCtx(), e)); } /** - * Get Depreciation method + * Get Depreciation method from cache + * @param A_Depreciation_ID depreciation id + */ + public static MDepreciation get(int A_Depreciation_ID) + { + return get(Env.getCtx(), A_Depreciation_ID); + } + + /** + * Get Depreciation method from cache * @param ctx * @param A_Depreciation_ID depreciation id */ public static MDepreciation get(Properties ctx, int A_Depreciation_ID) { - MDepreciation depr = s_cache.get(A_Depreciation_ID); + MDepreciation depr = s_cache.get(A_Depreciation_ID, e -> new MDepreciation(ctx, e)); if (depr != null) - { return depr; - } - depr = new MDepreciation(ctx, A_Depreciation_ID, null); - if (depr.get_ID() > 0) + + depr = new MDepreciation(ctx, A_Depreciation_ID, (String)null); + if (depr.get_ID() == A_Depreciation_ID) { addToCache(depr); + return depr; } - else - { - depr = null; - } - return depr; + return null; } // get /** * Get Depreciation method + * @param depreciationType depreciation type (e.g. SL) + */ + public static MDepreciation get(String depreciationType) + { + return get(Env.getCtx(), depreciationType); + } + + /** + * Get Depreciation method (immutable) * @param ctx * @param depreciationType depreciation type (e.g. SL) */ @@ -104,11 +150,9 @@ public class MDepreciation extends X_A_Depreciation { int AD_Client_ID = Env.getAD_Client_ID(ctx); String key = "" + AD_Client_ID + "_" + depreciationType; - MDepreciation depr = s_cache_forType.get(key); + MDepreciation depr = s_cache_forType.get(key, e -> new MDepreciation(ctx, e)); if (depr != null) - { return depr; - } final String whereClause = COLUMNNAME_DepreciationType+"=?" +" AND AD_Client_ID IN (0,?)"; @@ -117,7 +161,7 @@ public class MDepreciation extends X_A_Depreciation .setParameters(new Object[]{depreciationType, AD_Client_ID}) .firstOnly(); addToCache(depr); - return depr; + return (MDepreciation) depr.markImmutable(); } // get /** @@ -482,4 +526,14 @@ public class MDepreciation extends X_A_Depreciation // TODO: Adding this method to compile correctly and future research return 0; } + + @Override + public MDepreciation markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } diff --git a/org.adempiere.base/src/org/compiere/model/MDepreciationConvention.java b/org.adempiere.base/src/org/compiere/model/MDepreciationConvention.java index 10aa841d72..8862822580 100644 --- a/org.adempiere.base/src/org/compiere/model/MDepreciationConvention.java +++ b/org.adempiere.base/src/org/compiere/model/MDepreciationConvention.java @@ -5,20 +5,22 @@ import java.sql.ResultSet; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** Convention for the first year of depreciation (ex. FMCON, FYCON ...) * @author Teo Sarca, SC Arhipac SRL * @version $Id$ */ -public class MDepreciationConvention extends X_A_Depreciation_Convention +public class MDepreciationConvention extends X_A_Depreciation_Convention implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 2274629486216430723L; - + private static final long serialVersionUID = -3735111030292424391L; + /** * Default Constructor * @param ctx context @@ -43,24 +45,69 @@ public class MDepreciationConvention extends X_A_Depreciation_Convention super (ctx, rs, trxName); } // MDepreciationConvention + /** + * + * @param copy + */ + public MDepreciationConvention(MDepreciationConvention copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MDepreciationConvention(Properties ctx, MDepreciationConvention copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MDepreciationConvention(Properties ctx, MDepreciationConvention copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 5); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 5); //~ /** Static logger */ //~ private static Logger s_log = CLogger.getCLogger(MDepreciationConvention.class); + /** + * Get MDepreciationConvention from cache (immutable) + * @param A_Depreciation_Convention_ID + * @return MDepreciationConvention + */ + public static MDepreciationConvention get(int A_Depreciation_Convention_ID) { + return get(Env.getCtx(), A_Depreciation_Convention_ID); + } + + /** + * Get MDepreciationConvention from cache (immutable) + * @param ctx context + * @param A_Depreciation_Convention_ID + * @return MDepreciationConvention + */ public static MDepreciationConvention get(Properties ctx, int A_Depreciation_Convention_ID) { Integer key = Integer.valueOf(A_Depreciation_Convention_ID); - MDepreciationConvention conv = s_cache.get(key); - if (conv != null) { + MDepreciationConvention conv = s_cache.get(ctx, key, e -> new MDepreciationConvention(ctx, e)); + if (conv != null) + return conv; + + conv = new MDepreciationConvention(ctx, A_Depreciation_Convention_ID, (String)null); + if (conv.get_ID() == A_Depreciation_Convention_ID) { + s_cache.put(key, conv, e -> new MDepreciationConvention(Env.getCtx(), e)); return conv; } - conv = new MDepreciationConvention(ctx, A_Depreciation_Convention_ID, null); - if (conv.get_ID() > 0) { - s_cache.put(key, conv); - } else { - conv = null; - } - return conv; + return null; } // get /** */ @@ -114,4 +161,14 @@ public class MDepreciationConvention extends X_A_Depreciation_Convention public BigDecimal apply_FMCON(int A_Asset_ID, String PostingType, int A_Asset_Acct_ID, int Flag, int Period) { return BigDecimal.ONE; } + + @Override + public MDepreciationConvention markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } diff --git a/org.adempiere.base/src/org/compiere/model/MDepreciationMethod.java b/org.adempiere.base/src/org/compiere/model/MDepreciationMethod.java index ad2f2d0700..7935b1f18d 100644 --- a/org.adempiere.base/src/org/compiere/model/MDepreciationMethod.java +++ b/org.adempiere.base/src/org/compiere/model/MDepreciationMethod.java @@ -8,21 +8,24 @@ import java.util.Properties; import java.util.logging.Level; import org.adempiere.exceptions.DBException; -import org.compiere.util.CCache; import org.compiere.util.CLogMgt; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.ImmutablePOCache; /** * Method of adjusting the difference between depreciation (Calculated) and registered as (booked). * ex. MDI, LDI, YDI ... * @author Teo Sarca, SC ARHIPAC SERVICE SRL */ -public class MDepreciationMethod extends X_A_Depreciation_Method +public class MDepreciationMethod extends X_A_Depreciation_Method implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 4622027905888469713L; + private static final long serialVersionUID = -7477974832683140825L; /** Standard Constructor */ public MDepreciationMethod (Properties ctx, int A_Depreciation_Method_ID, String trxName) @@ -40,12 +43,43 @@ public class MDepreciationMethod extends X_A_Depreciation_Method super (ctx, rs, trxName); } // MDepreciationMethod + /** + * + * @param copy + */ + public MDepreciationMethod(MDepreciationMethod copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MDepreciationMethod(Properties ctx, MDepreciationMethod copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MDepreciationMethod(Properties ctx, MDepreciationMethod copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** Cache */ - private static CCache - s_cache = new CCache(Table_Name, 5); + private static ImmutableIntPOCache + s_cache = new ImmutableIntPOCache(Table_Name, 5); /** Cache for type */ - private static CCache - s_cache_forType = new CCache(Table_Name, Table_Name+"_DepreciationType", 5); + private static ImmutablePOCache + s_cache_forType = new ImmutablePOCache(Table_Name, Table_Name+"_DepreciationType", 5); /** * @@ -56,8 +90,8 @@ public class MDepreciationMethod extends X_A_Depreciation_Method { return; } - s_cache.put(depr.get_ID(), depr); - s_cache_forType.put(depr.getDepreciationType(), depr); + s_cache.put(depr.get_ID(), depr, e -> new MDepreciationMethod(Env.getCtx(), e)); + s_cache_forType.put(depr.getDepreciationType(), depr, e -> new MDepreciationMethod(Env.getCtx(), e)); } /** @@ -67,45 +101,66 @@ public class MDepreciationMethod extends X_A_Depreciation_Method { return 2; } - + /** - * + * Get MDepreciationMethod from cache (immutable) + * @param A_Depreciation_Method_ID + * @return MDepreciationMethod + */ + public static MDepreciationMethod get(int A_Depreciation_Method_ID) + { + return get(Env.getCtx(), A_Depreciation_Method_ID); + } + + /** + * Get MDepreciationMethod from cache (immutable) + * @param ctx + * @param A_Depreciation_Method_ID + * @return MDepreciationMethod */ public static MDepreciationMethod get(Properties ctx, int A_Depreciation_Method_ID) { - MDepreciationMethod depr = s_cache.get(A_Depreciation_Method_ID); + MDepreciationMethod depr = s_cache.get(ctx, A_Depreciation_Method_ID, e -> new MDepreciationMethod(ctx, e)); if (depr != null) - { return depr; - } - depr = new MDepreciationMethod(ctx, A_Depreciation_Method_ID, null); - if (depr.get_ID() > 0) + + depr = new MDepreciationMethod(ctx, A_Depreciation_Method_ID, (String)null); + if (depr.get_ID() == A_Depreciation_Method_ID) { addToCache(depr); + return depr; } - else - { - depr = null; - } - return depr; + return null; } // get /** - * + * Get MDepreciationMethod from cache + * @param depreciationType + * @return MDepreciationMethod + */ + public static MDepreciationMethod get(String depreciationType) + { + return get(Env.getCtx(), depreciationType); + } + + /** + * Get MDepreciationMethod from cache (immutable) + * @param ctx + * @param depreciationType + * @return MDepreciationMethod */ public static MDepreciationMethod get(Properties ctx, String depreciationType) { String key = depreciationType; - MDepreciationMethod depr = s_cache_forType.get(key); + MDepreciationMethod depr = s_cache_forType.get(ctx, key, e -> new MDepreciationMethod(ctx, e)); if (depr != null) - { return depr; - } + depr = new Query(ctx, Table_Name, COLUMNNAME_DepreciationType+"=?", null) .setParameters(new Object[]{depreciationType}) .firstOnly(); addToCache(depr); - return depr; + return (MDepreciationMethod) depr.markImmutable(); } @@ -246,4 +301,14 @@ public class MDepreciationMethod extends X_A_Depreciation_Method } return periodAdjustment; } + + @Override + public MDepreciationMethod markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } diff --git a/org.adempiere.base/src/org/compiere/model/MDepreciationWorkfile.java b/org.adempiere.base/src/org/compiere/model/MDepreciationWorkfile.java index 3affa37a37..eb372c4013 100644 --- a/org.adempiere.base/src/org/compiere/model/MDepreciationWorkfile.java +++ b/org.adempiere.base/src/org/compiere/model/MDepreciationWorkfile.java @@ -9,8 +9,6 @@ import java.util.Properties; import java.util.logging.Level; import org.adempiere.base.Core; -import org.apache.commons.collections.keyvalue.MultiKey; -import org.compiere.util.CCache; import org.compiere.util.CLogMgt; import org.compiere.util.CLogger; import org.compiere.util.DB; @@ -276,6 +274,38 @@ public class MDepreciationWorkfile extends X_A_Depreciation_Workfile dump(); } + /** + * + * @param copy + */ + public MDepreciationWorkfile(MDepreciationWorkfile copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MDepreciationWorkfile(Properties ctx, MDepreciationWorkfile copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MDepreciationWorkfile(Properties ctx, MDepreciationWorkfile copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_asset = copy.m_asset != null ? new MAsset(ctx, copy.m_asset, trxName) : null; + } + /** Logger */ private CLogger log = CLogger.getCLogger(getClass()); @@ -316,20 +346,6 @@ public class MDepreciationWorkfile extends X_A_Depreciation_Workfile return null; } - final MultiKey key = new MultiKey(A_Asset_ID, postingType); - if (trxName == null) - { - MDepreciationWorkfile wk = s_cacheAsset.get(key); - if (wk != null) - return wk; - } - /* @win temporary change as this code is causing duplicate create MDepreciationWorkfile on asset addition - final String whereClause = COLUMNNAME_A_Asset_ID+"=?" - +" AND "+COLUMNNAME_PostingType+"=? AND "+COLUMNNAME_A_QTY_Current+">?"; - MDepreciationWorkfile wk = new Query(ctx, MDepreciationWorkfile.Table_Name, whereClause, trxName) - .setParameters(new Object[]{A_Asset_ID, postingType, 0}) - .firstOnly(); - */ final String whereClause = COLUMNNAME_A_Asset_ID+"=?" +" AND "+COLUMNNAME_PostingType+"=? AND " + COLUMNNAME_C_AcctSchema_ID + "=?" ; @@ -337,12 +353,7 @@ public class MDepreciationWorkfile extends X_A_Depreciation_Workfile MDepreciationWorkfile wk = new Query(ctx, MDepreciationWorkfile.Table_Name, whereClause, trxName) .setParameters(new Object[]{A_Asset_ID, postingType,acctSchemaId}) .firstOnly(); - - - if (trxName == null && wk != null) - { - s_cacheAsset.put(key, wk); - } + return wk; } @@ -358,9 +369,6 @@ public class MDepreciationWorkfile extends X_A_Depreciation_Workfile { return get(ctx, A_Asset_ID, postingType, trxName, 0); } - /** Static cache: Asset/PostingType -> Workfile */ - private static CCache - s_cacheAsset = new CCache(Table_Name, Table_Name+"_Asset", 10); /** Returns the date of the last action */ diff --git a/org.adempiere.base/src/org/compiere/model/MDiscountSchema.java b/org.adempiere.base/src/org/compiere/model/MDiscountSchema.java index 4342710982..4cfc35b037 100644 --- a/org.adempiere.base/src/org/compiere/model/MDiscountSchema.java +++ b/org.adempiere.base/src/org/compiere/model/MDiscountSchema.java @@ -21,13 +21,15 @@ import java.math.RoundingMode; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; +import java.util.Arrays; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.TimeUtil; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Discount Schema Model @@ -35,35 +37,47 @@ import org.compiere.util.TimeUtil; * @author Jorg Janke * @version $Id: MDiscountSchema.java,v 1.3 2006/07/30 00:51:04 jjanke Exp $ */ -public class MDiscountSchema extends X_M_DiscountSchema +public class MDiscountSchema extends X_M_DiscountSchema implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -3314884382853756019L; - + private static final long serialVersionUID = 4916780751688051566L; /** - * Get Discount Schema from Cache - * @param ctx context + * Get Discount Schema from Cache (immutable) + * @param M_DiscountSchema_ID id + * @return MDiscountSchema + */ + public static MDiscountSchema get (int M_DiscountSchema_ID) + { + return get(Env.getCtx(), M_DiscountSchema_ID); + } + + /** + * Get Discount Schema from Cache (immutable) + * @param ctx context * @param M_DiscountSchema_ID id * @return MDiscountSchema */ public static MDiscountSchema get (Properties ctx, int M_DiscountSchema_ID) { Integer key = Integer.valueOf(M_DiscountSchema_ID); - MDiscountSchema retValue = (MDiscountSchema) s_cache.get (key); + MDiscountSchema retValue = s_cache.get (ctx, key, e -> new MDiscountSchema(ctx, e)); if (retValue != null) return retValue; - retValue = new MDiscountSchema (ctx, M_DiscountSchema_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MDiscountSchema (ctx, M_DiscountSchema_ID, (String)null); + if (retValue.get_ID () == M_DiscountSchema_ID) + { + s_cache.put (key, retValue, e -> new MDiscountSchema(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private static CCache s_cache - = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache(Table_Name, 20); /************************************************************************** @@ -98,6 +112,39 @@ public class MDiscountSchema extends X_M_DiscountSchema super(ctx, rs, trxName); } // MDiscountSchema + /** + * + * @param copy + */ + public MDiscountSchema(MDiscountSchema copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MDiscountSchema(Properties ctx, MDiscountSchema copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MDiscountSchema(Properties ctx, MDiscountSchema copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_breaks = copy.m_breaks != null ? Arrays.stream(copy.m_breaks).map(e -> {return new MDiscountSchemaBreak(ctx, e, trxName);}).toArray(MDiscountSchemaBreak[]::new) : null; + this.m_lines = copy.m_lines != null ? Arrays.stream(copy.m_lines).map(e -> {return new MDiscountSchemaLine(ctx, e, trxName);}).toArray(MDiscountSchemaLine[]::new) : null; + } + /** Breaks */ private MDiscountSchemaBreak[] m_breaks = null; /** Lines */ @@ -123,7 +170,12 @@ public class MDiscountSchema extends X_M_DiscountSchema pstmt.setInt (1, getM_DiscountSchema_ID()); rs = pstmt.executeQuery (); while (rs.next ()) - list.add(new MDiscountSchemaBreak(getCtx(), rs, get_TrxName())); + { + MDiscountSchemaBreak dsb = new MDiscountSchemaBreak(getCtx(), rs, get_TrxName()); + if (is_Immutable()) + dsb.markImmutable(); + list.add(dsb); + } } catch (Exception e) { @@ -162,7 +214,12 @@ public class MDiscountSchema extends X_M_DiscountSchema pstmt.setInt (1, getM_DiscountSchema_ID()); rs = pstmt.executeQuery (); while (rs.next ()) - list.add(new MDiscountSchemaLine(getCtx(), rs, get_TrxName())); + { + MDiscountSchemaLine dsl = new MDiscountSchemaLine(getCtx(), rs, get_TrxName()); + if (is_Immutable()) + dsl.markImmutable(); + list.add(dsl); + } } catch (Exception e) { @@ -337,5 +394,17 @@ public class MDiscountSchema extends X_M_DiscountSchema m_breaks = null; return count; } // reSeq - + + @Override + public MDiscountSchema markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_lines != null) + Arrays.stream(m_lines).forEach(e -> {e.markImmutable();}); + if (m_breaks != null) + Arrays.stream(m_breaks).forEach(e -> {e.markImmutable();}); + return this; + } } // MDiscountSchema diff --git a/org.adempiere.base/src/org/compiere/model/MDiscountSchemaBreak.java b/org.adempiere.base/src/org/compiere/model/MDiscountSchemaBreak.java index de31f034be..fb97f224dc 100644 --- a/org.adempiere.base/src/org/compiere/model/MDiscountSchemaBreak.java +++ b/org.adempiere.base/src/org/compiere/model/MDiscountSchemaBreak.java @@ -20,6 +20,9 @@ import java.math.BigDecimal; import java.sql.ResultSet; import java.util.Properties; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; + /** * Discount Break Schema (Model) @@ -30,13 +33,13 @@ import java.util.Properties; * @author Teo Sarca, SC ARHIPAC SERVICE SRL *
  • BF [ 2012439 ] DiscountSchemaBreak: setting product & category is allowed */ -public class MDiscountSchemaBreak extends X_M_DiscountSchemaBreak +public class MDiscountSchemaBreak extends X_M_DiscountSchemaBreak implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 6413962940750128351L; + private static final long serialVersionUID = -5405425697628869517L; /** * Standard Constructor @@ -60,6 +63,36 @@ public class MDiscountSchemaBreak extends X_M_DiscountSchemaBreak super(ctx, rs, trxName); } // MDiscountSchemaBreak + /** + * + * @param copy + */ + public MDiscountSchemaBreak(MDiscountSchemaBreak copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MDiscountSchemaBreak(Properties ctx, MDiscountSchemaBreak copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MDiscountSchemaBreak(Properties ctx, MDiscountSchemaBreak copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } /** * Criteria apply @@ -123,5 +156,14 @@ public class MDiscountSchemaBreak extends X_M_DiscountSchemaBreak sb.append ("]"); return sb.toString (); } // toString - + + @Override + public MDiscountSchemaBreak markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MDiscountSchemaBreak diff --git a/org.adempiere.base/src/org/compiere/model/MDiscountSchemaLine.java b/org.adempiere.base/src/org/compiere/model/MDiscountSchemaLine.java index 3c5c192868..36dc9e11b4 100644 --- a/org.adempiere.base/src/org/compiere/model/MDiscountSchemaLine.java +++ b/org.adempiere.base/src/org/compiere/model/MDiscountSchemaLine.java @@ -19,6 +19,9 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; + /** * Discount Schema Line (Price List) Model @@ -26,13 +29,12 @@ import java.util.Properties; * @author Jorg Janke * @version $Id: MDiscountSchemaLine.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $ */ -public class MDiscountSchemaLine extends X_M_DiscountSchemaLine +public class MDiscountSchemaLine extends X_M_DiscountSchemaLine implements ImmutablePOSupport { - /** * */ - private static final long serialVersionUID = 1632154004024021493L; + private static final long serialVersionUID = 5145958821951855437L; /** * Standard Constructor @@ -56,4 +58,44 @@ public class MDiscountSchemaLine extends X_M_DiscountSchemaLine super(ctx, rs, trxName); } // MDiscountSchemaLine + /** + * + * @param copy + */ + public MDiscountSchemaLine(MDiscountSchemaLine copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MDiscountSchemaLine(Properties ctx, MDiscountSchemaLine copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MDiscountSchemaLine(Properties ctx, MDiscountSchemaLine copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + @Override + public MDiscountSchemaLine markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MDiscountSchemaLine diff --git a/org.adempiere.base/src/org/compiere/model/MDistribution.java b/org.adempiere.base/src/org/compiere/model/MDistribution.java index eef34b6b1d..80c85d3f12 100644 --- a/org.adempiere.base/src/org/compiere/model/MDistribution.java +++ b/org.adempiere.base/src/org/compiere/model/MDistribution.java @@ -20,6 +20,7 @@ import java.math.BigDecimal; import java.sql.ResultSet; import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.logging.Level; @@ -65,7 +66,6 @@ public class MDistribution extends X_GL_Distribution /** * Get Distributions for combination - * @param ctx context * @param C_AcctSchema_ID schema * @param PostingType posting type * @param C_DocType_ID document type @@ -85,6 +85,39 @@ public class MDistribution extends X_GL_Distribution * @param User2_ID user 2 * @return array of distributions or null */ + public static MDistribution[] get (int C_AcctSchema_ID, + String PostingType, int C_DocType_ID, Timestamp dateAcct, + int AD_Org_ID, int Account_ID, + int M_Product_ID, int C_BPartner_ID, int C_Project_ID, + int C_Campaign_ID, int C_Activity_ID, int AD_OrgTrx_ID, + int C_SalesRegion_ID, int C_LocTo_ID, int C_LocFrom_ID, + int User1_ID, int User2_ID) + { + return get(Env.getCtx(), C_AcctSchema_ID, PostingType, C_DocType_ID, dateAcct, AD_Org_ID, Account_ID, M_Product_ID, C_BPartner_ID, + C_Project_ID, C_Campaign_ID, C_Activity_ID, AD_OrgTrx_ID, C_SalesRegion_ID, C_LocTo_ID, C_LocFrom_ID, User1_ID, User2_ID); + } + + /** + * Get Distributions for combination + * @param ctx context + * @param C_AcctSchema_ID schema + * @param PostingType posting type + * @param C_DocType_ID document type + * @param AD_Org_ID org + * @param Account_ID account + * @param M_Product_ID product + * @param C_BPartner_ID partner + * @param C_Project_ID project + * @param C_Campaign_ID campaign + * @param C_Activity_ID activity + * @param AD_OrgTrx_ID trx org + * @param C_SalesRegion_ID + * @param C_LocTo_ID location to + * @param C_LocFrom_ID location from + * @param User1_ID user 1 + * @param User2_ID user 2 + * @return array of distributions or null + */ public static MDistribution[] get (Properties ctx, int C_AcctSchema_ID, String PostingType, int C_DocType_ID, Timestamp dateAcct, int AD_Org_ID, int Account_ID, @@ -93,7 +126,7 @@ public class MDistribution extends X_GL_Distribution int C_SalesRegion_ID, int C_LocTo_ID, int C_LocFrom_ID, int User1_ID, int User2_ID) { - MDistribution[] acctList = getAll(ctx); + MDistribution[] acctList = getAll(); if (acctList == null || acctList.length == 0) return null; // @@ -154,12 +187,23 @@ public class MDistribution extends X_GL_Distribution /** * Get Distributions for Account - * @param ctx context + * @param ctx ignore * @param Account_ID id * @return array of distributions */ public static MDistribution[] get (Properties ctx, int Account_ID) { + return get(Account_ID); + } + + /** + * Get Distributions for Account + * @param Account_ID id + * @return array of distributions + */ + public static MDistribution[] get (int Account_ID) + { + Properties ctx = Env.getCtx(); Integer key = Integer.valueOf(Account_ID); MDistribution[] retValue = (MDistribution[])s_accounts.get(key); if (retValue != null) @@ -177,20 +221,31 @@ public class MDistribution extends X_GL_Distribution .list(); // retValue = new MDistribution[list.size ()]; - list.toArray (retValue); + retValue = list.toArray (retValue); s_accounts.put(key, retValue); return retValue; } // get /** * Get All Distributions - * @param ctx context + * @param ctx ignore * @param Account_ID id * @return array of distributions + * @deprecated */ public static MDistribution[] getAll (Properties ctx) { - return get(ctx, -1); + return getAll(); + } + + /** + * Get All Distributions + * @param Account_ID id + * @return array of distributions + */ + public static MDistribution[] getAll () + { + return get(-1); } // get /** Static Logger */ @@ -245,6 +300,38 @@ public class MDistribution extends X_GL_Distribution super(ctx, rs, trxName); } // MDistribution + /** + * + * @param copy + */ + public MDistribution(MDistribution copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MDistribution(Properties ctx, MDistribution copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MDistribution(Properties ctx, MDistribution copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_lines = copy.m_lines != null ? Arrays.stream(copy.m_lines).map(e -> {var v = new MDistributionLine(ctx, e, trxName); v.setParent(this); return v;}).toArray(MDistributionLine[]::new) : null; + } + /** The Lines */ private MDistributionLine[] m_lines = null; @@ -449,5 +536,5 @@ public class MDistribution extends X_GL_Distribution setUser2_ID(0); return true; } // beforeSave - + } // MDistribution diff --git a/org.adempiere.base/src/org/compiere/model/MDistributionLine.java b/org.adempiere.base/src/org/compiere/model/MDistributionLine.java index 643ca8c73b..c865129aba 100644 --- a/org.adempiere.base/src/org/compiere/model/MDistributionLine.java +++ b/org.adempiere.base/src/org/compiere/model/MDistributionLine.java @@ -81,6 +81,41 @@ public class MDistributionLine extends X_GL_DistributionLine super(ctx, rs, trxName); } // MDistributionLine + /** + * + * @param copy + */ + public MDistributionLine(MDistributionLine copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MDistributionLine(Properties ctx, MDistributionLine copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MDistributionLine(Properties ctx, MDistributionLine copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_parent = null; + this.m_amt = copy.m_amt; + this.m_qty = copy.m_qty; + this.m_account = copy.m_account != null ? new MAccount(ctx, copy.m_account, trxName) : null; + } + /** The Parent */ private MDistribution m_parent = null; /** The Amount */ diff --git a/org.adempiere.base/src/org/compiere/model/MDistributionRunLine.java b/org.adempiere.base/src/org/compiere/model/MDistributionRunLine.java index e5baa1c3da..6356dc5991 100644 --- a/org.adempiere.base/src/org/compiere/model/MDistributionRunLine.java +++ b/org.adempiere.base/src/org/compiere/model/MDistributionRunLine.java @@ -215,7 +215,7 @@ public class MDistributionRunLine extends X_M_DistributionRunLine public MProduct getProduct() { if (m_product == null) - m_product = MProduct.get(getCtx(), getM_Product_ID()); + m_product = MProduct.getCopy(getCtx(), getM_Product_ID(), get_TrxName()); return m_product; } // getProduct diff --git a/org.adempiere.base/src/org/compiere/model/MDocType.java b/org.adempiere.base/src/org/compiere/model/MDocType.java index f5c504cacc..4baea98c6f 100644 --- a/org.adempiere.base/src/org/compiere/model/MDocType.java +++ b/org.adempiere.base/src/org/compiere/model/MDocType.java @@ -21,9 +21,10 @@ import java.util.List; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Document Type Model @@ -36,12 +37,12 @@ import org.compiere.util.Env; * See https://sourceforge.net/forum/message.php?msg_id=6499893 * @version $Id: MDocType.java,v 1.3 2006/07/30 00:54:54 jjanke Exp $ */ -public class MDocType extends X_C_DocType +public class MDocType extends X_C_DocType implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -6556521509479670059L; + private static final long serialVersionUID = -7313617271586412889L; /** * Return the first Doc Type for this BaseType @@ -86,24 +87,38 @@ public class MDocType extends X_C_DocType } // getOfClient /** - * Get Document Type (cached) + * Get Document Type (cached) (immutable) + * @param C_DocType_ID id + * @return document type + */ + static public MDocType get (int C_DocType_ID) + { + return get(Env.getCtx(), C_DocType_ID); + } + + /** + * Get Document Type (cached) (immutable) * @param ctx context * @param C_DocType_ID id * @return document type */ static public MDocType get (Properties ctx, int C_DocType_ID) { - MDocType retValue = (MDocType)s_cache.get(C_DocType_ID); - if (retValue == null) + MDocType retValue = s_cache.get(ctx, C_DocType_ID, e -> new MDocType(ctx, e)); + if (retValue != null) + return retValue; + + retValue = new MDocType (ctx, C_DocType_ID, (String)null); + if (retValue.getC_DocType_ID() == C_DocType_ID) { - retValue = new MDocType (ctx, C_DocType_ID, null); - s_cache.put(C_DocType_ID, retValue); + s_cache.put(C_DocType_ID, retValue, e -> new MDocType(Env.getCtx(), e)); + return retValue; } - return retValue; + return null; } // get /** Cache */ - static private CCache s_cache = new CCache(Table_Name, 20); + static private ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /************************************************************************** * Standard Constructor @@ -163,6 +178,37 @@ public class MDocType extends X_C_DocType setGL_Category_ID (); } // MDocType + /** + * + * @param copy + */ + public MDocType(MDocType copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MDocType(Properties ctx, MDocType copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MDocType(Properties ctx, MDocType copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Set Default GL Category */ @@ -314,7 +360,7 @@ public class MDocType extends X_C_DocType int relatedDocTypeId = 0; if (docTypeId != 0) { - MDocType docType = MDocType.get(Env.getCtx(), docTypeId); + MDocType docType = MDocType.get(docTypeId); // FIXME: Should refactor code and remove the hard coded name // Should change document type to allow query the value if ("Return Material".equals(docType.getName()) || @@ -368,4 +414,13 @@ public class MDocType extends X_C_DocType return get_Translation (COLUMNNAME_Name, Env.getAD_Language(getCtx())); } // getNameTrl + @Override + public MDocType markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MDocType diff --git a/org.adempiere.base/src/org/compiere/model/MDocTypeCounter.java b/org.adempiere.base/src/org/compiere/model/MDocTypeCounter.java index 8b9d333cfc..7d55c2f5c3 100644 --- a/org.adempiere.base/src/org/compiere/model/MDocTypeCounter.java +++ b/org.adempiere.base/src/org/compiere/model/MDocTypeCounter.java @@ -21,9 +21,11 @@ import java.sql.ResultSet; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** @@ -32,13 +34,12 @@ import org.compiere.util.DB; * @author Jorg Janke * @version $Id: MDocTypeCounter.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $ */ -public class MDocTypeCounter extends X_C_DocTypeCounter +public class MDocTypeCounter extends X_C_DocTypeCounter implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 3469046560457430527L; - + private static final long serialVersionUID = 3999273279386464393L; /** * Get Counter document for document type @@ -59,7 +60,7 @@ public class MDocTypeCounter extends X_C_DocTypeCounter // Indirect Relationship int Counter_C_DocType_ID = 0; - MDocType dt = MDocType.get(ctx, C_DocType_ID); + MDocType dt = MDocType.get(C_DocType_ID); if (!dt.isCreateCounter()) return -1; String cDocBaseType = getCounterDocBaseType(dt.getDocBaseType()); @@ -82,15 +83,23 @@ public class MDocTypeCounter extends X_C_DocTypeCounter return Counter_C_DocType_ID; } // getCounterDocType_ID - - /** * Get (first) valid Counter document for document type - * @param ctx context + * @param ctx ignore * @param C_DocType_ID base document * @return counter document (may be invalid) or null */ public static MDocTypeCounter getCounterDocType (Properties ctx, int C_DocType_ID) + { + return getCounterDocType(C_DocType_ID); + } + + /** + * Get (first) valid Counter document for document type + * @param C_DocType_ID base document + * @return counter document (may be invalid) or null + */ + public static MDocTypeCounter getCounterDocType (int C_DocType_ID) { Integer key = Integer.valueOf(C_DocType_ID); MDocTypeCounter retValue = (MDocTypeCounter)s_counter.get(key); @@ -109,12 +118,16 @@ public class MDocTypeCounter extends X_C_DocTypeCounter rs = pstmt.executeQuery (); while (rs.next () && retValue == null) { - retValue = new MDocTypeCounter (ctx, rs, null); + retValue = new MDocTypeCounter (Env.getCtx(), rs, null); if (!retValue.isCreateCounter() || !retValue.isValid()) { temp = retValue; retValue = null; } + else + { + s_counter.put(key, retValue); + } } } catch (Exception e) @@ -136,21 +149,46 @@ public class MDocTypeCounter extends X_C_DocTypeCounter /** * Get MDocTypeCounter from Cache - * @param ctx context * @param C_DocTypeCounter_ID id * @return MDocTypeCounter - * @param trxName transaction + */ + public static MDocTypeCounter get (int C_DocTypeCounter_ID) + { + return get(C_DocTypeCounter_ID, (String)null); + } + + /** + * Get MDocTypeCounter from Cache + * @param C_DocTypeCounter_ID id + * @param trxName transaction + * @return MDocTypeCounter + */ + public static MDocTypeCounter get (int C_DocTypeCounter_ID, String trxName) + { + return get(Env.getCtx(), C_DocTypeCounter_ID, trxName); + } + + /** + * Get MDocTypeCounter from Cache + * @param ctx context + * @param C_DocTypeCounter_ID id + * @param trxName + * @return MDocTypeCounter */ public static MDocTypeCounter get (Properties ctx, int C_DocTypeCounter_ID, String trxName) { Integer key = Integer.valueOf(C_DocTypeCounter_ID); - MDocTypeCounter retValue = (MDocTypeCounter) s_cache.get (key); + MDocTypeCounter retValue = (MDocTypeCounter) s_cache.get (ctx, key, e -> new MDocTypeCounter(ctx, e)); if (retValue != null) - return retValue; + return retValue; + retValue = new MDocTypeCounter (ctx, C_DocTypeCounter_ID, trxName); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + if (retValue.get_ID () == C_DocTypeCounter_ID) + { + s_cache.put(key, retValue, e -> new MDocTypeCounter(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** @@ -196,9 +234,9 @@ public class MDocTypeCounter extends X_C_DocTypeCounter /** Object Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** Counter Relationship Cache */ - private static CCache s_counter = new CCache(Table_Name, "C_DocTypeCounter_Relation", 20); + private static ImmutableIntPOCache s_counter = new ImmutableIntPOCache(Table_Name, "C_DocTypeCounter_Relation", 20); /** Static Logger */ private static CLogger s_log = CLogger.getCLogger (MDocTypeCounter.class); @@ -230,6 +268,36 @@ public class MDocTypeCounter extends X_C_DocTypeCounter super(ctx, rs, trxName); } // MDocTypeCounter + /** + * + * @param copy + */ + public MDocTypeCounter(MDocTypeCounter copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MDocTypeCounter(Properties ctx, MDocTypeCounter copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MDocTypeCounter(Properties ctx, MDocTypeCounter copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } /** * Set C_DocType_ID @@ -255,7 +323,7 @@ public class MDocTypeCounter extends X_C_DocTypeCounter } // setCounter_C_DocType_ID /** - * Get Doc Type + * Get Doc Type (immutable) * @return doc type or null if not existing */ public MDocType getDocType() @@ -271,7 +339,7 @@ public class MDocTypeCounter extends X_C_DocTypeCounter } // getDocType /** - * Get Counter Doc Type + * Get Counter Doc Type (immutable) * @return counter doc type or null if not existing */ public MDocType getCounterDocType() @@ -379,5 +447,14 @@ public class MDocTypeCounter extends X_C_DocTypeCounter validate(); return true; } // beforeSave - + + @Override + public MDocTypeCounter markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MDocTypeCounter diff --git a/org.adempiere.base/src/org/compiere/model/MEXPFormat.java b/org.adempiere.base/src/org/compiere/model/MEXPFormat.java index 40b3298b65..78e602d962 100644 --- a/org.adempiere.base/src/org/compiere/model/MEXPFormat.java +++ b/org.adempiere.base/src/org/compiere/model/MEXPFormat.java @@ -32,13 +32,17 @@ package org.compiere.model; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Properties; +import java.util.stream.Collectors; -import org.compiere.util.CCache; import org.compiere.util.CLogger; - +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.POCopyCache; /** * @author Trifon N. Trifonov @@ -50,18 +54,19 @@ import org.compiere.util.CLogger; *
  • https://sourceforge.net/tracker/?func=detail&atid=879332&aid=2936561&group_id=176962 * */ -public class MEXPFormat extends X_EXP_Format { +public class MEXPFormat extends X_EXP_Format implements ImmutablePOSupport { + /** * */ - private static final long serialVersionUID = -5011042965945626099L; + private static final long serialVersionUID = -2749091471654364602L; /** Static Logger */ @SuppressWarnings("unused") private static CLogger s_log = CLogger.getCLogger (MEXPFormat.class); - private static CCache s_cache = new CCache(MEXPFormat.Table_Name, 50 ); - private static CCache exp_format_by_id_cache = new CCache(MEXPFormat.Table_Name, 50); + private static POCopyCache s_cache = new POCopyCache(MEXPFormat.Table_Name, 50 ); + private static ImmutableIntPOCache exp_format_by_id_cache = new ImmutableIntPOCache(MEXPFormat.Table_Name, 50); private List m_lines = null; private List m_lines_unique = null; @@ -75,6 +80,36 @@ public class MEXPFormat extends X_EXP_Format { super (ctx, rs, trxName); } + /** + * + * @param copy + */ + public MEXPFormat(MEXPFormat copy) { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MEXPFormat(Properties ctx, MEXPFormat copy) { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MEXPFormat(Properties ctx, MEXPFormat copy, String trxName) { + this(ctx, 0, trxName); + copyPO(copy); + this.m_lines = copy.m_lines != null ? copy.m_lines.stream().map(e -> {return new MEXPFormatLine(ctx, e, trxName);}).collect(Collectors.toCollection(ArrayList::new)) : null; + this.m_lines_unique = copy.m_lines_unique != null ? copy.m_lines_unique.stream().map(e -> {return new MEXPFormatLine(ctx, e, trxName);}).collect(Collectors.toCollection(ArrayList::new)) : null; + } + public List getFormatLines() { return getFormatLinesOrderedBy(X_EXP_FormatLine.COLUMNNAME_Position); } @@ -92,6 +127,8 @@ public class MEXPFormat extends X_EXP_Format { .setParameters(getEXP_Format_ID()) .setOrderBy(orderBy) .list(); + if (is_Immutable() && m_lines.size() > 0) + m_lines.stream().forEach(e -> e.markImmutable()); return m_lines; } @@ -107,30 +144,62 @@ public class MEXPFormat extends X_EXP_Format { .setParameters(getEXP_Format_ID(), "Y") .setOrderBy(X_EXP_FormatLine.COLUMNNAME_Position) .list(); + if (is_Immutable() && m_lines_unique.size() > 0) + m_lines_unique.stream().forEach(e -> e.markImmutable()); return m_lines_unique; } + /** + * Get MEXPFormat from cache (immutable) + * @param EXP_Format_ID + * @return MEXPFormat + */ + public static MEXPFormat get(int EXP_Format_ID) + { + return get(EXP_Format_ID, (String)null); + } + + /** + * Get MEXPFormat from cache (immutable) + * @param EXP_Format_ID + * @param trxName + * @return MEXPFormat + */ + public static MEXPFormat get(int EXP_Format_ID, String trxName) + { + return get(Env.getCtx(), EXP_Format_ID, trxName); + } + + /** + * Get MEXPFormat from cache (immutable) + * @param ctx + * @param EXP_Format_ID + * @param trxName + * @return MEXPFormat + */ public static MEXPFormat get(Properties ctx, int EXP_Format_ID, String trxName) { - MEXPFormat exp_format = exp_format_by_id_cache.get(EXP_Format_ID); + MEXPFormat exp_format = exp_format_by_id_cache.get(ctx, EXP_Format_ID, e -> new MEXPFormat(ctx, e)); if(exp_format != null) return exp_format; + exp_format = new MEXPFormat(ctx, EXP_Format_ID , trxName); - if(exp_format!=null) + if(exp_format.getEXP_Format_ID() == EXP_Format_ID) { - exp_format.getFormatLines(); - exp_format_by_id_cache.put(EXP_Format_ID, exp_format); + exp_format.getFormatLines(); + exp_format_by_id_cache.put(EXP_Format_ID, exp_format, e -> new MEXPFormat(Env.getCtx(), e)); + return exp_format; } - return exp_format; + return null; } public static MEXPFormat getFormatByValueAD_Client_IDAndVersion(Properties ctx, String value, int AD_Client_ID, String version, String trxName) throws SQLException { String key = new String(value+version); - MEXPFormat retValue=null; - //if(retValue!=null) - // return retValue; + MEXPFormat retValue=s_cache.get(key, e -> new MEXPFormat(ctx, e, trxName)); + if (retValue != null) + return retValue; StringBuilder whereClause = new StringBuilder(X_EXP_Format.COLUMNNAME_Value).append("=?") .append(" AND AD_Client_ID = ?") @@ -139,22 +208,21 @@ public class MEXPFormat extends X_EXP_Format { retValue = (MEXPFormat) new Query(ctx,X_EXP_Format.Table_Name,whereClause.toString(),trxName) .setParameters(value,AD_Client_ID,version).first(); - if(retValue != null) + if (retValue != null) { retValue.getFormatLines(); - s_cache.put (key, retValue); - exp_format_by_id_cache.put(retValue.getEXP_Format_ID(), retValue); + s_cache.put (key, retValue, e -> new MEXPFormat(Env.getCtx(), e)); + exp_format_by_id_cache.put(retValue.getEXP_Format_ID(), new MEXPFormat(Env.getCtx(), retValue)); + return retValue; } - return retValue; + return null; } public static MEXPFormat getFormatByAD_Client_IDAD_Table_IDAndVersion(Properties ctx, int AD_Client_ID, int AD_Table_ID, String version, String trxName) throws SQLException { String key = new String(MTable.getTableName(ctx, AD_Table_ID)+version); - MEXPFormat retValue=null; - - retValue = (MEXPFormat)s_cache.get(key); + MEXPFormat retValue = s_cache.get(key, e -> new MEXPFormat(ctx, e, trxName)); if(retValue!=null) return retValue; @@ -168,11 +236,12 @@ public class MEXPFormat extends X_EXP_Format { if(retValue!=null) { retValue.getFormatLines(); - s_cache.put (key, retValue); - exp_format_by_id_cache.put(retValue.getEXP_Format_ID(), retValue); + s_cache.put (key, retValue, e -> new MEXPFormat(Env.getCtx(), e)); + exp_format_by_id_cache.put(retValue.getEXP_Format_ID(), new MEXPFormat(Env.getCtx(), retValue)); + return retValue.markImmutable(); } - return retValue; + return null; } @Override @@ -196,4 +265,19 @@ public class MEXPFormat extends X_EXP_Format { } return true; } // beforeDelete + + @Override + public MEXPFormat markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_lines != null && m_lines.size() > 0) + m_lines.stream().forEach(e -> e.markImmutable()); + if (m_lines_unique != null && m_lines_unique.size() > 0) + m_lines_unique.stream().forEach(e -> e.markImmutable()); + return this; + } + + } diff --git a/org.adempiere.base/src/org/compiere/model/MEXPFormatLine.java b/org.adempiere.base/src/org/compiere/model/MEXPFormatLine.java index bc02c71cea..b570e7ccb9 100644 --- a/org.adempiere.base/src/org/compiere/model/MEXPFormatLine.java +++ b/org.adempiere.base/src/org/compiere/model/MEXPFormatLine.java @@ -37,15 +37,17 @@ import java.util.logging.Level; import org.compiere.util.CLogger; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; /** * @author Trifon N. Trifonov */ -public class MEXPFormatLine extends X_EXP_FormatLine { +public class MEXPFormatLine extends X_EXP_FormatLine implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 1855089248134520749L; + private static final long serialVersionUID = 2125885766063286714L; /** Static Logger */ private static CLogger s_log = CLogger.getCLogger (X_EXP_FormatLine.class); @@ -59,6 +61,34 @@ public class MEXPFormatLine extends X_EXP_FormatLine { super (ctx, rs, trxName); } + /** + * + * @param copy + */ + public MEXPFormatLine(MEXPFormatLine copy) { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MEXPFormatLine(Properties ctx, MEXPFormatLine copy) { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MEXPFormatLine(Properties ctx, MEXPFormatLine copy, String trxName) { + this(ctx, 0, trxName); + copyPO(copy); + } + @Override public String toString() { StringBuilder sb = new StringBuilder ("X_EXP_FormatLine[ID=").append(get_ID()).append("; Value=").append(getValue()).append("; Type=").append(getType()).append("]"); @@ -98,4 +128,14 @@ public class MEXPFormatLine extends X_EXP_FormatLine { return result; } + + @Override + public MEXPFormatLine markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } diff --git a/org.adempiere.base/src/org/compiere/model/MElementValue.java b/org.adempiere.base/src/org/compiere/model/MElementValue.java index 7c880550ab..6ee1c610ac 100644 --- a/org.adempiere.base/src/org/compiere/model/MElementValue.java +++ b/org.adempiere.base/src/org/compiere/model/MElementValue.java @@ -22,6 +22,7 @@ import java.util.Properties; import org.adempiere.exceptions.AdempiereException; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; /** * Natural Account @@ -33,12 +34,12 @@ import org.compiere.util.Env; * BF [ 1883533 ] Change to summary - valid combination issue * BF [ 2320411 ] Translate "Already posted to" message */ -public class MElementValue extends X_C_ElementValue +public class MElementValue extends X_C_ElementValue implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 4765839867934329276L; + private static final long serialVersionUID = 6352667759697380460L; /** * Standard Constructor @@ -116,6 +117,37 @@ public class MElementValue extends X_C_ElementValue set(imp); } // MElementValue + /** + * + * @param copy + */ + public MElementValue(MElementValue copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MElementValue(Properties ctx, MElementValue copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MElementValue(Properties ctx, MElementValue copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Set/Update Settings from import * @param imp import @@ -279,4 +311,13 @@ public class MElementValue extends X_C_ElementValue return success; } // afterDelete + @Override + public MElementValue markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MElementValue diff --git a/org.adempiere.base/src/org/compiere/model/MEntityType.java b/org.adempiere.base/src/org/compiere/model/MEntityType.java index a0b641561a..88d74c4026 100644 --- a/org.adempiere.base/src/org/compiere/model/MEntityType.java +++ b/org.adempiere.base/src/org/compiere/model/MEntityType.java @@ -22,8 +22,10 @@ import static org.compiere.model.SystemIDs.ENTITYTYPE_DICTIONARY; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.CLogger; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.ImmutablePOCache; /** * Enitity Type Model @@ -39,34 +41,47 @@ import org.compiere.util.CLogger; *
  • BF [ 2861194 ] EntityType is not using normal PO framework for getting IDs * https://sourceforge.net/tracker/?func=detail&aid=2861194&group_id=176962&atid=879332 */ -public class MEntityType extends X_AD_EntityType +public class MEntityType extends X_AD_EntityType implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -8449015496292546851L; + private static final long serialVersionUID = -7160389442572466581L; /** - * Get EntityType object by name + * Get EntityType object by name (immutable) + * @param entityType + * @return entity type + */ + public static MEntityType get(String entityType) + { + return get(Env.getCtx(), entityType); + } + + /** + * Get EntityType object by name (immutable) * @param ctx * @param entityType - * @return + * @return entity type */ public static MEntityType get(Properties ctx, String entityType) { - MEntityType retValue = (MEntityType) s_cache.get (entityType); + MEntityType retValue = s_cache.get (ctx, entityType, e -> new MEntityType(ctx, e)); if (retValue != null) return retValue; + retValue = new Query(ctx, Table_Name, "EntityType=?", null) .setParameters(entityType) .firstOnly(); + if (retValue != null) - s_cache.put (entityType, retValue); + s_cache.put (entityType, retValue, e -> new MEntityType(Env.getCtx(), e)); + return retValue; } /** Cached EntityTypes */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutablePOCache s_cache = new ImmutablePOCache(Table_Name, 20); /** Logger */ @SuppressWarnings("unused") private static CLogger s_log = CLogger.getCLogger (MEntityType.class); @@ -93,6 +108,37 @@ public class MEntityType extends X_AD_EntityType super (ctx, rs, trxName); } // MEntityType + /** + * + * @param copy + */ + public MEntityType(MEntityType copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MEntityType(Properties ctx, MEntityType copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MEntityType(Properties ctx, MEntityType copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * First Not System Entity ID * 10=D, 20=C, 100=U, 110=CUST, 200=A, 210=EXT, 220=XX etc @@ -183,4 +229,13 @@ public class MEntityType extends X_AD_EntityType return true; } // beforeDelete + @Override + public MEntityType markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MEntityType diff --git a/org.adempiere.base/src/org/compiere/model/MField.java b/org.adempiere.base/src/org/compiere/model/MField.java index 08f4313ae8..ad783fe317 100644 --- a/org.adempiere.base/src/org/compiere/model/MField.java +++ b/org.adempiere.base/src/org/compiere/model/MField.java @@ -19,7 +19,9 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** @@ -28,35 +30,44 @@ import org.compiere.util.CCache; * @author Jorg Janke * @version $Id: MField.java,v 1.2 2006/07/30 00:58:04 jjanke Exp $ */ -public class MField extends X_AD_Field +public class MField extends X_AD_Field implements ImmutablePOSupport { - /** * */ - private static final long serialVersionUID = 7243492167390659946L; + private static final long serialVersionUID = -7382459987895129752L; /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** * - * @param ctx * @param AD_Field_ID - * @return MField + * @return MField (immutable) + */ + public static MField get(int AD_Field_ID) + { + return get(Env.getCtx(), AD_Field_ID); + } + + /** + * @param ctx context + * @param AD_Field_ID + * @return Immutable instance of MField */ public static MField get(Properties ctx, int AD_Field_ID) { Integer key = Integer.valueOf(AD_Field_ID); - MField retValue = s_cache.get (key); - if (retValue != null && retValue.getCtx() == ctx) { + MField retValue = s_cache.get (ctx, key, e -> new MField(ctx, e)); + if (retValue != null) + return retValue; + + retValue = new MField (ctx, AD_Field_ID, (String)null); + if (retValue.get_ID () == AD_Field_ID) { + s_cache.put (key, retValue, e -> new MField(Env.getCtx(), e)); return retValue; } - retValue = new MField (ctx, AD_Field_ID, null); - if (retValue.get_ID () == AD_Field_ID) { - s_cache.put (key, retValue); - } - return retValue; + return null; } /** @@ -122,6 +133,37 @@ public class MField extends X_AD_Field setEntityType(parent.getEntityType()); } // M_Field + /** + * + * @param copy + */ + public MField(MField copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MField(Properties ctx, MField copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MField(Properties ctx, MField copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Set Column Values * @param column column @@ -185,4 +227,13 @@ public class MField extends X_AD_Field return true; } // beforeSave + @Override + public MField markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MField diff --git a/org.adempiere.base/src/org/compiere/model/MGLCategory.java b/org.adempiere.base/src/org/compiere/model/MGLCategory.java index cab8f91794..c890ed55d1 100644 --- a/org.adempiere.base/src/org/compiere/model/MGLCategory.java +++ b/org.adempiere.base/src/org/compiere/model/MGLCategory.java @@ -21,10 +21,11 @@ import java.sql.ResultSet; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * GL Category @@ -32,30 +33,42 @@ import org.compiere.util.Env; * @author Jorg Janke * @version $Id: MGLCategory.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $ */ -public class MGLCategory extends X_GL_Category +public class MGLCategory extends X_GL_Category implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -272365151811522531L; - + private static final long serialVersionUID = 7294511214194057235L; /** - * Get MGLCategory from Cache - * @param ctx context + * Get MGLCategory from Cache (immutable) * @param GL_Category_ID id * @return MGLCategory */ + public static MGLCategory get (int GL_Category_ID) + { + return get(Env.getCtx(), GL_Category_ID); + } + + /** + * Get MGLCategory from Cache (immutable) + * @param ctx context + * @param GL_Category_ID id + * @return immutable instance of MGLCategory + */ public static MGLCategory get (Properties ctx, int GL_Category_ID) { Integer key = Integer.valueOf(GL_Category_ID); - MGLCategory retValue = (MGLCategory)s_cache.get (key); + MGLCategory retValue = s_cache.get (ctx, key, e -> new MGLCategory(ctx, e)); if (retValue != null) return retValue; - retValue = new MGLCategory (ctx, GL_Category_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MGLCategory (ctx, GL_Category_ID, (String)null); + if (retValue.get_ID () == GL_Category_ID) + { + s_cache.put (key, retValue, e -> new MGLCategory(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** @@ -126,8 +139,8 @@ public class MGLCategory extends X_GL_Category /** Logger */ private static CLogger s_log = CLogger.getCLogger (MGLCategory.class); /** Cache */ - private static CCache s_cache - = new CCache (Table_Name, 5); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache (Table_Name, 5); /************************************************************************** @@ -158,6 +171,37 @@ public class MGLCategory extends X_GL_Category super(ctx, rs, trxName); } // MGLCategory + /** + * + * @param copy + */ + public MGLCategory(MGLCategory copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MGLCategory(Properties ctx, MGLCategory copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MGLCategory(Properties ctx, MGLCategory copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + @Override public String toString() { @@ -169,4 +213,14 @@ public class MGLCategory extends X_GL_Category .append("]"); return msgreturn.toString(); } + + @Override + public MGLCategory markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MGLCategory diff --git a/org.adempiere.base/src/org/compiere/model/MGoal.java b/org.adempiere.base/src/org/compiere/model/MGoal.java index aa07f18e4c..a67fcb7dfb 100644 --- a/org.adempiere.base/src/org/compiere/model/MGoal.java +++ b/org.adempiere.base/src/org/compiere/model/MGoal.java @@ -359,7 +359,7 @@ public class MGoal extends X_PA_Goal public MMeasure getMeasure() { if (getPA_Measure_ID() != 0) - return MMeasure.get(getCtx(), getPA_Measure_ID()); + return MMeasure.get(getPA_Measure_ID()); return null; } // getMeasure @@ -372,7 +372,7 @@ public class MGoal extends X_PA_Goal public boolean updateGoal(boolean force) { if (log.isLoggable(Level.CONFIG)) log.config("Force=" + force); - MMeasure measure = MMeasure.get(getCtx(), getPA_Measure_ID()); + MMeasure measure = MMeasure.get(getPA_Measure_ID()); boolean isUpdateByInterfal = false; if (getDateLastRun() != null){ @@ -385,7 +385,7 @@ public class MGoal extends X_PA_Goal || getDateLastRun() == null || isUpdateByInterfal) { - measure.set_TrxName(get_TrxName()); + measure = new MMeasure(Env.getCtx(), measure, get_TrxName()); if (measure.updateGoals()) // saves { load(get_ID(), get_TrxName()); @@ -464,7 +464,7 @@ public class MGoal extends X_PA_Goal */ public MColorSchema getColorSchema() { - return MColorSchema.get(getCtx(), getPA_ColorSchema_ID()); + return MColorSchema.getCopy(getCtx(), getPA_ColorSchema_ID(), get_TrxName()); } /** diff --git a/org.adempiere.base/src/org/compiere/model/MGroup.java b/org.adempiere.base/src/org/compiere/model/MGroup.java index 1425a9c8e7..d7618b5945 100644 --- a/org.adempiere.base/src/org/compiere/model/MGroup.java +++ b/org.adempiere.base/src/org/compiere/model/MGroup.java @@ -19,41 +19,70 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Request Group Model * @author Jorg Janke * @version $Id: MGroup.java,v 1.2 2006/07/30 00:51:05 jjanke Exp $ */ -public class MGroup extends X_R_Group +public class MGroup extends X_R_Group implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 3218102715154328611L; - + private static final long serialVersionUID = 9013217403211341916L; /** - * Get MGroup from Cache - * @param ctx context + * Get MGroup from Cache (immutable) * @param R_Group_ID id - * @return MGroup + * @return MGroup + */ + public static MGroup get (int R_Group_ID) + { + return get(Env.getCtx(), R_Group_ID); + } + + /** + * Get MGroup from Cache (immutable) + * @param ctx context + * @param R_Group_ID id + * @return Immutable instance of MGroup */ public static MGroup get (Properties ctx, int R_Group_ID) { Integer key = Integer.valueOf(R_Group_ID); - MGroup retValue = (MGroup) s_cache.get (key); + MGroup retValue = s_cache.get (ctx, key, e -> new MGroup(ctx, e)); if (retValue != null) return retValue; - retValue = new MGroup (ctx, R_Group_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MGroup (ctx, R_Group_ID, (String)null); + if (retValue.get_ID () == R_Group_ID) + { + s_cache.put (key, retValue, e -> new MGroup(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MGroup from cache + * @param ctx + * @param R_Group_ID + * @param trxName + * @return MGroup + */ + public static MGroup getCopy(Properties ctx, int R_Group_ID, String trxName) + { + MGroup grp = get(ctx, R_Group_ID); + if (grp != null) + grp = new MGroup(ctx, grp, trxName); + return grp; + } + /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /************************************************************************** @@ -78,4 +107,44 @@ public class MGroup extends X_R_Group super (ctx, rs, trxName); } // MGroup + /** + * + * @param copy + */ + public MGroup(MGroup copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MGroup(Properties ctx, MGroup copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MGroup(Properties ctx, MGroup copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + @Override + public MGroup markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MGroup diff --git a/org.adempiere.base/src/org/compiere/model/MHierarchy.java b/org.adempiere.base/src/org/compiere/model/MHierarchy.java index 9200d66ada..e641f4b1c6 100644 --- a/org.adempiere.base/src/org/compiere/model/MHierarchy.java +++ b/org.adempiere.base/src/org/compiere/model/MHierarchy.java @@ -19,7 +19,9 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Reporting Hierarchy Model @@ -27,34 +29,47 @@ import org.compiere.util.CCache; * @author Jorg Janke * @version $Id: MHierarchy.java,v 1.2 2006/07/30 00:51:05 jjanke Exp $ */ -public class MHierarchy extends X_PA_Hierarchy +public class MHierarchy extends X_PA_Hierarchy implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 3278979908976853690L; + private static final long serialVersionUID = 7862096742442159952L; /** - * Get MHierarchy from Cache - * @param ctx context + * Get MHierarchy from Cache (immutable) + * @param PA_Hierarchy_ID id + * @return MHierarchy + */ + public static MHierarchy get (int PA_Hierarchy_ID) + { + return get(Env.getCtx(), PA_Hierarchy_ID); + } + + /** + * Get MHierarchy (Immutable) from Cache + * @param ctx context * @param PA_Hierarchy_ID id * @return MHierarchy */ public static MHierarchy get (Properties ctx, int PA_Hierarchy_ID) { Integer key = Integer.valueOf(PA_Hierarchy_ID); - MHierarchy retValue = (MHierarchy)s_cache.get (key); + MHierarchy retValue = (MHierarchy)s_cache.get (ctx, key, e -> new MHierarchy(ctx, e)); if (retValue != null) return retValue; - retValue = new MHierarchy (ctx, PA_Hierarchy_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MHierarchy (ctx, PA_Hierarchy_ID, (String)null); + if (retValue.get_ID () == PA_Hierarchy_ID) + { + s_cache.put (key, retValue, e -> new MHierarchy(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private static CCache s_cache - = new CCache (Table_Name, 20); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache (Table_Name, 20); /** * Default Constructor @@ -78,6 +93,37 @@ public class MHierarchy extends X_PA_Hierarchy super (ctx, rs, trxName); } // MHierarchy + /** + * + * @param copy + */ + public MHierarchy(MHierarchy copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MHierarchy(Properties ctx, MHierarchy copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MHierarchy(Properties ctx, MHierarchy copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Get AD_Tree_ID based on tree type * @param TreeType Tree Type @@ -106,4 +152,13 @@ public class MHierarchy extends X_PA_Hierarchy return 0; } // getAD_Tree_ID + @Override + public MHierarchy markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MHierarchy diff --git a/org.adempiere.base/src/org/compiere/model/MImage.java b/org.adempiere.base/src/org/compiere/model/MImage.java index 9b7e949b98..519ac24a91 100644 --- a/org.adempiere.base/src/org/compiere/model/MImage.java +++ b/org.adempiere.base/src/org/compiere/model/MImage.java @@ -33,8 +33,9 @@ import javax.swing.Icon; import javax.swing.ImageIcon; import org.adempiere.base.Core; -import org.compiere.util.CCache; -import org.compiere.util.Ini; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Image Model @@ -43,17 +44,27 @@ import org.compiere.util.Ini; * @author Jorg Janke * @version $Id: MImage.java,v 1.5 2006/07/30 00:51:02 jjanke Exp $ */ -public class MImage extends X_AD_Image +public class MImage extends X_AD_Image implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -7361463683427300715L; - + private static final long serialVersionUID = 1850627989276185947L; + private MStorageProvider provider; /** - * Get MImage from Cache + * Get MImage from Cache (immutable) + * @param AD_Image_ID id + * @return MImage + */ + public static MImage get (int AD_Image_ID) + { + return get(Env.getCtx(), AD_Image_ID); + } + + /** + * Get MImage (Immutable) from Cache * @param ctx context * @param AD_Image_ID id * @return MImage @@ -64,17 +75,36 @@ public class MImage extends X_AD_Image return new MImage (ctx, AD_Image_ID, null); // Integer key = Integer.valueOf(AD_Image_ID); - MImage retValue = (MImage) s_cache.get (key); + MImage retValue = s_cache.get (ctx, key, e -> new MImage(ctx, e)); if (retValue != null) return retValue; - retValue = new MImage (ctx, AD_Image_ID, null); - if (retValue.get_ID () != 0 && Ini.isClient()) - s_cache.put (key, retValue); - return retValue; + retValue = new MImage (ctx, AD_Image_ID, (String)null); + if (retValue.get_ID () == AD_Image_ID) + { + s_cache.put (key, retValue, e -> new MImage(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MImage from cache + * @param ctx context + * @param AD_Image_ID + * @param trxName transaction name + * @return MImage + */ + public static MImage getCopy(Properties ctx, int AD_Image_ID, String trxName) + { + MImage img = get(AD_Image_ID); + if (img != null && img.getAD_Image_ID() > 0) + img = new MImage(ctx, img, trxName); + + return img; + } + /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 20, 10); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20, 10); /** * Constructor @@ -102,6 +132,36 @@ public class MImage extends X_AD_Image initImageStoreDetails(ctx, trxName); } // MImage + /** + * + * @param copy + */ + public MImage(MImage copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MImage(Properties ctx, MImage copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MImage(Properties ctx, MImage copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } /** The Image */ private Image m_image = null; @@ -375,4 +435,14 @@ public class MImage extends X_AD_Image if (prov != null && prov.isPendingFlush()) prov.flush(this, provider); } + + @Override + public MImage markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MImage diff --git a/org.adempiere.base/src/org/compiere/model/MImportTemplate.java b/org.adempiere.base/src/org/compiere/model/MImportTemplate.java index ad17e78857..241d9ee68e 100644 --- a/org.adempiere.base/src/org/compiere/model/MImportTemplate.java +++ b/org.adempiere.base/src/org/compiere/model/MImportTemplate.java @@ -32,19 +32,20 @@ import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; +import org.idempiere.cache.ImmutablePOSupport; /** * Import Template Model * * @author Carlos Ruiz - GlobalQSS */ -public class MImportTemplate extends X_AD_ImportTemplate +public class MImportTemplate extends X_AD_ImportTemplate implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -1207697938690504067L; - + private static final long serialVersionUID = -4681075469110529774L; + /** Logger */ @SuppressWarnings("unused") private static CLogger s_log = CLogger.getCLogger(MImportTemplate.class); @@ -71,6 +72,37 @@ public class MImportTemplate extends X_AD_ImportTemplate super(ctx, rs, trxName); } // MImportTemplate + /** + * + * @param copy + */ + public MImportTemplate(MImportTemplate copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MImportTemplate(Properties ctx, MImportTemplate copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MImportTemplate(Properties ctx, MImportTemplate copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + @Override protected boolean beforeSave(boolean newRecord) { // Validate character set vs supported @@ -112,6 +144,8 @@ public class MImportTemplate extends X_AD_ImportTemplate .setParameters(Env.getAD_Client_ID(Env.getCtx()), tabid, roleid, roleid) .setOrderBy("Name") .list(); + if (retValue.size() > 0) + retValue.stream().forEach(e -> e.markImmutable()); s_cacheRoleTab.put(key, retValue); return retValue; } @@ -202,4 +236,13 @@ public class MImportTemplate extends X_AD_ImportTemplate return is; } + @Override + public MImportTemplate markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MImportTemplate diff --git a/org.adempiere.base/src/org/compiere/model/MInOutLine.java b/org.adempiere.base/src/org/compiere/model/MInOutLine.java index 3e45cea184..808c5f21d1 100644 --- a/org.adempiere.base/src/org/compiere/model/MInOutLine.java +++ b/org.adempiere.base/src/org/compiere/model/MInOutLine.java @@ -363,7 +363,7 @@ public class MInOutLine extends X_M_InOutLine public MProduct getProduct() { if (m_product == null && getM_Product_ID() != 0) - m_product = MProduct.get (getCtx(), getM_Product_ID()); + m_product = MProduct.getCopy(getCtx(), getM_Product_ID(), get_TrxName()); return m_product; } // getProduct diff --git a/org.adempiere.base/src/org/compiere/model/MInfoColumn.java b/org.adempiere.base/src/org/compiere/model/MInfoColumn.java index b49514eaba..376246ed58 100644 --- a/org.adempiere.base/src/org/compiere/model/MInfoColumn.java +++ b/org.adempiere.base/src/org/compiere/model/MInfoColumn.java @@ -224,9 +224,6 @@ public class MInfoColumn extends X_AD_InfoColumn implements IInfoColumn @Override public I_AD_Val_Rule getAD_Val_Rule() throws RuntimeException { - if (get_TrxName() != null) - return new MValRule(getCtx(), getAD_Val_Rule_ID(), get_TrxName()); - else - return MValRule.get(getCtx(), getAD_Val_Rule_ID()); + return MValRule.getCopy(getCtx(), getAD_Val_Rule_ID(), get_TrxName()); } } // MInfoColumn diff --git a/org.adempiere.base/src/org/compiere/model/MInterestArea.java b/org.adempiere.base/src/org/compiere/model/MInterestArea.java index c159ca99dc..9103e5e05c 100644 --- a/org.adempiere.base/src/org/compiere/model/MInterestArea.java +++ b/org.adempiere.base/src/org/compiere/model/MInterestArea.java @@ -23,9 +23,11 @@ import java.util.ArrayList; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Interest Area. @@ -35,14 +37,13 @@ import org.compiere.util.DB; * * @author Jorg Janke * @version $Id: MInterestArea.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $ - */ -public class MInterestArea extends X_R_InterestArea + */ +public class MInterestArea extends X_R_InterestArea implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -6910076559329764930L; - + private static final long serialVersionUID = -8171678779149295978L; /** * Get all active interest areas @@ -80,28 +81,40 @@ public class MInterestArea extends X_R_InterestArea return retValue; } // getAll + /** + * Get MInterestArea from Cache (immutable) + * @param R_InterestArea_ID id + * @return MInterestArea + */ + public static MInterestArea get (int R_InterestArea_ID) + { + return get(Env.getCtx(), R_InterestArea_ID); + } /** - * Get MInterestArea from Cache - * @param ctx context + * Get MInterestArea from Cache (immutable) + * @param ctx context * @param R_InterestArea_ID id * @return MInterestArea */ public static MInterestArea get (Properties ctx, int R_InterestArea_ID) { Integer key = Integer.valueOf(R_InterestArea_ID); - MInterestArea retValue = (MInterestArea) s_cache.get (key); + MInterestArea retValue = s_cache.get (ctx, key, e -> new MInterestArea(ctx, e)); if (retValue != null) return retValue; - retValue = new MInterestArea (ctx, R_InterestArea_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MInterestArea (Env.getCtx(), R_InterestArea_ID, (String)null); + if (retValue.get_ID () == R_InterestArea_ID) + { + s_cache.put (key, retValue, e -> new MInterestArea(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private static CCache s_cache = - new CCache(Table_Name, 5); + private static ImmutableIntPOCache s_cache = + new ImmutableIntPOCache(Table_Name, 5); /** Logger */ private static CLogger s_log = CLogger.getCLogger (MInterestArea.class); @@ -134,7 +147,40 @@ public class MInterestArea extends X_R_InterestArea super(ctx, rs, trxName); } // MInterestArea - + /** + * + * @param copy + */ + public MInterestArea(MInterestArea copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MInterestArea(Properties ctx, MInterestArea copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MInterestArea(Properties ctx, MInterestArea copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_AD_User_ID = copy.m_AD_User_ID; + this.m_ci = copy.m_ci != null ? new MContactInterest(ctx, copy.m_ci, trxName) : null; + } + + /** * Get Value * @return value @@ -228,4 +274,13 @@ public class MInterestArea extends X_R_InterestArea return m_ci.isSubscribed(); } // isSubscribed + @Override + public MInterestArea markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MInterestArea diff --git a/org.adempiere.base/src/org/compiere/model/MInventory.java b/org.adempiere.base/src/org/compiere/model/MInventory.java index 35cb14bbbb..9c0928dc3c 100644 --- a/org.adempiere.base/src/org/compiere/model/MInventory.java +++ b/org.adempiere.base/src/org/compiere/model/MInventory.java @@ -20,6 +20,7 @@ import java.io.File; import java.math.BigDecimal; import java.sql.ResultSet; import java.sql.Timestamp; +import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.logging.Level; @@ -28,7 +29,6 @@ import org.adempiere.exceptions.NegativeInventoryDisallowedException; import org.adempiere.exceptions.PeriodClosedException; import org.compiere.process.DocAction; import org.compiere.process.DocumentEngine; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; @@ -54,32 +54,36 @@ public class MInventory extends X_M_Inventory implements DocAction /** * */ - private static final long serialVersionUID = 4395759120481570701L; + private static final long serialVersionUID = 3877357565525655884L; + /** Reversal Indicator */ public static String REVERSE_INDICATOR = "^"; /** - * Get Inventory from Cache + * Get Inventory + * @param M_Inventory_ID id + * @return MInventory + */ + public static MInventory get (int M_Inventory_ID) + { + return get(Env.getCtx(), M_Inventory_ID); + } + + /** + * Get Inventory * @param ctx context * @param M_Inventory_ID id * @return MInventory */ public static MInventory get (Properties ctx, int M_Inventory_ID) { - Integer key = Integer.valueOf(M_Inventory_ID); - MInventory retValue = (MInventory) s_cache.get (key); - if (retValue != null) - return retValue; - retValue = new MInventory (ctx, M_Inventory_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + MInventory inventory = new MInventory(ctx, M_Inventory_ID, (String)null); + if (inventory.get_ID() == M_Inventory_ID) + return inventory; + else + return null; } // get - /** Cache */ - protected static CCache s_cache = new CCache(Table_Name, 5, 5); - - /** * Standard Constructor * @param ctx context @@ -136,7 +140,38 @@ public class MInventory extends X_M_Inventory implements DocAction setM_Warehouse_ID(wh.getM_Warehouse_ID()); } - + /** + * + * @param copy + */ + public MInventory(MInventory copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MInventory(Properties ctx, MInventory copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MInventory(Properties ctx, MInventory copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_lines = copy.m_lines != null ? Arrays.stream(copy.m_lines).map(e -> {var v = new MInventoryLine(ctx, e, trxName); v.setParent(this); return v;}).toArray(MInventoryLine[]::new) : null; + } + /** Lines */ protected MInventoryLine[] m_lines = null; @@ -205,7 +240,7 @@ public class MInventory extends X_M_Inventory implements DocAction */ public String getDocumentInfo() { - MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); + MDocType dt = MDocType.get(getC_DocType_ID()); StringBuilder msgreturn = new StringBuilder().append(dt.getNameTrl()).append(" ").append(getDocumentNo()); return msgreturn.toString(); } // getDocumentInfo @@ -353,7 +388,7 @@ public class MInventory extends X_M_Inventory implements DocAction if (product != null && product.isASIMandatory(line.isSOTrx())) { if (product.getAttributeSet() != null && !product.getAttributeSet().excludeTableEntry(MInventoryLine.Table_ID, line.isSOTrx())) { - MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); + MDocType dt = MDocType.get(getC_DocType_ID()); String docSubTypeInv = dt.getDocSubTypeInv(); BigDecimal qtyDiff = line.getQtyInternalUse(); if (MDocType.DOCSUBTYPEINV_PhysicalInventory.equals(docSubTypeInv)) @@ -417,7 +452,7 @@ public class MInventory extends X_M_Inventory implements DocAction */ public String completeIt() { - MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); + MDocType dt = MDocType.get(getC_DocType_ID()); String docSubTypeInv = dt.getDocSubTypeInv(); if (Util.isEmpty(docSubTypeInv)) { m_processMsg = "Document inventory subtype not configured, cannot complete"; @@ -665,7 +700,7 @@ public class MInventory extends X_M_Inventory implements DocAction * Set the definite document number after completed */ protected void setDefiniteDocumentNo() { - MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); + MDocType dt = MDocType.get(getC_DocType_ID()); if (dt.isOverwriteDateOnComplete()) { setMovementDate(TimeUtil.getDay(0)); MPeriod.testPeriodOpen(getCtx(), getMovementDate(), MDocType.DOCBASETYPE_MaterialPhysicalInventory, getAD_Org_ID()); @@ -958,7 +993,7 @@ public class MInventory extends X_M_Inventory implements DocAction reversalDate = new Timestamp(System.currentTimeMillis()); } - MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); + MDocType dt = MDocType.get(getC_DocType_ID()); MPeriod.testPeriodOpen(getCtx(), reversalDate, dt.getDocBaseType(), getAD_Org_ID()); // Deep Copy @@ -1151,5 +1186,5 @@ public class MInventory extends X_M_Inventory implements DocAction || DOCSTATUS_Closed.equals(ds) || DOCSTATUS_Reversed.equals(ds); } // isComplete - + } // MInventory diff --git a/org.adempiere.base/src/org/compiere/model/MInventoryLine.java b/org.adempiere.base/src/org/compiere/model/MInventoryLine.java index c6ae8f53c8..aa03ea1218 100644 --- a/org.adempiere.base/src/org/compiere/model/MInventoryLine.java +++ b/org.adempiere.base/src/org/compiere/model/MInventoryLine.java @@ -36,12 +36,12 @@ import org.compiere.util.Msg; *
  • BF [ 1817757 ] Error on saving MInventoryLine in a custom environment *
  • BF [ 1722982 ] Error with inventory when you enter count qty in negative */ -public class MInventoryLine extends X_M_InventoryLine +public class MInventoryLine extends X_M_InventoryLine { /** * */ - private static final long serialVersionUID = 7083622834698840042L; + private static final long serialVersionUID = 3973418005721380194L; /** * Get Inventory Line with parameters @@ -137,6 +137,39 @@ public class MInventoryLine extends X_M_InventoryLine this(inventory, M_Locator_ID, M_Product_ID, M_AttributeSetInstance_ID, QtyBook, QtyCount, null); } + /** + * + * @param copy + */ + public MInventoryLine(MInventoryLine copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MInventoryLine(Properties ctx, MInventoryLine copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MInventoryLine(Properties ctx, MInventoryLine copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_parent = null; + this.m_product = copy.m_product != null ? new MProduct(ctx, copy.m_product, trxName) : null; + } + /** Manually created */ //protected boolean m_isManualEntry = true; /** Parent */ @@ -156,7 +189,9 @@ public class MInventoryLine extends X_M_InventoryLine if (m_product != null && m_product.getM_Product_ID() != M_Product_ID) m_product = null; // reset if (m_product == null) - m_product = MProduct.get(getCtx(), M_Product_ID); + { + m_product = MProduct.getCopy(getCtx(), M_Product_ID, get_TrxName()); + } return m_product; } // getProduct @@ -461,4 +496,5 @@ public class MInventoryLine extends X_M_InventoryLine public boolean isSOTrx() { return getMovementQty().signum() < 0; } + } // MInventoryLine diff --git a/org.adempiere.base/src/org/compiere/model/MInvoice.java b/org.adempiere.base/src/org/compiere/model/MInvoice.java index 066a53edcb..375cfb9f1e 100644 --- a/org.adempiere.base/src/org/compiere/model/MInvoice.java +++ b/org.adempiere.base/src/org/compiere/model/MInvoice.java @@ -24,6 +24,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Arrays; import java.util.Hashtable; import java.util.List; import java.util.Properties; @@ -41,7 +42,6 @@ import org.compiere.process.DocAction; import org.compiere.process.DocumentEngine; import org.compiere.process.ProcessInfo; import org.compiere.process.ServerProcessCtl; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; @@ -69,7 +69,7 @@ public class MInvoice extends X_C_Invoice implements DocAction /** * */ - private static final long serialVersionUID = 5581441980246794522L; + private static final long serialVersionUID = -261338363319970683L; /** * Get Payments Of BPartner @@ -163,7 +163,7 @@ public class MInvoice extends X_C_Invoice implements DocAction if (counter) { to.setRef_Invoice_ID(from.getC_Invoice_ID()); - MOrg org = MOrg.get(from.getCtx(), from.getAD_Org_ID()); + MOrg org = MOrg.get(from.getAD_Org_ID()); int counterC_BPartner_ID = org.getLinkedC_BPartner_ID(trxName); if (counterC_BPartner_ID == 0) return null; @@ -239,29 +239,31 @@ public class MInvoice extends X_C_Invoice implements DocAction return sb.toString(); } // getPDFFileName - /** - * Get MInvoice from Cache - * @param ctx context + * Get MInvoice from db + * @param C_Invoice_ID id + * @return MInvoice + */ + public static MInvoice get (int C_Invoice_ID) + { + return get(Env.getCtx(), C_Invoice_ID); + } + + /** + * Get MInvoice from db * @param C_Invoice_ID id * @return MInvoice */ public static MInvoice get (Properties ctx, int C_Invoice_ID) { - Integer key = Integer.valueOf(C_Invoice_ID); - MInvoice retValue = (MInvoice) s_cache.get (key); - if (retValue != null) + MInvoice retValue = new MInvoice(ctx, C_Invoice_ID, (String)null); + if (retValue.get_ID () == C_Invoice_ID) + { return retValue; - retValue = new MInvoice (ctx, C_Invoice_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + } + return null; } // get - /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 20, 2); // 2 minutes - - /************************************************************************** * Invoice Constructor * @param ctx context @@ -327,7 +329,7 @@ public class MInvoice extends X_C_Invoice implements DocAction // if (C_DocTypeTarget_ID <= 0) { - MDocType odt = MDocType.get(order.getCtx(), order.getC_DocType_ID()); + MDocType odt = MDocType.get(order.getC_DocType_ID()); if (odt != null) { C_DocTypeTarget_ID = odt.getC_DocTypeInvoice_ID(); @@ -410,6 +412,40 @@ public class MInvoice extends X_C_Invoice implements DocAction setAD_User_ID(line.getAD_User_ID()); } // MInvoice + /** + * + * @param copy + */ + public MInvoice(MInvoice copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MInvoice(Properties ctx, MInvoice copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MInvoice(Properties ctx, MInvoice copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_openAmt = copy.m_openAmt; + this.m_lines = copy.m_lines != null ? Arrays.stream(copy.m_lines).map(e -> {var v = new MInvoiceLine(ctx, e, trxName); v.m_parent=this; return v;}).toArray(MInvoiceLine[]::new) : null; + this.m_taxes = copy.m_taxes != null ? Arrays.stream(copy.m_taxes).map(e -> {return new MInvoiceTax(ctx, e, trxName);}).toArray(MInvoiceTax[]::new) : null; + } + /** Open Amount */ private BigDecimal m_openAmt = null; @@ -559,7 +595,7 @@ public class MInvoice extends X_C_Invoice implements DocAction setPaymentRule(order.getPaymentRule()); setC_PaymentTerm_ID(order.getC_PaymentTerm_ID()); // - MDocType dt = MDocType.get(getCtx(), order.getC_DocType_ID()); + MDocType dt = MDocType.get(order.getC_DocType_ID()); if (dt.getC_DocTypeInvoice_ID() != 0) setC_DocTypeTarget_ID(dt.getC_DocTypeInvoice_ID()); // Overwrite Invoice BPartner @@ -577,7 +613,7 @@ public class MInvoice extends X_C_Invoice implements DocAction MRMA rma = new MRMA(getCtx(), ship.getM_RMA_ID(), get_TrxName()); // Retrieves the invoice DocType - MDocType dt = MDocType.get(getCtx(), rma.getC_DocType_ID()); + MDocType dt = MDocType.get(rma.getC_DocType_ID()); if (dt.getC_DocTypeInvoice_ID() != 0) { setC_DocTypeTarget_ID(dt.getC_DocTypeInvoice_ID()); @@ -682,7 +718,7 @@ public class MInvoice extends X_C_Invoice implements DocAction List list = new Query(getCtx(), I_C_InvoiceLine.Table_Name, whereClauseFinal, get_TrxName()) .setParameters(getC_Invoice_ID()) .setOrderBy("Line, C_InvoiceLine_ID") - .list(); + .list(); return list.toArray(new MInvoiceLine[list.size()]); } // getLines @@ -694,7 +730,9 @@ public class MInvoice extends X_C_Invoice implements DocAction public MInvoiceLine[] getLines (boolean requery) { if (m_lines == null || m_lines.length == 0 || requery) + { m_lines = getLines(null); + } set_TrxName(m_lines, get_TrxName()); return m_lines; } // getLines @@ -873,8 +911,7 @@ public class MInvoice extends X_C_Invoice implements DocAction */ public boolean isCreditMemo() { - MDocType dt = MDocType.get(getCtx(), - getC_DocType_ID()==0 ? getC_DocTypeTarget_ID() : getC_DocType_ID()); + MDocType dt = MDocType.get(getC_DocType_ID()==0 ? getC_DocTypeTarget_ID() : getC_DocType_ID()); return MDocType.DOCBASETYPE_APCreditMemo.equals(dt.getDocBaseType()) || MDocType.DOCBASETYPE_ARCreditMemo.equals(dt.getDocBaseType()); } // isCreditMemo @@ -2236,7 +2273,7 @@ public class MInvoice extends X_C_Invoice implements DocAction private void setDefiniteDocumentNo() { if (isReversal() && ! MSysConfig.getBooleanValue(MSysConfig.Invoice_ReverseUseNewNumber, true, getAD_Client_ID())) // IDEMPIERE-1771 return; - MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); + MDocType dt = MDocType.get(getC_DocType_ID()); if (dt.isOverwriteDateOnComplete()) { setDateInvoiced(TimeUtil.getDay(0)); if (getDateAcct().before(getDateInvoiced())) { @@ -2262,7 +2299,7 @@ public class MInvoice extends X_C_Invoice implements DocAction return null; // Org Must be linked to BPartner - MOrg org = MOrg.get(getCtx(), getAD_Org_ID()); + MOrg org = MOrg.get(getAD_Org_ID()); int counterC_BPartner_ID = org.getLinkedC_BPartner_ID(get_TrxName()); if (counterC_BPartner_ID == 0) return null; diff --git a/org.adempiere.base/src/org/compiere/model/MInvoiceLine.java b/org.adempiere.base/src/org/compiere/model/MInvoiceLine.java index 8f304810b6..7459ff6f5a 100644 --- a/org.adempiere.base/src/org/compiere/model/MInvoiceLine.java +++ b/org.adempiere.base/src/org/compiere/model/MInvoiceLine.java @@ -162,6 +162,49 @@ public class MInvoiceLine extends X_C_InvoiceLine super(ctx, rs, trxName); } // MInvoiceLine + /** + * + * @param copy + */ + public MInvoiceLine(MInvoiceLine copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MInvoiceLine(Properties ctx, MInvoiceLine copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MInvoiceLine(Properties ctx, MInvoiceLine copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_tax = copy.m_tax != null ? new MTax(ctx, copy.m_tax, trxName) : null; + this.m_M_PriceList_ID = copy.m_M_PriceList_ID; + this.m_DateInvoiced = copy.m_DateInvoiced; + this.m_C_BPartner_ID = copy.m_C_BPartner_ID; + this.m_C_BPartner_Location_ID = copy.m_C_BPartner_Location_ID; + this.m_IsSOTrx = copy.m_IsSOTrx; + this.m_product = copy.m_product != null ? new MProduct(ctx, copy.m_product, trxName) : null; + this.m_charge = copy.m_charge != null ? new MCharge(ctx, copy.m_charge, trxName) : null; + this.m_name = copy.m_name; + this.m_precision = copy.m_precision; + this.m_parent = null; + this.m_priceSet = copy.m_priceSet; + } + protected int m_M_PriceList_ID = 0; protected Timestamp m_DateInvoiced = null; protected int m_C_BPartner_ID = 0; @@ -489,17 +532,17 @@ public class MInvoiceLine extends X_C_InvoiceLine public MCharge getCharge() { if (m_charge == null && getC_Charge_ID() != 0) - m_charge = MCharge.get (getCtx(), getC_Charge_ID()); + m_charge = MCharge.getCopy(getCtx(), getC_Charge_ID(), get_TrxName()); return m_charge; } /** - * Get Tax + * Get Tax (immutable) * @return tax */ protected MTax getTax() { if (m_tax == null) - m_tax = MTax.get(getCtx(), getC_Tax_ID()); + m_tax = MTax.get(getCtx(), getC_Tax_ID()); return m_tax; } // getTax @@ -605,7 +648,7 @@ public class MInvoiceLine extends X_C_InvoiceLine public MProduct getProduct() { if (m_product == null && getM_Product_ID() != 0) - m_product = MProduct.get (getCtx(), getM_Product_ID()); + m_product = MProduct.getCopy(getCtx(), getM_Product_ID(), get_TrxName()); return m_product; } // getProduct diff --git a/org.adempiere.base/src/org/compiere/model/MInvoiceSchedule.java b/org.adempiere.base/src/org/compiere/model/MInvoiceSchedule.java index 383b1fef46..7e4125346b 100644 --- a/org.adempiere.base/src/org/compiere/model/MInvoiceSchedule.java +++ b/org.adempiere.base/src/org/compiere/model/MInvoiceSchedule.java @@ -23,8 +23,10 @@ import java.util.Calendar; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; +import org.compiere.util.Env; import org.compiere.util.TimeUtil; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Invoice Schedule Model @@ -32,17 +34,37 @@ import org.compiere.util.TimeUtil; * @author Jorg Janke * @version $Id: MInvoiceSchedule.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $ */ -public class MInvoiceSchedule extends X_C_InvoiceSchedule +public class MInvoiceSchedule extends X_C_InvoiceSchedule implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -1750020695983938895L; - + private static final long serialVersionUID = -2480759794244343907L; /** - * Get MInvoiceSchedule from Cache - * @param ctx context + * Get MInvoiceSchedule (Immutable) from Cache + * @param C_InvoiceSchedule_ID id + * @param trxName transaction + * @return MInvoiceSchedule + */ + public static MInvoiceSchedule get (int C_InvoiceSchedule_ID, String trxName) + { + return get(Env.getCtx(), C_InvoiceSchedule_ID, trxName); + } + + /** + * Get MInvoiceSchedule (Immutable) from Cache + * @param C_InvoiceSchedule_ID id + * @return MInvoiceSchedule + */ + public static MInvoiceSchedule get (int C_InvoiceSchedule_ID) + { + return get(C_InvoiceSchedule_ID, (String)null); + } + + /** + * Get MInvoiceSchedule (Immutable) from Cache + * @param ctx context * @param C_InvoiceSchedule_ID id * @param trxName transaction * @return MInvoiceSchedule @@ -50,17 +72,20 @@ public class MInvoiceSchedule extends X_C_InvoiceSchedule public static MInvoiceSchedule get (Properties ctx, int C_InvoiceSchedule_ID, String trxName) { Integer key = Integer.valueOf(C_InvoiceSchedule_ID); - MInvoiceSchedule retValue = (MInvoiceSchedule) s_cache.get (key); + MInvoiceSchedule retValue = (MInvoiceSchedule) s_cache.get (ctx, key, e -> new MInvoiceSchedule(ctx, e)); if (retValue != null) return retValue; - retValue = new MInvoiceSchedule (ctx, C_InvoiceSchedule_ID, trxName); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MInvoiceSchedule (Env.getCtx(), C_InvoiceSchedule_ID, trxName); + if (retValue.get_ID () == C_InvoiceSchedule_ID) + { + s_cache.put (key, retValue, e -> new MInvoiceSchedule(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 5); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 5); /************************************************************************** @@ -85,6 +110,37 @@ public class MInvoiceSchedule extends X_C_InvoiceSchedule super(ctx, rs, trxName); } // MInvoiceSchedule + /** + * + * @param copy + */ + public MInvoiceSchedule(MInvoiceSchedule copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MInvoiceSchedule(Properties ctx, MInvoiceSchedule copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MInvoiceSchedule(Properties ctx, MInvoiceSchedule copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Can I send Invoice * @param xDate date @@ -219,5 +275,14 @@ public class MInvoiceSchedule extends X_C_InvoiceSchedule // if (INVOICEWEEKDAY_Thursday.equals(day)) return Calendar.THURSDAY; } // getCalendarDay - + + @Override + public MInvoiceSchedule markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MInvoiceSchedule diff --git a/org.adempiere.base/src/org/compiere/model/MInvoiceTax.java b/org.adempiere.base/src/org/compiere/model/MInvoiceTax.java index 8256ba56ca..76f68da2c8 100644 --- a/org.adempiere.base/src/org/compiere/model/MInvoiceTax.java +++ b/org.adempiere.base/src/org/compiere/model/MInvoiceTax.java @@ -136,6 +136,39 @@ public class MInvoiceTax extends X_C_InvoiceTax super(ctx, rs, trxName); } // MInvoiceTax + /** + * + * @param copy + */ + public MInvoiceTax(MInvoiceTax copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MInvoiceTax(Properties ctx, MInvoiceTax copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MInvoiceTax(Properties ctx, MInvoiceTax copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_precision = copy.m_precision; + this.m_tax = copy.m_tax != null ? new MTax(ctx, copy.m_tax, trxName) : null; + } + /** Tax */ private MTax m_tax = null; /** Cached Precision */ @@ -163,7 +196,7 @@ public class MInvoiceTax extends X_C_InvoiceTax } // setPrecision /** - * Get Tax + * Get Tax (immutable) * @return tax */ protected MTax getTax() @@ -257,5 +290,4 @@ public class MInvoiceTax extends X_C_InvoiceTax .append ("]"); return sb.toString (); } // toString - } // MInvoiceTax diff --git a/org.adempiere.base/src/org/compiere/model/MLocation.java b/org.adempiere.base/src/org/compiere/model/MLocation.java index e840425bb1..0928149c27 100644 --- a/org.adempiere.base/src/org/compiere/model/MLocation.java +++ b/org.adempiere.base/src/org/compiere/model/MLocation.java @@ -23,13 +23,14 @@ import java.util.Comparator; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.Trx; import org.compiere.util.Util; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Location (Address) @@ -45,12 +46,13 @@ import org.compiere.util.Util; *
  • BF [ 3002736 ] MLocation.get cache all MLocations * https://sourceforge.net/tracker/?func=detail&aid=3002736&group_id=176962&atid=879332 */ -public class MLocation extends X_C_Location implements Comparator +public class MLocation extends X_C_Location implements Comparator, ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -4100591609253985073L; + private static final long serialVersionUID = -3421958100626539835L; + // http://jira.idempiere.com/browse/IDEMPIERE-147 public static String LOCATION_MAPS_URL_PREFIX = MSysConfig.getValue(MSysConfig.LOCATION_MAPS_URL_PREFIX); public static String LOCATION_MAPS_ROUTE_PREFIX = MSysConfig.getValue(MSysConfig.LOCATION_MAPS_ROUTE_PREFIX); @@ -59,7 +61,28 @@ public class MLocation extends X_C_Location implements Comparator /** * Get Location from Cache - * @param ctx context + * @param C_Location_ID id + * @param trxName transaction + * @return MLocation + */ + public static MLocation get (int C_Location_ID, String trxName) + { + return get(Env.getCtx(), C_Location_ID, trxName); + } + + /** + * Get Location from Cache (immutable) + * @param C_Location_ID id + * @return MLocation + */ + public static MLocation get (int C_Location_ID) + { + return get(C_Location_ID, (String)null); + } + + /** + * Get Location from Cache (immutable) + * @param ctx context * @param C_Location_ID id * @param trxName transaction * @return MLocation @@ -68,24 +91,36 @@ public class MLocation extends X_C_Location implements Comparator { // New if (C_Location_ID == 0) - return new MLocation(ctx, C_Location_ID, trxName); + return new MLocation(Env.getCtx(), C_Location_ID, trxName); // Integer key = Integer.valueOf(C_Location_ID); - MLocation retValue = null; - if (trxName == null) - retValue = (MLocation) s_cache.get (key); + MLocation retValue = s_cache.get (ctx, key, e -> new MLocation(ctx, e)); if (retValue != null) return retValue; retValue = new MLocation (ctx, C_Location_ID, trxName); - if (retValue.get_ID () != 0) // found + if (retValue.get_ID () == C_Location_ID) // found { - if (trxName == null) - s_cache.put (key, retValue); + s_cache.put (key, retValue, e -> new MLocation(Env.getCtx(), e)); return retValue; } return null; // not found } // get + /** + * Get updateable copy of MLocation from cache + * @param ctx context + * @param C_Location_ID + * @param trxName + * @return MLocation + */ + public static MLocation getCopy(Properties ctx, int C_Location_ID, String trxName) + { + MLocation loc = get(C_Location_ID, trxName); + if (loc != null && loc.getC_Location_ID() > 0) + loc = new MLocation(ctx, loc, trxName); + return loc; + } + /** * Load Location with ID if Business Partner Location * @param ctx context @@ -126,7 +161,7 @@ public class MLocation extends X_C_Location implements Comparator } // getBPLocation /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 100, 30); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 100, 30); /** Static Logger */ private static CLogger s_log = CLogger.getCLogger(MLocation.class); @@ -142,9 +177,9 @@ public class MLocation extends X_C_Location implements Comparator super (ctx, C_Location_ID, trxName); if (C_Location_ID == 0) { - MCountry defaultCountry = MCountry.getDefault(getCtx()); + MCountry defaultCountry = MCountry.getDefault(); setCountry(defaultCountry); - MRegion defaultRegion = MRegion.getDefault(getCtx()); + MRegion defaultRegion = MRegion.getDefault(); if (defaultRegion != null && defaultRegion.getC_Country_ID() == defaultCountry.getC_Country_ID()) setRegion(defaultRegion); @@ -190,6 +225,39 @@ public class MLocation extends X_C_Location implements Comparator super(ctx, rs, trxName); } // MLocation + /** + * + * @param copy + */ + public MLocation(MLocation copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MLocation(Properties ctx, MLocation copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MLocation(Properties ctx, MLocation copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_c = copy.m_c != null ? new MCountry(ctx, copy.m_c, trxName) : null; + this.m_r = copy.m_r != null ? new MRegion(ctx, copy.m_r, trxName) : null; + } + private MCountry m_c = null; private MRegion m_r = null; @@ -202,7 +270,7 @@ public class MLocation extends X_C_Location implements Comparator if (country != null) m_c = country; else - m_c = MCountry.getDefault(getCtx()); + m_c = MCountry.getDefault(); super.setC_Country_ID (m_c.getC_Country_ID()); } // setCountry @@ -214,11 +282,11 @@ public class MLocation extends X_C_Location implements Comparator { if (getC_Country_ID() != C_Country_ID) setRegion(null); - setCountry (MCountry.get(getCtx(), C_Country_ID)); + setCountry (MCountry.get(C_Country_ID)); } // setCountry /** - * Get Country + * Get Country (immutable) * @return country */ public MCountry getCountry() @@ -230,9 +298,9 @@ public class MLocation extends X_C_Location implements Comparator if (m_c == null) { if (getC_Country_ID() != 0) - m_c = MCountry.get(getCtx(), getC_Country_ID()); + m_c = MCountry.get(getC_Country_ID()); else - m_c = MCountry.getDefault(getCtx()); + m_c = MCountry.getDefault(); } return m_c; } // getCountry @@ -254,7 +322,7 @@ public class MLocation extends X_C_Location implements Comparator public String getCountry (boolean local) { if (local - && getC_Country_ID() == MCountry.getDefault(getCtx()).getC_Country_ID()) + && getC_Country_ID() == MCountry.getDefault().getC_Country_ID()) return null; return getCountryName(); } // getCountry @@ -266,7 +334,7 @@ public class MLocation extends X_C_Location implements Comparator public String getCountry (boolean local, String language) { if (local - && getC_Country_ID() == MCountry.getDefault(getCtx()).getC_Country_ID()) + && getC_Country_ID() == MCountry.getDefault().getC_Country_ID()) return null; MCountry mc = getCountry(); return mc.getTrlName(language); @@ -316,7 +384,7 @@ public class MLocation extends X_C_Location implements Comparator setRegion(null); } else - setRegion (MRegion.get(getCtx(), C_Region_ID)); + setRegion (MRegion.get(C_Region_ID)); } // setC_Region_ID /** @@ -330,7 +398,7 @@ public class MLocation extends X_C_Location implements Comparator m_r = null; // if (m_r == null && getC_Region_ID() != 0) - m_r = MRegion.get(getCtx(), getC_Region_ID()); + m_r = MRegion.get(getC_Region_ID()); return m_r; } // getRegion @@ -438,7 +506,7 @@ public class MLocation extends X_C_Location implements Comparator public boolean isAddressLinesReverse() { // Local - if (MCountry.getDefault(getCtx()) != null && getC_Country_ID() == MCountry.getDefault(getCtx()).getC_Country_ID()) + if (MCountry.getDefault() != null && getC_Country_ID() == MCountry.getDefault().getC_Country_ID()) return getCountry().isAddressLinesLocalReverse(); return getCountry().isAddressLinesReverse(); } // isAddressLinesReverse @@ -464,7 +532,7 @@ public class MLocation extends X_C_Location implements Comparator if (c == null) return "CountryNotFound"; - boolean local = MCountry.getDefault(getCtx()) != null && getC_Country_ID() == MCountry.getDefault(getCtx()).getC_Country_ID(); + boolean local = MCountry.getDefault() != null && getC_Country_ID() == MCountry.getDefault().getC_Country_ID(); String inStr = local ? c.getDisplaySequenceLocal() : c.getDisplaySequence(); StringBuilder outStr = new StringBuilder(); @@ -821,6 +889,15 @@ public class MLocation extends X_C_Location implements Comparator return ok; } + @Override + public MLocation markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + /** * Create address transaction instance * @param ctx diff --git a/org.adempiere.base/src/org/compiere/model/MLocationLookup.java b/org.adempiere.base/src/org/compiere/model/MLocationLookup.java index fb50ff7282..6bf9648f9a 100644 --- a/org.adempiere.base/src/org/compiere/model/MLocationLookup.java +++ b/org.adempiere.base/src/org/compiere/model/MLocationLookup.java @@ -127,7 +127,7 @@ public final class MLocationLookup extends Lookup */ public MLocation getLocation (int C_Location_ID, String trxName) { - return MLocation.get(m_ctx, C_Location_ID, trxName); + return MLocation.getCopy(m_ctx, C_Location_ID, trxName); } // getC_Location_ID /** diff --git a/org.adempiere.base/src/org/compiere/model/MLocator.java b/org.adempiere.base/src/org/compiere/model/MLocator.java index 4f5b8f50c5..1ed2d654ff 100644 --- a/org.adempiere.base/src/org/compiere/model/MLocator.java +++ b/org.adempiere.base/src/org/compiere/model/MLocator.java @@ -22,9 +22,11 @@ import java.sql.SQLException; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Warehouse Locator Object @@ -34,12 +36,12 @@ import org.compiere.util.DB; * @see [ 1966333 ] New Method to get the Default Locator based in Warehouse http://sourceforge.net/tracker/index.php?func=detail&aid=1966333&group_id=176962&atid=879335 * @version $Id: MLocator.java,v 1.3 2006/07/30 00:58:37 jjanke Exp $ */ -public class MLocator extends X_M_Locator +public class MLocator extends X_M_Locator implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -4502919527066173270L; + private static final long serialVersionUID = 539879105479299988L; /** * Get oldest Default Locator of warehouse with locator @@ -168,30 +170,56 @@ public class MLocator extends X_M_Locator retValue.saveEx(); } return retValue; - } // get + } // get /** - * Get Locator from Cache - * @param ctx context + * Get Locator from Cache (immutable) + * @param M_Locator_ID id + * @return MLocator + */ + public static MLocator get (int M_Locator_ID) + { + return get(Env.getCtx(), M_Locator_ID); + } + + /** + * Get Locator from Cache (immutable) + * @param ctx context * @param M_Locator_ID id * @return MLocator */ public static MLocator get (Properties ctx, int M_Locator_ID) { - if (s_cache == null) - s_cache = new CCache(Table_Name, 20); Integer key = Integer.valueOf(M_Locator_ID); - MLocator retValue = (MLocator) s_cache.get (key); + MLocator retValue = s_cache.get (ctx, key, e -> new MLocator(ctx, e)); if (retValue != null) return retValue; - retValue = new MLocator (ctx, M_Locator_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MLocator (ctx, M_Locator_ID, (String)null); + if (retValue.get_ID () == M_Locator_ID) + { + s_cache.put (key, retValue, e -> new MLocator(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MLocator from cache + * @param ctx + * @param M_Locator_ID + * @param trxName + * @return MLocator + */ + public static MLocator getCopy(Properties ctx, int M_Locator_ID, String trxName) + { + MLocator locator = get(M_Locator_ID); + if (locator != null) + locator = new MLocator(ctx, locator, trxName); + return locator; + } + /** Cache */ - protected volatile static CCache s_cache; + private final static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** Logger */ private static CLogger s_log = CLogger.getCLogger (MLocator.class); @@ -244,6 +272,37 @@ public class MLocator extends X_M_Locator super(ctx, rs, trxName); } // MLocator + /** + * + * @param copy + */ + public MLocator(MLocator copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MLocator(Properties ctx, MLocator copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MLocator(Properties ctx, MLocator copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Get String Representation * @return Value @@ -358,4 +417,13 @@ public class MLocator extends X_M_Locator */ } // isCanStoreProduct + @Override + public MLocator markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MLocator diff --git a/org.adempiere.base/src/org/compiere/model/MLocatorLookup.java b/org.adempiere.base/src/org/compiere/model/MLocatorLookup.java index 49062d84d6..3a3a93f3f0 100644 --- a/org.adempiere.base/src/org/compiere/model/MLocatorLookup.java +++ b/org.adempiere.base/src/org/compiere/model/MLocatorLookup.java @@ -272,7 +272,7 @@ public final class MLocatorLookup extends Lookup implements Serializable return null; } // - return Util.isEmpty(trxName) ? MLocator.get(m_ctx, M_Locator_ID) : new MLocator (m_ctx, M_Locator_ID, trxName); + return MLocator.getCopy(m_ctx, M_Locator_ID, trxName); } // getMLocator /** diff --git a/org.adempiere.base/src/org/compiere/model/MLocatorType.java b/org.adempiere.base/src/org/compiere/model/MLocatorType.java index 3ec2e27e84..f9c4df4191 100644 --- a/org.adempiere.base/src/org/compiere/model/MLocatorType.java +++ b/org.adempiere.base/src/org/compiere/model/MLocatorType.java @@ -27,41 +27,52 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.CLogger; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Warehouse Locator Type Object * * @author Carlos Ruiz - Quality Systems & Solutions - globalqss */ -public class MLocatorType extends X_M_LocatorType { +public class MLocatorType extends X_M_LocatorType implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -7567584133468332781L; + private static final long serialVersionUID = 3021833597380696668L; /** - * Get Locator Type from Cache - * @param ctx context + * Get Locator Type from Cache (immutable) + * @param M_LocatorType_ID id + * @return MLocator + */ + public static MLocatorType get (int M_LocatorType_ID) { + return get(Env.getCtx(), M_LocatorType_ID); + } + + /** + * Get Locator Type from Cache (immutable) + * @param ctx context * @param M_LocatorType_ID id * @return MLocator */ public static MLocatorType get (Properties ctx, int M_LocatorType_ID) { - if (s_cache == null) - s_cache = new CCache(Table_Name, 20); Integer key = Integer.valueOf(M_LocatorType_ID); - MLocatorType retValue = (MLocatorType) s_cache.get (key); + MLocatorType retValue = s_cache.get (ctx, key, e -> new MLocatorType(ctx, e)); if (retValue != null) return retValue; - retValue = new MLocatorType (ctx, M_LocatorType_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MLocatorType (ctx, M_LocatorType_ID, (String)null); + if (retValue.get_ID () == M_LocatorType_ID) { + s_cache.put (key, retValue, e -> new MLocatorType(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private volatile static CCache s_cache; + private final static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** Logger */ @SuppressWarnings("unused") @@ -92,6 +103,34 @@ public class MLocatorType extends X_M_LocatorType { super(ctx, rs, trxName); } // MLocatorType + /** + * + * @param copy + */ + public MLocatorType(MLocatorType copy) { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MLocatorType(Properties ctx, MLocatorType copy) { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MLocatorType(Properties ctx, MLocatorType copy, String trxName) { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Get String Representation * @return Name @@ -100,4 +139,13 @@ public class MLocatorType extends X_M_LocatorType { return getName(); } // toString + @Override + public MLocatorType markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MLocatorType diff --git a/org.adempiere.base/src/org/compiere/model/MLotCtlExclude.java b/org.adempiere.base/src/org/compiere/model/MLotCtlExclude.java new file mode 100644 index 0000000000..3545dcede4 --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/MLotCtlExclude.java @@ -0,0 +1,89 @@ +/********************************************************************** +* 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: * +* - Trek Global Corporation * +* - Heng Sin Low * +**********************************************************************/ +package org.compiere.model; + +import java.sql.ResultSet; +import java.util.Properties; + +import org.compiere.util.Env; + +/** + * @author hengsin + * + */ +public class MLotCtlExclude extends X_M_LotCtlExclude { + + /** + * + */ + private static final long serialVersionUID = -7189245472896373850L; + + /** + * @param ctx + * @param M_LotCtlExclude_ID + * @param trxName + */ + public MLotCtlExclude(Properties ctx, int M_LotCtlExclude_ID, String trxName) { + super(ctx, M_LotCtlExclude_ID, trxName); + } + + /** + * @param ctx + * @param rs + * @param trxName + */ + public MLotCtlExclude(Properties ctx, ResultSet rs, String trxName) { + super(ctx, rs, trxName); + } + + /** + * + * @param copy + */ + public MLotCtlExclude(MLotCtlExclude copy) { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MLotCtlExclude(Properties ctx, MLotCtlExclude copy) { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MLotCtlExclude(Properties ctx, MLotCtlExclude copy, String trxName) { + this(ctx, 0, trxName); + copyPO(copy); + } +} diff --git a/org.adempiere.base/src/org/compiere/model/MMeasure.java b/org.adempiere.base/src/org/compiere/model/MMeasure.java index f81cc7b5fa..854b32805b 100644 --- a/org.adempiere.base/src/org/compiere/model/MMeasure.java +++ b/org.adempiere.base/src/org/compiere/model/MMeasure.java @@ -30,12 +30,13 @@ import javax.script.ScriptEngine; import org.adempiere.apps.graph.GraphColumn; import org.adempiere.exceptions.AdempiereException; import org.adempiere.util.MeasureInterface; -import org.compiere.util.CCache; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.TimeUtil; import org.compiere.util.Util; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** @@ -50,34 +51,47 @@ import org.compiere.util.Util; *
  • FR [ 2905227 ] Calculate Measure based on the script to PA *
  • https://sourceforge.net/tracker/?func=detail&aid=2905227&group_id=176962&atid=879335 */ -public class MMeasure extends X_PA_Measure +public class MMeasure extends X_PA_Measure implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 6274990637485210675L; + private static final long serialVersionUID = -3584012092877837973L; /** - * Get MMeasure from Cache - * @param ctx context + * Get MMeasure from Cache (immutable) + * @param PA_Measure_ID id + * @return MMeasure + */ + public static MMeasure get (int PA_Measure_ID) + { + return get(Env.getCtx(), PA_Measure_ID); + } + + /** + * Get MMeasure from Cache (immutable) + * @param ctx context * @param PA_Measure_ID id * @return MMeasure */ public static MMeasure get (Properties ctx, int PA_Measure_ID) { Integer key = Integer.valueOf(PA_Measure_ID); - MMeasure retValue = (MMeasure)s_cache.get (key); + MMeasure retValue = s_cache.get (ctx, key, e -> new MMeasure(ctx, e)); if (retValue != null) return retValue; - retValue = new MMeasure (ctx, PA_Measure_ID, null); - if (retValue.get_ID() != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MMeasure (ctx, PA_Measure_ID, (String)null); + if (retValue.get_ID() == PA_Measure_ID) + { + s_cache.put (key, retValue, e -> new MMeasure(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private static CCache s_cache - = new CCache (Table_Name, 10); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache (Table_Name, 10); /** * Standard Constructor @@ -101,12 +115,43 @@ public class MMeasure extends X_PA_Measure super (ctx, rs, trxName); } // MMeasure + /** + * + * @param copy + */ + public MMeasure(MMeasure copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MMeasure(Properties ctx, MMeasure copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MMeasure(Properties ctx, MMeasure copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + public ArrayList getGraphColumnList(MGoal goal) { ArrayList list = new ArrayList(); if (MMeasure.MEASURETYPE_Calculated.equals(getMeasureType())) { - MMeasureCalc mc = MMeasureCalc.get(getCtx(), getPA_MeasureCalc_ID()); + MMeasureCalc mc = MMeasureCalc.get(getPA_MeasureCalc_ID()); String sql = mc.getSqlBarChart(goal.getRestrictions(false), goal.getMeasureDisplay(), goal.getDateFrom(), MRole.getDefault()); // logged in role @@ -465,7 +510,7 @@ public class MMeasure extends X_PA_Measure if (role == null) role = MRole.getDefault(getCtx(), false); // could result in wrong data // - MMeasureCalc mc = MMeasureCalc.get(getCtx(), getPA_MeasureCalc_ID()); + MMeasureCalc mc = MMeasureCalc.get(getPA_MeasureCalc_ID()); if (mc == null || mc.get_ID() == 0 || mc.get_ID() != getPA_MeasureCalc_ID()) { log.log(Level.SEVERE, "Not found PA_MeasureCalc_ID=" + getPA_MeasureCalc_ID()); @@ -669,4 +714,14 @@ public class MMeasure extends X_PA_Measure } return true; } // updateUserDefinedGoals + + @Override + public MMeasure markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MMeasure diff --git a/org.adempiere.base/src/org/compiere/model/MMeasureCalc.java b/org.adempiere.base/src/org/compiere/model/MMeasureCalc.java index b4a69ecac9..6296c22b67 100644 --- a/org.adempiere.base/src/org/compiere/model/MMeasureCalc.java +++ b/org.adempiere.base/src/org/compiere/model/MMeasureCalc.java @@ -23,9 +23,10 @@ import java.util.ArrayList; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Performance Measure Calculation @@ -33,34 +34,47 @@ import org.compiere.util.Env; * @author Jorg Janke * @version $Id: MMeasureCalc.java,v 1.4 2006/09/25 00:59:41 jjanke Exp $ */ -public class MMeasureCalc extends X_PA_MeasureCalc +public class MMeasureCalc extends X_PA_MeasureCalc implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 4720674127987683534L; + private static final long serialVersionUID = 3143013490477454559L; /** - * Get MMeasureCalc from Cache - * @param ctx context + * Get MMeasureCalc from Cache (immutable) + * @param PA_MeasureCalc_ID id + * @return MMeasureCalc + */ + public static MMeasureCalc get (int PA_MeasureCalc_ID) + { + return get(Env.getCtx(), PA_MeasureCalc_ID); + } + + /** + * Get MMeasureCalc from Cache (immutable) + * @param ctx context * @param PA_MeasureCalc_ID id * @return MMeasureCalc */ public static MMeasureCalc get (Properties ctx, int PA_MeasureCalc_ID) { Integer key = Integer.valueOf(PA_MeasureCalc_ID); - MMeasureCalc retValue = (MMeasureCalc)s_cache.get (key); + MMeasureCalc retValue = s_cache.get (ctx, key, e -> new MMeasureCalc(ctx, e)); if (retValue != null) return retValue; - retValue = new MMeasureCalc (ctx, PA_MeasureCalc_ID, null); - if (retValue.get_ID() != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MMeasureCalc (ctx, PA_MeasureCalc_ID, (String)null); + if (retValue.get_ID() == PA_MeasureCalc_ID) + { + s_cache.put (key, retValue, e -> new MMeasureCalc(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private static CCache s_cache - = new CCache (Table_Name, 10); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache (Table_Name, 10); /************************************************************************** * Standard Constructor @@ -84,6 +98,36 @@ public class MMeasureCalc extends X_PA_MeasureCalc super (ctx, rs, trxName); } // MMeasureCalc + /** + * + * @param copy + */ + public MMeasureCalc(MMeasureCalc copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MMeasureCalc(Properties ctx, MMeasureCalc copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MMeasureCalc(Properties ctx, MMeasureCalc copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } /** * Get Sql to return single value for the Performance Indicator @@ -465,5 +509,13 @@ public class MMeasureCalc extends X_PA_MeasureCalc return sb.toString (); } // toString - + @Override + public MMeasureCalc markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MMeasureCalc diff --git a/org.adempiere.base/src/org/compiere/model/MMessage.java b/org.adempiere.base/src/org/compiere/model/MMessage.java index 057e085cf6..13984a0124 100644 --- a/org.adempiere.base/src/org/compiere/model/MMessage.java +++ b/org.adempiere.base/src/org/compiere/model/MMessage.java @@ -21,9 +21,11 @@ import java.sql.ResultSet; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.ImmutablePOCache; /** * Message Model @@ -31,16 +33,26 @@ import org.compiere.util.DB; * @author Jorg Janke * @version $Id: MMessage.java,v 1.3 2006/07/30 00:54:54 jjanke Exp $ */ -public class MMessage extends X_AD_Message +public class MMessage extends X_AD_Message implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -7362947218094337783L; + private static final long serialVersionUID = -7983736322524189608L; /** - * Get Message (cached) - * @param ctx context + * Get Message (cached) (immutable) + * @param Value message value + * @return message + */ + public static MMessage get (String Value) + { + return get(Env.getCtx(), Value); + } + + /** + * Get Message (cached) (immutable) + * @param ctx context * @param Value message value * @return message */ @@ -48,7 +60,7 @@ public class MMessage extends X_AD_Message { if (Value == null || Value.length() == 0) return null; - MMessage retValue = (MMessage)s_cache.get(Value); + MMessage retValue = (MMessage)s_cache.get(ctx, Value, e -> new MMessage(ctx, e)); // if (retValue == null) { @@ -61,7 +73,7 @@ public class MMessage extends X_AD_Message pstmt.setString(1, Value); rs = pstmt.executeQuery(); if (rs.next()) - retValue = new MMessage (ctx, rs, null); + retValue = new MMessage (Env.getCtx(), rs, null); } catch (Exception e) { @@ -74,13 +86,20 @@ public class MMessage extends X_AD_Message pstmt = null; } if (retValue != null) - s_cache.put(Value, retValue); + { + s_cache.put(Value, retValue, e -> new MMessage(Env.getCtx(), e)); + } + return retValue; } - return retValue; + else + { + return retValue; + } + } // get /** - * Get Message (cached) + * Get Message (cached) (immutable) * @param ctx context * @param AD_Message_ID id * @return message @@ -88,18 +107,28 @@ public class MMessage extends X_AD_Message public static MMessage get (Properties ctx, int AD_Message_ID) { String key = String.valueOf(AD_Message_ID); - MMessage retValue = (MMessage)s_cache.get(key); + MMessage retValue = s_cache.get(ctx, key, e -> new MMessage(ctx, e)); if (retValue == null) { retValue = new MMessage (ctx, AD_Message_ID, null); - s_cache.put(key, retValue); + s_cache.put(key, retValue, e -> new MMessage(Env.getCtx(), e)); } return retValue; } // get /** * Get Message ID (cached) - * @param ctx context + * @param Value message value + * @return AD_Message_ID + */ + public static int getAD_Message_ID (String Value) + { + return getAD_Message_ID(Env.getCtx(), Value); + } + + /** + * Get Message ID (cached) + * @param ctx context * @param Value message value * @return AD_Message_ID */ @@ -112,7 +141,7 @@ public class MMessage extends X_AD_Message } // getAD_Message_ID /** Cache */ - static private CCache s_cache = new CCache(Table_Name, 100); + static private ImmutablePOCache s_cache = new ImmutablePOCache(Table_Name, 100); /** Static Logger */ private static CLogger s_log = CLogger.getCLogger(MMessage.class); @@ -138,4 +167,44 @@ public class MMessage extends X_AD_Message super(ctx, rs, trxName); } // MMessage + /** + * + * @param copy + */ + public MMessage(MMessage copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MMessage(Properties ctx, MMessage copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MMessage(Properties ctx, MMessage copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + @Override + public MMessage markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MMessage diff --git a/org.adempiere.base/src/org/compiere/model/MMovementLine.java b/org.adempiere.base/src/org/compiere/model/MMovementLine.java index 9c22bf7541..c193efd5e8 100644 --- a/org.adempiere.base/src/org/compiere/model/MMovementLine.java +++ b/org.adempiere.base/src/org/compiere/model/MMovementLine.java @@ -121,7 +121,7 @@ public class MMovementLine extends X_M_MovementLine public MProduct getProduct() { if (getM_Product_ID() != 0) - return MProduct.get(getCtx(), getM_Product_ID()); + return MProduct.getCopy(getCtx(), getM_Product_ID(), get_TrxName()); return null; } // getProduct diff --git a/org.adempiere.base/src/org/compiere/model/MOrderLine.java b/org.adempiere.base/src/org/compiere/model/MOrderLine.java index 8692f9c284..7813c0a0fa 100644 --- a/org.adempiere.base/src/org/compiere/model/MOrderLine.java +++ b/org.adempiere.base/src/org/compiere/model/MOrderLine.java @@ -369,11 +369,11 @@ public class MOrderLine extends X_C_OrderLine public MCharge getCharge() { if (m_charge == null && getC_Charge_ID() != 0) - m_charge = MCharge.get (getCtx(), getC_Charge_ID()); + m_charge = MCharge.getCopy(getCtx(), getC_Charge_ID(), get_TrxName()); return m_charge; } /** - * Get Tax + * Get Tax (immutable) * @return tax */ protected MTax getTax() @@ -472,7 +472,7 @@ public class MOrderLine extends X_C_OrderLine public MProduct getProduct() { if (m_product == null && getM_Product_ID() != 0) - m_product = MProduct.get (getCtx(), getM_Product_ID()); + m_product = MProduct.getCopy(getCtx(), getM_Product_ID(), get_TrxName()); return m_product; } // getProduct diff --git a/org.adempiere.base/src/org/compiere/model/MOrderTax.java b/org.adempiere.base/src/org/compiere/model/MOrderTax.java index f54bfe5e57..9a6f8fbb13 100644 --- a/org.adempiere.base/src/org/compiere/model/MOrderTax.java +++ b/org.adempiere.base/src/org/compiere/model/MOrderTax.java @@ -182,7 +182,7 @@ public class MOrderTax extends X_C_OrderTax } // setPrecision /** - * Get Tax + * Get Tax (immutable) * @return tax */ protected MTax getTax() @@ -266,5 +266,5 @@ public class MOrderTax extends X_C_OrderTax .append ("]"); return sb.toString (); } // toString - + } // MOrderTax diff --git a/org.adempiere.base/src/org/compiere/model/MOrg.java b/org.adempiere.base/src/org/compiere/model/MOrg.java index 3847ddd09a..c999c59f6a 100644 --- a/org.adempiere.base/src/org/compiere/model/MOrg.java +++ b/org.adempiere.base/src/org/compiere/model/MOrg.java @@ -20,9 +20,10 @@ import java.sql.ResultSet; import java.util.List; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Organization Model @@ -30,13 +31,12 @@ import org.compiere.util.Env; * @author Jorg Janke * @version $Id: MOrg.java,v 1.3 2006/07/30 00:58:04 jjanke Exp $ */ -public class MOrg extends X_AD_Org +public class MOrg extends X_AD_Org implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -5604686137606338725L; - + private static final long serialVersionUID = -696173265471741122L; /** * Get Active Organizations Of Client @@ -58,24 +58,36 @@ public class MOrg extends X_AD_Org } // getOfClient /** - * Get Org from Cache - * @param ctx context + * Get Org from Cache (immutable) + * @param AD_Org_ID id + * @return MOrg + */ + public static MOrg get (int AD_Org_ID) + { + return get(Env.getCtx(), AD_Org_ID); + } + + /** + * Get Org from Cache (immutable) * @param AD_Org_ID id * @return MOrg */ public static MOrg get (Properties ctx, int AD_Org_ID) { - MOrg retValue = s_cache.get (AD_Org_ID); + MOrg retValue = s_cache.get (ctx, AD_Org_ID, e -> new MOrg(ctx, e)); if (retValue != null) return retValue; - retValue = new MOrg (ctx, AD_Org_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (AD_Org_ID, retValue); - return retValue; + retValue = new MOrg (ctx, AD_Org_ID, (String)null); + if (retValue.get_ID () == AD_Org_ID) + { + s_cache.put (AD_Org_ID, retValue, e -> new MOrg(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 50); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 50); /************************************************************************** @@ -119,6 +131,38 @@ public class MOrg extends X_AD_Org setName (name); } // MOrg + /** + * + * @param copy + */ + public MOrg(MOrg copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MOrg(Properties ctx, MOrg copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MOrg(Properties ctx, MOrg copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_linkedBPartner = copy.m_linkedBPartner; + } + /** Linked Business Partner */ private Integer m_linkedBPartner = null; @@ -128,7 +172,8 @@ public class MOrg extends X_AD_Org */ public MOrgInfo getInfo() { - return MOrgInfo.get(getCtx(), getAD_Org_ID(), get_TrxName()); + MOrgInfo orgInfo = MOrgInfo.getCopy(Env.getCtx(), getAD_Org_ID(), get_TrxName()); + return orgInfo; } // getMOrgInfo @@ -151,7 +196,7 @@ public class MOrg extends X_AD_Org // Access MRoleOrgAccess.createForOrg (this); MRole role = MRole.getDefault(getCtx(), true); // reload - role.set_TrxName(get_TrxName()); + role = new MRole(getCtx(), role, get_TrxName()); role.loadAccess(true); // reload org access within transaction // TreeNode insert_Tree(MTree_Base.TREETYPE_Organization); @@ -199,5 +244,14 @@ public class MOrg extends X_AD_Org } return m_linkedBPartner.intValue(); } // getLinkedC_BPartner_ID - + + @Override + public MOrg markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MOrg diff --git a/org.adempiere.base/src/org/compiere/model/MOrgInfo.java b/org.adempiere.base/src/org/compiere/model/MOrgInfo.java index 23293be168..c7e901cf70 100644 --- a/org.adempiere.base/src/org/compiere/model/MOrgInfo.java +++ b/org.adempiere.base/src/org/compiere/model/MOrgInfo.java @@ -19,7 +19,9 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Organization Info Model @@ -30,51 +32,86 @@ import org.compiere.util.CCache; * @author Teo Sarca, www.arhipac.ro *
  • BF [ 2107083 ] Caching of MOrgInfo issue */ -public class MOrgInfo extends X_AD_OrgInfo +public class MOrgInfo extends X_AD_OrgInfo implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 2496591466841600079L; + private static final long serialVersionUID = -6257741576762100779L; /** - * Load Constructor - * @param ctx context + * Get MOrgInfo from cache (immutable) * @param AD_Org_ID id * @return Org Info - * @deprecated */ public static MOrgInfo get (Properties ctx, int AD_Org_ID) { - return get(ctx, AD_Org_ID, null); + return get(ctx, AD_Org_ID, (String)null); } // get /** - * Load Constructor - * @param ctx context + * Get MOrgInfo from cache (immutable) + * @param AD_Org_ID id + * @param trxName + * @return Org Info + */ + public static MOrgInfo get (int AD_Org_ID, String trxName) + { + return get(Env.getCtx(), AD_Org_ID, trxName); + } + + /** + * Get MOrgInfo from cache (immutable) + * @param AD_Org_ID id + * @return Org Info + */ + public static MOrgInfo get (int AD_Org_ID) + { + return get(AD_Org_ID, (String)null); + } + + /** + * Get MOrgInfo from cache (immutable) + * @param ctx context * @param AD_Org_ID id * @param trxName * @return Org Info */ public static MOrgInfo get (Properties ctx, int AD_Org_ID, String trxName) { - MOrgInfo retValue = s_cache.get(AD_Org_ID); + MOrgInfo retValue = s_cache.get(ctx, AD_Org_ID, e -> new MOrgInfo(ctx, e)); if (retValue != null) - { return retValue; - } - retValue = new Query(ctx, Table_Name, "AD_Org_ID=?", trxName) + + retValue = new Query(Env.getCtx(), Table_Name, "AD_Org_ID=?", trxName) .setParameters(AD_Org_ID) .firstOnly(); if (retValue != null) { - s_cache.put(AD_Org_ID, retValue); + s_cache.put(AD_Org_ID, retValue, e -> new MOrgInfo(Env.getCtx(), e)); + return retValue; + } - return retValue; + return null; } // get + /** + * Get updateable copy of MOrgInfo from cache + * @param ctx + * @param AD_Org_ID + * @param trxName + * @return MOrgInfo + */ + public static MOrgInfo getCopy(Properties ctx, int AD_Org_ID, String trxName) + { + MOrgInfo oi = get(ctx, AD_Org_ID, trxName); + if (oi != null) + oi = new MOrgInfo(ctx, oi, trxName); + return oi; + } + /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 50); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 50); /************************************************************************** @@ -100,4 +137,44 @@ public class MOrgInfo extends X_AD_OrgInfo setTaxID ("?"); } // MOrgInfo + /** + * + * @param copy + */ + public MOrgInfo(MOrgInfo copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MOrgInfo(Properties ctx, MOrgInfo copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MOrgInfo(Properties ctx, MOrgInfo copy, String trxName) + { + super(ctx, 0, trxName); + copyPO(copy); + } + + @Override + public MOrgInfo markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } diff --git a/org.adempiere.base/src/org/compiere/model/MPOS.java b/org.adempiere.base/src/org/compiere/model/MPOS.java index f63c154ac1..3fb8278b59 100644 --- a/org.adempiere.base/src/org/compiere/model/MPOS.java +++ b/org.adempiere.base/src/org/compiere/model/MPOS.java @@ -21,8 +21,10 @@ import java.util.Properties; import java.util.List; import java.util.logging.Level; -import org.compiere.util.CCache; +import org.compiere.util.Env; import org.compiere.util.Msg; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** @@ -31,15 +33,25 @@ import org.compiere.util.Msg; * @author Jorg Janke * @version $Id: MPOS.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $ */ -public class MPOS extends X_C_POS +public class MPOS extends X_C_POS implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -1568195843844720536L; + private static final long serialVersionUID = 2499679269059812831L; /** - * Get POS from Cache + * Get POS from Cache (immutable) + * @param C_POS_ID id + * @return MPOS + */ + public static MPOS get (int C_POS_ID) + { + return get(Env.getCtx(), C_POS_ID); + } + + /** + * Get POS from Cache (immutable) * @param ctx context * @param C_POS_ID id * @return MPOS @@ -47,13 +59,16 @@ public class MPOS extends X_C_POS public static MPOS get (Properties ctx, int C_POS_ID) { Integer key = Integer.valueOf(C_POS_ID); - MPOS retValue = (MPOS) s_cache.get (key); + MPOS retValue = (MPOS) s_cache.get (ctx, key, e -> new MPOS(ctx, e)); if (retValue != null) return retValue; - retValue = new MPOS (ctx, C_POS_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MPOS (ctx, C_POS_ID, (String)null); + if (retValue.get_ID () == C_POS_ID) + { + s_cache.put (key, retValue, e -> new MPOS(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** @@ -74,7 +89,7 @@ public class MPOS extends X_C_POS } // get /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** * Standard Constructor @@ -107,6 +122,38 @@ public class MPOS extends X_C_POS super(ctx, rs, trxName); } // MPOS + /** + * + * @param copy + */ + public MPOS(MPOS copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MPOS(Properties ctx, MPOS copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MPOS(Properties ctx, MPOS copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_template = copy.m_template != null ? new MBPartner(ctx, copy.m_template, trxName) : null; + } + /** Cash Business Partner */ private MBPartner m_template = null; @@ -154,14 +201,27 @@ public class MPOS extends X_C_POS m_template = MBPartner.getBPartnerCashTrx (getCtx(), getAD_Client_ID()); else m_template = new MBPartner(getCtx(), getC_BPartnerCashTrx_ID(), get_TrxName()); + if (is_Immutable() && m_template != null) + m_template.markImmutable(); if (log.isLoggable(Level.FINE)) log.fine("getBPartner - " + m_template); } return m_template; } // getBPartner + @Override + public MPOS markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_template != null) + m_template.markImmutable(); + return this; + } + @Override public String toString() { return super.getName(); - } + } } // MPOS diff --git a/org.adempiere.base/src/org/compiere/model/MPOSKey.java b/org.adempiere.base/src/org/compiere/model/MPOSKey.java index 361a997c9d..625032f66a 100644 --- a/org.adempiere.base/src/org/compiere/model/MPOSKey.java +++ b/org.adempiere.base/src/org/compiere/model/MPOSKey.java @@ -19,6 +19,9 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; + /** * POS Function Key Model @@ -26,12 +29,12 @@ import java.util.Properties; * @author Jorg Janke * @version $Id: MPOSKey.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $ */ -public class MPOSKey extends X_C_POSKey +public class MPOSKey extends X_C_POSKey implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 2595668386249398840L; + private static final long serialVersionUID = -5138032789563975514L; /** * Standard Constructor @@ -55,6 +58,37 @@ public class MPOSKey extends X_C_POSKey super(ctx, rs, trxName); } // MPOSKey + /** + * + * @param copy + */ + public MPOSKey(MPOSKey copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MPOSKey(Properties ctx, MPOSKey copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MPOSKey(Properties ctx, MPOSKey copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + @Override protected boolean postDelete() { if (getAD_Image_ID() > 0) { @@ -67,4 +101,13 @@ public class MPOSKey extends X_C_POSKey return true; } + @Override + public MPOSKey markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MPOSKey diff --git a/org.adempiere.base/src/org/compiere/model/MPOSKeyLayout.java b/org.adempiere.base/src/org/compiere/model/MPOSKeyLayout.java index 0b52b5e166..5d3fa6753b 100644 --- a/org.adempiere.base/src/org/compiere/model/MPOSKeyLayout.java +++ b/org.adempiere.base/src/org/compiere/model/MPOSKeyLayout.java @@ -19,11 +19,14 @@ package org.compiere.model; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; +import java.util.Arrays; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * POS Function Key Layout @@ -31,15 +34,25 @@ import org.compiere.util.DB; * @author Jorg Janke * @version $Id: MPOSKeyLayout.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $ */ -public class MPOSKeyLayout extends X_C_POSKeyLayout +public class MPOSKeyLayout extends X_C_POSKeyLayout implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 5047330258566607212L; + private static final long serialVersionUID = 8100247902607470888L; /** - * Get POS Key Layout from Cache + * Get POS Key Layout from Cache (immutable) + * @param C_POSKeyLayout_ID id + * @return MPOSKeyLayout + */ + public static MPOSKeyLayout get (int C_POSKeyLayout_ID) + { + return get(Env.getCtx(), C_POSKeyLayout_ID); + } + + /** + * Get POS Key Layout from Cache (immutable) * @param ctx context * @param C_POSKeyLayout_ID id * @return MPOSKeyLayout @@ -47,17 +60,20 @@ public class MPOSKeyLayout extends X_C_POSKeyLayout public static MPOSKeyLayout get (Properties ctx, int C_POSKeyLayout_ID) { Integer key = Integer.valueOf(C_POSKeyLayout_ID); - MPOSKeyLayout retValue = (MPOSKeyLayout) s_cache.get (key); + MPOSKeyLayout retValue = s_cache.get (ctx, key, e -> new MPOSKeyLayout(ctx, e)); if (retValue != null) return retValue; - retValue = new MPOSKeyLayout (ctx, C_POSKeyLayout_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MPOSKeyLayout (ctx, C_POSKeyLayout_ID, (String)null); + if (retValue.get_ID () == C_POSKeyLayout_ID) + { + s_cache.put (key, retValue, e -> new MPOSKeyLayout(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 3); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 3); /** * Standard Constructor @@ -81,6 +97,38 @@ public class MPOSKeyLayout extends X_C_POSKeyLayout super(ctx, rs, trxName); } // MPOSKeyLayout + /** + * + * @param copy + */ + public MPOSKeyLayout(MPOSKeyLayout copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MPOSKeyLayout(Properties ctx, MPOSKeyLayout copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MPOSKeyLayout(Properties ctx, MPOSKeyLayout copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_keys = copy.m_keys != null ? Arrays.stream(copy.m_keys).map(e -> {return new MPOSKey(ctx, e, trxName);}).toArray(MPOSKey[]::new) : null; + } + /** Keys */ private MPOSKey[] m_keys = null; @@ -117,6 +165,8 @@ public class MPOSKeyLayout extends X_C_POSKeyLayout pstmt = null; } + if (list.size() > 0 && is_Immutable()) + list.stream().forEach(e -> e.markImmutable()); m_keys = new MPOSKey[list.size ()]; list.toArray (m_keys); return m_keys; @@ -131,5 +181,17 @@ public class MPOSKeyLayout extends X_C_POSKeyLayout return getKeys(false).length; } // getNoOfKeys + @Override + public MPOSKeyLayout markImmutable() + { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_keys != null && m_keys.length > 0) + Arrays.stream(m_keys).forEach(e -> e.markImmutable()); + return this; + } + } // MPOSKeyLayout diff --git a/org.adempiere.base/src/org/compiere/model/MPOSTerminal.java b/org.adempiere.base/src/org/compiere/model/MPOSTerminal.java index e1be689b2b..3adcfb8203 100644 --- a/org.adempiere.base/src/org/compiere/model/MPOSTerminal.java +++ b/org.adempiere.base/src/org/compiere/model/MPOSTerminal.java @@ -23,7 +23,7 @@ import java.sql.ResultSet; import java.sql.Timestamp; import java.util.Properties; -import org.compiere.util.CCache; +import org.compiere.util.Env; /** * @author Ashley G Ramdass @@ -35,8 +35,6 @@ public class MPOSTerminal extends X_U_POSTerminal * */ private static final long serialVersionUID = 6972567212871993024L; - /** Cache */ - static private CCache s_cache = new CCache(Table_Name, 10, 60); /** * @param ctx Context @@ -58,6 +56,46 @@ public class MPOSTerminal extends X_U_POSTerminal super(ctx, U_POSTerminal_ID, trxName); } + /** + * + * @param copy + */ + public MPOSTerminal(MPOSTerminal copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MPOSTerminal(Properties ctx, MPOSTerminal copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MPOSTerminal(Properties ctx, MPOSTerminal copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + /** + * @param U_POSTerminal_ID Terminal ID + * @return Terminal + */ + public static MPOSTerminal get(int U_POSTerminal_ID) + { + return get(Env.getCtx(), U_POSTerminal_ID); + } + /** * @param ctx Context * @param U_POSTerminal_ID Terminal ID @@ -65,18 +103,12 @@ public class MPOSTerminal extends X_U_POSTerminal */ public static MPOSTerminal get(Properties ctx, int U_POSTerminal_ID) { - Integer key = Integer.valueOf(U_POSTerminal_ID); - MPOSTerminal retValue = (MPOSTerminal)s_cache.get(key); - if (retValue == null) + MPOSTerminal retValue = new MPOSTerminal (ctx, U_POSTerminal_ID, (String)null); + + if (retValue.get_ID() != U_POSTerminal_ID) { - retValue = new MPOSTerminal (ctx, U_POSTerminal_ID, null); - if (retValue.get_ID() <= 0) - { - return null; - } - s_cache.put(key, retValue); + return null; } - checkLock(retValue); return retValue; } @@ -122,20 +154,5 @@ public class MPOSTerminal extends X_U_POSTerminal } return true; - } - - /** - * @see org.compiere.model.PO#afterSave(boolean, boolean) - */ - protected boolean afterSave(boolean newRecord, boolean success) - { - success = super.afterSave(newRecord, success); - - if (success) - { - s_cache.remove(Integer.valueOf(get_ID())); - } - - return success; - } + } } diff --git a/org.adempiere.base/src/org/compiere/model/MPeriod.java b/org.adempiere.base/src/org/compiere/model/MPeriod.java index 6920814baf..f66b2a0c78 100644 --- a/org.adempiere.base/src/org/compiere/model/MPeriod.java +++ b/org.adempiere.base/src/org/compiere/model/MPeriod.java @@ -22,19 +22,20 @@ import java.sql.SQLException; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Iterator; +import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.logging.Level; import org.adempiere.exceptions.PeriodClosedException; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.TimeUtil; import org.compiere.util.Util; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Calendar Period Model @@ -50,15 +51,25 @@ import org.compiere.util.Util; *
  • FR [ 2520591 ] Support multiples calendar for Org * @see http://sourceforge.net/tracker2/?func=detail&atid=879335&aid=2520591&group_id=176962 */ -public class MPeriod extends X_C_Period +public class MPeriod extends X_C_Period implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 769103495098446073L; + private static final long serialVersionUID = -2781791828528639980L; /** - * Get Period from Cache + * Get Period from Cache (immutable) + * @param C_Period_ID id + * @return MPeriod + */ + public static MPeriod get (int C_Period_ID) + { + return get(Env.getCtx(), C_Period_ID); + } + + /** + * Get Period from Cache (immutable) * @param ctx context * @param C_Period_ID id * @return MPeriod @@ -69,14 +80,17 @@ public class MPeriod extends X_C_Period return null; // Integer key = Integer.valueOf(C_Period_ID); - MPeriod retValue = (MPeriod) s_cache.get (key); + MPeriod retValue = s_cache.get (ctx, key, e -> new MPeriod(ctx, e)); if (retValue != null) return retValue; // retValue = new MPeriod (ctx, C_Period_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + if (retValue.get_ID () == C_Period_ID) + { + s_cache.put (key, retValue, e -> new MPeriod(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** @@ -139,10 +153,9 @@ public class MPeriod extends X_C_Period int AD_Client_ID = Env.getAD_Client_ID(ctx); // Search in Cache first - Iterator it = s_cache.values().iterator(); - while (it.hasNext()) + MPeriod[] it = s_cache.values().toArray(new MPeriod[0]); + for (MPeriod period : it) { - MPeriod period = (MPeriod)it.next(); if (period.getC_Calendar_ID() == C_Calendar_ID && period.isStandardPeriod() && period.isInPeriod(DateAcct) && period.getAD_Client_ID() == AD_Client_ID) // globalqss - CarlosRuiz - Fix [ 1820810 ] Wrong Period Assigned to Fact_Acct return period; @@ -447,7 +460,7 @@ public class MPeriod extends X_C_Period } // getFirstInYear /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 10); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 10); /** Logger */ private static CLogger s_log = CLogger.getCLogger (MPeriod.class); @@ -507,7 +520,39 @@ public class MPeriod extends X_C_Period setEndDate(endDate); } // MPeriod - + /** + * + * @param copy + */ + public MPeriod(MPeriod copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MPeriod(Properties ctx, MPeriod copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MPeriod(Properties ctx, MPeriod copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_C_Calendar_ID = copy.m_C_Calendar_ID; + this.m_controls = copy.m_controls != null ? Arrays.stream(copy.m_controls).map(e -> {return new MPeriodControl(ctx, e, trxName);}).toArray(MPeriodControl[]::new) : null; + } + /** Period Controls */ private MPeriodControl[] m_controls = null; @@ -544,6 +589,8 @@ public class MPeriod extends X_C_Period rs = null; pstmt = null; } // + if (list.size() > 0 && is_Immutable()) + list.stream().forEach(e -> e.markImmutable()); m_controls = new MPeriodControl[list.size ()]; list.toArray (m_controls); return m_controls; @@ -889,4 +936,16 @@ public class MPeriod extends X_C_Period return C_Calendar_ID; } // getC_Calendar_ID + @Override + public MPeriod markImmutable() + { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_controls != null && m_controls.length > 0) + Arrays.stream(m_controls).forEach(e -> e.markImmutable()); + return this; + } + } // MPeriod diff --git a/org.adempiere.base/src/org/compiere/model/MPeriodControl.java b/org.adempiere.base/src/org/compiere/model/MPeriodControl.java index 0539d2aaa9..93074b6b84 100644 --- a/org.adempiere.base/src/org/compiere/model/MPeriodControl.java +++ b/org.adempiere.base/src/org/compiere/model/MPeriodControl.java @@ -19,13 +19,16 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; + /** * Period Control Model * * @author Jorg Janke * @version $Id: MPeriodControl.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $ */ -public class MPeriodControl extends X_C_PeriodControl +public class MPeriodControl extends X_C_PeriodControl implements ImmutablePOSupport { /** * @@ -91,6 +94,37 @@ public class MPeriodControl extends X_C_PeriodControl setDocBaseType (DocBaseType); } // MPeriodControl + /** + * + * @param copy + */ + public MPeriodControl(MPeriodControl copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MPeriodControl(Properties ctx, MPeriodControl copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MPeriodControl(Properties ctx, MPeriodControl copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Is Period Open * @return true if open @@ -113,6 +147,15 @@ public class MPeriodControl extends X_C_PeriodControl .append ("]"); return sb.toString (); } // toString - + + @Override + public MPeriodControl markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MPeriodControl diff --git a/org.adempiere.base/src/org/compiere/model/MPriceList.java b/org.adempiere.base/src/org/compiere/model/MPriceList.java index 4ff33827ef..409d5a43ed 100644 --- a/org.adempiere.base/src/org/compiere/model/MPriceList.java +++ b/org.adempiere.base/src/org/compiere/model/MPriceList.java @@ -18,12 +18,12 @@ package org.compiere.model; import java.sql.ResultSet; import java.sql.Timestamp; -import java.util.Iterator; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Price List Model @@ -34,15 +34,37 @@ import org.compiere.util.Env; * @author Teo Sarca, www.arhipac.ro *
  • BF [ 2073484 ] MPriceList.getDefault is not working correctly */ -public class MPriceList extends X_M_PriceList +public class MPriceList extends X_M_PriceList implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -5096935348390226068L; + private static final long serialVersionUID = 7128840936482927934L; + /** - * Get Price List (cached) + * Get Price List (cached) (immutable) + * @param M_PriceList_ID id + * @return PriceList + */ + public static MPriceList get (int M_PriceList_ID) + { + return get(M_PriceList_ID, (String)null); + } + + /** + * Get Price List (cached) (immutable) + * @param M_PriceList_ID id + * @param trxName transaction + * @return PriceList + */ + public static MPriceList get (int M_PriceList_ID, String trxName) + { + return get(Env.getCtx(), M_PriceList_ID, trxName); + } + + /** + * Get Price List (cached) (immutable) * @param ctx context * @param M_PriceList_ID id * @param trxName transaction @@ -51,15 +73,35 @@ public class MPriceList extends X_M_PriceList public static MPriceList get (Properties ctx, int M_PriceList_ID, String trxName) { Integer key = Integer.valueOf(M_PriceList_ID); - MPriceList retValue = (MPriceList)s_cache.get(key); + MPriceList retValue = s_cache.get(ctx, key, e -> new MPriceList(ctx, e)); if (retValue == null) { retValue = new MPriceList (ctx, M_PriceList_ID, trxName); - s_cache.put(key, retValue); + if (retValue.get_ID() == M_PriceList_ID) + { + s_cache.put(key, retValue, e -> new MPriceList(Env.getCtx(), e)); + return retValue; + } + return null; } return retValue; } // get + /** + * Get updateable copy of MPriceList from cache + * @param ctx + * @param M_PriceList_ID + * @param trxName + * @return MPriceList + */ + public static MPriceList getCopy(Properties ctx, int M_PriceList_ID, String trxName) + { + MPriceList pl = get(ctx, M_PriceList_ID, trxName); + if (pl != null) + pl = new MPriceList(ctx, pl, trxName); + return pl; + } + /** * Get Default Price List for Client (cached) * @param ctx context @@ -69,12 +111,10 @@ public class MPriceList extends X_M_PriceList public static MPriceList getDefault (Properties ctx, boolean IsSOPriceList) { int AD_Client_ID = Env.getAD_Client_ID(ctx); - MPriceList retValue = null; // Search for it in cache - Iterator it = s_cache.values().iterator(); - while (it.hasNext()) + MPriceList[] it = s_cache.values().toArray(new MPriceList[0]); + for(MPriceList retValue : it) { - retValue = it.next(); if (retValue.isDefault() && retValue.getAD_Client_ID() == AD_Client_ID && retValue.isSOPriceList() == IsSOPriceList) @@ -85,7 +125,7 @@ public class MPriceList extends X_M_PriceList // Get from DB final String whereClause = "AD_Client_ID=? AND IsDefault=? AND IsSOPriceList=?"; - retValue = new Query(ctx, Table_Name, whereClause, null) + MPriceList retValue = new Query(ctx, Table_Name, whereClause, null) .setParameters(AD_Client_ID, "Y", IsSOPriceList ? "Y" : "N") .setOnlyActiveRecords(true) .setOrderBy("M_PriceList_ID") @@ -94,7 +134,7 @@ public class MPriceList extends X_M_PriceList // Return value if (retValue != null) { - s_cache.put(retValue.get_ID(), retValue); + s_cache.put(retValue.get_ID(), retValue, e -> new MPriceList(Env.getCtx(), e)); } return retValue; } // getDefault @@ -115,12 +155,10 @@ public class MPriceList extends X_M_PriceList int M_Currency_ID = currency.get_ID(); - MPriceList retValue = null; // Search for it in cache - Iterator it = s_cache.values().iterator(); - while (it.hasNext()) + MPriceList[] it = s_cache.values().toArray(new MPriceList[0]); + for (MPriceList retValue : it) { - retValue = it.next(); if (retValue.isDefault() && retValue.getAD_Client_ID() == AD_Client_ID && retValue.isSOPriceList() == IsSOPriceList @@ -133,7 +171,7 @@ public class MPriceList extends X_M_PriceList // Get from DB final String whereClause = "AD_Client_ID=? AND IsDefault=? AND IsSOPriceList=? AND C_Currency_ID=?"; - retValue = new Query(ctx, Table_Name, whereClause, null) + MPriceList retValue = new Query(ctx, Table_Name, whereClause, null) .setParameters(AD_Client_ID, "Y", IsSOPriceList ? "Y" : "N", M_Currency_ID) .setOnlyActiveRecords(true) .setOrderBy("M_PriceList_ID") @@ -142,7 +180,7 @@ public class MPriceList extends X_M_PriceList // Return value if (retValue != null) { - s_cache.put(retValue.get_ID(), retValue); + s_cache.put(retValue.get_ID(), retValue, e -> new MPriceList(Env.getCtx(), e)); } return retValue; } @@ -172,7 +210,7 @@ public class MPriceList extends X_M_PriceList } // getPricePrecision /** Cache of Price Lists */ - private static CCache s_cache = new CCache(Table_Name, 5, 5); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 5, 5); /************************************************************************** @@ -226,6 +264,47 @@ public class MPriceList extends X_M_PriceList setEnforcePriceLimit(impPL.isEnforcePriceLimit()); } // MPriceList + /** + * + * @param copy + */ + public MPriceList(MPriceList copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MPriceList(Properties ctx, MPriceList copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MPriceList(Properties ctx, MPriceList copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + if (copy.m_plv != null) + { + this.m_plv = new MPriceListVersion(ctx, copy.m_plv, trxName); + this.m_plv.m_pl = this; + } + else + { + this.m_plv = null; + } + this.m_precision = copy.m_precision; + } + /** Cached PLV */ private MPriceListVersion m_plv = null; /** Cached Precision */ @@ -251,6 +330,8 @@ public class MPriceList extends X_M_PriceList if (log.isLoggable(Level.INFO)) log.info("None found M_PriceList_ID=" + getM_PriceList_ID() + " - " + valid); else if (log.isLoggable(Level.FINE)) log.fine(m_plv.toString()); + if (m_plv != null && is_Immutable()) + m_plv.markImmutable(); return m_plv; } // getPriceListVersion @@ -268,4 +349,15 @@ public class MPriceList extends X_M_PriceList return m_precision.intValue(); } // getStandardPrecision + @Override + public MPriceList markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_plv != null) + m_plv.markImmutable(); + return this; + } + } // MPriceList diff --git a/org.adempiere.base/src/org/compiere/model/MPriceListVersion.java b/org.adempiere.base/src/org/compiere/model/MPriceListVersion.java index d414a7cca9..84c3c625d1 100644 --- a/org.adempiere.base/src/org/compiere/model/MPriceListVersion.java +++ b/org.adempiere.base/src/org/compiere/model/MPriceListVersion.java @@ -17,11 +17,14 @@ package org.compiere.model; import java.sql.ResultSet; +import java.util.Arrays; import java.util.List; import java.util.Properties; import org.compiere.util.DisplayType; +import org.compiere.util.Env; import org.compiere.util.TimeUtil; +import org.idempiere.cache.ImmutablePOSupport; /** * Price List Version Model @@ -29,12 +32,12 @@ import org.compiere.util.TimeUtil; * @author Jorg Janke * @version $Id: MPriceListVersion.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $ */ -public class MPriceListVersion extends X_M_PriceList_Version +public class MPriceListVersion extends X_M_PriceList_Version implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -3607494586575155059L; + private static final long serialVersionUID = 1625884461739604147L; /** * Standard Constructor @@ -76,10 +79,43 @@ public class MPriceListVersion extends X_M_PriceList_Version setM_PriceList_ID(pl.getM_PriceList_ID()); } // MPriceListVersion + /** + * + * @param copy + */ + public MPriceListVersion(MPriceListVersion copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MPriceListVersion(Properties ctx, MPriceListVersion copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MPriceListVersion(Properties ctx, MPriceListVersion copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_pl = null; + this.m_pp = copy.m_pp != null ? Arrays.stream(copy.m_pp).map(e -> {return new MProductPrice(ctx, e, trxName);}).toArray(MProductPrice[]::new) : null; + } + /** Product Prices */ private MProductPrice[] m_pp = null; /** Price List */ - private MPriceList m_pl = null; + protected MPriceList m_pl = null; /** * Get Parent PriceList @@ -88,7 +124,12 @@ public class MPriceListVersion extends X_M_PriceList_Version public MPriceList getPriceList() { if (m_pl == null && getM_PriceList_ID() != 0) - m_pl = MPriceList.get (getCtx(), getM_PriceList_ID(), null); + { + if (is_Immutable()) + m_pl = MPriceList.get (getCtx(), getM_PriceList_ID(), null); + else + m_pl = MPriceList.getCopy(getCtx(), getM_PriceList_ID(), get_TrxName()); + } return m_pl; } // PriceList @@ -103,6 +144,8 @@ public class MPriceListVersion extends X_M_PriceList_Version if (m_pp != null && !refresh) return m_pp; m_pp = getProductPrice(null); + if (m_pp != null && m_pp.length > 0 && is_Immutable()) + Arrays.stream(m_pp).forEach(e -> e.markImmutable()); return m_pp; } // getProductPrice @@ -152,4 +195,18 @@ public class MPriceListVersion extends X_M_PriceList_Version return true; } // beforeSave + @Override + public MPriceListVersion markImmutable() + { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_pl != null) + m_pl.markImmutable(); + if (m_pp != null && m_pp.length > 0) + Arrays.stream(m_pp).forEach(e -> e.markImmutable()); + return this; + } + } // MPriceListVersion diff --git a/org.adempiere.base/src/org/compiere/model/MProcess.java b/org.adempiere.base/src/org/compiere/model/MProcess.java index 2f14c8ce88..a1e48cc354 100644 --- a/org.adempiere.base/src/org/compiere/model/MProcess.java +++ b/org.adempiere.base/src/org/compiere/model/MProcess.java @@ -17,13 +17,13 @@ package org.compiere.model; import java.sql.ResultSet; +import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.logging.Level; import org.adempiere.util.ProcessUtil; import org.compiere.process.ProcessInfo; -import org.compiere.util.CCache; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Trx; @@ -31,6 +31,10 @@ import org.compiere.util.Util; import org.compiere.wf.MWFNode; import org.compiere.wf.MWFProcess; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.ImmutablePOCache; + /** * Process Model * @@ -41,15 +45,25 @@ import org.compiere.wf.MWFProcess; *
  • BF [ 1757523 ] Server Processes are using Server's context *
  • FR [ 2214883 ] Remove SQL code and Replace for Query */ -public class MProcess extends X_AD_Process +public class MProcess extends X_AD_Process implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -7234986583327689692L; + private static final long serialVersionUID = 6928560924056836659L; /** - * Get MProcess from Cache + * Get MProcess from Cache (immutable) + * @param AD_Process_ID id + * @return MProcess + */ + public static MProcess get (int AD_Process_ID) + { + return get(Env.getCtx(), AD_Process_ID); + } + + /** + * Get MProcess from Cache (immutable) * @param ctx context * @param AD_Process_ID id * @return MProcess @@ -57,31 +71,65 @@ public class MProcess extends X_AD_Process public static MProcess get (Properties ctx, int AD_Process_ID) { Integer key = Integer.valueOf(AD_Process_ID); - MProcess retValue = (MProcess) s_cache.get (key); + MProcess retValue = s_cache.get (ctx, key, e -> new MProcess(ctx, e)); if (retValue != null) return retValue; - retValue = new MProcess (ctx, AD_Process_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MProcess (ctx, AD_Process_ID, (String)null); + if (retValue.get_ID () == AD_Process_ID) + { + s_cache.put (key, retValue, e -> new MProcess(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** - * Get MProcess from Cache based on UUID + * Get updateable copy of MProcess from cache + * @param ctx + * @param AD_Process_ID + * @param trxName + * @return MProcess + */ + public static MProcess getCopy(Properties ctx, int AD_Process_ID, String trxName) + { + MProcess process = get(AD_Process_ID); + if (process != null) + process = new MProcess(ctx, process, trxName); + return process; + } + + /** + * Get MProcess from Cache based on UUID (immutable) + * @param AD_Process_UU UUID + * @return MProcess + */ + public static MProcess get (String AD_Process_UU) + { + return get(Env.getCtx(), AD_Process_UU); + } + + /** + * Get MProcess from Cache based on UUID (immutable) * @param ctx context * @param AD_Process_UU UUID * @return MProcess */ public static MProcess get (Properties ctx, String AD_Process_UU) { - MProcess retValue = s_cacheUU.get(AD_Process_UU); + MProcess retValue = s_cacheUU.get(ctx, AD_Process_UU, e -> new MProcess(ctx, e)); if (retValue != null) return retValue; int id = DB.getSQLValueEx(null, "SELECT AD_Process_ID FROM AD_Process WHERE AD_Process_UU = ? ", AD_Process_UU); - retValue = new MProcess (ctx, id, null); - if (!Util.isEmpty(retValue.getAD_Process_UU())) - s_cacheUU.put (retValue.getAD_Process_UU(), retValue); - return retValue; + if (id > 0) + { + retValue = new MProcess (ctx, id, (String)null); + if (retValue.get_ID() == id && !Util.isEmpty(retValue.getAD_Process_UU())) + { + s_cacheUU.put (retValue.getAD_Process_UU(), retValue, e -> new MProcess(Env.getCtx(), e)); + return retValue; + } + } + return null; } // get /** @@ -99,16 +147,16 @@ public class MProcess extends X_AD_Process .firstOnly(); if (p != null) { - s_cache.put (p.get_ID(), p); + s_cache.put (p.get_ID(), p, e -> new MProcess(Env.getCtx(), e)); } return p; } // getFromMenu /** Cache ID */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** Cache UUID */ - private static CCache s_cacheUU = new CCache(Table_Name, Table_Name+"|AD_Process_UU", 20); + private static ImmutablePOCache s_cacheUU = new ImmutablePOCache(Table_Name, Table_Name+"|AD_Process_UU", 20); /************************************************************************** @@ -143,7 +191,38 @@ public class MProcess extends X_AD_Process super(ctx, rs, trxName); } // MProcess + /** + * + * @param copy + */ + public MProcess(MProcess copy) + { + this(Env.getCtx(), copy); + } + /** + * + * @param ctx + * @param copy + */ + public MProcess(Properties ctx, MProcess copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MProcess(Properties ctx, MProcess copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_parameters = copy.m_parameters != null ? Arrays.stream(copy.m_parameters).map(e -> {return new MProcessPara(ctx, e, trxName);}).toArray(MProcessPara[]::new) : null; + } + /** Parameters */ private MProcessPara[] m_parameters = null; @@ -163,6 +242,8 @@ public class MProcess extends X_AD_Process .setOrderBy(MProcessPara.COLUMNNAME_SeqNo) .list(); // + if (list.size() > 0 && is_Immutable()) + list.stream().forEach(e -> e.markImmutable()); m_parameters = new MProcessPara[list.size()]; list.toArray(m_parameters); return m_parameters; @@ -534,4 +615,16 @@ public class MProcess extends X_AD_Process return processIt(pi, trx, false); } // processItWithoutTrxClose + @Override + public MProcess markImmutable() + { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_parameters != null && m_parameters.length > 0) + Arrays.stream(m_parameters).forEach(e -> e.markImmutable()); + return this; + } + } // MProcess diff --git a/org.adempiere.base/src/org/compiere/model/MProcessPara.java b/org.adempiere.base/src/org/compiere/model/MProcessPara.java index 85d3d75937..84eec30890 100644 --- a/org.adempiere.base/src/org/compiere/model/MProcessPara.java +++ b/org.adempiere.base/src/org/compiere/model/MProcessPara.java @@ -20,10 +20,11 @@ import java.sql.ResultSet; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.DB; import org.compiere.util.DisplayType; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** @@ -32,15 +33,25 @@ import org.compiere.util.Env; * @author Jorg Janke * @version $Id: MProcessPara.java,v 1.3 2006/07/30 00:58:37 jjanke Exp $ */ -public class MProcessPara extends X_AD_Process_Para +public class MProcessPara extends X_AD_Process_Para implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 4580303034897910371L; + private static final long serialVersionUID = -770944613761780314L; /** - * Get MProcessPara from Cache + * Get MProcessPara from Cache (immutable) + * @param AD_Process_Para_ID id + * @return MProcessPara + */ + public static MProcessPara get (int AD_Process_Para_ID) + { + return get(Env.getCtx(), AD_Process_Para_ID); + } + + /** + * Get MProcessPara from Cache (immutable) * @param ctx context * @param AD_Process_Para_ID id * @return MProcessPara @@ -48,18 +59,21 @@ public class MProcessPara extends X_AD_Process_Para public static MProcessPara get (Properties ctx, int AD_Process_Para_ID) { Integer key = Integer.valueOf(AD_Process_Para_ID); - MProcessPara retValue = (MProcessPara)s_cache.get (key); + MProcessPara retValue = s_cache.get (ctx, key, e -> new MProcessPara(ctx, e)); if (retValue != null) return retValue; - retValue = new MProcessPara (ctx, AD_Process_Para_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MProcessPara (ctx, AD_Process_Para_ID, (String)null); + if (retValue.get_ID () == AD_Process_Para_ID) + { + s_cache.put (key, retValue, e -> new MProcessPara(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private static CCache s_cache - = new CCache (Table_Name, 20); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache (Table_Name, 20); /************************************************************************** @@ -110,6 +124,37 @@ public class MProcessPara extends X_AD_Process_Para setEntityType(parent.getEntityType()); } + /** + * + * @param copy + */ + public MProcessPara(MProcessPara copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MProcessPara(Properties ctx, MProcessPara copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MProcessPara(Properties ctx, MProcessPara copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** Virtual Window No - 999 */ public static int WINDOW_NO = 999; /** Virtual Tab No - 0 */ @@ -310,4 +355,13 @@ public class MProcessPara extends X_AD_Process_Para return foreignTable; } + @Override + public MProcessPara markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MProcessPara diff --git a/org.adempiere.base/src/org/compiere/model/MProduct.java b/org.adempiere.base/src/org/compiere/model/MProduct.java index 9329af9177..fafdd62080 100644 --- a/org.adempiere.base/src/org/compiere/model/MProduct.java +++ b/org.adempiere.base/src/org/compiere/model/MProduct.java @@ -18,16 +18,18 @@ package org.compiere.model; import java.math.BigDecimal; import java.sql.ResultSet; +import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.logging.Level; import org.adempiere.exceptions.AdempiereException; -import org.compiere.util.CCache; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.Util; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Product Model @@ -46,15 +48,25 @@ import org.compiere.util.Util; * @author Mark Ostermann (mark_o), metas consult GmbH *
  • BF [ 2814628 ] Wrong evaluation of Product inactive in beforeSave() */ -public class MProduct extends X_M_Product +public class MProduct extends X_M_Product implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 285926961771269935L; + private static final long serialVersionUID = -6713953630334843853L; /** - * Get MProduct from Cache + * Get MProduct from Cache (immutable) + * @param M_Product_ID id + * @return MProduct or null + */ + public static MProduct get (int M_Product_ID) + { + return get(Env.getCtx(), M_Product_ID); + } + + /** + * Get MProduct from Cache (immutable) * @param ctx context * @param M_Product_ID id * @return MProduct or null @@ -66,25 +78,40 @@ public class MProduct extends X_M_Product return null; } Integer key = Integer.valueOf(M_Product_ID); - MProduct retValue = (MProduct) s_cache.get (key); + MProduct retValue = s_cache.get (ctx, key, e -> new MProduct(ctx, e)); if (retValue != null) + return retValue; + + retValue = new MProduct (ctx, M_Product_ID, (String)null); + if (retValue.get_ID () == M_Product_ID) { + s_cache.put (key, retValue, e -> new MProduct(Env.getCtx(), e)); return retValue; } - retValue = new MProduct (ctx, M_Product_ID, null); - if (retValue.get_ID () != 0) - { - s_cache.put (key, retValue); - } - return retValue; + return null; } // get /** - * Get MProduct from Cache + * Get updateable copy of MProduct from cache + * @param ctx + * @param M_Product_ID + * @param trxName + * @return MProduct + */ + public static MProduct getCopy(Properties ctx, int M_Product_ID, String trxName) + { + MProduct product = get(M_Product_ID); + if (product != null) + product = new MProduct(ctx, product, trxName); + return product; + } + + /** + * Get MProducts from db * @param ctx context * @param whereClause sql where clause * @param trxName trx - * @return MProduct + * @return MProducts */ public static MProduct[] get (Properties ctx, String whereClause, String trxName) { @@ -122,7 +149,7 @@ public class MProduct extends X_M_Product } /** - * Get Product from Cache + * Get Product from Cache (immutable) * @param ctx context * @param S_Resource_ID resource ID * @param trxName @@ -138,7 +165,8 @@ public class MProduct extends X_M_Product // Try Cache if (trxName == null) { - for (MProduct p : s_cache.values()) + MProduct[] products = s_cache.values().toArray(new MProduct[0]); + for (MProduct p : products) { if (p.getS_Resource_ID() == S_Resource_ID) { @@ -150,9 +178,9 @@ public class MProduct extends X_M_Product MProduct p = new Query(ctx, Table_Name, COLUMNNAME_S_Resource_ID+"=?", trxName) .setParameters(new Object[]{S_Resource_ID}) .firstOnly(); - if (p != null && trxName == null) + if (p != null) { - s_cache.put(p.getM_Product_ID(), p); + s_cache.put(p.getM_Product_ID(), p, e -> new MProduct(Env.getCtx(), e)); } return p; } @@ -171,7 +199,7 @@ public class MProduct extends X_M_Product } // isProductStocked /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 40, 5); // 5 minutes + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 40, 5); // 5 minutes /************************************************************************** * Standard Constructor @@ -269,6 +297,39 @@ public class MProduct extends X_M_Product setWeight(impP.getWeight()); } // MProduct + /** + * + * @param copy + */ + public MProduct(MProduct copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MProduct(Properties ctx, MProduct copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MProduct(Properties ctx, MProduct copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_downloads = copy.m_downloads != null ? Arrays.stream(copy.m_downloads).map(e -> {return new MProductDownload(ctx, e, trxName);}).toArray(MProductDownload[]::new) : null; + this.m_precision = copy.m_precision; + } + /** Additional Downloads */ private MProductDownload[] m_downloads = null; @@ -456,7 +517,7 @@ public class MProduct extends X_M_Product public MAttributeSet getAttributeSet() { if (getM_AttributeSet_ID() != 0) - return MAttributeSet.get(getCtx(), getM_AttributeSet_ID()); + return MAttributeSet.getCopy(getCtx(), getM_AttributeSet_ID(), get_TrxName()); return null; } // getAttributeSet @@ -541,6 +602,8 @@ public class MProduct extends X_M_Product .setOrderBy(I_M_ProductDownload.COLUMNNAME_Name) .setParameters(get_ID()) .list(); + if (list.size() > 0 && is_Immutable()) + list.stream().forEach(e -> e.markImmutable()); m_downloads = list.toArray(new MProductDownload[list.size()]); return m_downloads; } // getProductDownloads @@ -927,4 +990,17 @@ public class MProduct extends X_M_Product MCost cost = MCost.get(this, M_ASI_ID, as, AD_Org_ID, ce.getM_CostElement_ID(), get_TrxName()); return cost.is_new() ? null : cost; } + + @Override + public MProduct markImmutable() + { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_downloads != null && m_downloads.length > 0) + Arrays.stream(m_downloads).forEach(e -> e.markImmutable()); + return this; + } + } // MProduct diff --git a/org.adempiere.base/src/org/compiere/model/MProductBOM.java b/org.adempiere.base/src/org/compiere/model/MProductBOM.java index c9cfdae077..139c6dafad 100644 --- a/org.adempiere.base/src/org/compiere/model/MProductBOM.java +++ b/org.adempiere.base/src/org/compiere/model/MProductBOM.java @@ -117,7 +117,7 @@ public class MProductBOM extends X_M_Product_BOM public MProduct getProduct() { if (m_product == null && getM_ProductBOM_ID() != 0) - m_product = MProduct.get (getCtx(), getM_ProductBOM_ID()); + m_product = MProduct.getCopy(getCtx(), getM_ProductBOM_ID(), get_TrxName()); return m_product; } // getProduct diff --git a/org.adempiere.base/src/org/compiere/model/MProductCategory.java b/org.adempiere.base/src/org/compiere/model/MProductCategory.java index 27ff1a214b..fa7bc90f69 100644 --- a/org.adempiere.base/src/org/compiere/model/MProductCategory.java +++ b/org.adempiere.base/src/org/compiere/model/MProductCategory.java @@ -29,6 +29,8 @@ import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Product Category Model @@ -36,15 +38,25 @@ import org.compiere.util.Msg; * @author Jorg Janke * @version $Id: MProductCategory.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $ */ -public class MProductCategory extends X_M_Product_Category +public class MProductCategory extends X_M_Product_Category implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 1239249591584452179L; + private static final long serialVersionUID = 6444388652482234582L; /** - * Get from Cache + * Get from Cache (immutable) + * @param M_Product_Category_ID id + * @return category + */ + public static MProductCategory get (int M_Product_Category_ID) + { + return get(Env.getCtx(), M_Product_Category_ID); + } + + /** + * Get from Cache (immutable) * @param ctx context * @param M_Product_Category_ID id * @return category @@ -52,13 +64,16 @@ public class MProductCategory extends X_M_Product_Category public static MProductCategory get (Properties ctx, int M_Product_Category_ID) { Integer ii = Integer.valueOf(M_Product_Category_ID); - MProductCategory retValue = (MProductCategory)s_cache.get(ii); + MProductCategory retValue = s_cache.get(ctx, ii, e -> new MProductCategory(ctx, e)); if (retValue != null) return retValue; - retValue = new MProductCategory (ctx, M_Product_Category_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (M_Product_Category_ID, retValue); - return retValue; + retValue = new MProductCategory (ctx, M_Product_Category_ID, (String)null); + if (retValue.get_ID () == M_Product_Category_ID) + { + s_cache.put (M_Product_Category_ID, retValue, e -> new MProductCategory(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** @@ -113,7 +128,7 @@ public class MProductCategory extends X_M_Product_Category } // isCategory /** Categopry Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** Product Cache */ private static CCache s_products = new CCache(I_M_Product.Table_Name, Table_Name + "|M_Product", 100); /** Static Logger */ @@ -151,6 +166,37 @@ public class MProductCategory extends X_M_Product_Category super(ctx, rs, trxName); } // MProductCategory + /** + * + * @param copy + */ + public MProductCategory(MProductCategory copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MProductCategory(Properties ctx, MProductCategory copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MProductCategory(Properties ctx, MProductCategory copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Before Save * @param newRecord new @@ -258,6 +304,15 @@ public class MProductCategory extends X_M_Product_Category return ret; } //hasLoop + @Override + public MProductCategory markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + /** * Simple class for tree nodes. * @author Karsten Thiemann, kthiemann@adempiere.org diff --git a/org.adempiere.base/src/org/compiere/model/MProductCategoryAcct.java b/org.adempiere.base/src/org/compiere/model/MProductCategoryAcct.java index 29cfd71efe..5bb8f9e661 100644 --- a/org.adempiere.base/src/org/compiere/model/MProductCategoryAcct.java +++ b/org.adempiere.base/src/org/compiere/model/MProductCategoryAcct.java @@ -19,25 +19,50 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.ImmutablePOCache; /** * Product Category Account Model * @author Jorg Janke * @version $Id: MProductCategoryAcct.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $ */ -public class MProductCategoryAcct extends X_M_Product_Category_Acct +public class MProductCategoryAcct extends X_M_Product_Category_Acct implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 2075372131034904732L; + private static final long serialVersionUID = -7990259665379770596L; /** Static cache */ - private static CCache - s_cache = new CCache(Table_Name, 40, 5); + private static ImmutablePOCache + s_cache = new ImmutablePOCache(Table_Name, 40, 5); /** * Get Category Acct + * @param M_Product_Category_ID category + * @param C_AcctSchema_ID acct schema + * @return category acct + */ + public static MProductCategoryAcct get (int M_Product_Category_ID, int C_AcctSchema_ID) + { + return get(M_Product_Category_ID, C_AcctSchema_ID, (String)null); + } + + /** + * Get Category Acct + * @param M_Product_Category_ID category + * @param C_AcctSchema_ID acct schema + * @param trxName trx + * @return category acct + */ + public static MProductCategoryAcct get (int M_Product_Category_ID, int C_AcctSchema_ID, String trxName) + { + return get(Env.getCtx(), M_Product_Category_ID, C_AcctSchema_ID, trxName); + } + + /** + * Get Category Acct from cache (immutable) * @param ctx context * @param M_Product_Category_ID category * @param C_AcctSchema_ID acct schema @@ -48,7 +73,7 @@ public class MProductCategoryAcct extends X_M_Product_Category_Acct int M_Product_Category_ID, int C_AcctSchema_ID, String trxName) { String key = M_Product_Category_ID+"#"+C_AcctSchema_ID; - MProductCategoryAcct acct = s_cache.get(key); + MProductCategoryAcct acct = s_cache.get(ctx, key, e -> new MProductCategoryAcct(ctx, e)); if (acct != null) return acct; @@ -58,7 +83,7 @@ public class MProductCategoryAcct extends X_M_Product_Category_Acct .firstOnly(); if (acct != null) { - s_cache.put(key, acct); + s_cache.put(key, acct, e -> new MProductCategoryAcct(Env.getCtx(), e)); } return acct; } // get @@ -87,6 +112,37 @@ public class MProductCategoryAcct extends X_M_Product_Category_Acct super (ctx, rs, trxName); } // MProductCategoryAcct + /** + * + * @param copy + */ + public MProductCategoryAcct(MProductCategoryAcct copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MProductCategoryAcct(Properties ctx, MProductCategoryAcct copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MProductCategoryAcct(Properties ctx, MProductCategoryAcct copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Check Costing Setup */ @@ -110,7 +166,16 @@ public class MProductCategoryAcct extends X_M_Product_Category_Acct checkCosting(); return success; } // afterSave - + + @Override + public MProductCategoryAcct markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + /** * String Representation * @return info diff --git a/org.adempiere.base/src/org/compiere/model/MProductDownload.java b/org.adempiere.base/src/org/compiere/model/MProductDownload.java index 3ab56452dc..e6033aa690 100644 --- a/org.adempiere.base/src/org/compiere/model/MProductDownload.java +++ b/org.adempiere.base/src/org/compiere/model/MProductDownload.java @@ -27,6 +27,8 @@ import java.util.logging.Level; import org.compiere.util.CLogger; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; /** @@ -35,12 +37,12 @@ import org.compiere.util.DB; * @version $Id: MProductDownload.java,v 1.2 2006/07/30 00:51:03 jjanke Exp $ * @author Michael Judd BF [ 2736995 ] - toURL() in java.io.File has been deprecated */ -public class MProductDownload extends X_M_ProductDownload +public class MProductDownload extends X_M_ProductDownload implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -2388247976802030211L; + private static final long serialVersionUID = 6930118119436114158L; /** * Migrate Download URLs (2.5.2c) @@ -133,6 +135,37 @@ public class MProductDownload extends X_M_ProductDownload super (ctx, rs, trxName); } // MProductDownload + /** + * + * @param copy + */ + public MProductDownload(MProductDownload copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MProductDownload(Properties ctx, MProductDownload copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MProductDownload(Properties ctx, MProductDownload copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * String Representation * @return info @@ -258,5 +291,13 @@ public class MProductDownload extends X_M_ProductDownload return in; } // getDownloadStream - + @Override + public MProductDownload markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MProductDownload diff --git a/org.adempiere.base/src/org/compiere/model/MProductPrice.java b/org.adempiere.base/src/org/compiere/model/MProductPrice.java index 1c2d9f610c..c1942ea518 100644 --- a/org.adempiere.base/src/org/compiere/model/MProductPrice.java +++ b/org.adempiere.base/src/org/compiere/model/MProductPrice.java @@ -22,6 +22,8 @@ import java.sql.ResultSet; import java.util.Properties; import org.compiere.util.CLogger; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; /** * Product Price @@ -29,12 +31,12 @@ import org.compiere.util.CLogger; * @author Jorg Janke * @version $Id: MProductPrice.java,v 1.3 2006/07/30 00:51:02 jjanke Exp $ */ -public class MProductPrice extends X_M_ProductPrice +public class MProductPrice extends X_M_ProductPrice implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 9187555438223385521L; + private static final long serialVersionUID = 6052691522260506413L; /** * Get Product Price @@ -129,6 +131,37 @@ public class MProductPrice extends X_M_ProductPrice setPrices (PriceList, PriceStd, PriceLimit); } // MProductPrice + /** + * + * @param copy + */ + public MProductPrice(MProductPrice copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MProductPrice(Properties ctx, MProductPrice copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MProductPrice(Properties ctx, MProductPrice copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Set Prices * @param PriceList list price @@ -156,4 +189,13 @@ public class MProductPrice extends X_M_ProductPrice return sb.toString (); } // toString + @Override + public MProductPrice markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MProductPrice diff --git a/org.adempiere.base/src/org/compiere/model/MProductPricing.java b/org.adempiere.base/src/org/compiere/model/MProductPricing.java index 8d2f75cc17..36756bc3bd 100644 --- a/org.adempiere.base/src/org/compiere/model/MProductPricing.java +++ b/org.adempiere.base/src/org/compiere/model/MProductPricing.java @@ -800,7 +800,7 @@ public class MProductPricing extends AbstractProductPricing if (M_DiscountSchema_ID == 0) return; - MDiscountSchema sd = MDiscountSchema.get(Env.getCtx(), M_DiscountSchema_ID); // not correct + MDiscountSchema sd = MDiscountSchema.get(M_DiscountSchema_ID); // not correct if (sd.get_ID() == 0 || (MDiscountSchema.DISCOUNTTYPE_Breaks.equals(sd.getDiscountType()) && !MDiscountSchema.CUMULATIVELEVEL_Line.equals(sd.getCumulativeLevel()))) return; // diff --git a/org.adempiere.base/src/org/compiere/model/MProjectType.java b/org.adempiere.base/src/org/compiere/model/MProjectType.java index bd0b22cf46..480e27a805 100644 --- a/org.adempiere.base/src/org/compiere/model/MProjectType.java +++ b/org.adempiere.base/src/org/compiere/model/MProjectType.java @@ -24,8 +24,10 @@ import java.util.ArrayList; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Project Type Model @@ -33,16 +35,25 @@ import org.compiere.util.DB; * @author Jorg Janke * @version $Id: MProjectType.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $ */ -public class MProjectType extends X_C_ProjectType +public class MProjectType extends X_C_ProjectType implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -6041540981032251476L; - + private static final long serialVersionUID = 2378841146277294989L; /** - * Get MProjectType from Cache + * Get MProjectType from Cache (immutable) + * @param C_ProjectType_ID id + * @return MProjectType + */ + public static MProjectType get (int C_ProjectType_ID) + { + return get(Env.getCtx(), C_ProjectType_ID); + } + + /** + * Get MProjectType from Cache (immutable) * @param ctx context * @param C_ProjectType_ID id * @return MProjectType @@ -50,18 +61,21 @@ public class MProjectType extends X_C_ProjectType public static MProjectType get (Properties ctx, int C_ProjectType_ID) { Integer key = Integer.valueOf(C_ProjectType_ID); - MProjectType retValue = (MProjectType)s_cache.get (key); + MProjectType retValue = s_cache.get (ctx, key, e -> new MProjectType(ctx, e)); if (retValue != null) return retValue; - retValue = new MProjectType (ctx, C_ProjectType_ID, null); - if (retValue.get_ID() != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MProjectType (ctx, C_ProjectType_ID, (String)null); + if (retValue.get_ID() == C_ProjectType_ID) + { + s_cache.put (key, retValue, e -> new MProjectType(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private static CCache s_cache - = new CCache (Table_Name, 20); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache (Table_Name, 20); /************************************************************************** @@ -93,6 +107,37 @@ public class MProjectType extends X_C_ProjectType super(ctx, rs, trxName); } // MProjectType + /** + * + * @param copy + */ + public MProjectType(MProjectType copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MProjectType(Properties ctx, MProjectType copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MProjectType(Properties ctx, MProjectType copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * String Representation * @return info @@ -309,4 +354,13 @@ public class MProjectType extends X_C_ProjectType return query; } // getQuery + @Override + public MProjectType markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MProjectType diff --git a/org.adempiere.base/src/org/compiere/model/MRMALine.java b/org.adempiere.base/src/org/compiere/model/MRMALine.java index 6383ac176b..8cc25e3106 100644 --- a/org.adempiere.base/src/org/compiere/model/MRMALine.java +++ b/org.adempiere.base/src/org/compiere/model/MRMALine.java @@ -480,7 +480,7 @@ public class MRMALine extends X_M_RMALine public MProduct getProduct() { if (m_product == null && getM_Product_ID() != 0) - m_product = MProduct.get (getCtx(), getM_Product_ID()); + m_product = MProduct.getCopy(getCtx(), getM_Product_ID(), get_TrxName()); return m_product; } @@ -491,12 +491,12 @@ public class MRMALine extends X_M_RMALine public MCharge getCharge() { if (m_charge == null && getC_Charge_ID() != 0) - m_charge = MCharge.get (getCtx(), getC_Charge_ID()); + m_charge = MCharge.getCopy(getCtx(), getC_Charge_ID(), get_TrxName()); return m_charge; } /** - * Get Tax + * Get Tax (immutable) * @return tax */ protected MTax getTax() diff --git a/org.adempiere.base/src/org/compiere/model/MRMATax.java b/org.adempiere.base/src/org/compiere/model/MRMATax.java index d0c698eebf..c0b6ab9958 100644 --- a/org.adempiere.base/src/org/compiere/model/MRMATax.java +++ b/org.adempiere.base/src/org/compiere/model/MRMATax.java @@ -175,7 +175,7 @@ public class MRMATax extends X_M_RMATax } // setPrecision /** - * Get Tax + * Get Tax (immutable) * @return tax */ protected MTax getTax() diff --git a/org.adempiere.base/src/org/compiere/model/MRecentItem.java b/org.adempiere.base/src/org/compiere/model/MRecentItem.java index dea7a16cc6..7b8a0ebb80 100644 --- a/org.adempiere.base/src/org/compiere/model/MRecentItem.java +++ b/org.adempiere.base/src/org/compiere/model/MRecentItem.java @@ -27,11 +27,12 @@ import java.util.logging.Level; import org.adempiere.base.Service; import org.adempiere.base.event.EventManager; import org.adempiere.exceptions.AdempiereException; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Util; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.ImmutablePOCache; import org.idempiere.distributed.IMessageService; import org.idempiere.distributed.ITopic; import org.osgi.service.event.Event; @@ -41,17 +42,17 @@ import org.osgi.service.event.Event; * * @author Carlos Ruiz - GlobalQSS */ -public class MRecentItem extends X_AD_RecentItem +public class MRecentItem extends X_AD_RecentItem implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -311416268128338337L; + private static final long serialVersionUID = -6564296810614189111L; public static final String ON_RECENT_ITEM_CHANGED_TOPIC = "onRecentItemChanged"; /** Recent Item Cache */ - private static CCache s_cache = new CCache(Table_Name, 10); + private static ImmutablePOCache s_cache = new ImmutablePOCache(Table_Name, 10); /** Logger */ private static CLogger s_log = CLogger.getCLogger(MRecentItem.class); @@ -67,13 +68,6 @@ public class MRecentItem extends X_AD_RecentItem public MRecentItem (Properties ctx, int AD_RecentItem_ID, String trxName) { super (ctx, AD_RecentItem_ID, trxName); - if (AD_RecentItem_ID > 0) { - synchronized (MRecentItem.class) { - String key = getCacheKey(AD_RecentItem_ID, ctx); - if (!s_cache.containsKey(key)) - s_cache.put (key, this); - } - } } // MRecentItem private static String getCacheKey(int AD_RecentItem_ID, Properties ctx) { @@ -89,20 +83,42 @@ public class MRecentItem extends X_AD_RecentItem public MRecentItem (Properties ctx, ResultSet rs, String trxName) { super(ctx, rs, trxName); - String key = null; - try { - key = getCacheKey(rs.getInt("AD_RecentItem_ID"), ctx); - } catch (SQLException e) { - throw new AdempiereException(e); - } - synchronized (MRecentItem.class) { - if (key != null && !s_cache.containsKey(key)) - s_cache.put (key, this); - } } // MRecentItem /** - * Get from Cache using ID + * + * @param copy + */ + public MRecentItem(MRecentItem copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MRecentItem(Properties ctx, MRecentItem copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MRecentItem(Properties ctx, MRecentItem copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_label = copy.m_label; + } + + /** + * Get from Cache using ID (immutable) * @param ctx context * @param AD_RecentItem_ID id * @return recent item @@ -110,14 +126,37 @@ public class MRecentItem extends X_AD_RecentItem public static synchronized MRecentItem get (Properties ctx, int AD_RecentItem_ID) { String ii = getCacheKey(AD_RecentItem_ID, ctx); - MRecentItem ri = (MRecentItem)s_cache.get(ii); + MRecentItem ri = s_cache.get(ctx, ii, e -> new MRecentItem(ctx, e)); if (ri == null) + { ri = new MRecentItem (ctx, AD_RecentItem_ID, null); + if (ri.get_ID() == AD_RecentItem_ID) + { + s_cache.put(ii, ri, e -> new MRecentItem(Env.getCtx(), e)); + return ri; + } + return null; + } return ri; } // get /** - * Get Recent Item from Cache using table+recordID + * Get updateable copy of MRecentItem from cache + * @param ctx + * @param AD_RecentItem_ID + * @param trxName + * @return MRecentItem + */ + public static synchronized MRecentItem getCopy(Properties ctx, int AD_RecentItem_ID, String trxName) + { + MRecentItem ri = get(ctx, AD_RecentItem_ID); + if (ri != null) + ri = new MRecentItem(ctx, ri, trxName); + return ri; + } + + /** + * Get Recent Item from Cache using table+recordID (immutable) * @param ctx context * @param AD_Table_ID tableID * @param Record_ID recordID @@ -165,7 +204,7 @@ public class MRecentItem extends X_AD_RecentItem if (retValue != null) { String key = getCacheKey(retValue.getAD_RecentItem_ID(), ctx); - s_cache.put (key, retValue); + s_cache.put (key, retValue, e -> new MRecentItem(Env.getCtx(), e)); } return retValue; } // get @@ -242,7 +281,7 @@ public class MRecentItem extends X_AD_RecentItem int cntri = DB.getSQLValue(null, "SELECT COUNT(*) FROM AD_RecentItem WHERE NVL(AD_User_ID,0)=? AND AD_Client_ID=?", AD_User_ID, AD_Client_ID); if (cntri > maxri) { int cntdel = cntri - maxri; - String sql = "SELECT AD_Table_ID, Record_ID FROM AD_RecentItem WHERE NVL(AD_User_ID,0)=? AND AD_Client_ID=? ORDER BY Updated"; + String sql = "SELECT * FROM AD_RecentItem WHERE NVL(AD_User_ID,0)=? AND AD_Client_ID=? ORDER BY Updated"; PreparedStatement pstmt = null; ResultSet rs = null; try @@ -252,9 +291,7 @@ public class MRecentItem extends X_AD_RecentItem pstmt.setInt(2, AD_Client_ID); rs = pstmt.executeQuery (); while (rs.next()) { - int AD_Table_ID = rs.getInt(1); - int Record_ID = rs.getInt(2); - MRecentItem ri = get(ctx, AD_Table_ID, Record_ID, AD_User_ID); + MRecentItem ri = new MRecentItem(ctx, rs, (String)null); ri.deleteEx(true); cntdel--; if (cntdel == 0) @@ -311,7 +348,10 @@ public class MRecentItem extends X_AD_RecentItem PO po = table.getPO(getRecord_ID(), null); if (po == null) { /* Recent Item was deleted (probably with direct SQL DELETE) */ - this.deleteEx(true, null); + if (is_Immutable()) + new MRecentItem(Env.getCtx(), this).deleteEx(true); + else + this.deleteEx(true, null); return null; } @@ -357,6 +397,15 @@ public class MRecentItem extends X_AD_RecentItem m_label = null; } + @Override + public MRecentItem markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + @Override public String toString() { StringBuilder sb = new StringBuilder("MRecentItem[").append(get_ID()).append("]=").append(getLabel()); diff --git a/org.adempiere.base/src/org/compiere/model/MRefTable.java b/org.adempiere.base/src/org/compiere/model/MRefTable.java index 595c8c80cb..74a5cb1957 100644 --- a/org.adempiere.base/src/org/compiere/model/MRefTable.java +++ b/org.adempiere.base/src/org/compiere/model/MRefTable.java @@ -19,15 +19,17 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; -public class MRefTable extends X_AD_Ref_Table +public class MRefTable extends X_AD_Ref_Table implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -3595900192339578282L; + private static final long serialVersionUID = 5068032076487795624L; /** * Standard Constructor @@ -59,22 +61,69 @@ public class MRefTable extends X_AD_Ref_Table super (ctx, rs, trxName); } // MRefTable + /** + * + * @param copy + */ + public MRefTable(MRefTable copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MRefTable(Properties ctx, MRefTable copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MRefTable(Properties ctx, MRefTable copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + @Override public I_AD_Table getAD_Table() throws RuntimeException { - MTable table = MTable.get(getCtx(), getAD_Table_ID(), get_TrxName()); + MTable table = MTable.getCopy(getCtx(), getAD_Table_ID(), get_TrxName()); return table; } /** Ref Table Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); + /** + * Get from Cache + * @param AD_Reference_ID id + * @return category + */ + public static MRefTable get (int AD_Reference_ID) + { + return get(Env.getCtx(), AD_Reference_ID); + } + + /** + * Get from Cache (immutable) + * @param ctx context + * @param AD_Reference_ID id + * @return category + */ public static MRefTable get (Properties ctx, int AD_Reference_ID) { return get (ctx, AD_Reference_ID, null); } /** - * Get from Cache + * Get from Cache (immutable) * @param ctx context * @param AD_Reference_ID id * @param trxName trx @@ -83,15 +132,26 @@ public class MRefTable extends X_AD_Ref_Table public static MRefTable get (Properties ctx, int AD_Reference_ID, String trxName) { Integer ii = Integer.valueOf(AD_Reference_ID); - MRefTable retValue = (MRefTable)s_cache.get(ii); + MRefTable retValue = s_cache.get(ctx, ii, e -> new MRefTable(ctx, e)); if (retValue != null) { - retValue.set_TrxName(trxName); return retValue; } retValue = new MRefTable (ctx, AD_Reference_ID, trxName); - if (retValue.get_ID () != 0) - s_cache.put (AD_Reference_ID, retValue); - return retValue; + if (retValue.get_ID () == AD_Reference_ID) + { + s_cache.put (AD_Reference_ID, retValue, e -> new MRefTable(Env.getCtx(), e)); + return retValue; + } + return null; } // get + @Override + public MRefTable markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MRefTable diff --git a/org.adempiere.base/src/org/compiere/model/MReference.java b/org.adempiere.base/src/org/compiere/model/MReference.java index 369a135cdd..9d98fb55df 100644 --- a/org.adempiere.base/src/org/compiere/model/MReference.java +++ b/org.adempiere.base/src/org/compiere/model/MReference.java @@ -27,13 +27,15 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; -public class MReference extends X_AD_Reference { +public class MReference extends X_AD_Reference implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 343092563490562893L; + private static final long serialVersionUID = -2722869411041069805L; /** * Standard Constructor @@ -58,16 +60,60 @@ public class MReference extends X_AD_Reference { super (ctx, rs, trxName); } // MReference - /** Reference Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + /** + * + * @param copy + */ + public MReference(MReference copy) { + this(Env.getCtx(), copy); + } + /** + * + * @param ctx + * @param copy + */ + public MReference(Properties ctx, MReference copy) { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MReference(Properties ctx, MReference copy, String trxName) { + this(ctx, 0, trxName); + copyPO(copy); + } + + /** Reference Cache */ + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); + + /** + * Get from Cache + * @param AD_Reference_ID id + * @return category + */ + public static MReference get (int AD_Reference_ID) + { + return get(Env.getCtx(), AD_Reference_ID); + } + + /** + * Get from Cache (immutable) + * @param ctx context + * @param AD_Reference_ID id + * @return category + */ public static MReference get (Properties ctx, int AD_Reference_ID) { return get(ctx, AD_Reference_ID, null); } /** - * Get from Cache + * Get from Cache (immutable) * @param ctx context * @param AD_Reference_ID id * @param trxName trx @@ -76,15 +122,26 @@ public class MReference extends X_AD_Reference { public static MReference get (Properties ctx, int AD_Reference_ID, String trxName) { Integer ii = Integer.valueOf(AD_Reference_ID); - MReference retValue = (MReference)s_cache.get(ii); + MReference retValue = s_cache.get(ctx, ii, e -> new MReference(ctx, e)); if (retValue != null) { - retValue.set_TrxName(trxName); return retValue; } retValue = new MReference (ctx, AD_Reference_ID, trxName); - if (retValue.get_ID () != 0) - s_cache.put (AD_Reference_ID, retValue); - return retValue; + if (retValue.get_ID () == AD_Reference_ID) + { + s_cache.put (AD_Reference_ID, retValue, e -> new MReference(Env.getCtx(), e)); + return retValue; + } + return null; } // get - + + @Override + public MReference markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MReference diff --git a/org.adempiere.base/src/org/compiere/model/MRegion.java b/org.adempiere.base/src/org/compiere/model/MRegion.java index 55c20ea3bf..9de7a412dc 100644 --- a/org.adempiere.base/src/org/compiere/model/MRegion.java +++ b/org.adempiere.base/src/org/compiere/model/MRegion.java @@ -21,18 +21,18 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.text.Collator; -import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; -import java.util.Iterator; import java.util.Properties; import java.util.logging.Level; import org.compiere.Adempiere; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.ImmutablePOCache; + import static org.compiere.model.SystemIDs.*; /** @@ -42,19 +42,17 @@ import static org.compiere.model.SystemIDs.*; * @version $Id: MRegion.java,v 1.3 2006/07/30 00:58:36 jjanke Exp $ */ public class MRegion extends X_C_Region - implements Comparator, Serializable + implements Comparator, Serializable, ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 1124865777747582617L; - + private static final long serialVersionUID = 5309795002353895615L; /** * Load Regions (cached) - * @param ctx context */ - private static void loadAllRegions (Properties ctx) + private static void loadAllRegions () { s_regions.clear(); String sql = "SELECT * FROM C_Region WHERE IsActive='Y'"; @@ -66,7 +64,8 @@ public class MRegion extends X_C_Region rs = stmt.executeQuery(sql); while(rs.next()) { - MRegion r = new MRegion (ctx, rs, null); + MRegion r = new MRegion (Env.getCtx(), rs, null); + r.markImmutable(); s_regions.put(String.valueOf(r.getC_Region_ID()), r); if (r.isDefault()) s_default = r; @@ -87,22 +86,31 @@ public class MRegion extends X_C_Region /** * Get Country (cached) - * @param ctx context * @param C_Region_ID ID * @return Country */ - public static MRegion get (Properties ctx, int C_Region_ID) + public static synchronized MRegion get (int C_Region_ID) { - if (s_regions == null || s_regions.size() == 0) - loadAllRegions(ctx); + return get(Env.getCtx(), C_Region_ID); + } + + /** + * Get Country (immutable, cached) + * @param C_Region_ID ID + * @return Country + */ + public static synchronized MRegion get (Properties ctx, int C_Region_ID) + { + if (s_regions.size() == 0) + loadAllRegions(); String key = String.valueOf(C_Region_ID); - MRegion r = (MRegion)s_regions.get(key); + MRegion r = s_regions.get(ctx, key, e -> new MRegion(ctx, e)); if (r != null) return r; r = new MRegion (ctx, C_Region_ID, null); if (r.getC_Region_ID() == C_Region_ID) { - s_regions.put(key, r); + s_regions.put(key, r, e -> new MRegion(Env.getCtx(), e)); return r; } return null; @@ -110,58 +118,79 @@ public class MRegion extends X_C_Region /** * Get Default Region - * @param ctx context + * @param ctx ignore + * @return Region or null + * @deprecated + */ + public static synchronized MRegion getDefault (Properties ctx) + { + return getDefault(); + } + + /** + * Get Default Region * @return Region or null */ - public static MRegion getDefault (Properties ctx) + public static synchronized MRegion getDefault () { - if (s_regions == null || s_regions.size() == 0) - loadAllRegions(ctx); + if (s_regions.size() == 0) + loadAllRegions(); return s_default; } // get /** * Return Regions as Array - * @param ctx context + * @param ctx ignore + * @return MCountry Array + * @deprecated + */ + public static synchronized MRegion[] getRegions(Properties ctx) + { + return getRegions(); + } + + /** + * Return Regions as Array * @return MCountry Array */ - public static MRegion[] getRegions(Properties ctx) + public static synchronized MRegion[] getRegions() { - if (s_regions == null || s_regions.size() == 0) - loadAllRegions(ctx); - MRegion[] retValue = new MRegion[s_regions.size()]; - s_regions.values().toArray(retValue); - Arrays.sort(retValue, new MRegion(ctx, 0, null)); + if (s_regions.size() == 0) + loadAllRegions(); + MRegion[] retValue = s_regions.values().stream().toArray(MRegion[]::new); + Arrays.sort(retValue, new MRegion(Env.getCtx(), 0, null)); return retValue; } // getRegions /** * Return Array of Regions of Country - * @param ctx context + * @param ctx ignore + * @param C_Country_ID country + * @return MRegion Array + * @deprecated + */ + public static synchronized MRegion[] getRegions (Properties ctx, int C_Country_ID) + { + return getRegions(C_Country_ID); + } + + /** + * Return Array of Regions of Country * @param C_Country_ID country * @return MRegion Array */ - public static MRegion[] getRegions (Properties ctx, int C_Country_ID) + public static synchronized MRegion[] getRegions (int C_Country_ID) { - if (s_regions == null || s_regions.size() == 0) - loadAllRegions(ctx); - ArrayList list = new ArrayList(); - Iterator it = s_regions.values().iterator(); - while (it.hasNext()) - { - MRegion r = it.next(); - if (r.getC_Country_ID() == C_Country_ID) - list.add(r); - } + if (s_regions.size() == 0) + loadAllRegions(); // Sort it - MRegion[] retValue = new MRegion[list.size()]; - list.toArray(retValue); - Arrays.sort(retValue, new MRegion(ctx, 0, null)); + MRegion[] retValue = s_regions.values().stream().filter(e-> e.getC_Country_ID()==C_Country_ID).toArray(MRegion[]::new); + Arrays.sort(retValue, new MRegion(Env.getCtx(), 0, null)); return retValue; } // getRegions /** Region Cache */ - private static CCache s_regions = new CCache(Table_Name, Table_Name, 100, 0, false, 0); + private static ImmutablePOCache s_regions = new ImmutablePOCache(Table_Name, Table_Name, 100, 0, false, 0); /** Default Region */ private static MRegion s_default = null; /** Static Logger */ @@ -205,6 +234,37 @@ public class MRegion extends X_C_Region setName(regionName); } // MRegion + /** + * + * @param copy + */ + public MRegion(MRegion copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MRegion(Properties ctx, MRegion copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MRegion(Properties ctx, MRegion copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Return Name * @return Name @@ -232,6 +292,15 @@ public class MRegion extends X_C_Region return collator.compare(s1, s2); } // compare + @Override + public MRegion markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + /** * Test / Load * @param args diff --git a/org.adempiere.base/src/org/compiere/model/MRegistrationAttribute.java b/org.adempiere.base/src/org/compiere/model/MRegistrationAttribute.java index 1e17010d66..e2ee33b643 100644 --- a/org.adempiere.base/src/org/compiere/model/MRegistrationAttribute.java +++ b/org.adempiere.base/src/org/compiere/model/MRegistrationAttribute.java @@ -22,10 +22,11 @@ import java.util.ArrayList; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Asset Registration Attribute @@ -33,12 +34,12 @@ import org.compiere.util.Env; * @author Jorg Janke * @version $Id: MRegistrationAttribute.java,v 1.2 2006/07/30 00:51:05 jjanke Exp $ */ -public class MRegistrationAttribute extends X_A_RegistrationAttribute +public class MRegistrationAttribute extends X_A_RegistrationAttribute implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 5306354702182270968L; + private static final long serialVersionUID = -5410660542293211173L; /** * Get All Asset Registration Attributes (not cached). @@ -65,7 +66,7 @@ public class MRegistrationAttribute extends X_A_RegistrationAttribute { MRegistrationAttribute value = new MRegistrationAttribute(ctx, rs, null); Integer key = Integer.valueOf(value.getA_RegistrationAttribute_ID()); - s_cache.put(key, value); + s_cache.put(key, value, e -> new MRegistrationAttribute(Env.getCtx(), e)); list.add(value); } } @@ -87,27 +88,69 @@ public class MRegistrationAttribute extends X_A_RegistrationAttribute /** * Get Registration Attribute (cached) + * @param A_RegistrationAttribute_ID id + * @return Registration Attribute + */ + public static MRegistrationAttribute get (int A_RegistrationAttribute_ID) + { + return get(A_RegistrationAttribute_ID, (String)null); + } + + /** + * Get Registration Attribute (cached) (immutable) + * @param A_RegistrationAttribute_ID id + * @param trxName + * @return Registration Attribute + */ + public static MRegistrationAttribute get (int A_RegistrationAttribute_ID, String trxName) + { + return get(Env.getCtx(), A_RegistrationAttribute_ID, trxName); + } + + /** + * Get Registration Attribute (cached) (immutable) * @param ctx context * @param A_RegistrationAttribute_ID id + * @param trxName * @return Registration Attribute */ public static MRegistrationAttribute get (Properties ctx, int A_RegistrationAttribute_ID, String trxName) { Integer key = Integer.valueOf(A_RegistrationAttribute_ID); - MRegistrationAttribute retValue = (MRegistrationAttribute)s_cache.get(key); + MRegistrationAttribute retValue = s_cache.get(ctx, key, e -> new MRegistrationAttribute(ctx, e, trxName)); if (retValue == null) { retValue = new MRegistrationAttribute (ctx, A_RegistrationAttribute_ID, trxName); - s_cache.put(key, retValue); + if (retValue.get_ID() == A_RegistrationAttribute_ID) + { + s_cache.put(key, retValue, e -> new MRegistrationAttribute(Env.getCtx(), e)); + return retValue; + } + return null; } return retValue; - } // getAll + } // get + /** + * Get updateable copy of MRegistrationAttribute from cache + * @param ctx + * @param A_RegistrationAttribute_ID + * @param trxName + * @return MRegistrationAttribute + */ + public static MRegistrationAttribute getCopy(Properties ctx, int A_RegistrationAttribute_ID, String trxName) + { + MRegistrationAttribute ra = get(ctx, A_RegistrationAttribute_ID, trxName); + if (ra != null) + ra = new MRegistrationAttribute(ctx, ra, trxName); + return ra; + } + /** Static Logger */ private static CLogger s_log = CLogger.getCLogger(MRegistrationAttribute.class); /** Cache */ - private static CCache s_cache - = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache(Table_Name, 20); /************************************************************************** * Standard Constructor @@ -129,4 +172,44 @@ public class MRegistrationAttribute extends X_A_RegistrationAttribute super(ctx, rs, trxName); } // MRegistrationAttribute + /** + * + * @param copy + */ + public MRegistrationAttribute(MRegistrationAttribute copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MRegistrationAttribute(Properties ctx, MRegistrationAttribute copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MRegistrationAttribute(Properties ctx, MRegistrationAttribute copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + @Override + public MRegistrationAttribute markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MRegistrationAttribute diff --git a/org.adempiere.base/src/org/compiere/model/MRegistrationValue.java b/org.adempiere.base/src/org/compiere/model/MRegistrationValue.java index edd92f67ff..6dae776fd3 100644 --- a/org.adempiere.base/src/org/compiere/model/MRegistrationValue.java +++ b/org.adempiere.base/src/org/compiere/model/MRegistrationValue.java @@ -88,7 +88,7 @@ public class MRegistrationValue extends X_A_RegistrationValue if (m_registrationAttribute == null) { int A_RegistrationAttribute_ID = getA_RegistrationAttribute_ID(); - MRegistrationAttribute att = MRegistrationAttribute.get (getCtx(), A_RegistrationAttribute_ID, get_TrxName()); + MRegistrationAttribute att = MRegistrationAttribute.getCopy(getCtx(), A_RegistrationAttribute_ID, get_TrxName()); m_registrationAttribute = att.getName(); m_registrationAttributeDescription = att.getDescription(); m_seqNo = att.getSeqNo(); diff --git a/org.adempiere.base/src/org/compiere/model/MReportView.java b/org.adempiere.base/src/org/compiere/model/MReportView.java index a6dd44b06d..d4ab50aaa8 100644 --- a/org.adempiere.base/src/org/compiere/model/MReportView.java +++ b/org.adempiere.base/src/org/compiere/model/MReportView.java @@ -18,19 +18,20 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; - -public class MReportView extends X_AD_ReportView { +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; +public class MReportView extends X_AD_ReportView implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -5674822764517548357L; + private static final long serialVersionUID = 6065574433744333005L; /** Static Logger */ //private static CLogger s_log = CLogger.getCLogger (MReportView.class); /** Cache */ - static private CCache s_cache = new CCache(Table_Name, 30, 60); + static private ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 30, 60); public MReportView(Properties ctx, int AD_ReportView_ID, String trxName) { @@ -43,9 +44,46 @@ public class MReportView extends X_AD_ReportView { /** * + * @param copy + */ + public MReportView(MReportView copy) { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MReportView(Properties ctx, MReportView copy) { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MReportView(Properties ctx, MReportView copy, String trxName) { + this(ctx, 0, trxName); + copyPO(copy); + } + + /** + * Get MReportView from cache (immutable) + * @param AD_ReportView_ID + * @return MReportView + */ + public static MReportView get (int AD_ReportView_ID) { + return get(Env.getCtx(), AD_ReportView_ID); + } + + /** + * Get MReportView from cache (immutable) * @param ctx * @param AD_ReportView_ID - * @return + * @return MReportView */ public static MReportView get (Properties ctx, int AD_ReportView_ID) { if(AD_ReportView_ID==0) { @@ -53,12 +91,27 @@ public class MReportView extends X_AD_ReportView { } Integer key = Integer.valueOf(AD_ReportView_ID); - MReportView retValue = (MReportView)s_cache.get(key); + MReportView retValue = s_cache.get(ctx, key, e -> new MReportView(ctx, e)); if (retValue == null) { - retValue = new MReportView (ctx, AD_ReportView_ID, null); - s_cache.put(key, retValue); + retValue = new MReportView (ctx, AD_ReportView_ID, (String)null); + if (retValue.get_ID() == AD_ReportView_ID) + { + s_cache.put(key, retValue, e -> new MReportView(Env.getCtx(), e)); + return retValue; + } + return null; } return retValue; } // get + + @Override + public MReportView markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } diff --git a/org.adempiere.base/src/org/compiere/model/MRequest.java b/org.adempiere.base/src/org/compiere/model/MRequest.java index 5dcfc70c7c..cef7ac0eca 100644 --- a/org.adempiere.base/src/org/compiere/model/MRequest.java +++ b/org.adempiere.base/src/org/compiere/model/MRequest.java @@ -317,7 +317,7 @@ public class MRequest extends X_R_Request setR_RequestType_ID(); R_RequestType_ID = getR_RequestType_ID(); } - m_requestType = MRequestType.get (getCtx(), R_RequestType_ID); + m_requestType = MRequestType.getCopy(getCtx(), R_RequestType_ID, get_TrxName()); } return m_requestType; } // getRequestType @@ -344,7 +344,7 @@ public class MRequest extends X_R_Request { if (getR_Category_ID() == 0) return null; - return MRequestCategory.get(getCtx(), getR_Category_ID()); + return MRequestCategory.getCopy(getCtx(), getR_Category_ID(), get_TrxName()); } // getCategory /** @@ -367,7 +367,7 @@ public class MRequest extends X_R_Request { if (getR_Group_ID() == 0) return null; - return MGroup.get(getCtx(), getR_Group_ID()); + return MGroup.getCopy(getCtx(), getR_Group_ID(), get_TrxName()); } // getGroup /** @@ -390,7 +390,7 @@ public class MRequest extends X_R_Request { if (getR_Status_ID() == 0) return null; - return MStatus.get(getCtx(), getR_Status_ID()); + return MStatus.getCopy(getCtx(), getR_Status_ID(), get_TrxName()); } // getStatus /** @@ -413,7 +413,7 @@ public class MRequest extends X_R_Request { if (getR_Resolution_ID() == 0) return null; - return MResolution.get(getCtx(), getR_Resolution_ID()); + return MResolution.getCopy(getCtx(), getR_Resolution_ID(), get_TrxName()); } // getResolution /** @@ -507,7 +507,7 @@ public class MRequest extends X_R_Request { if (getSalesRep_ID() == 0) return null; - return MUser.get(getCtx(), getSalesRep_ID()); + return MUser.getCopy(getCtx(), getSalesRep_ID(), get_TrxName()); } // getSalesRep /** diff --git a/org.adempiere.base/src/org/compiere/model/MRequestCategory.java b/org.adempiere.base/src/org/compiere/model/MRequestCategory.java index 0674802345..1bdb911502 100644 --- a/org.adempiere.base/src/org/compiere/model/MRequestCategory.java +++ b/org.adempiere.base/src/org/compiere/model/MRequestCategory.java @@ -19,23 +19,34 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Request Category Model * @author Jorg Janke * @version $Id: MRequestCategory.java,v 1.2 2006/07/30 00:51:05 jjanke Exp $ */ -public class MRequestCategory extends X_R_Category +public class MRequestCategory extends X_R_Category implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 9174605980194362716L; - + private static final long serialVersionUID = 984010124643923205L; /** - * Get MCategory from Cache + * Get MCategory from Cache (immutable) + * @param R_Category_ID id + * @return MCategory + */ + public static MRequestCategory get (int R_Category_ID) + { + return get(Env.getCtx(), R_Category_ID); + } + + /** + * Get MCategory from Cache (immutable) * @param ctx context * @param R_Category_ID id * @return MCategory @@ -43,18 +54,36 @@ public class MRequestCategory extends X_R_Category public static MRequestCategory get (Properties ctx, int R_Category_ID) { Integer key = Integer.valueOf(R_Category_ID); - MRequestCategory retValue = (MRequestCategory) s_cache.get (key); + MRequestCategory retValue = s_cache.get (ctx, key, e -> new MRequestCategory(ctx, e)); if (retValue != null) return retValue; - retValue = new MRequestCategory (ctx, R_Category_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MRequestCategory (ctx, R_Category_ID, (String)null); + if (retValue.get_ID () == R_Category_ID) + { + s_cache.put (key, retValue, e -> new MRequestCategory(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MRequestCategory from cache + * @param ctx + * @param R_Category_ID + * @param trxName + * @return MRequestCategory + */ + public static MRequestCategory getCopy(Properties ctx, int R_Category_ID, String trxName) + { + MRequestCategory rc = get(R_Category_ID); + if (rc != null) + rc = new MRequestCategory(ctx, rc, trxName); + return rc; + } + /** Cache */ - private static CCache s_cache - = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache(Table_Name, 20); /************************************************************************** @@ -79,4 +108,44 @@ public class MRequestCategory extends X_R_Category super (ctx, rs, trxName); } // MCategory + /** + * + * @param copy + */ + public MRequestCategory(MRequestCategory copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MRequestCategory(Properties ctx, MRequestCategory copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MRequestCategory(Properties ctx, MRequestCategory copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + @Override + public MRequestCategory markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MCategory diff --git a/org.adempiere.base/src/org/compiere/model/MRequestType.java b/org.adempiere.base/src/org/compiere/model/MRequestType.java index eeffc85566..11a2cfef6a 100644 --- a/org.adempiere.base/src/org/compiere/model/MRequestType.java +++ b/org.adempiere.base/src/org/compiere/model/MRequestType.java @@ -23,10 +23,11 @@ import java.util.ArrayList; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Request Type Model @@ -36,16 +37,25 @@ import org.compiere.util.Env; * * Teo Sarca - bug fix [ 1642833 ] MRequestType minor typo bug */ -public class MRequestType extends X_R_RequestType +public class MRequestType extends X_R_RequestType implements ImmutablePOSupport { - /** - * - */ - private static final long serialVersionUID = 6235793036503665638L; + * + */ + private static final long serialVersionUID = -1772516764599702671L; /** - * Get Request Type (cached) + * Get Request Type (cached) (immutable) + * @param R_RequestType_ID id + * @return Request Type + */ + public static MRequestType get (int R_RequestType_ID) + { + return get(Env.getCtx(), R_RequestType_ID); + } + + /** + * Get Request Type (cached) (immutable) * @param ctx context * @param R_RequestType_ID id * @return Request Type @@ -53,20 +63,40 @@ public class MRequestType extends X_R_RequestType public static MRequestType get (Properties ctx, int R_RequestType_ID) { Integer key = Integer.valueOf(R_RequestType_ID); - MRequestType retValue = (MRequestType)s_cache.get(key); + MRequestType retValue = s_cache.get(ctx, key, e -> new MRequestType(ctx, e)); if (retValue == null) { retValue = new MRequestType (ctx, R_RequestType_ID, null); - s_cache.put(key, retValue); + if (retValue.get_ID() == R_RequestType_ID) + { + s_cache.put(key, retValue, e -> new MRequestType(Env.getCtx(), e)); + return retValue; + } + return null; } return retValue; } // get + /** + * Get updateable copy of MRequestType from cache + * @param ctx + * @param R_RequestType_ID + * @param trxName + * @return MRequestType + */ + public static MRequestType getCopy(Properties ctx, int R_RequestType_ID, String trxName) + { + MRequestType rt = get(R_RequestType_ID); + if (rt != null) + rt = new MRequestType(ctx, rt, trxName); + return rt; + } + /** Static Logger */ @SuppressWarnings("unused") private static CLogger s_log = CLogger.getCLogger(MRequestType.class); /** Cache */ - static private CCache s_cache = new CCache(Table_Name, 10); + static private ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 10); /** * Get Default Request Type @@ -128,6 +158,37 @@ public class MRequestType extends X_R_RequestType super(ctx, rs, trxName); } // MRequestType + /** + * + * @param copy + */ + public MRequestType(MRequestType copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MRequestType(Properties ctx, MRequestType copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MRequestType(Properties ctx, MRequestType copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** Next time stats to be created */ private long m_nextStats = 0; @@ -497,5 +558,14 @@ public class MRequestType extends X_R_RequestType query.setRecordCount(1); return query; } // getQuery - + + @Override + public MRequestType markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MRequestType diff --git a/org.adempiere.base/src/org/compiere/model/MRequisitionLine.java b/org.adempiere.base/src/org/compiere/model/MRequisitionLine.java index b34eb87010..4240c8d421 100644 --- a/org.adempiere.base/src/org/compiere/model/MRequisitionLine.java +++ b/org.adempiere.base/src/org/compiere/model/MRequisitionLine.java @@ -327,7 +327,7 @@ public class MRequisitionLine extends X_M_RequisitionLine @Override public I_M_Product getM_Product() { - return MProduct.get(getCtx(), getM_Product_ID()); + return MProduct.getCopy(getCtx(), getM_Product_ID(), get_TrxName()); } /** diff --git a/org.adempiere.base/src/org/compiere/model/MResolution.java b/org.adempiere.base/src/org/compiere/model/MResolution.java index ec8ec38a8a..36bb78fd18 100644 --- a/org.adempiere.base/src/org/compiere/model/MResolution.java +++ b/org.adempiere.base/src/org/compiere/model/MResolution.java @@ -19,24 +19,34 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Request Resolution Model * @author Jorg Janke * @version $Id: MResolution.java,v 1.2 2006/07/30 00:51:03 jjanke Exp $ */ -public class MResolution extends X_R_Resolution +public class MResolution extends X_R_Resolution implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 9163046533055602877L; - - + private static final long serialVersionUID = 7430644542278601152L; /** - * Get MResolution from Cache + * Get MResolution from Cache (immutable) + * @param R_Resolution_ID id + * @return MResolution + */ + public static MResolution get (int R_Resolution_ID) + { + return get(Env.getCtx(), R_Resolution_ID); + } + + /** + * Get MResolution from Cache (immutable) * @param ctx context * @param R_Resolution_ID id * @return MResolution @@ -44,17 +54,35 @@ public class MResolution extends X_R_Resolution public static MResolution get (Properties ctx, int R_Resolution_ID) { Integer key = Integer.valueOf(R_Resolution_ID); - MResolution retValue = (MResolution) s_cache.get (key); + MResolution retValue = s_cache.get (ctx, key, e -> new MResolution(ctx, e)); if (retValue != null) return retValue; - retValue = new MResolution (ctx, R_Resolution_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MResolution (ctx, R_Resolution_ID, (String)null); + if (retValue.get_ID () == R_Resolution_ID) + { + s_cache.put (key, retValue, e -> new MResolution(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MResolution from cache + * @param ctx + * @param R_Resolution_ID + * @param trxName + * @return MResolution + */ + public static MResolution getCopy(Properties ctx, int R_Resolution_ID, String trxName) + { + MResolution resolution = get(R_Resolution_ID); + if (resolution != null) + resolution = new MResolution(ctx, resolution, trxName); + return resolution; + } + /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 10); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 10); @@ -80,4 +108,44 @@ public class MResolution extends X_R_Resolution super (ctx, rs, trxName); } // MResolution + /** + * + * @param copy + */ + public MResolution(MResolution copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MResolution(Properties ctx, MResolution copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MResolution(Properties ctx, MResolution copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + @Override + public MResolution markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MResolution diff --git a/org.adempiere.base/src/org/compiere/model/MResource.java b/org.adempiere.base/src/org/compiere/model/MResource.java index 51f54971f3..adf57ff6e5 100644 --- a/org.adempiere.base/src/org/compiere/model/MResource.java +++ b/org.adempiere.base/src/org/compiere/model/MResource.java @@ -20,7 +20,9 @@ import java.sql.ResultSet; import java.util.Properties; import org.adempiere.exceptions.AdempiereException; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** @@ -35,17 +37,27 @@ import org.compiere.util.CCache; *
  • BF [ 2824795 ] Deleting Resource product should be forbidden * https://sourceforge.net/tracker/?func=detail&aid=2824795&group_id=176962&atid=879332 */ -public class MResource extends X_S_Resource +public class MResource extends X_S_Resource implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 6799272062821593975L; + private static final long serialVersionUID = -6893347336885257619L; /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** - * Get from Cache + * Get from Cache (immutable) + * @param S_Resource_ID + * @return MResource + */ + public static MResource get(int S_Resource_ID) + { + return get(Env.getCtx(), S_Resource_ID); + } + + /** + * Get from Cache (immutable) * @param ctx * @param S_Resource_ID * @return MResource @@ -54,16 +66,33 @@ public class MResource extends X_S_Resource { if (S_Resource_ID <= 0) return null; - MResource r = s_cache.get(S_Resource_ID); + MResource r = s_cache.get(ctx, S_Resource_ID, e -> new MResource(ctx, e)); if (r == null) { - r = new MResource(ctx, S_Resource_ID, null); + r = new MResource(ctx, S_Resource_ID, (String)null); if (r.get_ID() == S_Resource_ID) { - s_cache.put(S_Resource_ID, r); + s_cache.put(S_Resource_ID, r, e -> new MResource(Env.getCtx(), e)); + return r; } + return null; } return r; } + /** + * Get updateable copy of MResource from cache + * @param ctx + * @param S_Resource_ID + * @param trxName + * @return MResource + */ + public static MResource getCopy(Properties ctx, int S_Resource_ID, String trxName) + { + MResource rs = get(S_Resource_ID); + if (rs != null) + rs = new MResource(ctx, rs, trxName); + return rs; + } + /** * Standard Constructor * @param ctx context @@ -84,6 +113,38 @@ public class MResource extends X_S_Resource super(ctx, rs, trxName); } // MResource + /** + * + * @param copy + */ + public MResource(MResource copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MResource(Properties ctx, MResource copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MResource(Properties ctx, MResource copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_resourceType = copy.m_resourceType != null ? new MResourceType(ctx, copy.m_resourceType, trxName) : null; + this.m_product = copy.m_product != null ? new MProduct(ctx, copy.m_product, trxName) : null; + } /** Cached Resource Type */ private MResourceType m_resourceType = null; @@ -97,12 +158,11 @@ public class MResource extends X_S_Resource */ public MResourceType getResourceType() { - // Use cache if we are outside transaction: - if (get_TrxName() == null && getS_ResourceType_ID() > 0) - return MResourceType.get(getCtx(), getS_ResourceType_ID()); - // if (m_resourceType == null && getS_ResourceType_ID() != 0) { - m_resourceType = new MResourceType (getCtx(), getS_ResourceType_ID(), get_TrxName()); + if (is_Immutable()) + m_resourceType = MResourceType.get(getCtx(), getS_ResourceType_ID()); + else + m_resourceType = MResourceType.getCopy(getCtx(), getS_ResourceType_ID(), get_TrxName()); } return m_resourceType; } // getResourceType @@ -116,8 +176,10 @@ public class MResource extends X_S_Resource if (m_product == null) { m_product = MProduct.forS_Resource_ID(getCtx(), getS_Resource_ID(), get_TrxName()); + if (!is_Immutable() && m_product != null) + m_product = new MProduct(getCtx(), m_product, get_TrxName()); } - else + else if (!is_Immutable()) { m_product.set_TrxName(get_TrxName()); } @@ -176,6 +238,20 @@ public class MResource extends X_S_Resource return true; } + @Override + public MResource markImmutable() + { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_product != null) + m_product.markImmutable(); + if (m_resourceType != null) + m_resourceType.markImmutable(); + return this; + } + @Override public String toString() { diff --git a/org.adempiere.base/src/org/compiere/model/MResourceType.java b/org.adempiere.base/src/org/compiere/model/MResourceType.java index 3a938ca2c3..40640d32e9 100644 --- a/org.adempiere.base/src/org/compiere/model/MResourceType.java +++ b/org.adempiere.base/src/org/compiere/model/MResourceType.java @@ -25,8 +25,10 @@ import java.util.Properties; import org.adempiere.exceptions.AdempiereException; import org.adempiere.exceptions.FillMandatoryException; -import org.compiere.util.CCache; +import org.compiere.util.Env; import org.compiere.util.TimeUtil; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** @@ -40,17 +42,27 @@ import org.compiere.util.TimeUtil; *
  • added manufacturing related methods (getDayStart, getDayEnd etc) *
  • BF [ 2431049 ] If Time Slot then Time Slot Start/End should be mandatory */ -public class MResourceType extends X_S_ResourceType +public class MResourceType extends X_S_ResourceType implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 6303797933825680667L; + private static final long serialVersionUID = 1738229111191830237L; /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** - * Get from Cache + * Get from Cache (immutable) + * @param S_ResourceType_ID + * @return MResourceType + */ + public static MResourceType get(int S_ResourceType_ID) + { + return get(Env.getCtx(), S_ResourceType_ID); + } + + /** + * Get from Cache (immutable) * @param ctx * @param S_ResourceType_ID * @return MResourceType @@ -60,16 +72,33 @@ public class MResourceType extends X_S_ResourceType if (S_ResourceType_ID <= 0) return null; - MResourceType type = s_cache.get(S_ResourceType_ID); + MResourceType type = s_cache.get(ctx, S_ResourceType_ID, e -> new MResourceType(ctx, e)); if (type == null) { - type = new MResourceType(ctx, S_ResourceType_ID, null); + type = new MResourceType(ctx, S_ResourceType_ID, (String)null); if (type.get_ID() == S_ResourceType_ID) { - s_cache.put(S_ResourceType_ID, type); + s_cache.put(S_ResourceType_ID, type, e -> new MResourceType(Env.getCtx(), e)); + return type; } + return null; } return type; } + /** + * Get updateable copy of MResourceType from cache + * @param ctx + * @param S_ResourceType_ID + * @param trxName + * @return MResourceType + */ + public static MResourceType getCopy(Properties ctx, int S_ResourceType_ID, String trxName) + { + MResourceType rt = get(S_ResourceType_ID); + if (rt != null) + rt = new MResourceType(ctx, rt, trxName); + return rt; + } + /** * Standard Constructor * @param ctx context @@ -90,6 +119,37 @@ public class MResourceType extends X_S_ResourceType super(ctx, rs, trxName); } // MResourceType + /** + * + * @param copy + */ + public MResourceType(MResourceType copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MResourceType(Properties ctx, MResourceType copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MResourceType(Properties ctx, MResourceType copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + @Override protected boolean beforeSave(boolean newRecord) { @@ -309,4 +369,14 @@ public class MResourceType extends X_S_ResourceType } return sb.append("]").toString(); } + + @Override + public MResourceType markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MResourceType diff --git a/org.adempiere.base/src/org/compiere/model/MRfQ.java b/org.adempiere.base/src/org/compiere/model/MRfQ.java index 1a6385c80a..57425bffe7 100644 --- a/org.adempiere.base/src/org/compiere/model/MRfQ.java +++ b/org.adempiere.base/src/org/compiere/model/MRfQ.java @@ -23,8 +23,8 @@ import java.util.ArrayList; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.DB; +import org.compiere.util.Env; import org.compiere.util.TimeUtil; /** @@ -38,11 +38,31 @@ public class MRfQ extends X_C_RfQ /** * */ - private static final long serialVersionUID = -8318627400543638950L; - + private static final long serialVersionUID = 5332116213254863257L; /** - * Get MRfQ from Cache + * Get MRfQ from Cache (immutable) + * @param C_RfQ_ID id + * @return MRfQ + */ + public static MRfQ get (int C_RfQ_ID) + { + return get(C_RfQ_ID, (String)null); + } + + /** + * Get MRfQ from db + * @param C_RfQ_ID id + * @param trxName transaction + * @return MRfQ + */ + public static MRfQ get (int C_RfQ_ID, String trxName) + { + return get(Env.getCtx(), C_RfQ_ID, trxName); + } + + /** + * Get MRfQ from db * @param ctx context * @param C_RfQ_ID id * @param trxName transaction @@ -50,20 +70,14 @@ public class MRfQ extends X_C_RfQ */ public static MRfQ get (Properties ctx, int C_RfQ_ID, String trxName) { - Integer key = Integer.valueOf(C_RfQ_ID); - MRfQ retValue = (MRfQ) s_cache.get (key); - if (retValue != null) + MRfQ retValue = new MRfQ (ctx, C_RfQ_ID, trxName); + if (retValue.get_ID () == C_RfQ_ID) + { return retValue; - retValue = new MRfQ (ctx, C_RfQ_ID, trxName); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + } + return null; } // get - /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 10); - - /** * Standard Constructor * @param ctx context @@ -103,6 +117,37 @@ public class MRfQ extends X_C_RfQ super(ctx, rs, trxName); } // MRfQ + /** + * + * @param copy + */ + public MRfQ(MRfQ copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MRfQ(Properties ctx, MRfQ copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MRfQ(Properties ctx, MRfQ copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Get active Lines * @return array of lines diff --git a/org.adempiere.base/src/org/compiere/model/MRfQLine.java b/org.adempiere.base/src/org/compiere/model/MRfQLine.java index 6508d90540..e5321bb984 100644 --- a/org.adempiere.base/src/org/compiere/model/MRfQLine.java +++ b/org.adempiere.base/src/org/compiere/model/MRfQLine.java @@ -19,11 +19,12 @@ package org.compiere.model; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; +import java.util.Arrays; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.DB; +import org.compiere.util.Env; import org.compiere.util.TimeUtil; /** @@ -37,10 +38,31 @@ public class MRfQLine extends X_C_RfQLine /** * */ - private static final long serialVersionUID = 5090299865266992874L; + private static final long serialVersionUID = -387372215148731148L; /** - * Get MRfQLine from Cache + * Get MRfQLine from db + * @param C_RfQLine_ID id + * @return MRfQLine + */ + public static MRfQLine get (int C_RfQLine_ID) + { + return get(C_RfQLine_ID, (String)null); + } + + /** + * Get MRfQLine from db + * @param C_RfQLine_ID id + * @param trxName transaction + * @return MRfQLine + */ + public static MRfQLine get (int C_RfQLine_ID, String trxName) + { + return get(Env.getCtx(), C_RfQLine_ID, trxName); + } + + /** + * Get MRfQLine from db * @param ctx context * @param C_RfQLine_ID id * @param trxName transaction @@ -48,19 +70,14 @@ public class MRfQLine extends X_C_RfQLine */ public static MRfQLine get (Properties ctx, int C_RfQLine_ID, String trxName) { - Integer key = Integer.valueOf(C_RfQLine_ID); - MRfQLine retValue = (MRfQLine) s_cache.get (key); - if (retValue != null) + MRfQLine retValue = new MRfQLine (ctx, C_RfQLine_ID, trxName); + if (retValue.get_ID () == C_RfQLine_ID) + { return retValue; - retValue = new MRfQLine (ctx, C_RfQLine_ID, trxName); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + } + return null; } // get - /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); - /** * Standard Constructor * @param ctx context @@ -98,6 +115,38 @@ public class MRfQLine extends X_C_RfQLine setC_RfQ_ID(rfq.getC_RfQ_ID()); } // MRfQLine + /** + * + * @param copy + */ + public MRfQLine(MRfQLine copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MRfQLine(Properties ctx, MRfQLine copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MRfQLine(Properties ctx, MRfQLine copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_qtys = copy.m_qtys != null ? Arrays.stream(copy.m_qtys).map(e -> {return new MRfQLineQty(ctx, e, trxName);}).toArray(MRfQLineQty[]::new) : null; + } + /** Qyantities */ private MRfQLineQty[] m_qtys = null; diff --git a/org.adempiere.base/src/org/compiere/model/MRfQLineQty.java b/org.adempiere.base/src/org/compiere/model/MRfQLineQty.java index 3269807b41..755923595f 100644 --- a/org.adempiere.base/src/org/compiere/model/MRfQLineQty.java +++ b/org.adempiere.base/src/org/compiere/model/MRfQLineQty.java @@ -51,11 +51,14 @@ public class MRfQLineQty extends X_C_RfQLineQty Integer key = Integer.valueOf(C_RfQLineQty_ID); MRfQLineQty retValue = (MRfQLineQty) s_cache.get (key); if (retValue != null) - return retValue; + return new MRfQLineQty(ctx, retValue, trxName); retValue = new MRfQLineQty (ctx, C_RfQLineQty_ID, trxName); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + if (retValue.get_ID () == C_RfQLineQty_ID) + { + s_cache.put (key, new MRfQLineQty(Env.getCtx(), retValue)); + return retValue; + } + return null; } // get /** Cache */ @@ -102,6 +105,38 @@ public class MRfQLineQty extends X_C_RfQLineQty setC_RfQLine_ID (line.getC_RfQLine_ID()); } // MRfQLineQty + /** + * + * @param copy + */ + public MRfQLineQty(MRfQLineQty copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MRfQLineQty(Properties ctx, MRfQLineQty copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MRfQLineQty(Properties ctx, MRfQLineQty copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_uom = copy.m_uom != null ? new MUOM(ctx, copy.m_uom, trxName) : null; + } + /** Unit of Measure */ private MUOM m_uom = null; @@ -169,5 +204,4 @@ public class MRfQLineQty extends X_C_RfQLineQty .append ("]"); return sb.toString (); } // toString - } // MRfQLineQty diff --git a/org.adempiere.base/src/org/compiere/model/MRfQResponse.java b/org.adempiere.base/src/org/compiere/model/MRfQResponse.java index 153d185493..b1bf74a3cd 100644 --- a/org.adempiere.base/src/org/compiere/model/MRfQResponse.java +++ b/org.adempiere.base/src/org/compiere/model/MRfQResponse.java @@ -213,7 +213,8 @@ public class MRfQResponse extends X_C_RfQResponse public MRfQ getRfQ() { if (m_rfq == null) - m_rfq = MRfQ.get (getCtx(), getC_RfQ_ID(), get_TrxName()); + m_rfq = MRfQ.get(getCtx(), getC_RfQ_ID(), get_TrxName()); + return m_rfq; } // getRfQ diff --git a/org.adempiere.base/src/org/compiere/model/MRole.java b/org.adempiere.base/src/org/compiere/model/MRole.java index 28b75f81a9..8e7ef1fef2 100644 --- a/org.adempiere.base/src/org/compiere/model/MRole.java +++ b/org.adempiere.base/src/org/compiere/model/MRole.java @@ -25,6 +25,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -36,7 +37,6 @@ import java.util.Set; import java.util.logging.Level; import org.adempiere.exceptions.AdempiereException; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; @@ -46,6 +46,8 @@ import org.compiere.util.Msg; import org.compiere.util.Trace; import org.compiere.util.Util; import org.compiere.wf.MWorkflow; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.POCopyCache; /** * Role Model. @@ -58,12 +60,12 @@ import org.compiere.wf.MWorkflow; * @contributor KittiU - FR [ 3062553 ] - Duplicated action in DocAction list for Multiple Role Users * @version $Id: MRole.java,v 1.5 2006/08/09 16:38:47 jjanke Exp $ */ -public final class MRole extends X_AD_Role +public final class MRole extends X_AD_Role implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 8041397465891798378L; + private static final long serialVersionUID = -6317084960843429042L; /** * Get Default (Client) Role @@ -112,7 +114,7 @@ public final class MRole extends X_AD_Role } /** - * Get Role for User + * Get Role for User from cache * @param ctx context * @param AD_Role_ID role * @param AD_User_ID user @@ -123,11 +125,10 @@ public final class MRole extends X_AD_Role { if (s_log.isLoggable(Level.INFO)) s_log.info("AD_Role_ID=" + AD_Role_ID + ", AD_User_ID=" + AD_User_ID + ", reload=" + reload); String key = AD_Role_ID + "_" + AD_User_ID; - MRole role = (MRole)s_roles.get (key); + MRole role = (MRole)s_roles.get (key, e -> new MRole(ctx, e)); if (role == null || reload) { - role = new MRole (ctx, AD_Role_ID, null); - s_roles.put (key, role); + role = new MRole (ctx, AD_Role_ID, null); if (AD_Role_ID == 0) { String trxName = null; @@ -135,6 +136,7 @@ public final class MRole extends X_AD_Role } role.setAD_User_ID(AD_User_ID); role.loadAccess(reload); + s_roles.put (key, role, e -> new MRole(Env.getCtx(), e)); if (s_log.isLoggable(Level.INFO)) s_log.info(role.toString()); } return role; @@ -173,6 +175,17 @@ public final class MRole extends X_AD_Role * @return roles of client */ public static MRole[] getOfClient (Properties ctx) + { + return getOfClient(ctx, (String)null); + } + + /** + * Get Roles Of Client + * @param ctx context + * @param trxName + * @return roles of client + */ + public static MRole[] getOfClient (Properties ctx, String trxName) { String sql = "SELECT * FROM AD_Role WHERE AD_Client_ID=?"; ArrayList list = new ArrayList (); @@ -180,11 +193,11 @@ public final class MRole extends X_AD_Role ResultSet rs = null; try { - pstmt = DB.prepareStatement (sql, null); + pstmt = DB.prepareStatement (sql, trxName); pstmt.setInt (1, Env.getAD_Client_ID(ctx)); rs = pstmt.executeQuery (); while (rs.next ()) - list.add (new MRole(ctx, rs, null)); + list.add (new MRole(ctx, rs, trxName)); } catch (Exception e) { @@ -236,7 +249,7 @@ public final class MRole extends X_AD_Role } // getOf /** Role/User Cache */ - private static CCache s_roles = new CCache(Table_Name, 5); + private static POCopyCache s_roles = new POCopyCache(Table_Name, 5); /** Log */ private static CLogger s_log = CLogger.getCLogger(MRole.class); @@ -298,6 +311,57 @@ public final class MRole extends X_AD_Role super(ctx, rs, trxName); } // MRole + /** + * + * @param copy + */ + public MRole(MRole copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MRole(Properties ctx, MRole copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MRole(Properties ctx, MRole copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_AD_User_ID = copy.m_AD_User_ID; + this.m_orgAccess = copy.m_orgAccess != null ? Arrays.copyOf(copy.m_orgAccess, copy.m_orgAccess.length) : null; + this.m_tableAccess = copy.m_tableAccess != null ? Arrays.copyOf(copy.m_tableAccess, copy.m_tableAccess.length): null; + this.m_columnAccess = copy.m_columnAccess != null ? Arrays.copyOf(copy.m_columnAccess, copy.m_columnAccess.length) : null; + this.m_recordAccess = copy.m_recordAccess != null ? Arrays.copyOf(copy.m_recordAccess, copy.m_recordAccess.length) : null; + this.m_recordDependentAccess = copy.m_recordDependentAccess != null ? Arrays.copyOf(copy.m_recordDependentAccess, copy.m_recordDependentAccess.length) : null; + this.m_tableAccessLevel = copy.m_tableAccessLevel != null ? new HashMap(copy.m_tableAccessLevel) : null; + this.m_tableName = copy.m_tableName != null ? new HashMap(copy.m_tableName) : null; + this.m_viewName = copy.m_viewName != null ? new HashSet(copy.m_viewName) : null; + this.m_tableIdName = copy.m_tableIdName != null ? new HashMap(copy.m_tableIdName) : null; + this.m_windowAccess = copy.m_windowAccess != null ? new HashMap(copy.m_windowAccess) : null; + this.m_processAccess = copy.m_processAccess != null ? new HashMap(copy.m_processAccess) : null; + this.m_taskAccess = copy.m_taskAccess != null ? new HashMap(copy.m_taskAccess) : null; + this.m_workflowAccess = copy.m_workflowAccess != null ? new HashMap(copy.m_workflowAccess) : null; + this.m_formAccess = copy.m_formAccess != null ? new HashMap(copy.m_formAccess) : null; + this.m_infoAccess = copy.m_infoAccess != null ? new HashMap(copy.m_infoAccess) : null; + this.m_includedRoles = copy.m_includedRoles != null ? new ArrayList(copy.m_includedRoles) : null; + this.m_parent = copy.m_parent != null ? new MRole(ctx, copy.m_parent, trxName) : null; + this.m_includedSeqNo = copy.m_includedSeqNo; + this.m_canAccess_Info_Product = copy.m_canAccess_Info_Product; + } + /** * Get Confirm Query Records * @return entered records or 500 (default) @@ -816,7 +880,7 @@ public final class MRole extends X_AD_Role // Do we look for trees? if (getAD_Tree_Org_ID() == 0) return; - MOrg org = MOrg.get(getCtx(), oa.AD_Org_ID); + MOrg org = MOrg.get(oa.AD_Org_ID); if (!org.isSummary()) return; // Summary Org - Get Dependents @@ -2538,7 +2602,7 @@ public final class MRole extends X_AD_Role clientName = MClient.get(getCtx(), AD_Client_ID).getName(); String orgName = "*"; if (AD_Org_ID != 0) - orgName = MOrg.get(getCtx(), AD_Org_ID).getName(); + orgName = MOrg.get(AD_Org_ID).getName(); StringBuilder sb = new StringBuilder(); sb.append(Msg.translate(getCtx(), "AD_Client_ID")).append("=") .append(clientName).append(" - ") @@ -3343,7 +3407,7 @@ public final class MRole extends X_AD_Role } return access; } - + /** * Does the table is excluded for current role (this method doesn't check the level of the table, use isTableAccess for this purpose) * @param tableID ID of the table @@ -3365,4 +3429,13 @@ public final class MRole extends X_AD_Role return false; } // isTableAccessExcluded + @Override + public MRole markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MRole diff --git a/org.adempiere.base/src/org/compiere/model/MRoleOrgAccess.java b/org.adempiere.base/src/org/compiere/model/MRoleOrgAccess.java index 92fd9cde5c..3505218c7f 100644 --- a/org.adempiere.base/src/org/compiere/model/MRoleOrgAccess.java +++ b/org.adempiere.base/src/org/compiere/model/MRoleOrgAccess.java @@ -116,7 +116,7 @@ public class MRoleOrgAccess extends X_AD_Role_OrgAccess public static boolean createForOrg (MOrg org) { int counter = 0; - MRole[] roles = MRole.getOfClient(org.getCtx()); + MRole[] roles = MRole.getOfClient(org.getCtx(), org.get_TrxName()); for (int i = 0; i < roles.length; i++) { if (!roles[i].isManual()) diff --git a/org.adempiere.base/src/org/compiere/model/MRule.java b/org.adempiere.base/src/org/compiere/model/MRule.java index 47d68c91f1..9526960e27 100644 --- a/org.adempiere.base/src/org/compiere/model/MRule.java +++ b/org.adempiere.base/src/org/compiere/model/MRule.java @@ -19,17 +19,18 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Enumeration; -import java.util.Iterator; import java.util.List; import java.util.Properties; import javax.script.ScriptEngine; import org.adempiere.base.Core; -import org.compiere.util.CCache; import org.compiere.util.CLogger; +import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.Util; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Persistent Rule Model @@ -37,13 +38,12 @@ import org.compiere.util.Util; * @version $Id: MRule.java * */ -public class MRule extends X_AD_Rule +public class MRule extends X_AD_Rule implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -9166262780531877045L; - + private static final long serialVersionUID = -288947666359685155L; //global or login context variable prefix public final static String GLOBAL_CONTEXT_PREFIX = "G_"; //window context variable prefix @@ -56,7 +56,17 @@ public class MRule extends X_AD_Rule public static final String SCRIPT_PREFIX = "@script:"; /** - * Get Rule from Cache + * Get Rule from Cache (immutable) + * @param AD_Rule_ID id + * @return MRule + */ + public static MRule get (int AD_Rule_ID) + { + return get(Env.getCtx(), AD_Rule_ID); + } + + /** + * Get Rule from Cache (immutable) * @param ctx context * @param AD_Rule_ID id * @return MRule @@ -64,13 +74,16 @@ public class MRule extends X_AD_Rule public static MRule get (Properties ctx, int AD_Rule_ID) { Integer key = Integer.valueOf(AD_Rule_ID); - MRule retValue = (MRule) s_cache.get (key); + MRule retValue = s_cache.get (ctx, key, e -> new MRule(ctx, e)); if (retValue != null) return retValue; - retValue = new MRule (ctx, AD_Rule_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MRule (ctx, AD_Rule_ID, (String)null); + if (retValue.get_ID () == AD_Rule_ID) + { + s_cache.put (key, retValue, e -> new MRule(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** @@ -83,10 +96,9 @@ public class MRule extends X_AD_Rule { if (ruleValue == null) return null; - Iterator it = s_cache.values().iterator(); - while (it.hasNext()) + MRule[] it = s_cache.values().toArray(new MRule[0]); + for (MRule retValue : it) { - MRule retValue = (MRule)it.next(); if (ruleValue.equals(retValue.getValue())) return retValue; } @@ -124,7 +136,7 @@ public class MRule extends X_AD_Rule } // getModelValidatorLoginRules /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** Static Logger */ @SuppressWarnings("unused") @@ -155,6 +167,38 @@ public class MRule extends X_AD_Rule super(ctx, rs, trxName); } // MRule + /** + * + * @param copy + */ + public MRule(MRule copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MRule(Properties ctx, MRule copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MRule(Properties ctx, MRule copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.engine = copy.engine; + } + /** * Before Save * @param newRecord new @@ -267,4 +311,13 @@ public class MRule extends X_AD_Rule } } // convertKey + @Override + public MRule markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MRule \ No newline at end of file diff --git a/org.adempiere.base/src/org/compiere/model/MSLACriteria.java b/org.adempiere.base/src/org/compiere/model/MSLACriteria.java index 5f66ad22d5..b43b644f6d 100644 --- a/org.adempiere.base/src/org/compiere/model/MSLACriteria.java +++ b/org.adempiere.base/src/org/compiere/model/MSLACriteria.java @@ -24,8 +24,10 @@ import java.util.logging.Level; import org.compiere.sla.SLACriteria; import org.compiere.util.AdempiereSystemError; -import org.compiere.util.CCache; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Service Level Agreement Criteria Model @@ -33,14 +35,34 @@ import org.compiere.util.DB; * @author Jorg Janke * @version $Id: MSLACriteria.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $ */ -public class MSLACriteria extends X_PA_SLA_Criteria +public class MSLACriteria extends X_PA_SLA_Criteria implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -3295590987540402184L; - + private static final long serialVersionUID = 6772238818871223076L; + /** + * Get MSLACriteria from Cache + * @param PA_SLA_Criteria_ID id + * @return MSLACriteria + */ + public static MSLACriteria get (int PA_SLA_Criteria_ID) + { + return get(PA_SLA_Criteria_ID, (String)null); + } + + /** + * Get MSLACriteria from Cache + * @param PA_SLA_Criteria_ID id + * @param trxName transaction + * @return MSLACriteria + */ + public static MSLACriteria get (int PA_SLA_Criteria_ID, String trxName) + { + return get(Env.getCtx(), PA_SLA_Criteria_ID, trxName); + } + /** * Get MSLACriteria from Cache * @param ctx context @@ -51,17 +73,20 @@ public class MSLACriteria extends X_PA_SLA_Criteria public static MSLACriteria get (Properties ctx, int PA_SLA_Criteria_ID, String trxName) { Integer key = Integer.valueOf(PA_SLA_Criteria_ID); - MSLACriteria retValue = (MSLACriteria) s_cache.get (key); + MSLACriteria retValue = s_cache.get (ctx, key, e -> new MSLACriteria(ctx, e)); if (retValue != null) return retValue; retValue = new MSLACriteria (ctx, PA_SLA_Criteria_ID, trxName); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + if (retValue.get_ID () == PA_SLA_Criteria_ID) + { + s_cache.put (key, retValue, e -> new MSLACriteria(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** @@ -86,6 +111,37 @@ public class MSLACriteria extends X_PA_SLA_Criteria super(ctx, rs, trxName); } // MSLACriteria + /** + * + * @param copy + */ + public MSLACriteria(MSLACriteria copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MSLACriteria(Properties ctx, MSLACriteria copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MSLACriteria(Properties ctx, MSLACriteria copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Get Goals of Criteria * @return array of Goals @@ -143,4 +199,13 @@ public class MSLACriteria extends X_PA_SLA_Criteria } } // newInstance + @Override + public MSLACriteria markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MSLACriteria diff --git a/org.adempiere.base/src/org/compiere/model/MSalesRegion.java b/org.adempiere.base/src/org/compiere/model/MSalesRegion.java index 7c3b408b32..dd32fb2b1a 100644 --- a/org.adempiere.base/src/org/compiere/model/MSalesRegion.java +++ b/org.adempiere.base/src/org/compiere/model/MSalesRegion.java @@ -19,7 +19,9 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** @@ -28,15 +30,26 @@ import org.compiere.util.CCache; * @author Jorg Janke * @version $Id: MSalesRegion.java,v 1.3 2006/07/30 00:54:54 jjanke Exp $ */ -public class MSalesRegion extends X_C_SalesRegion +public class MSalesRegion extends X_C_SalesRegion implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -6166934441386906620L; + private static final long serialVersionUID = -1958080117315345389L; + /** - * Get SalesRegion from Cache + * Get SalesRegion from Cache (immutable) + * @param C_SalesRegion_ID id + * @return MSalesRegion + */ + public static MSalesRegion get (int C_SalesRegion_ID) + { + return get(Env.getCtx(), C_SalesRegion_ID); + } + + /** + * Get SalesRegion from Cache (immutable) * @param ctx context * @param C_SalesRegion_ID id * @return MSalesRegion @@ -44,17 +57,20 @@ public class MSalesRegion extends X_C_SalesRegion public static MSalesRegion get (Properties ctx, int C_SalesRegion_ID) { Integer key = Integer.valueOf(C_SalesRegion_ID); - MSalesRegion retValue = (MSalesRegion) s_cache.get (key); + MSalesRegion retValue = (MSalesRegion) s_cache.get (ctx, key, e -> new MSalesRegion(ctx, e)); if (retValue != null) return retValue; - retValue = new MSalesRegion (ctx, C_SalesRegion_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MSalesRegion (ctx, C_SalesRegion_ID, (String)null); + if (retValue.get_ID () == C_SalesRegion_ID) + { + s_cache.put (key, retValue, e -> new MSalesRegion(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 10); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 10); /************************************************************************** @@ -79,6 +95,37 @@ public class MSalesRegion extends X_C_SalesRegion super(ctx, rs, trxName); } // MSalesRegion + /** + * + * @param copy + */ + public MSalesRegion(MSalesRegion copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MSalesRegion(Properties ctx, MSalesRegion copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MSalesRegion(Properties ctx, MSalesRegion copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * After Save. * Insert @@ -113,5 +160,14 @@ public class MSalesRegion extends X_C_SalesRegion delete_Tree(MTree_Base.TREETYPE_SalesRegion); return success; } // afterDelete - + + @Override + public MSalesRegion markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MSalesRegion diff --git a/org.adempiere.base/src/org/compiere/model/MSchedule.java b/org.adempiere.base/src/org/compiere/model/MSchedule.java index 8b82ce0b7e..53d7208335 100644 --- a/org.adempiere.base/src/org/compiere/model/MSchedule.java +++ b/org.adempiere.base/src/org/compiere/model/MSchedule.java @@ -31,16 +31,17 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; -public class MSchedule extends X_AD_Schedule +public class MSchedule extends X_AD_Schedule implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -3319184522988847237L; - + private static final long serialVersionUID = 7183417983901074702L; private static Pattern VALID_IPV4_PATTERN = null; private static Pattern VALID_IPV6_PATTERN = null; private static final String ipv4Pattern = "(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])"; @@ -56,6 +57,34 @@ public class MSchedule extends X_AD_Schedule // TODO Auto-generated constructor stub } + /** + * + * @param copy + */ + public MSchedule(MSchedule copy) { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MSchedule(Properties ctx, MSchedule copy) { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MSchedule(Properties ctx, MSchedule copy, String trxName) { + this(ctx, 0, trxName); + copyPO(copy); + } + @Override protected boolean beforeSave(boolean newRecord) { // Set Schedule Type & Frequencies @@ -158,20 +187,39 @@ public class MSchedule extends X_AD_Schedule return false; } // checkIP + /** + * Get MSchedule from cache (immutable) + * @param AD_Schedule_ID + * @return MSchedule + */ + public static MSchedule get(int AD_Schedule_ID) + { + return get(Env.getCtx(), AD_Schedule_ID); + } + + /** + * Get MSchedule from cache (immutable) + * @param ctx + * @param AD_Schedule_ID + * @return MSchedule + */ public static MSchedule get(Properties ctx, int AD_Schedule_ID) { Integer key = Integer.valueOf(AD_Schedule_ID); - MSchedule retValue = (MSchedule)s_cache.get (key); + MSchedule retValue = s_cache.get (ctx, key, e -> new MSchedule(ctx, e)); if (retValue != null) return retValue; - retValue = new MSchedule (ctx, AD_Schedule_ID, null); - if (retValue.get_ID() != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MSchedule (ctx, AD_Schedule_ID, (String)null); + if (retValue.get_ID() == AD_Schedule_ID) + { + s_cache.put (key, retValue, e -> new MSchedule(Env.getCtx(), e)); + return retValue; + } + return null; } /** Cache */ - private static CCache s_cache = new CCache (Table_Name, 10); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache (Table_Name, 10); public boolean chekIPFormat(String ipOnly) { @@ -248,4 +296,13 @@ public class MSchedule extends X_AD_Schedule return 0; } // getNextRunMS + @Override + public MSchedule markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } diff --git a/org.adempiere.base/src/org/compiere/model/MScheduler.java b/org.adempiere.base/src/org/compiere/model/MScheduler.java index 296f5bb1d9..82a432808b 100644 --- a/org.adempiere.base/src/org/compiere/model/MScheduler.java +++ b/org.adempiere.base/src/org/compiere/model/MScheduler.java @@ -18,13 +18,16 @@ package org.compiere.model; import java.sql.ResultSet; import java.sql.Timestamp; +import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.TreeSet; import org.compiere.util.DB; import org.compiere.util.DisplayType; +import org.compiere.util.Env; import org.compiere.util.Msg; +import org.idempiere.cache.ImmutablePOSupport; /** @@ -37,12 +40,12 @@ import org.compiere.util.Msg; * Carlos Ruiz - globalqss - FR [3135351] - Enable Scheduler for buttons */ public class MScheduler extends X_AD_Scheduler - implements AdempiereProcessor, AdempiereProcessor2 + implements AdempiereProcessor, AdempiereProcessor2, ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 5106574386025319255L; + private static final long serialVersionUID = -2427229109274587547L; /** * Get Active @@ -85,6 +88,39 @@ public class MScheduler extends X_AD_Scheduler super(ctx, rs, trxName); } // MScheduler + /** + * + * @param copy + */ + public MScheduler(MScheduler copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MScheduler(Properties ctx, MScheduler copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MScheduler(Properties ctx, MScheduler copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_parameter = copy.m_parameter != null ? Arrays.stream(copy.m_parameter).map(e -> {return new MSchedulerPara(ctx, e, trxName);}).toArray(MSchedulerPara[]::new) : null; + this.m_recipients = copy.m_recipients != null ? Arrays.stream(copy.m_recipients).map(e -> {return new MSchedulerRecipient(ctx, e, trxName);}).toArray(MSchedulerRecipient[]::new) : null; + } + /** Process Parameter */ private MSchedulerPara[] m_parameter = null; /** Process Recipients */ @@ -155,7 +191,7 @@ public class MScheduler extends X_AD_Scheduler */ public MProcess getProcess() { - return MProcess.get(getCtx(), getAD_Process_ID()); + return MProcess.getCopy(getCtx(), getAD_Process_ID(), (String)null); } // getProcess /** @@ -173,6 +209,8 @@ public class MScheduler extends X_AD_Scheduler .setParameters(getAD_Scheduler_ID()) .setOnlyActiveRecords(true) .list(); + if (list.size() > 0 && is_Immutable()) + list.stream().forEach(e -> e.markImmutable()); m_parameter = new MSchedulerPara[list.size()]; list.toArray(m_parameter); return m_parameter; @@ -193,6 +231,9 @@ public class MScheduler extends X_AD_Scheduler .setParameters(getAD_Scheduler_ID()) .setOnlyActiveRecords(true) .list(); + if (list.size() > 0 && is_Immutable()) + list.stream().forEach(e -> e.markImmutable()); + m_recipients = new MSchedulerRecipient[list.size()]; list.toArray(m_recipients); return m_recipients; @@ -316,4 +357,19 @@ public class MScheduler extends X_AD_Scheduler return MSchedule.get(getCtx(),getAD_Schedule_ID()).getCronPattern(); } + @Override + public MScheduler markImmutable() + { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_parameter != null && m_parameter.length > 0) + Arrays.stream(m_parameter).forEach(e -> e.markImmutable()); + if (m_recipients != null && m_recipients.length > 0) + Arrays.stream(m_recipients).forEach(e -> e.markImmutable()); + + return this; + } + } // MScheduler diff --git a/org.adempiere.base/src/org/compiere/model/MSchedulerPara.java b/org.adempiere.base/src/org/compiere/model/MSchedulerPara.java index 6d969500b0..2501f283a7 100644 --- a/org.adempiere.base/src/org/compiere/model/MSchedulerPara.java +++ b/org.adempiere.base/src/org/compiere/model/MSchedulerPara.java @@ -19,18 +19,21 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; + /** * Scheduler Parameter Model * * @author Jorg Janke * @version $Id: MSchedulerPara.java,v 1.2 2006/07/30 00:51:05 jjanke Exp $ */ -public class MSchedulerPara extends X_AD_Scheduler_Para +public class MSchedulerPara extends X_AD_Scheduler_Para implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -703173920039087748L; + private static final long serialVersionUID = -9178948165437974600L; /** * Standard Constructor @@ -55,6 +58,38 @@ public class MSchedulerPara extends X_AD_Scheduler_Para super (ctx, rs, trxName); } // MSchedulerPara + /** + * + * @param copy + */ + public MSchedulerPara(MSchedulerPara copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MSchedulerPara(Properties ctx, MSchedulerPara copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MSchedulerPara(Properties ctx, MSchedulerPara copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_parameter = copy.m_parameter != null ? new MProcessPara(ctx, copy.m_parameter, trxName) : null; + } + /** Parameter Column Name */ private MProcessPara m_parameter = null; @@ -92,5 +127,14 @@ public class MSchedulerPara extends X_AD_Scheduler_Para .append("]"); return sb.toString(); } // toString - + + @Override + public MSchedulerPara markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MSchedulerPara diff --git a/org.adempiere.base/src/org/compiere/model/MSchedulerRecipient.java b/org.adempiere.base/src/org/compiere/model/MSchedulerRecipient.java index 1ab1550e5c..cf63d3ef0a 100644 --- a/org.adempiere.base/src/org/compiere/model/MSchedulerRecipient.java +++ b/org.adempiere.base/src/org/compiere/model/MSchedulerRecipient.java @@ -19,18 +19,21 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; + /** * Scheduler Recipient Model * * @author Jorg Janke * @version $Id: MSchedulerRecipient.java,v 1.2 2006/07/30 00:51:03 jjanke Exp $ */ -public class MSchedulerRecipient extends X_AD_SchedulerRecipient +public class MSchedulerRecipient extends X_AD_SchedulerRecipient implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -6521993049769786393L; + private static final long serialVersionUID = -4928359768598663557L; /** * Standard Constructor @@ -55,4 +58,44 @@ public class MSchedulerRecipient extends X_AD_SchedulerRecipient super (ctx, rs, trxName); } // MSchedulerRecipient + /** + * + * @param copy + */ + public MSchedulerRecipient(MSchedulerRecipient copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MSchedulerRecipient(Properties ctx, MSchedulerRecipient copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MSchedulerRecipient(Properties ctx, MSchedulerRecipient copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + @Override + public MSchedulerRecipient markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MSchedulerRecipient diff --git a/org.adempiere.base/src/org/compiere/model/MSerNoCtlExclude.java b/org.adempiere.base/src/org/compiere/model/MSerNoCtlExclude.java new file mode 100644 index 0000000000..54ba060172 --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/MSerNoCtlExclude.java @@ -0,0 +1,87 @@ +/********************************************************************** +* 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: * +* - Trek Global Corporation * +* - Heng Sin Low * +**********************************************************************/ +package org.compiere.model; + +import java.sql.ResultSet; +import java.util.Properties; + +import org.compiere.util.Env; + +public class MSerNoCtlExclude extends X_M_SerNoCtlExclude { + + /** + * + */ + private static final long serialVersionUID = -5338323423136199056L; + + /** + * + * @param ctx + * @param M_SerNoCtlExclude_ID + * @param trxName + */ + public MSerNoCtlExclude(Properties ctx, int M_SerNoCtlExclude_ID, String trxName) { + super(ctx, M_SerNoCtlExclude_ID, trxName); + } + + /** + * + * @param ctx + * @param rs + * @param trxName + */ + public MSerNoCtlExclude(Properties ctx, ResultSet rs, String trxName) { + super(ctx, rs, trxName); + } + + /** + * + * @param copy + */ + public MSerNoCtlExclude(MSerNoCtlExclude copy) { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MSerNoCtlExclude(Properties ctx, MSerNoCtlExclude copy) { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MSerNoCtlExclude(Properties ctx, MSerNoCtlExclude copy, String trxName) { + this(ctx, 0, trxName); + copyPO(copy); + } +} diff --git a/org.adempiere.base/src/org/compiere/model/MSetup.java b/org.adempiere.base/src/org/compiere/model/MSetup.java index 0f5bceb83b..8b46ace562 100644 --- a/org.adempiere.base/src/org/compiere/model/MSetup.java +++ b/org.adempiere.base/src/org/compiere/model/MSetup.java @@ -60,10 +60,21 @@ public final class MSetup * @param WindowNo window */ public MSetup(Properties ctx, int WindowNo) + { + this(ctx, WindowNo, false); + } + + /** + * Constructor + * @param ctx context + * @param WindowNo window + */ + public MSetup(Properties ctx, int WindowNo, boolean dryRun) { m_ctx = new Properties(ctx); // copy m_lang = Env.getAD_Language(m_ctx); m_WindowNo = WindowNo; + m_dryRun = dryRun; } // MSetup /** Logger */ @@ -101,6 +112,7 @@ public final class MSetup private boolean m_hasSRegion = false; private boolean m_hasActivity = false; + private boolean m_dryRun = false; /** * Create Client Info. * - Client, Trees, Org, Role, User, User_Role @@ -202,7 +214,7 @@ public final class MSetup m_info.append(Msg.translate(m_lang, "AD_Org_ID")).append("=").append(name).append("\n"); // Set Organization Phone, Phone2, Fax, EMail - MOrgInfo orgInfo = MOrgInfo.get(m_ctx, getAD_Org_ID(), m_trx.getTrxName()); + MOrgInfo orgInfo = MOrgInfo.getCopy(m_ctx, getAD_Org_ID(), m_trx.getTrxName()); orgInfo.setPhone(phone); orgInfo.setPhone2(phone2); orgInfo.setFax(fax); @@ -1442,6 +1454,10 @@ public final class MSetup else log.log(Level.SEVERE, "CashBook NOT inserted"); // + //do not commit if it is a dry run + if (m_dryRun) + return true; + boolean success = m_trx.commit(); m_trx.close(); log.info("finish"); @@ -1527,4 +1543,11 @@ public final class MSetup } catch (Exception e) {} } + /** + * + * @return trxName + */ + public String getTrxName() { + return m_trx != null ? m_trx.getTrxName() : null; + } } // MSetup diff --git a/org.adempiere.base/src/org/compiere/model/MStatus.java b/org.adempiere.base/src/org/compiere/model/MStatus.java index 164ce26f8a..2b5ccb2288 100644 --- a/org.adempiere.base/src/org/compiere/model/MStatus.java +++ b/org.adempiere.base/src/org/compiere/model/MStatus.java @@ -23,26 +23,36 @@ import java.util.ArrayList; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Request Status Model * @author Jorg Janke * @version $Id: MStatus.java,v 1.2 2006/07/30 00:51:05 jjanke Exp $ */ -public class MStatus extends X_R_Status +public class MStatus extends X_R_Status implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -4549127671165860354L; - + private static final long serialVersionUID = 446327334122691551L; /** - * Get Request Status (cached) + * Get Request Status (cached) (immutable) + * @param R_Status_ID id + * @return Request Status or null + */ + public static MStatus get (int R_Status_ID) + { + return get(Env.getCtx(), R_Status_ID); + } + + /** + * Get Request Status (cached) (immutable) * @param ctx context * @param R_Status_ID id * @return Request Status or null @@ -52,15 +62,35 @@ public class MStatus extends X_R_Status if (R_Status_ID == 0) return null; Integer key = Integer.valueOf(R_Status_ID); - MStatus retValue = (MStatus)s_cache.get(key); + MStatus retValue = s_cache.get(ctx, key, e -> new MStatus(ctx, e)); if (retValue == null) { - retValue = new MStatus (ctx, R_Status_ID, null); - s_cache.put(key, retValue); + retValue = new MStatus (ctx, R_Status_ID, (String)null); + if (retValue.get_ID() == R_Status_ID) + { + s_cache.put(key, retValue, e -> new MStatus(Env.getCtx(), e)); + return retValue; + } + return null; } return retValue; } // get + /** + * Get updateable copy of MStatus from cache + * @param ctx + * @param R_Status_ID + * @param trxName + * @return MStatus + */ + public static MStatus getCopy(Properties ctx, int R_Status_ID, String trxName) + { + MStatus status = get(R_Status_ID); + if (status != null) + status = new MStatus(ctx, status, trxName); + return status; + } + /** * Get Default Request Status * @param ctx context @@ -70,7 +100,7 @@ public class MStatus extends X_R_Status public static MStatus getDefault (Properties ctx, int R_RequestType_ID) { Integer key = Integer.valueOf(R_RequestType_ID); - MStatus retValue = (MStatus)s_cacheDefault.get(key); + MStatus retValue = s_cacheDefault.get(ctx, key, e -> new MStatus(ctx, e)); if (retValue != null) return retValue; // Get New @@ -100,8 +130,10 @@ public class MStatus extends X_R_Status rs = null; pstmt = null; } - if (retValue != null) - s_cacheDefault.put(key, retValue); + if (retValue != null) + { + s_cacheDefault.put(key, retValue, e -> new MStatus(Env.getCtx(), e)); + } return retValue; } // getDefault @@ -146,11 +178,11 @@ public class MStatus extends X_R_Status /** Static Logger */ private static CLogger s_log = CLogger.getCLogger(MStatus.class); /** Cache */ - static private CCache s_cache - = new CCache (Table_Name, 10); + static private ImmutableIntPOCache s_cache + = new ImmutableIntPOCache (Table_Name, 10); /** Default Cache (Key=Client) */ - static private CCache s_cacheDefault - = new CCache(Table_Name, "R_Status_Default", 10); + static private ImmutableIntPOCache s_cacheDefault + = new ImmutableIntPOCache(Table_Name, "R_Status_Default", 10); /************************************************************************** @@ -185,7 +217,37 @@ public class MStatus extends X_R_Status super (ctx, rs, trxName); } // MStatus + /** + * + * @param copy + */ + public MStatus(MStatus copy) + { + this(Env.getCtx(), copy); + } + /** + * + * @param ctx + * @param copy + */ + public MStatus(Properties ctx, MStatus copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MStatus(Properties ctx, MStatus copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Before Save * @param newRecord new @@ -218,4 +280,13 @@ public class MStatus extends X_R_Status return sb.toString (); } // toString + @Override + public MStatus markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MStatus diff --git a/org.adempiere.base/src/org/compiere/model/MStatusCategory.java b/org.adempiere.base/src/org/compiere/model/MStatusCategory.java index 644c025c2d..04306ef5a5 100644 --- a/org.adempiere.base/src/org/compiere/model/MStatusCategory.java +++ b/org.adempiere.base/src/org/compiere/model/MStatusCategory.java @@ -19,14 +19,16 @@ package org.compiere.model; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; +import java.util.Arrays; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Request Status Category Model @@ -34,13 +36,12 @@ import org.compiere.util.Msg; * @author Jorg Janke * @version $Id: MStatusCategory.java,v 1.2 2006/07/30 00:51:02 jjanke Exp $ */ -public class MStatusCategory extends X_R_StatusCategory +public class MStatusCategory extends X_R_StatusCategory implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -7538457243144691380L; - + private static final long serialVersionUID = -5527646898927619293L; /** * Get Default Status Categpru for Client @@ -99,7 +100,17 @@ public class MStatusCategory extends X_R_StatusCategory } // createDefault /** - * Get Request Status Category from Cache + * Get Request Status Category from Cache (immutable) + * @param R_StatusCategory_ID id + * @return RStatusCategory + */ + public static MStatusCategory get (int R_StatusCategory_ID) + { + return get(Env.getCtx(), R_StatusCategory_ID); + } + + /** + * Get Request Status Category from Cache (immutable) * @param ctx context * @param R_StatusCategory_ID id * @return RStatusCategory @@ -107,18 +118,21 @@ public class MStatusCategory extends X_R_StatusCategory public static MStatusCategory get (Properties ctx, int R_StatusCategory_ID) { Integer key = Integer.valueOf(R_StatusCategory_ID); - MStatusCategory retValue = (MStatusCategory)s_cache.get (key); + MStatusCategory retValue = s_cache.get (ctx, key, e -> new MStatusCategory(ctx, e)); if (retValue != null) return retValue; - retValue = new MStatusCategory (ctx, R_StatusCategory_ID, null); - if (retValue.get_ID() != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MStatusCategory (ctx, R_StatusCategory_ID, (String)null); + if (retValue.get_ID() == R_StatusCategory_ID) + { + s_cache.put (key, retValue, e -> new MStatusCategory(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private static CCache s_cache - = new CCache (Table_Name, 20); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache (Table_Name, 20); /** Logger */ private static CLogger s_log = CLogger.getCLogger (MStatusCategory.class); @@ -150,6 +164,38 @@ public class MStatusCategory extends X_R_StatusCategory super (ctx, rs, trxName); } // RStatusCategory + /** + * + * @param copy + */ + public MStatusCategory(MStatusCategory copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MStatusCategory(Properties ctx, MStatusCategory copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MStatusCategory(Properties ctx, MStatusCategory copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_status = copy.m_status != null ? Arrays.stream(copy.m_status).map(e ->{return new MStatus(ctx, e, trxName);}).toArray(MStatus[]::new) : null; + } + /** The Status */ private MStatus[] m_status = null; @@ -187,6 +233,8 @@ public class MStatusCategory extends X_R_StatusCategory pstmt = null; } // + if (list.size() > 0 && is_Immutable()) + list.stream().forEach(e -> e.markImmutable()); m_status = new MStatus[list.size ()]; list.toArray (m_status); return m_status; @@ -211,6 +259,18 @@ public class MStatusCategory extends X_R_StatusCategory return 0; } // getDefaultR_Status_ID + @Override + public MStatusCategory markImmutable() + { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_status != null && m_status.length > 0) + Arrays.stream(m_status).forEach(e -> e.markImmutable()); + return this; + } + /** * String Representation * @return info diff --git a/org.adempiere.base/src/org/compiere/model/MStatusLine.java b/org.adempiere.base/src/org/compiere/model/MStatusLine.java index 00ede25210..c59c4d2910 100644 --- a/org.adempiere.base/src/org/compiere/model/MStatusLine.java +++ b/org.adempiere.base/src/org/compiere/model/MStatusLine.java @@ -33,6 +33,8 @@ import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.ImmutablePOCache; /** * Status Line Model @@ -40,17 +42,16 @@ import org.compiere.util.Msg; * @author Nicolas Micoud * @version $Id: MStatusLine.java */ -public class MStatusLine extends X_AD_StatusLine +public class MStatusLine extends X_AD_StatusLine implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 2473407023692665378L; - + private static final long serialVersionUID = -2804602992872075936L; /** Logging */ private static CLogger s_log = CLogger.getCLogger(MStatusLine.class); /** Status Line Cache */ - private static CCache s_cache = new CCache(Table_Name, 10); + private static ImmutablePOCache s_cache = new ImmutablePOCache(Table_Name, 10); private static CCache s_cachew = new CCache(Table_Name, Table_Name+"|MStatusLine[]", 10); /** @@ -76,7 +77,38 @@ public class MStatusLine extends X_AD_StatusLine } // MStatusLine /** - * Get the status line defined for the window|tab|table + * + * @param copy + */ + public MStatusLine(MStatusLine copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MStatusLine(Properties ctx, MStatusLine copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MStatusLine(Properties ctx, MStatusLine copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + /** + * Get the status line defined for the window|tab|table (immutable) * @param window_ID * @param tab_ID * @param table_ID @@ -128,13 +160,12 @@ public class MStatusLine extends X_AD_StatusLine if (slid > 0) { retValue = new MStatusLine(Env.getCtx(), slid, null); } - s_cache.put(key.toString(), retValue); - + s_cache.put(key.toString(), retValue, e -> new MStatusLine(Env.getCtx(), e)); return retValue; } /** - * Get the widget lines defined for the window&tab&table + * Get the widget lines defined for the window&tab&table (immutable) * @param window_ID * @param tab_ID * @param table_ID @@ -164,6 +195,7 @@ public class MStatusLine extends X_AD_StatusLine ArrayList list = new ArrayList(); for (int wlid : wlids) { MStatusLine wl = new MStatusLine(Env.getCtx(), wlid, null); + wl.markImmutable(); list.add(wl); } // Convert to array @@ -242,4 +274,13 @@ public class MStatusLine extends X_AD_StatusLine return null; } + @Override + public MStatusLine markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MStatusLine diff --git a/org.adempiere.base/src/org/compiere/model/MStyle.java b/org.adempiere.base/src/org/compiere/model/MStyle.java index 824ce1ce9c..fb6a558924 100644 --- a/org.adempiere.base/src/org/compiere/model/MStyle.java +++ b/org.adempiere.base/src/org/compiere/model/MStyle.java @@ -4,28 +4,29 @@ package org.compiere.model; import java.sql.ResultSet; +import java.util.Arrays; import java.util.List; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.Env; import org.compiere.util.Evaluatee; import org.compiere.util.Evaluator; import org.compiere.util.Util; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * @author hengsin * */ -public class MStyle extends X_AD_Style { +public class MStyle extends X_AD_Style implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 712675285511854305L; - + private static final long serialVersionUID = 5409686715292148171L; /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 30, 60); - private X_AD_StyleLine[] m_lines = null; + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 30, 60); + private MStyleLine[] m_lines = null; public static final String SCLASS_PREFIX = "@sclass="; public static final String ZCLASS_PREFIX = "@zclass="; @@ -38,23 +39,77 @@ public class MStyle extends X_AD_Style { super(ctx, rs, trxName); } + /** + * + * @param copy + */ + public MStyle(MStyle copy) { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MStyle(Properties ctx, MStyle copy) { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MStyle(Properties ctx, MStyle copy, String trxName) { + this(ctx, 0, trxName); + copyPO(copy); + this.m_lines = copy.m_lines != null ? Arrays.stream(copy.m_lines).map(e -> {return new MStyleLine(ctx, e, trxName);}).toArray(MStyleLine[]::new) : null; + } + + /** + * Get MStyle from cache (immutable) + * @param AD_Style_ID + * @return MStyle + */ + public static MStyle get (int AD_Style_ID) + { + return get(Env.getCtx(), AD_Style_ID); + } + + /** + * Get MStyle from cache (immutable) + * @param ctx + * @param AD_Style_ID + * @return MStyle + */ public static MStyle get (Properties ctx, int AD_Style_ID) { Integer key = Integer.valueOf(AD_Style_ID); - MStyle retValue = (MStyle)s_cache.get(key); + MStyle retValue = s_cache.get(ctx, key, e -> new MStyle(ctx, e)); if (retValue == null) { - retValue = new MStyle (ctx, AD_Style_ID, null); - s_cache.put(key, retValue); + retValue = new MStyle (ctx, AD_Style_ID, (String)null); + if (retValue.get_ID() == AD_Style_ID) + { + s_cache.put(key, retValue, e -> new MStyle(Env.getCtx(), e)); + return retValue; + } + return null; } return retValue; } // get - public X_AD_StyleLine[] getStyleLines() { + public MStyleLine[] getStyleLines() { if (m_lines == null) { Query query = new Query(Env.getCtx(), I_AD_StyleLine.Table_Name, "AD_Style_ID=? AND InlineStyle IS NOT NULL", null); - List lines = query.setParameters(getAD_Style_ID()).setOnlyActiveRecords(true).setOrderBy("Line").list(); - m_lines = lines.toArray(new X_AD_StyleLine[0]); + List lines = query.setParameters(getAD_Style_ID()).setOnlyActiveRecords(true).setOrderBy("Line").list(); + if (lines.size() > 0 && is_Immutable()) { + for (MStyleLine line : lines) + line.markImmutable(); + } + m_lines = lines.toArray(new MStyleLine[0]); } return m_lines; } @@ -82,4 +137,17 @@ public class MStyle extends X_AD_Style { } return styleBuilder.toString(); } + + @Override + public MStyle markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_lines != null && m_lines.length > 0) + Arrays.stream(m_lines).forEach(e -> e.markImmutable()); + return this; + } + + } diff --git a/org.adempiere.base/src/org/compiere/model/MStyleLine.java b/org.adempiere.base/src/org/compiere/model/MStyleLine.java new file mode 100644 index 0000000000..56fbaf2008 --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/MStyleLine.java @@ -0,0 +1,100 @@ +/********************************************************************** +* 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: * +* - Trek Global Corporation * +* - Heng Sin Low * +**********************************************************************/ +package org.compiere.model; + +import java.sql.ResultSet; +import java.util.Properties; + +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; + +/** + * @author hengsin + * + */ +public class MStyleLine extends X_AD_StyleLine implements ImmutablePOSupport { + + /** + * + */ + private static final long serialVersionUID = -5884961214171382581L; + + /** + * @param ctx + * @param AD_StyleLine_ID + * @param trxName + */ + public MStyleLine(Properties ctx, int AD_StyleLine_ID, String trxName) { + super(ctx, AD_StyleLine_ID, trxName); + } + + /** + * @param ctx + * @param rs + * @param trxName + */ + public MStyleLine(Properties ctx, ResultSet rs, String trxName) { + super(ctx, rs, trxName); + } + + /** + * + * @param copy + */ + public MStyleLine(MStyleLine copy) { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MStyleLine(Properties ctx, MStyleLine copy) { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MStyleLine(Properties ctx, MStyleLine copy, String trxName) { + this(ctx, 0, trxName); + copyPO(copy); + } + + @Override + public MStyleLine markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + +} diff --git a/org.adempiere.base/src/org/compiere/model/MSystem.java b/org.adempiere.base/src/org/compiere/model/MSystem.java index 9433ad7ee4..7b5ea98d59 100644 --- a/org.adempiere.base/src/org/compiere/model/MSystem.java +++ b/org.adempiere.base/src/org/compiere/model/MSystem.java @@ -66,7 +66,7 @@ public class MSystem extends X_AD_System public synchronized static MSystem get (Properties ctx) { if (s_system.get(0) != null) - return s_system.get(0); + return new MSystem(ctx, s_system.get(0)); // MSystem system = new Query(ctx, Table_Name, null, null) .setOrderBy(COLUMNNAME_AD_System_ID) @@ -78,7 +78,7 @@ public class MSystem extends X_AD_System { system.saveEx(); } - s_system.put(0, system); + s_system.put(0, new MSystem(Env.getCtx(), system)); return system; } // get @@ -113,6 +113,37 @@ public class MSystem extends X_AD_System s_system.put(0, this); } // MSystem + /** + * + * @param copy + */ + public MSystem(MSystem copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MSystem(Properties ctx, MSystem copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MSystem(Properties ctx, MSystem copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Is LDAP Authentification defined * @return true if ldap defined diff --git a/org.adempiere.base/src/org/compiere/model/MTab.java b/org.adempiere.base/src/org/compiere/model/MTab.java index af504f96d0..f9f56a86bb 100644 --- a/org.adempiere.base/src/org/compiere/model/MTab.java +++ b/org.adempiere.base/src/org/compiere/model/MTab.java @@ -20,12 +20,15 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Properties; import java.util.logging.Level; import org.adempiere.exceptions.FillMandatoryException; import org.compiere.util.CLogger; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; /** * Tab Model @@ -36,12 +39,12 @@ import org.compiere.util.DB; *
  • http://sourceforge.net/tracker/?func=detail&atid=879335&aid=2826384&group_id=176962 * @version $Id: MTab.java,v 1.2 2006/07/30 00:58:37 jjanke Exp $ */ -public class MTab extends X_AD_Tab +public class MTab extends X_AD_Tab implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -2964171360368660043L; + private static final long serialVersionUID = -8111075325920938135L; /** * Standard Constructor @@ -107,6 +110,37 @@ public class MTab extends X_AD_Tab setEntityType(parent.getEntityType()); } // M_Tab + /** + * + * @param copy + */ + public MTab(MTab copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MTab(Properties ctx, MTab copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MTab(Properties ctx, MTab copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_fields = copy.m_fields != null ? Arrays.stream(copy.m_fields).map(e -> {return new MField(ctx, e, trxName);}).toArray(MField[]::new) : null; + } /** The Fields */ private MField[] m_fields = null; @@ -226,5 +260,13 @@ public class MTab extends X_AD_Tab return parentTabID; } + @Override + public MTab markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } } // M_Tab diff --git a/org.adempiere.base/src/org/compiere/model/MTable.java b/org.adempiere.base/src/org/compiere/model/MTable.java index 8a66993167..1ef26f3616 100644 --- a/org.adempiere.base/src/org/compiere/model/MTable.java +++ b/org.adempiere.base/src/org/compiere/model/MTable.java @@ -20,6 +20,7 @@ package org.compiere.model; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -34,13 +35,14 @@ import org.adempiere.base.Service; import org.adempiere.model.GenericPO; import org.compiere.db.AdempiereDatabase; import org.compiere.db.Database; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.KeyNamePair; import org.compiere.util.Msg; import org.compiere.util.Util; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Persistent Table Model @@ -58,17 +60,27 @@ import org.compiere.util.Util; * https://sourceforge.net/tracker/?func=detail&aid=3017117&group_id=176962&atid=879332 * @version $Id: MTable.java,v 1.3 2006/07/30 00:58:04 jjanke Exp $ */ -public class MTable extends X_AD_Table +public class MTable extends X_AD_Table implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 4736882280922026772L; + private static final long serialVersionUID = -4037560922339534982L; public final static int MAX_OFFICIAL_ID = 999999; /** - * Get Table from Cache + * Get Table from Cache (immutable) + * @param AD_Table_ID id + * @return MTable + */ + public static MTable get (int AD_Table_ID) + { + return get(Env.getCtx(), AD_Table_ID); + } + + /** + * Get Table from Cache (immutable) * @param ctx context * @param AD_Table_ID id * @return MTable @@ -79,7 +91,7 @@ public class MTable extends X_AD_Table } // get /** - * Get Table from Cache + * Get Table from Cache (immutable) * @param ctx context * @param AD_Table_ID id * @param trxName transaction @@ -88,19 +100,34 @@ public class MTable extends X_AD_Table public static synchronized MTable get (Properties ctx, int AD_Table_ID, String trxName) { Integer key = Integer.valueOf(AD_Table_ID); - MTable retValue = s_cache.get (key); - if (retValue != null && retValue.getCtx() == ctx) { - if (trxName != null) - retValue.set_TrxName(trxName); + MTable retValue = s_cache.get (ctx, key, e -> new MTable(ctx, e)); + if (retValue != null) + return retValue; + + retValue = new MTable (ctx, AD_Table_ID, trxName); + if (retValue.get_ID () == AD_Table_ID) + { + s_cache.put (key, retValue, e -> new MTable(Env.getCtx(), e)); return retValue; } - retValue = new MTable (ctx, AD_Table_ID, trxName); - if (retValue.get_ID () != 0) { - s_cache.put (key, retValue); - } - return retValue; + return null; } // get + /** + * Get updateable copy of MTable from cache + * @param ctx + * @param AD_Table_ID + * @param trxName + * @return MTable + */ + public static MTable getCopy(Properties ctx, int AD_Table_ID, String trxName) + { + MTable table = get(ctx, AD_Table_ID, trxName); + if (table != null) + table = new MTable(ctx, table, trxName); + return table; + } + /** * Get Table from Cache * @param ctx context @@ -177,7 +204,7 @@ public class MTable extends X_AD_Table /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** Static Logger */ private static CLogger s_log = CLogger.getCLogger (MTable.class); @@ -237,6 +264,42 @@ public class MTable extends X_AD_Table super(ctx, rs, trxName); } // MTable + /** + * + * @param copy + */ + public MTable(MTable copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MTable(Properties ctx, MTable copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MTable(Properties ctx, MTable copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_columns = copy.m_columns != null ? Arrays.stream(copy.m_columns).map(e -> {return new MColumn(ctx, e, trxName);}).toArray(MColumn[]::new): null; + this.m_columnNameMap = copy.m_columnNameMap != null ? new HashMap(copy.m_columnNameMap) : null; + this.m_columnIdMap = copy.m_columnIdMap != null ? new HashMap(copy.m_columnIdMap) : null; + this.m_viewComponents = copy.m_viewComponents != null ? Arrays.stream(copy.m_viewComponents).map(e -> {return new MViewComponent(ctx, e, trxName);}).toArray(MViewComponent[]::new) : null; + } + + /** Columns */ private MColumn[] m_columns = null; /** column name to index map **/ @@ -268,6 +331,8 @@ public class MTable extends X_AD_Table rs = pstmt.executeQuery (); while (rs.next ()) { MColumn column = new MColumn (getCtx(), rs, get_TrxName()); + if (is_Immutable()) + column.markImmutable(); list.add (column); m_columnNameMap.put(column.getColumnName().toUpperCase(), list.size() - 1); m_columnIdMap.put(column.getAD_Column_ID(), list.size() - 1); @@ -283,6 +348,8 @@ public class MTable extends X_AD_Table rs = null; pstmt = null; } // + if (list.size() > 0 && is_Immutable()) + list.stream().forEach(e -> e.markImmutable()); m_columns = new MColumn[list.size ()]; list.toArray (m_columns); return m_columns; @@ -630,7 +697,9 @@ public class MTable extends X_AD_Table query.setParameters(getAD_Table_ID()); query.setOrderBy(MViewComponent.COLUMNNAME_SeqNo); query.setOnlyActiveRecords(true); - List list = query.list(); + List list = query.list(); + if (list.size() > 0 && is_Immutable()) + list.stream().forEach(e -> e.markImmutable()); m_viewComponents = new MViewComponent[list.size()]; list.toArray(m_viewComponents); @@ -669,4 +738,18 @@ public class MTable extends X_AD_Table tablename.equals("M_AttributeSetInstance")); } + @Override + public MTable markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_columns != null && m_columns.length > 0) + Arrays.stream(m_columns).forEach(e -> e.markImmutable()); + if (m_viewComponents != null && m_viewComponents.length > 0) + Arrays.stream(m_viewComponents).forEach(e -> e.markImmutable()); + return this; + } + + } // MTable diff --git a/org.adempiere.base/src/org/compiere/model/MTableScriptValidator.java b/org.adempiere.base/src/org/compiere/model/MTableScriptValidator.java index 4d91c0fd51..bb3e495013 100644 --- a/org.adempiere.base/src/org/compiere/model/MTableScriptValidator.java +++ b/org.adempiere.base/src/org/compiere/model/MTableScriptValidator.java @@ -18,12 +18,17 @@ package org.compiere.model; import java.sql.ResultSet; +import java.util.ArrayList; import java.util.List; import java.util.Properties; +import java.util.stream.Collectors; import org.apache.commons.collections.keyvalue.MultiKey; import org.compiere.util.CCache; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Table Validator Scripts @@ -35,15 +40,25 @@ import org.compiere.util.DB; *
  • BF [ 2819654 ] Table Script Validator SeqNo is not set * https://sourceforge.net/tracker/?func=detail&atid=879332&aid=2819654&group_id=176962 */ -public class MTableScriptValidator extends X_AD_Table_ScriptValidator +public class MTableScriptValidator extends X_AD_Table_ScriptValidator implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 6272423660330749776L; + private static final long serialVersionUID = 6776991549481106111L; /** - * Get table script validator from cache + * Get table script validator from cache (immutable) + * @param AD_Table_ScriptValidator_ID id + * @return MTableScriptValidator + */ + public static MTableScriptValidator get (int AD_Table_ScriptValidator_ID) + { + return get(Env.getCtx(), AD_Table_ScriptValidator_ID); + } + + /** + * Get table script validator from cache (immutable) * @param ctx context * @param AD_Table_ScriptValidator_ID id * @return MTableScriptValidator @@ -51,13 +66,16 @@ public class MTableScriptValidator extends X_AD_Table_ScriptValidator public static MTableScriptValidator get (Properties ctx, int AD_Table_ScriptValidator_ID) { final Integer key = AD_Table_ScriptValidator_ID; - MTableScriptValidator retValue = (MTableScriptValidator) s_cache.get (key); + MTableScriptValidator retValue = s_cache.get (ctx, key, e -> new MTableScriptValidator(ctx, e)); if (retValue != null) return retValue; - retValue = new MTableScriptValidator (ctx, AD_Table_ScriptValidator_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MTableScriptValidator (ctx, AD_Table_ScriptValidator_ID, (String)null); + if (retValue.get_ID () == AD_Table_ScriptValidator_ID) + { + s_cache.put (key, retValue, e -> new MTableScriptValidator(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** @@ -74,10 +92,7 @@ public class MTableScriptValidator extends X_AD_Table_ScriptValidator List mvrs = s_cacheTableEvent.get(key); if (mvrs != null) { - if (mvrs.size() > 0) - return mvrs; - else - return null; + return mvrs; } // // Fetch now @@ -90,12 +105,17 @@ public class MTableScriptValidator extends X_AD_Table_ScriptValidator // Store to cache for (MTableScriptValidator rule : mvrs) { - s_cache.put(rule.get_ID(), rule); + s_cache.put(rule.get_ID(), rule, e -> new MTableScriptValidator(Env.getCtx(), e)); } // Store to cache if (mvrs != null) - s_cacheTableEvent.put(key, mvrs); + { + if (ctx == Env.getCtx()) + s_cacheTableEvent.put(key, mvrs.stream().collect(Collectors.toCollection(ArrayList::new))); + else + s_cacheTableEvent.put(key, mvrs.stream().map(e ->{return (MTableScriptValidator)new MTableScriptValidator(Env.getCtx(), e).markImmutable();}).collect(Collectors.toCollection(ArrayList::new))); + } // if (mvrs != null && mvrs.size() > 0) return mvrs; @@ -104,8 +124,8 @@ public class MTableScriptValidator extends X_AD_Table_ScriptValidator } // getModelValidatorRules /** Cache */ - private static CCache s_cache - = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache + = new ImmutableIntPOCache(Table_Name, 20); /** Cache / Table Event */ private static CCache> s_cacheTableEvent = new CCache>(null, Table_Name+"_TableEvent", 20, false); @@ -132,6 +152,37 @@ public class MTableScriptValidator extends X_AD_Table_ScriptValidator super(ctx, rs, trxName); } // MTableScriptValidator + /** + * + * @param copy + */ + public MTableScriptValidator(MTableScriptValidator copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MTableScriptValidator(Properties ctx, MTableScriptValidator copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MTableScriptValidator(Properties ctx, MTableScriptValidator copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + @Override protected boolean beforeSave(boolean newRecord) { @@ -154,4 +205,14 @@ public class MTableScriptValidator extends X_AD_Table_ScriptValidator .append(getEventModelValidator()).append("]"); return sb.toString (); } // toString + + @Override + public MTableScriptValidator markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MTableScriptValidator \ No newline at end of file diff --git a/org.adempiere.base/src/org/compiere/model/MTax.java b/org.adempiere.base/src/org/compiere/model/MTax.java index 00839e3ed6..2feaae8d20 100644 --- a/org.adempiere.base/src/org/compiere/model/MTax.java +++ b/org.adempiere.base/src/org/compiere/model/MTax.java @@ -19,6 +19,7 @@ package org.compiere.model; import java.math.BigDecimal; import java.math.RoundingMode; import java.sql.ResultSet; +import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.logging.Level; @@ -27,6 +28,8 @@ import org.compiere.util.CCache; import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.TimeUtil; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Tax Model @@ -37,15 +40,14 @@ import org.compiere.util.TimeUtil; * trifonnt - BF [2913276] - Allow only one Default Tax Rate per Tax Category * mjmckay - BF [2948632] - Allow edits to the Default Tax Rate */ -public class MTax extends X_C_Tax +public class MTax extends X_C_Tax implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 5871827364071851846L; - + private static final long serialVersionUID = -7971399495606742382L; /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 5); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 5); /** Cache of Client */ private static CCache s_cacheAll = new CCache(Table_Name, Table_Name+"_Of_Client", 5); @@ -65,7 +67,12 @@ public class MTax extends X_C_Tax int AD_Client_ID = Env.getAD_Client_ID(ctx); MTax[] retValue = (MTax[])s_cacheAll.get(AD_Client_ID); if (retValue != null) - return retValue; + { + if (ctx == Env.getCtx()) + return retValue; + else + return Arrays.stream(retValue).map(e -> {return new MTax(ctx, e).markImmutable();}).toArray(MTax[]::new); + } // Create it //FR: [ 2214883 ] Remove SQL code and Replace for Query - red1 @@ -76,16 +83,28 @@ public class MTax extends X_C_Tax .list(); for (MTax tax : list) { - s_cache.put(tax.get_ID(), tax); + s_cache.put(tax.get_ID(), tax, e -> new MTax(Env.getCtx(), e)); } retValue = list.toArray(new MTax[list.size()]); - s_cacheAll.put(AD_Client_ID, retValue); + if (ctx == Env.getCtx()) + s_cacheAll.put(AD_Client_ID, retValue); + else + s_cacheAll.put(AD_Client_ID, Arrays.stream(retValue).map(e -> {return new MTax(Env.getCtx(), e);}).toArray(MTax[]::new)); return retValue; } // getAll + /** + * Get Tax from Cache (immutable) + * @param C_Tax_ID id + * @return MTax + */ + public static MTax get (int C_Tax_ID) + { + return get(Env.getCtx(), C_Tax_ID); + } /** - * Get Tax from Cache + * Get Tax from Cache (immutable) * @param ctx context * @param C_Tax_ID id * @return MTax @@ -93,15 +112,33 @@ public class MTax extends X_C_Tax public static MTax get (Properties ctx, int C_Tax_ID) { Integer key = Integer.valueOf(C_Tax_ID); - MTax retValue = (MTax) s_cache.get (key); + MTax retValue = s_cache.get (ctx, key, e -> new MTax(ctx, e)); if (retValue != null) return retValue; - retValue = new MTax (ctx, C_Tax_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MTax (ctx, C_Tax_ID, (String)null); + if (retValue.get_ID () == C_Tax_ID) + { + s_cache.put (key, retValue, e -> new MTax(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MTax from cache + * @param ctx + * @param C_Tax_ID + * @param trxName + * @return MTax + */ + public static MTax getCopy(Properties ctx, int C_Tax_ID, String trxName) + { + MTax tax = get(C_Tax_ID); + if (tax != null) + tax = new MTax(ctx, tax, trxName); + return tax; + } + /************************************************************************** * Standard Constructor * @param ctx context @@ -155,6 +192,40 @@ public class MTax extends X_C_Tax setC_TaxCategory_ID (C_TaxCategory_ID); // FK } // MTax + /** + * + * @param copy + */ + public MTax(MTax copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MTax(Properties ctx, MTax copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MTax(Properties ctx, MTax copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_childTaxes = copy.m_childTaxes != null ? Arrays.stream(copy.m_childTaxes).map(e -> {return new MTax(ctx, e, trxName);}).toArray(MTax[]::new) : null; + this.m_postals = copy.m_postals != null ? Arrays.stream(copy.m_postals).map(e -> {return new MTaxPostal(ctx, e, trxName);}).toArray(MTaxPostal[]::new) : null; + } + + /** * Get Child Taxes * @param requery reload @@ -174,6 +245,8 @@ public class MTax extends X_C_Tax .setOnlyActiveRecords(true) .list(); //red1 - end - + if (list.size() > 0 && is_Immutable()) + list.stream().forEach(e -> e.markImmutable()); m_childTaxes = new MTax[list.size ()]; list.toArray (m_childTaxes); @@ -198,6 +271,8 @@ public class MTax extends X_C_Tax .setOrderBy(I_C_TaxPostal.COLUMNNAME_Postal+", "+I_C_TaxPostal.COLUMNNAME_Postal_To) .list(); //red1 - end - + if (list.size() > 0 && is_Immutable()) + list.stream().forEach(e -> e.markImmutable()); if (list.size() > 0) { m_postals = new MTaxPostal[list.size ()]; @@ -326,4 +401,18 @@ public class MTax extends X_C_Tax return success; } // afterSave + @Override + public MTax markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_childTaxes != null && m_childTaxes.length > 0) + Arrays.stream(m_childTaxes).forEach(e -> e.markImmutable()); + if (m_postals != null && m_postals.length > 0) + Arrays.stream(m_postals).forEach(e -> e.markImmutable()); + + return this; + } + } // MTax diff --git a/org.adempiere.base/src/org/compiere/model/MTaxPostal.java b/org.adempiere.base/src/org/compiere/model/MTaxPostal.java index 3f5852b331..cc8b8867c8 100644 --- a/org.adempiere.base/src/org/compiere/model/MTaxPostal.java +++ b/org.adempiere.base/src/org/compiere/model/MTaxPostal.java @@ -19,6 +19,9 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; + /** * Tax Postal Model @@ -26,12 +29,12 @@ import java.util.Properties; * @author Jorg Janke * @version $Id: MTaxPostal.java,v 1.3 2006/07/30 00:51:02 jjanke Exp $ */ -public class MTaxPostal extends X_C_TaxPostal +public class MTaxPostal extends X_C_TaxPostal implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -7048614254051075174L; + private static final long serialVersionUID = 2517717028191578304L; /** * Standard Constructor @@ -55,4 +58,44 @@ public class MTaxPostal extends X_C_TaxPostal super(ctx, rs, trxName); } // MTaxPostal + /** + * + * @param copy + */ + public MTaxPostal(MTaxPostal copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MTaxPostal(Properties ctx, MTaxPostal copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MTaxPostal(Properties ctx, MTaxPostal copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + @Override + public MTaxPostal markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MTaxPostal diff --git a/org.adempiere.base/src/org/compiere/model/MTree_Base.java b/org.adempiere.base/src/org/compiere/model/MTree_Base.java index 6f06f5abc5..30d817a2f0 100644 --- a/org.adempiere.base/src/org/compiere/model/MTree_Base.java +++ b/org.adempiere.base/src/org/compiere/model/MTree_Base.java @@ -19,8 +19,10 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Base Tree Model. @@ -29,14 +31,12 @@ import org.compiere.util.DB; * @author Jorg Janke * @version $Id: MTree_Base.java,v 1.2 2006/07/30 00:58:37 jjanke Exp $ */ -public class MTree_Base extends X_AD_Tree +public class MTree_Base extends X_AD_Tree implements ImmutablePOSupport { - /** * */ - private static final long serialVersionUID = -7657958239525901547L; - + private static final long serialVersionUID = -6785430530028279055L; /** * Add Node to correct tree @@ -196,7 +196,28 @@ public class MTree_Base extends X_AD_Tree } // getSourceTableName /** - * Get MTree_Base from Cache + * Get MTree_Base from Cache (immutable) + * @param AD_Tree_ID id + * @return MTree_Base + */ + public static MTree_Base get (int AD_Tree_ID) + { + return get(AD_Tree_ID, (String)null); + } + + /** + * Get MTree_Base from Cache (immutable) + * @param AD_Tree_ID id + * @param trxName transaction + * @return MTree_Base + */ + public static MTree_Base get (int AD_Tree_ID, String trxName) + { + return get(Env.getCtx(), AD_Tree_ID, trxName); + } + + /** + * Get MTree_Base from Cache (immutable) * @param ctx context * @param AD_Tree_ID id * @param trxName transaction @@ -205,18 +226,21 @@ public class MTree_Base extends X_AD_Tree public static MTree_Base get (Properties ctx, int AD_Tree_ID, String trxName) { Integer key = Integer.valueOf(AD_Tree_ID); - MTree_Base retValue = (MTree_Base) s_cache.get (key); + MTree_Base retValue = s_cache.get (ctx, key, e -> new MTree_Base(ctx, e)); if (retValue != null) return retValue; retValue = new MTree_Base (ctx, AD_Tree_ID, trxName); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + if (retValue.get_ID () == AD_Tree_ID) + { + s_cache.put (key, retValue, e -> new MTree_Base(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 10); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 10); /************************************************************************** @@ -279,6 +303,36 @@ public class MTree_Base extends X_AD_Tree setIsDefault(false); } // MTree_Base + /** + * + * @param copy + */ + public MTree_Base(MTree_Base copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MTree_Base(Properties ctx, MTree_Base copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MTree_Base(Properties ctx, MTree_Base copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } /** * Get Node TableName @@ -408,6 +462,15 @@ public class MTree_Base extends X_AD_Tree return success; } // afterSave + @Override + public MTree_Base markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + /** Returns true if should load all tree nodes immediately */ public static boolean isLoadAllNodesImmediately(int treeID, String trxName) { return DB.getSQLValueStringEx(trxName, "SELECT IsLoadAllNodesImmediately FROM AD_Tree WHERE AD_Tree_ID = ?", treeID).equals("Y"); diff --git a/org.adempiere.base/src/org/compiere/model/MUOM.java b/org.adempiere.base/src/org/compiere/model/MUOM.java index d9b4034b7e..26a4629758 100644 --- a/org.adempiere.base/src/org/compiere/model/MUOM.java +++ b/org.adempiere.base/src/org/compiere/model/MUOM.java @@ -23,10 +23,10 @@ import java.util.Iterator; import java.util.List; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.DB; import org.compiere.util.Env; -import org.compiere.util.Ini; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Unit Of Measure Model @@ -34,12 +34,12 @@ import org.compiere.util.Ini; * @author Jorg Janke * @version $Id: MUOM.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $ */ -public class MUOM extends X_C_UOM +public class MUOM extends X_C_UOM implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 3119054530389871561L; + private static final long serialVersionUID = 6277867983718121588L; /** X12 Element 355 Code Second */ public static final String X12_SECOND = "03"; /** X12 Element 355 Code Minute */ @@ -66,7 +66,7 @@ public class MUOM extends X_C_UOM */ public static int getMinute_UOM_ID (Properties ctx) { - if (Ini.isClient()) + synchronized (MUOM.class) { Iterator it = s_cache.values().iterator(); while (it.hasNext()) @@ -98,26 +98,40 @@ public class MUOM extends X_C_UOM /*************************************************************************/ /** UOM Cache */ - protected static CCache s_cache = new CCache(Table_Name, 30); + protected static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 30); /** - * Get UOM from Cache + * Get UOM from Cache (immutable) + * @param C_UOM_ID ID + * @return UOM + */ + public static synchronized MUOM get (int C_UOM_ID) + { + return get(Env.getCtx(), C_UOM_ID); + } + + /** + * Get UOM from Cache (immutable) * @param ctx context * @param C_UOM_ID ID * @return UOM */ - public static MUOM get (Properties ctx, int C_UOM_ID) + public static synchronized MUOM get (Properties ctx, int C_UOM_ID) { if (s_cache.size() == 0) loadUOMs (ctx); // - MUOM uom = s_cache.get(C_UOM_ID); + MUOM uom = s_cache.get(ctx, C_UOM_ID, e -> new MUOM(ctx, e)); if (uom != null) return uom; // - uom = new MUOM (ctx, C_UOM_ID, null); - s_cache.put(C_UOM_ID, uom); - return uom; + uom = new MUOM (ctx, C_UOM_ID, (String)null); + if (uom.get_ID() == C_UOM_ID) + { + s_cache.put(C_UOM_ID, uom, e -> new MUOM(Env.getCtx(), e)); + return uom; + } + return null; } // get /** @@ -151,14 +165,14 @@ public class MUOM extends X_C_UOM * Load All UOMs * @param ctx context */ - protected static void loadUOMs (Properties ctx) + protected static synchronized void loadUOMs (Properties ctx) { List list = new Query(ctx, Table_Name, "IsActive='Y'", null) .setApplyAccessFilter(MRole.SQL_NOTQUALIFIED, MRole.SQL_RO) .list(); // for (MUOM uom : list) { - s_cache.put(uom.get_ID(), uom); + s_cache.put(uom.get_ID(), uom, e -> new MUOM(Env.getCtx(), e)); } } // loadUOMs @@ -193,6 +207,37 @@ public class MUOM extends X_C_UOM super(ctx, rs, trxName); } // UOM + /** + * + * @param copy + */ + public MUOM(MUOM copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MUOM(Properties ctx, MUOM copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MUOM(Properties ctx, MUOM copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * String Representation * @return info @@ -294,4 +339,13 @@ public class MUOM extends X_C_UOM return X12_YEAR.equals(getX12DE355()); } + @Override + public MUOM markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MUOM diff --git a/org.adempiere.base/src/org/compiere/model/MUOMConversion.java b/org.adempiere.base/src/org/compiere/model/MUOMConversion.java index 58eaf42263..2caca136d5 100644 --- a/org.adempiere.base/src/org/compiere/model/MUOMConversion.java +++ b/org.adempiere.base/src/org/compiere/model/MUOMConversion.java @@ -24,6 +24,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.List; @@ -37,6 +38,7 @@ import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Ini; import org.compiere.util.Msg; +import org.idempiere.cache.ImmutablePOSupport; /** * Unit of Measure Conversion Model @@ -44,13 +46,12 @@ import org.compiere.util.Msg; * @author Jorg Janke * @version $Id: MUOMConversion.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $ */ -public class MUOMConversion extends X_C_UOM_Conversion +public class MUOMConversion extends X_C_UOM_Conversion implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 3555218774291122619L; - + private static final long serialVersionUID = 1772365359514185604L; /** * Convert qty to target UOM and round. @@ -605,7 +606,12 @@ public class MUOMConversion extends X_C_UOM_Conversion Integer key = Integer.valueOf(M_Product_ID); MUOMConversion[] result = (MUOMConversion[])s_conversionProduct.get(key); if (result != null) - return result; + { + if (ctx == Env.getCtx()) + return result; + else + return Arrays.stream(result).map(e -> {return new MUOMConversion(ctx, e).markImmutable();}).toArray(MUOMConversion[]::new); + } ArrayList list = new ArrayList(); // Add default conversion @@ -620,11 +626,15 @@ public class MUOMConversion extends X_C_UOM_Conversion .setOnlyActiveRecords(true) .list(); list.addAll(conversions); + list.stream().forEach(e -> e.markImmutable()); // Convert & save result = new MUOMConversion[list.size ()]; list.toArray (result); - s_conversionProduct.put(key, result); + if (ctx == Env.getCtx()) + s_conversionProduct.put(key, result); + else + s_conversionProduct.put(key, Arrays.stream(result).map(e -> {return new MUOMConversion(Env.getCtx(), e);}).toArray(MUOMConversion[]::new)); if (s_log.isLoggable(Level.FINE)) s_log.fine("getProductConversions - M_Product_ID=" + M_Product_ID + " #" + result.length); return result; } // getProductConversions @@ -694,6 +704,37 @@ public class MUOMConversion extends X_C_UOM_Conversion setDivideRate(Env.ONE); } // MUOMConversion + /** + * + * @param copy + */ + public MUOMConversion(MUOMConversion copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MUOMConversion(Properties ctx, MUOMConversion copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MUOMConversion(Properties ctx, MUOMConversion copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Before Save * @param newRecord new @@ -759,4 +800,13 @@ public class MUOMConversion extends X_C_UOM_Conversion return sb.toString (); } // toString + @Override + public MUOMConversion markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // UOMConversion diff --git a/org.adempiere.base/src/org/compiere/model/MUser.java b/org.adempiere.base/src/org/compiere/model/MUser.java index 9c4842d733..a0acf66080 100644 --- a/org.adempiere.base/src/org/compiere/model/MUser.java +++ b/org.adempiere.base/src/org/compiere/model/MUser.java @@ -23,6 +23,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Properties; @@ -33,7 +34,6 @@ import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import org.adempiere.exceptions.DBException; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.EMail; @@ -42,6 +42,8 @@ import org.compiere.util.Msg; import org.compiere.util.Secure; import org.compiere.util.SecureEngine; import org.compiere.util.Util; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * User Model @@ -53,12 +55,12 @@ import org.compiere.util.Util; *
  • FR [ 2788430 ] MUser.getOfBPartner add trxName parameter * https://sourceforge.net/tracker/index.php?func=detail&aid=2788430&group_id=176962&atid=879335 */ -public class MUser extends X_AD_User +public class MUser extends X_AD_User implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 1366564982801896588L; + private static final long serialVersionUID = 1351277092193923708L; /** * Get active Users of BPartner @@ -128,7 +130,18 @@ public class MUser extends X_AD_User } // getWithRole /** - * Get User (cached) + * Get User (cached) (immutable) + * Also loads Admninistrator (0) + * @param AD_User_ID id + * @return user + */ + public static MUser get (int AD_User_ID) + { + return get(Env.getCtx(), AD_User_ID); + } + + /** + * Get User (cached) (immutable) * Also loads Admninistrator (0) * @param ctx context * @param AD_User_ID id @@ -137,16 +150,21 @@ public class MUser extends X_AD_User public static MUser get (Properties ctx, int AD_User_ID) { Integer key = Integer.valueOf(AD_User_ID); - MUser retValue = (MUser)s_cache.get(key); + MUser retValue = s_cache.get(ctx, key, e -> new MUser(ctx, e)); if (retValue == null) { - retValue = new MUser (ctx, AD_User_ID, null); + retValue = new MUser (ctx, AD_User_ID, (String)null); if (AD_User_ID == 0) { String trxName = null; retValue.load(trxName); // load System Record } - s_cache.put(key, retValue); + if (retValue.get_ID() == AD_User_ID) + { + s_cache.put(key, retValue, e -> new MUser(Env.getCtx(), e)); + return retValue; + } + return null; } return retValue; } // get @@ -161,6 +179,21 @@ public class MUser extends X_AD_User return get(ctx, Env.getAD_User_ID(ctx)); } // get + /** + * Get updateable copy of MUser from cache + * @param ctx + * @param AD_User_ID + * @param trxName + * @return MUser + */ + public static MUser getCopy(Properties ctx, int AD_User_ID, String trxName) + { + MUser user = get(AD_User_ID); + if (user != null) + user = new MUser(ctx, user, trxName); + return user; + } + /** * Get User * @param ctx context @@ -267,7 +300,7 @@ public class MUser extends X_AD_User } // isSalesRep /** Cache */ - static private CCache s_cache = new CCache(Table_Name, 30, 60); + static private ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 30, 60); /** Static Logger */ private static CLogger s_log = CLogger.getCLogger (MUser.class); @@ -311,6 +344,41 @@ public class MUser extends X_AD_User super(ctx, rs, trxName); } // MUser + /** + * + * @param copy + */ + public MUser(MUser copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MUser(Properties ctx, MUser copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MUser(Properties ctx, MUser copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_roles = copy.m_roles != null ? Arrays.stream(copy.m_roles).map(e ->{return new MRole(ctx, e, trxName);}).toArray(MRole[]::new) : null; + this.m_rolesAD_Org_ID = copy.m_rolesAD_Org_ID; + this.m_isAdministrator = copy.m_isAdministrator; + this.m_bpAccess = copy.m_bpAccess != null ? Arrays.copyOf(copy.m_bpAccess, copy.m_bpAccess.length) : null; + } + /** Roles of User with Org */ private MRole[] m_roles = null; /** Roles of User with Org */ @@ -318,7 +386,7 @@ public class MUser extends X_AD_User /** Is Administrator */ private Boolean m_isAdministrator = null; /** User Access Rights */ - private X_AD_UserBPAccess[] m_bpAccess = null; + private MUserBPAccess[] m_bpAccess = null; /** Password Hashed **/ private boolean being_hashed = false; @@ -755,7 +823,7 @@ public class MUser extends X_AD_User pstmt.setInt (4, AD_Org_ID); rs = pstmt.executeQuery (); while (rs.next ()) - list.add (new MRole(getCtx(), rs, get_TrxName())); + list.add (new MRole(Env.getCtx(), rs, get_TrxName())); } catch (Exception e) { @@ -767,6 +835,9 @@ public class MUser extends X_AD_User rs = null; pstmt = null; } // + if (list.size() > 0 && is_Immutable()) + list.stream().forEach(e -> e.markImmutable()); + m_rolesAD_Org_ID = AD_Org_ID; m_roles = new MRole[list.size()]; list.toArray (m_roles); @@ -848,12 +919,12 @@ public class MUser extends X_AD_User * @param requery requery * @return access list */ - public X_AD_UserBPAccess[] getBPAccess (boolean requery) + public MUserBPAccess[] getBPAccess (boolean requery) { if (m_bpAccess != null && !requery) return m_bpAccess; String sql = "SELECT * FROM AD_UserBPAccess WHERE AD_User_ID=? AND IsActive='Y'"; - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList(); PreparedStatement pstmt = null; ResultSet rs = null; try @@ -863,7 +934,7 @@ public class MUser extends X_AD_User rs = pstmt.executeQuery (); while (rs.next ()) { - list.add (new X_AD_UserBPAccess (getCtx(), rs, null)); + list.add (new MUserBPAccess (getCtx(), rs, null)); } } catch (Exception e) @@ -874,7 +945,11 @@ public class MUser extends X_AD_User { DB.close(rs, pstmt); } - m_bpAccess = new X_AD_UserBPAccess[list.size ()]; + + if (list.size() > 0 && is_Immutable()) + list.stream().forEach(e -> e.markImmutable()); + + m_bpAccess = new MUserBPAccess[list.size ()]; list.toArray (m_bpAccess); return m_bpAccess; } // getBPAccess @@ -1011,7 +1086,7 @@ public class MUser extends X_AD_User rs = pstmt.executeQuery (); if (rs.next()) { - retValue = MUser.get(ctx, rs.getInt(1)); + retValue = MUser.getCopy(ctx, rs.getInt(1), (String)null); if (rs.next()) s_log.warning ("More then one user with Name/Password = " + name); } @@ -1112,4 +1187,18 @@ public class MUser extends X_AD_User return true; } + @Override + public MUser markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_roles != null && m_roles.length > 0) + Arrays.stream(m_roles).forEach(e -> e.markImmutable()); + if (m_bpAccess != null && m_bpAccess.length > 0) + Arrays.stream(m_bpAccess).forEach(e -> e.markImmutable()); + + return this; + } + } // MUser diff --git a/org.adempiere.base/src/org/compiere/model/MUserBPAccess.java b/org.adempiere.base/src/org/compiere/model/MUserBPAccess.java new file mode 100644 index 0000000000..275de42c7b --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/MUserBPAccess.java @@ -0,0 +1,71 @@ +/********************************************************************** +* 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: * +* - Trek Global Corporation * +* - Heng Sin Low * +**********************************************************************/ +package org.compiere.model; + +import java.sql.ResultSet; +import java.util.Properties; + +import org.idempiere.cache.ImmutablePOSupport; + +/** + * @author hengsin + * + */ +public class MUserBPAccess extends X_AD_UserBPAccess implements ImmutablePOSupport { + + /** + * + */ + private static final long serialVersionUID = 4549943360035715233L; + + /** + * @param ctx + * @param AD_UserBPAccess_ID + * @param trxName + */ + public MUserBPAccess(Properties ctx, int AD_UserBPAccess_ID, String trxName) { + super(ctx, AD_UserBPAccess_ID, trxName); + } + + /** + * @param ctx + * @param rs + * @param trxName + */ + public MUserBPAccess(Properties ctx, ResultSet rs, String trxName) { + super(ctx, rs, trxName); + } + + @Override + public MUserBPAccess markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + +} diff --git a/org.adempiere.base/src/org/compiere/model/MUserDefProc.java b/org.adempiere.base/src/org/compiere/model/MUserDefProc.java index 402fc09d3f..ae35e695e9 100644 --- a/org.adempiere.base/src/org/compiere/model/MUserDefProc.java +++ b/org.adempiere.base/src/org/compiere/model/MUserDefProc.java @@ -18,8 +18,9 @@ import java.util.List; import java.util.Properties; import org.adempiere.exceptions.AdempiereException; -import org.compiere.util.CCache; import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.ImmutablePOCache; /** * Model class for Process Customizations @@ -27,12 +28,12 @@ import org.compiere.util.Env; * @author raphael.gildo (devCoffee, www.devcoffee.com.br) * */ -public class MUserDefProc extends X_AD_UserDef_Proc { +public class MUserDefProc extends X_AD_UserDef_Proc implements ImmutablePOSupport { /** - * + * */ - private static final long serialVersionUID = 2564901065651870698L; + private static final long serialVersionUID = 1599140293008534080L; private volatile static List m_fullList = null; /** @@ -55,6 +56,34 @@ public class MUserDefProc extends X_AD_UserDef_Proc { // TODO Auto-generated constructor stub } + /** + * + * @param copy + */ + public MUserDefProc(MUserDefProc copy) { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MUserDefProc(Properties ctx, MUserDefProc copy) { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MUserDefProc(Properties ctx, MUserDefProc copy, String trxName) { + this(ctx, 0, trxName); + copyPO(copy); + } + private static MUserDefProc[] getAll (Properties ctx, int processID) { if (m_fullList == null) { @@ -97,7 +126,7 @@ public class MUserDefProc extends X_AD_UserDef_Proc { .append(AD_User_ID) .toString(); if (s_cache.containsKey(key)) - return s_cache.get(key); + return s_cache.get(ctx, key, e -> new MUserDefProc(ctx, e)); //candidates MUserDefProc[] candidates = getAll(ctx, AD_Process_ID); @@ -160,7 +189,7 @@ public class MUserDefProc extends X_AD_UserDef_Proc { if (weight[maxindex] > -1) { MUserDefProc retValue = null; retValue = candidates[maxindex]; - s_cache.put(key, retValue); + s_cache.put(key, retValue, e -> new MUserDefProc(Env.getCtx(), e)); return retValue; } else { s_cache.put(key, null); @@ -169,7 +198,7 @@ public class MUserDefProc extends X_AD_UserDef_Proc { } //Cache of selected MUserDefProc entries **/ - private static CCache s_cache = new CCache(Table_Name, 3); // 3 weights + private static ImmutablePOCache s_cache = new ImmutablePOCache(Table_Name, 3); // 3 weights @Override protected boolean beforeSave(boolean newRecord) { @@ -206,4 +235,13 @@ public class MUserDefProc extends X_AD_UserDef_Proc { return true; } + @Override + public MUserDefProc markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } diff --git a/org.adempiere.base/src/org/compiere/model/MUserDefWin.java b/org.adempiere.base/src/org/compiere/model/MUserDefWin.java index 6948f6fdad..7b04fd4789 100644 --- a/org.adempiere.base/src/org/compiere/model/MUserDefWin.java +++ b/org.adempiere.base/src/org/compiere/model/MUserDefWin.java @@ -19,8 +19,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.ImmutablePOCache; /** * User overrides for window model @@ -28,13 +29,12 @@ import org.compiere.util.Env; * @version $Id$ * */ -public class MUserDefWin extends X_AD_UserDef_Win +public class MUserDefWin extends X_AD_UserDef_Win implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -5775251886672840324L; - + private static final long serialVersionUID = -7542708120229671875L; private volatile static List m_fullList = null; /** @@ -64,6 +64,37 @@ public class MUserDefWin extends X_AD_UserDef_Win super (ctx, rs, trxName); } // MUserDefWin + /** + * + * @param copy + */ + public MUserDefWin(MUserDefWin copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MUserDefWin(Properties ctx, MUserDefWin copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MUserDefWin(Properties ctx, MUserDefWin copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Get all MUserDefWin entries related to window * @param ctx context @@ -123,7 +154,7 @@ public class MUserDefWin extends X_AD_UserDef_Win .append(AD_User_ID) .toString(); if (s_cache.containsKey(key)) - return s_cache.get(key); + return s_cache.get(ctx, key, e -> new MUserDefWin(ctx, e)); // candidates MUserDefWin[] candidates = getAll(ctx, window_ID); @@ -186,7 +217,7 @@ public class MUserDefWin extends X_AD_UserDef_Win if (weight[maxindex] > -1) { MUserDefWin retValue = null; retValue=candidates[maxindex]; - s_cache.put(key, retValue); + s_cache.put(key, retValue, e -> new MUserDefWin(Env.getCtx(), e)); return retValue; } else { s_cache.put(key, null); @@ -195,7 +226,7 @@ public class MUserDefWin extends X_AD_UserDef_Win } /** Cache of selected MUserDefWin entries **/ - private static CCache s_cache = new CCache(Table_Name, 3); // 3 weights + private static ImmutablePOCache s_cache = new ImmutablePOCache(Table_Name, 3); // 3 weights @Override protected boolean beforeSave(boolean newRecord) { @@ -208,5 +239,15 @@ public class MUserDefWin extends X_AD_UserDef_Win m_fullList = null; return true; } - + + @Override + public MUserDefWin markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + + } // MUserDefWin diff --git a/org.adempiere.base/src/org/compiere/model/MValRule.java b/org.adempiere.base/src/org/compiere/model/MValRule.java index 672f79a37f..4abfafa859 100644 --- a/org.adempiere.base/src/org/compiere/model/MValRule.java +++ b/org.adempiere.base/src/org/compiere/model/MValRule.java @@ -27,41 +27,83 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; -import org.compiere.util.CCache; import org.compiere.util.CLogger; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Persistent Validation Rule Model * @author Carlos Ruiz * @version $Id: MValRule.java */ -public class MValRule extends X_AD_Val_Rule +public class MValRule extends X_AD_Val_Rule implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -8482599477870030638L; + private static final long serialVersionUID = -2475798196422214666L; /** - * Get Rule from Cache + * Get Rule from Cache (immutable) + * @param AD_Val_Rule_ID id + * @return MValRule + */ + public static MValRule get (int AD_Val_Rule_ID) + { + return get(Env.getCtx(), AD_Val_Rule_ID); + } + + /** + * Get Rule from Cache (immutable) * @param ctx context * @param AD_Val_Rule_ID id * @return MValRule */ public static MValRule get (Properties ctx, int AD_Val_Rule_ID) + { + return get(ctx, AD_Val_Rule_ID, (String)null); + } + + /** + * Get Rule from Cache (immutable) + * @param ctx context + * @param AD_Val_Rule_ID id + * @param trxName + * @return MValRule + */ + public static MValRule get (Properties ctx, int AD_Val_Rule_ID, String trxName) { Integer key = Integer.valueOf(AD_Val_Rule_ID); - MValRule retValue = (MValRule) s_cache.get (key); + MValRule retValue = s_cache.get (ctx, key, e -> new MValRule(ctx, e)); if (retValue != null) return retValue; - retValue = new MValRule (ctx, AD_Val_Rule_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MValRule (ctx, AD_Val_Rule_ID, trxName); + if (retValue.get_ID () == AD_Val_Rule_ID) + { + s_cache.put (key, retValue, e -> new MValRule(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MValRule from cache + * @param ctx + * @param AD_Val_Rule_ID + * @param trxName + * @return MValRule + */ + public static MValRule getCopy(Properties ctx, int AD_Val_Rule_ID, String trxName) + { + MValRule vr = get(ctx, AD_Val_Rule_ID, trxName); + if (vr != null) + vr = new MValRule(ctx, vr, trxName); + return vr; + } + /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** Static Logger */ @SuppressWarnings("unused") @@ -89,6 +131,46 @@ public class MValRule extends X_AD_Val_Rule super(ctx, rs, trxName); } // MValRule + /** + * + * @param copy + */ + public MValRule(MValRule copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MValRule(Properties ctx, MValRule copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MValRule(Properties ctx, MValRule copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + @Override + public MValRule markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + /** * String Representation * @return info diff --git a/org.adempiere.base/src/org/compiere/model/MViewColumn.java b/org.adempiere.base/src/org/compiere/model/MViewColumn.java index a712acfdd8..b256861692 100644 --- a/org.adempiere.base/src/org/compiere/model/MViewColumn.java +++ b/org.adempiere.base/src/org/compiere/model/MViewColumn.java @@ -20,15 +20,17 @@ import java.sql.ResultSet; import java.util.Properties; import org.compiere.db.Database; +import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.Util; +import org.idempiere.cache.ImmutablePOSupport; -public class MViewColumn extends X_AD_ViewColumn { +public class MViewColumn extends X_AD_ViewColumn implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -7325808411400037317L; + private static final long serialVersionUID = 4049071242637196213L; /** * Standard constructor @@ -63,6 +65,37 @@ public class MViewColumn extends X_AD_ViewColumn { setAD_ViewComponent_ID(parent.getAD_ViewComponent_ID()); } + /** + * + * @param copy + */ + public MViewColumn(MViewColumn copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MViewColumn(Properties ctx, MViewColumn copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MViewColumn(Properties ctx, MViewColumn copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * String representation * @return info @@ -92,4 +125,13 @@ public class MViewColumn extends X_AD_ViewColumn { return true; } + @Override + public MViewColumn markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } diff --git a/org.adempiere.base/src/org/compiere/model/MViewComponent.java b/org.adempiere.base/src/org/compiere/model/MViewComponent.java index add2a2d003..d05318ac92 100644 --- a/org.adempiere.base/src/org/compiere/model/MViewComponent.java +++ b/org.adempiere.base/src/org/compiere/model/MViewComponent.java @@ -17,19 +17,21 @@ package org.compiere.model; import java.sql.ResultSet; +import java.util.Arrays; import java.util.List; import java.util.Properties; import org.adempiere.exceptions.AdempiereException; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; -public class MViewComponent extends X_AD_ViewComponent { - +public class MViewComponent extends X_AD_ViewComponent implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -8915166706061086737L; + private static final long serialVersionUID = 1580063310233871896L; /** * Standard constructor @@ -64,6 +66,38 @@ public class MViewComponent extends X_AD_ViewComponent { setAD_Table_ID(parent.getAD_Table_ID()); } + /** + * + * @param copy + */ + public MViewComponent(MViewComponent copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MViewComponent(Properties ctx, MViewComponent copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MViewComponent(Properties ctx, MViewComponent copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_columns = copy.m_columns != null ? Arrays.stream(copy.m_columns).map(e -> {return new MViewColumn(ctx, e, trxName);}).toArray(MViewColumn[]::new) : null; + } + /** Columns */ private MViewColumn[] m_columns = null; @@ -82,6 +116,8 @@ public class MViewComponent extends X_AD_ViewComponent { query.setOnlyActiveRecords(true); query.setOrderBy("SeqNo, AD_ViewColumn_ID"); List list = query.list(); + if (list.size() > 0) + list.stream().forEach(e -> e.markImmutable()); m_columns = new MViewColumn[list.size()]; list.toArray(m_columns); @@ -160,6 +196,18 @@ public class MViewComponent extends X_AD_ViewComponent { return sb.toString(); } + + @Override + public MViewComponent markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_columns != null && m_columns.length > 0) + Arrays.stream(m_columns).forEach(e -> e.markImmutable()); + return this; + } + /** * String representation * @return info diff --git a/org.adempiere.base/src/org/compiere/model/MWarehouse.java b/org.adempiere.base/src/org/compiere/model/MWarehouse.java index 71382d3d0c..03006251ac 100644 --- a/org.adempiere.base/src/org/compiere/model/MWarehouse.java +++ b/org.adempiere.base/src/org/compiere/model/MWarehouse.java @@ -17,14 +17,16 @@ package org.compiere.model; import java.sql.ResultSet; +import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Warehouse Model @@ -36,15 +38,25 @@ import org.compiere.util.Msg; *
  • BF [ 1874419 ] JDBC Statement not close in a finally block * @version $Id: MWarehouse.java,v 1.3 2006/07/30 00:58:05 jjanke Exp $ */ -public class MWarehouse extends X_M_Warehouse +public class MWarehouse extends X_M_Warehouse implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -3065089372599460372L; - + private static final long serialVersionUID = 5425515002759989733L; + /** - * Get from Cache + * Get from Cache (immutable) + * @param M_Warehouse_ID id + * @return warehouse + */ + public static MWarehouse get (int M_Warehouse_ID) + { + return get(Env.getCtx(), M_Warehouse_ID); + } + + /** + * Get from Cache (immutable) * @param ctx context * @param M_Warehouse_ID id * @return warehouse @@ -55,7 +67,7 @@ public class MWarehouse extends X_M_Warehouse } /** - * Retrieves warehouse from cache under transaction scope + * Retrieves warehouse from cache (immutable) * @param ctx context * @param M_Warehouse_ID id of warehouse to load * @param trxName transaction name @@ -64,13 +76,17 @@ public class MWarehouse extends X_M_Warehouse public static MWarehouse get (Properties ctx, int M_Warehouse_ID, String trxName) { Integer key = Integer.valueOf(M_Warehouse_ID); - MWarehouse retValue = (MWarehouse)s_cache.get(key); + MWarehouse retValue = s_cache.get(ctx, key, e -> new MWarehouse(ctx, e)); if (retValue != null) return retValue; // retValue = new MWarehouse (ctx, M_Warehouse_ID, trxName); - s_cache.put (key, retValue); - return retValue; + if (retValue.get_ID() == M_Warehouse_ID) + { + s_cache.put (key, retValue, e -> new MWarehouse(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** @@ -109,7 +125,7 @@ public class MWarehouse extends X_M_Warehouse } // get /** Cache */ - protected static CCache s_cache = new CCache(Table_Name, 50 ); + protected static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 50 ); /** * Standard Constructor * @param ctx context @@ -153,6 +169,38 @@ public class MWarehouse extends X_M_Warehouse setC_Location_ID (org.getInfo().getC_Location_ID()); } // MWarehouse + /** + * + * @param copy + */ + public MWarehouse(MWarehouse copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MWarehouse(Properties ctx, MWarehouse copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MWarehouse(Properties ctx, MWarehouse copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_locators = copy.m_locators != null ? Arrays.stream(copy.m_locators).map(e -> {return new MLocator(ctx, e, trxName);}).toArray(MLocator[]::new) : null; + } + /** Warehouse Locators */ protected MLocator[] m_locators = null; @@ -172,6 +220,8 @@ public class MWarehouse extends X_M_Warehouse .setOnlyActiveRecords(true) .setOrderBy("X,Y,Z") .list(); + if (list.size() > 0 && is_Immutable()) + list.stream().forEach(e -> e.markImmutable()); m_locators = list.toArray(new MLocator[list.size()]); return m_locators; } // getLocators @@ -274,4 +324,18 @@ public class MWarehouse extends X_M_Warehouse return success; } // afterSave + @Override + public MWarehouse markImmutable() + { + if (this.is_Immutable()) + return this; + + makeImmutable(); + if (m_locators != null && m_locators.length > 0) + Arrays.stream(m_locators).forEach(e -> e.markImmutable()); + + return this; + } + + } // MWarehouse diff --git a/org.adempiere.base/src/org/compiere/model/MWindow.java b/org.adempiere.base/src/org/compiere/model/MWindow.java index 4fb81b4b00..07b71107ce 100644 --- a/org.adempiere.base/src/org/compiere/model/MWindow.java +++ b/org.adempiere.base/src/org/compiere/model/MWindow.java @@ -20,16 +20,18 @@ import java.awt.Dimension; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.Iterator; +import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; +import org.compiere.util.Util; import org.compiere.wf.MWFNode; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Window Model @@ -37,22 +39,31 @@ import org.compiere.wf.MWFNode; * @author Jorg Janke * @version $Id: MWindow.java,v 1.2 2006/07/30 00:58:05 jjanke Exp $ */ -public class MWindow extends X_AD_Window +public class MWindow extends X_AD_Window implements ImmutablePOSupport { - /** * */ - private static final long serialVersionUID = -9200113429427897527L; + private static final long serialVersionUID = -7482290667487859946L; /** Static Logger */ private static CLogger s_log = CLogger.getCLogger (MWindow.class); /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** - * Get Window from Cache + * Get Window from Cache (immutable) + * @param AD_Window_ID id + * @return MWindow + */ + public static MWindow get (int AD_Window_ID) + { + return get(Env.getCtx(), AD_Window_ID); + } + + /** + * Get Window from Cache (immutable) * @param ctx context * @param AD_Window_ID id * @return MWindow @@ -60,15 +71,16 @@ public class MWindow extends X_AD_Window public static MWindow get (Properties ctx, int AD_Window_ID) { Integer key = Integer.valueOf(AD_Window_ID); - MWindow retValue = s_cache.get (key); - if (retValue != null && retValue.getCtx() == ctx) { + MWindow retValue = s_cache.get (ctx, key, e -> new MWindow(ctx, e)); + if (retValue != null) + return retValue; + + retValue = new MWindow (ctx, AD_Window_ID, (String)null); + if (retValue.get_ID () == AD_Window_ID) { + s_cache.put (key, retValue, e -> new MWindow(Env.getCtx(), e)); return retValue; } - retValue = new MWindow (ctx, AD_Window_ID, null); - if (retValue.get_ID () != 0) { - s_cache.put (key, retValue); - } - return retValue; + return null; } // get /** @@ -77,30 +89,25 @@ public class MWindow extends X_AD_Window * @param uu AD_Window_UU * @return MWindow object */ - public static synchronized MWindow get(Properties ctx, String uu) + public static MWindow get(Properties ctx, String uu) { - if (uu == null) + if (Util.isEmpty(uu, true)) return null; - MWindow retValue = null; - Iterator it = s_cache.values().iterator(); - while (it.hasNext()) + MWindow[] it = s_cache.values().toArray(new MWindow[0]); + for (MWindow retValue : it) { - retValue = it.next(); - if (uu.equals(retValue.getAD_Window_UU()) && retValue.getCtx() == ctx) + if (uu.equals(retValue.getAD_Window_UU())) { - return retValue; + return new MWindow(ctx, retValue); } } final String whereClause = MWindow.COLUMNNAME_AD_Window_UU + "=?"; - MWindow window = new Query(Env.getCtx(), MWindow.Table_Name, whereClause, null) + MWindow retValue = new Query(ctx, MWindow.Table_Name, whereClause, (String)null) .setParameters(uu) .setOnlyActiveRecords(true) .first(); - if (window != null) - retValue = window; - return retValue; } @@ -133,6 +140,38 @@ public class MWindow extends X_AD_Window super(ctx, rs, trxName); } // M_Window + /** + * + * @param copy + */ + public MWindow(MWindow copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MWindow(Properties ctx, MWindow copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MWindow(Properties ctx, MWindow copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_tabs = copy.m_tabs != null ? Arrays.stream(copy.m_tabs).map(e -> {return new MTab(ctx, e, trxName);}).toArray(MTab[]::new) : null; + } + /** * Set Window Size * @param size size @@ -165,6 +204,8 @@ public class MWindow extends X_AD_Window .setOrderBy(I_AD_Tab.COLUMNNAME_SeqNo) .list(); // + if (list.size() > 0 && is_Immutable()) + list.stream().forEach(e -> e.markImmutable()); m_tabs = new MTab[list.size ()]; list.toArray (m_tabs); return m_tabs; @@ -276,4 +317,15 @@ public class MWindow extends X_AD_Window } //end vpj-cd e-evolution + @Override + public MWindow markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_tabs != null && m_tabs.length > 0) + Arrays.stream(m_tabs).forEach(e -> e.markImmutable()); + return this; + } + } // M_Window diff --git a/org.adempiere.base/src/org/compiere/model/MZoomCondition.java b/org.adempiere.base/src/org/compiere/model/MZoomCondition.java index 2984a57958..7aafe9c092 100644 --- a/org.adempiere.base/src/org/compiere/model/MZoomCondition.java +++ b/org.adempiere.base/src/org/compiere/model/MZoomCondition.java @@ -25,6 +25,7 @@ import org.compiere.util.Env; import org.compiere.util.Evaluatee; import org.compiere.util.Evaluator; import org.compiere.util.Util; +import org.idempiere.cache.ImmutablePOSupport; /** * Zoom Condition model @@ -32,12 +33,12 @@ import org.compiere.util.Util; * @author Nico * @version $Id: MZoomCondition.java */ -public class MZoomCondition extends X_AD_ZoomCondition +public class MZoomCondition extends X_AD_ZoomCondition implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 3077830061348224074L; + private static final long serialVersionUID = -2472970418557589702L; /************************************************************************** * Standard Constructor @@ -61,6 +62,37 @@ public class MZoomCondition extends X_AD_ZoomCondition super (ctx, rs, trxName); } // MZoomCondition + /** + * + * @param copy + */ + public MZoomCondition(MZoomCondition copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MZoomCondition(Properties ctx, MZoomCondition copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MZoomCondition(Properties ctx, MZoomCondition copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** Cache of Table Conditions Array **/ private static CCache s_conditions = new CCache(Table_Name, 0); @@ -79,8 +111,10 @@ public class MZoomCondition extends X_AD_ZoomCondition .setOnlyActiveRecords(true) .setOrderBy(MZoomCondition.COLUMNNAME_SeqNo) .list(); + list.stream().forEach(e -> e.markImmutable()); conditions = list.toArray(new MZoomCondition[list.size()]); s_conditions.put(AD_Table_ID, conditions); + return conditions; } return conditions; } // getConditions @@ -297,4 +331,14 @@ public class MZoomCondition extends X_AD_ZoomCondition int no = DB.getSQLValue(null, builder.toString()); return no == 1; } + + @Override + public MZoomCondition markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MZoomCondition \ No newline at end of file diff --git a/org.adempiere.base/src/org/compiere/model/PO.java b/org.adempiere.base/src/org/compiere/model/PO.java index 8fd55a8b57..0b12e38d3e 100644 --- a/org.adempiere.base/src/org/compiere/model/PO.java +++ b/org.adempiere.base/src/org/compiere/model/PO.java @@ -285,6 +285,9 @@ public abstract class PO /** Trifon - Indicates that this record is created by replication functionality.*/ private boolean m_isReplication = false; + + /** Immutable flag **/ + private boolean m_isImmutable = false; /** Access Level S__ 100 4 System info */ public static final int ACCESSLEVEL_SYSTEM = 4; @@ -727,6 +730,8 @@ public abstract class PO */ protected final boolean set_Value (String ColumnName, Object value, boolean checkWritable) { + checkImmutable(); + if (value instanceof String && ColumnName.equals("WhereClause") && value.toString().toUpperCase().indexOf("=NULL") != -1) log.warning("Invalid Null Value - " + ColumnName + "=" + value); @@ -785,6 +790,8 @@ public abstract class PO */ protected final boolean set_Value (int index, Object value, boolean checkWritable) { + checkImmutable(); + if (index < 0 || index >= get_ColumnCount()) { log.log(Level.WARNING, "Index invalid - " + index); @@ -940,6 +947,8 @@ public abstract class PO Fill the column ProcessedOn (if it exists) with a bigdecimal representation of current timestamp (with nanoseconds) */ public void setProcessedOn(String ColumnName, Object value, Object oldValue) { + checkImmutable(); + if ("Processed".equals(ColumnName) && value instanceof Boolean && ((Boolean)value).booleanValue() == true @@ -1058,6 +1067,8 @@ public abstract class PO */ public final boolean set_CustomColumnReturningBoolean (String columnName, Object value) { + checkImmutable(); + // [ 1845793 ] PO.set_CustomColumn not updating correctly m_newValues // this is for columns not in PO - verify and call proper method if exists int poIndex = get_ColumnIndex(columnName); @@ -1091,6 +1102,8 @@ public abstract class PO */ private void set_Keys (String ColumnName, Object value) { + checkImmutable(); + // Update if KeyColumn for (int i = 0; i < m_IDs.length; i++) { @@ -1309,6 +1322,8 @@ public abstract class PO */ protected void load (int ID, String trxName) { + checkImmutable(); + if (log.isLoggable(Level.FINEST)) log.finest("ID=" + ID); if (ID > 0) { @@ -1408,6 +1423,8 @@ public abstract class PO finally { DB.close(rs, pstmt); rs = null; pstmt = null; + if (is_Immutable()) + m_trxName = null; } loadComplete(success); return success; @@ -1494,6 +1511,8 @@ public abstract class PO */ protected boolean load (HashMap hmIn) { + checkImmutable(); + int size = get_ColumnCount(); boolean success = true; int index = 0; @@ -1548,6 +1567,13 @@ public abstract class PO return success; } // load + protected void checkImmutable() { + if (is_Immutable()) + { + throw new IllegalStateException("PO is Immutable: " + getClass().getName()); + } + } + /** * Create Hashmap with data as Strings * @return HashMap @@ -2049,6 +2075,8 @@ public abstract class PO */ public boolean save() { + checkImmutable(); + checkValidContext(); CLogger.resetLast(); boolean newRecord = is_new(); // save locally as load resets @@ -2406,6 +2434,7 @@ public abstract class PO public void saveReplica (boolean isFromReplication) throws AdempiereException { + checkImmutable(); setReplication(isFromReplication); saveEx(); } @@ -3233,6 +3262,8 @@ public abstract class PO */ public boolean delete (boolean force) { + checkImmutable(); + checkValidContext(); CLogger.resetLast(); if (is_new()) @@ -4256,6 +4287,10 @@ public abstract class PO */ public void set_TrxName (String trxName) { + if (trxName != null) + { + checkImmutable(); + } m_trxName = trxName; } // setTrx @@ -4711,7 +4746,7 @@ public abstract class PO * @param doc Document */ public void setDoc(Doc doc) { - m_doc = doc; + m_doc = doc; } public void setReplication(boolean isFromReplication) @@ -4846,6 +4881,8 @@ public abstract class PO } public void set_Attribute(String columnName, Object value) { + checkImmutable(); + if (m_attributes == null) m_attributes = new HashMap(); m_attributes.put(columnName, value); @@ -4861,6 +4898,25 @@ public abstract class PO return m_attributes; } + /** + * Turn on immutable check + */ + protected void makeImmutable() { + if (is_Immutable()) + return; + + m_isImmutable = true; + m_trxName = null; + } + + /** + * + * @return true if PO is immutable, false otherwise + */ + public boolean is_Immutable() { + return m_isImmutable; + } + private void validateUniqueIndex() { ValueNamePair ppE = CLogger.retrieveError(); diff --git a/org.adempiere.base/src/org/compiere/print/MPrintColor.java b/org.adempiere.base/src/org/compiere/print/MPrintColor.java index 489f3b8f08..0b19843316 100644 --- a/org.adempiere.base/src/org/compiere/print/MPrintColor.java +++ b/org.adempiere.base/src/org/compiere/print/MPrintColor.java @@ -24,10 +24,11 @@ import java.util.logging.Level; import org.compiere.model.PO; import org.compiere.model.X_AD_PrintColor; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.Env; import org.compiere.util.Util; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * AD_PrintColor Print Color Model @@ -35,12 +36,12 @@ import org.compiere.util.Util; * @author Jorg Janke * @version $Id: MPrintColor.java,v 1.3 2006/07/30 00:53:02 jjanke Exp $ */ -public class MPrintColor extends X_AD_PrintColor +public class MPrintColor extends X_AD_PrintColor implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -5611659311562283304L; + private static final long serialVersionUID = 729053102783763723L; /************************************************************************** * Create Color in Database and save @@ -77,12 +78,23 @@ public class MPrintColor extends X_AD_PrintColor /*************************************************************************/ /** Cached Colors */ - static private CCache s_colors = new CCache(Table_Name, 20); + static private ImmutableIntPOCache s_colors = new ImmutableIntPOCache(Table_Name, 20); /** Static Logger */ private static CLogger s_log = CLogger.getCLogger (MPrintColor.class); /** - * Get Color. + * Get Color from cache (immutable) + * if id = 0, it returns a new color (black) - but do not modify/save as cached + * @param AD_PrintColor_ID id + * @return Color + */ + static public MPrintColor get (int AD_PrintColor_ID) + { + return get(Env.getCtx(), AD_PrintColor_ID); + } + + /** + * Get Color from cache (immutable) * if id = 0, it returns a new color (black) - but do not modify/save as cached * @param ctx context * @param AD_PrintColor_ID id @@ -93,11 +105,16 @@ public class MPrintColor extends X_AD_PrintColor // if (AD_PrintColor_ID == 0) // return new MPrintColor (ctx, 0); Integer key = Integer.valueOf(AD_PrintColor_ID); - MPrintColor pc = (MPrintColor)s_colors.get(key); + MPrintColor pc = s_colors.get(ctx, key, e -> new MPrintColor(ctx, e)); if (pc == null) { - pc = new MPrintColor (ctx, AD_PrintColor_ID, null); - s_colors.put(key, pc); + pc = new MPrintColor (ctx, AD_PrintColor_ID, (String)null); + if (pc.get_ID() == AD_PrintColor_ID) + { + s_colors.put(key, pc, e -> new MPrintColor(Env.getCtx(), e)); + return pc; + } + return null; } return pc; } // get @@ -144,6 +161,38 @@ public class MPrintColor extends X_AD_PrintColor super (ctx, rs, trxName); } + /** + * + * @param copy + */ + public MPrintColor(MPrintColor copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MPrintColor(Properties ctx, MPrintColor copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MPrintColor(Properties ctx, MPrintColor copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_cacheColor = copy.m_cacheColor; + } + /** Color cached */ private Color m_cacheColor = null; @@ -200,6 +249,15 @@ public class MPrintColor extends X_AD_PrintColor return sb.toString(); } // getRRGGBB + @Override + public MPrintColor markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + /** * String Representation * @return info diff --git a/org.adempiere.base/src/org/compiere/print/MPrintFont.java b/org.adempiere.base/src/org/compiere/print/MPrintFont.java index ea70daabc4..aa8140b59e 100644 --- a/org.adempiere.base/src/org/compiere/print/MPrintFont.java +++ b/org.adempiere.base/src/org/compiere/print/MPrintFont.java @@ -26,8 +26,9 @@ import java.util.logging.Level; import org.compiere.model.PO; import org.compiere.model.X_AD_PrintFont; -import org.compiere.util.CCache; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * AD_PrintFont Print Font Model @@ -35,12 +36,12 @@ import org.compiere.util.Env; * @author Jorg Janke * @version $Id: MPrintFont.java,v 1.3 2006/07/30 00:53:02 jjanke Exp $ */ -public class MPrintFont extends X_AD_PrintFont +public class MPrintFont extends X_AD_PrintFont implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -2986160498367260541L; + private static final long serialVersionUID = -613305916546183810L; /** * Constructor @@ -60,6 +61,38 @@ public class MPrintFont extends X_AD_PrintFont super (ctx, rs, trxName); } + /** + * + * @param copy + */ + public MPrintFont(MPrintFont copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MPrintFont(Properties ctx, MPrintFont copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MPrintFont(Properties ctx, MPrintFont copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_cacheFont = copy.m_cacheFont; + } + /** Font cached */ private Font m_cacheFont = null; @@ -196,7 +229,7 @@ public class MPrintFont extends X_AD_PrintFont /*************************************************************************/ /** Cached Fonts */ - static private CCache s_fonts = new CCache(Table_Name, 20); + static private ImmutableIntPOCache s_fonts = new ImmutableIntPOCache(Table_Name, 20); /** * Get Font @@ -206,15 +239,29 @@ public class MPrintFont extends X_AD_PrintFont static public MPrintFont get (int AD_PrintFont_ID) { Integer key = Integer.valueOf(AD_PrintFont_ID); - MPrintFont pf = (MPrintFont)s_fonts.get(key); + MPrintFont pf = s_fonts.get(key); if (pf == null) { - pf = new MPrintFont (Env.getCtx(), AD_PrintFont_ID, null); - s_fonts.put(key, pf); + pf = new MPrintFont (Env.getCtx(), AD_PrintFont_ID, (String)null); + if (pf.get_ID() == AD_PrintFont_ID) + { + s_fonts.put(key, pf); + return pf; + } + return null; } return pf; } // get + @Override + public MPrintFont markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + /*************************************************************************/ /** diff --git a/org.adempiere.base/src/org/compiere/print/MPrintFormat.java b/org.adempiere.base/src/org/compiere/print/MPrintFormat.java index 5aa03d88d3..9a9e276a60 100644 --- a/org.adempiere.base/src/org/compiere/print/MPrintFormat.java +++ b/org.adempiere.base/src/org/compiere/print/MPrintFormat.java @@ -39,7 +39,6 @@ import org.compiere.model.MQuery; import org.compiere.model.MRole; import org.compiere.model.Query; import org.compiere.model.X_AD_PrintFormat; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; @@ -47,6 +46,8 @@ import org.compiere.util.KeyNamePair; import org.compiere.util.Language; import org.compiere.util.Msg; import org.compiere.util.Util; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * AD_PrintFormat - Print Format Model. @@ -55,12 +56,12 @@ import org.compiere.util.Util; * @author Jorg Janke * @version $Id: MPrintFormat.java,v 1.3 2006/07/30 00:53:02 jjanke Exp $ */ -public class MPrintFormat extends X_AD_PrintFormat +public class MPrintFormat extends X_AD_PrintFormat implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 2979978408305853342L; + private static final long serialVersionUID = -5693788724825608611L; /** * Public Constructor. @@ -86,6 +87,8 @@ public class MPrintFormat extends X_AD_PrintFormat public void reloadItems() { m_items = getItems(); + if (is_Immutable() && m_items != null && m_items.length > 0) + Arrays.stream(m_items).forEach(e -> e.markImmutable()); } /** @@ -102,17 +105,38 @@ public class MPrintFormat extends X_AD_PrintFormat } // MPrintFormat /** - * Copy constructor + * * @param copy */ - public MPrintFormat(MPrintFormat copy) + public MPrintFormat(MPrintFormat copy) { - this(Env.getCtx(), 0, (String)null); + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MPrintFormat(Properties ctx, MPrintFormat copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MPrintFormat(Properties ctx, MPrintFormat copy, String trxName) + { + this(ctx, 0, trxName); copyPO(copy); this.m_translationViewLanguage = copy.m_translationViewLanguage; - this.m_items = copy.m_items != null ? Arrays.stream(copy.m_items).map(MPrintFormatItem::new).toArray(MPrintFormatItem[]::new) : null; + this.m_items = copy.m_items != null ? Arrays.stream(copy.m_items).map(e -> {return new MPrintFormatItem(ctx, e, trxName);}).toArray(MPrintFormatItem[]::new) : null; this.m_language = copy.m_language != null ? new Language(copy.m_language) : null; - this.m_tFormat = copy.m_tFormat != null ? new MPrintTableFormat(copy.m_tFormat) : null; + this.m_tFormat = copy.m_tFormat != null ? new MPrintTableFormat(ctx, copy.m_tFormat, trxName) : null; } /** Items */ @@ -448,6 +472,8 @@ public class MPrintFormat extends X_AD_PrintFormat { super.setAD_PrintTableFormat_ID(AD_PrintTableFormat_ID); m_tFormat = MPrintTableFormat.get (getCtx(), AD_PrintTableFormat_ID, getAD_PrintFont_ID()); + if (is_Immutable()) + m_tFormat.markImmutable(); } // getAD_PrintTableFormat_ID /** @@ -457,7 +483,11 @@ public class MPrintFormat extends X_AD_PrintFormat public MPrintTableFormat getTableFormat() { if (m_tFormat == null) + { m_tFormat = MPrintTableFormat.get(getCtx(), getAD_PrintTableFormat_ID(), getAD_PrintFont_ID()); + if (is_Immutable()) + m_tFormat.markImmutable(); + } return m_tFormat; } // getTableFormat @@ -975,14 +1005,14 @@ public class MPrintFormat extends X_AD_PrintFormat MPrintFormatItem[] items = fromFormat.getItemsNotIn(toFormat.get_ID()); for (int i = 0; i < items.length; i++) { - MPrintFormatItem pfi = items[i].copyToClient (toFormat.getAD_Client_ID(), toFormat.get_ID()); + MPrintFormatItem pfi = items[i].copyToClient (toFormat.getAD_Client_ID(), toFormat.get_ID(), toFormat.get_TrxName()); if (pfi != null) list.add (pfi); } // MPrintFormatItem[] retValue = new MPrintFormatItem[list.size()]; list.toArray(retValue); - copyTranslationItems (items, retValue); // JTP fix + copyTranslationItems (items, retValue, toFormat.get_TrxName()); // JTP fix return retValue; } // copyItems @@ -990,9 +1020,10 @@ public class MPrintFormat extends X_AD_PrintFormat * Copy translation records (from - to) * @param fromItems from items * @param toItems to items + * @param trxName */ static private void copyTranslationItems (MPrintFormatItem[] fromItems, - MPrintFormatItem[] toItems) + MPrintFormatItem[] toItems, String trxName) { if (fromItems == null || toItems == null) return; // should not happen @@ -1019,7 +1050,7 @@ public class MPrintFormat extends X_AD_PrintFormat .append(" WHERE old.AD_Language=new.AD_Language") .append(" AND AD_PrintFormatItem_ID =").append(fromID) .append(")"); - int no = DB.executeUpdate(sql.toString(), null); + int no = DB.executeUpdate(sql.toString(), trxName); if (no == 0) // if first has no translation, the rest does neither break; counter += no; @@ -1051,7 +1082,21 @@ public class MPrintFormat extends X_AD_PrintFormat public static MPrintFormat copyToClient (Properties ctx, int AD_PrintFormat_ID, int to_Client_ID) { - return copy (ctx, AD_PrintFormat_ID, 0, to_Client_ID); + return copyToClient(ctx, AD_PrintFormat_ID, to_Client_ID, (String)null); + } + + /** + * Copy existing Definition To Client + * @param ctx context + * @param AD_PrintFormat_ID format + * @param to_Client_ID to client + * @param trxName + * @return print format + */ + public static MPrintFormat copyToClient (Properties ctx, + int AD_PrintFormat_ID, int to_Client_ID, String trxName) + { + return copy (ctx, AD_PrintFormat_ID, 0, to_Client_ID, trxName); } // copy /** @@ -1064,6 +1109,20 @@ public class MPrintFormat extends X_AD_PrintFormat */ private static MPrintFormat copy (Properties ctx, int from_AD_PrintFormat_ID, int to_AD_PrintFormat_ID, int to_Client_ID) + { + return copy(ctx, from_AD_PrintFormat_ID, to_AD_PrintFormat_ID, to_Client_ID, (String)null); + } + + /** + * Copy existing Definition To Client + * @param ctx context + * @param from_AD_PrintFormat_ID format + * @param to_AD_PrintFormat_ID to format or 0 for new + * @param to_Client_ID to client (ignored, if to_AD_PrintFormat_ID <> 0) + * @return print format + */ + private static MPrintFormat copy (Properties ctx, int from_AD_PrintFormat_ID, + int to_AD_PrintFormat_ID, int to_Client_ID, String trxName) { if (s_log.isLoggable(Level.INFO)) s_log.info ("From AD_PrintFormat_ID=" + from_AD_PrintFormat_ID + ", To AD_PrintFormat_ID=" + to_AD_PrintFormat_ID @@ -1071,8 +1130,8 @@ public class MPrintFormat extends X_AD_PrintFormat if (from_AD_PrintFormat_ID == 0) throw new IllegalArgumentException ("From_AD_PrintFormat_ID is 0"); // - MPrintFormat from = new MPrintFormat(ctx, from_AD_PrintFormat_ID, null); - MPrintFormat to = new MPrintFormat (ctx, to_AD_PrintFormat_ID, null); // could be 0 + MPrintFormat from = new MPrintFormat(ctx, from_AD_PrintFormat_ID, trxName); + MPrintFormat to = new MPrintFormat (ctx, to_AD_PrintFormat_ID, trxName); // could be 0 MPrintFormat.copyValues (from, to); // New if (to_AD_PrintFormat_ID == 0) @@ -1104,10 +1163,20 @@ public class MPrintFormat extends X_AD_PrintFormat } /** Cached Formats */ - static private CCache s_formats = new CCache(Table_Name, 30); + static private ImmutableIntPOCache s_formats = new ImmutableIntPOCache(Table_Name, 30); /** - * Get Format + * Get Format from cache (immutable) + * @param AD_PrintFormat_ID id + * @return Format + */ + static public MPrintFormat get (int AD_PrintFormat_ID) + { + return get(Env.getCtx(), AD_PrintFormat_ID, false); + } + + /** + * Get Format from cache (immutable) * @param ctx context * @param AD_PrintFormat_ID id * @param readFromDisk refresh from disk @@ -1118,20 +1187,18 @@ public class MPrintFormat extends X_AD_PrintFormat Integer key = Integer.valueOf(AD_PrintFormat_ID); MPrintFormat pf = null; if (!readFromDisk) - pf = (MPrintFormat)s_formats.get(key); + pf = s_formats.get(ctx, key, e -> new MPrintFormat(ctx, e)); if (pf == null) { - pf = new MPrintFormat (ctx, AD_PrintFormat_ID, null); - if (pf.get_ID() <= 0) - pf = null; - else - s_formats.put(key, pf); + pf = new MPrintFormat (ctx, AD_PrintFormat_ID, (String)null); + if (pf.get_ID() == AD_PrintFormat_ID) + { + s_formats.put(key, pf, e -> new MPrintFormat(Env.getCtx(), e)); + return pf; + } + return null; } - if (pf != null) - { - pf = new MPrintFormat(pf); - } return pf; } // get @@ -1282,6 +1349,20 @@ public class MPrintFormat extends X_AD_PrintFormat return pfAD_Window_ID; } + @Override + public MPrintFormat markImmutable() + { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_items != null && m_items.length > 0) + Arrays.stream(m_items).forEach(e -> e.markImmutable()); + if (m_tFormat != null) + m_tFormat.markImmutable(); + return this; + } + /************************************************************************** * Test * @param args arga diff --git a/org.adempiere.base/src/org/compiere/print/MPrintFormatItem.java b/org.adempiere.base/src/org/compiere/print/MPrintFormatItem.java index 20a291a570..7aeda03c3f 100644 --- a/org.adempiere.base/src/org/compiere/print/MPrintFormatItem.java +++ b/org.adempiere.base/src/org/compiere/print/MPrintFormatItem.java @@ -31,6 +31,7 @@ import org.compiere.util.DB; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.Language; +import org.idempiere.cache.ImmutablePOSupport; /** * Print Format Item Model. @@ -40,12 +41,12 @@ import org.compiere.util.Language; * @author Jorg Janke * @version $Id: MPrintFormatItem.java,v 1.3 2006/08/03 22:17:17 jjanke Exp $ */ -public class MPrintFormatItem extends X_AD_PrintFormatItem +public class MPrintFormatItem extends X_AD_PrintFormatItem implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 7145503984951798641L; + private static final long serialVersionUID = 2950704375830865408L; /** * Constructor @@ -112,12 +113,33 @@ public class MPrintFormatItem extends X_AD_PrintFormatItem } // MPrintFormatItem /** - * Copy constructor + * * @param copy */ - public MPrintFormatItem(MPrintFormatItem copy) + public MPrintFormatItem(MPrintFormatItem copy) { - this(Env.getCtx(), 0, (String)null); + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MPrintFormatItem(Properties ctx, MPrintFormatItem copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MPrintFormatItem(Properties ctx, MPrintFormatItem copy, String trxName) + { + this(ctx, 0, trxName); copyPO(copy); this.m_columnName = copy.m_columnName; this.m_newTranslationLabel = copy.m_newTranslationLabel; @@ -645,7 +667,18 @@ public class MPrintFormatItem extends X_AD_PrintFormatItem */ public MPrintFormatItem copyToClient (int To_Client_ID, int AD_PrintFormat_ID) { - MPrintFormatItem to = new MPrintFormatItem (p_ctx, 0, null); + return copyToClient(To_Client_ID, AD_PrintFormat_ID, (String)null); + } + + /** + * Copy existing Definition To Client + * @param To_Client_ID to client + * @param AD_PrintFormat_ID parent print format + * @return print format item + */ + public MPrintFormatItem copyToClient (int To_Client_ID, int AD_PrintFormat_ID, String trxName) + { + MPrintFormatItem to = new MPrintFormatItem (p_ctx, 0, trxName); MPrintFormatItem.copyValues(this, to); to.setClientOrg(To_Client_ID, 0); to.setAD_PrintFormat_ID(AD_PrintFormat_ID); @@ -744,5 +777,14 @@ public class MPrintFormatItem extends X_AD_PrintFormatItem return true; return super.is_Changed(); } - + + @Override + public MPrintFormatItem markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MPrintFormatItem diff --git a/org.adempiere.base/src/org/compiere/print/MPrintPaper.java b/org.adempiere.base/src/org/compiere/print/MPrintPaper.java index d6bb08dc5a..fe74b01706 100644 --- a/org.adempiere.base/src/org/compiere/print/MPrintPaper.java +++ b/org.adempiere.base/src/org/compiere/print/MPrintPaper.java @@ -28,10 +28,11 @@ import javax.print.attribute.standard.MediaSizeName; import org.adempiere.exceptions.AdempiereException; import org.compiere.model.PO; import org.compiere.model.X_AD_PrintPaper; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.Env; import org.compiere.util.Language; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * AD_PrintPaper Print Paper Model @@ -48,26 +49,27 @@ import org.compiere.util.Language; *
  • FR [ 2829019 ] Check PrintPaper on save * https://sourceforge.net/tracker/?func=detail&aid=2829019&group_id=176962&atid=879335 */ -public class MPrintPaper extends X_AD_PrintPaper +public class MPrintPaper extends X_AD_PrintPaper implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -3609557177958141344L; + private static final long serialVersionUID = -4968342903056251506L; /** - * Get Paper + * Get Paper from cache (immutable) * @param AD_PrintPaper_ID id * @return Paper */ static public MPrintPaper get (int AD_PrintPaper_ID) { Integer key = Integer.valueOf(AD_PrintPaper_ID); - MPrintPaper pp = (MPrintPaper)s_papers.get(key); + MPrintPaper pp = s_papers.get(key); if (pp == null) { pp = new MPrintPaper (Env.getCtx(), AD_PrintPaper_ID, null); s_papers.put(key, pp); + return pp; } else if (s_log.isLoggable(Level.CONFIG)) s_log.config("AD_PrintPaper_ID=" + AD_PrintPaper_ID); @@ -92,8 +94,8 @@ public class MPrintPaper extends X_AD_PrintPaper /** Logger */ private static CLogger s_log = CLogger.getCLogger(MPrintPaper.class); /** Cached Fonts */ - static private CCache s_papers - = new CCache(Table_Name, 5); + static private ImmutableIntPOCache s_papers + = new ImmutableIntPOCache(Table_Name, 5); /************************************************************************** @@ -128,7 +130,38 @@ public class MPrintPaper extends X_AD_PrintPaper super (ctx, rs, trxName); } // MPrintPaper + /** + * + * @param copy + */ + public MPrintPaper(MPrintPaper copy) + { + this(Env.getCtx(), copy); + } + /** + * + * @param ctx + * @param copy + */ + public MPrintPaper(Properties ctx, MPrintPaper copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MPrintPaper(Properties ctx, MPrintPaper copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_mediaSize = copy.m_mediaSize; + } + /** Media Size */ private MediaSize m_mediaSize = null; @@ -244,7 +277,14 @@ public class MPrintPaper extends X_AD_PrintPaper return true; } + @Override + public MPrintPaper markImmutable() { + if (is_Immutable()) + return this; + makeImmutable(); + return this; + } /** * Media Size Name diff --git a/org.adempiere.base/src/org/compiere/print/MPrintTableFormat.java b/org.adempiere.base/src/org/compiere/print/MPrintTableFormat.java index f7dcc79471..9952aa44ed 100644 --- a/org.adempiere.base/src/org/compiere/print/MPrintTableFormat.java +++ b/org.adempiere.base/src/org/compiere/print/MPrintTableFormat.java @@ -33,10 +33,11 @@ import java.util.logging.Level; import org.compiere.model.MAttachment; import org.compiere.model.MImage; import org.compiere.model.X_AD_PrintTableFormat; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.IntPOCopyCache; /** * Table Print Format @@ -47,12 +48,12 @@ import org.compiere.util.Env; *
  • http://sourceforge.net/tracker/index.php?func=detail&aid=2011567&group_id=176962&atid=879335 * @version $Id: MPrintTableFormat.java,v 1.3 2006/07/30 00:53:02 jjanke Exp $ */ -public class MPrintTableFormat extends X_AD_PrintTableFormat +public class MPrintTableFormat extends X_AD_PrintTableFormat implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -357529310875242899L; + private static final long serialVersionUID = -1608017405401341288L; /** * Standard Constructor @@ -87,12 +88,33 @@ public class MPrintTableFormat extends X_AD_PrintTableFormat } // MPrintTableFormat /** - * Copy constructor + * * @param copy */ - public MPrintTableFormat(MPrintTableFormat copy) + public MPrintTableFormat(MPrintTableFormat copy) { - this(Env.getCtx(), 0, (String)null); + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MPrintTableFormat(Properties ctx, MPrintTableFormat copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MPrintTableFormat(Properties ctx, MPrintTableFormat copy, String trxName) + { + this(ctx, 0, trxName); copyPO(copy); this.standard_Font = copy.standard_Font; this.funct_Font = copy.funct_Font; @@ -568,8 +590,8 @@ public class MPrintTableFormat extends X_AD_PrintTableFormat /*************************************************************************/ - private static CCache s_cache - = new CCache(Table_Name, 3); + private static IntPOCopyCache s_cache + = new IntPOCopyCache(Table_Name, 3); /** Static Logger */ private static CLogger s_log = CLogger.getCLogger(MPrintTableFormat.class); @@ -583,14 +605,20 @@ public class MPrintTableFormat extends X_AD_PrintTableFormat static public MPrintTableFormat get (Properties ctx, int AD_PrintTableFormat_ID, Font standard_font) { Integer ii = Integer.valueOf(AD_PrintTableFormat_ID); - MPrintTableFormat tf = (MPrintTableFormat)s_cache.get(ii); + MPrintTableFormat tf = s_cache.get(ii, e -> new MPrintTableFormat(ctx, e)); if (tf == null) { if (AD_PrintTableFormat_ID == 0) + { tf = getDefault (ctx); + } else - tf = new MPrintTableFormat (ctx, AD_PrintTableFormat_ID, null); - s_cache.put(ii, tf); + { + tf = new MPrintTableFormat (ctx, AD_PrintTableFormat_ID, (String)null); + if (tf.get_ID() != AD_PrintTableFormat_ID) + return null; + } + s_cache.put(tf.get_ID(), tf, e -> new MPrintTableFormat(Env.getCtx(), e)); } tf.setStandard_Font(standard_font); return tf; @@ -714,4 +742,14 @@ public class MPrintTableFormat extends X_AD_PrintTableFormat } return m_image_water_mark; } // getImage + + @Override + public MPrintTableFormat markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MPrintTableFormat diff --git a/org.adempiere.base/src/org/compiere/print/PrintUtil.java b/org.adempiere.base/src/org/compiere/print/PrintUtil.java index 6a26acf090..7cbc7277e9 100644 --- a/org.adempiere.base/src/org/compiere/print/PrintUtil.java +++ b/org.adempiere.base/src/org/compiere/print/PrintUtil.java @@ -542,7 +542,6 @@ public class PrintUtil // dump(null, null); } // testSPS*/ - /************************************************************************** * Create Print Form & Print Formats for a new Client. * - Order, Invoice, etc. @@ -550,30 +549,42 @@ public class PrintUtil * @param AD_Client_ID new Client */ public static void setupPrintForm (int AD_Client_ID) + { + setupPrintForm(AD_Client_ID, (String)null); + } + + /************************************************************************** + * Create Print Form & Print Formats for a new Client. + * - Order, Invoice, etc. + * Called from VSetup + * @param AD_Client_ID new Client + * @param trxName + */ + public static void setupPrintForm (int AD_Client_ID, String trxName) { if (log.isLoggable(Level.CONFIG)) log.config("AD_Client_ID=" + AD_Client_ID); Properties ctx = Env.getCtx(); CLogMgt.enable(false); // // Order Template - int Order_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_ORDER_HEADER_TEMPLATE, AD_Client_ID).get_ID(); - int OrderLine_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_ORDER_LINETAX_TEMPLATE, AD_Client_ID).get_ID(); - updatePrintFormatHeader(Order_PrintFormat_ID, OrderLine_PrintFormat_ID); + int Order_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_ORDER_HEADER_TEMPLATE, AD_Client_ID, trxName).get_ID(); + int OrderLine_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_ORDER_LINETAX_TEMPLATE, AD_Client_ID, trxName).get_ID(); + updatePrintFormatHeader(Order_PrintFormat_ID, OrderLine_PrintFormat_ID, trxName); // Invoice - int Invoice_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_INVOICE_HEADER_TEMPLATE, AD_Client_ID).get_ID(); - int InvoiceLine_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_INVOICE_LINETAX_TEMPLATE, AD_Client_ID).get_ID(); - updatePrintFormatHeader(Invoice_PrintFormat_ID, InvoiceLine_PrintFormat_ID); + int Invoice_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_INVOICE_HEADER_TEMPLATE, AD_Client_ID, trxName).get_ID(); + int InvoiceLine_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_INVOICE_LINETAX_TEMPLATE, AD_Client_ID, trxName).get_ID(); + updatePrintFormatHeader(Invoice_PrintFormat_ID, InvoiceLine_PrintFormat_ID, trxName); // Shipment - int Shipment_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_INOUT_HEADER_TEMPLATE, AD_Client_ID).get_ID(); - int ShipmentLine_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_INOUT_LINE_TEMPLATE, AD_Client_ID).get_ID(); - updatePrintFormatHeader(Shipment_PrintFormat_ID, ShipmentLine_PrintFormat_ID); + int Shipment_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_INOUT_HEADER_TEMPLATE, AD_Client_ID, trxName).get_ID(); + int ShipmentLine_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_INOUT_LINE_TEMPLATE, AD_Client_ID, trxName).get_ID(); + updatePrintFormatHeader(Shipment_PrintFormat_ID, ShipmentLine_PrintFormat_ID, trxName); // Check - int Check_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_PAYSELECTION_CHECK_TEMPLATE, AD_Client_ID).get_ID(); - int RemittanceLine_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_PAYSELECTION_REMITTANCE_LINES_TEMPLATE, AD_Client_ID).get_ID(); - updatePrintFormatHeader(Check_PrintFormat_ID, RemittanceLine_PrintFormat_ID); + int Check_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_PAYSELECTION_CHECK_TEMPLATE, AD_Client_ID, trxName).get_ID(); + int RemittanceLine_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_PAYSELECTION_REMITTANCE_LINES_TEMPLATE, AD_Client_ID, trxName).get_ID(); + updatePrintFormatHeader(Check_PrintFormat_ID, RemittanceLine_PrintFormat_ID, trxName); // Remittance - int Remittance_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_PAYSELECTION_REMITTANCE__TEMPLATE, AD_Client_ID).get_ID(); - updatePrintFormatHeader(Remittance_PrintFormat_ID, RemittanceLine_PrintFormat_ID); + int Remittance_PrintFormat_ID = MPrintFormat.copyToClient(ctx, PRINTFORMAT_PAYSELECTION_REMITTANCE__TEMPLATE, AD_Client_ID, trxName).get_ID(); + updatePrintFormatHeader(Remittance_PrintFormat_ID, RemittanceLine_PrintFormat_ID, trxName); // TODO: MPrintForm // MPrintForm form = new MPrintForm(); @@ -585,7 +596,7 @@ public class PrintUtil + "'" + Msg.translate(ctx, "Standard") + "'," + Order_PrintFormat_ID + "," + Invoice_PrintFormat_ID + "," + Remittance_PrintFormat_ID + "," + Shipment_PrintFormat_ID + ")"; - int no = DB.executeUpdate(sql, null); + int no = DB.executeUpdate(sql, trxName); if (no != 1) log.log(Level.SEVERE, "PrintForm NOT inserted"); // @@ -596,8 +607,9 @@ public class PrintUtil * Update the PrintFormat Header lines with Reference to Child Print Format. * @param Header_ID AD_PrintFormat_ID for Header * @param Line_ID AD_PrintFormat_ID for Line + * @param trxName */ - static private void updatePrintFormatHeader (int Header_ID, int Line_ID) + static private void updatePrintFormatHeader (int Header_ID, int Line_ID, String trxName) { StringBuilder sb = new StringBuilder(); sb.append("UPDATE AD_PrintFormatItem SET AD_PrintFormatChild_ID=") @@ -605,7 +617,7 @@ public class PrintUtil .append(" WHERE AD_PrintFormatChild_ID IS NOT NULL AND AD_PrintFormat_ID=") .append(Header_ID); @SuppressWarnings("unused") - int no = DB.executeUpdate(sb.toString(), null); + int no = DB.executeUpdate(sb.toString(), trxName); } // updatePrintFormatHeader /*************************************************************************/ diff --git a/org.adempiere.base/src/org/compiere/report/FinReport.java b/org.adempiere.base/src/org/compiere/report/FinReport.java index 7ed505ce8d..3db4345196 100644 --- a/org.adempiere.base/src/org/compiere/report/FinReport.java +++ b/org.adempiere.base/src/org/compiere/report/FinReport.java @@ -1813,7 +1813,10 @@ public class FinReport extends SvrProcess m_report.saveEx(); } else + { pf = MPrintFormat.get (getCtx(), AD_PrintFormat_ID, false); // use Cache + pf = new MPrintFormat(getCtx(), pf); + } // Print Format Sync if (!m_report.getName().equals(pf.getName())) { diff --git a/org.adempiere.base/src/org/compiere/util/CCache.java b/org.adempiere.base/src/org/compiere/util/CCache.java index 877ba2960f..bbfc2fe7d3 100644 --- a/org.adempiere.base/src/org/compiere/util/CCache.java +++ b/org.adempiere.base/src/org/compiere/util/CCache.java @@ -21,8 +21,8 @@ import java.beans.VetoableChangeSupport; import java.io.Serializable; import java.util.Collection; import java.util.Collections; +import java.util.ConcurrentModificationException; import java.util.HashSet; -import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicLong; @@ -45,13 +45,12 @@ public class CCache implements CacheInterface, Map, Serializable */ private static final long serialVersionUID = -2268565219001179841L; - private Map cache = null; + protected Map cache = null; - private Set nullList = null; + protected Set nullList = null; private String m_tableName; - @SuppressWarnings("unused") private boolean m_distributed; private int m_maxSize = 0; @@ -299,6 +298,7 @@ public class CCache implements CacheInterface, Map, Serializable /** * @see java.util.Map#get(java.lang.Object) */ + @Override public V get(Object key) { expire(); @@ -428,9 +428,17 @@ public class CCache implements CacheInterface, Map, Serializable public int reset(int recordId) { if (recordId <= 0) return reset(); + + if (cache.isEmpty() && nullList.isEmpty()) + return 0; - Iterator iterator = cache.keySet().iterator(); - K firstKey = iterator.hasNext() ? iterator.next() : null; + K firstKey = null; + try { + if (!cache.isEmpty()) + firstKey = cache.keySet().iterator().next(); + else if (!nullList.isEmpty()) + firstKey = nullList.iterator().next(); + } catch (ConcurrentModificationException e) {} if (firstKey != null && firstKey instanceof Integer) { if (!nullList.isEmpty()) { if (nullList.remove(recordId)) return 1; @@ -460,5 +468,5 @@ public class CCache implements CacheInterface, Map, Serializable public long getMiss() { return m_miss.get(); - } + } } // CCache diff --git a/org.adempiere.base/src/org/compiere/util/Env.java b/org.adempiere.base/src/org/compiere/util/Env.java index 5f05d24d82..779044d0d2 100644 --- a/org.adempiere.base/src/org/compiere/util/Env.java +++ b/org.adempiere.base/src/org/compiere/util/Env.java @@ -88,6 +88,8 @@ public final class Env public static final String AD_ORG_NAME = "#AD_Org_Name"; public static final String M_WAREHOUSE_ID = "#M_Warehouse_ID"; + + public static final String RUNNING_UNIT_TESTING_TEST_CASE = "#RUNNING_UNIT_TESTING_TEST_CASE"; private final static ContextProvider clientContextProvider = new DefaultContextProvider(); diff --git a/org.adempiere.base/src/org/compiere/wf/MWFActivity.java b/org.adempiere.base/src/org/compiere/wf/MWFActivity.java index 2422fc1a45..a03e5e267a 100644 --- a/org.adempiere.base/src/org/compiere/wf/MWFActivity.java +++ b/org.adempiere.base/src/org/compiere/wf/MWFActivity.java @@ -489,7 +489,7 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable public MWFNode getNode() { if (m_node == null) - m_node = MWFNode.get (getCtx(), getAD_WF_Node_ID()); + m_node = MWFNode.getCopy(getCtx(), getAD_WF_Node_ID(), get_TrxName()); return m_node; } // getNode @@ -651,7 +651,7 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable */ public MWFResponsible getResponsible() { - MWFResponsible resp = MWFResponsible.get(getCtx(), getAD_WF_Responsible_ID()); + MWFResponsible resp = MWFResponsible.getCopy(getCtx(), getAD_WF_Responsible_ID(), get_TrxName()); return resp; } // isInvoker @@ -1098,8 +1098,7 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable { if (log.isLoggable(Level.FINE)) log.fine("Report:AD_Process_ID=" + m_node.getAD_Process_ID()); // Process - MProcess process = MProcess.get(getCtx(), m_node.getAD_Process_ID()); - process.set_TrxName(trx != null ? trx.getTrxName() : null); + MProcess process = MProcess.getCopy(getCtx(), m_node.getAD_Process_ID(), (trx != null ? trx.getTrxName() : null)); if (!process.isReport() || process.getAD_ReportView_ID() == 0) throw new IllegalStateException("Not a Report AD_Process_ID=" + m_node.getAD_Process_ID()); // diff --git a/org.adempiere.base/src/org/compiere/wf/MWFBlock.java b/org.adempiere.base/src/org/compiere/wf/MWFBlock.java index 6b69e444e9..e33ee26301 100644 --- a/org.adempiere.base/src/org/compiere/wf/MWFBlock.java +++ b/org.adempiere.base/src/org/compiere/wf/MWFBlock.java @@ -20,7 +20,9 @@ import java.sql.ResultSet; import java.util.Properties; import org.compiere.model.X_AD_WF_Block; -import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** @@ -29,16 +31,25 @@ import org.compiere.util.CCache; * @author Jorg Janke * @version $Id: MWFBlock.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $ */ -public class MWFBlock extends X_AD_WF_Block +public class MWFBlock extends X_AD_WF_Block implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -2084396539959122888L; - + private static final long serialVersionUID = -650413593723153474L; /** - * Get MWFBlock from Cache + * Get MWFBlock from Cache (immutable) + * @param AD_WF_Block_ID id + * @return MWFBlock + */ + public static MWFBlock get (int AD_WF_Block_ID) + { + return get(Env.getCtx(), AD_WF_Block_ID); + } + + /** + * Get MWFBlock from Cache (immutable) * @param ctx context * @param AD_WF_Block_ID id * @return MWFBlock @@ -46,17 +57,20 @@ public class MWFBlock extends X_AD_WF_Block public static MWFBlock get (Properties ctx, int AD_WF_Block_ID) { Integer key = Integer.valueOf(AD_WF_Block_ID); - MWFBlock retValue = (MWFBlock) s_cache.get (key); + MWFBlock retValue = s_cache.get (ctx, key, e -> new MWFBlock(ctx, e)); if (retValue != null) return retValue; - retValue = new MWFBlock (ctx, AD_WF_Block_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MWFBlock (ctx, AD_WF_Block_ID, (String)null); + if (retValue.get_ID () == AD_WF_Block_ID) + { + s_cache.put (key, retValue, e -> new MWFBlock(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** @@ -81,4 +95,44 @@ public class MWFBlock extends X_AD_WF_Block super(ctx, rs, trxName); } // MWFBlock + /** + * + * @param copy + */ + public MWFBlock(MWFBlock copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MWFBlock(Properties ctx, MWFBlock copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MWFBlock(Properties ctx, MWFBlock copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + + @Override + public MWFBlock markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MWFBlock diff --git a/org.adempiere.base/src/org/compiere/wf/MWFNextCondition.java b/org.adempiere.base/src/org/compiere/wf/MWFNextCondition.java index c132f18231..5e8add6b80 100644 --- a/org.adempiere.base/src/org/compiere/wf/MWFNextCondition.java +++ b/org.adempiere.base/src/org/compiere/wf/MWFNextCondition.java @@ -23,6 +23,7 @@ import java.util.logging.Level; import org.compiere.model.PO; import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; import org.compiere.model.X_AD_WF_NextCondition; /** @@ -34,12 +35,12 @@ import org.compiere.model.X_AD_WF_NextCondition; * @author Teo Sarca, SC ARHIPAC SERVICE SRL *
  • BF [ 1943720 ] WF Next Condition: handling boolean values is poor */ -public class MWFNextCondition extends X_AD_WF_NextCondition +public class MWFNextCondition extends X_AD_WF_NextCondition implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 1690335423407194318L; + private static final long serialVersionUID = 1694467559057544172L; /** * Default Constructor @@ -63,6 +64,38 @@ public class MWFNextCondition extends X_AD_WF_NextCondition super(ctx, rs, trxName); } // MWFNextCondition + /** + * + * @param copy + */ + public MWFNextCondition(MWFNextCondition copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MWFNextCondition(Properties ctx, MWFNextCondition copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MWFNextCondition(Properties ctx, MWFNextCondition copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_numeric = copy.m_numeric; + } + /** Numeric evaluation */ private boolean m_numeric = true; @@ -301,4 +334,13 @@ public class MWFNextCondition extends X_AD_WF_NextCondition return sb.toString (); } // toString + @Override + public MWFNextCondition markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MWFNextCondition \ No newline at end of file diff --git a/org.adempiere.base/src/org/compiere/wf/MWFNode.java b/org.adempiere.base/src/org/compiere/wf/MWFNode.java index 3a2fc8f06e..b56600eb8f 100644 --- a/org.adempiere.base/src/org/compiere/wf/MWFNode.java +++ b/org.adempiere.base/src/org/compiere/wf/MWFNode.java @@ -24,20 +24,22 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.logging.Level; +import java.util.stream.Collectors; -import org.adempiere.exceptions.AdempiereException; import org.adempiere.exceptions.DBException; import org.compiere.model.MColumn; import org.compiere.model.MRole; import org.compiere.model.Query; import org.compiere.model.X_AD_WF_Node; -import org.compiere.util.CCache; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.ImmutablePOCache; /** * Workflow Node Model @@ -50,14 +52,23 @@ import org.compiere.util.Msg; *
  • BF [ 2815732 ] MWFNode.getWorkflow not working in trx * https://sourceforge.net/tracker/?func=detail&aid=2815732&group_id=176962&atid=879332 */ -public class MWFNode extends X_AD_WF_Node +public class MWFNode extends X_AD_WF_Node implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 4330589837679937718L; - + private static final long serialVersionUID = 3328770995394833132L; + /** + * Get WF Node from Cache + * @param AD_WF_Node_ID id + * @return MWFNode + */ + public static MWFNode get (int AD_WF_Node_ID) + { + return get(Env.getCtx(), AD_WF_Node_ID); + } + /** * Get WF Node from Cache * @param ctx context @@ -67,17 +78,35 @@ public class MWFNode extends X_AD_WF_Node public static MWFNode get (Properties ctx, int AD_WF_Node_ID) { String key = Env.getAD_Language(ctx) + "_" + AD_WF_Node_ID; - MWFNode retValue = (MWFNode) s_cache.get (key); + MWFNode retValue = s_cache.get (ctx, key, e -> new MWFNode(ctx, e)); if (retValue != null) return retValue; - retValue = new MWFNode (ctx, AD_WF_Node_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MWFNode (ctx, AD_WF_Node_ID, (String)null); + if (retValue.get_ID () == AD_WF_Node_ID) + { + s_cache.put (key, retValue, e -> new MWFNode(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MWFNode from cache + * @param ctx + * @param AD_WF_Node_ID + * @param trxName + * @return MWFNode + */ + public static MWFNode getCopy(Properties ctx, int AD_WF_Node_ID, String trxName) + { + MWFNode node = get(AD_WF_Node_ID); + if (node != null) + node = new MWFNode(ctx, node, trxName); + return node; + } + /** Cache */ - private static CCache s_cache = new CCache (Table_Name, 50); + private static ImmutablePOCache s_cache = new ImmutablePOCache (Table_Name, 50); /************************************************************************** @@ -140,21 +169,47 @@ public class MWFNode extends X_AD_WF_Node super(ctx, rs, trxName); loadNext(); loadTrl(); - // Save to Cache - String key = null; - try { - Integer wfnodeid = Integer.valueOf(rs.getInt("AD_WF_Node_ID")); - if (wfnodeid != null && wfnodeid.intValue() > 0) - key = Env.getAD_Language(ctx) + "_" + wfnodeid; - } catch (SQLException e) { - throw new AdempiereException(e); - } - if (key != null && trxName == null && !s_cache.containsKey(key)) - s_cache.put (key, this); } // MWFNode - - + /** + * + * @param copy + */ + public MWFNode(MWFNode copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MWFNode(Properties ctx, MWFNode copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MWFNode(Properties ctx, MWFNode copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_next = copy.m_next != null ? copy.m_next.stream().map(e -> {return new MWFNodeNext(ctx, e, trxName);}).collect(Collectors.toCollection(ArrayList::new)) : null; + this.m_name_trl = copy.m_name_trl; + this.m_description_trl = copy.m_description_trl; + this.m_help_trl = copy.m_help_trl; + this.m_translated = copy.m_translated; + this.m_column = copy.m_column != null ? new MColumn(ctx, copy.m_column, trxName) : null; + this.m_paras = copy.m_paras != null ? Arrays.stream(copy.m_paras).map(e ->{return new MWFNodePara(ctx, e, trxName);}).toArray(MWFNodePara[]::new) : null; + this.m_durationBaseMS = copy.m_durationBaseMS; + } + /** Next Modes */ private List m_next = new ArrayList(); /** Translated Name */ @@ -197,6 +252,8 @@ public class MWFNode extends X_AD_WF_Node for (MWFNodeNext next : m_next) { next.setFromSplitAnd(splitAnd); + if (is_Immutable()) + next.markImmutable(); } if (log.isLoggable(Level.FINE)) log.fine("#" + m_next.size()); } // loadNext @@ -397,7 +454,12 @@ public class MWFNode extends X_AD_WF_Node if (getAD_Column_ID() == 0) return null; if (m_column == null) - m_column = MColumn.get(getCtx(), getAD_Column_ID()); + { + if (is_Immutable()) + m_column = MColumn.get(getCtx(), getAD_Column_ID()); + else + m_column = MColumn.getCopy(getCtx(), getAD_Column_ID(), get_TrxName()); + } return m_column; } // getColumn @@ -509,7 +571,11 @@ public class MWFNode extends X_AD_WF_Node public MWFNodePara[] getParameters() { if (m_paras == null) + { m_paras = MWFNodePara.getParameters(getCtx(), getAD_WF_Node_ID()); + if (m_paras != null && m_paras.length > 0 && is_Immutable()) + Arrays.stream(m_paras).forEach(e -> e.markImmutable()); + } return m_paras; } // getParameters @@ -526,10 +592,7 @@ public class MWFNode extends X_AD_WF_Node @Override public MWorkflow getAD_Workflow() { - if (get_TrxName() == null) - return MWorkflow.get(getCtx(), getAD_Workflow_ID()); - else - return (MWorkflow)super.getAD_Workflow(); + return MWorkflow.getCopy(getCtx(), getAD_Workflow_ID(), get_TrxName()); } /** @@ -711,4 +774,22 @@ public class MWFNode extends X_AD_WF_Node return false; return true; } + + @Override + public MWFNode markImmutable() + { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_column != null) + m_column.markImmutable(); + if (m_next != null && m_next.size() > 0) + m_next.stream().forEach(e -> e.markImmutable()); + if (m_paras != null && m_paras.length > 0) + Arrays.stream(m_paras).forEach(e -> e.markImmutable()); + + return this; + } + } // M_WFNext diff --git a/org.adempiere.base/src/org/compiere/wf/MWFNodeNext.java b/org.adempiere.base/src/org/compiere/wf/MWFNodeNext.java index 10e4d87b57..96c977f99b 100644 --- a/org.adempiere.base/src/org/compiere/wf/MWFNodeNext.java +++ b/org.adempiere.base/src/org/compiere/wf/MWFNodeNext.java @@ -17,6 +17,7 @@ package org.compiere.wf; import java.sql.ResultSet; +import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.logging.Level; @@ -26,6 +27,7 @@ import org.compiere.model.Query; import org.compiere.model.X_AD_WF_NodeNext; import org.compiere.process.DocAction; import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; /** * Workflow Node Next - Transition @@ -33,12 +35,12 @@ import org.compiere.util.Env; * @author Jorg Janke * @version $Id: MWFNodeNext.java,v 1.3 2006/10/06 00:42:24 jjanke Exp $ */ -public class MWFNodeNext extends X_AD_WF_NodeNext +public class MWFNodeNext extends X_AD_WF_NodeNext implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -7925133581626319200L; + private static final long serialVersionUID = -7758585369030074980L; /** * Standard Costructor @@ -83,6 +85,40 @@ public class MWFNodeNext extends X_AD_WF_NodeNext setAD_WF_Next_ID(AD_WF_Next_ID); } // MWFNodeNext + /** + * + * @param copy + */ + public MWFNodeNext(MWFNodeNext copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MWFNodeNext(Properties ctx, MWFNodeNext copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MWFNodeNext(Properties ctx, MWFNodeNext copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_conditions = copy.m_conditions != null ? Arrays.stream(copy.m_conditions).map(e ->{return new MWFNextCondition(ctx, e, trxName);}).toArray(MWFNextCondition[]::new) : null; + this.m_fromSplitAnd = copy.m_fromSplitAnd; + this.m_toJoinAnd = copy.m_toJoinAnd; + } + /** Transition Conditions */ private MWFNextCondition[] m_conditions = null; /** From (Split Eleemnt) is AND */ @@ -134,6 +170,8 @@ public class MWFNodeNext extends X_AD_WF_NodeNext .setOnlyActiveRecords(true) .setOrderBy(MWFNextCondition.COLUMNNAME_SeqNo) .list(); + if (is_Immutable() && list.size() > 0) + list.stream().forEach(e -> e.markImmutable()); m_conditions = new MWFNextCondition[list.size()]; list.toArray (m_conditions); return m_conditions; @@ -249,4 +287,15 @@ public class MWFNodeNext extends X_AD_WF_NodeNext m_toJoinAnd = Boolean.valueOf(toJoinAnd); } // setToJoinAnd + @Override + public MWFNodeNext markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_conditions != null && m_conditions.length > 0) + Arrays.stream(m_conditions).forEach(e -> e.markImmutable()); + return this; + } + } // MWFNodeNext diff --git a/org.adempiere.base/src/org/compiere/wf/MWFNodePara.java b/org.adempiere.base/src/org/compiere/wf/MWFNodePara.java index b478d006c5..7d0442c47b 100644 --- a/org.adempiere.base/src/org/compiere/wf/MWFNodePara.java +++ b/org.adempiere.base/src/org/compiere/wf/MWFNodePara.java @@ -23,6 +23,8 @@ import java.util.Properties; import org.compiere.model.MProcessPara; import org.compiere.model.Query; import org.compiere.model.X_AD_WF_Node_Para; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; /** @@ -31,13 +33,12 @@ import org.compiere.model.X_AD_WF_Node_Para; * @author Jorg Janke * @version $Id: MWFNodePara.java,v 1.2 2006/07/30 00:51:05 jjanke Exp $ */ -public class MWFNodePara extends X_AD_WF_Node_Para +public class MWFNodePara extends X_AD_WF_Node_Para implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 4132254339643230238L; - + private static final long serialVersionUID = -7304684637362248174L; /** * Get Parameters for a node @@ -79,6 +80,37 @@ public class MWFNodePara extends X_AD_WF_Node_Para super(ctx, rs, trxName); } // MWFNodePara + /** + * + * @param copy + */ + public MWFNodePara(MWFNodePara copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MWFNodePara(Properties ctx, MWFNodePara copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MWFNodePara(Properties ctx, MWFNodePara copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_processPara = copy.m_processPara != null ? new MProcessPara(ctx, copy.m_processPara, trxName) : null; + } /** Linked Process Parameter */ private MProcessPara m_processPara = null; @@ -90,7 +122,11 @@ public class MWFNodePara extends X_AD_WF_Node_Para public MProcessPara getProcessPara() { if (m_processPara == null) + { m_processPara = new MProcessPara (getCtx(), getAD_Process_Para_ID(), get_TrxName()); + if (is_Immutable()) + m_processPara.markImmutable(); + } return m_processPara; } // getProcessPara @@ -139,4 +175,15 @@ public class MWFNodePara extends X_AD_WF_Node_Para setAttributeName(null); } + @Override + public MWFNodePara markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_processPara != null) + m_processPara.markImmutable(); + return this; + } + } // MWFNodePara diff --git a/org.adempiere.base/src/org/compiere/wf/MWFProcess.java b/org.adempiere.base/src/org/compiere/wf/MWFProcess.java index 035c6fc7af..671df72f2b 100644 --- a/org.adempiere.base/src/org/compiere/wf/MWFProcess.java +++ b/org.adempiere.base/src/org/compiere/wf/MWFProcess.java @@ -495,7 +495,7 @@ public class MWFProcess extends X_AD_WF_Process public MWorkflow getWorkflow() { if (m_wf == null) - m_wf = MWorkflow.get (getCtx(), getAD_Workflow_ID()); + m_wf = MWorkflow.getCopy(getCtx(), getAD_Workflow_ID(), get_TrxName()); if (m_wf.get_ID() == 0) throw new IllegalStateException("Not found - AD_Workflow_ID=" + getAD_Workflow_ID()); return m_wf; diff --git a/org.adempiere.base/src/org/compiere/wf/MWFResponsible.java b/org.adempiere.base/src/org/compiere/wf/MWFResponsible.java index 9108911e02..b17b57ee93 100644 --- a/org.adempiere.base/src/org/compiere/wf/MWFResponsible.java +++ b/org.adempiere.base/src/org/compiere/wf/MWFResponsible.java @@ -21,8 +21,10 @@ import java.util.Properties; import org.compiere.model.MRole; import org.compiere.model.X_AD_WF_Responsible; -import org.compiere.util.CCache; +import org.compiere.util.Env; import org.compiere.util.Msg; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** @@ -31,15 +33,25 @@ import org.compiere.util.Msg; * @author Jorg Janke * @version $Id: MWFResponsible.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $ */ -public class MWFResponsible extends X_AD_WF_Responsible +public class MWFResponsible extends X_AD_WF_Responsible implements ImmutablePOSupport { - /** - * long - serialVersionUID. - */ - private static final long serialVersionUID = 4167967243996935999L; - /** - * Get WF Responsible from Cache + * + */ + private static final long serialVersionUID = -5073542640376766737L; + + /** + * Get WF Responsible from Cache (immutable) + * @param AD_WF_Responsible_ID id + * @return MWFResponsible + */ + public static MWFResponsible get (int AD_WF_Responsible_ID) + { + return get(Env.getCtx(), AD_WF_Responsible_ID); + } + + /** + * Get WF Responsible from Cache (immutable) * @param ctx context * @param AD_WF_Responsible_ID id * @return MWFResponsible @@ -47,17 +59,35 @@ public class MWFResponsible extends X_AD_WF_Responsible public static MWFResponsible get (Properties ctx, int AD_WF_Responsible_ID) { Integer key = Integer.valueOf(AD_WF_Responsible_ID); - MWFResponsible retValue = (MWFResponsible) s_cache.get (key); + MWFResponsible retValue = s_cache.get (ctx, key, e -> new MWFResponsible(ctx, e)); if (retValue != null) return retValue; - retValue = new MWFResponsible (ctx, AD_WF_Responsible_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MWFResponsible (ctx, AD_WF_Responsible_ID, (String)null); + if (retValue.get_ID () == AD_WF_Responsible_ID) + { + s_cache.put (key, retValue, e -> new MWFResponsible(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MWFResponsible from cache + * @param ctx + * @param AD_WF_Responsible_ID + * @param trxName + * @return MWFResponsible + */ + public static MWFResponsible getCopy(Properties ctx, int AD_WF_Responsible_ID, String trxName) + { + MWFResponsible r = get(AD_WF_Responsible_ID); + if (r != null) + r = new MWFResponsible(ctx, r, trxName); + return r; + } + /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 10); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 10); /************************************************************************** @@ -82,6 +112,37 @@ public class MWFResponsible extends X_AD_WF_Responsible super(ctx, rs, trxName); } // MWFResponsible + /** + * + * @param copy + */ + public MWFResponsible(MWFResponsible copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MWFResponsible(Properties ctx, MWFResponsible copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MWFResponsible(Properties ctx, MWFResponsible copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * Invoker - return true if no user and no role * @return true if invoker @@ -185,4 +246,13 @@ public class MWFResponsible extends X_AD_WF_Responsible return RESPONSIBLETYPE_Manual.equals(getResponsibleType()); } + @Override + public MWFResponsible markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MWFResponsible diff --git a/org.adempiere.base/src/org/compiere/wf/MWorkflow.java b/org.adempiere.base/src/org/compiere/wf/MWorkflow.java index b81908b386..b62e006df5 100644 --- a/org.adempiere.base/src/org/compiere/wf/MWorkflow.java +++ b/org.adempiere.base/src/org/compiere/wf/MWorkflow.java @@ -21,10 +21,12 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.List; import java.util.Properties; import java.util.logging.Level; +import java.util.stream.Collectors; import org.adempiere.exceptions.DBException; import org.compiere.model.MColumn; @@ -44,6 +46,8 @@ import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.Trx; +import org.idempiere.cache.ImmutablePOSupport; +import org.idempiere.cache.ImmutablePOCache; /** * WorkFlow Model @@ -57,15 +61,25 @@ import org.compiere.util.Trx; * @author Silvano Trinchero, www.freepath.it *
  • IDEMPIERE-3209 changed functions to public to improve integration support */ -public class MWorkflow extends X_AD_Workflow +public class MWorkflow extends X_AD_Workflow implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 1905448790453650036L; + private static final long serialVersionUID = 727250581144217545L; /** - * Get Workflow from Cache + * Get Workflow from Cache (immutable) + * @param AD_Workflow_ID id + * @return workflow + */ + public static MWorkflow get (int AD_Workflow_ID) + { + return get(Env.getCtx(), AD_Workflow_ID); + } + + /** + * Get Workflow from Cache (immutable) * @param ctx context * @param AD_Workflow_ID id * @return workflow @@ -73,15 +87,32 @@ public class MWorkflow extends X_AD_Workflow public static MWorkflow get (Properties ctx, int AD_Workflow_ID) { String key = Env.getAD_Language(ctx) + "_" + AD_Workflow_ID; - MWorkflow retValue = (MWorkflow)s_cache.get(key); + MWorkflow retValue = s_cache.get(ctx, key, e -> new MWorkflow(ctx, e)); if (retValue != null) return retValue; - retValue = new MWorkflow (ctx, AD_Workflow_ID, null); - if (retValue.get_ID() != 0) - s_cache.put(key, retValue); - return retValue; + retValue = new MWorkflow (ctx, AD_Workflow_ID, (String)null); + if (retValue.get_ID() == AD_Workflow_ID) + { + s_cache.put(key, retValue, e -> new MWorkflow(Env.getCtx(), e)); + return retValue; + } + return null; } // get + /** + * Get updateable copy of MWorkflow from cache + * @param ctx + * @param AD_Workflow_ID + * @param trxName + * @return MWorkflow + */ + public static MWorkflow getCopy(Properties ctx, int AD_Workflow_ID, String trxName) + { + MWorkflow wf = get(AD_Workflow_ID); + if (wf != null) + wf = new MWorkflow(ctx, wf, trxName); + return wf; + } /** * Get Doc Value Workflow @@ -90,7 +121,7 @@ public class MWorkflow extends X_AD_Workflow * @param AD_Table_ID table * @return document value workflow array or null */ - public static MWorkflow[] getDocValue (Properties ctx, int AD_Client_ID, int AD_Table_ID + public static synchronized MWorkflow[] getDocValue (Properties ctx, int AD_Client_ID, int AD_Table_ID , String trxName //Bug 1568766 Trx should be kept all along the road ) { @@ -112,9 +143,7 @@ public class MWorkflow extends X_AD_Workflow newKey = "C" + wf.getAD_Client_ID() + "T" + wf.getAD_Table_ID(); if (!newKey.equals(oldKey) && list.size() > 0) { - MWorkflow[] wfs = new MWorkflow[list.size()]; - list.toArray(wfs); - s_cacheDocValue.put (oldKey, wfs); + s_cacheDocValue.put (oldKey, list.stream().map(e -> {return new MWorkflow(Env.getCtx(), e);}).toArray(MWorkflow[]::new)); list = new ArrayList(); } oldKey = newKey; @@ -124,9 +153,7 @@ public class MWorkflow extends X_AD_Workflow // Last one if (list.size() > 0) { - MWorkflow[] wfs = new MWorkflow[list.size()]; - list.toArray(wfs); - s_cacheDocValue.put (oldKey, wfs); + s_cacheDocValue.put (oldKey, list.stream().map(e -> {return new MWorkflow(Env.getCtx(), e);}).toArray(MWorkflow[]::new)); } if (s_log.isLoggable(Level.CONFIG)) s_log.config("#" + s_cacheDocValue.size()); } @@ -142,12 +169,12 @@ public class MWorkflow extends X_AD_Workflow retValue[i].set_TrxName(trxName); } }*/ - return retValue; + return retValue != null ? Arrays.stream(retValue).map(e -> {return new MWorkflow(ctx, e, trxName);}).toArray(MWorkflow[]::new) : null; } // getDocValue /** Single Cache */ - private static CCache s_cache = new CCache(Table_Name, Table_Name+"|Language_Workflow", 20); + private static ImmutablePOCache s_cache = new ImmutablePOCache(Table_Name, Table_Name+"|Language_Workflow", 20); /** Document Value Cache */ private static CCache s_cacheDocValue = new CCache (Table_Name, Table_Name+"|AD_Client_Table", 5); /** Static Logger */ @@ -198,6 +225,42 @@ public class MWorkflow extends X_AD_Workflow loadNodes(); } // Workflow + /** + * + * @param copy + */ + public MWorkflow(MWorkflow copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MWorkflow(Properties ctx, MWorkflow copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MWorkflow(Properties ctx, MWorkflow copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_description_trl = copy.m_description_trl; + this.m_help_trl = copy.m_help_trl; + this.m_name_trl = copy.m_name_trl; + this.m_nodes = copy.m_nodes != null ? copy.m_nodes.stream().map(e ->{return new MWFNode(ctx, e, trxName);}).collect(Collectors.toCollection(ArrayList::new)) : null; + this.m_translated = copy.m_translated; + } + /** WF Nodes */ private List m_nodes = new ArrayList(); @@ -256,6 +319,8 @@ public class MWorkflow extends X_AD_Workflow .setParameters(new Object[]{get_ID()}) .setOnlyActiveRecords(true) .list(); + if (m_nodes.size() > 0 && is_Immutable()) + m_nodes.stream().forEach(e -> e.markImmutable()); if (log.isLoggable(Level.FINE)) log.fine("#" + m_nodes.size()); } // loadNodes @@ -962,6 +1027,18 @@ public class MWorkflow extends X_AD_Workflow return true; } + @Override + public MWorkflow markImmutable() + { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_nodes != null && m_nodes.size() > 0) + m_nodes.stream().forEach(e -> e.markImmutable()); + return this; + } + /** * * @param po diff --git a/org.adempiere.base/src/org/eevolution/model/MDDOrderLine.java b/org.adempiere.base/src/org/eevolution/model/MDDOrderLine.java index fed088d854..9635b8b42a 100644 --- a/org.adempiere.base/src/org/eevolution/model/MDDOrderLine.java +++ b/org.adempiere.base/src/org/eevolution/model/MDDOrderLine.java @@ -275,7 +275,7 @@ public class MDDOrderLine extends X_DD_OrderLine public MProduct getProduct() { if (m_product == null && getM_Product_ID() != 0) - m_product = MProduct.get (getCtx(), getM_Product_ID()); + m_product = MProduct.getCopy(getCtx(), getM_Product_ID(), get_TrxName()); return m_product; } // getProduct diff --git a/org.adempiere.base/src/org/eevolution/model/MPPProductBOM.java b/org.adempiere.base/src/org/eevolution/model/MPPProductBOM.java index 8b9cb3709c..b587f20bc8 100644 --- a/org.adempiere.base/src/org/eevolution/model/MPPProductBOM.java +++ b/org.adempiere.base/src/org/eevolution/model/MPPProductBOM.java @@ -22,12 +22,14 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; import java.util.Properties; +import java.util.stream.Collectors; import org.compiere.model.MProduct; import org.compiere.model.Query; -import org.compiere.util.CCache; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * PP Product BOM Model. @@ -35,15 +37,14 @@ import org.compiere.util.Env; * @author Victor Perez www.e-evolution.com * @author Teo Sarca, http://www.arhipac.ro */ -public class MPPProductBOM extends X_PP_Product_BOM +public class MPPProductBOM extends X_PP_Product_BOM implements ImmutablePOSupport { - /** * */ - private static final long serialVersionUID = 1561124355655122911L; + private static final long serialVersionUID = -5048325803007991296L; /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 40, 5); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 40, 5); /** BOM Lines */ private List m_lines = null; @@ -61,8 +62,19 @@ public class MPPProductBOM extends X_PP_Product_BOM .list(); } + /** - * Get Product BOM by ID (cached) + * Get Product BOM by ID (cached) (immutable) + * @param PP_Product_BOM_ID + * @return product bom + */ + public static MPPProductBOM get(int PP_Product_BOM_ID) + { + return get(Env.getCtx(), PP_Product_BOM_ID); + } + + /** + * Get Product BOM by ID (cached) (immutable) * @param ctx * @param PP_Product_BOM_ID * @return product bom @@ -71,18 +83,30 @@ public class MPPProductBOM extends X_PP_Product_BOM { if (PP_Product_BOM_ID <= 0) return null; - MPPProductBOM bom = s_cache.get(PP_Product_BOM_ID); + MPPProductBOM bom = s_cache.get(ctx, PP_Product_BOM_ID, e -> new MPPProductBOM(ctx, e)); if (bom != null) return bom; - bom = new MPPProductBOM(ctx, PP_Product_BOM_ID, null); + bom = new MPPProductBOM(ctx, PP_Product_BOM_ID, (String)null); if (bom.get_ID() == PP_Product_BOM_ID) { - s_cache.put(PP_Product_BOM_ID, bom); - } - else - { - bom = null; + s_cache.put(PP_Product_BOM_ID, bom, e -> new MPPProductBOM(Env.getCtx(), e)); + return bom; } + return null; + } + + /** + * Get updateable copy of MPPProductBOM from cache + * @param ctx + * @param PP_Product_BOM_ID + * @param trxName + * @return MPPProductBOM + */ + public static MPPProductBOM getCopy(Properties ctx, int PP_Product_BOM_ID, String trxName) + { + MPPProductBOM bom = get(PP_Product_BOM_ID); + if (bom != null) + bom = new MPPProductBOM(ctx, bom, trxName); return bom; } @@ -107,7 +131,7 @@ public class MPPProductBOM extends X_PP_Product_BOM */ public static MPPProductBOM getDefault(MProduct product, String trxName) { - MPPProductBOM bom = new Query(product.getCtx(), Table_Name, "M_Product_ID=? AND Value=?", trxName) + MPPProductBOM bom = new Query(Env.getCtx(), Table_Name, "M_Product_ID=? AND Value=?", trxName) .setParameters(new Object[]{product.getM_Product_ID(), product.getValue()}) .setClient_ID() .firstOnly(); @@ -179,6 +203,38 @@ public class MPPProductBOM extends X_PP_Product_BOM super (ctx, rs,trxName); } + /** + * + * @param copy + */ + public MPPProductBOM(MPPProductBOM copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MPPProductBOM(Properties ctx, MPPProductBOM copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MPPProductBOM(Properties ctx, MPPProductBOM copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_lines = copy.m_lines != null ? copy.m_lines.stream().map(e -> {return new MPPProductBOMLine(ctx, e, trxName);}).collect(Collectors.toCollection(ArrayList::new)) : null; + } + /** * Get BOM Lines valid date for Product BOM * @param valid Date to Validate @@ -221,6 +277,8 @@ public class MPPProductBOM extends X_PP_Product_BOM .setOnlyActiveRecords(true) .setOrderBy(MPPProductBOMLine.COLUMNNAME_Line) .list(); + if (m_lines.size() > 0 && is_Immutable()) + m_lines.stream().forEach(e -> e.markImmutable()); } return this.m_lines.toArray(new MPPProductBOMLine[this.m_lines.size()]); } // getLines @@ -270,6 +328,19 @@ public class MPPProductBOM extends X_PP_Product_BOM product.setIsBOM(count > 0); product.saveEx(); } + + @Override + public MPPProductBOM markImmutable() + { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_lines != null && m_lines.size() > 0) + m_lines.stream().forEach(e -> e.markImmutable()); + return this; + } + @Override public String toString () diff --git a/org.adempiere.base/src/org/eevolution/model/MPPProductBOMLine.java b/org.adempiere.base/src/org/eevolution/model/MPPProductBOMLine.java index 6750910dae..4d8e215972 100644 --- a/org.adempiere.base/src/org/eevolution/model/MPPProductBOMLine.java +++ b/org.adempiere.base/src/org/eevolution/model/MPPProductBOMLine.java @@ -35,6 +35,7 @@ import org.compiere.model.MUOM; import org.compiere.model.Query; import org.compiere.util.DB; import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; /** * PP Product BOM Line Model. @@ -48,14 +49,13 @@ import org.compiere.util.Env; * @author Victor Perez www.e-evolution.com * @author Teo Sarca, www.arhipac.ro */ -public class MPPProductBOMLine extends X_PP_Product_BOMLine +public class MPPProductBOMLine extends X_PP_Product_BOMLine implements ImmutablePOSupport { - - /** * */ - private static final long serialVersionUID = -5792418944606756221L; + private static final long serialVersionUID = 5942313871247489972L; + MPPProductBOM m_bom = null; /** @@ -104,6 +104,38 @@ public class MPPProductBOMLine extends X_PP_Product_BOMLine super(ctx, rs, trxName); } // MPPProductBOMLine + /** + * + * @param copy + */ + public MPPProductBOMLine(MPPProductBOMLine copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MPPProductBOMLine(Properties ctx, MPPProductBOMLine copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MPPProductBOMLine(Properties ctx, MPPProductBOMLine copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_bom = copy.m_bom != null ? new MPPProductBOM(ctx, copy.m_bom, trxName) : null; + } + /** * Calculate Low Level of a Product * @param ID Product @@ -129,7 +161,7 @@ public class MPPProductBOMLine extends X_PP_Product_BOMLine public MProduct getProduct() { - return MProduct.get(getCtx(), getM_Product_ID()); + return MProduct.getCopy(getCtx(), getM_Product_ID(), get_TrxName()); } /** @@ -275,6 +307,16 @@ public class MPPProductBOMLine extends X_PP_Product_BOMLine } return allocationPercent; } + + @Override + public MPPProductBOMLine markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } class ProductLowLevelCalculator diff --git a/org.adempiere.base/src/org/eevolution/model/MPPProductPlanning.java b/org.adempiere.base/src/org/eevolution/model/MPPProductPlanning.java index 66c80ee594..518a50d968 100644 --- a/org.adempiere.base/src/org/eevolution/model/MPPProductPlanning.java +++ b/org.adempiere.base/src/org/eevolution/model/MPPProductPlanning.java @@ -216,19 +216,19 @@ public class MPPProductPlanning extends X_PP_Product_Planning @Override public MPPProductBOM getPP_Product_BOM() { - return MPPProductBOM.get(getCtx(), getPP_Product_BOM_ID()); + return MPPProductBOM.getCopy(getCtx(), getPP_Product_BOM_ID(), get_TrxName()); } @Override public MWorkflow getAD_Workflow() { - return MWorkflow.get(getCtx(), getAD_Workflow_ID()); + return MWorkflow.getCopy(getCtx(), getAD_Workflow_ID(), get_TrxName()); } @Override public MResource getS_Resource() { - return MResource.get(getCtx(), getS_Resource_ID()); + return MResource.getCopy(getCtx(), getS_Resource_ID(), get_TrxName()); } diff --git a/org.adempiere.base/src/org/idempiere/broadcast/BroadcastMsgUtil.java b/org.adempiere.base/src/org/idempiere/broadcast/BroadcastMsgUtil.java index 67aa75615f..71e0b48e8b 100644 --- a/org.adempiere.base/src/org/idempiere/broadcast/BroadcastMsgUtil.java +++ b/org.adempiere.base/src/org/idempiere/broadcast/BroadcastMsgUtil.java @@ -54,7 +54,7 @@ public class BroadcastMsgUtil */ public static void publishBroadcastMessage(final int messageID, String trxName) { - MBroadcastMessage mbMessage = MBroadcastMessage.get(Env.getCtx(), messageID); + MBroadcastMessage mbMessage = new MBroadcastMessage(Env.getCtx(), messageID, trxName); String broadcastType = mbMessage.getBroadcastType(); if (MBroadcastMessage.BROADCASTTYPE_Login.equals(broadcastType) diff --git a/org.adempiere.base/src/org/idempiere/broadcast/process/ExpireBrodcastMessage.java b/org.adempiere.base/src/org/idempiere/broadcast/process/ExpireBrodcastMessage.java index 9361d370d2..56c3f5cc4d 100644 --- a/org.adempiere.base/src/org/idempiere/broadcast/process/ExpireBrodcastMessage.java +++ b/org.adempiere.base/src/org/idempiere/broadcast/process/ExpireBrodcastMessage.java @@ -33,7 +33,7 @@ public class ExpireBrodcastMessage extends SvrProcess{ @Override protected String doIt() throws Exception { - MBroadcastMessage mbMessage = MBroadcastMessage.get(Env.getCtx(), getRecord_ID()); + MBroadcastMessage mbMessage = new MBroadcastMessage(Env.getCtx(), getRecord_ID(), get_TrxName()); if (MBroadcastMessage.BROADCASTFREQUENCY_UntilExpiration.equals(mbMessage.getBroadcastFrequency()) && !mbMessage.isExpired() && mbMessage.isPublished()){ String sql = "UPDATE AD_Note SET Processed='Y' WHERE AD_BroadcastMessage_ID = ?"; diff --git a/org.adempiere.base/src/org/idempiere/cache/ImmutableIntPOCache.java b/org.adempiere.base/src/org/idempiere/cache/ImmutableIntPOCache.java new file mode 100644 index 0000000000..32277532b0 --- /dev/null +++ b/org.adempiere.base/src/org/idempiere/cache/ImmutableIntPOCache.java @@ -0,0 +1,139 @@ +/********************************************************************** +* 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: * +* - Trek Global Corporation * +* - Heng Sin Low * +**********************************************************************/ +package org.idempiere.cache; + +import org.compiere.model.PO; + +/** + * ImmutableIntPOCache key by Integer record id + * @author hengsin + * + */ +public class ImmutableIntPOCache extends ImmutablePOCache { + + /** + * + */ + private static final long serialVersionUID = -6605758049101851103L; + + /** + * @param name + * @param initialCapacity + * @param expireMinutes + * @param distributed + * @param maxSize + */ + public ImmutableIntPOCache(String name, int initialCapacity, int expireMinutes, boolean distributed, int maxSize) { + super(name, initialCapacity, expireMinutes, distributed, maxSize); + } + + /** + * @param name + * @param initialCapacity + * @param expireMinutes + * @param distributed + */ + public ImmutableIntPOCache(String name, int initialCapacity, int expireMinutes, boolean distributed) { + super(name, initialCapacity, expireMinutes, distributed); + } + + /** + * @param name + * @param initialCapacity + * @param expireMinutes + */ + public ImmutableIntPOCache(String name, int initialCapacity, int expireMinutes) { + super(name, initialCapacity, expireMinutes); + } + + /** + * @param name + * @param initialCapacity + */ + public ImmutableIntPOCache(String name, int initialCapacity) { + super(name, initialCapacity); + } + + /** + * @param tableName + * @param name + * @param initialCapacity + * @param distributed + */ + public ImmutableIntPOCache(String tableName, String name, int initialCapacity, boolean distributed) { + super(tableName, name, initialCapacity, distributed); + } + + /** + * @param tableName + * @param name + * @param initialCapacity + * @param expireMinutes + * @param distributed + * @param maxSize + */ + public ImmutableIntPOCache(String tableName, String name, int initialCapacity, int expireMinutes, + boolean distributed, int maxSize) { + super(tableName, name, initialCapacity, expireMinutes, distributed, maxSize); + } + + /** + * @param tableName + * @param name + * @param initialCapacity + * @param expireMinutes + * @param distributed + */ + public ImmutableIntPOCache(String tableName, String name, int initialCapacity, int expireMinutes, + boolean distributed) { + super(tableName, name, initialCapacity, expireMinutes, distributed); + } + + /** + * @param tableName + * @param name + * @param initialCapacity + */ + public ImmutableIntPOCache(String tableName, String name, int initialCapacity) { + super(tableName, name, initialCapacity); + } + + @Override + public int reset(int recordId) { + if (recordId <= 0) + return reset(); + + if (cache.isEmpty() && nullList.isEmpty()) + return 0; + + if (!nullList.isEmpty()) { + if (nullList.remove(recordId)) return 1; + } + V removed = cache.remove(recordId); + return removed != null ? 1 : 0; + } + +} diff --git a/org.adempiere.base/src/org/idempiere/cache/ImmutablePOCache.java b/org.adempiere.base/src/org/idempiere/cache/ImmutablePOCache.java new file mode 100644 index 0000000000..82bb7030b1 --- /dev/null +++ b/org.adempiere.base/src/org/idempiere/cache/ImmutablePOCache.java @@ -0,0 +1,277 @@ +/********************************************************************** +* 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: * +* - Trek Global Corporation * +* - Heng Sin Low * +**********************************************************************/ +package org.idempiere.cache; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Properties; +import java.util.function.UnaryOperator; + +import org.compiere.model.PO; +import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.compiere.util.Util; + +/** + * Thread safe PO cache. For thread safety, only PO with thread local context (po.getCtx() == Env.getCtx() and without trxName is keep in cache. + * PO is mark immutable before being added to cache. If the pass in PO doesn't match the 2 condition, a copy of the PO is added to cache instead. + * For get operation, if request is being make with non thread local context (ctx != Env.getCtx()) or with trxName, a copy of the PO from cache + * is return instead. + * + * @author hengsin + */ +public class ImmutablePOCache extends CCache { + + /** + * + */ + private static final long serialVersionUID = -3342469152066078741L; + + /** + * + * @param name + * @param initialCapacity + * @param expireMinutes + * @param distributed + * @param maxSize + */ + public ImmutablePOCache(String name, int initialCapacity, int expireMinutes, boolean distributed, int maxSize) { + super(name, initialCapacity, expireMinutes, distributed, maxSize); + } + + /** + * + * @param name + * @param initialCapacity + * @param expireMinutes + * @param distributed + */ + public ImmutablePOCache(String name, int initialCapacity, int expireMinutes, boolean distributed) { + super(name, initialCapacity, expireMinutes, distributed); + } + + /** + * + * @param name + * @param initialCapacity + * @param expireMinutes + */ + public ImmutablePOCache(String name, int initialCapacity, int expireMinutes) { + super(name, initialCapacity, expireMinutes); + } + + /** + * + * @param name + * @param initialCapacity + */ + public ImmutablePOCache(String name, int initialCapacity) { + super(name, initialCapacity); + } + + /** + * + * @param tableName + * @param name + * @param initialCapacity + * @param distributed + */ + public ImmutablePOCache(String tableName, String name, int initialCapacity, boolean distributed) { + super(tableName, name, initialCapacity, distributed); + } + + /** + * + * @param tableName + * @param name + * @param initialCapacity + * @param expireMinutes + * @param distributed + * @param maxSize + */ + public ImmutablePOCache(String tableName, String name, int initialCapacity, int expireMinutes, boolean distributed, + int maxSize) { + super(tableName, name, initialCapacity, expireMinutes, distributed, maxSize); + } + + /** + * + * @param tableName + * @param name + * @param initialCapacity + * @param expireMinutes + * @param distributed + */ + public ImmutablePOCache(String tableName, String name, int initialCapacity, int expireMinutes, boolean distributed) { + super(tableName, name, initialCapacity, expireMinutes, distributed); + } + + /** + * + * @param tableName + * @param name + * @param initialCapacity + */ + public ImmutablePOCache(String tableName, String name, int initialCapacity) { + super(tableName, name, initialCapacity); + } + + @Override + public V put(K key, V value) { + return put(key, value, (UnaryOperator)null); + } + + /** + * PO is mark immutable and add to cache if it is without trxName and with thread local context (i.e po.getCtx() == Env.getCtx()). + * If neither of the condition is not true, a copy of the PO will be created and add to cache using the pass copyOperator or + * through copy constructor (through reflection) if copyOperator parameter is null (exception is throw if both copyOperator and + * copy constructor is not available). + * @param key + * @param po + * @param copyOperator operator to call copy constructor if po has transaction name or po.getCtx() != Env.getCtx() + * @return po or the copy of po that have been added to cache + */ + public V put(K key, V po, UnaryOperator copyOperator) { + if (po == null) { + super.put(key, po); + return null; + } + + po.markImmutable(); + if (Util.isEmpty(po.get_TrxName(), true) && po.getCtx() == Env.getCtx()) { + super.put(key, po); + return po; + } else if (copyOperator == null) { + try { + V copy = null; + try { + copy = copyOf(Env.getCtx(), po); + } catch (Exception e) {} + if (copy == null) + copy = copyOf(Env.getCtx(), po, (String)null); + + if (copy != null) { + super.put(key, copy); + return copy; + } + throw new RuntimeException("No copy constructor for " + po.getClass().getName()); + } catch (NoSuchMethodException | SecurityException | InvocationTargetException | IllegalAccessException | InstantiationException e) { + throw new RuntimeException("Error calling copy constructor for " + po.getClass().getName() + " : " + e.getMessage(), e); + } + } else { + V copy = copyOperator.apply(po); + copy.markImmutable(); + super.put(key, copy); + return copy; + } + } + + @SuppressWarnings("unchecked") + @Override + public V get(Object key) { + try { + return get((Properties)null, (K)key); + } catch (ClassCastException e) { + return null; + } + } + + /** + * @param ctx context + * @param key + * @return value for key + */ + public V get(Properties ctx, K key) { + return get(ctx, key, (UnaryOperator)null); + } + + /** + * Get PO from cache. If ctx != Env.getCtx() or trxName is not empty, a copy of the PO is return instead + * @param ctx context + * @param key + * @param copyOperator operator to call copy constructor when ctx != po.getCtx() or transaction name is not empty + * @return PO from cache (if there's match for key) + */ + @SuppressWarnings("unchecked") + public V get(Properties ctx, K key, UnaryOperator copyOperator) { + V value = super.get(key); + if (value == null) + return null; + + if (ctx == null) + ctx = Env.getCtx(); + if (ctx != value.getCtx()) { + if (copyOperator == null) { + //use reflection to find copy constructor + try { + try { + V copy = copyOf(ctx, value); + if (copy != null) + return copy; + } catch (Exception e) {} + + V copy = copyOf(ctx, value, (String)null); + if (copy != null) + return copy; + + throw new RuntimeException("No copy constructor for " + value.getClass().getName()); + } catch (NoSuchMethodException | SecurityException | InvocationTargetException | IllegalAccessException | InstantiationException e) { + throw new RuntimeException("Error calling copy constructor for " + value.getClass().getName() + " : " + e.getMessage(), e); + } + + } else { + V copy = copyOperator.apply(value); + return (V) copy.markImmutable(); + } + } else { + return value; + } + } + + @SuppressWarnings("unchecked") + private V copyOf(Properties ctx, V value, String trxName) + throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + Constructor copyConstructor; + copyConstructor = value.getClass().getDeclaredConstructor(Properties.class, value.getClass(), String.class); + if (copyConstructor != null) { + V copy = (V) copyConstructor.newInstance(ctx, value, trxName); + return (V) copy.markImmutable(); + } + return null; + } + + @SuppressWarnings("unchecked") + private V copyOf(Properties ctx, V value) + throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + Constructor copyConstructor; + copyConstructor = value.getClass().getDeclaredConstructor(Properties.class, value.getClass()); + if (copyConstructor != null) { + V copy = (V) copyConstructor.newInstance(ctx, value); + return (V) copy.markImmutable(); + } + return null; + } +} diff --git a/org.adempiere.base/src/org/idempiere/cache/ImmutablePOSupport.java b/org.adempiere.base/src/org/idempiere/cache/ImmutablePOSupport.java new file mode 100644 index 0000000000..5e6a8bfbcd --- /dev/null +++ b/org.adempiere.base/src/org/idempiere/cache/ImmutablePOSupport.java @@ -0,0 +1,41 @@ +/********************************************************************** +* 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: * +* - Trek Global Corporation * +* - Heng Sin Low * +**********************************************************************/ +package org.idempiere.cache; + +import org.compiere.model.PO; + +/** + * Model class that support immutable should implement this interface + * @author hengsin + * + */ +public interface ImmutablePOSupport { + /** + * mark PO as immutable + * @return PO + */ + public PO markImmutable(); +} diff --git a/org.adempiere.base/src/org/idempiere/cache/IntPOCopyCache.java b/org.adempiere.base/src/org/idempiere/cache/IntPOCopyCache.java new file mode 100644 index 0000000000..d8363a48f4 --- /dev/null +++ b/org.adempiere.base/src/org/idempiere/cache/IntPOCopyCache.java @@ -0,0 +1,137 @@ +/********************************************************************** +* 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: * +* - Trek Global Corporation * +* - Heng Sin Low * +**********************************************************************/ +package org.idempiere.cache; + +import org.compiere.model.PO; + +/** + * POCopyCache key by Integer record id + * @author hengsin + * + */ +public class IntPOCopyCache extends POCopyCache { + + /** + * + */ + private static final long serialVersionUID = 606664825366527176L; + + /** + * @param name + * @param initialCapacity + * @param expireMinutes + * @param distributed + * @param maxSize + */ + public IntPOCopyCache(String name, int initialCapacity, int expireMinutes, boolean distributed, int maxSize) { + super(name, initialCapacity, expireMinutes, distributed, maxSize); + } + + /** + * @param name + * @param initialCapacity + * @param expireMinutes + * @param distributed + */ + public IntPOCopyCache(String name, int initialCapacity, int expireMinutes, boolean distributed) { + super(name, initialCapacity, expireMinutes, distributed); + } + + /** + * @param name + * @param initialCapacity + * @param expireMinutes + */ + public IntPOCopyCache(String name, int initialCapacity, int expireMinutes) { + super(name, initialCapacity, expireMinutes); + } + + /** + * @param name + * @param initialCapacity + */ + public IntPOCopyCache(String name, int initialCapacity) { + super(name, initialCapacity); + } + + /** + * @param tableName + * @param name + * @param initialCapacity + * @param distributed + */ + public IntPOCopyCache(String tableName, String name, int initialCapacity, boolean distributed) { + super(tableName, name, initialCapacity, distributed); + } + + /** + * @param tableName + * @param name + * @param initialCapacity + * @param expireMinutes + * @param distributed + * @param maxSize + */ + public IntPOCopyCache(String tableName, String name, int initialCapacity, int expireMinutes, boolean distributed, + int maxSize) { + super(tableName, name, initialCapacity, expireMinutes, distributed, maxSize); + } + + /** + * @param tableName + * @param name + * @param initialCapacity + * @param expireMinutes + * @param distributed + */ + public IntPOCopyCache(String tableName, String name, int initialCapacity, int expireMinutes, boolean distributed) { + super(tableName, name, initialCapacity, expireMinutes, distributed); + } + + /** + * @param tableName + * @param name + * @param initialCapacity + */ + public IntPOCopyCache(String tableName, String name, int initialCapacity) { + super(tableName, name, initialCapacity); + } + + @Override + public int reset(int recordId) { + if (recordId <= 0) + return reset(); + + if (cache.isEmpty() && nullList.isEmpty()) + return 0; + + if (!nullList.isEmpty()) { + if (nullList.remove(recordId)) return 1; + } + V removed = cache.remove(recordId); + return removed != null ? 1 : 0; + } +} diff --git a/org.adempiere.base/src/org/idempiere/cache/POCopyCache.java b/org.adempiere.base/src/org/idempiere/cache/POCopyCache.java new file mode 100644 index 0000000000..246bc846c6 --- /dev/null +++ b/org.adempiere.base/src/org/idempiere/cache/POCopyCache.java @@ -0,0 +1,275 @@ +/********************************************************************** +* 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: * +* - Trek Global Corporation * +* - Heng Sin Low * +**********************************************************************/ +package org.idempiere.cache; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Properties; +import java.util.function.UnaryOperator; + +import org.compiere.model.PO; +import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.compiere.util.Util; + +/** + * Thread safe PO cache using copy on read and copy on write strategy. + * + * @author hengsin + */ +public class POCopyCache extends CCache { + + /** + * + */ + private static final long serialVersionUID = 7463584909438958260L; + + /** + * + * @param name + * @param initialCapacity + * @param expireMinutes + * @param distributed + * @param maxSize + */ + public POCopyCache(String name, int initialCapacity, int expireMinutes, boolean distributed, int maxSize) { + super(name, initialCapacity, expireMinutes, distributed, maxSize); + } + + /** + * + * @param name + * @param initialCapacity + * @param expireMinutes + * @param distributed + */ + public POCopyCache(String name, int initialCapacity, int expireMinutes, boolean distributed) { + super(name, initialCapacity, expireMinutes, distributed); + } + + /** + * + * @param name + * @param initialCapacity + * @param expireMinutes + */ + public POCopyCache(String name, int initialCapacity, int expireMinutes) { + super(name, initialCapacity, expireMinutes); + } + + /** + * + * @param name + * @param initialCapacity + */ + public POCopyCache(String name, int initialCapacity) { + super(name, initialCapacity); + } + + /** + * + * @param tableName + * @param name + * @param initialCapacity + * @param distributed + */ + public POCopyCache(String tableName, String name, int initialCapacity, boolean distributed) { + super(tableName, name, initialCapacity, distributed); + } + + /** + * + * @param tableName + * @param name + * @param initialCapacity + * @param expireMinutes + * @param distributed + * @param maxSize + */ + public POCopyCache(String tableName, String name, int initialCapacity, int expireMinutes, boolean distributed, + int maxSize) { + super(tableName, name, initialCapacity, expireMinutes, distributed, maxSize); + } + + /** + * + * @param tableName + * @param name + * @param initialCapacity + * @param expireMinutes + * @param distributed + */ + public POCopyCache(String tableName, String name, int initialCapacity, int expireMinutes, boolean distributed) { + super(tableName, name, initialCapacity, expireMinutes, distributed); + } + + /** + * + * @param tableName + * @param name + * @param initialCapacity + */ + public POCopyCache(String tableName, String name, int initialCapacity) { + super(tableName, name, initialCapacity); + } + + @Override + public V put(K key, V value) { + return put(key, value, (UnaryOperator)null); + } + + /** + * A copy of the PO will be created and add to cache using copyOperator or through copy constructor (through reflection) + * if copyOperator parameter is null (exception is throw if both copyOperator and copy constructor is not available). + * @param key + * @param po + * @param copyOperator operator to call copy constructor + * @return PO added to cache + */ + public V put(K key, V po, UnaryOperator copyOperator) { + if (po == null ) { + super.put(key, po); + return null; + } + + if (copyOperator == null) { + try { + try { + V copy = copyOf(Env.getCtx(), po); + if (copy != null) { + super.put(key, copy); + return copy; + } + } catch (Exception e) {} + + V copy = copyOf(Env.getCtx(), po, (String)null); + if (copy != null) { + super.put(key, copy); + return copy; + } + throw new RuntimeException("No copy constructor for " + po.getClass().getName()); + } catch (NoSuchMethodException | SecurityException | InvocationTargetException | IllegalAccessException | InstantiationException e) { + throw new RuntimeException("Error calling copy constructor for " + po.getClass().getName() + " : " + e.getMessage(), e); + } + } else { + V copy = copyOperator.apply(po); + super.put(key, copy); + return copy; + } + } + + @SuppressWarnings("unchecked") + @Override + public V get(Object key) { + try { + return get((Properties)null, (K)key); + } catch (ClassCastException e) { + return null; + } + } + + /** + * @param ctx context + * @param key + * @return value for key + */ + public V get(Properties ctx, K key) { + return get(ctx, key, (String)null); + } + + /** + * @param ctx context + * @param key + * @param trxName + * @return value for key + */ + public V get(Properties ctx, K key, String trxName) { + V value = super.get(key); + if (value == null) + return null; + + if (ctx == null) + ctx = Env.getCtx(); + + //use reflection to find copy constructor + try { + if (Util.isEmpty(trxName, true)) { + try { + V copy = copyOf(ctx, value); + if (copy != null) + return copy; + } catch (Exception e) {} + } + + V copy = copyOf(ctx, value, trxName); + if (copy != null) + return copy; + + throw new RuntimeException("No copy constructor for " + value.getClass().getName()); + } catch (NoSuchMethodException | SecurityException | InvocationTargetException | IllegalAccessException | InstantiationException e) { + throw new RuntimeException("Error calling copy constructor for " + value.getClass().getName() + " : " + e.getMessage(), e); + } + } + + /** + * Get PO from cache. A copy of the cached PO is return + * @param key + * @param copyOperator operator to call copy constructor + * @return PO from cache (if there's match for key) + */ + public V get(K key, UnaryOperator copyOperator) { + V value = super.get(key); + if (value == null) + return null; + + V copy = copyOperator.apply(value); + return copy; + } + + @SuppressWarnings("unchecked") + private V copyOf(Properties ctx, V value, String trxName) + throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + Constructor copyConstructor; + copyConstructor = value.getClass().getDeclaredConstructor(Properties.class, value.getClass(), String.class); + if (copyConstructor != null) { + V copy = (V) copyConstructor.newInstance(ctx, value, trxName); + return copy; + } + return null; + } + + @SuppressWarnings("unchecked") + private V copyOf(Properties ctx, V value) + throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + Constructor copyConstructor; + copyConstructor = value.getClass().getDeclaredConstructor(Properties.class, value.getClass()); + if (copyConstructor != null) { + V copy = (V) copyConstructor.newInstance(ctx, value); + return copy; + } + return null; + } +} diff --git a/org.adempiere.server/src/main/server/org/compiere/server/Scheduler.java b/org.adempiere.server/src/main/server/org/compiere/server/Scheduler.java index ac9875c14d..6c6a8355f9 100644 --- a/org.adempiere.server/src/main/server/org/compiere/server/Scheduler.java +++ b/org.adempiere.server/src/main/server/org/compiere/server/Scheduler.java @@ -48,14 +48,13 @@ import org.compiere.print.MPrintFormat; import org.compiere.process.ProcessInfo; import org.compiere.process.ProcessInfoUtil; import org.compiere.process.ServerProcessCtl; -import org.compiere.util.CCache; import org.compiere.util.DB; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.TimeUtil; import org.compiere.util.Trx; import org.compiere.util.Util; - +import org.idempiere.cache.ImmutableIntPOCache; /** * Scheduler @@ -86,7 +85,7 @@ public class Scheduler extends AdempiereServer protected int AD_Scheduler_ID; - private static CCache s_cache = new CCache(MScheduler.Table_Name, 10, 60, true); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(MScheduler.Table_Name, 10, 60, true); /** * Work @@ -611,6 +610,7 @@ public class Scheduler extends AdempiereServer } // getServerInfo /** + * Get MScheduler from cache (immutable) * @param ctx * @param AD_Scheduler_ID * @return MScheduler @@ -618,16 +618,21 @@ public class Scheduler extends AdempiereServer protected static MScheduler get(Properties ctx, int AD_Scheduler_ID) { Integer key = Integer.valueOf(AD_Scheduler_ID); - MScheduler retValue = (MScheduler)s_cache.get(key); + MScheduler retValue = s_cache.get(ctx, key, e -> new MScheduler(ctx, e)); if (retValue == null) { - retValue = new MScheduler(ctx, AD_Scheduler_ID, null); + retValue = new MScheduler(ctx, AD_Scheduler_ID, (String)null); if (AD_Scheduler_ID == 0) { String trxName = null; retValue.load(trxName); // load System Record } - s_cache.put(key, retValue); + if (retValue.get_ID() == AD_Scheduler_ID) + { + s_cache.put(key, retValue, e -> new MScheduler(Env.getCtx(), e)); + return retValue; + } + return null; } return retValue; } // get diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WResetPassword.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WResetPassword.java index 36ef7d1ca5..ac413eb686 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WResetPassword.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WResetPassword.java @@ -309,7 +309,7 @@ public class WResetPassword implements IFormController, EventListener, Va String p_NewEMailUser = txtNewEMailUser.getValue(); String p_NewEMailUserPW = txtNewEMailUserPW.getValue(); - MUser user = MUser.get(Env.getCtx(), p_AD_User_ID); + MUser user = new MUser(Env.getCtx(), p_AD_User_ID, (String)null); if (log.isLoggable(Level.FINE)) log.fine("User=" + user); // Do we need a password ? @@ -377,7 +377,6 @@ public class WResetPassword implements IFormController, EventListener, Va } catch(AdempiereException e) { - user.load(user.get_TrxName()); throw e; } clearForm(); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/wf/WFEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/wf/WFEditor.java index 95902d0d32..4cf7b45b55 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/wf/WFEditor.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/wf/WFEditor.java @@ -270,7 +270,7 @@ public class WFEditor extends ADForm { private void load(int workflowId, boolean reread) { // Get Workflow - m_wf = MWorkflow.get(Env.getCtx(), workflowId); + m_wf = MWorkflow.getCopy(Env.getCtx(), workflowId, (String)null); m_workflowId = workflowId; nodeContainer = new WFNodeContainer(); nodeContainer.setWorkflow(m_wf); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRecentItems.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRecentItems.java index d48f36b7ea..fda1721698 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRecentItems.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRecentItems.java @@ -174,8 +174,11 @@ public class DPRecentItems extends DashboardPanel implements EventListener } // load data if (m_mImage == null) - m_mImage = MImage.get (Env.getCtx(), 0); + m_mImage = new MImage (Env.getCtx(), 0, null); else { if (m_mImage.getData()!=null) @@ -272,7 +272,7 @@ public class WImageDialog extends Window implements EventListener image.setContent(img); if (m_mImage == null) - m_mImage = MImage.get (Env.getCtx(), 0); + m_mImage = new MImage (Env.getCtx(), 0, null); m_mImage.setName(defaultNameForCaptureImage); m_mImage.setBinaryData(imageData); fileNameTextbox.setValue(defaultNameForCaptureImage); @@ -351,7 +351,7 @@ public class WImageDialog extends Window implements EventListener // Save info if (m_mImage == null) - m_mImage = MImage.get (Env.getCtx(), 0); + m_mImage = new MImage (Env.getCtx(), 0, null); m_mImage.setName(fileName); m_mImage.setImageURL(fileName); if (image.getContent() != null) diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WLocationDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WLocationDialog.java index b0280a9f9e..c3544a901d 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WLocationDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WLocationDialog.java @@ -180,7 +180,7 @@ public class WLocationDialog extends Window implements EventListener initComponents(); init(); // Current Country - for (MCountry country:MCountry.getCountries(Env.getCtx())) + for (MCountry country:MCountry.getCountries()) { lstCountry.appendItem(country.toString(), country); } @@ -190,7 +190,7 @@ public class WLocationDialog extends Window implements EventListener m_origCountry_ID = m_location.getC_Country_ID(); // Current Region lstRegion.appendItem("", null); - for (MRegion region : MRegion.getRegions(Env.getCtx(), m_origCountry_ID)) + for (MRegion region : MRegion.getRegions(m_origCountry_ID)) { lstRegion.appendItem(region.getName(),region); } @@ -540,7 +540,7 @@ public class WLocationDialog extends Window implements EventListener lstRegion.getChildren().clear(); if (country.isHasRegion()) { lstRegion.appendItem("", null); - for (MRegion region : MRegion.getRegions(Env.getCtx(), country.getC_Country_ID())) + for (MRegion region : MRegion.getRegions(country.getC_Country_ID())) { lstRegion.appendItem(region.getName(),region); } diff --git a/org.idempiere.test/src/org/idempiere/test/AbstractTestCase.java b/org.idempiere.test/src/org/idempiere/test/AbstractTestCase.java index b22e8a8b6d..4d9fcb2651 100644 --- a/org.idempiere.test/src/org/idempiere/test/AbstractTestCase.java +++ b/org.idempiere.test/src/org/idempiere/test/AbstractTestCase.java @@ -106,6 +106,7 @@ public abstract class AbstractTestCase { Env.verifyLanguage(Env.getCtx(), getLanguage()); Env.setContext(Env.getCtx(), Env.LANGUAGE, getLanguage().getAD_Language()); Env.setContext(Env.getCtx(), Env.LOCALE, getLanguage().getLocale().toString()); + Env.setContext(Env.getCtx(), Env.RUNNING_UNIT_TESTING_TEST_CASE, true); if (loginDetails.getRoleId() > 0) { if (MRole.getDefault(Env.getCtx(), false).isShowAcct()) diff --git a/org.idempiere.test/src/org/idempiere/test/base/InitialClientSetupTest.java b/org.idempiere.test/src/org/idempiere/test/base/InitialClientSetupTest.java new file mode 100644 index 0000000000..55c5f5ced5 --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/base/InitialClientSetupTest.java @@ -0,0 +1,115 @@ +/*********************************************************************** + * 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: * + * - hengsin * + **********************************************************************/ +package org.idempiere.test.base; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.File; +import java.sql.Timestamp; + +import org.compiere.Adempiere; +import org.compiere.model.MPInstance; +import org.compiere.model.MPInstancePara; +import org.compiere.model.MProcess; +import org.compiere.process.ProcessInfo; +import org.compiere.util.Language; +import org.compiere.util.Trx; +import org.idempiere.test.AbstractTestCase; +import org.idempiere.test.LoginDetails; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; + +/** + * @author hengsin + * + */ +public class InitialClientSetupTest extends AbstractTestCase { + + /** + * + */ + public InitialClientSetupTest() { + } + + @Override + protected LoginDetails newLoginDetails(TestInfo testInfo) { + //System client, SuperUser and System Administrator role + return new LoginDetails(0, 0, 0, 0, 0, + new Timestamp(System.currentTimeMillis()), Language.getLanguage("en_US")); + } + + @Test + public void testSetup() { + int AD_Process_ID = 53161; + MProcess process = MProcess.get(AD_Process_ID); + + MPInstance pinstance = new MPInstance(process, 0); + MPInstancePara[] paras = pinstance.getParameters(); + for (MPInstancePara para : paras) { + if (para.getParameterName().equals("ClientName")) { + para.setP_String("JUnit_InitialClientSetupTest"); + para.saveEx(); + } else if (para.getParameterName().equals("OrgValue")) { + para.setP_String("OrgValue"); + para.saveEx(); + } else if (para.getParameterName().equals("OrgName")) { + para.setP_String("OrgName"); + para.saveEx(); + } else if (para.getParameterName().equals("AdminUserName")) { + para.setP_String("AdminUserName"); + para.saveEx(); + } else if (para.getParameterName().equals("NormalUserName")) { + para.setP_String("NormalUserName"); + para.saveEx(); + } else if (para.getParameterName().equals("C_Currency_ID")) { + para.setP_Number(100); + para.saveEx(); + } else if (para.getParameterName().equals("C_Country_ID")) { + para.setP_Number(100); + para.saveEx(); + } else if (para.getParameterName().equals("CoAFile")) { + para.setP_String(Adempiere.getAdempiereHome() + File.separator + + "org.adempiere.server-feature" + File.separator + + "data" + File.separator + "import" + + File.separator + "AccountingDefaultsOnly.csv"); + para.saveEx(); + } else if (para.getParameterName().equals("AdminUserEmail")) { + para.setP_String("admin@junit-test-idempiere.org"); + para.saveEx(); + } else if (para.getParameterName().equals("NormalUserEmail")) { + para.setP_String("user@junit-test-idempiere.org"); + para.saveEx(); + } + } + + ProcessInfo pi = new ProcessInfo(process.getName(), AD_Process_ID); + pi.setAD_PInstance_ID(pinstance.getAD_PInstance_ID()); + process.processIt(pi, Trx.get(getTrxName(), false), false); + + assertTrue(!pi.isError(), pi.getSummary()); + + rollback(); + } +} diff --git a/org.idempiere.test/src/org/idempiere/test/model/BankStatementTest.java b/org.idempiere.test/src/org/idempiere/test/model/BankStatementTest.java new file mode 100644 index 0000000000..d7af6502bd --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/model/BankStatementTest.java @@ -0,0 +1,81 @@ +/*********************************************************************** + * 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: * + * - hengsin * + **********************************************************************/ +package org.idempiere.test.model; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import java.math.BigDecimal; +import java.sql.Timestamp; + +import org.compiere.model.MBankStatement; +import org.compiere.model.MBankStatementLine; +import org.compiere.process.DocAction; +import org.compiere.process.ProcessInfo; +import org.compiere.util.Env; +import org.compiere.util.TimeUtil; +import org.compiere.wf.MWorkflow; +import org.idempiere.test.AbstractTestCase; +import org.junit.jupiter.api.Test; + +/** + * @author hengsin + * + */ +public class BankStatementTest extends AbstractTestCase { + + /** + * + */ + public BankStatementTest() { + } + + @Test + public void testCompleteStatement() { + MBankStatement stmt = new MBankStatement(Env.getCtx(), 0, getTrxName()); + stmt.setC_BankAccount_ID(100); + Timestamp today = TimeUtil.getDay(System.currentTimeMillis()); + stmt.setStatementDate(today); + stmt.setDateAcct(today); + stmt.setName(System.currentTimeMillis()+""); + stmt.setDocAction(DocAction.ACTION_Complete); + stmt.setDocStatus(DocAction.STATUS_Drafted); + stmt.saveEx(); + + MBankStatementLine line = new MBankStatementLine(stmt); + line.setValutaDate(today); + line.setStatementLineDate(today); + line.setStmtAmt(new BigDecimal("10.00")); + line.setTrxAmt(new BigDecimal("10.00")); + line.setC_Currency_ID(100); + line.saveEx(); + + ProcessInfo pi = MWorkflow.runDocumentActionWorkflow(stmt, DocAction.ACTION_Complete); + assertFalse(pi.isError()); + + stmt.load(getTrxName()); + assertEquals(DocAction.STATUS_Completed, stmt.getDocStatus()); + } +} diff --git a/org.idempiere.test/src/org/idempiere/test/model/RequisitionTest.java b/org.idempiere.test/src/org/idempiere/test/model/RequisitionTest.java new file mode 100644 index 0000000000..3cd1d36429 --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/model/RequisitionTest.java @@ -0,0 +1,88 @@ +/*********************************************************************** + * 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: * + * - hengsin * + **********************************************************************/ +package org.idempiere.test.model; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import java.math.BigDecimal; +import java.sql.Timestamp; + +import org.compiere.model.MRequisition; +import org.compiere.model.MRequisitionLine; +import org.compiere.process.DocAction; +import org.compiere.process.ProcessInfo; +import org.compiere.util.Env; +import org.compiere.util.TimeUtil; +import org.compiere.wf.MWorkflow; +import org.idempiere.test.AbstractTestCase; +import org.junit.jupiter.api.Test; + +/** + * @author hengsin + * + */ +public class RequisitionTest extends AbstractTestCase { + + /** + * + */ + public RequisitionTest() { + } + + @Test + public void testComplete() { + int purchaseRequisition = 127; + int standardPriceList = 101; + Timestamp today = TimeUtil.getDay(System.currentTimeMillis()); + MRequisition requisition = new MRequisition(Env.getCtx(), 0, getTrxName()); + requisition.setC_DocType_ID(purchaseRequisition); + requisition.setDateDoc(today); + requisition.setDateRequired(today); + requisition.setDocAction(DocAction.ACTION_Complete); + requisition.setDocStatus(DocAction.STATUS_Drafted); + requisition.setM_Warehouse_ID(getM_Warehouse_ID()); + requisition.setAD_User_ID(getAD_User_ID()); + requisition.setAD_Org_ID(getAD_Org_ID()); + requisition.setM_PriceList_ID(standardPriceList); + requisition.setPriorityRule(MRequisition.PRIORITYRULE_Medium); + requisition.saveEx(); + + int seeder = 143; + int each = 100; + MRequisitionLine line = new MRequisitionLine(requisition); + line.setM_Product_ID(seeder); + line.setC_UOM_ID(each); + line.setQty(new BigDecimal("1")); + line.setPrice(); + line.saveEx(); + + ProcessInfo pi = MWorkflow.runDocumentActionWorkflow(requisition, DocAction.ACTION_Complete); + assertFalse(pi.isError(), pi.getSummary()); + + requisition.load(getTrxName()); + assertEquals(DocAction.STATUS_Completed, requisition.getDocStatus()); + } +} diff --git a/org.idempiere.test/src/org/idempiere/test/model/SalesOrderTest.java b/org.idempiere.test/src/org/idempiere/test/model/SalesOrderTest.java index 4edd36c382..7d2094199f 100644 --- a/org.idempiere.test/src/org/idempiere/test/model/SalesOrderTest.java +++ b/org.idempiere.test/src/org/idempiere/test/model/SalesOrderTest.java @@ -34,6 +34,7 @@ import java.sql.Timestamp; import org.compiere.model.MBPartner; import org.compiere.model.MInOut; import org.compiere.model.MInOutLine; +import org.compiere.model.MInvoice; import org.compiere.model.MOrder; import org.compiere.model.MOrderLine; import org.compiere.model.MProduct; @@ -278,4 +279,43 @@ public class SalesOrderTest extends AbstractTestCase { line1.load(getTrxName()); assertEquals(0, line1.getQtyReserved().intValue()); } + + @Test + public void testPOSOrder() { + MOrder order = new MOrder(Env.getCtx(), 0, getTrxName()); + //Joe Block + order.setBPartner(MBPartner.get(Env.getCtx(), 118)); + order.setC_DocTypeTarget_ID(MOrder.DocSubTypeSO_POS); + order.setDeliveryRule(MOrder.DELIVERYRULE_CompleteOrder); + order.setDocStatus(DocAction.STATUS_Drafted); + order.setDocAction(DocAction.ACTION_Complete); + Timestamp today = TimeUtil.getDay(System.currentTimeMillis()); + order.setDatePromised(today); + order.saveEx(); + + MOrderLine line1 = new MOrderLine(order); + line1.setLine(10); + //Azalea Bush + line1.setProduct(MProduct.get(Env.getCtx(), 128)); + line1.setQty(new BigDecimal("1")); + line1.setDatePromised(today); + line1.saveEx(); + + ProcessInfo info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_Complete); + assertFalse(info.isError(), info.getSummary()); + order.load(getTrxName()); + assertEquals(DocAction.STATUS_Completed, order.getDocStatus()); + line1.load(getTrxName()); + assertEquals(0, line1.getQtyReserved().intValue()); + assertEquals(1, line1.getQtyDelivered().intValue()); + assertEquals(1, line1.getQtyInvoiced().intValue()); + + MInOut[] shipments = order.getShipments(); + assertEquals(1, shipments.length); + assertEquals(DocAction.STATUS_Completed, shipments[0].getDocStatus()); + + MInvoice[] invoices = order.getInvoices(); + assertEquals(1, invoices.length); + assertEquals(DocAction.STATUS_Completed, invoices[0].getDocStatus()); + } } diff --git a/org.idempiere.test/src/org/idempiere/test/performance/CacheTest.java b/org.idempiere.test/src/org/idempiere/test/performance/CacheTest.java index 5e1d340ccc..aa4244c84b 100644 --- a/org.idempiere.test/src/org/idempiere/test/performance/CacheTest.java +++ b/org.idempiere.test/src/org/idempiere/test/performance/CacheTest.java @@ -75,15 +75,58 @@ public class CacheTest extends AbstractTestCase { */ public void testTableCache() { MTable table = MTable.get(Env.getCtx(), MOrder.Table_ID); + + //find table cache instance + @SuppressWarnings("rawtypes") + CCache tblCache = null; + CacheInterface[] cis = CacheMgt.get().getInstancesAsArray(); + for(CacheInterface ci : cis) { + if (ci instanceof CCache) { + @SuppressWarnings("rawtypes") + CCache ccache = (CCache) ci; + if (ccache.getName().equals(ccache.getTableName()) && ccache.getTableName().equals(MTable.Table_Name)) { + if (ccache.containsKey(MOrder.Table_ID)) { + tblCache = ccache; + break; + } + } + } + } + + if (tblCache == null) + fail("Table cache instance missing"); + + long hit = tblCache.getHit(); + MColumn column = table.getColumn(MOrder.COLUMNNAME_C_Order_ID); + @SuppressWarnings("unused") I_AD_Table table2 = column.getAD_Table(); - assertTrue(table == table2); + assertEquals(hit+1, tblCache.getHit()); //M_Warehouse of Client - table = MTable.get(Env.getCtx(), MWarehouse.Table_ID); + table = MTable.get(Env.getCtx(), MWarehouse.Table_ID); MRefTable refTable = MRefTable.get(Env.getCtx(), 197); + + tblCache = null; + for(CacheInterface ci : cis) { + if (ci instanceof CCache) { + @SuppressWarnings("rawtypes") + CCache ccache = (CCache) ci; + if (ccache.getName().equals(ccache.getTableName()) && ccache.getTableName().equals(MTable.Table_Name)) { + if (ccache.containsKey(MWarehouse.Table_ID)) { + tblCache = ccache; + break; + } + } + } + } + + if (tblCache == null) + fail("Table cache instance missing"); + + hit = tblCache.getHit(); table2 = refTable.getAD_Table(); - assertTrue(table == table2); + assertEquals(hit+1, tblCache.getHit()); } @SuppressWarnings({"unchecked", "rawtypes"}) @@ -129,7 +172,7 @@ public class CacheTest extends AbstractTestCase { assertEquals(oak, p2.getM_Product_ID()); assertTrue(pc.getHit() > hit, "Second get of product Oak, cache hit should increase"); - p2.set_TrxName(getTrxName()); + p2 = new MProduct(Env.getCtx(), p2, getTrxName()); p2.setDescription("Test Update @ " + System.currentTimeMillis()); p2.saveEx(); @@ -165,7 +208,7 @@ public class CacheTest extends AbstractTestCase { //test update when cache is empty CacheMgt.get().reset(); - p2.set_TrxName(getTrxName()); + p2 = new MProduct(Env.getCtx(), p2, getTrxName()); p2.setDescription("Test1@"+System.currentTimeMillis()); p2.saveEx(); diff --git a/org.idempiere.webservices/WEB-INF/src/org/compiere/model/MWebService.java b/org.idempiere.webservices/WEB-INF/src/org/compiere/model/MWebService.java index c82486b8a5..d526b93a30 100644 --- a/org.idempiere.webservices/WEB-INF/src/org/compiere/model/MWebService.java +++ b/org.idempiere.webservices/WEB-INF/src/org/compiere/model/MWebService.java @@ -32,28 +32,40 @@ package org.compiere.model; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; -import java.util.Iterator; +import java.util.Arrays; import java.util.Properties; import java.util.logging.Level; -import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; /** * Web Services Model * * @author Carlos Ruiz */ -public class MWebService extends X_WS_WebService +public class MWebService extends X_WS_WebService implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 3561409141850981248L; + private static final long serialVersionUID = 297628235579089311L; /** - * Get MWebService from Cache + * Get MWebService from Cache (immutable) + * @param WS_WebService_ID id + * @return MWebService + */ + public static MWebService get (int WS_WebService_ID) + { + return get(Env.getCtx(), WS_WebService_ID); + } + + /** + * Get MWebService from Cache (immutable) * @param ctx context * @param WS_WebService_ID id * @return MWebService @@ -61,13 +73,16 @@ public class MWebService extends X_WS_WebService public static MWebService get (Properties ctx, int WS_WebService_ID) { Integer key = Integer.valueOf(WS_WebService_ID); - MWebService retValue = (MWebService) s_cache.get (key); + MWebService retValue = s_cache.get (ctx, key, e -> new MWebService(ctx, e)); if (retValue != null) return retValue; - retValue = new MWebService (ctx, WS_WebService_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; + retValue = new MWebService (ctx, WS_WebService_ID, (String)null); + if (retValue.get_ID () == WS_WebService_ID) + { + s_cache.put (key, retValue, e -> new MWebService(Env.getCtx(), e)); + return retValue; + } + return null; } // get /** @@ -76,14 +91,13 @@ public class MWebService extends X_WS_WebService * @param webServiceValue * @return Table */ - public static synchronized MWebService get (Properties ctx, String webServiceValue) + public static MWebService get (Properties ctx, String webServiceValue) { if (webServiceValue == null) return null; - Iterator it = s_cache.values().iterator(); - while (it.hasNext()) + MWebService[] it = s_cache.values().toArray(new MWebService[0]); + for (MWebService retValue : it) { - MWebService retValue = it.next(); if (webServiceValue.equals(retValue.getValue())) return retValue; } @@ -119,19 +133,19 @@ public class MWebService extends X_WS_WebService } // get /** Methods */ - private X_WS_WebServiceMethod[] m_methods = null; + private MWebServiceMethod[] m_methods = null; /** * Get Methods * @param requery requery * @return array of methods */ - public X_WS_WebServiceMethod[] getMethods (boolean requery) + public MWebServiceMethod[] getMethods (boolean requery) { if (m_methods != null && !requery) return m_methods; String sql = "SELECT * FROM WS_WebServiceMethod WHERE WS_WebService_ID=? AND IsActive='Y' ORDER BY Value"; - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList(); PreparedStatement pstmt = null; ResultSet rs = null; try @@ -140,7 +154,7 @@ public class MWebService extends X_WS_WebService pstmt.setInt (1, getWS_WebService_ID()); rs = pstmt.executeQuery (); while (rs.next ()) - list.add (new X_WS_WebServiceMethod (getCtx(), rs, get_TrxName())); + list.add (new MWebServiceMethod (getCtx(), rs, get_TrxName())); } catch (Exception e) { @@ -153,7 +167,9 @@ public class MWebService extends X_WS_WebService pstmt = null; } // - m_methods = new X_WS_WebServiceMethod[list.size ()]; + if (list.size() > 0 && is_Immutable()) + list.stream().forEach(e -> e.markImmutable()); + m_methods = new MWebServiceMethod[list.size ()]; list.toArray (m_methods); return m_methods; } // getMethods @@ -178,7 +194,7 @@ public class MWebService extends X_WS_WebService } // getMethod /** Cache */ - private static CCache s_cache = new CCache(Table_Name, 20); + private static ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 20); /** Static Logger */ private static final CLogger s_log = CLogger.getCLogger (MWebService.class); @@ -211,4 +227,48 @@ public class MWebService extends X_WS_WebService super(ctx, rs, trxName); } // MWebService + /** + * + * @param copy + */ + public MWebService(MWebService copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MWebService(Properties ctx, MWebService copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MWebService(Properties ctx, MWebService copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_methods = copy.m_methods != null ? Arrays.stream(copy.m_methods).map(e -> {return new MWebServiceMethod(ctx, e, trxName);}).toArray(MWebServiceMethod[]::new) : null; + } + + @Override + public MWebService markImmutable() + { + if (is_Immutable()) + return this; + + makeImmutable(); + if (m_methods != null && m_methods.length > 0) + Arrays.stream(m_methods).forEach(e -> e.markImmutable()); + return this; + } + } // MWebService diff --git a/org.idempiere.webservices/WEB-INF/src/org/compiere/model/MWebServiceMethod.java b/org.idempiere.webservices/WEB-INF/src/org/compiere/model/MWebServiceMethod.java new file mode 100644 index 0000000000..c192436b16 --- /dev/null +++ b/org.idempiere.webservices/WEB-INF/src/org/compiere/model/MWebServiceMethod.java @@ -0,0 +1,100 @@ +/********************************************************************** +* 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: * +* - Trek Global Corporation * +* - Heng Sin Low * +**********************************************************************/ +package org.compiere.model; + +import java.sql.ResultSet; +import java.util.Properties; + +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; + +/** + * @author hengsin + * + */ +public class MWebServiceMethod extends X_WS_WebServiceMethod implements ImmutablePOSupport { + + /** + * + */ + private static final long serialVersionUID = 6822623209157500849L; + + /** + * @param ctx + * @param WS_WebServiceMethod_ID + * @param trxName + */ + public MWebServiceMethod(Properties ctx, int WS_WebServiceMethod_ID, String trxName) { + super(ctx, WS_WebServiceMethod_ID, trxName); + } + + /** + * @param ctx + * @param rs + * @param trxName + */ + public MWebServiceMethod(Properties ctx, ResultSet rs, String trxName) { + super(ctx, rs, trxName); + } + + /** + * + * @param copy + */ + public MWebServiceMethod(MWebServiceMethod copy) { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MWebServiceMethod(Properties ctx, MWebServiceMethod copy) { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MWebServiceMethod(Properties ctx, MWebServiceMethod copy, String trxName) { + this(ctx, 0, trxName); + copyPO(copy); + } + + @Override + public MWebServiceMethod markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + +} diff --git a/org.idempiere.webservices/WEB-INF/src/org/compiere/model/MWebServicePara.java b/org.idempiere.webservices/WEB-INF/src/org/compiere/model/MWebServicePara.java index e462453d66..3fae211add 100644 --- a/org.idempiere.webservices/WEB-INF/src/org/compiere/model/MWebServicePara.java +++ b/org.idempiere.webservices/WEB-INF/src/org/compiere/model/MWebServicePara.java @@ -32,6 +32,8 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; +import org.compiere.util.Env; + /** * Web Services Parameters Model * @@ -72,6 +74,37 @@ public class MWebServicePara extends X_WS_WebService_Para super(ctx, rs, trxName); } // MWebServicePara + /** + * + * @param copy + */ + public MWebServicePara(MWebServicePara copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MWebServicePara(Properties ctx, MWebServicePara copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MWebServicePara(Properties ctx, MWebServicePara copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + @Override protected boolean beforeSave(boolean newRecord) { if ( "Filter".equalsIgnoreCase(getParameterName()) diff --git a/org.idempiere.webservices/WEB-INF/src/org/compiere/model/MWebServiceType.java b/org.idempiere.webservices/WEB-INF/src/org/compiere/model/MWebServiceType.java index b105afcf9b..0d48502019 100644 --- a/org.idempiere.webservices/WEB-INF/src/org/compiere/model/MWebServiceType.java +++ b/org.idempiere.webservices/WEB-INF/src/org/compiere/model/MWebServiceType.java @@ -31,6 +31,7 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -38,6 +39,8 @@ import java.util.Properties; import org.compiere.util.CLogger; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutablePOSupport; /** * Web Services Type Model @@ -45,12 +48,12 @@ import org.compiere.util.DB; * @author Carlos Ruiz * @author Deepak Pansheriya - Updated to support CreateUpdate service */ -public class MWebServiceType extends X_WS_WebServiceType +public class MWebServiceType extends X_WS_WebServiceType implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = -2713868996404459577L; + private static final long serialVersionUID = -6105547694847198509L; /** Parameters */ private MWebServicePara[] m_para = null; @@ -240,6 +243,42 @@ public class MWebServiceType extends X_WS_WebServiceType super(ctx, rs, trxName); } // MWebServiceType + /** + * + * @param copy + */ + public MWebServiceType(MWebServiceType copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MWebServiceType(Properties ctx, MWebServiceType copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MWebServiceType(Properties ctx, MWebServiceType copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + this.m_para = copy.m_para != null ? Arrays.stream(copy.m_para).map(e -> {return new MWebServicePara(ctx, e, trxName);}).toArray(MWebServicePara[]::new) : null; + this.m_inputcolumnnames = copy.m_inputcolumnnames != null ? Arrays.copyOf(copy.m_inputcolumnnames, copy.m_inputcolumnnames.length) : null; + this.m_outputcolumnnames = copy.m_outputcolumnnames != null ? Arrays.copyOf(copy.m_outputcolumnnames, copy.m_outputcolumnnames.length) : null; + this.m_inputFieldMap = copy.m_inputFieldMap != null ? new HashMap(copy.m_inputFieldMap) : null; + this.m_keyColumns = copy.m_keyColumns != null ? new ArrayList(copy.m_keyColumns) : null; + } + /** * * @param requery @@ -332,4 +371,14 @@ public class MWebServiceType extends X_WS_WebServiceType wsp.saveEx(); } } + + @Override + public MWebServiceType markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } // MWebServiceType diff --git a/org.idempiere.webservices/WEB-INF/src/org/compiere/model/WS_ModelFactory.java b/org.idempiere.webservices/WEB-INF/src/org/compiere/model/WS_ModelFactory.java index f4ff96a091..a9557a7859 100644 --- a/org.idempiere.webservices/WEB-INF/src/org/compiere/model/WS_ModelFactory.java +++ b/org.idempiere.webservices/WEB-INF/src/org/compiere/model/WS_ModelFactory.java @@ -40,6 +40,8 @@ public class WS_ModelFactory implements IModelFactory { return MWebServiceType.class; if (X_WS_WebService.Table_Name.equals(tableName)) return MWebService.class; + if (MWebServiceMethod.Table_Name.equals(tableName)) + return MWebServiceMethod.class; return null; } @@ -51,6 +53,8 @@ public class WS_ModelFactory implements IModelFactory { return new MWebServiceType(Env.getCtx(), Record_ID, trxName); if (X_WS_WebService.Table_Name.equals(tableName)) return new MWebService(Env.getCtx(), Record_ID, trxName); + if (MWebServiceMethod.Table_Name.equals(tableName)) + return new MWebServiceMethod(Env.getCtx(), Record_ID, trxName); return null; } @@ -62,6 +66,8 @@ public class WS_ModelFactory implements IModelFactory { return new MWebServiceType(Env.getCtx(), rs, trxName); if (X_WS_WebService.Table_Name.equals(tableName)) return new MWebService(Env.getCtx(), rs, trxName); + if (MWebServiceMethod.Table_Name.equals(tableName)) + return new MWebServiceMethod(Env.getCtx(), rs, trxName); return null; } diff --git a/org.idempiere.webservices/WEB-INF/src/org/idempiere/webservices/AbstractService.java b/org.idempiere.webservices/WEB-INF/src/org/idempiere/webservices/AbstractService.java index 14ce7e1ab7..6248b2f6c4 100644 --- a/org.idempiere.webservices/WEB-INF/src/org/idempiere/webservices/AbstractService.java +++ b/org.idempiere.webservices/WEB-INF/src/org/idempiere/webservices/AbstractService.java @@ -55,6 +55,7 @@ import org.idempiere.adInterface.x10.OutputFields; import org.idempiere.adInterface.x10.StandardResponse; import org.idempiere.adInterface.x10.StandardResponseDocument; import org.idempiere.adinterface.CompiereService; +import org.idempiere.cache.ImmutablePOCache; import org.idempiere.webservices.fault.IdempiereServiceFault; @@ -207,7 +208,7 @@ public class AbstractService { return authenticate(webService, method, serviceType, m_cs); } - private static CCache s_WebServiceTypeCache = new CCache(MWebServiceType.Table_Name, 10, 60); //60 minutes + private static ImmutablePOCache s_WebServiceTypeCache = new ImmutablePOCache(MWebServiceType.Table_Name, 10, 60); //60 minutes private static CCache s_RoleAccessCache = new CCache<>(X_WS_WebServiceTypeAccess.Table_Name, 60, 60); /** @@ -232,7 +233,7 @@ public class AbstractService { String key = m_cs.getAD_Client_ID() + "|" + m_webservice.getWS_WebService_ID() + "|" + m_webservicemethod.getWS_WebServiceMethod_ID() + "|" + serviceTypeValue; synchronized (s_WebServiceTypeCache) { - m_webservicetype = s_WebServiceTypeCache.get(key); + m_webservicetype = s_WebServiceTypeCache.get(m_cs.getCtx(), key, e -> new MWebServiceType(m_cs.getCtx(), e)); if (m_webservicetype == null) { m_webservicetype = new Query(m_cs.getCtx(), MWebServiceType.Table_Name, "AD_Client_ID IN (0,?) AND WS_WebService_ID=? AND WS_WebServiceMethod_ID=? AND Value=?", @@ -242,7 +243,7 @@ public class AbstractService { .setOrderBy("AD_Client_ID DESC") // IDEMPIERE-3394 give precedence to tenant defined if there are system+tenant .first(); if (m_webservicetype != null) { - s_WebServiceTypeCache.put(key, m_webservicetype); + s_WebServiceTypeCache.put(key, m_webservicetype, e -> new MWebServiceType(Env.getCtx(), e)); } } }