So the architect I am working with (Chris Kulinski) came up with the
following patch to 1.1.5...

Index: src/main/java/javax/faces/component/UIComponent.java
===================================================================
--- src/main/java/javax/faces/component/UIComponent.java    (revision
536301)
+++ src/main/java/javax/faces/component/UIComponent.java    (working copy)
@@ -59,6 +59,8 @@

    public abstract boolean isRendered();

+    public abstract boolean isRenderedCached();
+
    public abstract void setRendered(boolean rendered);

    public abstract java.lang.String getRendererType();
Index: src/main/java/javax/faces/component/UIMessages.java
===================================================================
--- src/main/java/javax/faces/component/UIMessages.java    (revision 536301)
+++ src/main/java/javax/faces/component/UIMessages.java    (working copy)
@@ -28,7 +28,7 @@
 * @version $Revision$ $Date$
 */
public class UIMessages
-        extends UIComponentBase
+        extends UIComponentBaseCached
{
    //------------------ GENERATED CODE BEGIN (do not modify!)
--------------------

Index: src/main/java/javax/faces/component/UIData.java
===================================================================
--- src/main/java/javax/faces/component/UIData.java    (revision 536301)
+++ src/main/java/javax/faces/component/UIData.java    (working copy)
@@ -126,7 +126,7 @@
 * @author Manfred Geiler (latest modification by $Author$)
 * @version $Revision$ $Date$
 */
-public class UIData extends UIComponentBase implements NamingContainer
+public class UIData extends UIComponentBaseCached implements
NamingContainer
{
    private static final int STATE_SIZE = 5;
    private static final int SUPER_STATE_INDEX = 0;
@@ -577,7 +577,7 @@
    {
        if (context == null)
            throw new NullPointerException("context");
-        if (!isRendered())
+        if (!isRenderedCached())
            return;
        setRowIndex(-1);
        processFacets(context, PROCESS_DECODES);
@@ -599,7 +599,7 @@
    {
        if (context == null)
            throw new NullPointerException("context");
-        if (!isRendered())
+        if (!isRenderedCached())
            return;
        setRowIndex(-1);
        processFacets(context, PROCESS_VALIDATORS);
@@ -618,7 +618,7 @@
    {
        if (context == null)
            throw new NullPointerException("context");
-        if (!isRendered())
+        if (!isRenderedCached())
            return;
        setRowIndex(-1);
        processFacets(context, PROCESS_UPDATES);
@@ -656,7 +656,7 @@
            UIComponent child = (UIComponent) childIter.next();
            if (child instanceof UIColumn)
            {
-                if (!child.isRendered())
+                if (!child.isRenderedCached())
                {
                    //Column is not visible
                    continue;
@@ -705,7 +705,7 @@
                UIComponent child = (UIComponent) it.next();
                if (child instanceof UIColumn)
                {
-                    if (!child.isRendered())
+                    if (!child.isRenderedCached())
                    {
                        //Column is not visible
                        continue;
Index: src/main/java/javax/faces/component/UIParameter.java
===================================================================
--- src/main/java/javax/faces/component/UIParameter.java    (revision
536301)
+++ src/main/java/javax/faces/component/UIParameter.java    (working copy)
@@ -28,7 +28,7 @@
 * @version $Revision$ $Date$
 */
public class UIParameter
-        extends UIComponentBase
+        extends UIComponentBaseCached
{
    //------------------ GENERATED CODE BEGIN (do not modify!)
--------------------

Index: src/main/java/javax/faces/component/UIMessage.java
===================================================================
--- src/main/java/javax/faces/component/UIMessage.java    (revision 536301)
+++ src/main/java/javax/faces/component/UIMessage.java    (working copy)
@@ -30,7 +30,7 @@
 * @version $Revision$ $Date$
 */
public class UIMessage
-        extends UIComponentBase
+        extends UIComponentBaseCached
{
    //------------------ GENERATED CODE BEGIN (do not modify!)
--------------------

Index: src/main/java/javax/faces/component/UIForm.java
===================================================================
--- src/main/java/javax/faces/component/UIForm.java    (revision 536301)
+++ src/main/java/javax/faces/component/UIForm.java    (working copy)
@@ -28,7 +28,7 @@
 * @version $Revision$ $Date$
 */
public class UIForm
-        extends UIComponentBase
+        extends UIComponentBaseCached
        implements NamingContainer
{
    //private static final Log log = LogFactory.getLog(UIForm.class);
Index: src/main/java/javax/faces/component/UIGraphic.java
===================================================================
--- src/main/java/javax/faces/component/UIGraphic.java    (revision 536301)
+++ src/main/java/javax/faces/component/UIGraphic.java    (working copy)
@@ -28,7 +28,7 @@
 * @version $Revision$ $Date$
 */
public class UIGraphic
-        extends UIComponentBase
+        extends UIComponentBaseCached
{
    private static final String URL_PROPERTY = "url";
    private static final String VALUE_PROPERTY = "value";
Index: src/main/java/javax/faces/component/UICommand.java
===================================================================
--- src/main/java/javax/faces/component/UICommand.java    (revision 536301)
+++ src/main/java/javax/faces/component/UICommand.java    (working copy)
@@ -31,7 +31,7 @@
 * @version $Revision$ $Date$
 */
public class UICommand
-        extends UIComponentBase
+        extends UIComponentBaseCached
        implements ActionSource
{
    private MethodBinding _action = null;
Index: src/main/java/javax/faces/component/UIViewRoot.java
===================================================================
--- src/main/java/javax/faces/component/UIViewRoot.java    (revision 536301)
+++ src/main/java/javax/faces/component/UIViewRoot.java    (working copy)
@@ -38,7 +38,7 @@
 * @version $Revision$ $Date$
 */
public class UIViewRoot
-        extends UIComponentBase
+        extends UIComponentBaseCached
{
    public static final String UNIQUE_ID_PREFIX = "_id";

Index: src/main/java/javax/faces/component/UIColumn.java
===================================================================
--- src/main/java/javax/faces/component/UIColumn.java    (revision 536301)
+++ src/main/java/javax/faces/component/UIColumn.java    (working copy)
@@ -27,7 +27,7 @@
 * @version $Revision$ $Date$
 */
public class UIColumn
-        extends UIComponentBase
+        extends UIComponentBaseCached
{
    private static final String FOOTER_FACET_NAME = "footer";
    private static final String HEADER_FACET_NAME = "header";
Index: src/main/java/javax/faces/component/UIComponentBase.java
===================================================================
--- src/main/java/javax/faces/component/UIComponentBase.java    (revision
536301)
+++ src/main/java/javax/faces/component/UIComponentBase.java    (working
copy)
@@ -508,7 +508,7 @@
            throws IOException
    {
        if (context == null) throw new NullPointerException("context");
-        if (!isRendered()) return;
+        if (!isRenderedCached()) return;
        Renderer renderer = getRenderer(context);
        if (renderer != null)
        {
@@ -520,7 +520,7 @@
            throws IOException
    {
        if (context == null) throw new NullPointerException("context");
-        if (!isRendered()) return;
+        if (!isRenderedCached()) return;
        Renderer renderer = getRenderer(context);
        if (renderer != null)
        {
@@ -532,7 +532,7 @@
            throws IOException
    {
        if (context == null) throw new NullPointerException("context");
-        if (!isRendered()) return;
+        if (!isRenderedCached()) return;
        Renderer renderer = getRenderer(context);
        if (renderer != null)
        {
@@ -598,7 +598,7 @@
    public void processDecodes(FacesContext context)
    {
        if (context == null) throw new NullPointerException("context");
-                if (!isRendered()) return;
+                if (!isRenderedCached()) return;
        for (Iterator it = getFacetsAndChildren(); it.hasNext(); )
        {
            UIComponent childOrFacet = (UIComponent)it.next();
@@ -619,7 +619,7 @@
    public void processValidators(FacesContext context)
    {
        if (context == null) throw new NullPointerException("context");
-        if (!isRendered()) return;
+        if (!isRenderedCached()) return;

        for (Iterator it = getFacetsAndChildren(); it.hasNext(); )
        {
@@ -640,7 +640,7 @@
    public void processUpdates(FacesContext context)
    {
        if (context == null) throw new NullPointerException("context");
-        if (!isRendered()) return;
+        if (!isRenderedCached()) return;

        for (Iterator it = getFacetsAndChildren(); it.hasNext(); )
        {
@@ -1063,6 +1063,7 @@

    private Boolean _rendered = null;
    private String _rendererType = null;
+    private Boolean _renderedCached = null;



@@ -1072,11 +1073,29 @@
    }

    public boolean isRendered()
+    {
+        if (_rendered != null) return _rendered.booleanValue();
+        ValueBinding vb = getValueBinding("rendered");
+        // AUTOTRADER: Cache the rendered value so its not computed
multiple times.
+        _renderedCached = vb != null ?
(Boolean)vb.getValue(getFacesContext()) : null;
+        return _renderedCached != null ? _renderedCached.booleanValue() :
DEFAULT_RENDERED;
+    }
+
+    public boolean isRenderedCached()
    {
        if (_rendered != null) return _rendered.booleanValue();
+
+        // AUTOTRADER: Cache the rendered value so its not computed
multiple times.
+        if (_renderedCached != null) {
+            //System.out.println("using CACHED value for:"+getId()+"
"+this);
+            return _renderedCached.booleanValue();
+        }
+
        ValueBinding vb = getValueBinding("rendered");
-        Boolean v = vb != null ? (Boolean)vb.getValue(getFacesContext()) :
null;
-        return v != null ? v.booleanValue() : DEFAULT_RENDERED;
+        // AUTOTRADER: Cache the rendered value so its not computed
multiple times.
+        _renderedCached = vb != null ?
(Boolean)vb.getValue(getFacesContext()) : null;
+        //System.out.println("Computing NO CACHE value for:"+getId()+"
"+this);
+        return _renderedCached != null ? _renderedCached.booleanValue() :
DEFAULT_RENDERED;
    }

    public void setRendererType(String rendererType)
Index: src/main/java/javax/faces/component/UIPanel.java
===================================================================
--- src/main/java/javax/faces/component/UIPanel.java    (revision 536301)
+++ src/main/java/javax/faces/component/UIPanel.java    (working copy)
@@ -27,7 +27,7 @@
 * @version $Revision$ $Date$
 */
public class UIPanel
-        extends UIComponentBase
+        extends UIComponentBaseCached
{
    //------------------ GENERATED CODE BEGIN (do not modify!)
--------------------

Index: src/main/java/javax/faces/component/UIOutput.java
===================================================================
--- src/main/java/javax/faces/component/UIOutput.java    (revision 536301)
+++ src/main/java/javax/faces/component/UIOutput.java    (working copy)
@@ -29,7 +29,7 @@
 * @version $Revision$ $Date$
 */
public class UIOutput
-        extends UIComponentBase
+        extends UIComponentBaseCached
        implements ValueHolder
{
    public Object getLocalValue()
---------------------------------------------------------------------------------

and here is the UIComponentBaseCached class:

package javax.faces.component;

public abstract class UIComponentBaseCached extends UIComponentBase {

   public boolean isRendered()
   {
       return isRenderedCached();
   }
}


So far so good, I will post the results if anything stops working.

Wesley



On 5/9/07, Wesley Hales <[EMAIL PROTECTED]> wrote:

I am trying to address this at a framework level (i.e. I'm not rewriting
the renderer for each component that calls an EL method)

On 5/9/07, Adam Winer <[EMAIL PROTECTED]> wrote:
>
> Technically, rendered is supposed to be:
> - Constant across encodeBegin()/encodeChildren()/encodeEnd()
> - Constant across processDecodes()/processValidators()/
>    processUpdateModel().
>
> Unfortunately, the latter doesn't help - since a component inside
> a table would have processDecodes() called repeatedly,
> then processValidators() repeatedly, etc. - and "rendered"
> could be different from one row to the next.
>
> But the former should be fine - if you always fetch and
> store the value in encodeBegin() (whether or not encodeBegin()
> has previously been called), then use that in encodeChildren()
> and encodeEnd(), you should be fine.
>
> -- Adam
>
>
> On 5/8/07, Simon Kitching < [EMAIL PROTECTED]> wrote:
> > Andrew, are you just stating what currently happens or are you saying
> > that there is a *reason* for evaluating "rendered" in encodeBegin,
> > encodeChildren and encodeEnd?
> >
> > I can't initially see any reason why it would need to be evaluated
> more
> > than once.
> >
> > UIComponentBase does indeed call isRendered in encodeBegin,
> > encodeChildren and encodeEnd. It also implements isRendered as an
> > evaluation of the EL expression (myfaces 1.1.3 implementation).
> >
> > But As Wesley asks, why would it ever make sense for rendered to be
> true
> > in encodeBegin, but false in encodeEnd? I cannot see any way that
> would
> > be useful, so why not just compute it once then cache it somewhere for
> > the rest of that render cycle (eg in a "transient" member of the
> > component)? This would be a significant performance boost..
> >
> > Wesley, your proposed modification which stores the rendered state
> into
> > _rendered is not good because setting _rendered will permanently
> > override the rendered EL expression, not just for the current render
> > cycle but for the lifetime of that component. What is needed is to
> > figure out when the first call to isRendered is done *during the
> render
> > cycle* and then cache that until rendering finishes. Note that
> > isRendered is also called during postback processing, and it's
> perfectly
> > reasonable to change this value between postback and render so caching
>
> > really should only be done between encodeBegin() and encodeEnd(). So
> > implementing this optimisation is a little tricky - but not impossible
> > I'm sure.
> >
> > Regards,
> >
> > Simon
> >
> > Andrew Robinson wrote:
> > > At the very least rendered is called during encodeBegin,
> > > encodeChildren, and encodeEnd.
> > >
> > > On 5/8/07, Wesley Hales < [EMAIL PROTECTED]> wrote:
> > >> Hello - Why do we continually call isRendered after encodeBegin()?
> > >> Once the
> > >> begin tag is written out, it shouldn't matter what the body and end
>
> > >> rendered
> > >> states are.
> > >>
> > >> Facelets 1.1.11
> > >>  Myfaces 1.1.5 & 1.2
> > >>
> > >> So if I have  <t:div rendered="#{ MyBean.alerts > 0}"...
> > >> The #{MyBean.alerts method is called 5 times! and it is like this
> for
> > >> every
> > >> EL eval on the page. I do know that EL can only bind to the
> > >> FaceletsContext
> > >> and no other scopes... So are there any other options than what I
> have
> > >> listed below?
> > >>
> > >> 1. Tried to modify MyFaces src in UIComponentBase:
> > >> public boolean isRendered()
> > >>      {
> > >>            if(_rendered == null){
> > >>
> > >>            // our modification! Only compute the rendered value
> once, and
> > >> cache for the rest of the lifecycle.
> > >>            Boolean rend = getExpressionValue("rendered", _rendered,
> > >> DEFAULT_RENDERED);
> > >>            _rendered = rend.booleanValue();
> > >>            }
> > >>          return _rendered;
> > >>      }
> > >> This didn't work :( - Something happend to A4J and we had no ideas
> > >> what the
> > >> implication would be on all components.
> > >>
> > >> 2. Tried using Facelets <ui:param and <c:set to store the EL in a
> page
> > >> scoped variable, then have the variable evaluated in the rendered
> > >> attribute.
> > >> This didn't work either because it is on FacesContext.
> > >>
> > >> So this may just be me not fully understanding  what JSF does
> behind the
> > >> scenes of component rendering, or some people say that  the spec is
>
> > >> screwed
> > >> up when it comes to this. I'm sure some of the pros can help me out
> > >> here :).
> > >>
> > >> Thx,
> > >> Wesley Hales
> >
> >
>


Reply via email to