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.