Beispiel #1
0
  @Override
  public UIViewRoot createView(FacesContext context, String viewId) {
    UIViewRoot root = null;

    try {
      root = super.createView(context, viewId);
    } catch (RuntimeException e) {
      if (AjaxUtil.isAjaxRequest(context)) {
        // If exception was caught during our ajax request then we need to process it
        // and send ajax response with details about exception.
        CommonAjaxViewRoot.processExceptionDuringAjax(context, e);
        Log.log(context, e.getMessage(), e);
      } else {
        // We need to rethrow exception.
        throw new RuntimeException(e);
      }
    } catch (Error e) {
      if (AjaxUtil.isAjaxRequest(context)) {
        // If exception was caught during our ajax request then we need to process it
        // and send ajax response with details about exception.
        CommonAjaxViewRoot.processExceptionDuringAjax(context, e);
        Log.log(context, e.getMessage(), e);
      } else {
        // We need to rethrow exception.
        throw new Error(e);
      }
    }

    // If created instance of UIViewRoot does not implement our interface WrappedAjaxRoot
    // then we need to wrap it with our AjaxViewRoot
    UIViewRoot riRoot;
    if (null == root || root instanceof WrappedAjaxRoot) {
      riRoot = root;
    } else {
      riRoot = getAjaxViewRoot(root, context);
    }

    ExternalContext externalContext = context.getExternalContext();
    Map<String, String> requestParameterMap = externalContext.getRequestParameterMap();
    Map<String, Object> requestMap = externalContext.getRequestMap();
    if (requestParameterMap.containsKey("of_sessionExpiration")
        && requestParameterMap.containsKey(AjaxUtil.AJAX_REQUEST_MARKER)) {
      if (!requestMap.containsKey(SESSION_EXPIRATION_PROCESSING)) {
        requestMap.put(SESSION_EXPIRATION_PROCESSING, Boolean.TRUE);

        String actionURL = getActionURL(context, viewId);
        actionURL = externalContext.encodeActionURL(actionURL);
        requestMap.put(LOCATION_HEADER, actionURL);
      }
    }

    return riRoot;
  }
Beispiel #2
0
 @Override
 public void queueEvent(FacesEvent event) {
   if (AjaxUtil.isAjaxRequest(getFacesContext())) {
     commonAjaxViewRoot.queueEvent(event);
     return;
   }
   super.queueEvent(event);
 }
Beispiel #3
0
  @Override
  public boolean getRendersChildren() {
    FacesContext context = FacesContext.getCurrentInstance();
    // For non Ajax request, view root not render children
    if (!AjaxUtil.isAjaxRequest(context)) {
      return false;
    }

    // Ajax Request. Control all output.
    return true;
  }
Beispiel #4
0
 private void updateSessionExpirationFlagUnderPortlets(
     FacesContext context,
     UIViewRoot root,
     ExternalContext externalContext,
     Map<String, Object> requestMap) {
   if (AjaxUtil.isPortletRequest(context)
       && externalContext.getSessionMap().containsKey(SESSION_EXPIRATION_PROCESSING)
       && !(requestMap.containsKey(LOCATION_HEADER))) {
     requestMap.put(SESSION_EXPIRATION_PROCESSING, Boolean.TRUE.toString());
     addSessionExpirationFlagUnderPortlets(context, root);
     externalContext.getSessionMap().remove(SESSION_EXPIRATION_PROCESSING);
   }
 }
Beispiel #5
0
  @Override
  public UIViewRoot restoreView(FacesContext context, String viewId) {

    Map<String, Object> sessionMap = context.getExternalContext().getSessionMap();

    if (!sessionMap.containsKey(SESSION_SYNCHRONIZATION)) {
      // RequestSyncObject is required for synchronization of parallel ajax requests.
      // If sessionMap doesn't contain RequestSyncObject, we need to put it in.
      sessionMap.put(SESSION_SYNCHRONIZATION, new RequestsSyncObject());
    }

    // Begin of synchronized block
    synchronized (sessionMap.get(SESSION_SYNCHRONIZATION)) {
      Map<String, Object> requestMap = context.getExternalContext().getRequestMap();
      // RequestMap will contain SKIP_FURTHER_VIEW_HANDLERS key, only if one of our viewHandler
      // instances in "chain" already done it's processing.
      RequestsSyncObject syncObject = (RequestsSyncObject) sessionMap.get(SESSION_SYNCHRONIZATION);
      if (requestMap == null || !requestMap.containsKey(SKIP_FURTHER_VIEW_HANDLERS)) {

        while (syncObject.getAjaxRequestProcessing()) {
          // While we have ajax request in progress,
          // all new requests that comes from client should wait for finishing of previous one.
          try {
            syncObject.wait();
          } catch (InterruptedException e) {
            // It's OK.
          }
        }
      }

      UIViewRoot viewRoot = null;
      try {
        viewRoot = super.restoreView(context, viewId);
      } catch (RuntimeException e) {
        // If exception was caught during our ajax request then we need to process it
        // and send ajax response with details about exception.
        if (AjaxUtil.isAjaxRequest(context)) {
          CommonAjaxViewRoot.processExceptionDuringAjax(context, e);
          Log.log(context, e.getMessage(), e);
        } else {
          // If current request is not our ajax request and exception was caught then we need to
          // rethrow exception.
          throw new RuntimeException(e);
        }
      } catch (Error e) {
        // If exception was caught during our ajax request then we need to process it
        // and send ajax response with details about exception.
        if (AjaxUtil.isAjaxRequest(context)) {
          CommonAjaxViewRoot.processExceptionDuringAjax(context, e);
          Log.log(context, e.getMessage(), e);
        } else {
          // If current request is not our ajax request and exception was caught then we need to
          // rethrow exception.
          throw new Error(e);
        }
      }

      if (AjaxUtil.isAjaxRequest(context)) {
        if (!requestMap.containsKey(SKIP_FURTHER_VIEW_HANDLERS)) {
          // Ajax request processing starts from here, so we need to set boolean flag
          // on RequestSyncObject for futher synchronization of parallel ajax requests
          syncObject.setAjaxRequestProcessing(true);
          // AjaxViewHandler's logic need to be invoked only once,
          // so we indicate it by putting SKIP_FURTHER_VIEW_HANDLERS attribute
          requestMap.put(SKIP_FURTHER_VIEW_HANDLERS, Boolean.TRUE);
        }
      }

      ExternalContext externalContext = context.getExternalContext();
      Object httpSession = externalContext.getSession(false);
      boolean isSessionExpirationTesting =
          context
              .getExternalContext()
              .getRequestParameterMap()
              .containsKey(SESSION_EXPIRATION_TESTING_PARAM);
      // This statement checks for session expiration. It works in both client and server state
      // saving.
      if (isSessionExpirationTesting
          || null == httpSession
          || isNewSession(httpSession)
          || viewRoot == null) {
        boolean isLiferay = Environment.isLiferay(requestMap);
        if (!isLiferay) {
          if (AjaxUtil.isAjaxRequest(context)
              && !requestMap.containsKey(SESSION_EXPIRATION_PROCESSING)) {
            // If session expired, we need to set request scoped parameter,
            // this will indicate session expiration processing.
            requestMap.put(SESSION_EXPIRATION_PROCESSING, Boolean.TRUE);

            if (AjaxUtil.isPortletRequest(context)) {
              // In portlet environment we need to set session scoped parameter that indicate
              // session expiration processing
              // because in portlet for one user request, we have ActionRequest and RenderRequest on
              // a server.
              // Both these requests have their own request maps.
              sessionMap.put(SESSION_EXPIRATION_PROCESSING, Boolean.TRUE);
            }

            if (!AjaxUtil.isPortletRequest(context)) {
              // After session expired, we need to send to the client redirect location url
              // So, here we encode redirect url for current view and put it into requestMap for
              // futher processing.
              String actionURL = getActionURL(context, viewId);
              actionURL = externalContext.encodeActionURL(actionURL);
              requestMap.put(LOCATION_HEADER, actionURL);
            }
            return null;
          }

        } else {
          // If we work in LifeRay environment, we need only to set session-scoped parameter, that
          // current session was expired and we will process it accordingly.
          if (AjaxUtil.isAjaxRequest(context)) {
            sessionMap.put(SESSION_EXPIRATION_PROCESSING, Boolean.TRUE);
          }
        }
      }
      return viewRoot;
    }
  }
Beispiel #6
0
  private void processSessionExpirationUnderPortletsMyFaces(
      FacesContext context, UIViewRoot root, ExternalContext externalContext, Object session) {
    Object requestObject = context.getExternalContext().getRequest();

    HttpServletRequest catalinaServletRequest = null;
    try {
      Class jbossRenderRequestClass = Class.forName("org.jboss.portlet.JBossRenderRequest");
      Class abstractRequestContextClass =
          Class.forName("org.jboss.portal.portlet.impl.spi.AbstractRequestContext");

      Class requestObjectClass = requestObject.getClass();
      if (jbossRenderRequestClass.isAssignableFrom(requestObjectClass)) {
        Field requestContextField =
            requestObject
                .getClass()
                .getSuperclass()
                .getSuperclass()
                .getDeclaredField("requestContext");
        requestContextField.setAccessible(true);
        Object requestContext = requestContextField.get(requestObject);
        Class requestContextClass = requestContext.getClass();
        if (abstractRequestContextClass.isAssignableFrom(requestContextClass)) {
          Field reqField = requestContextClass.getDeclaredField("req");
          reqField.setAccessible(true);
          Object req = reqField.get(requestContext);
          if (req instanceof HttpServletRequest) {
            catalinaServletRequest = (HttpServletRequest) req;
          }
        }
      }
    } catch (ClassNotFoundException e) {
      externalContext.log(e.getMessage());
    } catch (NoSuchFieldException e) {
      externalContext.log(e.getMessage());
    } catch (IllegalAccessException e) {
      externalContext.log(e.getMessage());
    }

    if (AjaxUtil.isPortletRenderRequest(context)
        && !AjaxUtil.isAjaxRequest(context)
        && catalinaServletRequest != null
        && catalinaServletRequest.getParameterMap().size() > 0) {
      if (isNewSession(session)) {
        addAjaxRequestMarkerUnderPortlets(context, root);
        addSessionExpirationFlagUnderPortlets(context, root);
      }
    }

    if (Environment.isLiferay(context.getExternalContext().getRequestMap())) {
      if (context
          .getExternalContext()
          .getSessionMap()
          .containsKey(AjaxViewHandler.SESSION_EXPIRATION_PROCESSING)) {
        addAjaxRequestMarkerUnderPortlets(context, root);
        addSessionExpirationFlagUnderPortlets(context, root);
        context
            .getExternalContext()
            .getSessionMap()
            .remove(AjaxViewHandler.SESSION_EXPIRATION_PROCESSING);
      }
    }
  }
Beispiel #7
0
  @Override
  public void renderView(FacesContext context, UIViewRoot root) throws IOException, FacesException {
    Components.runScheduledActions();
    if (!context.getResponseComplete()) {

      ExternalContext externalContext = context.getExternalContext();
      Object session = externalContext.getSession(false);
      Map<String, Object> requestMap = externalContext.getRequestMap();

      if (externalContext.getSessionMap().containsKey(ERROR_OCCURRED_UNDER_PORTLETS)) {
        processExceptionUnderPortlets(context);
        return;
      }

      if (AjaxUtil.isPortletRequest(context)
          && Environment.isMyFaces()
          && isNewSession(externalContext.getSession(false))) {
        processSessionExpirationUnderPortletsMyFaces(context, root, externalContext, session);
      }

      if (AjaxUtil.isPortletRequest(context)
          && Environment.isRI()
          && isNewSession(externalContext.getSession(false))) {
        processSessionExpirationUnderPortletsRI(context, root, externalContext);
      }

      boolean ajaxRequest = AjaxUtil.isAjaxRequest(context);
      if (!ajaxRequest && !AjaxUtil.isAjax4jsfRequest())
        ValidationSupportResponseWriter.resetBubbleIndex(context);

      if (ajaxRequest) {
        updateSessionExpirationFlagUnderPortlets(context, root, externalContext, requestMap);
        try {
          // HACK for MyFaces ( <f:view> tag not call renderers )
          // ServletResponse response = (ServletResponse) context
          //		.getExternalContext().getResponse();
          Object response = externalContext.getResponse();

          if (!AjaxUtil.isPortletRequest(context)) {
            try {
              response.getClass().getDeclaredMethod("resetResponse").invoke(response);
              // response.reset();
            } catch (Exception e) {
              // Do nothing - we will use directly and reset
              // wrapper
            }
          }

          if (requestMap.containsKey(SESSION_EXPIRATION_PROCESSING)) {
            super.renderView(context, root);
            // This is done for MyFaces use-case, because MyFaces doesn't call rendering methods for
            // ViewRoot
            if (!Environment.isRI()) {
              root.encodeChildren(context);
            }
            Map<String, Object> sessionMap = context.getExternalContext().getSessionMap();
            if (sessionMap != null && !sessionMap.containsKey(SESSION_SCOPED_PARAMETER)) {
              sessionMap.put(SESSION_SCOPED_PARAMETER, Boolean.TRUE.toString());
            }
            return;
          }

          if (Environment.isFacelets(context)) {
            super.renderView(context, root);
          } else {
            root.encodeBegin(context);
            if (root.getRendersChildren()) {
              root.encodeChildren(context);
            }
            root.encodeEnd(context);
          }
        } catch (RuntimeException e) {
          CommonAjaxViewRoot.processExceptionDuringAjax(context, e);
          externalContext.log(e.getMessage(), e);
        } catch (Error e) {
          CommonAjaxViewRoot.processExceptionDuringAjax(context, e);
          externalContext.log(e.getMessage(), e);
        }

      } else {

        super.renderView(context, root);
        Map<String, Object> sessionMap = context.getExternalContext().getSessionMap();
        if (sessionMap != null && !sessionMap.containsKey(SESSION_SCOPED_PARAMETER)) {
          sessionMap.put(SESSION_SCOPED_PARAMETER, Boolean.TRUE.toString());
        }

        if (AjaxUtil.isAjax4jsfRequest()) {
          Resources.processHeadResources(context);
        }
      }
    }
  }