You may want to submit a comment for the JSF specification on changing
this behavior.

On 5/9/07, Wesley Hales <[EMAIL PROTECTED]> wrote:
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