/****************************************************************************** * 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. * * 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., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * For the text or an alternative of this public license, you may reach us * * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * * or via info@compiere.org or http://www.compiere.org/license.html * *****************************************************************************/ package org.compiere.model; import java.net.InetAddress; import java.net.UnknownHostException; import java.sql.ResultSet; import java.util.Properties; import java.util.logging.Level; import org.compiere.Adempiere; import org.compiere.util.Env; import org.compiere.util.TimeUtil; import org.compiere.util.Util; import org.compiere.util.WebUtil; import org.idempiere.cache.ImmutableIntPOCache; import org.idempiere.cache.ImmutablePOSupport; /** * Session Model. * * @author Jorg Janke * @version $Id: MSession.java,v 1.3 2006/07/30 00:58:05 jjanke Exp $ * * @author Teo Sarca, SC ARHIPAC SERVICE SRL *
  • BF [ 1810182 ] Session lost after cache reset *
  • BF [ 1892156 ] MSession is not really cached */ public class MSession extends X_AD_Session implements ImmutablePOSupport { /** * generated serial id */ private static final long serialVersionUID = -5836154187760734691L; /** * Get existing or create local session * @param ctx context * @param createNew create if not found * @return session session * @deprecated use Get and Create functions. */ @Deprecated public static MSession get (Properties ctx, boolean createNew) { MSession session = get(ctx); if(session == null && createNew) return MSession.create(ctx); return session; } // get /** * Get session from context * @param ctx context * @return session */ public static MSession get (Properties ctx) { int AD_Session_ID = Env.getContextAsInt(ctx, Env.AD_SESSION_ID); MSession session = s_sessions.get(ctx, AD_Session_ID, e -> new MSession(ctx, e)); // Try to load if (session == null && AD_Session_ID > 0) { session = new MSession(ctx, AD_Session_ID, null); if (session.get_ID () == AD_Session_ID) { s_sessions.put (AD_Session_ID, session, e -> new MSession(Env.getCtx(), e)); } else { session = null; } } return session; } // get /** * Create new session for context * @param ctx context * @return session */ public static MSession create (Properties ctx) { MSession session = new MSession (ctx, (String)null); // local session session.saveEx(); int AD_Session_ID = session.getAD_Session_ID(); Env.setContext (ctx, Env.AD_SESSION_ID, AD_Session_ID); return session; } // get /** * Get existing or create new session * @param ctx context * @param Remote_Addr remote address * @param Remote_Host remote host * @param WebSession web session * @return session */ public static MSession get (Properties ctx, String Remote_Addr, String Remote_Host, String WebSession) { int AD_Session_ID = Env.getContextAsInt(ctx, Env.AD_SESSION_ID); MSession session = get(ctx); if (session == null) { session = new MSession (ctx, Remote_Addr, Remote_Host, WebSession, null); // remote session session.saveEx(); AD_Session_ID = session.getAD_Session_ID(); Env.setContext(ctx, Env.AD_SESSION_ID, AD_Session_ID); } else { session = new MSession(ctx, session.getAD_Session_ID(), null); } return session; } // get /** Session Cache */ private static ImmutableIntPOCache s_sessions = new ImmutableIntPOCache(Table_Name, Table_Name, 100, 0, false, 0) { private static final long serialVersionUID = 8421415709907257867L; public int reset() { return 0; // do not remove on cache reset }; public int reset(int recordId) { return 0; // do not remove the session on update }; }; /** * UUID based Constructor * @param ctx Context * @param AD_Session_UU UUID key * @param trxName Transaction */ public MSession(Properties ctx, String AD_Session_UU, String trxName) { super(ctx, AD_Session_UU, trxName); if (Util.isEmpty(AD_Session_UU)) setInitialDefaults(); } /** * Standard Constructor * @param ctx context * @param AD_Session_ID id * @param trxName transaction */ public MSession (Properties ctx, int AD_Session_ID, String trxName) { super(ctx, AD_Session_ID, trxName); if (AD_Session_ID == 0) setInitialDefaults(); } // MSession /** * Set the initial defaults for a new record */ private void setInitialDefaults() { setProcessed (false); } /** * Load Constructor * @param ctx context * @param rs result set * @param trxName transaction */ public MSession(Properties ctx, ResultSet rs, String trxName) { super(ctx, rs, trxName); } // MSession /** * New Session Constructor * @param ctx context * @param Remote_Addr remote address * @param Remote_Host remote host * @param WebSession web session * @param trxName transaction */ public MSession (Properties ctx, String Remote_Addr, String Remote_Host, String WebSession, String trxName) { this (ctx, 0, trxName); setServerName(WebUtil.getServerName()); if (Remote_Addr != null) setRemote_Addr(Remote_Addr); if (Remote_Host != null) setRemote_Host(Remote_Host); if (WebSession != null) setWebSession(WebSession); setDescription(Adempiere.MAIN_VERSION + "_" + Adempiere.DATE_VERSION + " " + Adempiere.getImplementationVersion()); setAD_Role_ID(Env.getContextAsInt(ctx, Env.AD_ROLE_ID)); setLoginDate(Env.getContextAsDate(ctx, Env.DATE)); } // MSession /** * New Session Constructor * @param ctx context * @param trxName transaction */ public MSession (Properties ctx, String trxName) { this (ctx, 0, trxName); try { InetAddress lh = InetAddress.getLocalHost(); setServerName(WebUtil.getServerName()); setRemote_Addr(lh.getHostAddress()); setRemote_Host(lh.getHostName()); setDescription(Adempiere.MAIN_VERSION + "_" + Adempiere.DATE_VERSION + " " + Adempiere.getImplementationVersion()); setAD_Role_ID(Env.getContextAsInt(ctx, Env.AD_ROLE_ID)); setLoginDate(Env.getContextAsDate(ctx, Env.DATE)); } catch (UnknownHostException e) { log.log(Level.SEVERE, "No Local Host", e); } } // MSession /** * Copy constructor * @param copy */ public MSession(MSession copy) { this(Env.getCtx(), copy); } /** * Copy constructor * @param ctx * @param copy */ public MSession(Properties ctx, MSession copy) { this(ctx, copy, (String) null); } /** * Copy constructor * @param ctx * @param copy * @param trxName */ public MSession(Properties ctx, MSession copy, String trxName) { this(ctx, 0, trxName); copyPO(copy); } /** Web Store Session */ private boolean m_webStoreSession = false; /** * Is it a Web Store Session * @return true if this is a Web Store Session. */ public boolean isWebStoreSession () { return m_webStoreSession; } // isWebStoreSession /** * Set Web Store Session * @param webStoreSession Web Store Session flag */ public void setWebStoreSession (boolean webStoreSession) { m_webStoreSession = webStoreSession; } // setWebStoreSession /** * String Representation * @return info */ @Override public String toString() { StringBuilder sb = new StringBuilder("MSession[") .append(getAD_Session_ID()) .append(",AD_User_ID=").append(getCreatedBy()) .append(",").append(getCreated()) .append(",Remote=").append(getRemote_Addr()); String s = getRemote_Host(); if (s != null && s.length() > 0) sb.append(",").append(s); if (m_webStoreSession) sb.append(",WebStoreSession"); sb.append("]"); return sb.toString(); } // toString /** * Logout this session */ public void logout() { setProcessed(true); saveEx(); s_sessions.remove(Integer.valueOf(getAD_Session_ID())); if (log.isLoggable(Level.INFO)) log.info(TimeUtil.formatElapsed(getCreated(), getUpdated())); } // logout /** * Preserved for backward compatibility * @deprecated */ @Deprecated public MChangeLog changeLog ( String TrxName, int AD_ChangeLog_ID, int AD_Table_ID, int AD_Column_ID, int Record_ID, int AD_Client_ID, int AD_Org_ID, Object OldValue, Object NewValue) { return changeLog(TrxName, AD_ChangeLog_ID, AD_Table_ID, AD_Column_ID, Record_ID, null, AD_Client_ID, AD_Org_ID, OldValue, NewValue, (String) null); } // changeLog /** * Create Change Log (if table is logged) * @param TrxName transaction name * @param AD_ChangeLog_ID 0 for new change log * @param AD_Table_ID table * @param AD_Column_ID column * @param Record_ID record * @param AD_Client_ID client * @param AD_Org_ID org * @param OldValue old * @param NewValue new * @param event * @return saved change log or null */ public MChangeLog changeLog ( String TrxName, int AD_ChangeLog_ID, int AD_Table_ID, int AD_Column_ID, int Record_ID, int AD_Client_ID, int AD_Org_ID, Object OldValue, Object NewValue, String event) { return changeLog(TrxName, AD_ChangeLog_ID, AD_Table_ID, AD_Column_ID, Record_ID, null, AD_Client_ID, AD_Org_ID, OldValue, NewValue, (String) null); } /** * Create Change Log (if table is logged) * @param TrxName transaction name * @param AD_ChangeLog_ID 0 for new change log * @param AD_Table_ID table * @param AD_Column_ID column * @param Record_ID record * @param Record_UU record UUID * @param AD_Client_ID client * @param AD_Org_ID org * @param OldValue old * @param NewValue new * @param event * @return saved change log or null */ public MChangeLog changeLog ( String TrxName, int AD_ChangeLog_ID, int AD_Table_ID, int AD_Column_ID, int Record_ID, String Record_UU, int AD_Client_ID, int AD_Org_ID, Object OldValue, Object NewValue, String event) { // never log change log itself (recursive error) if (AD_Table_ID == MChangeLog.Table_ID) return null; // Null handling if (OldValue == null && NewValue == null) return null; // Equal Value if (OldValue != null && NewValue != null && OldValue.equals(NewValue)) return null; // Role Logging MRole role = MRole.getDefault(getCtx(), false); // Do we need to log if (m_webStoreSession // log if WebStore || MChangeLog.isLogged(AD_Table_ID) // im/explicit log || (role != null && role.isChangeLog()))// Role Logging ; else return null; // if (log.isLoggable(Level.FINEST)) log.finest("AD_ChangeLog_ID=" + AD_ChangeLog_ID + ", AD_Session_ID=" + getAD_Session_ID() + ", AD_Table_ID=" + AD_Table_ID + ", AD_Column_ID=" + AD_Column_ID + ": " + OldValue + " -> " + NewValue); try { MChangeLog cl = new MChangeLog(getCtx(), AD_ChangeLog_ID, TrxName, getAD_Session_ID(), AD_Table_ID, AD_Column_ID, Record_ID, Record_UU, AD_Client_ID, AD_Org_ID, OldValue, NewValue, event); if (cl.saveCrossTenantSafe()) return cl; } catch (Exception e) { log.log(Level.SEVERE, "AD_ChangeLog_ID=" + AD_ChangeLog_ID + ", AD_Session_ID=" + getAD_Session_ID() + ", AD_Table_ID=" + AD_Table_ID + ", AD_Column_ID=" + AD_Column_ID, e); return null; } log.log(Level.SEVERE, "AD_ChangeLog_ID=" + AD_ChangeLog_ID + ", AD_Session_ID=" + getAD_Session_ID() + ", AD_Table_ID=" + AD_Table_ID + ", AD_Column_ID=" + AD_Column_ID); return null; } // changeLog /** * @return number of cached sessions */ public static int getCachedSessionCount() { return s_sessions.size()-1; } @Override public MSession markImmutable() { if (is_Immutable()) return this; makeImmutable(); return this; } } // MSession