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;
+ }
+ }
+ }
+}