public UIViewRoot restoreView()

in trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java [652:865]


  public UIViewRoot restoreView(
    FacesContext context,
    String       viewId,
    String       renderKitId)
  {
    final ExternalContext extContext = context.getExternalContext();

    // If we're being asked to execute a "return" event from, say, a dialog, always
    // restore the "launch view", which was set over in the TrinidadFilter.

    Map<String, Object> requestMap = extContext.getRequestMap();
    UIViewRoot launchView = (UIViewRoot)
                            requestMap.remove(RequestContextImpl.LAUNCH_VIEW);
    if (launchView != null)
    {
      TrinidadPhaseListener.markPostback(context);
      return launchView;
    }

    final Object structure;
    final Object state;

    ResponseStateManager rsm = _getResponseStateManager(context, renderKitId);

    if (_saveAsToken(context, true))
    {
      // we saved the token in the structure portion of the state, so retrieve the
      // structure portion of the state to get the token.
      String token = (String)rsm.getTreeStructureToRestore(context, viewId);
      if (token == null)
      {
        _LOG.finest("No token in the request for view \"{0}\";  probably a first view.", viewId);
        return null;
      }

      _LOG.finer("Restoring saved view state for token {0}", token);

      // get the PageState for the token
      PageState viewState = _getPageState(extContext, token);

      if (viewState != null)
        _updateRequestTokenForResponse(context, token);

      RequestContext trinContext = RequestContext.getCurrentInstance();

      // Make sure that if the view state is present, the cache still
      // has the token, and vice versa

      // NOTE: it's very important that we call through to the
      // token cache here, not just inside the assert.  If we don't,
      // then we don't actually access the token, so it doesn't
      // get bumped up to the front in the LRU Cache!
      boolean isAvailable = _getViewCache(trinContext, extContext).isAvailable((String) token);
      assert ((viewState != null) == isAvailable);
      
      if (viewState == null)
      {
        _LOG.severe("CANNOT_FIND_SAVED_VIEW_STATE", token);

        if(TokenCacheDebugUtils.debugTokenCache())
        {

          TokenCacheDebugUtils.startLog("Restore View");
          
          String sessionId = "";
          boolean isNewSession = false;
          Object session = extContext.getSession(false);
          
          if (session == null)
          {
            isNewSession = true;
          }
          else if (session instanceof HttpSession)
          {
            isNewSession = ((HttpSession)session).isNew();            
            sessionId    = ((HttpSession)session).getId();
          }
          
          if (isNewSession)
          {
            TokenCacheDebugUtils.addToLog("The session is new. Session id = " + sessionId);
          }
          else
          {      
            TokenCacheDebugUtils.addToLog("The session is NOT new. Session id = " + sessionId);
          }
          
          // get the state map
          String subkey = _getViewCacheKey(extContext,
                                           RequestContext.getCurrentInstance(),
                                           _SUBKEY_SEPARATOR);

          Map<String, PageState> stateMap = new SubKeyMap<PageState>(
                           extContext.getSessionMap(),
                           subkey);
          
          // log what's currently in the state map
          TokenCacheDebugUtils.logCacheInfo(stateMap, null, "token '" + token + "' not found"); 
          _LOG.severe(TokenCacheDebugUtils.getLogString());        
        }
        
        return null;
      }

      _LOG.fine("Successfully found view state for token {0}", token);

      UIViewRoot root = viewState.popRoot(context); // bug 4712492
      if (root != null)
      {
        _LOG.finer("UIViewRoot for token {0} already exists. Bypassing restoreState", token);
        return root;
      }

      StateManagementStrategy sms = _getStateManagementStrategy(context, viewId);

      if (sms!= null)
      {
        // TODO This is a hack because stateManagementStrategy doesn't take
        // a state object as a param, instead it always asks the responseStateManager
        // for the state, so push the state onto the request where the CoreResponseStateManager
        // can return it. We will file a bug agains JSF 2.0 asking that the
        // stateManagementStrategy deprecate the current restoreView method in favor of
        // a restoreView method that takes state
        try
        {
          requestMap.put(RESPONSE_STATE_MANAGER_STATE_KEY, viewState.getViewState(context));
          root = sms.restoreView(context, viewId, renderKitId);
        }
        finally
        {
          requestMap.remove(RESPONSE_STATE_MANAGER_STATE_KEY);
        }

        return root;
      }
      else
      {
        Object[] stateArray = (Object[])viewState.getViewState(context);
        structure = stateArray[0];
        state = stateArray[1];
      }
    }
    else
    {

      StateManagementStrategy sms = _getStateManagementStrategy(context, viewId);

      if (sms!= null)
      {
        return sms.restoreView(context, viewId, renderKitId);
      }

      Object[] stateArray = (Object[])rsm.getState(context, viewId);
      structure = stateArray[0];
      state = stateArray[1];
    }


    if (structure == null)
    {

      UIViewRoot root = context.getViewRoot();
      if (root == null && _needStructure(context))
      {
        _LOG.severe("NO_STRUCTURE_ROOT_AVAILABLE");
        return null;
      }

      if (state != null)
        root.processRestoreState(context, state);

      return root;
    }
    else
    {
      if (!(structure instanceof Structure))
      {
        _LOG.severe("NO_STRUCTURE_AVAILABLE");
        return null;
      }

      // OK, we've structure and state; let's see what we can do!
      try
      {
        UIViewRoot root = (UIViewRoot)
        ((Structure) structure).createComponent();

        if (state != null)
        {
          if (context.getViewRoot() == null)
          {
            context.setViewRoot(root);
          }
          root.processRestoreState(context, state);
        }
        _LOG.finer("Restored state for view \"{0}\"", viewId);
        return root;
      }
      catch (ClassNotFoundException cnfe)
      {
        _LOG.severe(cnfe);
      }
      catch (InstantiationException ie)
      {
        _LOG.severe(ie);
      }
      catch (IllegalAccessException iae)
      {
        _LOG.severe(iae);
      }
    }

    return null;
  }