From a674a185a32529b60cd1b09448a147ab1f903ae8 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Tue, 4 Aug 2015 15:52:19 -0500 Subject: [PATCH 1/6] IDEMPIERE-2064 Implement toolbar+tab button / implement backward compatibility with 2packs generated before IDEMPIERE-2477 --- .../src/org/adempiere/pipo2/PoFiller.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/org.adempiere.pipo/src/org/adempiere/pipo2/PoFiller.java b/org.adempiere.pipo/src/org/adempiere/pipo2/PoFiller.java index 60fcb6ff04..5254ddd427 100644 --- a/org.adempiere.pipo/src/org/adempiere/pipo2/PoFiller.java +++ b/org.adempiere.pipo/src/org/adempiere/pipo2/PoFiller.java @@ -57,8 +57,16 @@ public class PoFiller{ return; else if (oldValue != null && oldValue.toString().equals(value)) return; - else + else { + if (po instanceof MColumn && "IsToolbarButton".equals(columnName)) { + // IDEMPIERE-2064 - backward compatibility with 2packs generated before IDEMPIERE-2477 + if ("true".equals(value)) + value ="Y"; + else if ("false".equals(value)) + value ="N"; + } po.set_ValueNoCheck(columnName, value); + } } /** From 2694d54b7180c8f04af090c8f13c0124b6b0375d Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Wed, 5 Aug 2015 07:11:13 -0500 Subject: [PATCH 2/6] IDEMPIERE-2752 Same Attribute Instance on many Products --- .../src/org/compiere/model/MProduct.java | 30 +++++++++++++------ .../webui/window/WPAttributeDialog.java | 4 +-- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/org.adempiere.base/src/org/compiere/model/MProduct.java b/org.adempiere.base/src/org/compiere/model/MProduct.java index d6c9ef5fb9..fcd11091af 100644 --- a/org.adempiere.base/src/org/compiere/model/MProduct.java +++ b/org.adempiere.base/src/org/compiere/model/MProduct.java @@ -598,17 +598,29 @@ public class MProduct extends X_M_Product m_precision = null; // AttributeSetInstance reset - if (is_ValueChanged(COLUMNNAME_M_AttributeSet_ID)) + if (getM_AttributeSetInstance_ID() > 0 && is_ValueChanged(COLUMNNAME_M_AttributeSet_ID)) { MAttributeSetInstance asi = new MAttributeSetInstance(getCtx(), getM_AttributeSetInstance_ID(), get_TrxName()); - setM_AttributeSetInstance_ID(0); - // Delete the old m_attributesetinstance - try { - asi.deleteEx(true, get_TrxName()); - } catch (AdempiereException ex) - { - log.saveError("Error", "Error deleting the AttributeSetInstance"); - return false; + if (asi.getM_AttributeSet_ID() != getM_AttributeSet_ID()) + setM_AttributeSetInstance_ID(0); + } + if (!newRecord && is_ValueChanged(COLUMNNAME_M_AttributeSetInstance_ID)) + { + // IDEMPIERE-2752 check if the ASI is referenced in other products before trying to delete it + int oldasiid = get_ValueOldAsInt(COLUMNNAME_M_AttributeSetInstance_ID); + if (oldasiid > 0) { + MAttributeSetInstance oldasi = new MAttributeSetInstance(getCtx(), get_ValueOldAsInt(COLUMNNAME_M_AttributeSetInstance_ID), get_TrxName()); + int cnt = DB.getSQLValueEx(get_TrxName(), "SELECT COUNT(*) FROM M_Product WHERE M_AttributeSetInstance_ID=?", oldasi.getM_AttributeSetInstance_ID()); + if (cnt == 1) { + // Delete the old m_attributesetinstance + try { + oldasi.deleteEx(true, get_TrxName()); + } catch (AdempiereException ex) + { + log.saveError("Error", "Error deleting the AttributeSetInstance"); + return false; + } + } } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPAttributeDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPAttributeDialog.java index 0527c39010..ef021501ae 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPAttributeDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPAttributeDialog.java @@ -253,7 +253,8 @@ public class WPAttributeDialog extends Window implements EventListener MAttributeSet as = null; - if (m_M_Product_ID != 0) + int M_AttributeSet_ID = Env.getContextAsInt(Env.getCtx(), m_WindowNoParent, "M_AttributeSet_ID"); + if (m_M_Product_ID != 0 && M_AttributeSet_ID == 0) { // Get Model m_masi = MAttributeSetInstance.get(Env.getCtx(), m_M_AttributeSetInstance_ID, m_M_Product_ID); @@ -269,7 +270,6 @@ public class WPAttributeDialog extends Window implements EventListener } else { - int M_AttributeSet_ID = Env.getContextAsInt(Env.getCtx(), m_WindowNoParent, "M_AttributeSet_ID"); m_masi = new MAttributeSetInstance (Env.getCtx(), m_M_AttributeSetInstance_ID, M_AttributeSet_ID, null); as = m_masi.getMAttributeSet(); } From bdb7675ed16a00b65e9b8a7aa494c1685081999d Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Wed, 5 Aug 2015 09:19:31 -0500 Subject: [PATCH 3/6] IDEMPIERE-2747 Env.parseVariable doesn't work with CreatedBy/UpdatedBy --- org.adempiere.base/src/org/compiere/util/Env.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.adempiere.base/src/org/compiere/util/Env.java b/org.adempiere.base/src/org/compiere/util/Env.java index dcc4c73031..5d61f14c86 100644 --- a/org.adempiere.base/src/org/compiere/util/Env.java +++ b/org.adempiere.base/src/org/compiere/util/Env.java @@ -1582,7 +1582,7 @@ public final class Env String foreignTable = colToken.getReferenceTableName(); if (v != null) { if (format != null && format.length() > 0) { - if (v instanceof Integer && (Integer) v > 0 && token.endsWith("_ID")) { + if (v instanceof Integer && (Integer) v > 0 && !Util.isEmpty(foreignTable)) { int tblIndex = format.indexOf("."); String tableName = null; if (tblIndex > 0) From 45ce71ef4807035a3b7ca5b3f20f471b84200e56 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Thu, 6 Aug 2015 17:30:03 -0500 Subject: [PATCH 4/6] IDEMPIERE-2757 Key for M_Storage wrongly defined on dictionary --- migration/i2.1/oracle/201508061729_IDEMPIERE-2757.sql | 11 +++++++++++ .../i2.1/postgresql/201508061729_IDEMPIERE-2757.sql | 8 ++++++++ 2 files changed, 19 insertions(+) create mode 100644 migration/i2.1/oracle/201508061729_IDEMPIERE-2757.sql create mode 100644 migration/i2.1/postgresql/201508061729_IDEMPIERE-2757.sql diff --git a/migration/i2.1/oracle/201508061729_IDEMPIERE-2757.sql b/migration/i2.1/oracle/201508061729_IDEMPIERE-2757.sql new file mode 100644 index 0000000000..5322ede126 --- /dev/null +++ b/migration/i2.1/oracle/201508061729_IDEMPIERE-2757.sql @@ -0,0 +1,11 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- IDEMPIERE-2757 Key for M_Storage wrongly defined on dictionary +-- Aug 6, 2015 5:28:43 PM COT +UPDATE AD_Column SET IsParent='Y', IsUpdateable='N',Updated=TO_DATE('2015-08-06 17:28:43','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=210887 +; + +SELECT register_migration_script('201508061729_IDEMPIERE-2757.sql') FROM dual +; + diff --git a/migration/i2.1/postgresql/201508061729_IDEMPIERE-2757.sql b/migration/i2.1/postgresql/201508061729_IDEMPIERE-2757.sql new file mode 100644 index 0000000000..8c2d659cd1 --- /dev/null +++ b/migration/i2.1/postgresql/201508061729_IDEMPIERE-2757.sql @@ -0,0 +1,8 @@ +-- IDEMPIERE-2757 Key for M_Storage wrongly defined on dictionary +-- Aug 6, 2015 5:28:43 PM COT +UPDATE AD_Column SET IsParent='Y', IsUpdateable='N',Updated=TO_TIMESTAMP('2015-08-06 17:28:43','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=210887 +; + +SELECT register_migration_script('201508061729_IDEMPIERE-2757.sql') FROM dual +; + From d726d9c75a4bb178c9f7e1cba63a0fa406ca1eca Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Fri, 7 Aug 2015 10:03:18 -0500 Subject: [PATCH 5/6] IDEMPIERE-2756 Background threads losing context when user log out --- org.adempiere.base/src/org/compiere/model/PO.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/org.adempiere.base/src/org/compiere/model/PO.java b/org.adempiere.base/src/org/compiere/model/PO.java index 83bb9c1e3d..430dd1fd48 100644 --- a/org.adempiere.base/src/org/compiere/model/PO.java +++ b/org.adempiere.base/src/org/compiere/model/PO.java @@ -1989,6 +1989,7 @@ public abstract class PO */ public boolean save() { + checkValidContext(); CLogger.resetLast(); boolean newRecord = is_new(); // save locally as load resets if (!newRecord && !is_Changed()) @@ -3107,6 +3108,7 @@ public abstract class PO */ public boolean delete (boolean force) { + checkValidContext(); CLogger.resetLast(); if (is_new()) return true; @@ -4670,4 +4672,10 @@ public abstract class PO log.saveError(msg, info); } } + + private void checkValidContext() { + if (getCtx().size() == 0) + throw new AdempiereException("Context lost"); + } + } // PO From ad6290e09c637305d3f360786d5bc84633e92916 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Fri, 7 Aug 2015 10:03:50 -0500 Subject: [PATCH 6/6] IDEMPIERE-2756 Background threads losing context when user log out / integrate fix from hengsin for the server services --- .../org/compiere/server/AdempiereServer.java | 337 ++++++++++-------- .../server/org/compiere/server/Scheduler.java | 34 +- 2 files changed, 200 insertions(+), 171 deletions(-) diff --git a/org.adempiere.server/src/main/server/org/compiere/server/AdempiereServer.java b/org.adempiere.server/src/main/server/org/compiere/server/AdempiereServer.java index 4afb642e17..5f0c5e453a 100644 --- a/org.adempiere.server/src/main/server/org/compiere/server/AdempiereServer.java +++ b/org.adempiere.server/src/main/server/org/compiere/server/AdempiereServer.java @@ -1,8 +1,8 @@ -/****************************************************************************** - * Product: Adempiere ERP & CRM Smart Business Solution * - * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify it * - * under the terms version 2 of the GNU General Public License as published * +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. 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. * @@ -16,62 +16,62 @@ *****************************************************************************/ package org.compiere.server; -import java.sql.Timestamp; -import java.util.Properties; -import java.util.logging.Level; - -import org.compiere.model.AdempiereProcessor; -import org.compiere.model.AdempiereProcessor2; -import org.compiere.model.AdempiereProcessorLog; -import org.compiere.model.MClient; -import org.compiere.model.MSchedule; -import org.compiere.model.MSystem; -import org.compiere.util.CLogger; -import org.compiere.util.Env; -import org.compiere.util.TimeUtil; - -/** - * Adempiere Server Base - * - * @author Jorg Janke - * @version $Id: AdempiereServer.java,v 1.3 2006/10/09 00:23:26 jjanke Exp $ - */ -public abstract class AdempiereServer implements Runnable -{ +import java.sql.Timestamp; +import java.util.Properties; +import java.util.logging.Level; + +import org.adempiere.util.ServerContext; +import org.compiere.model.AdempiereProcessor; +import org.compiere.model.AdempiereProcessor2; +import org.compiere.model.AdempiereProcessorLog; +import org.compiere.model.MClient; +import org.compiere.model.MSchedule; +import org.compiere.model.MSystem; +import org.compiere.model.PO; +import org.compiere.util.CLogger; +import org.compiere.util.Env; +import org.compiere.util.TimeUtil; + +/** + * Adempiere Server Base + * + * @author Jorg Janke + * @version $Id: AdempiereServer.java,v 1.3 2006/10/09 00:23:26 jjanke Exp $ + */ +public abstract class AdempiereServer implements Runnable +{ /************************************************************************** * Server Base Class - * @param model model - * @param initialNap delay time running in sec - */ - protected AdempiereServer (AdempiereProcessor model, int initialNap) - { - p_model = model; - m_ctx = new Properties(model.getCtx()); - if (p_system == null) - p_system = MSystem.get(m_ctx); - p_client = MClient.get(m_ctx); - Env.setContext(m_ctx, "#AD_Client_ID", p_client.getAD_Client_ID()); - m_initialNap = initialNap; - - Timestamp dateNextRun = getDateNextRun(true); - if (dateNextRun != null) - m_nextWork = dateNextRun.getTime(); - - long now = System.currentTimeMillis(); - if (m_nextWork > now) - { - m_sleepMS = m_nextWork - now; + * @param model model + * @param initialNap delay time running in sec + */ + protected AdempiereServer (AdempiereProcessor model, int initialNap) + { + p_model = model; + if (p_system == null) + p_system = MSystem.get(model.getCtx()); + p_client = MClient.get(model.getCtx(), model.getAD_Client_ID()); + m_initialNap = initialNap; + + Timestamp dateNextRun = getDateNextRun(true); + if (dateNextRun != null) + m_nextWork = dateNextRun.getTime(); + + long now = System.currentTimeMillis(); + if (m_nextWork > now) + { + m_sleepMS = m_nextWork - now; } - } // ServerBase - - /** The Processor Model */ - protected volatile AdempiereProcessor p_model; - /** Initial nap is seconds */ - private int m_initialNap = 0; - - /** Milliseconds to sleep - 0 Sec default */ - protected long m_sleepMS = 0; + } // ServerBase + + /** The Processor Model */ + protected volatile AdempiereProcessor p_model; + /** Initial nap is seconds */ + private int m_initialNap = 0; + + /** Milliseconds to sleep - 0 Sec default */ + protected long m_sleepMS = 0; /** Sleeping */ private volatile boolean m_sleeping = true; /** Server start time */ @@ -89,8 +89,6 @@ public abstract class AdempiereServer implements Runnable /** Logger */ protected CLogger log = CLogger.getCLogger(getClass()); - /** Context */ - private Properties m_ctx = null; /** System */ protected volatile static MSystem p_system = null; /** Client */ @@ -102,7 +100,7 @@ public abstract class AdempiereServer implements Runnable */ public Properties getCtx() { - return m_ctx; + return Env.getCtx(); } // getCtx /** @@ -112,18 +110,41 @@ public abstract class AdempiereServer implements Runnable { return m_sleepMS; } // getSleepMS - - public long getInitialNap() - { - return m_initialNap; + + public long getInitialNap() + { + return m_initialNap; } + public void runNow() + { + Properties context = new Properties(); + Env.setContext(context, "#AD_Client_ID", p_model.getAD_Client_ID()); + if (p_model instanceof PO) { + PO po = (PO) p_model; + if (po.get_ColumnIndex("AD_Org_ID") >= 0) + Env.setContext(context, "#AD_Org_ID", po.get_ValueAsInt("AD_Org_ID")); + if (po.get_ColumnIndex("AD_User_ID") >= 0) + Env.setContext(context, "#AD_User_ID", po.get_ValueAsInt("AD_User_ID")); + } + + Properties prevContext = ServerContext.getCurrentInstance(); + try { + ServerContext.setCurrentInstance(context); + m_sleeping = false; + doRunNow(); + } finally { + ServerContext.dispose(); + ServerContext.setCurrentInstance(prevContext); + m_sleeping = true; + } + } + /** * Run Now */ - public void runNow() - { - m_sleeping = false; + public void doRunNow() + { p_startWork = System.currentTimeMillis(); doWork(); long now = System.currentTimeMillis(); @@ -135,31 +156,55 @@ public abstract class AdempiereServer implements Runnable // p_model.setDateLastRun(new Timestamp(now)); p_model.saveEx(); - // + // if (log.isLoggable(Level.FINE)) - log.fine(getStatistics()); - m_sleeping = true; + log.fine(getStatistics()); } // runNow + public void run() + { + final Thread currentThread = Thread.currentThread(); + final String oldThreadName = currentThread.getName(); + String newThreadName = getName(); + boolean renamed = false; + if (!oldThreadName.equals(newThreadName)) { + try { + currentThread.setName(newThreadName); + renamed = true; + } catch (SecurityException e) {} + } + + Properties context = new Properties(); + Env.setContext(context, "#AD_Client_ID", p_model.getAD_Client_ID()); + if (p_model instanceof PO) { + PO po = (PO) p_model; + if (po.get_ColumnIndex("AD_Org_ID") >= 0) + Env.setContext(context, "#AD_Org_ID", po.get_ValueAsInt("AD_Org_ID")); + if (po.get_ColumnIndex("AD_User_ID") >= 0) + Env.setContext(context, "#AD_User_ID", po.get_ValueAsInt("AD_User_ID")); + } + + try { + ServerContext.setCurrentInstance(context); + m_sleeping = false; + doRun(); + } finally { + m_sleeping = true; + ServerContext.dispose(); + if (renamed) { + // Revert the name back if the current thread was renamed. + // We do not check the exception here because we know it works. + currentThread.setName(oldThreadName); + } + } + } /************************************************************************** * Run async */ - public void run () - { - final Thread currentThread = Thread.currentThread(); - final String oldThreadName = currentThread.getName(); - String newThreadName = getName(); - boolean renamed = false; - if (!oldThreadName.equals(newThreadName)) { - try { - currentThread.setName(newThreadName); - renamed = true; - } catch (SecurityException e) {} - } - - m_sleeping = false; - if (m_start == 0) - m_start = System.currentTimeMillis(); + protected void doRun() + { + if (m_start == 0) + m_start = System.currentTimeMillis(); // --------------- p_startWork = System.currentTimeMillis(); @@ -169,35 +214,29 @@ public abstract class AdempiereServer implements Runnable p_runCount++; m_runLastMS = now - p_startWork; - m_runTotalMS += m_runLastMS; + m_runTotalMS += m_runLastMS; // Finished work - calculate datetime for next run - Timestamp lastRun = new Timestamp(now); - if (p_model instanceof AdempiereProcessor2) - { - AdempiereProcessor2 ap = (AdempiereProcessor2) p_model; - if (ap.isIgnoreProcessingTime()) - { - lastRun = new Timestamp(p_startWork); - } - } - - m_nextWork = MSchedule.getNextRunMS(lastRun.getTime(), - p_model.getScheduleType(), p_model.getFrequencyType(), - p_model.getFrequency(), p_model.getCronPattern()); - - m_sleepMS = m_nextWork - now; - if (log.isLoggable(Level.INFO)) log.info(" Next run: " + new Timestamp(m_nextWork) + " sleep " + m_sleepMS); + Timestamp lastRun = new Timestamp(now); + if (p_model instanceof AdempiereProcessor2) + { + AdempiereProcessor2 ap = (AdempiereProcessor2) p_model; + if (ap.isIgnoreProcessingTime()) + { + lastRun = new Timestamp(p_startWork); + } + } + + m_nextWork = MSchedule.getNextRunMS(lastRun.getTime(), + p_model.getScheduleType(), p_model.getFrequencyType(), + p_model.getFrequency(), p_model.getCronPattern()); + + m_sleepMS = m_nextWork - now; + if (log.isLoggable(Level.INFO)) log.info(" Next run: " + new Timestamp(m_nextWork) + " sleep " + m_sleepMS); // p_model.setDateLastRun(lastRun); p_model.setDateNextRun(new Timestamp(m_nextWork)); - p_model.saveEx(); - m_sleeping = true; - if (renamed) { - // Revert the name back if the current thread was renamed. - // We do not check the exception here because we know it works. - currentThread.setName(oldThreadName); - } + p_model.saveEx(); } // run /** @@ -261,13 +300,13 @@ public abstract class AdempiereServer implements Runnable } // getDescription /** - * Get Model - * @return Model - */ - public AdempiereProcessor getModel() - { - return p_model; - } // getModel + * Get Model + * @return Model + */ + public AdempiereProcessor getModel() + { + return p_model; + } // getModel /** * Is Sleeping @@ -317,35 +356,35 @@ public abstract class AdempiereServer implements Runnable } // getStartTime /** - * Get Processor Logs - * @return logs - */ - public AdempiereProcessorLog[] getLogs() - { - return p_model.getLogs(); - } // getLogs - - - protected boolean isInterrupted() { - return Thread.currentThread().isInterrupted(); - } - - - public String getName() { - return p_model.getName(); - } - - - public static boolean isOKtoRunOnIP(AdempiereProcessor model) { - if (model instanceof AdempiereProcessor2) { - int AD_Schedule_ID = ((AdempiereProcessor2)model).getAD_Schedule_ID(); - MSchedule schedule = MSchedule.get(Env.getCtx(), AD_Schedule_ID); - if (!schedule.isOKtoRunOnIP()) - { - return false; // done - } - } - return true; - } - -} // AdempiereServer + * Get Processor Logs + * @return logs + */ + public AdempiereProcessorLog[] getLogs() + { + return p_model.getLogs(); + } // getLogs + + + protected boolean isInterrupted() { + return Thread.currentThread().isInterrupted(); + } + + + public String getName() { + return p_model.getName(); + } + + + public static boolean isOKtoRunOnIP(AdempiereProcessor model) { + if (model instanceof AdempiereProcessor2) { + int AD_Schedule_ID = ((AdempiereProcessor2)model).getAD_Schedule_ID(); + MSchedule schedule = MSchedule.get(Env.getCtx(), AD_Schedule_ID); + if (!schedule.isOKtoRunOnIP()) + { + return false; // done + } + } + return true; + } + +} // AdempiereServer 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 38a91b3cc7..539cfec5fc 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 @@ -27,10 +27,8 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.List; -import java.util.Properties; import java.util.logging.Level; -import org.adempiere.util.ServerContext; import org.compiere.model.MAttachment; import org.compiere.model.MClient; import org.compiere.model.MNote; @@ -83,9 +81,6 @@ public class Scheduler extends AdempiereServer /** Transaction */ protected Trx m_trx = null; - // ctx for the report/process - protected Properties m_schedulerctx = new Properties(); - /** * Work */ @@ -95,29 +90,27 @@ public class Scheduler extends AdempiereServer .append(" - "); // Prepare a ctx for the report/process - BF [1966880] - m_schedulerctx.clear(); MClient schedclient = MClient.get(getCtx(), m_model.getAD_Client_ID()); - Env.setContext(m_schedulerctx, "#AD_Client_ID", schedclient.getAD_Client_ID()); - Env.setContext(m_schedulerctx, "#AD_Language", schedclient.getAD_Language()); - Env.setContext(m_schedulerctx, "#AD_Org_ID", m_model.getAD_Org_ID()); + Env.setContext(getCtx(), "#AD_Client_ID", schedclient.getAD_Client_ID()); + Env.setContext(getCtx(), "#AD_Language", schedclient.getAD_Language()); + Env.setContext(getCtx(), "#AD_Org_ID", m_model.getAD_Org_ID()); if (m_model.getAD_Org_ID() != 0) { MOrgInfo schedorg = MOrgInfo.get(getCtx(), m_model.getAD_Org_ID(), null); if (schedorg.getM_Warehouse_ID() > 0) - Env.setContext(m_schedulerctx, "#M_Warehouse_ID", schedorg.getM_Warehouse_ID()); + Env.setContext(getCtx(), "#M_Warehouse_ID", schedorg.getM_Warehouse_ID()); } - Env.setContext(m_schedulerctx, "#AD_User_ID", getAD_User_ID()); - Env.setContext(m_schedulerctx, "#SalesRep_ID", getAD_User_ID()); + Env.setContext(getCtx(), "#AD_User_ID", getAD_User_ID()); + Env.setContext(getCtx(), "#SalesRep_ID", getAD_User_ID()); // TODO: It can be convenient to add AD_Scheduler.AD_Role_ID MUser scheduser = MUser.get(getCtx(), getAD_User_ID()); MRole[] schedroles = scheduser.getRoles(m_model.getAD_Org_ID()); if (schedroles != null && schedroles.length > 0) - Env.setContext(m_schedulerctx, "#AD_Role_ID", schedroles[0].getAD_Role_ID()); // first role, ordered by AD_Role_ID + Env.setContext(getCtx(), "#AD_Role_ID", schedroles[0].getAD_Role_ID()); // first role, ordered by AD_Role_ID Timestamp ts = new Timestamp(System.currentTimeMillis()); SimpleDateFormat dateFormat4Timestamp = new SimpleDateFormat("yyyy-MM-dd"); - Env.setContext(m_schedulerctx, "#Date", dateFormat4Timestamp.format(ts)+" 00:00:00" ); // JDBC format - ServerContext.setCurrentInstance(m_schedulerctx); + Env.setContext(getCtx(), "#Date", dateFormat4Timestamp.format(ts)+" 00:00:00" ); // JDBC format - MProcess process = new MProcess(m_schedulerctx, m_model.getAD_Process_ID(), null); + MProcess process = new MProcess(getCtx(), m_model.getAD_Process_ID(), null); try { m_trx = Trx.get(Trx.createTrxName("Scheduler"), true); @@ -137,9 +130,6 @@ public class Scheduler extends AdempiereServer m_trx.close(); } - // clear thread local context - ServerContext.dispose(); - // int no = m_model.deleteLog(); m_summary.append(" Logs deleted=").append(no); @@ -161,7 +151,7 @@ public class Scheduler extends AdempiereServer if (log.isLoggable(Level.INFO)) log.info(process.toString()); boolean isReport = (process.isReport() || process.getAD_ReportView_ID() > 0 || process.getJasperReport() != null || process.getAD_PrintFormat_ID() > 0); - String schedulerName = Env.parseContext(m_schedulerctx, -1, m_model.getName(), false, true); + String schedulerName = Env.parseContext(getCtx(), -1, m_model.getName(), false, true); // Process (see also MWFActivity.performWork int AD_Table_ID = m_model.getAD_Table_ID(); @@ -449,7 +439,7 @@ public class Scheduler extends AdempiereServer String sql = variable.substring(5); // w/o tag //sql = Env.parseContext(m_vo.ctx, m_vo.WindowNo, sql, false, true); // replace variables //hengsin, capture unparseable error to avoid subsequent sql exception - sql = Env.parseContext(m_schedulerctx, 0, sql, false, false); // replace variables + sql = Env.parseContext(getCtx(), 0, sql, false, false); // replace variables if (sql.equals("")) log.log(Level.WARNING, "(" + sPara.getColumnName() + ") - Default SQL variable parse failed: " + variable); else { @@ -493,7 +483,7 @@ public class Scheduler extends AdempiereServer String tail=index < (columnName.length()-1) ? columnName.substring(index+1) : null; columnName = columnName.substring(0, index); // try Env - String env = Env.getContext(m_schedulerctx, columnName); + String env = Env.getContext(getCtx(), columnName); if (env == null || env.length() == 0) env = Env.getContext(getCtx(), columnName); if (env.length() == 0)