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);
    }
  }
Esempio n. 2
0
  /**
   * 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;
  }
Esempio n. 3
0
  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));
  }
Esempio n. 4
0
 // 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));
   }
 }
Esempio n. 5
0
 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;
   }
 }
Esempio n. 6
0
  /**
   * 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;
    }
  }
Esempio n. 7
0
 /**
  * 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());
   }
 }
Esempio n. 8
0
  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;
  }