Allow FlattenedComponent to render content
------------------------------------------

                 Key: TRINIDAD-1504
                 URL: https://issues.apache.org/jira/browse/TRINIDAD-1504
             Project: MyFaces Trinidad
          Issue Type: Improvement
    Affects Versions:  1.2.11-core
            Reporter: Blake Sullivan


Currently components implementing the FlattenedComponent interface cannot 
render any content when flattening their children because while rendering can 
only occur once per component per request, flattening may occur multiple times 
during rendering since Renderers often make one or more passes over their 
children to collect information before making the rendering pass.  
Unfortunately, there is currently no way for FlattenedComponents to distinguish 
the cases where flattening is occurring for the purposes of simple in-context 
child iteration from the cases where encoding will occur.  The proposal is to 
add apis to allow the FlattenedComponents to distinguish between these two 
cases.

To org.apache.myfaces.trinidad.component.ComponentProcessingContext

Add:

  /**
   * Hints to the the FlattenedComponents regarding what the flattened 
iteration is being used for,
   * The FlattenedComponent may use this information to change its flattening 
behavior.
   * For example, a FlattenedComponent may generate output during a 
<code>PROCESS_FOR_ENCODING</code>
   * iteration, but not during a normal iteration.
   */
  public enum ProcessingHint
  {
    /**
     * Indicates that the iteration is occurring in order to encode iterated 
components.  This
     * hint may only be used during the RenderResponse phase and only once per 
an iterated
     * component.  Due to these guarantees, the FlattenedComponent is allowed 
to generate
     * content during the iteration, an exception to the normal rule that 
iterations must
     * be idempotent in case the same component is iterated multiple times.
     */
    PROCESS_FOR_ENCODING
  }

  /**
   * <p>Returns hints that influence the behavior of the component 
processing</p>
   *
   * @return a non-empty, unmodifiable collection of ProcessingHints
   */
  public Set<ProcessingHint> getHints()
  {
    return _hints;
  }

To org.apache.myfaces.trinidad.component.UIXComponent

Add:

  /**
   * Helper function called by Renderers to encode a flattened view of a group 
of
   * potentially FlattenedComponent instances rooted at a single child of the 
component,
   * invoking the <code>childProcessor</code> with its
   * <code>callbackContext</code> on each renderable instance.  This method 
must  be called
   * when the childProcessor is actually encoding and the childProcessor must 
not attempt
   * to encode the same component instances more than once per request.
   * <p>
   * If a Renderer needs to
   * collect information about its possibly flattened children before calling
   * <code>encodeFlattenedChild(FacesContext, ComponentProcessor, UIComponent, 
Object)</code>,
   * it should call <code>processFlattenedChildren(FacesContext, 
ComponentProcessor, UIComponent, Object)</code>
   * to collect the information.
   * <p>
   * If the child is a FlattenedComponent, the <code>childProcessor</code> will
   * be called  on each of that FlattenedComponent's children, recursing if 
those children are
   * themselves FlattenedComponents, otherwise, the <code>childProcessor</code> 
will be called on
   * the child itself.
   * <p>
   * FlattenedComponents that wish to check whether they are processed for the 
purpose of
   * encoding can check the ProcessingHints of the ComponentProcessingContext 
for the
   * presence of <code>PROCESS_FOR_ENCODING hint</code>.
   * <p>
   * If the Renderer accidentally passes in the component to be encoded instead 
of one
   * of its children, the result will almost certainly be an infinite recursion 
and stack overflow.
   * @return <code>true</code> If any children were processed
   * @see UIXComponent#processFlattenedChildren(FacesContext, 
ComponentProcessor, UIComponent, Object)
   * @see FlattenedComponent
   */
  public static <S> boolean encodeFlattenedChild(
    FacesContext context,
    ComponentProcessor<S> childProcessor,
    UIComponent child,
    S callbackContext) throws IOException

  /**
   * Helper function called by Renderers to encode a flattened view of their 
children,
   * invoking the <code>childProcessor</code> with its
   * <code>callbackContext</code> on each renderable instance.  This method 
must  be called
   * when the childProcessor is actually encoding and the childProcessor must 
not attempt
   * to encode the same component instances more than once per request.
   * <p>
   * If a Renderer needs to
   * collect information about its possibly flattened children before calling
   * <code>encodeFlattenedChild(FacesContext, ComponentProcessor, 
Iterable<UIComponent>, Object)</code>,
   * it should call
   * <code>processFlattenedChildren(FacesContext, ComponentProcessor, 
Iterable<UIComponent>, Object)</code>
   * to collect the information.
   * <p>
   * For each FlattenedComponent child, the <code>childProcessor</code> will
   * be called on each of that FlattenedComponent's children, recursing if 
those children are
   * themselves FlattenedComponents, otherwise, the <code>childProcessor</code> 
will be called on
   * the child itself.
   * <p>
   * FlattenedComponents that wish to check whether they are processed for the 
purpose of
   * encoding can check the ProcessingHints of the ComponentProcessingContext 
for the
   * presence of <code>PROCESS_FOR_ENCODING hint</code>.
   * @return <code>true</code> If any children were processed
   * @see UIXComponent#processFlattenedChildren(FacesContext, 
ComponentProcessor, Iterable, Object)
   * @see FlattenedComponent
   */
  public static <S> boolean encodeFlattenedChildren(
    FacesContext context,
    ComponentProcessor<S> childProcessor,
    Iterable<UIComponent> children,
    S callbackContext) throws IOException

When encoding their flattened children, the Renderers call one of the two 
encoding methods on UIXComponent.  If a FlattenedComponent wishes to check 
whether its children are being flattened for the purpose of encoding, it can 
check 
ComponentProcessingContext.getHints().contains(ProcessingHint.PROCESS_FOR_ENCODING)


-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to