You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sk...@apache.org on 2005/11/24 05:12:15 UTC
svn commit: r348641 -
/myfaces/api/trunk/src/java/javax/faces/component/UIData.java
Author: skitching
Date: Wed Nov 23 20:12:12 2005
New Revision: 348641
URL: http://svn.apache.org/viewcvs?rev=348641&view=rev
Log:
* Explain why _rowState is reset on render
* Explain the _dataModelMap member
* Note that UIColumn components don't get to render their children; the
UIData does it for them.
Modified:
myfaces/api/trunk/src/java/javax/faces/component/UIData.java
Modified: myfaces/api/trunk/src/java/javax/faces/component/UIData.java
URL: http://svn.apache.org/viewcvs/myfaces/api/trunk/src/java/javax/faces/component/UIData.java?rev=348641&r1=348640&r2=348641&view=diff
==============================================================================
--- myfaces/api/trunk/src/java/javax/faces/component/UIData.java (original)
+++ myfaces/api/trunk/src/java/javax/faces/component/UIData.java Wed Nov 23 20:12:12 2005
@@ -39,7 +39,12 @@
import javax.faces.model.ScalarDataModel;
import javax.servlet.jsp.jstl.sql.Result;
-/**<h1>
+/**
+ * Represents a component which has multiple "rows" of data.
+ * <p>
+ * The children of this component are expected to be UIColumn components.
+ * <p>
+ *<h1>
* Implementation Notes
* </h1>
* <p>
@@ -53,11 +58,8 @@
* current state then reinitialise themselves from the appropriate saved
* state. This allows a single set of real objects to represent multiple
* objects which have the same types but potentially different internal
- * state.
- * </p>
- * <p>
- * When a row is selected for the first time, its state is set to a
- * clean "initial" state.
+ * state. When a row is selected for the first time, its state is set to
+ * a clean "initial" state.
* </p>
* <p>
* Note that a table is a "naming container", so that components
@@ -83,6 +85,21 @@
* row currently being decoded. Exactly the same process applies for
* the later validation and updateModel phases.
* </p>
+ * <p>
+ * When the data model for the table is bound to a backing bean property,
+ * and no validation errors have occured during processing of a postback,
+ * the data model is refetched at the start of the rendering phase
+ * (ie after the update model phase) so that the contents of the data model
+ * can be changed as a result of the latest form submission. Because the
+ * saved row state must correspond to the elements within the data model,
+ * the row state must be discarded whenever a new data model is fetched;
+ * not doing this would cause all sorts of inconsistency issues. This does
+ * imply that changing the state of components within the table (such as
+ * modifying the rendered state) during the invokeApplication phase has no
+ * effect on the rendering of the table. When a validation error has occurred,
+ * a new DataModel is <i>not</i> fetched, and the saved state of the child
+ * components is <i>not</i> discarded.
+ * </p>
* @author Manfred Geiler (latest modification by $Author$)
* @version $Revision$ $Date$
*/
@@ -110,6 +127,13 @@
// holds for each row the states of the child components of this UIData
private Map _rowStates = new HashMap();
+ /**
+ * Handle case where this table is nested inside another table.
+ * See method getDataModel for more details.
+ * <p>
+ * Key: parentClientId (aka rowId when nested within a parent table)
+ * Value: DataModel
+ */
private Map _dataModelMap = new HashMap();
// will be set to false if the data should not be refreshed at the beginning of the encode phase
@@ -392,13 +416,25 @@
}
}
+ /**
+ * Perform necessary actions when rendering of this component starts,
+ * before delegating to the inherited implementation which calls the
+ * associated renderer's encodeBegin method.
+ */
public void encodeBegin(FacesContext context) throws IOException
{
_initialDescendantComponentState = null;
if (_isValidChilds && !hasErrorMessages(context))
{
- //Refresh DataModel for rendering:
+ // Clear the data model so that when rendering code calls
+ // getDataModel a fresh model is fetched from the backing
+ // bean via the value-binding.
_dataModelMap.clear();
+
+ // When the data model is cleared it is also necessary to
+ // clear the saved row state, as there is an implicit 1:1
+ // relation between objects in the _rowStates and the
+ // corresponding DataModel element.
_rowStates.clear();
}
super.encodeBegin(context);
@@ -494,6 +530,14 @@
}
}
+ /**
+ * Invoke the specified phase on all facets of all UIColumn children
+ * of this component. Note that no methods are called on the UIColumn
+ * child objects themselves.
+ *
+ * @param context is the current faces context.
+ * @param processAction specifies a JSF phase: decode, validate or update.
+ */
private void processColumnFacets(FacesContext context, int processAction)
{
for (Iterator childIter = getChildren().iterator(); childIter.hasNext();)
@@ -516,6 +560,14 @@
}
}
+ /**
+ * Invoke the specified phase on all non-facet children of all UIColumn
+ * children of this component. Note that no methods are called on the
+ * UIColumn child objects themselves.
+ *
+ * @param context is the current faces context.
+ * @param processAction specifies a JSF phase: decode, validate or update.
+ */
private void processColumnChildren(FacesContext context, int processAction)
{
int first = getFirst();
@@ -576,6 +628,21 @@
}
}
+ /**
+ * Return the datamodel for this table, potentially fetching the data from
+ * a backing bean via a value-binding if this is the first time this method
+ * has been called.
+ * <p>
+ * This is complicated by the fact that this table may be nested within
+ * another table. In this case a different datamodel should be fetched
+ * for each row. When nested within a parent table, the parent reference
+ * won't change but parent.getClientId() will, as the suffix changes
+ * depending upon the current row index. A map object on this component
+ * is therefore used to cache the datamodel for each row of the table.
+ * In the normal case where this table is not nested inside a component
+ * that changes its id (like a table does) then this map only ever has
+ * one entry.
+ */
private DataModel getDataModel()
{
DataModel dataModel = null;
@@ -595,7 +662,16 @@
}
/**
- * Creates a new DataModel around the current value.
+ * Evaluate this object's value property and convert the result into a
+ * DataModel. Normally this object's value property will be a value-binding
+ * which will cause the value to be fetched from some backing bean.
+ * <p>
+ * The result of fetching the value may be a DataModel object, in which
+ * case that object is returned directly. If the value is of type
+ * List, Array, ResultSet, Result, other object or null then an appropriate
+ * wrapper is created and returned.
+ * <p>
+ * Null is never returned by this method.
*/
private DataModel createDataModel()
{