IDEMPIERE-5557 Dashboard Rendering Threads do not hold language set after login (#1659)

- add setup of thread local Locale to ContextRunnable
This commit is contained in:
hengsin 2023-02-05 18:21:48 +08:00 committed by GitHub
parent 291a4df19e
commit 2b24496d16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 104 additions and 18 deletions

View File

@ -17,13 +17,19 @@ import java.util.Properties;
/**
* Base class to implement runnable that will execute code in session context
* @author hengsin
*
*/
public abstract class ContextRunnable implements Runnable {
/**
* current session context
*/
protected Properties context = null;
/**
* default constructor
*/
public ContextRunnable() {
this.context = ServerContext.getCurrentInstance();
}
@ -34,12 +40,29 @@ public abstract class ContextRunnable implements Runnable {
@Override
public void run() {
try {
ServerContext.setCurrentInstance(context);
setup();
doRun();
} finally {
ServerContext.dispose();
cleanup();
}
}
/**
* setup thread context
*/
protected void setup() {
ServerContext.setCurrentInstance(context);
}
/**
* clean up thread context
*/
protected void cleanup() {
ServerContext.dispose();
}
/**
* override to execute code in session context
*/
protected abstract void doRun();
}

View File

@ -24,7 +24,6 @@ import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import org.adempiere.util.Callback;
import org.adempiere.util.ContextRunnable;
import org.adempiere.util.IProcessUI;
import org.adempiere.util.ServerContext;
import org.adempiere.webui.LayoutUtils;
@ -50,6 +49,7 @@ import org.adempiere.webui.info.InfoWindow;
import org.adempiere.webui.process.WProcessInfo;
import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.util.ZkContextRunnable;
import org.adempiere.webui.window.Dialog;
import org.adempiere.webui.window.MultiFileDownloadDialog;
import org.adempiere.webui.window.SimplePDFViewer;
@ -1142,7 +1142,7 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
return downloadFiles;
}
private class ProcessDialogRunnable extends ContextRunnable
private class ProcessDialogRunnable extends ZkContextRunnable
{
private Trx m_trx;

View File

@ -29,12 +29,12 @@
package org.adempiere.webui.dashboard;
import org.adempiere.util.ContextRunnable;
import org.adempiere.webui.apps.BusyDialog;
import org.adempiere.webui.apps.graph.WDocumentStatusPanel;
import org.adempiere.webui.component.ToolBarButton;
import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.util.ServerPushTemplate;
import org.adempiere.webui.util.ZkContextRunnable;
import org.compiere.Adempiere;
import org.compiere.util.Env;
import org.compiere.util.Msg;
@ -102,7 +102,7 @@ public class DPDocumentStatus extends DashboardPanel implements EventListener<Ev
busyDialog.setShadow(false);
getParent().insertBefore(busyDialog, getParent().getFirstChild());
ServerPushTemplate template = new ServerPushTemplate(getDesktop());
ContextRunnable cr = new ContextRunnable() {
ZkContextRunnable cr = new ZkContextRunnable() {
@Override
protected void doRun() {
refresh(template);

View File

@ -20,11 +20,11 @@ import java.util.List;
import java.util.Locale;
import java.util.Properties;
import org.adempiere.util.ContextRunnable;
import org.adempiere.util.ServerContext;
import org.adempiere.webui.apps.BusyDialog;
import org.adempiere.webui.session.SessionContextListener;
import org.adempiere.webui.util.ServerPushTemplate;
import org.adempiere.webui.util.ZkContextRunnable;
import org.compiere.Adempiere;
import org.compiere.util.CLogger;
import org.zkoss.util.Locales;
@ -139,7 +139,7 @@ public class DashboardRunnable implements Runnable, Serializable
BusyDialog busyDialog = new BusyDialog();
busyDialog.setShadow(false);
dpanel.getParent().insertBefore(busyDialog, dpanel.getParent().getFirstChild());
ContextRunnable cr = new ContextRunnable() {
ZkContextRunnable cr = new ZkContextRunnable() {
@Override
protected void doRun() {
dpanel.refresh(template);

View File

@ -33,7 +33,6 @@ import java.util.Properties;
import java.util.logging.Level;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.util.ContextRunnable;
import org.adempiere.webui.ClientInfo;
import org.adempiere.webui.Extensions;
import org.adempiere.webui.LayoutUtils;
@ -53,6 +52,7 @@ import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.util.ServerPushTemplate;
import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.util.ZkContextRunnable;
import org.adempiere.webui.window.ZkReportViewerProvider;
import org.compiere.Adempiere;
import org.compiere.model.I_AD_Menu;
@ -295,7 +295,7 @@ public class DashboardController implements EventListener<Event> {
}
}
final Component zulComponent = zComponent;
ContextRunnable cr = new ContextRunnable() {
ZkContextRunnable cr = new ZkContextRunnable() {
@Override
protected void doRun() {
try {
@ -594,7 +594,7 @@ public class DashboardController implements EventListener<Event> {
}
}
final Component zulComponent = zComponent;
ContextRunnable cr = new ContextRunnable() {
ZkContextRunnable cr = new ZkContextRunnable() {
@Override
protected void doRun() {
try {

View File

@ -0,0 +1,63 @@
/***********************************************************************
* 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.adempiere.webui.util;
import java.util.Locale;
import org.adempiere.util.ContextRunnable;
import org.zkoss.util.Locales;
/**
* This class setup additional zk specific session context.
* Zk web UI code should use this instead of ContextRunnable.
* @author hengsin
*/
public abstract class ZkContextRunnable extends ContextRunnable {
//session locale
private Locale locale = null;
//original locale for thread
private Locale old = null;
/**
* default constructor
*/
public ZkContextRunnable() {
super();
locale = Locales.getCurrent();
}
@Override
protected void setup() {
super.setup();
old = Locales.setThreadLocal(locale);
}
@Override
protected void cleanup() {
super.cleanup();
Locales.setThreadLocal(old);
}
}

View File

@ -38,7 +38,6 @@ import org.adempiere.base.upload.IUploadService;
import org.adempiere.exceptions.DBException;
import org.adempiere.pdf.Document;
import org.adempiere.util.Callback;
import org.adempiere.util.ContextRunnable;
import org.adempiere.webui.ClientInfo;
import org.adempiere.webui.Extensions;
import org.adempiere.webui.LayoutUtils;
@ -71,6 +70,7 @@ import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.util.IServerPushCallback;
import org.adempiere.webui.util.ServerPushTemplate;
import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.util.ZkContextRunnable;
import org.compiere.model.GridField;
import org.compiere.model.MArchive;
import org.compiere.model.MAttachment;
@ -1797,7 +1797,7 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
}
}
static class PDFRendererRunnable extends ContextRunnable implements IServerPushCallback {
static class PDFRendererRunnable extends ZkContextRunnable implements IServerPushCallback {
private ZkReportViewer viewer;
@ -1833,7 +1833,7 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
}
static class HTMLRendererRunnable extends ContextRunnable implements IServerPushCallback {
static class HTMLRendererRunnable extends ZkContextRunnable implements IServerPushCallback {
private ZkReportViewer viewer;
public HTMLRendererRunnable(ZkReportViewer viewer) {
@ -1868,7 +1868,7 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
}
}
static class XLSRendererRunnable extends ContextRunnable implements IServerPushCallback {
static class XLSRendererRunnable extends ZkContextRunnable implements IServerPushCallback {
private ZkReportViewer viewer;
@ -1904,7 +1904,7 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
}
static class CSVRendererRunnable extends ContextRunnable implements IServerPushCallback {
static class CSVRendererRunnable extends ZkContextRunnable implements IServerPushCallback {
private ZkReportViewer viewer;
@ -1938,7 +1938,7 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
}
protected static class XLSXRendererRunnable extends ContextRunnable implements IServerPushCallback
protected static class XLSXRendererRunnable extends ZkContextRunnable implements IServerPushCallback
{
private ZkReportViewer viewer;