private void addCacheSessionListener(final String uuid) { final ExternalContext.Session session = NetUtils.getSession(XFormsStateManager.FORCE_SESSION_CREATION); assert session != null; final Map<String, Object> sessionAttributes = session.getAttributesMap(ExternalContext.Session.APPLICATION_SCOPE); final String listenerSessionKey = getListenerSessionKey(uuid); if (sessionAttributes.get(listenerSessionKey) == null) { // Remove from cache when session expires final ExternalContext.Session.SessionListener listener = new ExternalContext.Session.SessionListener() { public void sessionDestroyed() { indentedLogger.logDebug( LOG_TYPE, "Removing document from cache following session expiration."); // NOTE: This will call onRemoved() on the document, and onRemovedFromCache() on // XFormsStateManager XFormsDocumentCache.instance().removeDocument(uuid); } }; // Add listener session.addListener(listener); // Remember, in session, mapping (UUID -> session listener) sessionAttributes.put(listenerSessionKey, listener); } }
/** * Transform an URI accessible from the server into a URI accessible from the client. The mapping * expires with the session. * * @param propertyContext context to obtain session * @param uri server URI to transform * @param filename file name * @param contentType type of the content referred to by the URI, or null if unknown * @param lastModified last modification timestamp * @return client URI */ public static String proxyURI( PropertyContext propertyContext, String uri, String filename, String contentType, long lastModified) { // Create a digest, so that for a given URI we always get the same key final String digest = SecureUtils.digestString(uri, "MD5", "hex"); // Get session final ExternalContext externalContext = (ExternalContext) propertyContext.getAttribute(PipelineContext.EXTERNAL_CONTEXT); final ExternalContext.Session session = externalContext.getSession( true); // NOTE: We force session creation here. Should we? What's the alternative? if (session != null) { // Store mapping into session session .getAttributesMap(ExternalContext.Session.APPLICATION_SCOPE) .put( DYNAMIC_RESOURCES_SESSION_KEY + digest, new DynamicResource(uri, filename, contentType, -1, lastModified)); } // Rewrite new URI to absolute path without the context return DYNAMIC_RESOURCES_PATH + digest; }
private static void addDocumentToSession(String uuid) { final ExternalContext.Session session = NetUtils.getSession(XFormsStateManager.FORCE_SESSION_CREATION); final Map<String, Object> sessionAttributes = session.getAttributesMap(ExternalContext.Session.APPLICATION_SCOPE); sessionAttributes.put(getUUIDSessionKey(uuid), new SessionDocument(uuid)); }
// Keep public and static for unit tests and submission processor (called from XSLT) public static void removeSessionDocument(String uuid) { final ExternalContext.Session session = NetUtils.getSession(false); if (session != null) { final Map<String, Object> sessionAttributes = session.getAttributesMap(ExternalContext.Session.APPLICATION_SCOPE); sessionAttributes.remove(getUUIDSessionKey(uuid)); } }
private static SessionDocument getSessionDocument(String uuid) { final ExternalContext.Session session = NetUtils.getSession(false); if (session != null) { final Map<String, Object> sessionAttributes = session.getAttributesMap(ExternalContext.Session.APPLICATION_SCOPE); return (SessionDocument) sessionAttributes.get(getUUIDSessionKey(uuid)); } else { return null; } }
/** * Return the delay for the session heartbeat event. * * @param containingDocument containing document * @param externalContext external context (for access to session and application scopes) * @return delay in ms, or -1 is not applicable */ public static long getHeartbeatDelay( XFormsContainingDocument containingDocument, ExternalContext externalContext) { if (containingDocument.getStaticState().isClientStateHandling()) { // No heartbeat for client state. Is that reasonable? return -1; } else { final boolean isSessionHeartbeat = containingDocument.isSessionHeartbeat(); final ExternalContext.Session session = externalContext.getRequest().getSession(FORCE_SESSION_CREATION); final long heartbeatDelay; if (isSessionHeartbeat) heartbeatDelay = session.getMaxInactiveInterval() * 800; // 80% of session expiration time, in ms else heartbeatDelay = -1; return heartbeatDelay; } }
/** * Add listener to fileItem which is going to be automatically destroyed on session destruction * * @param pipelineContext PipelineContext * @param fileItem FileItem */ public static void deleteFileOnSessionTermination( PipelineContext pipelineContext, final FileItem fileItem) { // Try to delete the file on exit and on session termination final ExternalContext externalContext = (ExternalContext) pipelineContext.getAttribute(PipelineContext.EXTERNAL_CONTEXT); final ExternalContext.Session session = externalContext.getSession(false); if (session != null) { session.addListener( new ExternalContext.Session.SessionListener() { public void sessionDestroyed() { deleteFileItem(fileItem, SESSION_SCOPE); } }); } else { logger.debug( "No existing session found so cannot register temporary file deletion upon session destruction: " + fileItem.getName()); } }
private void removeCacheSessionListener(String uuid) { // Tricky: if onRemove() is called upon session expiration, there might not be an // ExternalContext. But it's fine, // because the session goes away -> all of its attributes go away so we don't have to remove // them below. final ExternalContext.Session session = NetUtils.getSession(XFormsStateManager.FORCE_SESSION_CREATION); if (session != null) { final Map<String, Object> sessionAttributes = session.getAttributesMap(ExternalContext.Session.APPLICATION_SCOPE); final String listenerSessionKey = getListenerSessionKey(uuid); final ExternalContext.Session.SessionListener listener = (ExternalContext.Session.SessionListener) sessionAttributes.get(listenerSessionKey); if (listener != null) { // Remove listener session.removeListener(listener); // Forget, in session, mapping (UUID -> session listener) sessionAttributes.remove(listenerSessionKey); } } }
private XFormsContainingDocument createDocumentFromStore( RequestParameters parameters, boolean isInitialState, boolean disableUpdates) { final boolean isServerState = parameters.getEncodedClientStaticState() == null; final XFormsState xformsState; if (isServerState) { // State must be found by UUID in the store final ExternalContext externalContext = NetUtils.getExternalContext(); final XFormsStateStore stateStore = XFormsStateStoreFactory.instance(externalContext); if (indentedLogger.isDebugEnabled()) indentedLogger.logDebug( LOG_TYPE, "Getting document state from store.", "current cache size", Integer.toString(XFormsDocumentCache.instance().getCurrentSize()), "current store size", Long.toString(stateStore.getCurrentSize()), "max store size", Long.toString(stateStore.getMaxSize())); final ExternalContext.Session session = externalContext.getRequest().getSession(XFormsStateManager.FORCE_SESSION_CREATION); xformsState = stateStore.findState(session, parameters.getUUID(), isInitialState); if (xformsState == null) { // Oops, we couldn't find the state in the store final String UNABLE_TO_RETRIEVE_XFORMS_STATE_MESSAGE = "Unable to retrieve XForms engine state."; final String PLEASE_RELOAD_PAGE_MESSAGE = "Please reload the current page. Note that you will lose any unsaved changes."; // Produce exception final ExternalContext.Session currentSession = externalContext.getRequest().getSession(false); final String message; if (currentSession == null || currentSession.isNew()) { // This means that no session is currently existing, or a session exists but it is newly // created message = "Your session has expired. " + PLEASE_RELOAD_PAGE_MESSAGE; } else { // There is a session and it is still known by the client message = UNABLE_TO_RETRIEVE_XFORMS_STATE_MESSAGE + " " + PLEASE_RELOAD_PAGE_MESSAGE; } indentedLogger.logError("", message); throw new OXFException(message); } } else { // State comes directly with request xformsState = new XFormsState( scala.Option.<String>apply(null), parameters.getEncodedClientStaticState(), DynamicState.apply(parameters.getEncodedClientDynamicState())); } // Create document final XFormsContainingDocument document = new XFormsContainingDocument(xformsState, disableUpdates); assert isServerState ? document.getStaticState().isServerStateHandling() : document.getStaticState().isClientStateHandling(); return document; }