MyFaces Trinidad
  1. MyFaces Trinidad
  2. TRINIDAD-1368

Backport JSF 2.0 Component Tree Visiting and Optimize PPR Rendering

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.2.10-core
    • Fix Version/s: 1.2.13-core
    • Component/s: None
    • Labels:
      None

      Description

      JSF 2.0 will add the ability for applications to visit all or a subset of the components in the component Tree in context using a visitTree function in a similar manner to how invokeOnComponent works with the following improvements:

      1) For a single component, visitTree is faster than invokeOnComponent because visitTree avoids most calls to getClientId() on the traversed components

      2) For multiple components, visitTree can visit all of the components in a single pass, avoiding replicating the work to setup and teardown the component contexts when visiting. In addition, visitTree guarantees the relative ordering of the component visits

      3) visitTree supports optionally skipping non-rendered components, matching the visiting behavior of the JSF phases.

      4) visitTree supports components and renderers that set up different or additional context when visiting during the encoding phase

      With a few improvements, this visitation scheme can be extended to support optimizing partial page rendering. Trinidad currently implements partial apge rendering by performing a full render of the component tree (with optimizations for NamingContainers with no targets) and discarding the results of the content outside of the partial targets. This is inefficient because the unrendered components still generate their markup, more expensively, they continue to evaluate the EL and execute the models necessary to generate that content. Thus, on a large complicated page, it is not especially faster (on the server) to render a small portion of the page than a large portion (with the exception of the NamingContainer optimization which does typically avoid executing tables). This limitation is one of the main performance issues with PPR (the other is the need to re-execute the JSP in JSP environments)

      1. JIRA_1368_12101.patch
        135 kB
        Blake Sullivan
      2. JIRA_1368_More_Traversal_1_2_12_2.patch
        95 kB
        Blake Sullivan
      3. JIRA_1368_More_Traversal_Trunk.patch
        94 kB
        Blake Sullivan
      4. TRINIDAD-1368.trunk.diff
        13 kB
        Andrew Robinson
      5. visit.zip
        7 kB
        Blake Sullivan

        Issue Links

          Activity

          Blake Sullivan created issue -
          Hide
          Blake Sullivan added a comment -

          Patch to 1.2.10.1

          Since the aptch file can't contain new files, place the contents of visit.zip relative to org.apache.myfaces.trinidad.api.component

          For now PPR Optimization is controlled by two internal flags:
          org.apache.myfaces.trinidadinternal.ENABLE_PPR_OPTIMIZATION (default is false for now)
          is a servlet initialization parameter that controls whether we ever attempt to use optimized

          PPR. The default is temporarily false to ensure no regressions. This flag will eventually be removed.

          org.apache.myfaces.trinidadinternal.DISABLE_PPR_OPTIMIZATION is an ApplicationMap property

          (default false), for turning off PPR Optimization once turned on by the servlet initialization

          parameter. This property can be used to temporarily turn off PPR optimization when debugging to determine whether a bug was caused by PPR Optimization.

          Work done:

          org.apache.myfaces.trinidad.component.visit package

          /**
          *

          • <p>A simple callback interface that enables
          • taking action on a specific UIComponent (either facet or child) during
          • a component tree visit.</p>
            *
          • @see org.apache.myfaces.trinidad.component.UIXComponent#visitTree UIComponent.visitTree()
            */
            public interface VisitCallback

          /**
          *

          • <p>A context object that is used to hold
          • state relating to a component tree visit.</p>
            *
          • <p>Component tree visits are initiated by calling
          • {@link org.apache.myfaces.trinidad.component.UIXComponent#visitTree UIComponent.visitTree ()},
            * at which point both a {@link VisitContext} and a {@link VisitCallback}
            * must be provided.
            *
            * @see org.apache.myfaces.trinidad.component.UIXComponent#visitTree UIXComponent.visitTree()
            * @see VisitCallback
            *
            */
            abstract public class VisitContext

            /**
            *
            * <p>An enum that specifies the possible
            * results of a call to {@link VisitCallback#visit VisitCallback.visit()}.
            * </p>
            *
            * @see VisitCallback#visit VisitCallback.visit()
            */
            public enum VisitResult


            /**
            *
            * <p>An enum that specifies hints that impact
            * the behavior of a component tree visit.</p>
            *
            * @see VisitContext#getHints VisitContext.getHints()
            */
            public enum VisitHint



            UIXComponent add support for visiting the UIComponent tree in context, using a similar approach to that proposed for JSF 2.0. Compared to calls to invokeOnComponent, visiting has the

            following advantages:
            1) For a single component, visitTree is faster than invokeOnComponent because visitTree avoids most calls to getClientId() on the traversed components

            2) For multiple components, visitTree can visit all of the components in a single pass, avoiding replicating the work to setup and teardown the component contexts when visiting. In addition, visitTree guarantees the relative ordering of the component visits

            3) visitTree supports optionally skipping non-rendered components, matching the visiting behavior of the JSF phases.

            4) visitTree supports components and renderers that set up different or additional context when visiting during the encoding phaseTo support component (and Renderer) control over visitation during encoding, partialEncodeVisit, which is called during visits during the encoding phase was also added.

            The context setup for tree visitation is shared with invokeOnComponent by adding new protected methods UIXComponent.setupVisitingContext() and tearDownVisitingContext() as the location for placing the context setup and teardown code. UiXComponentBase.invokeOnComponent() now calls these methods from its invokeOnComponent() override.

            /**
            * <p>Perform a tree visit starting at
            * this node in the tree.</p>
            *
            * <p>UIXComponent.visitTree() implementations do not invoke the
            * {@code VisitCallback} directly, but instead call
            * {@code VisitContext.invokeVisitCallback()} to invoke the
            * callback. This allows {@code VisitContext} implementations
            * to provide optimized tree traversals, for example by only
            * calling the {@code VisitCallback} for a subset of components.</p>
            *
            * @param visitContext the <code>VisitContext</code> for this visit
            * @param callback the <code>VisitCallback</code> instance
            * whose <code>visit</code> method will be called
            * for each node visited.
            * @return component implementations may return <code>true</code>
            * to indicate that the tree visit is complete (eg. all components
            * that need to be visited have been visited). This results in
            * the tree visit being short-circuited such that no more components
            * are visited.
            *
            * @see VisitContext#invokeVisitCallback VisitContext.invokeVisitCallback()
            */
            public boolean visitTree(
            VisitContext visitContext,
            VisitCallback callback)


            UIXComponentBase:

            Override invokeOnComponent() to call setupVisitingContext() and tearDownVisitingContext() and to not call super.invokeOnComponent() (in order to avoid an unnecessary call to getClientId()).

            Add protected convenience functions invokeOnNamingContainerComponent() and invokeOnChildrenComponents() to make it easier for subclasses to implement invokeOnComponent

            optimally.

            CoreRenderer:

            Add:

            /**
            * <p>
            * Called when visiting the CoreRenderer's component during optimized partial page encoding

            so
            * that the CoreRenderer can modify what is actually encoded. For example tab controls often
            * render the tabs for the ShowDetailItems in the tab bar before delegating to the
            * disclosed ShowDetailItem to render the tab content. As a result, the tab control
            * needs to encode its tab bar if any of its ShowDetailItems are partial targets so that
            * the tab labels, for example, are up-to-date.
            * </p>
            * <p>
            * The default implementation calls the VisitCallback and returns its result if this

            UIXComponent
            * is a partial target of the current encoding.
            * </p>
            * @param visitContext VisitContext to pass to the VisitCallback
            * @param partialContext PartialPageContext for the current partial encoding
            * @param component The component for the CoreRenderer to visit
            * @param callback VisitCallback to call if this component is a partial target
            * @return The VisitResult controlling continued iteration of the visit.
            */
            public VisitResult partialEncodeVisit(
            VisitContext visitContext,
            PartialPageContext partialContext,
            UIComponent component,
            VisitCallback callback)

            /**
            * <p>
            * Called before rendering the current component's children in order to set
            * up any special context.
            * </p>
            * <p>If <code>setupEncodingContext</code> succeeds then
            * <code>tearDownEncodingContext</code> will be called for the same component.
            * </p>
            * <p>The default implementation does nothing</p>
            * @param context FacesContext for this request
            * @param rc RenderingContext for this encoding pass
            * @ param component Component to encode using this Renderer
            * @see #tearDownEncodingContext
            */
            public void setupEncodingContext(
            FacesContext context,
            RenderingContext rc,
            UIXComponent component)

            /**
            * <p>
            * Called after rendering the current component's children in order to tear
            * down any special context.
            * </p>
            * <p>
            * <code>tearDownEncodingContext</code> will be called on the component if
            * <code>setupEncodingContext</code> succeeded.
            * </p>
            * <p>The default implementation does nothing</p>
            * @param context FacesContext for this request
            * @param rc RenderingContext for this encoding pass
            * @ param component Component to encode using this Renderer
            * @see #setupEncodingContext
            */
            public void tearDownEncodingContext(
            FacesContext context,
            RenderingContext rc,
            UIXComponent component)

            The default implementations of beforeEncode() and afterEncode() have been changed to call setUpEncodingContext() and tearDownEncodingContext() respectively for backwards compatibility.


            PartialPageContext:

            Add new methods:

            abstract public boolean isPossiblePartialTarget(String componentId);

            As an optimization for checking whether a componentId is the suffix of a clientId to be rendered

            and

            public abstract boolean areAllTargetsProcessed();

            Which returns true when all of the request partial targets have been encoded.

            and

            abstract public VisitContext getVisitContext();

            Returning a VisitContext that can be used for visiting the components to be

            RequestContext:

            Add factory support for creating VisitContexts:


            /**
            * <p>Creates a VisitContext instance for use with
            * {@link org.apache.myfaces.trinidad.component.UIXComponent#visitTree UIComponent.visitTree ()}

            .</p>
            *

          • @param context the FacesContext for the current request
          • @param ids the client ids of the components to visit. If null,
          • all components will be visited.
          • @param hints the VisitHints to apply to the visit
          • @param phaseId. PhaseId if any for this visit. If PhaseId is specified,
          • hints must contain VisitHint.EXECUTE_LIFECYCLE
          • @return a VisitContext instance that is initialized with the
          • specified ids and hints.
            */
            public abstract VisitContext createVisitContext(
            FacesContext context,
            Collection<String> ids,
            Set<VisitHint> hints,
            PhaseId phaseId);

          Unlike the JSF 2.0 version, this optionally takes the phaseId as a parameter as the current

          phase isn't easily accessible in JSF 1.2.

          Other work:

          Add missing utilities to CollectionUtils for:

          1) Converting an Iterator to an ArrayList
          2) Creating an empty queue
          3) Getting an empty Iterator
          4) Getting an empty ListIterator

          CoreRenderingContext:

          Add getFacesContext() and getRequestContext() to avoid hammering the ThreadLocals

          PartialPageUtils:

          Add function controlling whether OptimizedPPR is currently enabled for this request in order to

          abstract the implementation of the temporary controls for enabling this feature from the
          rendering code.

          /**

          • Returns <code>true</code> if optimized PPR is enabled for this request
          • @return
            */
            public static boolean isOptimizedPPREnabled(FacesContext context, boolean checkIsPPR)

          PartialPageContextImpl:

          Implement:
          public boolean isPossiblePartialTarget(String componentId)
          public boolean areAllTargetsProcessed()
          public VisitContext getVisitContext()

          Provide an internal implementation of VisitContext used for optimised PPR rendering ensuring a

          single source of truth by delegating back to the PartialPageContext so that additions to the

          PartialPageContext's partial targets are reflected in the set of visited components

          PanelPartialRootRenderer:

          Perform the optimized partial render when Optimized PPR is enabled.

          RequestContextImpl:

          Implement

          public VisitContext createVisitContext(
          FacesContext context,
          Collection<String> ids,
          Set<VisitHint> hints,
          PhaseId phaseId)

          using new internal classes FullVisitContext and PartialVisitContext to handle the cases where

          either all of the components in the component tree should be visited, or only the specified

          components should be visited.

          FormRenderer

          Handle rendering the state hidden form field as well as validation javascript and other
          hidden form fields when OptimizedPPR is enabled.

          MRequestContextImpl:

          Provide stub implementation of createVisitContext()

          UIXComponentRefTemplate
          UIXDecorateCollectionTemplate
          UIXMenuTemplate
          UIXSubformTemplate

          Use invokeOnNamingContainer as the invokeOnComponent implementation

          UIXCollection

          OVerride invokeOnComponent to call setUpVisitingContext/tearDownVisitingContext around visits

          to the children using invokeOnChildrenComponents()

          ComponentEditorHandler:

          Add the editedComponent as a partial target when its properties change

          Editor.jspf

          Use partial submit when the property inspector's "update" button is pressed

          Web.xml

          Add new internal flag for turning feature on for now and make false by default

          Show
          Blake Sullivan added a comment - Patch to 1.2.10.1 Since the aptch file can't contain new files, place the contents of visit.zip relative to org.apache.myfaces.trinidad.api.component For now PPR Optimization is controlled by two internal flags: org.apache.myfaces.trinidadinternal.ENABLE_PPR_OPTIMIZATION (default is false for now) is a servlet initialization parameter that controls whether we ever attempt to use optimized PPR. The default is temporarily false to ensure no regressions. This flag will eventually be removed. org.apache.myfaces.trinidadinternal.DISABLE_PPR_OPTIMIZATION is an ApplicationMap property (default false), for turning off PPR Optimization once turned on by the servlet initialization parameter. This property can be used to temporarily turn off PPR optimization when debugging to determine whether a bug was caused by PPR Optimization. Work done: org.apache.myfaces.trinidad.component.visit package /** * <p>A simple callback interface that enables taking action on a specific UIComponent (either facet or child) during a component tree visit.</p> * @see org.apache.myfaces.trinidad.component.UIXComponent#visitTree UIComponent.visitTree() */ public interface VisitCallback /** * <p>A context object that is used to hold state relating to a component tree visit.</p> * <p>Component tree visits are initiated by calling {@link org.apache.myfaces.trinidad.component.UIXComponent#visitTree UIComponent.visitTree ()}, * at which point both a {@link VisitContext} and a {@link VisitCallback} * must be provided. * * @see org.apache.myfaces.trinidad.component.UIXComponent#visitTree UIXComponent.visitTree() * @see VisitCallback * */ abstract public class VisitContext /** * * <p>An enum that specifies the possible * results of a call to {@link VisitCallback#visit VisitCallback.visit()}. * </p> * * @see VisitCallback#visit VisitCallback.visit() */ public enum VisitResult /** * * <p>An enum that specifies hints that impact * the behavior of a component tree visit.</p> * * @see VisitContext#getHints VisitContext.getHints() */ public enum VisitHint UIXComponent add support for visiting the UIComponent tree in context, using a similar approach to that proposed for JSF 2.0. Compared to calls to invokeOnComponent, visiting has the following advantages: 1) For a single component, visitTree is faster than invokeOnComponent because visitTree avoids most calls to getClientId() on the traversed components 2) For multiple components, visitTree can visit all of the components in a single pass, avoiding replicating the work to setup and teardown the component contexts when visiting. In addition, visitTree guarantees the relative ordering of the component visits 3) visitTree supports optionally skipping non-rendered components, matching the visiting behavior of the JSF phases. 4) visitTree supports components and renderers that set up different or additional context when visiting during the encoding phaseTo support component (and Renderer) control over visitation during encoding, partialEncodeVisit, which is called during visits during the encoding phase was also added. The context setup for tree visitation is shared with invokeOnComponent by adding new protected methods UIXComponent.setupVisitingContext() and tearDownVisitingContext() as the location for placing the context setup and teardown code. UiXComponentBase.invokeOnComponent() now calls these methods from its invokeOnComponent() override. /** * <p>Perform a tree visit starting at * this node in the tree.</p> * * <p>UIXComponent.visitTree() implementations do not invoke the * {@code VisitCallback} directly, but instead call * {@code VisitContext.invokeVisitCallback()} to invoke the * callback. This allows {@code VisitContext} implementations * to provide optimized tree traversals, for example by only * calling the {@code VisitCallback} for a subset of components.</p> * * @param visitContext the <code>VisitContext</code> for this visit * @param callback the <code>VisitCallback</code> instance * whose <code>visit</code> method will be called * for each node visited. * @return component implementations may return <code>true</code> * to indicate that the tree visit is complete (eg. all components * that need to be visited have been visited). This results in * the tree visit being short-circuited such that no more components * are visited. * * @see VisitContext#invokeVisitCallback VisitContext.invokeVisitCallback() */ public boolean visitTree( VisitContext visitContext, VisitCallback callback) UIXComponentBase: Override invokeOnComponent() to call setupVisitingContext() and tearDownVisitingContext() and to not call super.invokeOnComponent() (in order to avoid an unnecessary call to getClientId()). Add protected convenience functions invokeOnNamingContainerComponent() and invokeOnChildrenComponents() to make it easier for subclasses to implement invokeOnComponent optimally. CoreRenderer: Add: /** * <p> * Called when visiting the CoreRenderer's component during optimized partial page encoding so * that the CoreRenderer can modify what is actually encoded. For example tab controls often * render the tabs for the ShowDetailItems in the tab bar before delegating to the * disclosed ShowDetailItem to render the tab content. As a result, the tab control * needs to encode its tab bar if any of its ShowDetailItems are partial targets so that * the tab labels, for example, are up-to-date. * </p> * <p> * The default implementation calls the VisitCallback and returns its result if this UIXComponent * is a partial target of the current encoding. * </p> * @param visitContext VisitContext to pass to the VisitCallback * @param partialContext PartialPageContext for the current partial encoding * @param component The component for the CoreRenderer to visit * @param callback VisitCallback to call if this component is a partial target * @return The VisitResult controlling continued iteration of the visit. */ public VisitResult partialEncodeVisit( VisitContext visitContext, PartialPageContext partialContext, UIComponent component, VisitCallback callback) /** * <p> * Called before rendering the current component's children in order to set * up any special context. * </p> * <p>If <code>setupEncodingContext</code> succeeds then * <code>tearDownEncodingContext</code> will be called for the same component. * </p> * <p>The default implementation does nothing</p> * @param context FacesContext for this request * @param rc RenderingContext for this encoding pass * @ param component Component to encode using this Renderer * @see #tearDownEncodingContext */ public void setupEncodingContext( FacesContext context, RenderingContext rc, UIXComponent component) /** * <p> * Called after rendering the current component's children in order to tear * down any special context. * </p> * <p> * <code>tearDownEncodingContext</code> will be called on the component if * <code>setupEncodingContext</code> succeeded. * </p> * <p>The default implementation does nothing</p> * @param context FacesContext for this request * @param rc RenderingContext for this encoding pass * @ param component Component to encode using this Renderer * @see #setupEncodingContext */ public void tearDownEncodingContext( FacesContext context, RenderingContext rc, UIXComponent component) The default implementations of beforeEncode() and afterEncode() have been changed to call setUpEncodingContext() and tearDownEncodingContext() respectively for backwards compatibility. PartialPageContext: Add new methods: abstract public boolean isPossiblePartialTarget(String componentId); As an optimization for checking whether a componentId is the suffix of a clientId to be rendered and public abstract boolean areAllTargetsProcessed(); Which returns true when all of the request partial targets have been encoded. and abstract public VisitContext getVisitContext(); Returning a VisitContext that can be used for visiting the components to be RequestContext: Add factory support for creating VisitContexts: /** * <p>Creates a VisitContext instance for use with * {@link org.apache.myfaces.trinidad.component.UIXComponent#visitTree UIComponent.visitTree ()} .</p> * @param context the FacesContext for the current request @param ids the client ids of the components to visit. If null, all components will be visited. @param hints the VisitHints to apply to the visit @param phaseId. PhaseId if any for this visit. If PhaseId is specified, hints must contain VisitHint.EXECUTE_LIFECYCLE @return a VisitContext instance that is initialized with the specified ids and hints. */ public abstract VisitContext createVisitContext( FacesContext context, Collection<String> ids, Set<VisitHint> hints, PhaseId phaseId); Unlike the JSF 2.0 version, this optionally takes the phaseId as a parameter as the current phase isn't easily accessible in JSF 1.2. Other work: Add missing utilities to CollectionUtils for: 1) Converting an Iterator to an ArrayList 2) Creating an empty queue 3) Getting an empty Iterator 4) Getting an empty ListIterator CoreRenderingContext: Add getFacesContext() and getRequestContext() to avoid hammering the ThreadLocals PartialPageUtils: Add function controlling whether OptimizedPPR is currently enabled for this request in order to abstract the implementation of the temporary controls for enabling this feature from the rendering code. /** Returns <code>true</code> if optimized PPR is enabled for this request @return */ public static boolean isOptimizedPPREnabled(FacesContext context, boolean checkIsPPR) PartialPageContextImpl: Implement: public boolean isPossiblePartialTarget(String componentId) public boolean areAllTargetsProcessed() public VisitContext getVisitContext() Provide an internal implementation of VisitContext used for optimised PPR rendering ensuring a single source of truth by delegating back to the PartialPageContext so that additions to the PartialPageContext's partial targets are reflected in the set of visited components PanelPartialRootRenderer: Perform the optimized partial render when Optimized PPR is enabled. RequestContextImpl: Implement public VisitContext createVisitContext( FacesContext context, Collection<String> ids, Set<VisitHint> hints, PhaseId phaseId) using new internal classes FullVisitContext and PartialVisitContext to handle the cases where either all of the components in the component tree should be visited, or only the specified components should be visited. FormRenderer Handle rendering the state hidden form field as well as validation javascript and other hidden form fields when OptimizedPPR is enabled. MRequestContextImpl: Provide stub implementation of createVisitContext() UIXComponentRefTemplate UIXDecorateCollectionTemplate UIXMenuTemplate UIXSubformTemplate Use invokeOnNamingContainer as the invokeOnComponent implementation UIXCollection OVerride invokeOnComponent to call setUpVisitingContext/tearDownVisitingContext around visits to the children using invokeOnChildrenComponents() ComponentEditorHandler: Add the editedComponent as a partial target when its properties change Editor.jspf Use partial submit when the property inspector's "update" button is pressed Web.xml Add new internal flag for turning feature on for now and make false by default
          Blake Sullivan made changes -
          Field Original Value New Value
          Attachment visit.zip [ 12398169 ]
          Attachment JIRA_1368_12101.patch [ 12398168 ]
          Hide
          Matthias Weßendorf added a comment -

          Thanks to Blake for the patch

          Show
          Matthias Weßendorf added a comment - Thanks to Blake for the patch
          Matthias Weßendorf made changes -
          Fix Version/s  1.2.11-core [ 12313510 ]
          Status Open [ 1 ] Resolved [ 5 ]
          Assignee Matthias Weßendorf [ matzew ]
          Resolution Fixed [ 1 ]
          Hide
          Andrew Robinson added a comment -

          This bug fix breaks backwards compatibility.

          The problem is that in CoreRenderKit.java, we use the Trinidad HtmlFormRenederer to render "javax.faces.Form" components (HtmlForm). The code introduced in this bug makes an incorrect assumption that CoreRenderer always renders components of type UIXComponent.

          Therefore, the code needs to check in the beforeEncode method that the component is a UIXComponent before casting.

          Class cast exception occurs in this code:

          protected void beforeEncode(
          FacesContext context,
          RenderingContext arc,
          UIComponent component,
          FacesBean bean)

          { setupEncodingContext(context, arc, (UIXComponent)component); }

          of this source:
          https://svn.apache.org/repos/asf/myfaces/trinidad/trunk_1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/CoreRenderer.java

          I am not familiar yet with this new encoding context, so I cannot write the fix.

          This will break any trinidad application that uses <h:form/> in any of their pages

          Show
          Andrew Robinson added a comment - This bug fix breaks backwards compatibility. The problem is that in CoreRenderKit.java, we use the Trinidad HtmlFormRenederer to render "javax.faces.Form" components (HtmlForm). The code introduced in this bug makes an incorrect assumption that CoreRenderer always renders components of type UIXComponent. Therefore, the code needs to check in the beforeEncode method that the component is a UIXComponent before casting. Class cast exception occurs in this code: protected void beforeEncode( FacesContext context, RenderingContext arc, UIComponent component, FacesBean bean) { setupEncodingContext(context, arc, (UIXComponent)component); } of this source: https://svn.apache.org/repos/asf/myfaces/trinidad/trunk_1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/CoreRenderer.java I am not familiar yet with this new encoding context, so I cannot write the fix. This will break any trinidad application that uses <h:form/> in any of their pages
          Andrew Robinson made changes -
          Status Resolved [ 5 ] Reopened [ 4 ]
          Resolution Fixed [ 1 ]
          Hide
          Andrew Robinson added a comment -

          Changing the status as this now breaks backward compatibility and the work-around is to update all pages and change h:form to tr:form.

          Show
          Andrew Robinson added a comment - Changing the status as this now breaks backward compatibility and the work-around is to update all pages and change h:form to tr:form.
          Andrew Robinson made changes -
          Priority Major [ 3 ] Blocker [ 1 ]
          Hide
          Andrew Robinson added a comment -

          TRINIDAD-1385 was opened for the regression

          Show
          Andrew Robinson added a comment - TRINIDAD-1385 was opened for the regression
          Andrew Robinson made changes -
          Resolution Fixed [ 1 ]
          Status Reopened [ 4 ] Resolved [ 5 ]
          Andrew Robinson made changes -
          Link This issue blocks TRINIDAD-1385 [ TRINIDAD-1385 ]
          Andrew Robinson made changes -
          Link This issue blocks TRINIDAD-1385 [ TRINIDAD-1385 ]
          Andrew Robinson made changes -
          Link This issue is related to TRINIDAD-1385 [ TRINIDAD-1385 ]
          Hide
          Andrew Robinson added a comment -

          UIXCollection was not updated, as a result, the iterator, table and tree all do not callback per iteration, but instead only once per child component. Re-opening the issue to be able to allow more work to be done to finish the task and get all of the Trinidad components correctly working under this new API

          Show
          Andrew Robinson added a comment - UIXCollection was not updated, as a result, the iterator, table and tree all do not callback per iteration, but instead only once per child component. Re-opening the issue to be able to allow more work to be done to finish the task and get all of the Trinidad components correctly working under this new API
          Andrew Robinson made changes -
          Resolution Fixed [ 1 ]
          Status Resolved [ 5 ] Reopened [ 4 ]
          Andrew Robinson made changes -
          Priority Blocker [ 1 ] Major [ 3 ]
          Hide
          Matthias Weßendorf added a comment -

          I am removing the "Fix Version" since this was reopened.

          Show
          Matthias Weßendorf added a comment - I am removing the "Fix Version" since this was reopened.
          Matthias Weßendorf made changes -
          Fix Version/s  1.2.11-core [ 12313510 ]
          Hide
          Andrew Robinson added a comment -

          I really would like this to be fixed. Here is a proposed patch to 1.2.11.4 and Trunk. I would like to have it be reviewed before committing it, especially with the UIXNavigation and its sub-classes (For example, should undisclosed row keys be visited?)

          Thanks

          Show
          Andrew Robinson added a comment - I really would like this to be fixed. Here is a proposed patch to 1.2.11.4 and Trunk. I would like to have it be reviewed before committing it, especially with the UIXNavigation and its sub-classes (For example, should undisclosed row keys be visited?) Thanks
          Andrew Robinson made changes -
          Attachment TRINIDAD-1368.1.2.11.4.diff [ 12414698 ]
          Attachment TRINIDAD-1368.trunk.diff [ 12414699 ]
          Hide
          Blake Sullivan added a comment -

          The first problem we have had is that components need to separate the contex6 setup and teardown needed to process their children from the context setup and tear down of the components themselves. For example, consider a composite component that establishes an EL context for its children--that context should only be setup when the children are being processed, not when the component is processing its own attributes.

          In the case of encoding, we want to delegate to the Renderer to ensure that the setup and teardown of context for child processing is consistent between optimized rendering using tree visiting and full rendering traversals.

          The second problem was that UIXComponent.setUpEncodingContext was named differently than all of the other set up methods. I've made the spelling consistent (which after a quick check of the dictionary is consitently wrong through out Trinidad setup as a compound word is a noun and as a verb is two words, so it should have been setUp. Drat!) and temporarily left a final deprecated version in that I will whack shortly.

          The third issue is that iterating components often want to modify only the manner in which their data is iterated over. To simplify this, we add a hook visitData() to UIXCollection.

          – Blake Sullivan

          UIXComponent:

          /**

          • Hook for subclasses to override the manner in which the component's children are visited. The default
          • implementation visits all of the children and facets of the Component.
          • <code>setupChildrenVisitingContext</code> will have been called before this method is
          • invoked and <code>tearDownChildrenVisitingContext</code> will be called after.
          • respectively. If the purpose of this visit was to encode the component and the
          • component uses a CoreRenderer, the CoreRenderer's
          • <code>setupChildrenEncodingContext</code> and <code>tearDownChildrenEncodingContext</code>
          • will be called before and after this method is invoked, respectively.
          • @param visitContext the <code>VisitContext</code> for this visit
          • @param callback the <code>VisitCallback</code> instance
          • @return <code>true</code> if the visit is complete.
          • @see #setupChildrenVisitingContext
          • @see #tearDownChildrenVisitingContext
          • @see org.apache.myfaces.trinidad.render.CoreRenderer#setupChildrenEncodingContext
          • @see org.apache.myfaces.trinidad.render.CoreRenderer#tearDownChildrenEncodingContext
            */
            protected boolean visitChildren(
            VisitContext visitContext,
            VisitCallback callback)

          /**

          • <p>Sets up the context necessary to visit or invoke the children of a component for all phases.
          • </p>
          • <p>The default implementation does nothing.</p>
          • <p>If a subclass overrides this method, it should override
          • <code>tearDownChildrenVisitingContext</code> as well.</p>
          • <p>It is guaranteed that if <code>setupChildrenVisitingContext</code> completes
          • <code>tearDownChildrenVisitingContext</code> will be called for this component</p>
          • @param context FacesContext
          • @see #visitChildren
          • @see #tearDownChildrenVisitingContext
            */
            protected void setupChildrenVisitingContext(@SuppressWarnings("unused") FacesContext context)

          /**

          • <p>Tears down context created in order to visit or invoke the children of a component
          • for all phases.</p>
          • <p>The default implementation does nothing.</p>
          • <p>A subclass should only override this method if it overrode
          • <code>setupChildrenVisitingContext</code> as well</p>
          • <p>It is guaranteed that <code>tearDownChildrenVisitingContext</code> will be called only after
          • <code>setupChildrenVisitingContext</code> has been called for this component</p>
          • @param context FacesContext
          • @see #setupChildrenVisitingContext
          • @see #visitChildren
            */
            protected void tearDownChildrenVisitingContext(@SuppressWarnings("unused") FacesContext context)

          CoreRenderer

          • <p>
          • Called before rendering the current component's children in order to set
          • up any special context.
          • </p>
          • <p>If <code>setupChildrenEncodingContext</code> succeeds then
          • <code>tearDownChildrenEncodingContext</code> will be called for the same component.
          • </p>
          • <p>The default implementation does nothing</p>
          • @param context FacesContext for this request
          • @param rc RenderingContext for this encoding pass
          • @param component Component to encode using this Renderer
          • @see #tearDownChildrenEncodingContext
            */
            public void setupChildrenEncodingContext(
            @SuppressWarnings("unused") FacesContext context,
            @SuppressWarnings("unused") RenderingContext rc,
            @SuppressWarnings("unused") UIComponent component)

          /**

          • <p>
          • Called after rendering the current component's children in order to tear
          • down any special context.
          • </p>
          • <p>
          • <code>tearDownChildrenEncodingContext</code> will be called on the component if
          • <code>setupChildrenEncodingContext</code> succeeded.
          • </p>
          • <p>The default implementation does nothing</p>
          • @param context FacesContext for this request
          • @param rc RenderingContext for this encoding pass
          • @param component Component to encode using this Renderer
          • @see #setupChildrenEncodingContext
            */
            public void tearDownChildrenEncodingContext(
            @SuppressWarnings("unused") FacesContext context,
            @SuppressWarnings("unused") RenderingContext rc,
            @SuppressWarnings("unused") UIComponent component)

          UIXCollection:

          /**

          • Visit the rows and children of the columns of the collection per row-index. This should
          • not visit row index -1 (it will be perfomed in the visitTree method). The columns
          • themselves should not be visited, only their children in this function.
            *
          • @param visitContext The visiting context
          • @param callback The visit callback
          • @return true if the visiting should stop
          • @see #visitChildren(VisitContext, VisitCallback)
            */
            protected abstract boolean visitData(
            VisitContext visitContext,
            VisitCallback callback);
          Show
          Blake Sullivan added a comment - The first problem we have had is that components need to separate the contex6 setup and teardown needed to process their children from the context setup and tear down of the components themselves. For example, consider a composite component that establishes an EL context for its children--that context should only be setup when the children are being processed, not when the component is processing its own attributes. In the case of encoding, we want to delegate to the Renderer to ensure that the setup and teardown of context for child processing is consistent between optimized rendering using tree visiting and full rendering traversals. The second problem was that UIXComponent.setUpEncodingContext was named differently than all of the other set up methods. I've made the spelling consistent (which after a quick check of the dictionary is consitently wrong through out Trinidad setup as a compound word is a noun and as a verb is two words, so it should have been setUp. Drat!) and temporarily left a final deprecated version in that I will whack shortly. The third issue is that iterating components often want to modify only the manner in which their data is iterated over. To simplify this, we add a hook visitData() to UIXCollection. – Blake Sullivan UIXComponent: /** Hook for subclasses to override the manner in which the component's children are visited. The default implementation visits all of the children and facets of the Component. <code>setupChildrenVisitingContext</code> will have been called before this method is invoked and <code>tearDownChildrenVisitingContext</code> will be called after. respectively. If the purpose of this visit was to encode the component and the component uses a CoreRenderer, the CoreRenderer's <code>setupChildrenEncodingContext</code> and <code>tearDownChildrenEncodingContext</code> will be called before and after this method is invoked, respectively. @param visitContext the <code>VisitContext</code> for this visit @param callback the <code>VisitCallback</code> instance @return <code>true</code> if the visit is complete. @see #setupChildrenVisitingContext @see #tearDownChildrenVisitingContext @see org.apache.myfaces.trinidad.render.CoreRenderer#setupChildrenEncodingContext @see org.apache.myfaces.trinidad.render.CoreRenderer#tearDownChildrenEncodingContext */ protected boolean visitChildren( VisitContext visitContext, VisitCallback callback) /** <p>Sets up the context necessary to visit or invoke the children of a component for all phases. </p> <p>The default implementation does nothing.</p> <p>If a subclass overrides this method, it should override <code>tearDownChildrenVisitingContext</code> as well.</p> <p>It is guaranteed that if <code>setupChildrenVisitingContext</code> completes <code>tearDownChildrenVisitingContext</code> will be called for this component</p> @param context FacesContext @see #visitChildren @see #tearDownChildrenVisitingContext */ protected void setupChildrenVisitingContext(@SuppressWarnings("unused") FacesContext context) /** <p>Tears down context created in order to visit or invoke the children of a component for all phases.</p> <p>The default implementation does nothing.</p> <p>A subclass should only override this method if it overrode <code>setupChildrenVisitingContext</code> as well</p> <p>It is guaranteed that <code>tearDownChildrenVisitingContext</code> will be called only after <code>setupChildrenVisitingContext</code> has been called for this component</p> @param context FacesContext @see #setupChildrenVisitingContext @see #visitChildren */ protected void tearDownChildrenVisitingContext(@SuppressWarnings("unused") FacesContext context) CoreRenderer <p> Called before rendering the current component's children in order to set up any special context. </p> <p>If <code>setupChildrenEncodingContext</code> succeeds then <code>tearDownChildrenEncodingContext</code> will be called for the same component. </p> <p>The default implementation does nothing</p> @param context FacesContext for this request @param rc RenderingContext for this encoding pass @param component Component to encode using this Renderer @see #tearDownChildrenEncodingContext */ public void setupChildrenEncodingContext( @SuppressWarnings("unused") FacesContext context, @SuppressWarnings("unused") RenderingContext rc, @SuppressWarnings("unused") UIComponent component) /** <p> Called after rendering the current component's children in order to tear down any special context. </p> <p> <code>tearDownChildrenEncodingContext</code> will be called on the component if <code>setupChildrenEncodingContext</code> succeeded. </p> <p>The default implementation does nothing</p> @param context FacesContext for this request @param rc RenderingContext for this encoding pass @param component Component to encode using this Renderer @see #setupChildrenEncodingContext */ public void tearDownChildrenEncodingContext( @SuppressWarnings("unused") FacesContext context, @SuppressWarnings("unused") RenderingContext rc, @SuppressWarnings("unused") UIComponent component) UIXCollection: /** Visit the rows and children of the columns of the collection per row-index. This should not visit row index -1 (it will be perfomed in the visitTree method). The columns themselves should not be visited, only their children in this function. * @param visitContext The visiting context @param callback The visit callback @return true if the visiting should stop @see #visitChildren(VisitContext, VisitCallback) */ protected abstract boolean visitData( VisitContext visitContext, VisitCallback callback);
          Blake Sullivan made changes -
          Attachment JIRA_1368_More_Traversal_1_2_12_2.patch [ 12435322 ]
          Blake Sullivan made changes -
          Attachment TRINIDAD-1368.1.2.11.4.diff [ 12414698 ]
          Blake Sullivan made changes -
          Assignee Matthias Weßendorf [ matzew ] Blake Sullivan [ btsulliv ]
          Hide
          Blake Sullivan added a comment -

          The first problem we have had is that components need to separate the contex6 setup and teardown needed to process their children from the context setup and tear down of the components themselves. For example, consider a composite component that establishes an EL context for its children--that context should only be setup when the children are being processed, not when the component is processing its own attributes.

          In the case of encoding, we want to delegate to the Renderer to ensure that the setup and teardown of context for child processing is consistent between optimized rendering using tree visiting and full rendering traversals.

          The second problem was that UIXComponent.setUpEncodingContext was named differently than all of the other set up methods. I've made the spelling consistent (which after a quick check of the dictionary is consitently wrong through out Trinidad setup as a compound word is a noun and as a verb is two words, so it should have been setUp. Drat!) and temporarily left a final deprecated version in that I will whack shortly.

          The third issue is that iterating components often want to modify only the manner in which their data is iterated over. To simplify this, we add a hook visitData() to UIXCollection.

          – Blake Sullivan

          UIXComponent:

          /**

          • Hook for subclasses to override the manner in which the component's children are visited. The default
          • implementation visits all of the children and facets of the Component.
          • <code>setupChildrenVisitingContext</code> will have been called before this method is
          • invoked and <code>tearDownChildrenVisitingContext</code> will be called after.
          • respectively. If the purpose of this visit was to encode the component and the
          • component uses a CoreRenderer, the CoreRenderer's
          • <code>setupChildrenEncodingContext</code> and <code>tearDownChildrenEncodingContext</code>
          • will be called before and after this method is invoked, respectively.
          • @param visitContext the <code>VisitContext</code> for this visit
          • @param callback the <code>VisitCallback</code> instance
          • @return <code>true</code> if the visit is complete.
          • @see #setupChildrenVisitingContext
          • @see #tearDownChildrenVisitingContext
          • @see org.apache.myfaces.trinidad.render.CoreRenderer#setupChildrenEncodingContext
          • @see org.apache.myfaces.trinidad.render.CoreRenderer#tearDownChildrenEncodingContext
            */
            protected boolean visitChildren(
            VisitContext visitContext,
            VisitCallback callback)

          /**

          • <p>Sets up the context necessary to visit or invoke the children of a component for all phases.
          • </p>
          • <p>The default implementation does nothing.</p>
          • <p>If a subclass overrides this method, it should override
          • <code>tearDownChildrenVisitingContext</code> as well.</p>
          • <p>It is guaranteed that if <code>setupChildrenVisitingContext</code> completes
          • <code>tearDownChildrenVisitingContext</code> will be called for this component</p>
          • @param context FacesContext
          • @see #visitChildren
          • @see #tearDownChildrenVisitingContext
            */
            protected void setupChildrenVisitingContext(@SuppressWarnings("unused") FacesContext context)

          /**

          • <p>Tears down context created in order to visit or invoke the children of a component
          • for all phases.</p>
          • <p>The default implementation does nothing.</p>
          • <p>A subclass should only override this method if it overrode
          • <code>setupChildrenVisitingContext</code> as well</p>
          • <p>It is guaranteed that <code>tearDownChildrenVisitingContext</code> will be called only after
          • <code>setupChildrenVisitingContext</code> has been called for this component</p>
          • @param context FacesContext
          • @see #setupChildrenVisitingContext
          • @see #visitChildren
            */
            protected void tearDownChildrenVisitingContext(@SuppressWarnings("unused") FacesContext context)

          CoreRenderer

          • <p>
          • Called before rendering the current component's children in order to set
          • up any special context.
          • </p>
          • <p>If <code>setupChildrenEncodingContext</code> succeeds then
          • <code>tearDownChildrenEncodingContext</code> will be called for the same component.
          • </p>
          • <p>The default implementation does nothing</p>
          • @param context FacesContext for this request
          • @param rc RenderingContext for this encoding pass
          • @param component Component to encode using this Renderer
          • @see #tearDownChildrenEncodingContext
            */
            public void setupChildrenEncodingContext(
            @SuppressWarnings("unused") FacesContext context,
            @SuppressWarnings("unused") RenderingContext rc,
            @SuppressWarnings("unused") UIComponent component)

          /**

          • <p>
          • Called after rendering the current component's children in order to tear
          • down any special context.
          • </p>
          • <p>
          • <code>tearDownChildrenEncodingContext</code> will be called on the component if
          • <code>setupChildrenEncodingContext</code> succeeded.
          • </p>
          • <p>The default implementation does nothing</p>
          • @param context FacesContext for this request
          • @param rc RenderingContext for this encoding pass
          • @param component Component to encode using this Renderer
          • @see #setupChildrenEncodingContext
            */
            public void tearDownChildrenEncodingContext(
            @SuppressWarnings("unused") FacesContext context,
            @SuppressWarnings("unused") RenderingContext rc,
            @SuppressWarnings("unused") UIComponent component)

          UIXCollection:

          /**

          • Visit the rows and children of the columns of the collection per row-index. This should
          • not visit row index -1 (it will be perfomed in the visitTree method). The columns
          • themselves should not be visited, only their children in this function.
            *
          • @param visitContext The visiting context
          • @param callback The visit callback
          • @return true if the visiting should stop
          • @see #visitChildren(VisitContext, VisitCallback)
            */
            protected abstract boolean visitData(
            VisitContext visitContext,
            VisitCallback callback);
          Show
          Blake Sullivan added a comment - The first problem we have had is that components need to separate the contex6 setup and teardown needed to process their children from the context setup and tear down of the components themselves. For example, consider a composite component that establishes an EL context for its children--that context should only be setup when the children are being processed, not when the component is processing its own attributes. In the case of encoding, we want to delegate to the Renderer to ensure that the setup and teardown of context for child processing is consistent between optimized rendering using tree visiting and full rendering traversals. The second problem was that UIXComponent.setUpEncodingContext was named differently than all of the other set up methods. I've made the spelling consistent (which after a quick check of the dictionary is consitently wrong through out Trinidad setup as a compound word is a noun and as a verb is two words, so it should have been setUp. Drat!) and temporarily left a final deprecated version in that I will whack shortly. The third issue is that iterating components often want to modify only the manner in which their data is iterated over. To simplify this, we add a hook visitData() to UIXCollection. – Blake Sullivan UIXComponent: /** Hook for subclasses to override the manner in which the component's children are visited. The default implementation visits all of the children and facets of the Component. <code>setupChildrenVisitingContext</code> will have been called before this method is invoked and <code>tearDownChildrenVisitingContext</code> will be called after. respectively. If the purpose of this visit was to encode the component and the component uses a CoreRenderer, the CoreRenderer's <code>setupChildrenEncodingContext</code> and <code>tearDownChildrenEncodingContext</code> will be called before and after this method is invoked, respectively. @param visitContext the <code>VisitContext</code> for this visit @param callback the <code>VisitCallback</code> instance @return <code>true</code> if the visit is complete. @see #setupChildrenVisitingContext @see #tearDownChildrenVisitingContext @see org.apache.myfaces.trinidad.render.CoreRenderer#setupChildrenEncodingContext @see org.apache.myfaces.trinidad.render.CoreRenderer#tearDownChildrenEncodingContext */ protected boolean visitChildren( VisitContext visitContext, VisitCallback callback) /** <p>Sets up the context necessary to visit or invoke the children of a component for all phases. </p> <p>The default implementation does nothing.</p> <p>If a subclass overrides this method, it should override <code>tearDownChildrenVisitingContext</code> as well.</p> <p>It is guaranteed that if <code>setupChildrenVisitingContext</code> completes <code>tearDownChildrenVisitingContext</code> will be called for this component</p> @param context FacesContext @see #visitChildren @see #tearDownChildrenVisitingContext */ protected void setupChildrenVisitingContext(@SuppressWarnings("unused") FacesContext context) /** <p>Tears down context created in order to visit or invoke the children of a component for all phases.</p> <p>The default implementation does nothing.</p> <p>A subclass should only override this method if it overrode <code>setupChildrenVisitingContext</code> as well</p> <p>It is guaranteed that <code>tearDownChildrenVisitingContext</code> will be called only after <code>setupChildrenVisitingContext</code> has been called for this component</p> @param context FacesContext @see #setupChildrenVisitingContext @see #visitChildren */ protected void tearDownChildrenVisitingContext(@SuppressWarnings("unused") FacesContext context) CoreRenderer <p> Called before rendering the current component's children in order to set up any special context. </p> <p>If <code>setupChildrenEncodingContext</code> succeeds then <code>tearDownChildrenEncodingContext</code> will be called for the same component. </p> <p>The default implementation does nothing</p> @param context FacesContext for this request @param rc RenderingContext for this encoding pass @param component Component to encode using this Renderer @see #tearDownChildrenEncodingContext */ public void setupChildrenEncodingContext( @SuppressWarnings("unused") FacesContext context, @SuppressWarnings("unused") RenderingContext rc, @SuppressWarnings("unused") UIComponent component) /** <p> Called after rendering the current component's children in order to tear down any special context. </p> <p> <code>tearDownChildrenEncodingContext</code> will be called on the component if <code>setupChildrenEncodingContext</code> succeeded. </p> <p>The default implementation does nothing</p> @param context FacesContext for this request @param rc RenderingContext for this encoding pass @param component Component to encode using this Renderer @see #setupChildrenEncodingContext */ public void tearDownChildrenEncodingContext( @SuppressWarnings("unused") FacesContext context, @SuppressWarnings("unused") RenderingContext rc, @SuppressWarnings("unused") UIComponent component) UIXCollection: /** Visit the rows and children of the columns of the collection per row-index. This should not visit row index -1 (it will be perfomed in the visitTree method). The columns themselves should not be visited, only their children in this function. * @param visitContext The visiting context @param callback The visit callback @return true if the visiting should stop @see #visitChildren(VisitContext, VisitCallback) */ protected abstract boolean visitData( VisitContext visitContext, VisitCallback callback);
          Blake Sullivan made changes -
          Attachment JIRA_1368_More_Traversal_Trunk.patch [ 12435339 ]
          Hide
          Blake Sullivan added a comment -

          Fixed in revision 908215 on Trunk and revision 908149 in 2.1.12.2

          The first problem we have had is that components need to separate the contex6 setup and teardown needed to process their children from the context setup and tear down of the components themselves. For example, consider a composite component that establishes an EL context for its children--that context should only be setup when the children are being processed, not when the component is processing its own attributes.

          In the case of encoding, we want to delegate to the Renderer to ensure that the setup and teardown of context for child processing is consistent between optimized rendering using tree visiting and full rendering traversals.

          The second problem was that UIXComponent.setUpEncodingContext was named differently than all of the other set up methods. I've made the spelling consistent (which after a quick check of the dictionary is consitently wrong through out Trinidad setup as a compound word is a noun and as a verb is two words, so it should have been setUp. Drat!) and temporarily left a final deprecated version in that I will whack shortly.

          The third issue is that iterating components often want to modify only the manner in which their data is iterated over. To simplify this, we add a hook visitData() to UIXCollection.

          – Blake Sullivan

          UIXComponent:

          /**

          • Hook for subclasses to override the manner in which the component's children are visited. The default
          • implementation visits all of the children and facets of the Component.
          • <code>setupChildrenVisitingContext</code> will have been called before this method is
          • invoked and <code>tearDownChildrenVisitingContext</code> will be called after.
          • respectively. If the purpose of this visit was to encode the component and the
          • component uses a CoreRenderer, the CoreRenderer's
          • <code>setupChildrenEncodingContext</code> and <code>tearDownChildrenEncodingContext</code>
          • will be called before and after this method is invoked, respectively.
          • @param visitContext the <code>VisitContext</code> for this visit
          • @param callback the <code>VisitCallback</code> instance
          • @return <code>true</code> if the visit is complete.
          • @see #setupChildrenVisitingContext
          • @see #tearDownChildrenVisitingContext
          • @see org.apache.myfaces.trinidad.render.CoreRenderer#setupChildrenEncodingContext
          • @see org.apache.myfaces.trinidad.render.CoreRenderer#tearDownChildrenEncodingContext
            */
            protected boolean visitChildren(
            VisitContext visitContext,
            VisitCallback callback)

          /**

          • <p>Sets up the context necessary to visit or invoke the children of a component for all phases.
          • </p>
          • <p>The default implementation does nothing.</p>
          • <p>If a subclass overrides this method, it should override
          • <code>tearDownChildrenVisitingContext</code> as well.</p>
          • <p>It is guaranteed that if <code>setupChildrenVisitingContext</code> completes
          • <code>tearDownChildrenVisitingContext</code> will be called for this component</p>
          • @param context FacesContext
          • @see #visitChildren
          • @see #tearDownChildrenVisitingContext
            */
            protected void setupChildrenVisitingContext(@SuppressWarnings("unused") FacesContext context)

          /**

          • <p>Tears down context created in order to visit or invoke the children of a component
          • for all phases.</p>
          • <p>The default implementation does nothing.</p>
          • <p>A subclass should only override this method if it overrode
          • <code>setupChildrenVisitingContext</code> as well</p>
          • <p>It is guaranteed that <code>tearDownChildrenVisitingContext</code> will be called only after
          • <code>setupChildrenVisitingContext</code> has been called for this component</p>
          • @param context FacesContext
          • @see #setupChildrenVisitingContext
          • @see #visitChildren
            */
            protected void tearDownChildrenVisitingContext(@SuppressWarnings("unused") FacesContext context)

          CoreRenderer

          • <p>
          • Called before rendering the current component's children in order to set
          • up any special context.
          • </p>
          • <p>If <code>setupChildrenEncodingContext</code> succeeds then
          • <code>tearDownChildrenEncodingContext</code> will be called for the same component.
          • </p>
          • <p>The default implementation does nothing</p>
          • @param context FacesContext for this request
          • @param rc RenderingContext for this encoding pass
          • @param component Component to encode using this Renderer
          • @see #tearDownChildrenEncodingContext
            */
            public void setupChildrenEncodingContext(
            @SuppressWarnings("unused") FacesContext context,
            @SuppressWarnings("unused") RenderingContext rc,
            @SuppressWarnings("unused") UIComponent component)

          /**

          • <p>
          • Called after rendering the current component's children in order to tear
          • down any special context.
          • </p>
          • <p>
          • <code>tearDownChildrenEncodingContext</code> will be called on the component if
          • <code>setupChildrenEncodingContext</code> succeeded.
          • </p>
          • <p>The default implementation does nothing</p>
          • @param context FacesContext for this request
          • @param rc RenderingContext for this encoding pass
          • @param component Component to encode using this Renderer
          • @see #setupChildrenEncodingContext
            */
            public void tearDownChildrenEncodingContext(
            @SuppressWarnings("unused") FacesContext context,
            @SuppressWarnings("unused") RenderingContext rc,
            @SuppressWarnings("unused") UIComponent component)

          UIXCollection:

          /**

          • Visit the rows and children of the columns of the collection per row-index. This should
          • not visit row index -1 (it will be perfomed in the visitTree method). The columns
          • themselves should not be visited, only their children in this function.
            *
          • @param visitContext The visiting context
          • @param callback The visit callback
          • @return true if the visiting should stop
          • @see #visitChildren(VisitContext, VisitCallback)
            */
            protected abstract boolean visitData(
            VisitContext visitContext,
            VisitCallback callback);
          Show
          Blake Sullivan added a comment - Fixed in revision 908215 on Trunk and revision 908149 in 2.1.12.2 The first problem we have had is that components need to separate the contex6 setup and teardown needed to process their children from the context setup and tear down of the components themselves. For example, consider a composite component that establishes an EL context for its children--that context should only be setup when the children are being processed, not when the component is processing its own attributes. In the case of encoding, we want to delegate to the Renderer to ensure that the setup and teardown of context for child processing is consistent between optimized rendering using tree visiting and full rendering traversals. The second problem was that UIXComponent.setUpEncodingContext was named differently than all of the other set up methods. I've made the spelling consistent (which after a quick check of the dictionary is consitently wrong through out Trinidad setup as a compound word is a noun and as a verb is two words, so it should have been setUp. Drat!) and temporarily left a final deprecated version in that I will whack shortly. The third issue is that iterating components often want to modify only the manner in which their data is iterated over. To simplify this, we add a hook visitData() to UIXCollection. – Blake Sullivan UIXComponent: /** Hook for subclasses to override the manner in which the component's children are visited. The default implementation visits all of the children and facets of the Component. <code>setupChildrenVisitingContext</code> will have been called before this method is invoked and <code>tearDownChildrenVisitingContext</code> will be called after. respectively. If the purpose of this visit was to encode the component and the component uses a CoreRenderer, the CoreRenderer's <code>setupChildrenEncodingContext</code> and <code>tearDownChildrenEncodingContext</code> will be called before and after this method is invoked, respectively. @param visitContext the <code>VisitContext</code> for this visit @param callback the <code>VisitCallback</code> instance @return <code>true</code> if the visit is complete. @see #setupChildrenVisitingContext @see #tearDownChildrenVisitingContext @see org.apache.myfaces.trinidad.render.CoreRenderer#setupChildrenEncodingContext @see org.apache.myfaces.trinidad.render.CoreRenderer#tearDownChildrenEncodingContext */ protected boolean visitChildren( VisitContext visitContext, VisitCallback callback) /** <p>Sets up the context necessary to visit or invoke the children of a component for all phases. </p> <p>The default implementation does nothing.</p> <p>If a subclass overrides this method, it should override <code>tearDownChildrenVisitingContext</code> as well.</p> <p>It is guaranteed that if <code>setupChildrenVisitingContext</code> completes <code>tearDownChildrenVisitingContext</code> will be called for this component</p> @param context FacesContext @see #visitChildren @see #tearDownChildrenVisitingContext */ protected void setupChildrenVisitingContext(@SuppressWarnings("unused") FacesContext context) /** <p>Tears down context created in order to visit or invoke the children of a component for all phases.</p> <p>The default implementation does nothing.</p> <p>A subclass should only override this method if it overrode <code>setupChildrenVisitingContext</code> as well</p> <p>It is guaranteed that <code>tearDownChildrenVisitingContext</code> will be called only after <code>setupChildrenVisitingContext</code> has been called for this component</p> @param context FacesContext @see #setupChildrenVisitingContext @see #visitChildren */ protected void tearDownChildrenVisitingContext(@SuppressWarnings("unused") FacesContext context) CoreRenderer <p> Called before rendering the current component's children in order to set up any special context. </p> <p>If <code>setupChildrenEncodingContext</code> succeeds then <code>tearDownChildrenEncodingContext</code> will be called for the same component. </p> <p>The default implementation does nothing</p> @param context FacesContext for this request @param rc RenderingContext for this encoding pass @param component Component to encode using this Renderer @see #tearDownChildrenEncodingContext */ public void setupChildrenEncodingContext( @SuppressWarnings("unused") FacesContext context, @SuppressWarnings("unused") RenderingContext rc, @SuppressWarnings("unused") UIComponent component) /** <p> Called after rendering the current component's children in order to tear down any special context. </p> <p> <code>tearDownChildrenEncodingContext</code> will be called on the component if <code>setupChildrenEncodingContext</code> succeeded. </p> <p>The default implementation does nothing</p> @param context FacesContext for this request @param rc RenderingContext for this encoding pass @param component Component to encode using this Renderer @see #setupChildrenEncodingContext */ public void tearDownChildrenEncodingContext( @SuppressWarnings("unused") FacesContext context, @SuppressWarnings("unused") RenderingContext rc, @SuppressWarnings("unused") UIComponent component) UIXCollection: /** Visit the rows and children of the columns of the collection per row-index. This should not visit row index -1 (it will be perfomed in the visitTree method). The columns themselves should not be visited, only their children in this function. * @param visitContext The visiting context @param callback The visit callback @return true if the visiting should stop @see #visitChildren(VisitContext, VisitCallback) */ protected abstract boolean visitData( VisitContext visitContext, VisitCallback callback);
          Blake Sullivan made changes -
          Status Reopened [ 4 ] Resolved [ 5 ]
          Fix Version/s 1.2.13-core [ 12314170 ]
          Resolution Fixed [ 1 ]
          Transition Time In Source Status Execution Times Last Executer Last Execution Date
          Open Open Resolved Resolved
          2d 16h 39m 1 Matthias Weßendorf 20/Jan/09 23:19
          Resolved Resolved Reopened Reopened
          12d 13h 16m 2 Andrew Robinson 02/Feb/09 16:53
          Reopened Reopened Resolved Resolved
          372d 8h 25m 2 Blake Sullivan 09/Feb/10 21:02

            People

            • Assignee:
              Blake Sullivan
              Reporter:
              Blake Sullivan
            • Votes:
              2 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Time Tracking

                Estimated:
                Original Estimate - 336h
                336h
                Remaining:
                Remaining Estimate - 336h
                336h
                Logged:
                Time Spent - Not Specified
                Not Specified

                  Development