You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sl...@apache.org on 2009/04/04 20:44:19 UTC

svn commit: r761981 [3/7] - in /myfaces/core/branches/2_0_0/api/src/main/java/javax/faces: ./ application/ component/ component/behavior/ component/visit/ context/ convert/ event/ model/ render/ validator/ view/ view/facelets/ webapp/ webapp/pdl/

Modified: myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponentBase.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponentBase.java?rev=761981&r1=761980&r2=761981&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponentBase.java (original)
+++ myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponentBase.java Sat Apr  4 18:44:14 2009
@@ -22,6 +22,7 @@
 import java.io.Serializable;
 import java.lang.reflect.Array;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -31,12 +32,13 @@
 import javax.el.ValueExpression;
 import javax.faces.FacesException;
 import javax.faces.FactoryFinder;
+import javax.faces.component.behavior.ClientBehavior;
 import javax.faces.context.FacesContext;
 import javax.faces.el.ValueBinding;
 import javax.faces.event.AbortProcessingException;
-import javax.faces.event.BeforeRenderEvent;
 import javax.faces.event.FacesEvent;
 import javax.faces.event.FacesListener;
+import javax.faces.event.PreRenderComponentEvent;
 import javax.faces.render.RenderKit;
 import javax.faces.render.RenderKitFactory;
 import javax.faces.render.Renderer;
@@ -48,15 +50,17 @@
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
 
 /**
+ * TODO: IMPLEMENT HERE - Delta state saving support
+ * 
  * Standard implementation of the UIComponent base class; all standard JSF components extend this class.
  * <p>
  * <i>Disclaimer</i>: The official definition for the behaviour of this class is the JSF 1.1 specification but for legal
  * reasons the specification cannot be replicated here. Any javadoc here therefore describes the current implementation
  * rather than the spec, though this class has been verified as correctly implementing the spec.
- *
+ * 
  * see Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a> for
  * more.
- *
+ * 
  * @author Manfred Geiler (latest modification by $Author$)
  * @version $Revision$ $Date$
  */
@@ -84,82 +88,8 @@
     }
 
     /**
-     * Get a map through which all the UIComponent's properties, value-bindings and non-property attributes can be read
-     * and written.
-     * <p>
-     * When writing to the returned map:
-     * <ul>
-     * <li>If this component has an explicit property for the specified key then the setter method is called. An
-     * IllegalArgumentException is thrown if the property is read-only. If the property is readable then the old value
-     * is returned, otherwise null is returned.
-     * <li>Otherwise the key/value pair is stored in a map associated with the component.
-     * </ul>
-     * Note that value-bindings are <i>not</i> written by put calls to this map. Writing to the attributes map using a
-     * key for which a value-binding exists will just store the value in the attributes map rather than evaluating the
-     * binding, effectively "hiding" the value-binding from later attributes.get calls. Setter methods on components
-     * commonly do <i>not</i> evaluate a binding of the same name; they just store the provided value directly on the
-     * component.
-     * <p>
-     * When reading from the returned map:
-     * <ul>
-     * <li>If this component has an explicit property for the specified key then the getter method is called. If the
-     * property exists, but is read-only (ie only a setter method is defined) then an IllegalArgumentException is
-     * thrown.
-     * <li>If the attribute map associated with the component has an entry with the specified key, then that is
-     * returned.
-     * <li>If this component has a value-binding for the specified key, then the value-binding is evaluated to fetch the
-     * value.
-     * <li>Otherwise, null is returned.
-     * </ul>
-     * Note that components commonly define getter methods such that they evaluate a value-binding of the same name if
-     * there isn't yet a local property.
-     * <p>
-     * Assigning values to the map which are not explicit properties on the underlying component can be used to "tunnel"
-     * attributes from the JSP tag (or view-specific equivalent) to the associated renderer without modifying the
-     * component itself.
-     * <p>
-     * Any value-bindings and non-property attributes stored in this map are automatically serialized along with the
-     * component when the view is serialized.
-     */
-    @Override
-    public Map<String, Object> getAttributes()
-    {
-        if (_attributesMap == null)
-        {
-            _attributesMap = new _ComponentAttributesMap(this);
-        }
-
-        return _attributesMap;
-    }
-
-    /**
-     * Get the named value-binding associated with this component.
-     * <p>
-     * Value-bindings are stored in a map associated with the component, though there is commonly a property
-     * (setter/getter methods) of the same name defined on the component itself which evaluates the value-binding when
-     * called.
-     *
-     * @deprecated Replaced by getValueExpression
-     */
-    @Deprecated
-    @Override
-    public ValueBinding getValueBinding(String name)
-    {
-        ValueExpression expression = getValueExpression(name);
-        if (expression != null)
-        {
-            if (expression instanceof _ValueBindingToValueExpression)
-            {
-                return ((_ValueBindingToValueExpression)expression).getValueBinding();
-            }
-            return new _ValueExpressionToValueBinding(expression);
-        }
-        return null;
-    }
-
-    /**
      * Put the provided value-binding into a map of value-bindings associated with this component.
-     *
+     * 
      * @deprecated Replaced by setValueExpression
      */
     @Deprecated
@@ -170,114 +100,6 @@
     }
 
     /**
-     * Get a string which can be output to the response which uniquely identifies this UIComponent within the current
-     * view.
-     * <p>
-     * The component should have an id attribute already assigned to it; however if the id property is currently null
-     * then a unique id is generated and set for this component. This only happens when components are programmatically
-     * created without ids, as components created by a ViewHandler should be assigned ids when they are created.
-     * <p>
-     * If this component is a descendant of a NamingContainer then the client id is of form
-     * "{namingContainerId}:{componentId}". Note that the naming container's id may itself be of compound form if it has
-     * an ancestor naming container. Note also that this only applies to naming containers; other UIComponent types in
-     * the component's ancestry do not affect the clientId.
-     * <p>
-     * Finally the renderer associated with this component is asked to convert the id into a suitable form. This allows
-     * escaping of any characters in the clientId which are significant for the markup language generated by that
-     * renderer.
-     */
-    @Override
-    public String getClientId(FacesContext context)
-    {
-        if (context == null)
-            throw new NullPointerException("context");
-
-        if (_clientId != null)
-            return _clientId;
-
-        boolean idWasNull = false;
-        String id = getId();
-        if (id == null)
-        {
-            // Although this is an error prone side effect, we automatically create a new id
-            // just to be compatible to the RI
-            UIViewRoot viewRoot = context.getViewRoot();
-            if (viewRoot != null)
-            {
-                id = viewRoot.createUniqueId();
-            }
-            else
-            {
-                // The RI throws a NPE
-                throw new FacesException(
-                    "Cannot create clientId. No id is assigned for component to create an id and UIViewRoot is not defined: "
-                            + getPathToComponent(this));
-            }
-            setId(id);
-            // We remember that the id was null and log a warning down below
-            idWasNull = true;
-        }
-
-        UIComponent namingContainer = _ComponentUtils.findParentNamingContainer(this, false);
-        if (namingContainer != null)
-        {
-            String containerClientId = namingContainer.getContainerClientId(context);
-            if (containerClientId != null)
-            {
-                StringBuilder bld = __getSharedStringBuilder();
-                _clientId = bld.append(containerClientId).append(NamingContainer.SEPARATOR_CHAR).append(id).toString();
-            }
-            else
-            {
-                _clientId = id;
-            }
-        }
-        else
-        {
-            _clientId = id;
-        }
-
-        Renderer renderer = getRenderer(context);
-        if (renderer != null)
-        {
-            _clientId = renderer.convertClientId(context, _clientId);
-        }
-
-        if (idWasNull && log.isWarnEnabled())
-        {
-            log.warn("WARNING: Component " + _clientId
-                    + " just got an automatic id, because there was no id assigned yet. "
-                    + "If this component was created dynamically (i.e. not by a JSP tag) you should assign it an "
-                    + "explicit static id or assign it the id you get from "
-                    + "the createUniqueId from the current UIViewRoot "
-                    + "component right after creation! Path to Component: " + getPathToComponent(this));
-        }
-
-        return _clientId;
-    }
-
-    /**
-     * Get a string which uniquely identifies this UIComponent within the scope of the nearest ancestor NamingContainer
-     * component. The id is not necessarily unique across all components in the current view.
-     */
-    @JSFProperty
-      (rtexprvalue = true)
-    public String getId()
-    {
-        return _id;
-    }
-
-    /**
-     * <code>invokeOnComponent</code> must be implemented in <code>UIComponentBase</code> too...
-     */
-    @Override
-    public boolean invokeOnComponent(FacesContext context, String clientId, ContextCallback callback)
-        throws FacesException
-    {
-        return super.invokeOnComponent(context, clientId, callback);
-    }
-
-    /**
      * Set an identifier for this component which is unique within the scope of the nearest ancestor NamingContainer
      * component. The id is not necessarily unique across all components in the current view.
      * <p>
@@ -290,7 +112,7 @@
      * Null is allowed as a parameter, and will reset the id to null.
      * <p>
      * The clientId of this component is reset by this method; see getClientId for more info.
-     *
+     * 
      * @throws IllegalArgumentException
      *             if the id is not valid.
      */
@@ -303,67 +125,189 @@
     }
 
     @Override
-    public UIComponent getParent()
-    {
-        return _parent;
-    }
-
-    @Override
     public void setParent(UIComponent parent)
     {
         _parent = parent;
     }
 
     /**
-     * Indicates whether this component or its renderer manages the invocation of the rendering methods of its child
-     * components. When this is true:
-     * <ul>
-     * <li>This component's encodeBegin method will only be called after all the child components have been created and
-     * added to this component. <li>This component's encodeChildren method will be called after its encodeBegin method.
-     * Components for which this method returns false do not get this method invoked at all. <li>No rendering methods
-     * will be called automatically on child components; this component is required to invoke the
-     * encodeBegin/encodeEnd/etc on them itself.
-     * </ul>
+     * 
+     * @param eventName
+     * @param behavior
+     * 
+     * @since 2.0
      */
-    @Override
-    public boolean getRendersChildren()
+    public void addClientBehavior(String eventName, ClientBehavior behavior)
     {
-        Renderer renderer = getRenderer(getFacesContext());
-        return renderer != null ? renderer.getRendersChildren() : false;
+        // TODO: IMPLEMENT HERE
     }
 
     /**
-     * Return a list of the UIComponent objects which are direct children of this component.
+     * Invoke any listeners attached to this object which are listening for an event whose type matches the specified
+     * event's runtime type.
      * <p>
-     * The list object returned has some non-standard behaviour:
-     * <ul>
-     * <li>The list is type-checked; only UIComponent objects can be added.
-     * <li>If a component is added to the list with an id which is the same as some other component in the list then an
-     * exception is thrown. However multiple components with a null id may be added.
-     * <li>The component's parent property is set to this component. If the component already had a parent, then the
-     * component is first removed from its original parent's child list.
-     * </ul>
+     * This method does not propagate the event up to parent components, ie listeners attached to parent components
+     * don't automatically get called.
+     * <p>
+     * If any of the listeners throws AbortProcessingException then that exception will prevent any further listener
+     * callbacks from occurring, and the exception propagates out of this method without alteration.
+     * <p>
+     * ActionEvent events are typically queued by the renderer associated with this component in its decode method;
+     * ValueChangeEvent events by the component's validate method. In either case the event's source property references
+     * a component. At some later time the UIViewRoot component iterates over its queued events and invokes the
+     * broadcast method on each event's source object.
+     * 
+     * @param event
+     *            must not be null.
      */
     @Override
-    public List<UIComponent> getChildren()
+    public void broadcast(FacesEvent event) throws AbortProcessingException
     {
-        if (_childrenList == null)
+        if (event == null)
+            throw new NullPointerException("event");
+        try
         {
-            _childrenList = new _ComponentChildrenList(this);
+
+            if (_facesListeners == null)
+                return;
+            for (Iterator<FacesListener> it = _facesListeners.iterator(); it.hasNext();)
+            {
+                FacesListener facesListener = it.next();
+                if (event.isAppropriateListener(facesListener))
+                {
+                    event.processListener(facesListener);
+                }
+            }
         }
-        return _childrenList;
+        catch (Exception ex)
+        {
+            if (ex instanceof AbortProcessingException)
+            {
+                throw (AbortProcessingException) ex;
+            }
+            throw new FacesException("Exception while calling broadcast on component : " + getPathToComponent(this), ex);
+        }
+    }
+    
+    public void clearInitialState()
+    {
+        // TODO: IMPLEMENT HERE
     }
 
     /**
-     * Return the number of direct child components this component has.
-     * <p>
-     * Identical to getChildren().size() except that when this component has no children this method will not force an
-     * empty list to be created.
+     * Check the submitted form parameters for data associated with this component. This default implementation
+     * delegates to this component's renderer if there is one, and otherwise ignores the call.
      */
     @Override
-    public int getChildCount()
+    public void decode(FacesContext context)
     {
-        return _childrenList == null ? 0 : _childrenList.size();
+        if (context == null)
+            throw new NullPointerException("context");
+        try
+        {
+            Renderer renderer = getRenderer(context);
+            if (renderer != null)
+            {
+                renderer.decode(context, this);
+            }
+        }
+        catch (Exception ex)
+        {
+            throw new FacesException("Exception while decoding component : " + getPathToComponent(this), ex);
+        }
+    }
+
+    @Override
+    public void encodeBegin(FacesContext context) throws IOException
+    {
+        if (context == null)
+        {
+            throw new NullPointerException("context");
+        }
+
+        // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
+        pushComponentToEL(context, this);
+
+        if (isRendered())
+        {
+            // If our rendered property is true, render the beginning of the current state of this UIComponent to the
+            // response contained in the specified FacesContext.
+
+            // Call Application.publishEvent(java.lang.Class, java.lang.Object), passing BeforeRenderEvent.class as
+            // the first argument and the component instance to be rendered as the second argument.
+            context.getApplication().publishEvent(PreRenderComponentEvent.class, this);
+
+            Renderer renderer = getRenderer(context);
+            if (renderer != null)
+            {
+                // If a Renderer is associated with this UIComponent, the actual encoding will be delegated to
+                // Renderer.encodeBegin(FacesContext, UIComponent).
+                renderer.encodeBegin(context, this);
+            }
+        }
+    }
+
+    @Override
+    public void encodeChildren(FacesContext context) throws IOException
+    {
+        if (context == null)
+        {
+            throw new NullPointerException("context");
+        }
+
+        if (isRendered())
+        {
+            // If our rendered property is true, render the child UIComponents of this UIComponent.
+
+            Renderer renderer = getRenderer(context);
+            if (renderer == null)
+            {
+                // If no Renderer is associated with this UIComponent, iterate over each of the children of this
+                // component and call UIComponent.encodeAll(javax.faces.context.FacesContext).
+                if (getChildCount() > 0)
+                {
+                    for (UIComponent child : getChildren())
+                    {
+                        child.encodeAll(context);
+                    }
+                }
+            }
+            else
+            {
+                // If a Renderer is associated with this UIComponent, the actual encoding will be delegated to
+                // Renderer.encodeChildren(FacesContext, UIComponent).
+                renderer.encodeChildren(context, this);
+            }
+        }
+    }
+
+    @Override
+    public void encodeEnd(FacesContext context) throws IOException
+    {
+        try
+        {
+            if (context == null)
+            {
+                throw new NullPointerException("context");
+            }
+            if (isRendered())
+            {
+                // If our rendered property is true, render the ending of the current state of this UIComponent.
+                Renderer renderer = getRenderer(context);
+                if (renderer != null)
+                {
+                    // If a Renderer is associated with this UIComponent, the actual encoding will be delegated to
+                    // Renderer.encodeEnd(FacesContext, UIComponent).
+                    renderer.encodeEnd(context, this);
+                }
+            }
+        }
+        finally
+        {
+            // Call UIComponent.popComponentFromEL(javax.faces.context.FacesContext). before returning regardless
+            // of the value of the rendered property.
+            popComponentFromEL(context);
+        }
     }
 
     /**
@@ -383,7 +327,7 @@
      * <li>Otherwise, the search starts from the nearest ancestor NamingContainer (or the root component if there is no
      * NamingContainer ancestor).
      * </ul>
-     *
+     * 
      * @param expr
      *            is of form "id1:id2:id3".
      * @return UIComponent or null if no component with the specified id is found.
@@ -436,221 +380,376 @@
 
     }
 
+    /**
+     * Get a map through which all the UIComponent's properties, value-bindings and non-property attributes can be read
+     * and written.
+     * <p>
+     * When writing to the returned map:
+     * <ul>
+     * <li>If this component has an explicit property for the specified key then the setter method is called. An
+     * IllegalArgumentException is thrown if the property is read-only. If the property is readable then the old value
+     * is returned, otherwise null is returned.
+     * <li>Otherwise the key/value pair is stored in a map associated with the component.
+     * </ul>
+     * Note that value-bindings are <i>not</i> written by put calls to this map. Writing to the attributes map using a
+     * key for which a value-binding exists will just store the value in the attributes map rather than evaluating the
+     * binding, effectively "hiding" the value-binding from later attributes.get calls. Setter methods on components
+     * commonly do <i>not</i> evaluate a binding of the same name; they just store the provided value directly on the
+     * component.
+     * <p>
+     * When reading from the returned map:
+     * <ul>
+     * <li>If this component has an explicit property for the specified key then the getter method is called. If the
+     * property exists, but is read-only (ie only a setter method is defined) then an IllegalArgumentException is
+     * thrown.
+     * <li>If the attribute map associated with the component has an entry with the specified key, then that is
+     * returned.
+     * <li>If this component has a value-binding for the specified key, then the value-binding is evaluated to fetch the
+     * value.
+     * <li>Otherwise, null is returned.
+     * </ul>
+     * Note that components commonly define getter methods such that they evaluate a value-binding of the same name if
+     * there isn't yet a local property.
+     * <p>
+     * Assigning values to the map which are not explicit properties on the underlying component can be used to "tunnel"
+     * attributes from the JSP tag (or view-specific equivalent) to the associated renderer without modifying the
+     * component itself.
+     * <p>
+     * Any value-bindings and non-property attributes stored in this map are automatically serialized along with the
+     * component when the view is serialized.
+     */
     @Override
-    public Map<String, UIComponent> getFacets()
+    public Map<String, Object> getAttributes()
     {
-        if (_facetMap == null)
+        if (_attributesMap == null)
         {
-            _facetMap = new _ComponentFacetMap<UIComponent>(this);
+            _attributesMap = new _ComponentAttributesMap(this);
         }
-        return _facetMap;
+
+        return _attributesMap;
     }
 
+    /**
+     * Return the number of direct child components this component has.
+     * <p>
+     * Identical to getChildren().size() except that when this component has no children this method will not force an
+     * empty list to be created.
+     */
     @Override
-    public UIComponent getFacet(String name)
+    public int getChildCount()
     {
-        return _facetMap == null ? null : _facetMap.get(name);
+        return _childrenList == null ? 0 : _childrenList.size();
     }
 
+    /**
+     * Return a list of the UIComponent objects which are direct children of this component.
+     * <p>
+     * The list object returned has some non-standard behaviour:
+     * <ul>
+     * <li>The list is type-checked; only UIComponent objects can be added.
+     * <li>If a component is added to the list with an id which is the same as some other component in the list then an
+     * exception is thrown. However multiple components with a null id may be added.
+     * <li>The component's parent property is set to this component. If the component already had a parent, then the
+     * component is first removed from its original parent's child list.
+     * </ul>
+     */
     @Override
-    public Iterator<UIComponent> getFacetsAndChildren()
+    public List<UIComponent> getChildren()
     {
-        if (_facetMap == null)
-        {
-            if (_childrenList == null)
-                return _EMPTY_UICOMPONENT_ITERATOR;
-
-            if (_childrenList.isEmpty())
-                return _EMPTY_UICOMPONENT_ITERATOR;
-
-            return _childrenList.iterator();
-        }
-        else
+        if (_childrenList == null)
         {
-            if (_facetMap.isEmpty())
-            {
-                if (_childrenList == null)
-                    return _EMPTY_UICOMPONENT_ITERATOR;
-
-                if (_childrenList.isEmpty())
-                    return _EMPTY_UICOMPONENT_ITERATOR;
-
-                return _childrenList.iterator();
-            }
-            else
-            {
-                if (_childrenList == null)
-                    return _facetMap.values().iterator();
-
-                if (_childrenList.isEmpty())
-                    return _facetMap.values().iterator();
-
-                return new _FacetsAndChildrenIterator(_facetMap, _childrenList);
-            }
+            _childrenList = new _ComponentChildrenList(this);
         }
+        return _childrenList;
+    }
+    
+    /**
+     * 
+     * @return
+     * 
+     * @since 2.0
+     */
+    public Map<String,List<ClientBehavior>> getClientBehaviors()
+    {
+        // TODO: IMPLEMENT HERE
+        return null;
     }
 
     /**
-     * Invoke any listeners attached to this object which are listening for an event whose type matches the specified
-     * event's runtime type.
+     * Get a string which can be output to the response which uniquely identifies this UIComponent within the current
+     * view.
      * <p>
-     * This method does not propagate the event up to parent components, ie listeners attached to parent components
-     * don't automatically get called.
+     * The component should have an id attribute already assigned to it; however if the id property is currently null
+     * then a unique id is generated and set for this component. This only happens when components are programmatically
+     * created without ids, as components created by a ViewHandler should be assigned ids when they are created.
      * <p>
-     * If any of the listeners throws AbortProcessingException then that exception will prevent any further listener
-     * callbacks from occurring, and the exception propagates out of this method without alteration.
+     * If this component is a descendant of a NamingContainer then the client id is of form
+     * "{namingContainerId}:{componentId}". Note that the naming container's id may itself be of compound form if it has
+     * an ancestor naming container. Note also that this only applies to naming containers; other UIComponent types in
+     * the component's ancestry do not affect the clientId.
      * <p>
-     * ActionEvent events are typically queued by the renderer associated with this component in its decode method;
-     * ValueChangeEvent events by the component's validate method. In either case the event's source property references
-     * a component. At some later time the UIViewRoot component iterates over its queued events and invokes the
-     * broadcast method on each event's source object.
-     *
-     * @param event
-     *            must not be null.
+     * Finally the renderer associated with this component is asked to convert the id into a suitable form. This allows
+     * escaping of any characters in the clientId which are significant for the markup language generated by that
+     * renderer.
      */
     @Override
-    public void broadcast(FacesEvent event) throws AbortProcessingException
+    public String getClientId(FacesContext context)
     {
-        if (event == null)
-            throw new NullPointerException("event");
-        try
-        {
+        if (context == null)
+            throw new NullPointerException("context");
 
-            if (_facesListeners == null)
-                return;
-            for (Iterator<FacesListener> it = _facesListeners.iterator(); it.hasNext();)
+        if (_clientId != null)
+            return _clientId;
+
+        boolean idWasNull = false;
+        String id = getId();
+        if (id == null)
+        {
+            // Although this is an error prone side effect, we automatically create a new id
+            // just to be compatible to the RI
+            UIViewRoot viewRoot = context.getViewRoot();
+            if (viewRoot != null)
             {
-                FacesListener facesListener = it.next();
-                if (event.isAppropriateListener(facesListener))
-                {
-                    event.processListener(facesListener);
-                }
+                id = viewRoot.createUniqueId();
+            }
+            else
+            {
+                // The RI throws a NPE
+                throw new FacesException(
+                                         "Cannot create clientId. No id is assigned for component to create an id and UIViewRoot is not defined: "
+                                                 + getPathToComponent(this));
             }
+            setId(id);
+            // We remember that the id was null and log a warning down below
+            idWasNull = true;
         }
-        catch (Exception ex)
+
+        UIComponent namingContainer = _ComponentUtils.findParentNamingContainer(this, false);
+        if (namingContainer != null)
         {
-            if (ex instanceof AbortProcessingException)
+            String containerClientId = namingContainer.getContainerClientId(context);
+            if (containerClientId != null)
             {
-                throw (AbortProcessingException)ex;
+                StringBuilder bld = __getSharedStringBuilder();
+                _clientId = bld.append(containerClientId).append(NamingContainer.SEPARATOR_CHAR).append(id).toString();
             }
-            throw new FacesException("Exception while calling broadcast on component : " + getPathToComponent(this), ex);
+            else
+            {
+                _clientId = id;
+            }
+        }
+        else
+        {
+            _clientId = id;
+        }
+
+        Renderer renderer = getRenderer(context);
+        if (renderer != null)
+        {
+            _clientId = renderer.convertClientId(context, _clientId);
+        }
+
+        if (idWasNull && log.isWarnEnabled())
+        {
+            log.warn("WARNING: Component " + _clientId
+                    + " just got an automatic id, because there was no id assigned yet. "
+                    + "If this component was created dynamically (i.e. not by a JSP tag) you should assign it an "
+                    + "explicit static id or assign it the id you get from "
+                    + "the createUniqueId from the current UIViewRoot "
+                    + "component right after creation! Path to Component: " + getPathToComponent(this));
         }
+
+        return _clientId;
+    }
+    
+    /**
+     * 
+     * @return
+     * 
+     * @since 2.0
+     */
+    public String getDefaultEventName()
+    {
+        // TODO: IMPLEMENT HERE
+        return null;
+    }
+    
+    /**
+     * 
+     * @return
+     * 
+     * @since 2.0
+     */
+    public Collection<String> getEventNames()
+    {
+        // TODO: IMPLEMENT HERE
+        return null;
+    }
+
+    @Override
+    public UIComponent getFacet(String name)
+    {
+        return _facetMap == null ? null : _facetMap.get(name);
     }
 
     /**
-     * Check the submitted form parameters for data associated with this component. This default implementation
-     * delegates to this component's renderer if there is one, and otherwise ignores the call.
+     * @since 1.2
      */
     @Override
-    public void decode(FacesContext context)
+    public int getFacetCount()
     {
-        if (context == null)
-            throw new NullPointerException("context");
-        try
-        {
-            Renderer renderer = getRenderer(context);
-            if (renderer != null)
-            {
-                renderer.decode(context, this);
-            }
-        }
-        catch (Exception ex)
+        return _facetMap == null ? 0 : _facetMap.size();
+    }
+
+    @Override
+    public Map<String, UIComponent> getFacets()
+    {
+        if (_facetMap == null)
         {
-            throw new FacesException("Exception while decoding component : " + getPathToComponent(this), ex);
+            _facetMap = new _ComponentFacetMap<UIComponent>(this);
         }
+        return _facetMap;
     }
 
     @Override
-    public void encodeBegin(FacesContext context) throws IOException
+    public Iterator<UIComponent> getFacetsAndChildren()
     {
-        if (context == null)
+        if (_facetMap == null)
         {
-            throw new NullPointerException("context");
-        }
+            if (_childrenList == null)
+                return _EMPTY_UICOMPONENT_ITERATOR;
 
-        // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
-        pushComponentToEL(context, this);
+            if (_childrenList.isEmpty())
+                return _EMPTY_UICOMPONENT_ITERATOR;
 
-        if (isRendered())
+            return _childrenList.iterator();
+        }
+        else
         {
-            // If our rendered property is true, render the beginning of the current state of this UIComponent to the
-            // response contained in the specified FacesContext.
+            if (_facetMap.isEmpty())
+            {
+                if (_childrenList == null)
+                    return _EMPTY_UICOMPONENT_ITERATOR;
 
-            // Call Application.publishEvent(java.lang.Class, java.lang.Object), passing BeforeRenderEvent.class as
-            // the first argument and the component instance to be rendered as the second argument.
-            context.getApplication().publishEvent(BeforeRenderEvent.class, this);
+                if (_childrenList.isEmpty())
+                    return _EMPTY_UICOMPONENT_ITERATOR;
 
-            Renderer renderer = getRenderer(context);
-            if (renderer != null)
+                return _childrenList.iterator();
+            }
+            else
             {
-                // If a Renderer is associated with this UIComponent, the actual encoding will be delegated to
-                // Renderer.encodeBegin(FacesContext, UIComponent).
-                renderer.encodeBegin(context, this);
+                if (_childrenList == null)
+                    return _facetMap.values().iterator();
+
+                if (_childrenList.isEmpty())
+                    return _facetMap.values().iterator();
+
+                return new _FacetsAndChildrenIterator(_facetMap, _childrenList);
             }
         }
     }
 
+    /**
+     * Get a string which uniquely identifies this UIComponent within the scope of the nearest ancestor NamingContainer
+     * component. The id is not necessarily unique across all components in the current view.
+     */
+    @JSFProperty(rtexprvalue = true)
+    public String getId()
+    {
+        return _id;
+    }
+
     @Override
-    public void encodeChildren(FacesContext context) throws IOException
+    public UIComponent getParent()
     {
-        if (context == null)
-        {
-            throw new NullPointerException("context");
-        }
+        return _parent;
+    }
 
-        if (isRendered())
-        {
-            // If our rendered property is true, render the child UIComponents of this UIComponent.
+    @Override
+    public String getRendererType()
+    {
+        return getExpressionValue("rendererType", _rendererType, null);
+    }
 
-            Renderer renderer = getRenderer(context);
-            if (renderer == null)
-            {
-                // If no Renderer is associated with this UIComponent, iterate over each of the children of this
-                // component and call UIComponent.encodeAll(javax.faces.context.FacesContext).
-                if (getChildCount() > 0)
-                {
-                    for (UIComponent child : getChildren())
-                    {
-                        child.encodeAll(context);
-                    }
-                }
-            }
-            else
-            {
-                // If a Renderer is associated with this UIComponent, the actual encoding will be delegated to
-                // Renderer.encodeChildren(FacesContext, UIComponent).
-                renderer.encodeChildren(context, this);
-            }
-        }
+    /**
+     * Indicates whether this component or its renderer manages the invocation of the rendering methods of its child
+     * components. When this is true:
+     * <ul>
+     * <li>This component's encodeBegin method will only be called after all the child components have been created and
+     * added to this component. <li>This component's encodeChildren method will be called after its encodeBegin method.
+     * Components for which this method returns false do not get this method invoked at all. <li>No rendering methods
+     * will be called automatically on child components; this component is required to invoke the
+     * encodeBegin/encodeEnd/etc on them itself.
+     * </ul>
+     */
+    @Override
+    public boolean getRendersChildren()
+    {
+        Renderer renderer = getRenderer(getFacesContext());
+        return renderer != null ? renderer.getRendersChildren() : false;
     }
 
+    /**
+     * Get the named value-binding associated with this component.
+     * <p>
+     * Value-bindings are stored in a map associated with the component, though there is commonly a property
+     * (setter/getter methods) of the same name defined on the component itself which evaluates the value-binding when
+     * called.
+     * 
+     * @deprecated Replaced by getValueExpression
+     */
+    @Deprecated
     @Override
-    public void encodeEnd(FacesContext context) throws IOException
+    public ValueBinding getValueBinding(String name)
     {
-        try
+        ValueExpression expression = getValueExpression(name);
+        if (expression != null)
         {
-            if (context == null)
-            {
-                throw new NullPointerException("context");
-            }
-            if (isRendered())
+            if (expression instanceof _ValueBindingToValueExpression)
             {
-                // If our rendered property is true, render the ending of the current state of this UIComponent.
-                Renderer renderer = getRenderer(context);
-                if (renderer != null)
-                {
-                    // If a Renderer is associated with this UIComponent, the actual encoding will be delegated to
-                    // Renderer.encodeEnd(FacesContext, UIComponent).
-                    renderer.encodeEnd(context, this);
-                }
+                return ((_ValueBindingToValueExpression) expression).getValueBinding();
             }
+            return new _ValueExpressionToValueBinding(expression);
         }
-        finally
-        {
-            // Call UIComponent.popComponentFromEL(javax.faces.context.FacesContext). before returning regardless
-            // of the value of the rendered property.
-            popComponentFromEL(context);
-        }
+        return null;
+    }
+    
+    public boolean initialStateMarked()
+    {
+        // TODO: IMPLEMENT HERE
+        // FIXME: Nofity EG, this method should be in the specification
+        return false;
+    }
+
+    /**
+     * <code>invokeOnComponent</code> must be implemented in <code>UIComponentBase</code> too...
+     */
+    @Override
+    public boolean invokeOnComponent(FacesContext context, String clientId, ContextCallback callback)
+            throws FacesException
+    {
+        return super.invokeOnComponent(context, clientId, callback);
+    }
+
+    /**
+     * A boolean value that indicates whether this component should be rendered. Default value: true.
+     **/
+    @Override
+    @JSFProperty
+    public boolean isRendered()
+    {
+        return getExpressionValue("rendered", _rendered, DEFAULT_RENDERED);
+    }
+
+    @JSFProperty(literalOnly = true, istransient = true, tagExcluded = true)
+    public boolean isTransient()
+    {
+        return _transient;
+    }
+    
+    public void markInitialState()
+    {
+        // TODO: IMPLEMENT HERE
     }
 
     @Override
@@ -666,6 +765,13 @@
     }
 
     @Override
+    protected FacesContext getFacesContext()
+    {
+        return FacesContext.getCurrentInstance();
+    }
+
+    // FIXME: Notify EG for generic usage
+    @Override
     protected FacesListener[] getFacesListeners(Class clazz)
     {
         if (clazz == null)
@@ -679,7 +785,7 @@
 
         if (_facesListeners == null)
         {
-            return (FacesListener[])Array.newInstance(clazz, 0);
+            return (FacesListener[]) Array.newInstance(clazz, 0);
         }
         List<FacesListener> lst = null;
         for (Iterator<FacesListener> it = _facesListeners.iterator(); it.hasNext();)
@@ -694,10 +800,34 @@
         }
         if (lst == null)
         {
-            return (FacesListener[])Array.newInstance(clazz, 0);
+            return (FacesListener[]) Array.newInstance(clazz, 0);
         }
 
-        return lst.toArray((FacesListener[])Array.newInstance(clazz, lst.size()));
+        return lst.toArray((FacesListener[]) Array.newInstance(clazz, lst.size()));
+    }
+
+    @Override
+    protected Renderer getRenderer(FacesContext context)
+    {
+        if (context == null)
+            throw new NullPointerException("context");
+        String rendererType = getRendererType();
+        if (rendererType == null)
+            return null;
+        String renderKitId = context.getViewRoot().getRenderKitId();
+        RenderKitFactory rkf = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
+        RenderKit renderKit = rkf.getRenderKit(context, renderKitId);
+        Renderer renderer = renderKit.getRenderer(getFamily(), rendererType);
+        if (renderer == null)
+        {
+            getFacesContext().getExternalContext().log(
+                                                       "No Renderer found for component " + getPathToComponent(this)
+                                                               + " (component-family=" + getFamily()
+                                                               + ", renderer-type=" + rendererType + ")");
+            log.warn("No Renderer found for component " + getPathToComponent(this) + " (component-family="
+                    + getFamily() + ", renderer-type=" + rendererType + ")");
+        }
+        return renderer;
     }
 
     @Override
@@ -863,7 +993,7 @@
 
                         // Ensure that UIComponent.popComponentFromEL(javax.faces.context.FacesContext) is called
                         // correctly after each child or facet.
-                        //popComponentFromEL(context);
+                        // popComponentFromEL(context);
                     }
                 }
             }
@@ -876,7 +1006,8 @@
 
                 // To improve speed and robustness, the facets and children processing is splited to maintain the
                 // facet --> state coherence based on the facet's name
-                for (UIComponent child : getChildren()) {
+                for (UIComponent child : getChildren())
+                {
                     if (!child.isTransient())
                     {
                         if (childrenList == null)
@@ -916,7 +1047,7 @@
             throw new NullPointerException("context");
         }
 
-        Object[] stateValues = (Object[])state;
+        Object[] stateValues = (Object[]) state;
 
         // Call the restoreState() method of this component.
         restoreState(context, stateValues[0]);
@@ -943,13 +1074,11 @@
 
                         // After returning from the processRestoreState() method on a child or facet, call
                         // UIComponent.popComponentFromEL(javax.faces.context.FacesContext)
-                        //popComponentFromEL(context);
+                        // popComponentFromEL(context);
                     }
                     else
                     {
-                        context.getExternalContext().log(
-                                "No state found to restore facet "
-                                        + entry.getKey());
+                        context.getExternalContext().log("No state found to restore facet " + entry.getKey());
                     }
                 }
             }
@@ -973,13 +1102,11 @@
 
                             // After returning from the processRestoreState() method on a child or facet, call
                             // UIComponent.popComponentFromEL(javax.faces.context.FacesContext)
-                            //popComponentFromEL(context);
+                            // popComponentFromEL(context);
                         }
                         else
                         {
-                            context.getExternalContext().log(
-                                    "No state found to restore child of component "
-                                            + getId());
+                            context.getExternalContext().log("No state found to restore child of component " + getId());
                         }
                     }
                 }
@@ -991,35 +1118,6 @@
         }
     }
 
-    @Override
-    protected FacesContext getFacesContext()
-    {
-        return FacesContext.getCurrentInstance();
-    }
-
-    @Override
-    protected Renderer getRenderer(FacesContext context)
-    {
-        if (context == null)
-            throw new NullPointerException("context");
-        String rendererType = getRendererType();
-        if (rendererType == null)
-            return null;
-        String renderKitId = context.getViewRoot().getRenderKitId();
-        RenderKitFactory rkf = (RenderKitFactory)FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
-        RenderKit renderKit = rkf.getRenderKit(context, renderKitId);
-        Renderer renderer = renderKit.getRenderer(getFamily(), rendererType);
-        if (renderer == null)
-        {
-            getFacesContext().getExternalContext().log(
-                "No Renderer found for component " + getPathToComponent(this) + " (component-family=" + getFamily()
-                        + ", renderer-type=" + rendererType + ")");
-            log.warn("No Renderer found for component " + getPathToComponent(this) + " (component-family="
-                    + getFamily() + ", renderer-type=" + rendererType + ")");
-        }
-        return renderer;
-    }
-
     private String getPathToComponent(UIComponent component)
     {
         StringBuffer buf = new StringBuffer();
@@ -1051,7 +1149,7 @@
         if (component instanceof UIViewRoot)
         {
             intBuf.append(",ViewId: ");
-            intBuf.append(((UIViewRoot)component).getViewId());
+            intBuf.append(((UIViewRoot) component).getViewId());
         }
         else
         {
@@ -1065,12 +1163,6 @@
         getPathToComponent(component.getParent(), buf);
     }
 
-    @JSFProperty(literalOnly = true, istransient = true, tagExcluded = true)
-    public boolean isTransient()
-    {
-        return _transient;
-    }
-
     public void setTransient(boolean transientFlag)
     {
         _transient = transientFlag;
@@ -1100,8 +1192,8 @@
             return null;
         if (attachedObject instanceof List)
         {
-            List<Object> lst = new ArrayList<Object>(((List<?>)attachedObject).size());
-            for (Object item : (List<?>)attachedObject)
+            List<Object> lst = new ArrayList<Object>(((List<?>) attachedObject).size());
+            for (Object item : (List<?>) attachedObject)
             {
                 lst.add(saveAttachedState(context, item));
             }
@@ -1110,7 +1202,7 @@
         }
         else if (attachedObject instanceof StateHolder)
         {
-            StateHolder holder = (StateHolder)attachedObject;
+            StateHolder holder = (StateHolder) attachedObject;
             if (holder.isTransient())
             {
                 return null;
@@ -1136,7 +1228,7 @@
             return null;
         if (stateObj instanceof _AttachedListStateWrapper)
         {
-            List<Object> lst = ((_AttachedListStateWrapper)stateObj).getWrappedStateList();
+            List<Object> lst = ((_AttachedListStateWrapper) stateObj).getWrappedStateList();
             List<Object> restoredList = new ArrayList<Object>(lst.size());
             for (Object item : lst)
             {
@@ -1146,7 +1238,7 @@
         }
         else if (stateObj instanceof _AttachedStateWrapper)
         {
-            Class<?> clazz = ((_AttachedStateWrapper)stateObj).getClazz();
+            Class<?> clazz = ((_AttachedStateWrapper) stateObj).getClazz();
             Object restoredObject;
             try
             {
@@ -1163,10 +1255,10 @@
             }
             if (restoredObject instanceof StateHolder)
             {
-                _AttachedStateWrapper wrapper = (_AttachedStateWrapper)stateObj;
+                _AttachedStateWrapper wrapper = (_AttachedStateWrapper) stateObj;
                 Object wrappedState = wrapper.getWrappedStateObject();
 
-                StateHolder holder = (StateHolder)restoredObject;
+                StateHolder holder = (StateHolder) restoredObject;
                 holder.restoreState(context, wrappedState);
             }
             return restoredObject;
@@ -1199,20 +1291,20 @@
      * Invoked in the "restore view" phase, this initialises this object's members from the values saved previously into
      * the provided state object.
      * <p>
-     *
+     * 
      * @param state
      *            is an object previously returned by the saveState method of this class.
      */
     @SuppressWarnings("unchecked")
     public void restoreState(FacesContext context, Object state)
     {
-        Object values[] = (Object[])state;
-        _id = (String)values[0];
-        _rendered = (Boolean)values[1];
-        _rendererType = (String)values[2];
-        _clientId = (String)values[3];
+        Object values[] = (Object[]) state;
+        _id = (String) values[0];
+        _rendered = (Boolean) values[1];
+        _rendererType = (String) values[2];
+        _clientId = (String) values[3];
         restoreAttributesMap(values[4]);
-        _facesListeners = (List<FacesListener>)restoreAttachedState(context, values[5]);
+        _facesListeners = (List<FacesListener>) restoreAttachedState(context, values[5]);
         restoreValueExpressionMap(context, values[6]);
     }
 
@@ -1226,7 +1318,7 @@
     {
         if (stateObj != null)
         {
-            _attributesMap = new _ComponentAttributesMap(this, (Map<String, Object>)stateObj);
+            _attributesMap = new _ComponentAttributesMap(this, (Map<String, Object>) stateObj);
         }
         else
         {
@@ -1255,12 +1347,12 @@
     {
         if (stateObj != null)
         {
-            Map<String, Object> stateMap = (Map<String, Object>)stateObj;
+            Map<String, Object> stateMap = (Map<String, Object>) stateObj;
             int initCapacity = (stateMap.size() * 4 + 3) / 3;
             bindings = new HashMap<String, ValueExpression>(initCapacity);
             for (Map.Entry<String, Object> entry : stateMap.entrySet())
             {
-                bindings.put(entry.getKey(), (ValueExpression)restoreAttachedState(context, entry.getValue()));
+                bindings.put(entry.getKey(), (ValueExpression) restoreAttachedState(context, entry.getValue()));
             }
         }
         else
@@ -1297,8 +1389,8 @@
         if (!Character.isLetter(string.charAt(0)) && string.charAt(0) != '_')
         {
             throw new IllegalArgumentException(
-                "component identifier's first character must be a letter or an underscore ('_')! But it is \""
-                        + string.charAt(0) + "\"");
+                                               "component identifier's first character must be a letter or an underscore ('_')! But it is \""
+                                                       + string.charAt(0) + "\"");
         }
         for (int i = 1; i < string.length(); i++)
         {
@@ -1307,8 +1399,8 @@
             if (!Character.isLetterOrDigit(c) && c != '-' && c != '_')
             {
                 throw new IllegalArgumentException(
-                    "Subsequent characters of component identifier must be a letter, a digit, an underscore ('_'), or a dash ('-')! But component identifier contains \""
-                            + c + "\"");
+                                                   "Subsequent characters of component identifier must be a letter, a digit, an underscore ('_'), or a dash ('-')! But component identifier contains \""
+                                                           + c + "\"");
             }
         }
     }
@@ -1391,37 +1483,12 @@
         _rendered = Boolean.valueOf(rendered);
     }
 
-    /**
-     * A boolean value that indicates whether this component should be rendered. Default value: true.
-     **/
-    @Override
-    @JSFProperty
-    public boolean isRendered()
-    {
-        return getExpressionValue("rendered", _rendered, DEFAULT_RENDERED);
-    }
-
     @Override
     public void setRendererType(String rendererType)
     {
         _rendererType = rendererType;
     }
 
-    @Override
-    public String getRendererType()
-    {
-        return getExpressionValue("rendererType", _rendererType, null);
-    }
-
     // ------------------ GENERATED CODE END ---------------------------------------
 
-    /**
-     * @since 1.2
-     */
-
-    @Override
-    public int getFacetCount()
-    {
-        return _facetMap == null ? 0 : _facetMap.size();
-    }
 }

Modified: myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIData.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIData.java?rev=761981&r1=761980&r2=761981&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIData.java (original)
+++ myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIData.java Sat Apr  4 18:44:14 2009
@@ -98,7 +98,7 @@
  * @version $Revision$ $Date$
  */
 @JSFComponent(defaultRendererType = "javax.faces.Table")
-public class UIData extends UIComponentBase implements NamingContainer
+public class UIData extends UIComponentBase implements NamingContainer, UniqueIdVendor
 {
     public static final String COMPONENT_FAMILY = "javax.faces.Data";
     public static final String COMPONENT_TYPE = "javax.faces.Data"; // for unit tests
@@ -677,6 +677,19 @@
     }
 
     /**
+     * 
+     * {@inheritDoc}
+     * 
+     * @since 2.0
+     */
+    @Override
+    public String createUniqueId(FacesContext context, String seed)
+    {
+        // TODO: IMPLEMENT HERE
+        return null;
+    }
+
+    /**
      * Perform necessary actions when rendering of this component starts, before delegating to the inherited
      * implementation which calls the associated renderer's encodeBegin method.
      */

Modified: myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIForm.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIForm.java?rev=761981&r1=761980&r2=761981&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIForm.java (original)
+++ myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIForm.java Sat Apr  4 18:44:14 2009
@@ -32,7 +32,7 @@
  * @version $Revision$ $Date$
  */
 @JSFComponent(type = "javax.faces.Form", family = "javax.faces.Form")
-public class UIForm extends UIComponentBase implements NamingContainer
+public class UIForm extends UIComponentBase implements NamingContainer, UniqueIdVendor
 {
     // private static final Log log = LogFactory.getLog(UIForm.class);
 
@@ -40,6 +40,19 @@
 
     private Boolean _prependId;
 
+    /**
+     * 
+     * {@inheritDoc}
+     * 
+     * @since 2.0
+     */
+    @Override
+    public String createUniqueId(FacesContext context, String seed)
+    {
+        // TODO: IMPLEMENT HERE
+        return null;
+    }
+
     public boolean isSubmitted()
     {
         return _submitted;

Modified: myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UINamingContainer.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UINamingContainer.java?rev=761981&r1=761980&r2=761981&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UINamingContainer.java (original)
+++ myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UINamingContainer.java Sat Apr  4 18:44:14 2009
@@ -18,6 +18,9 @@
  */
 package javax.faces.component;
 
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspProperty;
 
@@ -32,10 +35,11 @@
         bodyContent="JSP",
         tagClass="org.apache.myfaces.taglib.core.SubviewTag")
 @JSFJspProperty(name="id",required=true)
-public class UINamingContainer extends UIComponentBase implements NamingContainer
+public class UINamingContainer extends UIComponentBase implements NamingContainer, UniqueIdVendor
 {
     public static final String COMPONENT_TYPE = "javax.faces.NamingContainer";
     public static final String COMPONENT_FAMILY = "javax.faces.NamingContainer";
+    public static final String SEPARATOR_CHAR_PARAM_NAME = "javax.faces.SEPARATOR_CHAR";
 
     /**
      * Construct an instance of the UINamingContainer.
@@ -50,4 +54,45 @@
     {
         return COMPONENT_FAMILY;
     }
+
+    /**
+     * 
+     * {@inheritDoc}
+     * 
+     * @since 2.0
+     */
+    @Override
+    public String createUniqueId(FacesContext context, String seed)
+    {
+        // TODO: IMPLEMENT HERE
+        return null;
+    }
+    
+    /**
+     * 
+     * @param context
+     * @return
+     * 
+     * @since 2.0
+     */
+    @SuppressWarnings("deprecation")
+    public static char getSeparatorChar(FacesContext context)
+    {
+        ExternalContext eContext = context.getExternalContext();
+        
+        // The implementation must determine if there is a <context-param> with the value given by the 
+        // value of the symbolic constant SEPARATOR_CHAR_PARAM_NAME
+        String param = eContext.getInitParameter(SEPARATOR_CHAR_PARAM_NAME);
+        if (param == null || param.length() == 0)
+        {
+            // Otherwise, the value of the symbolic constant NamingContainer.SEPARATOR_CHAR must be returned.
+            return NamingContainer.SEPARATOR_CHAR;
+        }
+        else
+        {
+            // If there is a value for this param, the first character of the value must be returned from 
+            // this method
+            return param.charAt(0);
+        }
+    }
 }

Added: myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIViewParameter.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIViewParameter.java?rev=761981&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIViewParameter.java (added)
+++ myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIViewParameter.java Sat Apr  4 18:44:14 2009
@@ -0,0 +1,200 @@
+/*
+ * 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 javax.faces.component;
+
+import java.io.IOException;
+
+import javax.faces.FactoryFinder;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.ConverterException;
+import javax.faces.render.RenderKit;
+import javax.faces.render.RenderKitFactory;
+import javax.faces.render.Renderer;
+
+/**
+ * TODO: PLUGINIZE?
+ * 
+ * @author Simon Lessard (latest modification by $Author: slessard $)
+ * @version $Revision: 696523 $ $Date: 2009-03-14 14:43:57 -0400 (mer., 17 sept. 2008) $
+ * 
+ * @since 2.0
+ */
+public class UIViewParameter extends UIInput
+{
+    public static final String COMPONENT_FAMILY = "javax.faces.ViewParameter";
+    public static final String COMPONENT_TYPE = "javax.faces.ViewParameter";
+
+    private static final String DELEGATE_FAMILY = UIInput.COMPONENT_FAMILY;
+    private static final String DELEGATE_RENDERER_TYPE = "javax.faces.Text";
+
+    private static Renderer _delegateRenderer;
+
+    private String _name;
+
+    @Override
+    public String getFamily()
+    {
+        return COMPONENT_FAMILY;
+    }
+
+    @Override
+    public void decode(FacesContext context)
+    {
+        // Override behavior from superclass to pull a value from the incoming request parameter map under the 
+        // name given by getName() and store it with a call to UIInput.setSubmittedValue(java.lang.Object).
+        setSubmittedValue(context.getExternalContext().getRequestParameterMap().get(getName()));
+    }
+
+    @Override
+    public void encodeAll(FacesContext context) throws IOException
+    {
+        setSubmittedValue(getStringValue(context));
+    }
+
+    public String getName()
+    {
+        return _name;
+    }
+
+    public String getStringValue(FacesContext context)
+    {
+        // TODO: IMPLEMENT
+
+        return null;
+    }
+
+    public String getStringValueFromModel(FacesContext context) throws ConverterException
+    {
+        // TODO: IMPLEMENT
+
+        return null;
+    }
+
+    @Override
+    public String getSubmittedValue()
+    {
+        return (String)super.getSubmittedValue();
+    }
+
+    @Override
+    public boolean isImmediate()
+    {
+        return false;
+    }
+
+    @Override
+    public void processValidators(FacesContext context)
+    {
+        // TODO: IMPLEMENT
+    }
+
+    @Override
+    public void restoreState(FacesContext context, Object state)
+    {
+        Object[] stateValues = (Object[]) state;
+        super.restoreState(context, stateValues[0]);
+        _name = (String) stateValues[1];
+    }
+
+    @Override
+    public Object saveState(FacesContext context)
+    {
+        Object[] state = new Object[2];
+        state[0] = super.saveState(context);
+        state[1] = _name;
+
+        return state;
+    }
+
+    public void setName(String name)
+    {
+        _name = name;
+    }
+
+    @Override
+    public void updateModel(FacesContext context)
+    {
+        super.updateModel(context);
+        
+        // TODO: IMPLEMENT
+    }
+
+    @Override
+    protected Object getConvertedValue(FacesContext context, Object submittedValue)
+    {
+        return getDelegateRenderer(context).getConvertedValue(context, this, submittedValue);
+    }
+
+    private static Renderer getDelegateRenderer(FacesContext context)
+    {
+        if (_delegateRenderer == null)
+        {
+            RenderKitFactory factory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
+            RenderKit kit = factory.getRenderKit(context, RenderKitFactory.HTML_BASIC_RENDER_KIT);
+
+            _delegateRenderer = kit.getRenderer(DELEGATE_FAMILY, DELEGATE_RENDERER_TYPE);
+        }
+
+        return _delegateRenderer;
+    }
+
+    /**
+     * @author Simon Lessard (latest modification by $Author: slessard $)
+     * @version $Revision: 696523 $ $Date: 2009-03-14 14:43:57 -0400 (mer., 17 sept. 2008) $
+     * 
+     * @since 2.0
+     */
+    public static class Reference
+    {
+        private int _index;
+        private UIViewParameter _param;
+        private Object _state;
+        private String _viewId;
+
+        public Reference(FacesContext context, UIViewParameter param, int indexInParent,
+                         String viewIdAtTimeOfConstruction)
+        {
+            // This constructor cause the StateHolder.saveState(javax.faces.context.FacesContext) method
+            // to be called on argument UIViewParameter.
+            _param = param;
+            _viewId = viewIdAtTimeOfConstruction;
+            _index = indexInParent;
+            _state = param.saveState(context);
+        }
+
+        public UIViewParameter getUIViewParameter(FacesContext context)
+        {
+            // If the current viewId is the same as the viewId passed to our constructor
+            if (context.getViewRoot().getViewId().equals(_viewId))
+            {
+                // use the index passed to the constructor to find the actual UIViewParameter instance and return it.
+                // FIXME: How safe is that when dealing with component trees altered by applications?
+                return (UIViewParameter) _param.getParent().getChildren().get(_index);
+            }
+            else
+            {
+                // Otherwise, call StateHolder.restoreState(javax.faces.context.FacesContext, java.lang.Object) on
+                // the saved state and return the result.
+                _param.restoreState(context, _state);
+
+                return _param;
+            }
+        }
+    }
+}