javaserverfaces-spec-public
  1. javaserverfaces-spec-public
  2. JAVASERVERFACES_SPEC_PUBLIC-787

Restore ViewScope before templates are processed with buildView

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 2.0
    • Fix Version/s: 2.2
    • Component/s: Facelets/VDL
    • Labels:
      None
    • Environment:

      Operating System: All
      Platform: All

    • Issuezilla Id:
      787
    • Status Whiteboard:
      Hide

      size_medium importance_large draft

      Show
      size_medium importance_large draft

      Description

      Restoring the view with partial state saving enabled, the state is attached to
      the component tree after the view-definition is processed (aka the tree is built
      from the template). But sometimes the application of the view-definition might
      depend on state from the previous request. An example: we have a dialog system
      which remembers across requests which dialog is active.

      So, to be backwards compatible with JSF 1.2, we need a way to store this state
      across requests - it can not be part of the component state, cause the component
      state is applied too late.

      Our solution - and also recommendation for the next version of the spec - is
      that the ViewScope (or the complete state of the ViewRoot component, but
      ViewScope is sufficient) is restored before buildView() is called. That would
      allow components with dynamic behavior to keep state in the ViewScope.

      best regards,

      Martin and Hanspeter

      =====================

      Here what we do currently: we decorated ViewDeclarationLanguage.buildView like
      this (ok, for simplification we restored complete ViewRoot state):

      public void buildView(FacesContext context, UIViewRoot root) throws
      IOException {

      if(context.getCurrentPhaseId()== PhaseId.RESTORE_VIEW)

      { //restore the view-scope (part of the UIViewRoot state-saving process) //_before_ we run the templates RenderKit renderKit = context.getRenderKit(); ResponseStateManager rsm = renderKit.getResponseStateManager(); Object[] rawState = (Object[]) rsm.getState(context, root.getViewId()); //noinspection unchecked final Map<String, Object> state = (Map<String,Object>) rawState[1]; Object viewRootState = state.get(root.getClientId()); root.restoreState(context, viewRootState); }

      delegate.buildView(context, root);
      }

      1. changebundle.txt
        6 kB
        Ed Burns
      2. changebundle.txt
        7 kB
        Hanspeter Duennenberger
      3. changebundle-787-workaround.txt
        2 kB
        rogerk
      4. JAVASERVERFACES_SPEC_PUBLIC-787-restore-ViewScope-before-buildView.patch
        6 kB
        Hanspeter Duennenberger

        Issue Links

          Activity

          Hide
          fabmars added a comment -

          UIViewRoot#restoreViewScopeState isn't called from anywhere anymore.

          Probably this has to do with the big rework/split of StateManagementStrategyImpl in http://java.net/jira/browse/JAVASERVERFACES-2373

          Show
          fabmars added a comment - UIViewRoot#restoreViewScopeState isn't called from anywhere anymore. Probably this has to do with the big rework/split of StateManagementStrategyImpl in http://java.net/jira/browse/JAVASERVERFACES-2373
          Hide
          Hanspeter Duennenberger added a comment -

          After looking at the code on trunk I think UIViewRoot#restoreViewScopeState is no longer needed since ViewScope is now kept on session and only the viewScopeId becomes part of the View's state.
          This last change came from http://java.net/jira/browse/JAVASERVERFACES-2561 and completely makes sense - only think remaining - the UIViewRoot#restoreViewScopeState method could be removed or at least made deprecated.

          Show
          Hanspeter Duennenberger added a comment - After looking at the code on trunk I think UIViewRoot#restoreViewScopeState is no longer needed since ViewScope is now kept on session and only the viewScopeId becomes part of the View's state. This last change came from http://java.net/jira/browse/JAVASERVERFACES-2561 and completely makes sense - only think remaining - the UIViewRoot#restoreViewScopeState method could be removed or at least made deprecated.
          Hide
          lu4242 added a comment -

          I think UIViewRoot#restoreViewScopeState still has a lot of sense, and should not be marked as deprecated or removed, because it enforces the condition of restore the view scope state before restore the view state. If a side effect of ViewScope implementation is make this method not necessary, does not means that the method is not valid for other alternate implementations of ViewScope. In other words, it is not a good idea to rely on a implementation detail for something that should be enforced by spec.

          Show
          lu4242 added a comment - I think UIViewRoot#restoreViewScopeState still has a lot of sense, and should not be marked as deprecated or removed, because it enforces the condition of restore the view scope state before restore the view state. If a side effect of ViewScope implementation is make this method not necessary, does not means that the method is not valid for other alternate implementations of ViewScope. In other words, it is not a good idea to rely on a implementation detail for something that should be enforced by spec.
          Hide
          Hanspeter Duennenberger added a comment -

          Hi Leonardo,
          you are right about the spec aspect. On the other hand there is no counterpart like saveViewScopeState() to complete the state handling for ViewScope. Also with support for CDI or other Scope Managers these methods might not really fit.
          Currently it seems this restoreViewScopeState() method is a relict because it's never ever called in JSF RI.
          That is what needs to be resolved - I don't mind if this method is no longer used as long as the handling of ViewScope is clearly specified - at least the fact that ViewScope must be present before buidView() is called. I just don't know now if that is still specified.
          Best regards
          Hanspeter

          Show
          Hanspeter Duennenberger added a comment - Hi Leonardo, you are right about the spec aspect. On the other hand there is no counterpart like saveViewScopeState() to complete the state handling for ViewScope. Also with support for CDI or other Scope Managers these methods might not really fit. Currently it seems this restoreViewScopeState() method is a relict because it's never ever called in JSF RI. That is what needs to be resolved - I don't mind if this method is no longer used as long as the handling of ViewScope is clearly specified - at least the fact that ViewScope must be present before buidView() is called. I just don't know now if that is still specified. Best regards Hanspeter
          Hide
          lu4242 added a comment -

          Hi Hanspeter

          Ok, I see. It is clear restoreViewScopeState() is necessary for jsf 2.0 view scope, because in this case, JSF stores the view scope with the view state, but the question is how is really handle scopes in CDI, or in other words, how CDI recognize a specific "context". For example, how CDI knows that a view scope is for an specific bean. Does it uses the viewId? a combination of the windowId/viewId? a generated identifier stored in UIViewRoot?. In my understanding, MyFaces CODI/Openwebbeans uses a combination of the windowId/viewId.

          In my opinion, the flaw in the spec and the reason of the discussion over restoreViewScopeState() is more related to how JSF defines a "view context" and expose that information to the external context like CDI-JSF integration module or any other bean container. In the current design, CDI is responsible to handle the beans and all issues related to them (injection, serialization, ...), so JSF should not do operation to save / restore bean stated directly, and instead let CDI to do its magic under curtains.

          So, what has sense here is enforce that any view scope or the "view context" should be defined before restore the view state, which means in PSS context, call vdl.buildView and apply the state to the created component tree.

          In theory restoreViewScopeState() is not implemented directly by UIViewRoot, but it has sense to override UIViewRoot and implement it cases like portlets or even with plain CDI, because this method gives the chance to initialize the context properly, no matter which trick is used to define the "view context".

          Note I don't know the details behind CDI-JSF integration, but with the current spec, I suppose/guess the intention is do something like that.

          best regards,
          Leonardo

          Show
          lu4242 added a comment - Hi Hanspeter Ok, I see. It is clear restoreViewScopeState() is necessary for jsf 2.0 view scope, because in this case, JSF stores the view scope with the view state, but the question is how is really handle scopes in CDI, or in other words, how CDI recognize a specific "context". For example, how CDI knows that a view scope is for an specific bean. Does it uses the viewId? a combination of the windowId/viewId? a generated identifier stored in UIViewRoot?. In my understanding, MyFaces CODI/Openwebbeans uses a combination of the windowId/viewId. In my opinion, the flaw in the spec and the reason of the discussion over restoreViewScopeState() is more related to how JSF defines a "view context" and expose that information to the external context like CDI-JSF integration module or any other bean container. In the current design, CDI is responsible to handle the beans and all issues related to them (injection, serialization, ...), so JSF should not do operation to save / restore bean stated directly, and instead let CDI to do its magic under curtains. So, what has sense here is enforce that any view scope or the "view context" should be defined before restore the view state, which means in PSS context, call vdl.buildView and apply the state to the created component tree. In theory restoreViewScopeState() is not implemented directly by UIViewRoot, but it has sense to override UIViewRoot and implement it cases like portlets or even with plain CDI, because this method gives the chance to initialize the context properly, no matter which trick is used to define the "view context". Note I don't know the details behind CDI-JSF integration, but with the current spec, I suppose/guess the intention is do something like that. best regards, Leonardo

            People

            • Assignee:
              Hanspeter Duennenberger
              Reporter:
              Hanspeter Duennenberger
            • Votes:
              2 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: