- User context lost

* Cache plain property class in session
* Fixed context init for event thread
* Added missing context cleanup for event thread, this should be the issue that cause random user context loss.
This commit is contained in:
Heng Sin Low 2009-09-24 15:12:03 +00:00
parent 7eae15d181
commit 9c243122b6
3 changed files with 119 additions and 37 deletions

View File

@ -9,6 +9,7 @@ import java.text.ParseException;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.Properties;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
@ -22,7 +23,7 @@ import org.compiere.model.MAssignmentSlot;
import org.compiere.model.ScheduleUtil; import org.compiere.model.ScheduleUtil;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.zkforge.timeline.util.TimelineUtil; import org.zkforge.timeline.util.TimelineUtil;
import org.zkoss.web.fn.XMLFns; import org.zkoss.xel.fn.XmlFns;
import org.zkoss.xml.XMLs; import org.zkoss.xml.XMLs;
public class TimelineEventFeed extends HttpServlet { public class TimelineEventFeed extends HttpServlet {
@ -36,13 +37,18 @@ public class TimelineEventFeed extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { throws ServletException, IOException {
ServerContext ctx = (ServerContext)req.getSession().getAttribute(SessionContextListener.SESSION_CTX); Properties ctx = (Properties)req.getSession().getAttribute(SessionContextListener.SESSION_CTX);
if (ctx == null) { if (ctx == null) {
return; return;
} else {
ServerContext.setCurrentInstance(ctx);
} }
ServerContext serverContext = ServerContext.getCurrentInstance();
if (serverContext == null) {
serverContext = ServerContext.newInstance();
}
serverContext.clear();
serverContext.putAll(ctx);
int resourceId = 0; int resourceId = 0;
String resourceIdParam = req.getParameter("S_Resource_ID"); String resourceIdParam = req.getParameter("S_Resource_ID");
if (resourceIdParam != null && resourceIdParam.trim().length() > 0) { if (resourceIdParam != null && resourceIdParam.trim().length() > 0) {
@ -96,16 +102,16 @@ public class TimelineEventFeed extends HttpServlet {
for (MAssignmentSlot slot : mas) { for (MAssignmentSlot slot : mas) {
xml.append("<event ").append("\r\n"); xml.append("<event ").append("\r\n");
xml.append(XMLFns.attr("start", TimelineUtil.formatDateTime(new Date(slot.getStartTime().getTime())))); xml.append(XmlFns.attr("start", TimelineUtil.formatDateTime(new Date(slot.getStartTime().getTime()))));
if (slot.getEndTime() != null) { if (slot.getEndTime() != null) {
xml.append("\r\n"); xml.append("\r\n");
xml.append(XMLFns.attr("end", TimelineUtil.formatDateTime(new Date(slot.getEndTime().getTime())))); xml.append(XmlFns.attr("end", TimelineUtil.formatDateTime(new Date(slot.getEndTime().getTime()))));
xml.append("\r\n"); xml.append("\r\n");
xml.append(XMLFns.attr("isDuration", "true")); xml.append(XmlFns.attr("isDuration", "true"));
} }
xml.append(XMLFns.attr("color", "#"+ZkCssHelper.createHexColorString(slot.getColor(true)))); xml.append(XmlFns.attr("color", "#"+ZkCssHelper.createHexColorString(slot.getColor(true))));
xml.append("\r\n") xml.append("\r\n")
.append(XMLFns.attr("title", slot.getName())) .append(XmlFns.attr("title", slot.getName()))
.append("\r\n") .append("\r\n")
.append(">"); .append(">");
if (slot.getDescription() != null && slot.getDescription().trim().length() > 0) { if (slot.getDescription() != null && slot.getDescription().trim().length() > 0) {

View File

@ -16,6 +16,7 @@ package org.adempiere.webui.dashboard;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Properties;
import org.adempiere.webui.desktop.IDesktop; import org.adempiere.webui.desktop.IDesktop;
import org.adempiere.webui.session.ServerContext; import org.adempiere.webui.session.ServerContext;
@ -86,20 +87,34 @@ public class DashboardRunnable implements Runnable {
for(int i = 0; i < dashboardPanels.size(); i++) for(int i = 0; i < dashboardPanels.size(); i++)
{ {
//make sure context is correct //make sure context is correct
ServerContext ctx = (ServerContext)template.getDesktop().getSession().getAttribute(SessionContextListener.SESSION_CTX); Properties ctx = (Properties)template.getDesktop().getSession().getAttribute(SessionContextListener.SESSION_CTX);
if (ctx != null && ServerContext.getCurrentInstance() != ctx) if (ctx != null)
{ {
ServerContext.setCurrentInstance(ctx); ServerContext serverContext = ServerContext.getCurrentInstance();
} if (serverContext == null) {
serverContext = ServerContext.newInstance();
serverContext.putAll(ctx);
} else if (!ctx.getProperty(SessionContextListener.SERVLET_SESSION_ID).equals(serverContext.getProperty(SessionContextListener.SERVLET_SESSION_ID))) {
serverContext.clear();
serverContext.putAll(ctx);
}
}
dashboardPanels.get(i).refresh(template); dashboardPanels.get(i).refresh(template);
} }
//make sure context is correct //make sure context is correct
ServerContext ctx = (ServerContext)template.getDesktop().getSession().getAttribute(SessionContextListener.SESSION_CTX); Properties ctx = (Properties)template.getDesktop().getSession().getAttribute(SessionContextListener.SESSION_CTX);
if (ctx != null && ServerContext.getCurrentInstance() != ctx) if (ctx != null)
{ {
ServerContext.setCurrentInstance(ctx); ServerContext serverContext = ServerContext.getCurrentInstance();
} if (serverContext == null) {
serverContext = ServerContext.newInstance();
serverContext.putAll(ctx);
} else if (!ctx.getProperty(SessionContextListener.SERVLET_SESSION_ID).equals(serverContext.getProperty(SessionContextListener.SERVLET_SESSION_ID))) {
serverContext.clear();
serverContext.putAll(ctx);
}
}
appDesktop.onServerPush(template); appDesktop.onServerPush(template);
} }

View File

@ -18,14 +18,17 @@
package org.adempiere.webui.session; package org.adempiere.webui.session;
import java.util.List; import java.util.List;
import java.util.Properties;
import javax.servlet.http.HttpSession;
import org.adempiere.webui.apps.AEnv;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.zkoss.util.Locales; import org.zkoss.util.Locales;
import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Execution; import org.zkoss.zk.ui.Execution;
import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventThreadCleanup;
import org.zkoss.zk.ui.event.EventThreadInit; import org.zkoss.zk.ui.event.EventThreadInit;
import org.zkoss.zk.ui.event.EventThreadResume; import org.zkoss.zk.ui.event.EventThreadResume;
import org.zkoss.zk.ui.util.ExecutionCleanup; import org.zkoss.zk.ui.util.ExecutionCleanup;
@ -38,8 +41,9 @@ import org.zkoss.zk.ui.util.ExecutionInit;
* @version $Revision: 0.10 $ * @version $Revision: 0.10 $
*/ */
public class SessionContextListener implements ExecutionInit, public class SessionContextListener implements ExecutionInit,
ExecutionCleanup, EventThreadInit, EventThreadResume ExecutionCleanup, EventThreadInit, EventThreadResume, EventThreadCleanup
{ {
public static final String SERVLET_SESSION_ID = "servlet.sessionId";
public static final String SESSION_CTX = "WebUISessionContext"; public static final String SESSION_CTX = "WebUISessionContext";
/** /**
@ -52,17 +56,22 @@ public class SessionContextListener implements ExecutionInit,
{ {
if (parent == null) if (parent == null)
{ {
ServerContext ctx = (ServerContext)exec.getDesktop().getSession().getAttribute(SESSION_CTX); Properties ctx = (Properties)exec.getDesktop().getSession().getAttribute(SESSION_CTX);
if (ctx == null) if (ctx == null)
{ {
ctx = ServerContext.newInstance(); ctx = new Properties();
HttpSession session = (HttpSession)exec.getDesktop().getSession().getNativeSession();
ctx.setProperty(SERVLET_SESSION_ID, session.getId());
exec.getDesktop().getSession().setAttribute(SESSION_CTX, ctx); exec.getDesktop().getSession().setAttribute(SESSION_CTX, ctx);
} }
else
ServerContext serverContext = ServerContext.getCurrentInstance();
if (serverContext == null)
{ {
ServerContext.setCurrentInstance(ctx); serverContext = ServerContext.newInstance();
} }
exec.setAttribute(SESSION_CTX, ctx); serverContext.clear();
serverContext.putAll(ctx);
//set locale //set locale
Locales.setThreadLocal(Env.getLanguage(ctx).getLocale()); Locales.setThreadLocal(Env.getLanguage(ctx).getLocale());
@ -79,7 +88,6 @@ public class SessionContextListener implements ExecutionInit,
{ {
if (parent == null) if (parent == null)
{ {
exec.removeAttribute(SESSION_CTX);
ServerContext.dispose(); ServerContext.dispose();
} }
} }
@ -100,12 +108,26 @@ public class SessionContextListener implements ExecutionInit,
*/ */
public boolean init(Component comp, Event evt) public boolean init(Component comp, Event evt)
{ {
ServerContext ctx = (ServerContext) Executions.getCurrent().getAttribute( //setup context
SESSION_CTX); Properties ctx = (Properties)Executions.getCurrent().getDesktop().getSession().getAttribute(SESSION_CTX);
ServerContext.setCurrentInstance(ctx); if (ctx == null)
{
ctx = new Properties();
HttpSession session = (HttpSession)Executions.getCurrent().getDesktop().getSession().getNativeSession();
ctx.setProperty(SERVLET_SESSION_ID, session.getId());
Executions.getCurrent().getDesktop().getSession().setAttribute(SESSION_CTX, ctx);
}
// set locale ServerContext serverContext = ServerContext.getCurrentInstance();
Locales.setThreadLocal(AEnv.getLocale(ctx)); if (serverContext == null)
{
serverContext = ServerContext.newInstance();
}
serverContext.clear();
serverContext.putAll(ctx);
//set locale
Locales.setThreadLocal(Env.getLanguage(ctx).getLocale());
return true; return true;
} }
@ -126,9 +148,19 @@ public class SessionContextListener implements ExecutionInit,
*/ */
public void afterResume(Component comp, Event evt) public void afterResume(Component comp, Event evt)
{ {
ServerContext ctx = (ServerContext) Executions.getCurrent().getAttribute( //make sure context is correct
SESSION_CTX); Properties ctx = (Properties)Executions.getCurrent().getDesktop().getSession().getAttribute(SESSION_CTX);
ServerContext.setCurrentInstance(ctx); if (ctx != null)
{
ServerContext serverContext = ServerContext.getCurrentInstance();
if (serverContext == null) {
serverContext = ServerContext.newInstance();
serverContext.putAll(ctx);
} else if (!ctx.getProperty(SERVLET_SESSION_ID).equals(serverContext.getProperty(SERVLET_SESSION_ID))) {
serverContext.clear();
serverContext.putAll(ctx);
}
}
} }
/** /**
@ -138,6 +170,35 @@ public class SessionContextListener implements ExecutionInit,
*/ */
public void abortResume(Component comp, Event evt) public void abortResume(Component comp, Event evt)
{ {
// do nothing
} }
/**
* @param comp
* @param evt
* @param errs
* @see EventThreadCleanup#cleanup(Component, Event, List)
*/
public void cleanup(Component comp, Event evt, List errs) throws Exception
{
//update session context
Properties ctx = (Properties) Executions.getCurrent().getDesktop().getSession().getAttribute(SESSION_CTX);
ServerContext serverContext = ServerContext.getCurrentInstance();
if (ctx != null && serverContext != null
&& ctx.getProperty(SERVLET_SESSION_ID).equals(serverContext.getProperty(SERVLET_SESSION_ID)))
{
ctx.putAll(serverContext);
}
ServerContext.dispose();
}
/**
* @param comp
* @param evt
* @see EventThreadCleanup#complete(Component, Event)
*/
public void complete(Component comp, Event evt) throws Exception
{
}
} }