Represents an abstraction of a component which has multiple "rows" of data.

The children of this component are expected to be UIColumn components.

Note that the same set of child components are reused to implement each row of the table in turn during such phases
as apply-request-values and render-response. Altering any of the members of these components therefore affects the
attribute for every row, except for the following members:

submittedValue

value (where no EL binding is used)

valid

This reuse of the child components also means that it is not possible to save a reference to a component during table
processing, then access it later and expect it to still represent the same row of the table.

Implementation Notes

Each of the UIColumn children of this component has a few component children of its own to render the contents of the
table cell. However there can be a very large number of rows in a table, so it isn't efficient for the UIColumn and
all its child objects to be duplicated for each row in the table. Instead the "flyweight" pattern is used where a
serialized state is held for each row. When setRowIndex is invoked, the UIColumn objects and their children serialize
their 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. When a row
is selected for the first time, its state is set to a clean "initial" state. Transient components (including any
read-only component) do not save their state; they are just reinitialised as required. The state saved/restored when
changing rows is not the complete component state, just the fields that are expected to vary between rows:
"submittedValue", "value", "isValid".

Note that a table is a "naming container", so that components within the table have their ids prefixed with the id of
the table. Actually, when setRowIndex has been called on a table with id of "zzz" the table pretends to its children
that its ID is "zzz_n" where n is the row index. This means that renderers for child components which call
component.getClientId automatically get ids of form "zzz_n:childId" thus ensuring that components in different rows
of the table get different ids.

When decoding a submitted page, this class iterates over all its possible rowIndex values, restoring the appropriate
serialized row state then calling processDecodes on the child components. Because the child components (or their
renderers) use getClientId to get the request key to look for parameter data, and because this object pretends to
have a different id per row ("zzz_n") a single child component can decode data from each table row in turn without
being aware that it is within a table. The table's data model is updated before each call to child.processDecodes, so
the child decode method can assume that the data model's rowData points to the model object associated with the row
currently being decoded. Exactly the same process applies for the later validation and updateModel phases.

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 any of the members "submittedValue", "value" or "valid" of a component within the table during the
invokeApplication phase has no effect on the rendering of the table. When a validation error has occurred, a new
DataModel is not fetched, and the saved state of the child components is not discarded.

encodeBegin(FacesContext context)
Perform necessary actions when rendering of this component starts, before delegating to the inherited
implementation which calls the associated renderer's encodeBegin method.

getContainerClientId

queueEvent

Modify events queued for any child components so that the UIData state will be correctly configured before the
event's listeners are executed.

Child components or their renderers may register events against those child components. When the listener for
that event is eventually invoked, it may expect the uidata's rowData and rowIndex to be referring to the same
object that caused the event to fire.

The original queueEvent call against the child component has been forwarded up the chain of ancestors in the
standard way, making it possible here to wrap the event in a new event whose source is this component, not
the original one. When the event finally is executed, this component's broadcast method is invoked, which ensures
that the UIData is set to be at the correct row before executing the original event.

processUpdates

This isn't an input component, so just pass on the processUpdates call to child components and facets that might
be input components.

Components that were never rendered can't possibly be receiving update data (no corresponding fields were ever
put into the response) so if this component is not rendered then this method does not invoke processUpdates on
its children.

getDataModel

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.

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.getContainerClientId() 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.

Array-like parameters of type array-of-Object, java.util.List, java.sql.ResultSet or
javax.servlet.jsp.jstl.sql.Result are wrapped in a corresponding DataModel that knows how to iterate over the
elements.

Other values are wrapped in a DataModel as a single row.

Note in particular that unordered collections, eg Set are not supported. Therefore if the value expression
references such an object then the table will be considered to contain just one element - the collection itself.