package er.persistentsessionstorage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.webobjects.appserver.WOContext; import com.webobjects.appserver.WORequest; import com.webobjects.appserver.WOSession; import com.webobjects.appserver.WOSessionStore; import com.webobjects.eocontrol.EOEditingContext; import com.webobjects.foundation.NSMutableDictionary; import com.webobjects.foundation.NSTimestamp; import er.extensions.appserver.ERXApplication; import er.extensions.eof.ERXEC; import er.persistentsessionstorage.model.ERSessionInfo; public class ERPersistentSessionStore extends WOSessionStore { private static final Logger log = LoggerFactory.getLogger(ERPersistentSessionStore.class); @Override public WOSession removeSessionWithID(String s) { EOEditingContext ec = ERXEC.newEditingContext(); ERSessionInfo info = ERSessionInfo.clazz.objectMatchingKeyAndValue(ec, ERSessionInfo.SESSION_ID_KEY, s); if(info != null) { WOSession session = info.session(); info.delete(); ec.saveChanges(); return session; } return null; } @Override public WOSession restoreSessionWithID(String s, WORequest request) { EOEditingContext ec = ERXEC.newEditingContext(); ERSessionInfo info = ERSessionInfo.clazz.objectMatchingKeyAndValue(ec, ERSessionInfo.SESSION_ID_KEY, s); return info == null || info.expirationDate().getTime() < System.currentTimeMillis()?null:info.session(); } @Override public void saveSessionForContext(WOContext context) { WOSession session = context.session(); EOEditingContext ec = ERXEC.newEditingContext(); ERSessionInfo info = ERSessionInfo.clazz.objectMatchingKeyAndValue(ec, ERSessionInfo.SESSION_ID_KEY, session.sessionID()); if(info == null) { info = ERSessionInfo.clazz.createAndInsertObject(ec); info.setSessionID(session.sessionID()); } NSTimestamp expires = new NSTimestamp(System.currentTimeMillis() + session.timeOutMillis()); info.setExpirationDate(expires); try { /* * An error here can later hang the instance when the session is restored. * If the session fails to archive, delete it. */ info.archiveDataFromSession(session); } catch (Exception e) { log.error("Error archiving session! Deleting session."); ERXApplication app = ERXApplication.erxApplication(); NSMutableDictionary extraInfo = app.extraInformationForExceptionInContext(e, context); app.reportException(e, context, extraInfo); /* * If the session info is new, just don't save it. * Otherwise, we need to delete the session. */ if(!info.isNewObject()) { removeSessionWithID(session.sessionID()); } return; } ec.saveChanges(); } }