You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2011/09/30 16:31:46 UTC

svn commit: r1177679 [1/3] - in /myfaces/core/branches/2.0.x/impl/src: main/java/org/apache/myfaces/view/facelets/ main/java/org/apache/myfaces/view/facelets/compiler/ main/java/org/apache/myfaces/view/facelets/impl/ main/java/org/apache/myfaces/view/f...

Author: lu4242
Date: Fri Sep 30 14:31:45 2011
New Revision: 1177679

URL: http://svn.apache.org/viewvc?rev=1177679&view=rev
Log:
MYFACES-3329 Fix PSS algorithm to ensure c:if and ui:include src="#{...}" related use cases will work without rely on org.apache.myfaces.REFRESH_TRANSIENT_BUILD_ON_PSS_PRESERVE_STATE 
MYFACES-3331 Identifier stored on MARK_CREATED should be unique per component on the same 
MYFACES-3330 MYFACES-3329 Generate small generated unique ids for components without explicit ids
MYFACES-3332 Fix condition to call ComponentSupport.markComponentToRestoreFully on 2.1.x branch 

Added:
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/FaceletState.java
    myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/compiler/UniqueComponentIdTestCase.java
    myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/impl/   (with props)
    myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounterTest.java
    myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/compiler/testUniqueComponentIdChoose.xhtml
    myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/compiler/testUniqueComponentIdCif.xhtml
    myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/compiler/testUniqueComponentIdDecorate1.xhtml
    myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/compiler/testUniqueComponentIdDecorate1_0.xhtml
    myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/compiler/testUniqueComponentIdDecorate1_1.xhtml
    myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/compiler/testUniqueComponentIdDecorate1_2.xhtml
    myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/compiler/testUniqueComponentIdInclude1.xhtml
    myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/compiler/testUniqueComponentIdInclude1_0.xhtml
    myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/compiler/testUniqueComponentIdInclude1_1.xhtml
    myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/compiler/testUniqueComponentIdInclude1_2.xhtml
Modified:
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/UIInstructionHandler.java
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentSupport.java
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ChooseHandler.java
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ForEachHandler.java
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/IfHandler.java
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/ui/DecorateHandler.java
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/ui/IncludeHandler.java
    myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jstl/core/CifTestCase.java

Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java?rev=1177679&r1=1177678&r2=1177679&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java Fri Sep 30 14:31:45 2011
@@ -32,6 +32,7 @@ import javax.faces.FacesException;
 import javax.faces.FactoryFinder;
 import javax.faces.component.ContextCallback;
 import javax.faces.component.UIComponent;
+import javax.faces.component.UIComponentBase;
 import javax.faces.component.UIViewParameter;
 import javax.faces.component.UIViewRoot;
 import javax.faces.component.visit.VisitCallback;
@@ -55,6 +56,7 @@ import org.apache.myfaces.buildtools.mav
 import org.apache.myfaces.shared.util.ClassUtils;
 import org.apache.myfaces.shared.util.HashMapUtils;
 import org.apache.myfaces.shared.util.WebConfigParamUtils;
+import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
 
 /**
  * This class implements partial state saving feature when facelets
@@ -180,6 +182,7 @@ public class DefaultFaceletsStateManagem
         {
             // Per the spec: build the view.
             ViewDeclarationLanguage vdl = _vdlFactory.getViewDeclarationLanguage(viewId);
+            Object faceletViewState = null;
             try {
                 ViewMetadata metadata = vdl.getViewMetadata (context, viewId);
                 
@@ -201,6 +204,16 @@ public class DefaultFaceletsStateManagem
                 
                 context.setViewRoot (view); 
                 
+                if (state != null && state[1] != null)
+                {
+                    states = (Map<String, Object>) state[1];
+                    faceletViewState = UIComponentBase.restoreAttachedState(context,states.get(ComponentSupport.FACELET_STATE_INSTANCE));
+                    if (faceletViewState != null)
+                    {
+                        view.getAttributes().put(ComponentSupport.FACELET_STATE_INSTANCE,  faceletViewState);
+                    }
+                }
+
                 // TODO: Why is necessary enable event processing?
                 // ANS: On RestoreViewExecutor, setProcessingEvents is called first to false
                 // and then to true when postback. Since we need listeners registered to PostAddToViewEvent
@@ -238,6 +251,11 @@ public class DefaultFaceletsStateManagem
                 //Restore state of current components
                 restoreStateFromMap(context, states, view);
                 
+                if (faceletViewState != null)
+                {
+                    view.getAttributes().put(ComponentSupport.FACELET_STATE_INSTANCE,  faceletViewState);
+                }
+                
                 // TODO: handle dynamic add/removes as mandated by the spec.  Not sure how to do handle this yet.
                 List<String> clientIdsRemoved = getClientIdsRemoved(view);
                 
@@ -465,6 +483,13 @@ public class DefaultFaceletsStateManagem
             {
                 states = new HashMap<String, Object>();
 
+                Object faceletViewState = view.getAttributes().get(ComponentSupport.FACELET_STATE_INSTANCE);
+                if (faceletViewState != null)
+                {
+                    ((Map<String, Object>)states).put(ComponentSupport.FACELET_STATE_INSTANCE, UIComponentBase.saveAttachedState(context, faceletViewState));
+                    //Do not save on UIViewRoot
+                    view.getAttributes().remove(ComponentSupport.FACELET_STATE_INSTANCE);
+                }
                 if (isSaveStateWithVisitTreeOnPSS(context))
                 {
                     saveStateOnMapVisitTree(context,(Map<String,Object>) states, view);

Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java?rev=1177679&r1=1177678&r2=1177679&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java Fri Sep 30 14:31:45 2011
@@ -352,4 +352,49 @@ abstract public class FaceletComposition
     {
         return true;
     }
+
+    /**
+     * Start a new unique id section, which means a new counter is used to
+     * generate unique ids to components
+     * 
+     * @since 2.0.10, 2.1.4
+     * @return
+     */
+    public String startComponentUniqueIdSection()
+    {
+        return null;
+    }
+    
+    /**
+     * Generate a unique id that will be used later to derive a unique id per tag
+     * by FaceletContext.generateUniqueId(). This generator ensures uniqueness per
+     * view but FaceletContext.generateUniqueId() ensures uniqueness per view and
+     * per facelet hierarchy, so different included facelets will generate different
+     * ids.
+     * 
+     * @return
+     */
+    public String generateUniqueId()
+    {
+        return null;
+    }
+    
+    /**
+     * Generate a unique id for component instances. 
+     * 
+     * @return
+     */
+    public String generateUniqueComponentId()
+    {
+        return null;
+    }
+
+    /**
+     * Ends the current unique id section, so the previous counter will be used
+     * to generate unique ids to components.
+     */
+    public void endComponentUniqueIdSection()
+    {
+    }
+    
 }

Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/UIInstructionHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/UIInstructionHandler.java?rev=1177679&r1=1177678&r2=1177679&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/UIInstructionHandler.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/UIInstructionHandler.java Fri Sep 30 14:31:45 2011
@@ -93,6 +93,8 @@ final class UIInstructionHandler extends
             FaceletCompositionContext mctx= FaceletCompositionContext.getCurrentInstance(ctx);
             boolean componentFoundInserted = false;
             
+            String componentId = mctx.generateUniqueComponentId();
+            
             if (mctx.isRefreshingTransientBuild())
             {
                 c = ComponentSupport.findChildByTagId(parent, id);
@@ -180,7 +182,7 @@ final class UIInstructionHandler extends
                     // UIViewRoot implements UniqueIdVendor, so there is no need to cast to UIViewRoot
                     // and call createUniqueId(). Also, note that UIViewRoot.createUniqueId() javadoc
                     // says we could send as seed the facelet generated id.
-                    String uid = uniqueIdVendor.createUniqueId(ctx.getFacesContext(), id);
+                    String uid = uniqueIdVendor.createUniqueId(ctx.getFacesContext(), componentId);
                     c.setId(uid);
                 }                
                 c.getAttributes().put(ComponentSupport.MARK_CREATED, id);

Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java?rev=1177679&r1=1177678&r2=1177679&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java Fri Sep 30 14:31:45 2011
@@ -80,8 +80,8 @@ final class DefaultFaceletContext extend
 
     private FunctionMapper _fnMapper;
 
-    private final Map<String, Integer> _ids;
-    private final Map<Integer, Integer> _prefixes;
+    //private final Map<String, Integer> _ids;
+    //private final Map<Integer, Integer> _prefixes;
     private String _prefix;
 
     private final StringBuilder _uniqueIdBuilder = new StringBuilder(30);
@@ -106,8 +106,8 @@ final class DefaultFaceletContext extend
             AbstractFacelet facelet, boolean ccWrap)
     {
         _ctx = ctx._ctx;
-        _ids = ctx._ids;
-        _prefixes = ctx._prefixes;
+        //_ids = ctx._ids;
+        //_prefixes = ctx._prefixes;
         //_clients = ctx._clients;
         _faces = ctx._faces;
         _fnMapper = ctx._fnMapper;
@@ -161,8 +161,8 @@ final class DefaultFaceletContext extend
     public DefaultFaceletContext(FacesContext faces, AbstractFacelet facelet, FaceletCompositionContext mctx)
     {
         _ctx = faces.getELContext();
-        _ids = new HashMap<String, Integer>();
-        _prefixes = new HashMap<Integer, Integer>();
+        //_ids = new HashMap<String, Integer>();
+        //_prefixes = new HashMap<Integer, Integer>();
         //_clients = new LinkedList<TemplateManager>();
         _faces = faces;
         _fnMapper = _ctx.getFunctionMapper();
@@ -289,7 +289,38 @@ final class DefaultFaceletContext extend
     @Override
     public String generateUniqueId(String base)
     {
+        if (_prefix == null)
+        {
+            StringBuilder builder = new StringBuilder(
+                    _faceletHierarchy.size() * 30);
+            for (int i = 0; i < _faceletHierarchy.size(); i++)
+            {
+                AbstractFacelet facelet = _faceletHierarchy.get(i);
+                builder.append(facelet.getAlias());
+            }
 
+            // Integer prefixInt = new Integer(builder.toString().hashCode());
+            // -= Leonardo Uribe =- if the previous formula is used, it is possible that
+            // negative values are introduced. The presence of '-' char causes problems
+            // with htmlunit 2.4 or lower, so in order to prevent it it is better to use
+            // only positive values instead.
+            // Take into account CompilationManager.nextTagId() uses Math.abs too.
+            Integer prefixInt = new Integer(Math.abs(builder.toString().hashCode()));
+            _prefix = prefixInt.toString();
+        }
+
+        _uniqueIdBuilder.delete(0, _uniqueIdBuilder.length());
+        // getFaceletCompositionContext().generateUniqueId() is the one who ensures
+        // the final id will be unique, but prefix and base ensure it will be unique
+        // per facelet because prefix is calculated from faceletHierarchy and base is
+        // related to the tagId, which depends on the location.
+        _uniqueIdBuilder.append(getFaceletCompositionContext().generateUniqueId());
+        _uniqueIdBuilder.append("_");
+        _uniqueIdBuilder.append(_prefix);
+        _uniqueIdBuilder.append("_");
+        _uniqueIdBuilder.append(base);
+        return _uniqueIdBuilder.toString();
+        /*
         if (_prefix == null)
         {
             StringBuilder builder = new StringBuilder(
@@ -327,6 +358,8 @@ final class DefaultFaceletContext extend
         {
             _ids.put(base, Integer.valueOf(0));
             _uniqueIdBuilder.delete(0, _uniqueIdBuilder.length());
+            _uniqueIdBuilder.append(getFaceletCompositionContext().generateUniqueId());
+            _uniqueIdBuilder.append("_");
             _uniqueIdBuilder.append(_prefix);
             _uniqueIdBuilder.append("_");
             _uniqueIdBuilder.append(base);
@@ -337,13 +370,15 @@ final class DefaultFaceletContext extend
             int i = cnt.intValue() + 1;
             _ids.put(base, Integer.valueOf(i));
             _uniqueIdBuilder.delete(0, _uniqueIdBuilder.length());
+            _uniqueIdBuilder.append(getFaceletCompositionContext().generateUniqueId());
+            _uniqueIdBuilder.append("_");
             _uniqueIdBuilder.append(_prefix);
             _uniqueIdBuilder.append("_");
             _uniqueIdBuilder.append(base);
             _uniqueIdBuilder.append("_");
             _uniqueIdBuilder.append(i);
             return _uniqueIdBuilder.toString();
-        }
+        }*/
     }
 
     /**

Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java?rev=1177679&r1=1177678&r2=1177679&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java Fri Sep 30 14:31:45 2011
@@ -108,6 +108,10 @@ public class FaceletCompositionContextIm
 
     private static final String VIEWROOT_FACELET_ID = "oam.VIEW_ROOT";
     
+    private SectionUniqueIdCounter _sectionUniqueIdCounter;
+    
+    private SectionUniqueIdCounter _sectionUniqueComponentIdCounter;
+    
     public FaceletCompositionContextImpl(FaceletFactory factory, FacesContext facesContext)
     {
         super();
@@ -118,6 +122,8 @@ public class FaceletCompositionContextIm
         _methodExpressionsTargeted = new HashMap<UIComponent, Map<String, Object>>();
         _compositeComponentAttributesMarked = new HashMap<UIComponent, Map<String, Boolean>>();
         _deletionLevel = -1;
+        _sectionUniqueIdCounter = new SectionUniqueIdCounter();
+        _sectionUniqueComponentIdCounter = new SectionUniqueIdCounter("_");
     }
 
     public FaceletFactory getFaceletFactory()
@@ -137,6 +143,8 @@ public class FaceletCompositionContextIm
         _uniqueIdVendorStack = null;
         _validationGroupsStack = null;
         _componentsMarkedForDeletion = null;
+        _sectionUniqueIdCounter = null;
+        _sectionUniqueComponentIdCounter = null;
     }
    
     @Override
@@ -664,5 +672,27 @@ public class FaceletCompositionContextIm
         }
         
         decreaseComponentLevelMarkedForDeletion();
-    }    
+    }
+    
+    public String startComponentUniqueIdSection()
+    {
+        _sectionUniqueComponentIdCounter.startUniqueIdSection();
+        return _sectionUniqueIdCounter.startUniqueIdSection();
+    }
+    
+    public String generateUniqueId()
+    {
+        return _sectionUniqueIdCounter.generateUniqueId();
+    }
+    
+    public String generateUniqueComponentId()
+    {
+        return _sectionUniqueComponentIdCounter.generateUniqueId();
+    }
+    
+    public void endComponentUniqueIdSection()
+    {
+        _sectionUniqueIdCounter.endUniqueIdSection();
+        _sectionUniqueComponentIdCounter.endUniqueIdSection();
+    }
 }

Added: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java?rev=1177679&view=auto
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java (added)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java Fri Sep 30 14:31:45 2011
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Hierarchical counter to generate unique ids.
+ * 
+ * @author Leonardo Uribe
+ *
+ */
+public class SectionUniqueIdCounter
+{
+    private List<Section> _counterStack;
+    
+    private int _activeSection;
+    
+    private final String _prefix;
+    
+    private final StringBuilder _builder;
+    
+    private final int _radix;
+   
+    public SectionUniqueIdCounter()
+    {
+        _activeSection = 0;
+        _radix = Character.MAX_RADIX;
+        _counterStack = new ArrayList<Section>();
+        _counterStack.add(new Section(null,1,_radix));
+        _prefix = null;
+        _builder = new StringBuilder(30);
+    }
+    
+    public SectionUniqueIdCounter(String prefix)
+    {
+        _activeSection = 0;
+        _radix = Character.MAX_RADIX;
+        _counterStack = new ArrayList<Section>();
+        _counterStack.add(new Section(null,1,_radix));
+        _prefix = prefix;
+        _builder = new StringBuilder(30);
+    }
+    
+    public SectionUniqueIdCounter(String prefix, int radix)
+    {
+        _activeSection = 0;
+        _radix = radix;
+        _counterStack = new ArrayList<Section>();
+        _counterStack.add(new Section(null,1,_radix));
+        _prefix = prefix;
+        _builder = new StringBuilder(30);
+    }
+
+    public String startUniqueIdSection()
+    {
+        //1. Calculate prefix
+        _builder.delete(0, _builder.length());
+        boolean added = false;
+        for (int i = 0; i < _counterStack.size(); i++)
+        {
+            if (added)
+            {
+                _builder.append('_');
+            }
+            _builder.append(Long.toString(_counterStack.get(i).getCounter(), _radix));
+            added = true;
+        }
+        
+        _counterStack.add(new Section(_builder.toString(),1,_radix));
+        _activeSection++;
+        return _builder.toString();
+    }
+    
+    public String startUniqueIdSection(String base)
+    {
+        //1. Calculate prefix
+        _builder.delete(0, _builder.length());
+        boolean added = false;
+        for (int i = 0; i < _counterStack.size(); i++)
+        {
+            if (added)
+            {
+                _builder.append('_');
+            }
+            _builder.append(Long.toString(_counterStack.get(i).getCounter(), _radix));
+            added = true;
+        }
+        if (base != null && base.length() > 0)
+        {
+            _builder.append('_');
+            _builder.append(base);
+        }
+        _counterStack.add(new Section(_builder.toString(),1,_radix));
+        _activeSection++;
+        return _builder.toString();
+    }
+
+    public String generateUniqueId()
+    {
+        return _counterStack.get(_activeSection).generateUniqueId(_prefix);
+    }
+    
+    public void endUniqueIdSection()
+    {
+        if (_activeSection <= 0)
+        {
+            _counterStack.get(_activeSection).generateUniqueId(_prefix);
+            return;
+        }
+        else
+        {
+            _counterStack.remove(_activeSection);
+            _activeSection--;
+            _counterStack.get(_activeSection).generateUniqueId(_prefix);
+        }
+    }
+    
+    private static class Section {
+        
+        private String prefix;
+        private long counter;
+        private final StringBuilder _builder;
+        private final int _radix;
+        
+        public Section(String prefix, long counter, int radix)
+        {
+            super();
+            this.prefix = prefix;
+            this.counter = counter;
+            _builder = new StringBuilder(30);
+            _radix = radix;
+        }
+
+        public long getCounter()
+        {
+            return counter;
+        }
+
+        public String generateUniqueId(String base)
+        {
+            long i = this.counter;
+            this.counter++;
+            _builder.delete(0, _builder.length());
+            if (base != null)
+            {
+                _builder.append(base);
+            }
+            if (this.prefix != null)
+            {
+                _builder.append(this.prefix);
+                _builder.append('_');
+            }
+            _builder.append(Long.toString(i, _radix));
+            return _builder.toString();
+        }
+    }
+}

Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentSupport.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentSupport.java?rev=1177679&r1=1177678&r2=1177679&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentSupport.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentSupport.java Fri Sep 30 14:31:45 2011
@@ -31,6 +31,7 @@ import javax.faces.component.UINamingCon
 import javax.faces.component.UIPanel;
 import javax.faces.component.UIViewRoot;
 import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
 import javax.faces.view.facelets.FaceletContext;
 import javax.faces.view.facelets.TagAttribute;
 import javax.faces.view.facelets.TagAttributeException;
@@ -38,6 +39,7 @@ import javax.faces.view.facelets.TagAttr
 import org.apache.myfaces.shared.config.MyfacesConfig;
 import org.apache.myfaces.view.facelets.ComponentState;
 import org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy;
+import org.apache.myfaces.view.facelets.FaceletCompositionContext;
 import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage;
 
 /**
@@ -57,6 +59,11 @@ public final class ComponentSupport
      * This constant is duplicate in javax.faces.webapp.UIComponentClassicTagBase
      */
     public final static String FACET_CREATED_UIPANEL_MARKER = "org.apache.myfaces.facet.createdUIPanel";
+    
+    /**
+     * The key under the facelet state map is stored
+     */
+    public final static String FACELET_STATE_INSTANCE = "oam.FACELET_STATE_INSTANCE";
 
     /**
      * Used in conjunction with markForDeletion where any UIComponent marked will be removed.
@@ -530,4 +537,48 @@ public final class ComponentSupport
         }
         return sb.toString();
     }
+    
+    public static Object restoreInitialTagState(FaceletContext ctx, FaceletCompositionContext fcc, UIComponent parent, String uniqueId)
+    {
+        Object value = null;
+        if (fcc.isUsingPSSOnThisView() &&
+                PhaseId.RESTORE_VIEW.equals(ctx.getFacesContext().getCurrentPhaseId()) &&
+                !MyfacesConfig.getCurrentInstance(ctx.getFacesContext().getExternalContext()).isRefreshTransientBuildOnPSSPreserveState())
+        {
+            UIViewRoot root = getViewRoot(ctx, parent);
+            FaceletState map = (FaceletState) root.getAttributes().get(FACELET_STATE_INSTANCE);
+            if (map == null)
+            {
+                value = null;
+            }
+            else
+            {
+                value = map.getState(uniqueId);
+            }
+        }
+        return value;
+    }
+    
+    public static void saveInitialTagState(FaceletContext ctx, FaceletCompositionContext fcc, UIComponent parent, String uniqueId, Object value)
+    {
+        if (fcc.isUsingPSSOnThisView())
+        {
+            // Only save the value when the view was built the first time, to ensure PSS algorithm 
+            // work correctly. If preserve state is enabled, just ignore it, because this tag will
+            // force full restore over the parent
+            if (!fcc.isRefreshingTransientBuild() && !ctx.getFacesContext().isPostback()
+                && !MyfacesConfig.getCurrentInstance(ctx.getFacesContext().getExternalContext()).isRefreshTransientBuildOnPSSPreserveState())
+            {
+                UIViewRoot root = getViewRoot(ctx, parent);
+                FaceletState map = (FaceletState) root.getAttributes().get(FACELET_STATE_INSTANCE);
+                if (map == null)
+                {
+                    map = new FaceletState();
+                    root.getAttributes().put(FACELET_STATE_INSTANCE, map);
+                }
+                map.putState(uniqueId, value);
+            }
+        }
+    }
+
 }

Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java?rev=1177679&r1=1177678&r2=1177679&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java Fri Sep 30 14:31:45 2011
@@ -190,6 +190,8 @@ public class ComponentTagHandlerDelegate
         // Cast to use UniqueIdVendor stuff
         FaceletCompositionContext mctx = (FaceletCompositionContext) FaceletCompositionContext.getCurrentInstance(ctx);
                 
+        String componentId = mctx.generateUniqueComponentId();
+            
         // grab our component
         UIComponent c = null;
         //boolean componentFoundInserted = false;
@@ -301,7 +303,7 @@ public class ComponentTagHandlerDelegate
                 {
                     // UIViewRoot implements UniqueIdVendor, so there is no need to cast to UIViewRoot
                     // and call createUniqueId()
-                    String uid = uniqueIdVendor.createUniqueId(facesContext, id);
+                    String uid = uniqueIdVendor.createUniqueId(facesContext, componentId);
                     c.setId(uid);
                 }
             }

Added: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/FaceletState.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/FaceletState.java?rev=1177679&view=auto
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/FaceletState.java (added)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/FaceletState.java Fri Sep 30 14:31:45 2011
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.tag.jsf;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.faces.component.StateHolder;
+import javax.faces.component.UIComponentBase;
+import javax.faces.context.FacesContext;
+
+public class FaceletState implements StateHolder, Serializable
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -7823771271935942737L;
+    
+    public Map<String, Object> stateMap;
+    
+    public Object getState(String key)
+    {
+        if(stateMap == null)
+        {
+            return null;
+        }
+        return stateMap.get(key);
+    }
+    
+    public Object putState(String key, Object value)
+    {
+        if (stateMap == null)
+        {
+            stateMap = new HashMap<String, Object>();
+        }
+        return stateMap.put(key, value);
+    }
+    
+
+    public Object saveState(FacesContext context)
+    {
+        if (stateMap != null)
+        {
+            return UIComponentBase.saveAttachedState(context, stateMap);
+        }
+        return null;
+    }
+
+    @SuppressWarnings("unchecked")
+    public void restoreState(FacesContext context, Object state)
+    {
+        if (state == null)
+        {
+            stateMap = null;
+        }
+        else
+        {
+            stateMap = (Map<String,Object>) UIComponentBase.restoreAttachedState(context, state);
+        }
+    }
+
+    public boolean isTransient()
+    {
+        return false;
+    }
+
+    public void setTransient(boolean newTransientValue)
+    {
+    }
+
+}

Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ChooseHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ChooseHandler.java?rev=1177679&r1=1177678&r2=1177679&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ChooseHandler.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ChooseHandler.java Fri Sep 30 14:31:45 2011
@@ -83,24 +83,50 @@ public final class ChooseHandler extends
     public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, FaceletException,
             ELException
     {
+        FaceletCompositionContext fcc = FaceletCompositionContext.getCurrentInstance(ctx);
+        boolean processed = false;
+        //assign an unique id for this section
+        String uniqueId = fcc.startComponentUniqueIdSection();
+        Integer savedOption = getSavedOption(ctx, fcc, parent, uniqueId);
         for (int i = 0; i < this.when.length; i++)
         {
-            if (this.when[i].isTestTrue(ctx))
+            //Ensure each option has its unique section
+            fcc.startComponentUniqueIdSection();
+            if (!processed)
             {
-                this.when[i].apply(ctx, parent);
-                return;
+                if ((savedOption != null) ? savedOption.equals(i) : this.when[i].isTestTrue(ctx))
+                {
+                    this.when[i].apply(ctx, parent);
+                    processed = true;
+                    savedOption = i;
+                    //return;
+                }
             }
+            fcc.endComponentUniqueIdSection();
         }
         if (this.otherwise != null)
         {
-            this.otherwise.apply(ctx, parent);
+            fcc.startComponentUniqueIdSection();
+            if (!processed)
+            {
+                this.otherwise.apply(ctx, parent);
+                savedOption = -1;
+            }
+            fcc.endComponentUniqueIdSection();
         }
+        
+        fcc.endComponentUniqueIdSection();
 
-        if (FaceletCompositionContext.getCurrentInstance(ctx).
-                isMarkInitialStateAndIsRefreshTransientBuildOnPSS())
+        ComponentSupport.saveInitialTagState(ctx, fcc, parent, uniqueId, savedOption);
+        if (fcc.isUsingPSSOnThisView() && fcc.isRefreshTransientBuildOnPSS() && !fcc.isRefreshingTransientBuild())
         {
             //Mark the parent component to be saved and restored fully.
             ComponentSupport.markComponentToRestoreFully(ctx.getFacesContext(), parent);
         }
     }
+    
+    private Integer getSavedOption(FaceletContext ctx, FaceletCompositionContext fcc, UIComponent parent, String uniqueId)
+    {
+        return (Integer) ComponentSupport.restoreInitialTagState(ctx, fcc, parent, uniqueId);
+    }
 }

Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ForEachHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ForEachHandler.java?rev=1177679&r1=1177678&r2=1177679&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ForEachHandler.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ForEachHandler.java Fri Sep 30 14:31:45 2011
@@ -190,8 +190,10 @@ public final class ForEachHandler extend
             }
             src = b;
         }
+        FaceletCompositionContext fcc = FaceletCompositionContext.getCurrentInstance(ctx);
         if (src != null)
         {
+            fcc.startComponentUniqueIdSection();
             Iterator<?> itr = this.toIterator(src);
             if (itr != null)
             {
@@ -276,10 +278,10 @@ public final class ForEachHandler extend
                     }
                 }
             }
+            fcc.endComponentUniqueIdSection();
         }
 
-        if (FaceletCompositionContext.getCurrentInstance(ctx).
-                isMarkInitialStateAndIsRefreshTransientBuildOnPSS())
+        if (fcc.isUsingPSSOnThisView() && fcc.isRefreshTransientBuildOnPSS() && !fcc.isRefreshingTransientBuild())
         {
             //Mark the parent component to be saved and restored fully.
             ComponentSupport.markComponentToRestoreFully(ctx.getFacesContext(), parent);

Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/IfHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/IfHandler.java?rev=1177679&r1=1177678&r2=1177679&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/IfHandler.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/IfHandler.java Fri Sep 30 14:31:45 2011
@@ -30,7 +30,6 @@ import javax.faces.view.facelets.TagHand
 
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletAttribute;
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
-import org.apache.myfaces.view.facelets.AbstractFaceletContext;
 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
 import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
 
@@ -77,7 +76,9 @@ public final class IfHandler extends Tag
 
     public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, ELException
     {
-        boolean b = this.test.getBoolean(ctx);
+        FaceletCompositionContext fcc = FaceletCompositionContext.getCurrentInstance(ctx);
+        String uniqueId = fcc.startComponentUniqueIdSection();
+        boolean b = getTestValue(ctx, fcc, parent, uniqueId);
         if (this.var != null)
         {
             ctx.setAttribute(var.getValue(ctx), new Boolean(b));
@@ -86,13 +87,26 @@ public final class IfHandler extends Tag
         {
             this.nextHandler.apply(ctx, parent);
         }
+        fcc.endComponentUniqueIdSection();
         //AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
-        if (FaceletCompositionContext.getCurrentInstance(ctx).
-                isMarkInitialStateAndIsRefreshTransientBuildOnPSS())
+        ComponentSupport.saveInitialTagState(ctx, fcc, parent, uniqueId, b);
+        if (fcc.isUsingPSSOnThisView() && fcc.isRefreshTransientBuildOnPSS() && !fcc.isRefreshingTransientBuild())
         {
             //Mark the parent component to be saved and restored fully.
             ComponentSupport.markComponentToRestoreFully(ctx.getFacesContext(), parent);
         }
     }
-
+    
+    private boolean getTestValue(FaceletContext ctx, FaceletCompositionContext fcc, UIComponent parent, String uniqueId)
+    {
+        Boolean b = (Boolean) ComponentSupport.restoreInitialTagState(ctx, fcc, parent, uniqueId);
+        if (b != null)
+        {
+            return b.booleanValue();
+        }
+        else
+        {
+            return this.test.getBoolean(ctx);
+        }
+    }
 }

Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/ui/DecorateHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/ui/DecorateHandler.java?rev=1177679&r1=1177678&r2=1177679&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/ui/DecorateHandler.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/ui/DecorateHandler.java Fri Sep 30 14:31:45 2011
@@ -26,7 +26,6 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import javax.el.ELException;
-import javax.el.VariableMapper;
 import javax.faces.FacesException;
 import javax.faces.component.UIComponent;
 import javax.faces.view.facelets.FaceletContext;
@@ -38,9 +37,10 @@ import javax.faces.view.facelets.TagHand
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletAttribute;
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
+import org.apache.myfaces.view.facelets.FaceletCompositionContext;
 import org.apache.myfaces.view.facelets.TemplateClient;
-import org.apache.myfaces.view.facelets.el.VariableMapperWrapper;
 import org.apache.myfaces.view.facelets.tag.TagHandlerUtils;
+import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
 
 /**
  * The decorate tag acts the same as a composition tag, but it will not trim 
@@ -143,15 +143,36 @@ public final class DecorateHandler exten
             }
         }
 
+        FaceletCompositionContext fcc = FaceletCompositionContext.getCurrentInstance(ctx);
+        String path;
+        if (!_template.isLiteral())
+        {
+            String uniqueId = fcc.startComponentUniqueIdSection();
+            path = getTemplateValue(actx, fcc, parent, uniqueId);
+            ComponentSupport.saveInitialTagState(ctx, fcc, parent, uniqueId, path);
+        }
+        else
+        {
+            path = _template.getValue(ctx);
+        }
         try
         {
-            ctx.includeFacelet(parent, _template.getValue(ctx));
+            ctx.includeFacelet(parent, path);
         }
         finally
         {
             //ctx.setVariableMapper(orig);
             actx.popClient(this);
         }
+        if (!_template.isLiteral())
+        {
+            fcc.endComponentUniqueIdSection();
+        }
+        if ( !_template.isLiteral() && fcc.isUsingPSSOnThisView() && fcc.isRefreshTransientBuildOnPSS() && !fcc.isRefreshingTransientBuild())
+        {
+            //Mark the parent component to be saved and restored fully.
+            ComponentSupport.markComponentToRestoreFully(ctx.getFacesContext(), parent);
+        }
     }
 
     public boolean apply(FaceletContext ctx, UIComponent parent, String name) throws IOException, FacesException,
@@ -176,4 +197,17 @@ public final class DecorateHandler exten
             return true;
         }
     }
+    
+    private String getTemplateValue(FaceletContext ctx, FaceletCompositionContext fcc, UIComponent parent, String uniqueId)
+    {
+        String template = (String) ComponentSupport.restoreInitialTagState(ctx, fcc, parent, uniqueId);
+        if (template != null)
+        {
+            return template;
+        }
+        else
+        {
+            return this._template.getValue(ctx);
+        }
+    }
 }

Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/ui/IncludeHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/ui/IncludeHandler.java?rev=1177679&r1=1177678&r2=1177679&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/ui/IncludeHandler.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/ui/IncludeHandler.java Fri Sep 30 14:31:45 2011
@@ -108,81 +108,113 @@ public final class IncludeHandler extend
             ELException
     {
         AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
-        String path = this.src.getValue(ctx);
-        if (path == null || path.length() == 0)
+        FaceletCompositionContext fcc = FaceletCompositionContext.getCurrentInstance(ctx);
+        String path;
+        if (!src.isLiteral())
         {
-            return;
+            String uniqueId = fcc.startComponentUniqueIdSection();
+            path = getSrcValue(actx, fcc, parent, uniqueId);
+            ComponentSupport.saveInitialTagState(ctx, fcc, parent, uniqueId, path);
+        }
+        else
+        {
+            path = this.src.getValue(ctx);
         }
-        VariableMapper orig = ctx.getVariableMapper();
-        ctx.setVariableMapper(new VariableMapperWrapper(orig));
         try
         {
-            //Only ui:param could be inside ui:include.
-            //this.nextHandler.apply(ctx, null);
-            
-            URL url = null;
-            // if we are in ProjectStage Development and the path equals "javax.faces.error.xhtml"
-            // we should include the default error page
-            if (ctx.getFacesContext().isProjectStage(ProjectStage.Development) 
-                    && ERROR_PAGE_INCLUDE_PATH.equals(path))
+            if (path == null || path.length() == 0)
             {
-                url =ClassUtils.getResource(ERROR_FACELET);
-                
+                return;
             }
+            VariableMapper orig = ctx.getVariableMapper();
+            ctx.setVariableMapper(new VariableMapperWrapper(orig));
             try
             {
-                if (_params != null)
+                //Only ui:param could be inside ui:include.
+                //this.nextHandler.apply(ctx, null);
+                
+                URL url = null;
+                // if we are in ProjectStage Development and the path equals "javax.faces.error.xhtml"
+                // we should include the default error page
+                if (ctx.getFacesContext().isProjectStage(ProjectStage.Development) 
+                        && ERROR_PAGE_INCLUDE_PATH.equals(path))
                 {
-                    // ui:include defines a new TemplateContext, but ui:param EL expressions
-                    // defined inside should be built before the new context is setup, to
-                    // apply then after. The final effect is EL expressions will be resolved
-                    // correctly when nested ui:params with the same name or based on other
-                    // ui:params are used.
+                    url =ClassUtils.getResource(ERROR_FACELET);
                     
-                    String[] names = new String[_params.length];
-                    ValueExpression[] values = new ValueExpression[_params.length];
-                    
-                    for (int i = 0; i < _params.length; i++)
+                }
+                try
+                {
+                    if (_params != null)
                     {
-                        names[i] = _params[i].getName(ctx);
-                        values[i] = _params[i].getValue(ctx);
+                        // ui:include defines a new TemplateContext, but ui:param EL expressions
+                        // defined inside should be built before the new context is setup, to
+                        // apply then after. The final effect is EL expressions will be resolved
+                        // correctly when nested ui:params with the same name or based on other
+                        // ui:params are used.
+                        
+                        String[] names = new String[_params.length];
+                        ValueExpression[] values = new ValueExpression[_params.length];
+                        
+                        for (int i = 0; i < _params.length; i++)
+                        {
+                            names[i] = _params[i].getName(ctx);
+                            values[i] = _params[i].getValue(ctx);
+                        }
+                        
+                        actx.pushTemplateContext(new TemplateContextImpl());
+                        
+                        for (int i = 0; i < _params.length; i++)
+                        {
+                            _params[i].apply(ctx, parent, names[i], values[i]);
+                        }
                     }
-                    
-                    actx.pushTemplateContext(new TemplateContextImpl());
-                    
-                    for (int i = 0; i < _params.length; i++)
+                    else
                     {
-                        _params[i].apply(ctx, parent, names[i], values[i]);
+                        actx.pushTemplateContext(new TemplateContextImpl());
+                    }
+                    if (url == null)
+                    {
+                        ctx.includeFacelet(parent, path);
+                    }
+                    else
+                    {
+                        ctx.includeFacelet(parent, url);
                     }
                 }
-                else
-                {
-                    actx.pushTemplateContext(new TemplateContextImpl());
-                }
-                if (url == null)
-                {
-                    ctx.includeFacelet(parent, path);
-                }
-                else
+                finally
                 {
-                    ctx.includeFacelet(parent, url);
+                    actx.popTemplateContext();
                 }
             }
             finally
             {
-                actx.popTemplateContext();
+                ctx.setVariableMapper(orig);
             }
         }
         finally
         {
-            ctx.setVariableMapper(orig);
+            if (!src.isLiteral())
+            {
+                fcc.endComponentUniqueIdSection();
+            }
         }
-        if ( !src.isLiteral() && FaceletCompositionContext.getCurrentInstance(ctx).
-                isMarkInitialStateAndIsRefreshTransientBuildOnPSS())
+        if ( !src.isLiteral() && fcc.isUsingPSSOnThisView() && fcc.isRefreshTransientBuildOnPSS() && !fcc.isRefreshingTransientBuild())
         {
             //Mark the parent component to be saved and restored fully.
             ComponentSupport.markComponentToRestoreFully(ctx.getFacesContext(), parent);
         }
     }
 
+    private String getSrcValue(FaceletContext ctx, FaceletCompositionContext fcc, UIComponent parent, String uniqueId)
+    {
+        String src = (String) ComponentSupport.restoreInitialTagState(ctx, fcc, parent, uniqueId);
+        if (src != null)
+        {
+            return src;
+        }
+        else
+        {
+            return this.src.getValue(ctx);
+        }
+    }
 }