示例#1
0
  /**
   * Inspects the incoming request parameters for the standardized state parameter name. In this
   * case, the parameter value will be the composite ID generated by
   * ServerSideStateHelper#writeState(FacesContext, Object, StringBuilder).
   *
   * <p>The composite key will be used to find the appropriate view within the session obtained from
   * the provided <code>FacesContext</code>
   */
  public Object getState(FacesContext ctx, String viewId) {

    String compoundId = getStateParamValue(ctx);

    if (compoundId == null) {
      return null;
    }

    if ("stateless".equals(compoundId)) {
      return "stateless";
    }

    int sep = compoundId.indexOf(':');
    assert (sep != -1);
    assert (sep < compoundId.length());

    String idInLogicalMap = compoundId.substring(0, sep);
    String idInActualMap = compoundId.substring(sep + 1);

    ExternalContext externalCtx = ctx.getExternalContext();
    Object sessionObj = externalCtx.getSession(false);

    // stop evaluating if the session is not available
    if (sessionObj == null) {
      if (LOGGER.isLoggable(Level.FINE)) {
        LOGGER.log(
            Level.FINE,
            "Unable to restore server side state for view ID {0} as no session is available",
            viewId);
      }
      return null;
    }

    //noinspection SynchronizationOnLocalVariableOrMethodParameter
    synchronized (sessionObj) {
      Map logicalMap = (Map) externalCtx.getSessionMap().get(LOGICAL_VIEW_MAP);
      if (logicalMap != null) {
        Map actualMap = (Map) logicalMap.get(idInLogicalMap);
        if (actualMap != null) {
          RequestStateManager.set(ctx, RequestStateManager.LOGICAL_VIEW_MAP, idInLogicalMap);
          Object[] state = (Object[]) actualMap.get(idInActualMap);
          Object[] restoredState = new Object[2];

          restoredState[0] = state[0];
          restoredState[1] = state[1];

          if (state != null) {
            RequestStateManager.set(ctx, RequestStateManager.ACTUAL_VIEW_MAP, idInActualMap);
            if (state.length == 2 && state[1] != null) {
              restoredState[1] = handleRestoreState(state[1]);
            }
          }

          return restoredState;
        }
      }
    }

    return null;
  }
  //
  // Methods from FacesContextFactory
  //
  public FacesContext getFacesContext(
      Object sc, Object request, Object response, Lifecycle lifecycle) throws FacesException {

    try {
      Util.parameterNonNull(sc);
      Util.parameterNonNull(request);
      Util.parameterNonNull(response);
      Util.parameterNonNull(lifecycle);
    } catch (Exception e) {
      throw new NullPointerException(
          MessageUtils.getExceptionMessageString(
              MessageUtils.FACES_CONTEXT_CONSTRUCTION_ERROR_MESSAGE_ID));
    }
    FacesContext ctx =
        new FacesContextImpl(
            new ExternalContextImpl(
                (ServletContext) sc, (ServletRequest) request, (ServletResponse) response),
            lifecycle);
    // store the default FacesContext and ExternalContext implementations
    // in the request so that the API can delegate if the happen to be
    // decorated by 1.1 implementations
    RequestStateManager.set(ctx, RequestStateManager.FACESCONTEXT_IMPL_ATTR_NAME, ctx);
    RequestStateManager.set(
        ctx, RequestStateManager.EXTERNALCONTEXT_IMPL_ATTR_NAME, ctx.getExternalContext());
    return ctx;
  }
示例#3
0
  /**
   * Obtain and return the {@link ResponseStateManager} for the specified #renderKitId.
   *
   * @param context the {@link FacesContext} of the current request
   * @param renderKitId {@link RenderKit} ID
   * @return the {@link ResponseStateManager} for the specified #renderKitId
   * @throws FacesException if an exception occurs while trying to obtain the <code>
   *     ResponseStateManager</code>
   */
  public static ResponseStateManager getResponseStateManager(
      FacesContext context, String renderKitId) throws FacesException {

    assert (null != renderKitId);
    assert (null != context);

    RenderKit renderKit = context.getRenderKit();
    if (renderKit == null) {
      // check request scope for a RenderKitFactory implementation
      RenderKitFactory factory =
          (RenderKitFactory)
              RequestStateManager.get(context, RequestStateManager.RENDER_KIT_IMPL_REQ);
      if (factory != null) {
        renderKit = factory.getRenderKit(context, renderKitId);
      } else {
        factory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
        if (factory == null) {
          throw new IllegalStateException();
        } else {
          RequestStateManager.set(context, RequestStateManager.RENDER_KIT_IMPL_REQ, factory);
        }
        renderKit = factory.getRenderKit(context, renderKitId);
      }
    }
    return renderKit.getResponseStateManager();
  }
示例#4
0
  /**
   * Build the view.
   *
   * @param ctx the {@link FacesContext} for the current request
   * @param view the {@link UIViewRoot} to populate based of the Facelet template
   * @throws IOException if an error occurs building the view.
   */
  @Override
  public void buildView(FacesContext ctx, UIViewRoot view) throws IOException {

    if (Util.isViewPopulated(ctx, view)) {
      return;
    }
    updateStateSavingType(ctx, view.getViewId());
    view.setViewId(view.getViewId());

    if (LOGGER.isLoggable(Level.FINE)) {
      LOGGER.fine("Building View: " + view.getViewId());
    }
    if (faceletFactory == null) {
      ApplicationAssociate associate = ApplicationAssociate.getInstance(ctx.getExternalContext());
      faceletFactory = associate.getFaceletFactory();
      assert (faceletFactory != null);
    }
    RequestStateManager.set(ctx, RequestStateManager.FACELET_FACTORY, faceletFactory);
    Facelet f = faceletFactory.getFacelet(view.getViewId());

    // populate UIViewRoot
    f.apply(ctx, view);
    doPostBuildActions(view);
    Util.setViewPopulated(ctx, view);
  }
示例#5
0
  /**
   * @return Stack of UIComponentClassicTagBase instances, each of which is a "view" tag. The bottom
   *     most element on the stack is the ViewTag itself. Subsequent instances are SubviewTag
   *     instances.
   */
  static Stack<UIComponentClassicTagBase> getViewTagStack() {

    FacesContext ctx = FacesContext.getCurrentInstance();
    //noinspection unchecked
    Stack<UIComponentClassicTagBase> result =
        (Stack<UIComponentClassicTagBase>)
            RequestStateManager.get(ctx, RequestStateManager.VIEWTAG_STACK_ATTR_NAME);
    if (result == null) {
      result = new Stack<UIComponentClassicTagBase>();
      RequestStateManager.set(ctx, RequestStateManager.VIEWTAG_STACK_ATTR_NAME, result);
    }

    return result;
  }
示例#6
0
  /**
   * @see {@link javax.faces.render.ResponseStateManager#getState(javax.faces.context.FacesContext,
   *     String)}
   */
  @Override
  public Object getState(FacesContext context, String viewId) {

    Object state = RequestStateManager.get(context, RequestStateManager.FACES_VIEW_STATE);
    if (state == null) {
      try {
        state = helper.getState(context, viewId);
        if (state != null) {
          RequestStateManager.set(context, RequestStateManager.FACES_VIEW_STATE, state);
        }
      } catch (IOException e) {
        throw new FacesException(e);
      }
    }
    return state;
  }
示例#7
0
  public void execute(FacesContext facesContext) throws FacesException {

    if (LOGGER.isLoggable(Level.FINE)) {
      LOGGER.fine("Entering RenderResponsePhase");
    }
    if (LOGGER.isLoggable(Level.FINE)) {
      LOGGER.fine("About to render view " + facesContext.getViewRoot().getViewId());
    }
    // For requests intended to produce a partial response, we need prohibit
    // writing any content outside of the view itself (f:view).
    if (facesContext.isAjaxRequest()) {
      facesContext.enableResponseWriting(false);
    }

    try {
      // Setup message display LOGGER.
      if (LOGGER.isLoggable(Level.INFO)) {
        Iterator<String> clientIdIter = facesContext.getClientIdsWithMessages();

        // If Messages are queued
        if (clientIdIter.hasNext()) {
          Set<String> clientIds = new HashSet<String>();

          // Copy client ids to set of clientIds pending display.
          while (clientIdIter.hasNext()) {
            clientIds.add(clientIdIter.next());
          }
          RequestStateManager.set(
              facesContext, RequestStateManager.CLIENT_ID_MESSAGES_NOT_DISPLAYED, clientIds);
        }
      }

      // render the view
      facesContext
          .getApplication()
          .getViewHandler()
          .renderView(facesContext, facesContext.getViewRoot());

      // display results of message display LOGGER
      if (LOGGER.isLoggable(Level.INFO)
          && RequestStateManager.containsKey(
              facesContext, RequestStateManager.CLIENT_ID_MESSAGES_NOT_DISPLAYED)) {

        // remove so Set does not get modified when displaying messages.
        Set<String> clientIds =
            TypedCollections.dynamicallyCastSet(
                (Set)
                    RequestStateManager.remove(
                        facesContext, RequestStateManager.CLIENT_ID_MESSAGES_NOT_DISPLAYED),
                String.class);
        if (!clientIds.isEmpty()) {

          // Display each message possibly not displayed.
          StringBuilder builder = new StringBuilder();
          for (String clientId : clientIds) {
            Iterator<FacesMessage> messages = facesContext.getMessages(clientId);
            while (messages.hasNext()) {
              FacesMessage message = messages.next();
              builder.append("\n");
              builder.append("sourceId=").append(clientId);
              builder.append("[severity=(").append(message.getSeverity());
              builder.append("), summary=(").append(message.getSummary());
              builder.append("), detail=(").append(message.getDetail()).append(")]");
            }
          }
          LOGGER.log(Level.INFO, "jsf.non_displayed_message", builder.toString());
        }
      }
    } catch (IOException e) {
      throw new FacesException(e.getMessage(), e);
    }

    if (LOGGER.isLoggable(Level.FINEST)) {
      LOGGER.log(
          Level.FINEST,
          "+=+=+=+=+=+= View structure printout for " + facesContext.getViewRoot().getViewId());
      DebugUtil.printTree(facesContext.getViewRoot(), LOGGER, Level.FINEST);
    }

    if (LOGGER.isLoggable(Level.FINE)) {
      LOGGER.fine("Exiting RenderResponsePhase");
    }
  }
示例#8
0
  /**
   * Execute the target view. If the HTTP status code range is not 2xx, then return true to indicate
   * the response should be immediately flushed by the caller so that conditions such as 404 are
   * properly handled.
   *
   * @param context the <code>FacesContext</code> for the current request
   * @param viewToExecute the view to build
   * @return <code>true</code> if the response should be immediately flushed to the client,
   *     otherwise <code>false</code>
   * @throws java.io.IOException if an error occurs executing the page
   */
  private boolean executePageToBuildView(FacesContext context, UIViewRoot viewToExecute)
      throws IOException {

    if (null == context) {
      String message =
          MessageUtils.getExceptionMessageString(
              MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "context");
      throw new NullPointerException(message);
    }
    if (null == viewToExecute) {
      String message =
          MessageUtils.getExceptionMessageString(
              MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "viewToExecute");
      throw new NullPointerException(message);
    }

    ExternalContext extContext = context.getExternalContext();

    if ("/*".equals(RequestStateManager.get(context, RequestStateManager.INVOCATION_PATH))) {
      throw new FacesException(
          MessageUtils.getExceptionMessageString(MessageUtils.FACES_SERVLET_MAPPING_INCORRECT_ID));
    }

    String requestURI = viewToExecute.getViewId();

    if (LOGGER.isLoggable(Level.FINE)) {
      LOGGER.fine("About to execute view " + requestURI);
    }

    // update the JSTL locale attribute in request scope so that JSTL
    // picks up the locale from viewRoot. This attribute must be updated
    // before the JSTL setBundle tag is called because that is when the
    // new LocalizationContext object is created based on the locale.
    if (extContext.getRequest() instanceof ServletRequest) {
      Config.set(
          (ServletRequest) extContext.getRequest(),
          Config.FMT_LOCALE,
          context.getViewRoot().getLocale());
    }
    if (LOGGER.isLoggable(Level.FINE)) {
      LOGGER.fine("Before dispacthMessage to viewId " + requestURI);
    }

    // save the original response
    Object originalResponse = extContext.getResponse();

    // replace the response with our wrapper
    ViewHandlerResponseWrapper wrapped = getWrapper(extContext);
    extContext.setResponse(wrapped);

    try {

      // build the view by executing the page
      extContext.dispatch(requestURI);

      if (LOGGER.isLoggable(Level.FINE)) {
        LOGGER.fine("After dispacthMessage to viewId " + requestURI);
      }
    } finally {
      // replace the original response
      extContext.setResponse(originalResponse);
    }

    // Follow the JSTL 1.2 spec, section 7.4,
    // on handling status codes on a forward
    if (wrapped.getStatus() < 200 || wrapped.getStatus() > 299) {
      // flush the contents of the wrapper to the response
      // this is necessary as the user may be using a custom
      // error page - this content should be propagated
      wrapped.flushContentToWrappedResponse();
      return true;
    }

    // Put the AFTER_VIEW_CONTENT into request scope
    // temporarily
    RequestStateManager.set(context, RequestStateManager.AFTER_VIEW_CONTENT, wrapped);

    return false;
  }