You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Blake Sullivan <bl...@oracle.com> on 2009/06/12 23:50:04 UTC
[TRINIDAD][API] JIRA_1504 Allow FlattenedComponent to render content
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)
-- Blake Sullivan