You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by mb...@apache.org on 2005/07/19 12:17:51 UTC
svn commit: r219640 - in /myfaces: api/trunk/src/java/javax/faces/component/
tomahawk/trunk/src/java/org/apache/myfaces/component/html/ext/
tomahawk/trunk/src/java/org/apache/myfaces/custom/crosstable/
Author: mbr
Date: Tue Jul 19 03:17:49 2005
New Revision: 219640
URL: http://svn.apache.org/viewcvs?rev=219640&view=rev
Log:
fixes several issues (JIRA-337, 224, 115) of the new the uidata implementation:
- uidata holds all datamodels in a map to support nested uidatas
(clientid of uidata´s parent is used as a key)
- rowstate is stored in a map and is identified by the current
client id of the uidata
- an inital rowstate is used to initialize each row with its start values
- it is not necessary to call comp.setId(comp.getId()) to reset the client id.
Modified:
myfaces/api/trunk/src/java/javax/faces/component/UIData.java
myfaces/tomahawk/trunk/src/java/org/apache/myfaces/component/html/ext/HtmlDataTable.java
myfaces/tomahawk/trunk/src/java/org/apache/myfaces/component/html/ext/HtmlDataTableHack.java
myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/crosstable/UIColumns.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=219640&r1=219639&r2=219640&view=diff
==============================================================================
--- myfaces/api/trunk/src/java/javax/faces/component/UIData.java (original)
+++ myfaces/api/trunk/src/java/javax/faces/component/UIData.java Tue Jul 19 03:17:49 2005
@@ -16,7 +16,6 @@
package javax.faces.component;
import java.io.IOException;
-import java.io.Serializable;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Collection;
@@ -45,15 +44,13 @@
*/
public class UIData extends UIComponentBase implements NamingContainer
{
- private static final int STATE_SIZE = 8;
+ private static final int STATE_SIZE = 6;
private static final int SUPER_STATE_INDEX = 0;
private static final int FIRST_STATE_INDEX = 1;
private static final int ROWS_STATE_INDEX = 2;
private static final int VALUE_STATE_INDEX = 3;
private static final int VAR_STATE_INDEX = 4;
- private static final int ROW_STATE_INDEX = 5;
- private static final int DATAMODEL_STATE_INDEX = 6;
- private static final int VALID_CHILDS_STATE_INDEX = 7;
+ private static final int VALID_CHILDS_STATE_INDEX = 5;
private static final String FOOTER_FACET_NAME = "footer";
private static final String HEADER_FACET_NAME = "header";
@@ -67,17 +64,17 @@
private int _rowIndex = -1;
private String _var = null;
- // holds the states of the child components of this UIData
- private Map _rowState = new HashMap();
+ // holds for each row the states of the child components of this UIData
+ private Map _rowStates = null;
- private DataModel _dataModel = null;
+ // contains the initial row state which is used to initialize each row
+ private Object _initialRowState = null;
+
+ private Map _dataModelMap = new HashMap();
// will be set to false if the data should not be refreshed at the beginning of the encode phase
private boolean _isValidChilds = true;
- // will be set to false if the _rowstate and _datamodel should not be saved
- private boolean _processUIDataState = true;
-
public void setFooter(UIComponent footer)
{
getFacets().put(FOOTER_FACET_NAME, footer);
@@ -127,7 +124,18 @@
FacesContext facesContext = getFacesContext();
- saveDescendantComponentStates(facesContext, getFacetsAndChildren());
+ if (_rowIndex != -1)
+ {
+ if (_rowStates == null)
+ {
+ _rowStates = new HashMap();
+ }
+ _rowStates.put(getClientId(facesContext), processSaveRowState(facesContext));
+ }
+ else if (_initialRowState == null)
+ {
+ _initialRowState = processSaveRowState(facesContext);
+ }
_rowIndex = rowIndex;
@@ -158,43 +166,128 @@
}
}
- restoreDescendantComponentStates(facesContext, getFacetsAndChildren());
+ if (_rowIndex != -1 && _rowStates != null)
+ {
+ Object state = _rowStates.get(getClientId(facesContext));
+ if (state == null)
+ {
+ state = _initialRowState;
+ }
+ processRestoreRowState(facesContext, state);
+ }
+ else
+ {
+ processRestoreRowState(facesContext, _initialRowState);
+ }
+ }
+
+ private Object processSaveRowState(FacesContext context)
+ {
+ if (isTransient())
+ return null;
+ List childStates = null;
+ int columnCount = getChildCount();
+ if (columnCount > 0)
+ {
+ for (Iterator colIt = getChildren().iterator(); colIt.hasNext();)
+ {
+ UIComponent child = (UIComponent) colIt.next();
+ if (!child.isTransient())
+ {
+ if (childStates == null)
+ {
+ childStates = new ArrayList(columnCount);
+ }
+ if (child instanceof UIColumn)
+ {
+ childStates.add(new Object[] {child.saveState(context),
+ getColumnChildsState(context, child.getChildren().iterator())});
+ }
+ else
+ {
+ childStates.add(child.processSaveState(context));
+ }
+ }
+ }
+ }
+ return childStates;
}
- private void saveDescendantComponentStates(FacesContext context, Iterator childIterator)
+ private Object getColumnChildsState(FacesContext context, Iterator compIterator)
{
- while (childIterator.hasNext())
+ List result = null;
+ while (compIterator.hasNext())
{
- UIComponent child = (UIComponent) childIterator.next();
- if (!child.isTransient())
+ UIComponent colChild = (UIComponent) compIterator.next();
+ if (!colChild.isTransient())
{
- _rowState.put(child.getClientId(context), new ChildStateHolder(context, child));
- if (!(child instanceof UIData))
+ if (result == null)
{
- saveDescendantComponentStates(context, child.getFacetsAndChildren());
+ result = new ArrayList();
}
+ result.add(colChild.processSaveState(context));
}
}
+ return result;
}
- private void restoreDescendantComponentStates(FacesContext context, Iterator childIterator)
+ public void processRestoreRowState(FacesContext context, Object state)
{
- while (childIterator.hasNext())
+ List childrenStates = (List) state;
+ int childCount = getChildCount();
+ if (childrenStates != null && childCount > 0)
{
- UIComponent child = (UIComponent) childIterator.next();
- // the spec 1.1 (3.1.6) says: setting the id will recalculate the clientid
- child.setId(child.getId());
- if (!child.isTransient())
+ int idx = 0;
+ for (Iterator it = getChildren().iterator(); it.hasNext();)
{
- String clientId = child.getClientId(context);
- ChildStateHolder childStateHolder = (ChildStateHolder) _rowState.get(clientId);
- if (childStateHolder != null)
+ UIComponent child = (UIComponent) it.next();
+ if (!child.isTransient())
{
- childStateHolder.restoreState(context, child);
+ Object childState = childrenStates.get(idx++);
+ if (childState != null)
+ {
+ if (child instanceof UIColumn)
+ {
+ Object[] columnState = (Object[]) childState;
+ setColumnChildsState(context, child.getChildren().iterator(), columnState[1]);
+ child.restoreState(context, columnState[0]);
+ }
+ else
+ {
+ child.processRestoreState(context, childState);
+ }
+ }
+ else
+ {
+ context.getExternalContext().log(
+ "No state found to restore child of component " + getId());
+ }
}
- if (!(child instanceof UIData))
+ }
+ }
+ }
+
+ private void setColumnChildsState(FacesContext context, Iterator compIterator, Object state)
+ {
+ List childrenList = (List) state;
+ if (childrenList != null)
+ {
+ int idx = 0;
+ while (compIterator.hasNext())
+ {
+ UIComponent child = (UIComponent) compIterator.next();
+ if (!child.isTransient())
{
- restoreDescendantComponentStates(context, child.getFacetsAndChildren());
+ Object childState = childrenList.get(idx++);
+ if (childState != null)
+ {
+ child.processRestoreState(context, childState);
+ }
+ else
+ {
+ context.getExternalContext().log(
+ "No state found to restore child of component " + getId());
+ }
}
}
}
@@ -225,7 +318,8 @@
}
else if (name.equals("value"))
{
- _dataModel = null;
+ _dataModelMap.clear();
+ _rowStates = null;
}
else if (name.equals("var") || name.equals("rowIndex"))
{
@@ -272,11 +366,15 @@
if (_isValidChilds)
{
//Refresh DataModel for rendering:
- _dataModel = null;
+ _dataModelMap.clear();
+ _rowStates = null;
}
super.encodeBegin(context);
}
+ /**
+ * @see javax.faces.component.UIComponentBase#encodeEnd(javax.faces.context.FacesContext)
+ */
public void encodeEnd(FacesContext context) throws IOException
{
setRowIndex(-1);
@@ -363,8 +461,7 @@
//Column is not visible
continue;
}
- for (Iterator facetsIter = child.getFacets().values().iterator(); facetsIter
- .hasNext();)
+ for (Iterator facetsIter = child.getFacets().values().iterator(); facetsIter.hasNext();)
{
UIComponent facet = (UIComponent) facetsIter.next();
process(context, facet, processAction);
@@ -431,11 +528,14 @@
private DataModel getDataModel()
{
- if (_dataModel == null)
+ String clientID = getParent().getClientId(getFacesContext());
+ DataModel dataModel = (DataModel) _dataModelMap.get(clientID);
+ if (dataModel == null)
{
- _dataModel = createDataModel();
+ dataModel = createDataModel();
+ _dataModelMap.put(clientID, dataModel);
}
- return _dataModel;
+ return dataModel;
}
/**
@@ -573,47 +673,12 @@
}
};
- private static class ChildStateHolder implements Serializable
- {
- private final Object _state;
-
- public ChildStateHolder(FacesContext context, StateHolder stateHolder)
- {
- _state = stateHolder.saveState(context);
- }
-
- public void restoreState(FacesContext context, StateHolder stateHolder)
- {
- stateHolder.restoreState(context, _state);
- }
- }
-
public void setValue(Object value)
{
_value = value;
- _dataModel = null;
- }
-
- /**
- * @see javax.faces.component.UIComponentBase#processSaveState(javax.faces.context.FacesContext)
- */
- public Object processSaveState(FacesContext context)
- {
- // state of uidata will not be processed
- _processUIDataState = false;
- Object state = super.processSaveState(context);
- _processUIDataState = true;
- return state;
- }
-
- /**
- * @see javax.faces.component.UIComponentBase#processRestoreState(javax.faces.context.FacesContext, java.lang.Object)
- */
- public void processRestoreState(FacesContext context, Object state)
- {
- _processUIDataState = false;
- super.processRestoreState(context, state);
- _processUIDataState = true;
+ _dataModelMap.clear();
+ _rowStates = null;
+ _isValidChilds = true;
}
public Object saveState(FacesContext context)
@@ -624,13 +689,7 @@
values[ROWS_STATE_INDEX] = _rows;
values[VALUE_STATE_INDEX] = _value;
values[VAR_STATE_INDEX] = _var;
-
- if (_processUIDataState)
- {
- values[ROW_STATE_INDEX] = _rowState;
- values[DATAMODEL_STATE_INDEX] = _dataModel;
- values[VALID_CHILDS_STATE_INDEX] = Boolean.valueOf(_isValidChilds);
- }
+ values[VALID_CHILDS_STATE_INDEX] = Boolean.valueOf(_isValidChilds);
return values;
}
@@ -640,33 +699,17 @@
super.restoreState(context, values[0]);
_first = (Integer) values[FIRST_STATE_INDEX];
_rows = (Integer) values[ROWS_STATE_INDEX];
- _value = (Object) values[VALUE_STATE_INDEX];
+ _value = values[VALUE_STATE_INDEX];
_var = (String) values[VAR_STATE_INDEX];
- if (_processUIDataState)
+ Boolean validChilds = (Boolean) values[VALID_CHILDS_STATE_INDEX];
+ if (validChilds != null)
{
- Map rowState = (Map) values[ROW_STATE_INDEX];
- if (rowState != null)
- {
- _rowState = rowState;
- }
- else
- {
- _rowState.clear();
- }
-
- _dataModel = (DataModel) values[DATAMODEL_STATE_INDEX];
-
- Boolean validChilds = (Boolean) values[VALID_CHILDS_STATE_INDEX];
- if (validChilds != null)
- {
- _isValidChilds = validChilds.booleanValue();
- }
- else
- {
- // defaults to true
- _isValidChilds = true;
- }
+ _isValidChilds = validChilds.booleanValue();
+ }
+ else
+ {
+ _isValidChilds = true;
}
}
Modified: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/component/html/ext/HtmlDataTable.java
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/component/html/ext/HtmlDataTable.java?rev=219640&r1=219639&r2=219640&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/component/html/ext/HtmlDataTable.java (original)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/component/html/ext/HtmlDataTable.java Tue Jul 19 03:17:49 2005
@@ -24,8 +24,6 @@
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
-import javax.faces.event.AbortProcessingException;
-import javax.faces.event.FacesEvent;
import javax.faces.model.DataModel;
import org.apache.commons.logging.Log;
@@ -50,7 +48,7 @@
private static final boolean DEFAULT_SORTASCENDING = true;
private static final Class OBJECT_ARRAY_CLASS = (new Object[0]).getClass();
- private transient boolean _isDataModelRestored = false;
+ private _SerializableDataModel _preservedDataModel;
private String _sortColumn = null;
private Boolean _sortAscending = null;
@@ -59,13 +57,6 @@
private boolean _isValidChilds = true;
- public void setValue(Object value)
- {
- _dataModel = null;
- _isDataModelRestored = false;
- super.setValue(value);
- }
-
public void setRowIndex(int rowIndex)
{
String rowIndexVar = getRowIndexVar();
@@ -130,11 +121,6 @@
}
}
- public void processRestoreState(FacesContext context, Object state)
- {
- super.processRestoreState(context, state);
- }
-
public void processDecodes(FacesContext context)
{
if (!isRendered())
@@ -143,8 +129,7 @@
}
super.processDecodes(context);
setRowIndex(-1);
- processColumnsFacets(context, PROCESS_DECODES);
- processColumnsChildren(context, PROCESS_DECODES);
+ processColumns(context, PROCESS_DECODES);
setRowIndex(-1);
}
@@ -152,76 +137,14 @@
* @param context
* @param processAction
*/
- private void processColumnsChildren(FacesContext context, int processAction)
+ private void processColumns(FacesContext context, int processAction)
{
- int first = getFirst();
- int rows = getRows();
- int last;
- if (rows == 0)
+ for (Iterator it = getChildren().iterator(); it.hasNext();)
{
- last = getRowCount();
- }
- else
- {
- last = first + rows;
- }
- for (int rowIndex = first; rowIndex < last; rowIndex++)
- {
- setRowIndex(rowIndex);
- if (isRowAvailable())
- {
- for (Iterator it = getChildren().iterator(); it.hasNext();)
- {
- UIComponent child = (UIComponent) it.next();
- if (child instanceof UIColumns)
- {
- if (child.isRendered())
- {
- UIColumns columns = (UIColumns) child;
- for (int colIndex = 0, size = columns.getRowCount(); colIndex < size; colIndex++)
- {
- columns.setRowIndex(colIndex);
- for (Iterator columnChildIter = child.getChildren().iterator(); columnChildIter
- .hasNext();)
- {
- UIComponent columnChild = (UIComponent) columnChildIter.next();
- process(context, columnChild, processAction);
- }
- }
- columns.setRowIndex(-1);
- }
- }
- }
- }
- }
- }
-
- /**
- * @param context
- * @param processAction
- */
- private void processColumnsFacets(FacesContext context, int processAction)
- {
- for (Iterator childIter = getChildren().iterator(); childIter.hasNext();)
- {
- UIComponent child = (UIComponent) childIter.next();
+ UIComponent child = (UIComponent) it.next();
if (child instanceof UIColumns)
{
- if (child.isRendered())
- {
- UIColumns columns = (UIColumns) child;
- for (int i = 0, size = columns.getRowCount(); i < size; i++)
- {
- columns.setRowIndex(i);
- for (Iterator facetsIter = child.getFacets().values().iterator(); facetsIter
- .hasNext();)
- {
- UIComponent facet = (UIComponent) facetsIter.next();
- process(context, facet, processAction);
- }
- }
- columns.setRowIndex(-1);
- }
+ process(context, child, processAction);
}
}
}
@@ -248,11 +171,9 @@
{
return;
}
- setRowIndex(-1);
- processColumnsFacets(context, PROCESS_VALIDATORS);
- processColumnsChildren(context, PROCESS_VALIDATORS);
- setRowIndex(-1);
super.processValidators(context);
+ processColumns(context, PROCESS_VALIDATORS);
+ setRowIndex(-1);
if (context.getRenderResponse())
{
@@ -260,37 +181,24 @@
}
}
- public Object processSaveState(FacesContext context)
- {
- return super.processSaveState(context);
- }
-
- public void broadcast(FacesEvent event) throws AbortProcessingException
- {
- super.broadcast(event);
- }
-
public void processUpdates(FacesContext context)
{
if (!isRendered())
{
return;
}
- setRowIndex(-1);
- processColumnsFacets(context, PROCESS_UPDATES);
- processColumnsChildren(context, PROCESS_UPDATES);
- setRowIndex(-1);
-
super.processUpdates(context);
+ processColumns(context, PROCESS_UPDATES);
+ setRowIndex(-1);
- if (_isDataModelRestored)
+ if (isPreserveDataModel())
{
updateModelFromPreservedDataModel(context);
}
if (context.getRenderResponse())
{
- _isValidChilds = false;
+ _isValidChilds = false;
}
}
@@ -299,7 +207,7 @@
ValueBinding vb = getValueBinding("value");
if (vb != null && !vb.isReadOnly(context))
{
- _SerializableDataModel dm = (_SerializableDataModel) _dataModel;
+ _SerializableDataModel dm = (_SerializableDataModel) getDataModel();
Class type = vb.getType(context);
if (DataModel.class.isAssignableFrom(type))
{
@@ -333,67 +241,9 @@
}
}
}
- _dataModel = null;
- _isDataModelRestored = false;
+ _preservedDataModel = null;
}
-// (this is not called from anywhere)
-// /**
-// * TODO: We could perhaps optimize this if we know we are derived from MyFaces UIData implementation
-// */
-// private boolean isAllChildrenAndFacetsValid()
-// {
-// int first = getFirst();
-// int rows = getRows();
-// int last;
-// if (rows == 0)
-// {
-// last = getRowCount();
-// }
-// else
-// {
-// last = first + rows;
-// }
-// try
-// {
-// for (int rowIndex = first; rowIndex < last; rowIndex++)
-// {
-// setRowIndex(rowIndex);
-// if (isRowAvailable())
-// {
-// if (!isAllEditableValueHoldersValidRecursive(getFacetsAndChildren()))
-// {
-// return false;
-// }
-// }
-// }
-// }
-// finally
-// {
-// setRowIndex(-1);
-// }
-// return true;
-// }
-//
-
-// (this is not called from anywhere)
-// private boolean isAllEditableValueHoldersValidRecursive(Iterator facetsAndChildrenIterator)
-// {
-// while (facetsAndChildrenIterator.hasNext())
-// {
-// UIComponent c = (UIComponent) facetsAndChildrenIterator.next();
-// if (c instanceof EditableValueHolder && !((EditableValueHolder) c).isValid())
-// {
-// return false;
-// }
-// if (!isAllEditableValueHoldersValidRecursive(c.getFacetsAndChildren()))
-// {
-// return false;
-// }
-// }
-// return true;
-// }
-
public void encodeBegin(FacesContext context) throws IOException
{
if (!isRendered())
@@ -401,12 +251,20 @@
if (_isValidChilds)
{
- _isDataModelRestored = false;
+ _preservedDataModel = null;
}
if (isRenderedIfEmpty() || getRowCount() > 0)
{
super.encodeBegin(context);
+ for (Iterator iter = getChildren().iterator(); iter.hasNext();)
+ {
+ UIComponent component = (UIComponent) iter.next();
+ if (component instanceof UIColumns)
+ {
+ ((UIColumns) component).encodeTableBegin(context);
+ }
+ }
}
}
@@ -429,15 +287,23 @@
if (isRenderedIfEmpty() || getRowCount() > 0)
{
super.encodeEnd(context);
+ for (Iterator iter = getChildren().iterator(); iter.hasNext();)
+ {
+ UIComponent component = (UIComponent) iter.next();
+ if (component instanceof UIColumns)
+ {
+ ((UIColumns) component).encodeTableEnd(context);
+ }
+ }
}
}
public int getFirst()
{
- if (_isDataModelRestored)
+ if (_preservedDataModel != null)
{
//Rather get the currently restored DataModel attribute
- return ((_SerializableDataModel) _dataModel).getFirst();
+ return ((_SerializableDataModel) _preservedDataModel).getFirst();
}
else
{
@@ -447,20 +313,20 @@
public void setFirst(int first)
{
- if (_isDataModelRestored)
+ if (_preservedDataModel != null)
{
//Also change the currently restored DataModel attribute
- ((_SerializableDataModel) _dataModel).setFirst(first);
+ ((_SerializableDataModel) _preservedDataModel).setFirst(first);
}
super.setFirst(first);
}
public int getRows()
{
- if (_isDataModelRestored)
+ if (_preservedDataModel != null)
{
//Rather get the currently restored DataModel attribute
- return ((_SerializableDataModel) _dataModel).getRows();
+ return ((_SerializableDataModel) _preservedDataModel).getRows();
}
else
{
@@ -470,10 +336,10 @@
public void setRows(int rows)
{
- if (_isDataModelRestored)
+ if (_preservedDataModel != null)
{
//Also change the currently restored DataModel attribute
- ((_SerializableDataModel) _dataModel).setRows(rows);
+ ((_SerializableDataModel) _preservedDataModel).setRows(rows);
}
super.setRows(rows);
}
@@ -493,19 +359,32 @@
values[2] = null;
}
values[3] = _preserveSort;
- values[4] = _sortColumn;
+ values[4] = _sortColumn;
values[5] = _sortAscending;
values[6] = _renderedIfEmpty;
values[7] = _rowCountVar;
values[8] = _rowIndexVar;
values[9] = _rowOnMouseOver;
values[10] = _rowOnMouseOut;
- values[11] = preserveSort ? getSortColumn() : null;
- values[12] = preserveSort ? Boolean.valueOf(isSortAscending()) : null;
+ values[11] = preserveSort ? getSortColumn() : null;
+ values[12] = preserveSort ? Boolean.valueOf(isSortAscending()) : null;
return values;
}
+ /**
+ * @see org.apache.myfaces.component.html.ext.HtmlDataTableHack#getDataModel()
+ */
+ protected DataModel getDataModel()
+ {
+ if (_preservedDataModel != null)
+ {
+ setDataModel(_preservedDataModel);
+ _preservedDataModel = null;
+ }
+ return super.getDataModel();
+ }
+
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[]) state;
@@ -513,13 +392,11 @@
_preserveDataModel = (Boolean) values[1];
if (isPreserveDataModel())
{
- _dataModel = (_SerializableDataModel) restoreAttachedState(context, values[2]);
- _isDataModelRestored = true;
+ _preservedDataModel = (_SerializableDataModel) restoreAttachedState(context, values[2]);
}
else
{
- _dataModel = null;
- _isDataModelRestored = false;
+ _preservedDataModel = null;
}
_preserveSort = (Boolean) values[3];
_sortColumn = (String) values[4];
@@ -530,41 +407,42 @@
_rowOnMouseOver = (String) values[9];
_rowOnMouseOut = (String) values[10];
- if (isPreserveSort())
- {
- String sortColumn = (String) values[11];
- Boolean sortAscending = (Boolean) values[12];
- if (sortColumn != null && sortAscending != null)
- {
- ValueBinding vb = getValueBinding("sortColumn");
- if (vb != null && !vb.isReadOnly(context))
- {
- vb.setValue(context, sortColumn);
- }
-
- vb = getValueBinding("sortAscending");
- if (vb != null && !vb.isReadOnly(context))
- {
- vb.setValue(context, sortAscending);
- }
- }
+ if (isPreserveSort())
+ {
+ String sortColumn = (String) values[11];
+ Boolean sortAscending = (Boolean) values[12];
+ if (sortColumn != null && sortAscending != null)
+ {
+ ValueBinding vb = getValueBinding("sortColumn");
+ if (vb != null && !vb.isReadOnly(context))
+ {
+ vb.setValue(context, sortColumn);
+ }
+
+ vb = getValueBinding("sortAscending");
+ if (vb != null && !vb.isReadOnly(context))
+ {
+ vb.setValue(context, sortAscending);
+ }
+ }
}
}
public _SerializableDataModel getSerializableDataModel()
{
- if (_dataModel != null)
+ DataModel dm = getDataModel();
+ if (dm instanceof _SerializableDataModel)
{
- if (_dataModel instanceof _SerializableDataModel)
- {
- return (_SerializableDataModel) _dataModel;
- }
- else
- {
- return new _SerializableDataModel(getFirst(), getRows(), _dataModel);
- }
+ return (_SerializableDataModel) dm;
}
+ return createSerializableDataModel();
+ }
+ /**
+ * @return
+ */
+ private _SerializableDataModel createSerializableDataModel()
+ {
Object value = getValue();
if (value == null)
{
Modified: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/component/html/ext/HtmlDataTableHack.java
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/component/html/ext/HtmlDataTableHack.java?rev=219640&r1=219639&r2=219640&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/component/html/ext/HtmlDataTableHack.java (original)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/component/html/ext/HtmlDataTableHack.java Tue Jul 19 03:17:49 2005
@@ -1,16 +1,30 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.apache.myfaces.component.html.ext;
import java.io.IOException;
-import java.io.Serializable;
import java.sql.ResultSet;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import javax.faces.component.StateHolder;
+import javax.faces.component.UIColumn;
import javax.faces.component.UIComponent;
-import javax.faces.component.UIData;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import javax.faces.model.ArrayDataModel;
@@ -30,358 +44,407 @@
*/
abstract class HtmlDataTableHack extends javax.faces.component.html.HtmlDataTable
{
- protected DataModel _dataModel = null;
+ private Map _dataModelMap = new HashMap();
- // will be set to false if the data should not be refreshed at the beginning of the encode phase
- private boolean _isValidChilds = true;
+ // will be set to false if the data should not be refreshed at the beginning of the encode phase
+ private boolean _isValidChilds = true;
- private Map _rowState = new HashMap();
+ // holds for each row the states of the child components of this UIData
+ private Map _rowStates = null;
- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- // Every field and method from here is identical to UIData !!!!!!!!!
-
- private static final Class OBJECT_ARRAY_CLASS = (new Object[0]).getClass();
-
- private int _rowIndex = -1;
-
- // will be set to false if the _rowstate and _datamodel should not be saved
- private boolean _processUIDataState = true;
-
- public boolean isRowAvailable()
- {
- return getDataModel().isRowAvailable();
- }
-
- public int getRowCount()
- {
- return getDataModel().getRowCount();
- }
-
- public Object getRowData()
- {
- return getDataModel().getRowData();
- }
-
- public int getRowIndex()
- {
- return _rowIndex;
- }
-
- /**
- * @see javax.faces.component.UIData#processUpdates(javax.faces.context.FacesContext)
- */
- public void processUpdates(FacesContext context)
- {
- super.processUpdates(context);
- // check if a update model error forces the render response for our data
- if (context.getRenderResponse())
- {
- _isValidChilds = false;
- }
- }
-
- /**
- * @see javax.faces.component.UIData#processValidators(javax.faces.context.FacesContext)
- */
- public void processValidators(FacesContext context)
- {
- super.processValidators(context);
- // check if a validation error forces the render response for our data
- if (context.getRenderResponse())
- {
- _isValidChilds = false;
- }
- }
-
- /**
- * @see javax.faces.component.UIData#encodeBegin(javax.faces.context.FacesContext)
- */
- public void encodeBegin(FacesContext context) throws IOException
- {
- if (_isValidChilds)
- {
- //Refresh DataModel for rendering:
- _dataModel = null;
- }
- super.encodeBegin(context);
- }
-
- /**
- * @see javax.faces.component.UIData#encodeEnd(javax.faces.context.FacesContext)
- */
- public void encodeEnd(FacesContext context) throws IOException
- {
- setRowIndex(-1);
- super.encodeEnd(context);
- }
-
- public void setRowIndex(int rowIndex)
- {
- if (_rowIndex == rowIndex)
- {
- return;
- }
-
- FacesContext context = getFacesContext();
-
- saveDescendantComponentStates(context, getFacetsAndChildren());
-
- _rowIndex = rowIndex;
-
- DataModel dataModel = getDataModel();
- dataModel.setRowIndex(rowIndex);
-
- String var = getVar();
- if (rowIndex == -1)
- {
- if (var != null)
- {
- context.getExternalContext().getRequestMap().remove(var);
- }
- }
- else
- {
- if (var != null)
- {
- if (isRowAvailable())
- {
- Object rowData = dataModel.getRowData();
- context.getExternalContext().getRequestMap().put(var, rowData);
- }
- else
- {
- context.getExternalContext().getRequestMap().remove(var);
- }
- }
- }
-
- restoreDescendantComponentStates(context, getFacetsAndChildren());
- }
-
- private void saveDescendantComponentStates(FacesContext context, Iterator childIterator)
- {
- while (childIterator.hasNext())
- {
- UIComponent child = (UIComponent) childIterator.next();
- if (!child.isTransient())
- {
- _rowState.put(child.getClientId(context), new ChildStateHolder(context, child));
- if (!(child instanceof UIData))
- {
- saveDescendantComponentStates(context, child.getFacetsAndChildren());
- }
- }
- }
- }
-
- private void restoreDescendantComponentStates(FacesContext context, Iterator childIterator)
- {
- while (childIterator.hasNext())
- {
- UIComponent child = (UIComponent) childIterator.next();
- // the spec 1.1 (3.1.6) says: setting the id will recalculate the clientid
- child.setId(child.getId());
- if (!child.isTransient())
- {
- String clientId = child.getClientId(context);
- ChildStateHolder childStateHolder = (ChildStateHolder) _rowState.get(clientId);
- if (childStateHolder != null)
- {
- childStateHolder.restoreState(context, child);
- }
- if (!(child instanceof UIData))
- {
- restoreDescendantComponentStates(context, child.getFacetsAndChildren());
- }
- }
- }
- }
-
- public void setValueBinding(String name, ValueBinding binding)
- {
- if (name == null)
- {
- throw new NullPointerException("name");
- }
- else if (name.equals("value"))
- {
- _dataModel = null;
- }
- else if (name.equals("var") || name.equals("rowIndex"))
- {
- throw new IllegalArgumentException("name " + name);
- }
- super.setValueBinding(name, binding);
- }
-
- private DataModel getDataModel()
- {
- if (_dataModel == null)
- {
- _dataModel = createDataModel();
- }
- return _dataModel;
- }
-
- /**
- * Creates a new DataModel around the current value.
- */
- private DataModel createDataModel()
- {
- Object value = getValue();
- if (value == null)
- {
- return EMPTY_DATA_MODEL;
- }
- else if (value instanceof DataModel)
- {
- return (DataModel) value;
- }
- else if (value instanceof List)
- {
- return new ListDataModel((List) value);
- }
- else if (OBJECT_ARRAY_CLASS.isAssignableFrom(value.getClass()))
- {
- return new ArrayDataModel((Object[]) value);
- }
- else if (value instanceof ResultSet)
- {
- return new ResultSetDataModel((ResultSet) value);
- }
- else if (value instanceof Result)
- {
- return new ResultDataModel((Result) value);
- }
- else
- {
- return new ScalarDataModel(value);
- }
- }
-
- private static final DataModel EMPTY_DATA_MODEL = new DataModel()
- {
- public boolean isRowAvailable()
- {
- return false;
- }
-
- public int getRowCount()
- {
- return 0;
- }
-
- public Object getRowData()
- {
- throw new IllegalArgumentException();
- }
-
- public int getRowIndex()
- {
- return -1;
- }
-
- public void setRowIndex(int i)
- {
- if (i < -1)
- throw new IndexOutOfBoundsException("Index < 0 : " + i);
- }
-
- public Object getWrappedData()
- {
- return null;
- }
-
- public void setWrappedData(Object obj)
- {
- if (obj == null)
- return; //Clearing is allowed
- throw new UnsupportedOperationException(this.getClass().getName()
- + " UnsupportedOperationException");
- }
- };
-
- private static class ChildStateHolder implements Serializable
- {
- private final Object _state;
-
- public ChildStateHolder(FacesContext context, StateHolder stateHolder)
- {
- _state = stateHolder.saveState(context);
- }
-
- public void restoreState(FacesContext context, StateHolder stateHolder)
- {
- stateHolder.restoreState(context, _state);
- }
- }
-
- /**
- * @see javax.faces.component.UIComponentBase#processSaveState(javax.faces.context.FacesContext)
- */
- public Object processSaveState(FacesContext context)
- {
- // state of uidata will not be processed
- _processUIDataState = false;
- Object state = super.processSaveState(context);
- _processUIDataState = true;
- return state;
- }
-
- /**
- * @see javax.faces.component.UIComponentBase#processRestoreState(javax.faces.context.FacesContext, java.lang.Object)
- */
- public void processRestoreState(FacesContext context, Object state)
- {
- _processUIDataState = false;
- super.processRestoreState(context, state);
- _processUIDataState = true;
- }
-
- public Object saveState(FacesContext context)
- {
- Object values[] = new Object[4];
- values[0] = super.saveState(context);
-
- if (_processUIDataState)
- {
- values[1] = _rowState;
- values[2] = _dataModel;
- values[3] = Boolean.valueOf(_isValidChilds);
- }
- return values;
- }
-
- public void restoreState(FacesContext context, Object state)
- {
- Object values[] = (Object[]) state;
- super.restoreState(context, values[0]);
-
- if (_processUIDataState)
- {
- Map rowState = (Map) values[1];
- if (rowState != null)
- {
- _rowState = rowState;
- }
- else
- {
- _rowState.clear();
- }
-
- _dataModel = (DataModel) values[2];
-
- Boolean validChilds = (Boolean) values[3];
- if (validChilds != null)
- {
- _isValidChilds = validChilds.booleanValue();
- }
- else
- {
- // defaults to true
- _isValidChilds = true;
- }
- }
- }
+ // contains the initial row state which is used to initialize each row
+ private Object _initialRowState = null;
+
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // Every field and method from here is identical to UIData !!!!!!!!!
+
+ private static final Class OBJECT_ARRAY_CLASS = (new Object[0]).getClass();
+
+ private int _rowIndex = -1;
+
+ public boolean isRowAvailable()
+ {
+ return getDataModel().isRowAvailable();
+ }
+
+ public int getRowCount()
+ {
+ return getDataModel().getRowCount();
+ }
+
+ public Object getRowData()
+ {
+ return getDataModel().getRowData();
+ }
+
+ public int getRowIndex()
+ {
+ return _rowIndex;
+ }
+
+ /**
+ * @see javax.faces.component.UIData#processUpdates(javax.faces.context.FacesContext)
+ */
+ public void processUpdates(FacesContext context)
+ {
+ super.processUpdates(context);
+ // check if a update model error forces the render response for our data
+ if (context.getRenderResponse())
+ {
+ _isValidChilds = false;
+ }
+ }
+
+ /**
+ * @see javax.faces.component.UIData#processValidators(javax.faces.context.FacesContext)
+ */
+ public void processValidators(FacesContext context)
+ {
+ super.processValidators(context);
+ // check if a validation error forces the render response for our data
+ if (context.getRenderResponse())
+ {
+ _isValidChilds = false;
+ }
+ }
+
+ /**
+ * @see javax.faces.component.UIData#encodeBegin(javax.faces.context.FacesContext)
+ */
+ public void encodeBegin(FacesContext context) throws IOException
+ {
+ if (_isValidChilds)
+ {
+ //Refresh DataModel for rendering:
+ _dataModelMap.clear();
+ _rowStates = null;
+ }
+ super.encodeBegin(context);
+ }
+
+ /**
+ * @see javax.faces.component.UIComponentBase#encodeEnd(javax.faces.context.FacesContext)
+ */
+ public void encodeEnd(FacesContext context) throws IOException
+ {
+ setRowIndex(-1);
+ super.encodeEnd(context);
+ }
+
+ public void setRowIndex(int rowIndex)
+ {
+ if (_rowIndex == rowIndex)
+ {
+ return;
+ }
+
+ FacesContext context = getFacesContext();
+
+ if (_rowIndex != -1)
+ {
+ if (_rowStates == null)
+ {
+ _rowStates = new HashMap();
+ }
+ _rowStates.put(getClientId(context), processSaveRowState(context));
+ }
+ else if (_initialRowState == null)
+ {
+ _initialRowState = processSaveRowState(context);
+ }
+
+ _rowIndex = rowIndex;
+
+ DataModel dataModel = getDataModel();
+ dataModel.setRowIndex(rowIndex);
+
+ String var = getVar();
+ if (rowIndex == -1)
+ {
+ if (var != null)
+ {
+ context.getExternalContext().getRequestMap().remove(var);
+ }
+ }
+ else
+ {
+ if (var != null)
+ {
+ if (isRowAvailable())
+ {
+ Object rowData = dataModel.getRowData();
+ context.getExternalContext().getRequestMap().put(var, rowData);
+ }
+ else
+ {
+ context.getExternalContext().getRequestMap().remove(var);
+ }
+ }
+ }
+
+ if (_rowIndex != -1 && _rowStates != null)
+ {
+ Object state = _rowStates.get(getClientId(context));
+ if (state == null)
+ {
+ state = _initialRowState;
+ }
+ processRestoreRowState(context, state);
+ }
+ else
+ {
+ processRestoreRowState(context, _initialRowState);
+ }
+ }
+
+ private Object processSaveRowState(FacesContext context)
+ {
+ if (isTransient())
+ return null;
+ List childStates = null;
+ int columnCount = getChildCount();
+ if (columnCount > 0)
+ {
+ for (Iterator colIt = getChildren().iterator(); colIt.hasNext();)
+ {
+ UIComponent child = (UIComponent) colIt.next();
+ if (!child.isTransient())
+ {
+ if (childStates == null)
+ {
+ childStates = new ArrayList(columnCount);
+ }
+ if (child instanceof UIColumn)
+ {
+ childStates.add(new Object[] {child.saveState(context),
+ getColumnChildsState(context, child.getChildren().iterator())});
+ }
+ else
+ {
+ childStates.add(child.processSaveState(context));
+ }
+ }
+ }
+ }
+ return childStates;
+ }
+
+ private Object getColumnChildsState(FacesContext context, Iterator compIterator)
+ {
+ List result = null;
+ while (compIterator.hasNext())
+ {
+ UIComponent colChild = (UIComponent) compIterator.next();
+ if (!colChild.isTransient())
+ {
+ if (result == null)
+ {
+ result = new ArrayList();
+ }
+ result.add(colChild.processSaveState(context));
+ }
+ }
+ return result;
+ }
+
+ public void processRestoreRowState(FacesContext context, Object state)
+ {
+ List childrenStates = (List) state;
+ int childCount = getChildCount();
+ if (childCount > 0)
+ {
+ int idx = 0;
+ for (Iterator it = getChildren().iterator(); it.hasNext();)
+ {
+ UIComponent child = (UIComponent) it.next();
+ if (!child.isTransient())
+ {
+ Object childState = childrenStates.get(idx++);
+ if (childState != null)
+ {
+ if (child instanceof UIColumn)
+ {
+ Object[] columnState = (Object[]) childState;
+ setColumnChildsState(context, child.getChildren().iterator(), columnState[1]);
+ child.restoreState(context, columnState[0]);
+ }
+ else
+ {
+ child.processRestoreState(context, childState);
+ }
+ }
+ else
+ {
+ context.getExternalContext().log(
+ "No state found to restore child of component " + getId());
+ }
+ }
+ }
+ }
+ }
+
+ private void setColumnChildsState(FacesContext context, Iterator compIterator, Object state)
+ {
+ List childrenList = (List) state;
+ if (childrenList != null)
+ {
+ int idx = 0;
+ while (compIterator.hasNext())
+ {
+ UIComponent child = (UIComponent) compIterator.next();
+ if (!child.isTransient())
+ {
+ Object childState = childrenList.get(idx++);
+ if (childState != null)
+ {
+ child.processRestoreState(context, childState);
+ }
+ else
+ {
+ context.getExternalContext().log(
+ "No state found to restore child of component " + getId());
+ }
+ }
+ }
+ }
+ }
+
+ public void setValueBinding(String name, ValueBinding binding)
+ {
+ if (name == null)
+ {
+ throw new NullPointerException("name");
+ }
+ else if (name.equals("value"))
+ {
+ _dataModelMap.clear();
+ _rowStates = null;
+ }
+ else if (name.equals("var") || name.equals("rowIndex"))
+ {
+ throw new IllegalArgumentException("name " + name);
+ }
+ super.setValueBinding(name, binding);
+ }
+
+ protected DataModel getDataModel()
+ {
+ String clientID = getParent().getClientId(getFacesContext());
+ DataModel dataModel = (DataModel) _dataModelMap.get(clientID);
+ if (dataModel == null)
+ {
+ dataModel = createDataModel();
+ _dataModelMap.put(clientID, dataModel);
+ }
+ return dataModel;
+ }
+
+ protected void setDataModel(DataModel datamodel)
+ {
+ _dataModelMap.put(getParent().getClientId(getFacesContext()), datamodel);
+ }
+
+ /**
+ * Creates a new DataModel around the current value.
+ */
+ protected DataModel createDataModel()
+ {
+ Object value = getValue();
+ if (value == null)
+ {
+ return EMPTY_DATA_MODEL;
+ }
+ else if (value instanceof DataModel)
+ {
+ return (DataModel) value;
+ }
+ else if (value instanceof List)
+ {
+ return new ListDataModel((List) value);
+ }
+ else if (OBJECT_ARRAY_CLASS.isAssignableFrom(value.getClass()))
+ {
+ return new ArrayDataModel((Object[]) value);
+ }
+ else if (value instanceof ResultSet)
+ {
+ return new ResultSetDataModel((ResultSet) value);
+ }
+ else if (value instanceof Result)
+ {
+ return new ResultDataModel((Result) value);
+ }
+ else
+ {
+ return new ScalarDataModel(value);
+ }
+ }
+
+ private static final DataModel EMPTY_DATA_MODEL = new DataModel()
+ {
+ public boolean isRowAvailable()
+ {
+ return false;
+ }
+
+ public int getRowCount()
+ {
+ return 0;
+ }
+
+ public Object getRowData()
+ {
+ throw new IllegalArgumentException();
+ }
+
+ public int getRowIndex()
+ {
+ return -1;
+ }
+
+ public void setRowIndex(int i)
+ {
+ if (i < -1)
+ throw new IndexOutOfBoundsException("Index < 0 : " + i);
+ }
+
+ public Object getWrappedData()
+ {
+ return null;
+ }
+
+ public void setWrappedData(Object obj)
+ {
+ if (obj == null)
+ return; //Clearing is allowed
+ throw new UnsupportedOperationException(this.getClass().getName()
+ + " UnsupportedOperationException");
+ }
+ };
+
+ public Object saveState(FacesContext context)
+ {
+ Object values[] = new Object[2];
+ values[0] = super.saveState(context);
+ values[1] = Boolean.valueOf(_isValidChilds);
+
+ return values;
+ }
+
+ public void restoreState(FacesContext context, Object state)
+ {
+ Object values[] = (Object[]) state;
+ super.restoreState(context, values[0]);
+
+ Boolean validChilds = (Boolean) values[1];
+ if (validChilds != null)
+ {
+ _isValidChilds = validChilds.booleanValue();
+ }
+ else
+ {
+ _isValidChilds = true;
+ }
+ }
}
Modified: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/crosstable/UIColumns.java
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/crosstable/UIColumns.java?rev=219640&r1=219639&r2=219640&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/crosstable/UIColumns.java (original)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/crosstable/UIColumns.java Tue Jul 19 03:17:49 2005
@@ -15,7 +15,23 @@
*/
package org.apache.myfaces.custom.crosstable;
+import java.sql.ResultSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
import javax.faces.component.UIData;
+import javax.faces.context.FacesContext;
+import javax.faces.el.ValueBinding;
+import javax.faces.model.ArrayDataModel;
+import javax.faces.model.DataModel;
+import javax.faces.model.ListDataModel;
+import javax.faces.model.ResultDataModel;
+import javax.faces.model.ResultSetDataModel;
+import javax.faces.model.ScalarDataModel;
+import javax.servlet.jsp.jstl.sql.Result;
/**
* @author Mathias Broekelmann (latest modification by $Author$)
@@ -26,6 +42,24 @@
public static final String COMPONENT_TYPE = "org.apache.myfaces.Columns";
public static final String COMPONENT_FAMILY = UIData.COMPONENT_FAMILY;
+ private static final Class OBJECT_ARRAY_CLASS = (new Object[0]).getClass();
+ private static final int PROCESS_DECODES = 1;
+ private static final int PROCESS_VALIDATORS = 2;
+ private static final int PROCESS_UPDATES = 3;
+
+ private boolean _isValidChilds = true;
+
+ // holds the the state for each cell of the child components of this UIColumns
+ private Map _cellStates = null;
+
+ // contains the initial cell state which is used to initialize each cell
+ private Object _initialCellState = null;
+
+ private int _colIndex = -1;
+ private UIData _parentUIData;
+
+ private Map _dataModelMap = new HashMap();
+
/**
*
*/
@@ -48,5 +82,437 @@
public String getFamily()
{
return COMPONENT_FAMILY;
+ }
+
+ public boolean isRowAvailable()
+ {
+ return getDataModel().isRowAvailable();
+ }
+
+ public int getRowCount()
+ {
+ return getDataModel().getRowCount();
+ }
+
+ public Object getRowData()
+ {
+ return getDataModel().getRowData();
+ }
+
+ public int getRowIndex()
+ {
+ return _colIndex;
+ }
+
+ public void setRowIndex(int colIndex)
+ {
+ if (_colIndex == colIndex)
+ {
+ return;
+ }
+
+ FacesContext facesContext = getFacesContext();
+
+ int firstColIndex = getFirst();
+
+ if (_colIndex != -1)
+ {
+ if (_cellStates == null)
+ {
+ _cellStates = new HashMap();
+ }
+ _cellStates.put(getClientId(facesContext), processSaveState(facesContext));
+ }
+ else if (_initialCellState == null)
+ {
+ _initialCellState = processSaveState(facesContext);
+ }
+
+ _colIndex = colIndex;
+
+ DataModel dataModel = getDataModel();
+ dataModel.setRowIndex(colIndex);
+
+ String var = getVar();
+ if (colIndex == -1)
+ {
+ if (var != null)
+ {
+ facesContext.getExternalContext().getRequestMap().remove(var);
+ }
+ }
+ else
+ {
+ if (var != null)
+ {
+ if (isRowAvailable())
+ {
+ Object rowData = dataModel.getRowData();
+ facesContext.getExternalContext().getRequestMap().put(var, rowData);
+ }
+ else
+ {
+ facesContext.getExternalContext().getRequestMap().remove(var);
+ }
+ }
+ }
+
+ if (_colIndex != -1 && _cellStates != null)
+ {
+ Object state = _cellStates.get(getClientId(facesContext));
+ if (state == null)
+ {
+ state = _initialCellState;
+ }
+ processRestoreState(facesContext, state);
+ }
+ else
+ {
+ processRestoreState(facesContext, _initialCellState);
+ }
+ }
+
+ public void setValueBinding(String name, ValueBinding binding)
+ {
+ if (name == null)
+ {
+ throw new NullPointerException("name");
+ }
+ else if (name.equals("value"))
+ {
+ _dataModelMap.clear();
+ }
+ else if (name.equals("var") || name.equals("rowIndex"))
+ {
+ throw new IllegalArgumentException("name " + name);
+ }
+ super.setValueBinding(name, binding);
+ }
+
+ protected DataModel getDataModel()
+ {
+ String clientID = getParentUIData().getParent().getClientId(getFacesContext());
+ DataModel dataModel = (DataModel) _dataModelMap.get(clientID);
+ if (dataModel == null)
+ {
+ dataModel = createDataModel();
+ _dataModelMap.put(clientID, dataModel);
+ }
+ return dataModel;
+ }
+
+ protected void setDataModel(DataModel dataModel)
+ {
+ _dataModelMap.put(getParentUIData().getParent().getClientId(getFacesContext()), dataModel);
+ }
+
+ /**
+ * Creates a new DataModel around the current value.
+ */
+ protected DataModel createDataModel()
+ {
+ Object value = getValue();
+ if (value == null)
+ {
+ return EMPTY_DATA_MODEL;
+ }
+ else if (value instanceof DataModel)
+ {
+ return (DataModel) value;
+ }
+ else if (value instanceof List)
+ {
+ return new ListDataModel((List) value);
+ }
+ else if (OBJECT_ARRAY_CLASS.isAssignableFrom(value.getClass()))
+ {
+ return new ArrayDataModel((Object[]) value);
+ }
+ else if (value instanceof ResultSet)
+ {
+ return new ResultSetDataModel((ResultSet) value);
+ }
+ else if (value instanceof Result)
+ {
+ return new ResultDataModel((Result) value);
+ }
+ else
+ {
+ return new ScalarDataModel(value);
+ }
+ }
+
+ private static final DataModel EMPTY_DATA_MODEL = new DataModel()
+ {
+ public boolean isRowAvailable()
+ {
+ return false;
+ }
+
+ public int getRowCount()
+ {
+ return 0;
+ }
+
+ public Object getRowData()
+ {
+ throw new IllegalArgumentException();
+ }
+
+ public int getRowIndex()
+ {
+ return -1;
+ }
+
+ public void setRowIndex(int i)
+ {
+ if (i < -1)
+ throw new IndexOutOfBoundsException("Index < 0 : " + i);
+ }
+
+ public Object getWrappedData()
+ {
+ return null;
+ }
+
+ public void setWrappedData(Object obj)
+ {
+ if (obj == null)
+ return; //Clearing is allowed
+ throw new UnsupportedOperationException(this.getClass().getName()
+ + " UnsupportedOperationException");
+ }
+ };
+
+ public Object saveState(FacesContext context)
+ {
+ Object values[] = new Object[3];
+ values[0] = super.saveState(context);
+ values[1] = Boolean.valueOf(_isValidChilds);
+
+ return values;
+ }
+
+ public void restoreState(FacesContext context, Object state)
+ {
+ Object values[] = (Object[]) state;
+ super.restoreState(context, values[0]);
+
+ Boolean validChilds = (Boolean) values[2];
+ if (validChilds != null)
+ {
+ _isValidChilds = validChilds.booleanValue();
+ }
+ else
+ {
+ _isValidChilds = true;
+ }
+ }
+
+ /**
+ * @see javax.faces.component.UIData#processDecodes(javax.faces.context.FacesContext)
+ */
+ public void processDecodes(FacesContext context)
+ {
+ if (context == null)
+ throw new NullPointerException("context");
+ if (!isRendered())
+ return;
+
+ setRowIndex(-1);
+ processColumnsFacets(context, PROCESS_DECODES);
+ processRows(context, PROCESS_DECODES);
+ setRowIndex(-1);
+
+ try
+ {
+ decode(context);
+ }
+ catch (RuntimeException e)
+ {
+ context.renderResponse();
+ throw e;
+ }
+ }
+
+ /**
+ * @param context
+ * @param process_decodes2
+ */
+ private void processColumnsFacets(FacesContext context, int processAction)
+ {
+ int first = getFirst();
+ int cols = getRows();
+ int last;
+ if (cols == 0)
+ {
+ last = getRowCount();
+ }
+ else
+ {
+ last = first + cols;
+ }
+
+ for (int colIndex = first; colIndex < last; colIndex++)
+ {
+ setRowIndex(colIndex);
+ if (isRowAvailable())
+ {
+ for (Iterator facetsIter = getFacets().values().iterator(); facetsIter.hasNext();)
+ {
+ UIComponent facet = (UIComponent) facetsIter.next();
+ process(context, facet, processAction);
+ }
+ }
+ }
+ setRowIndex(-1);
+ }
+
+ /**
+ * @param context
+ * @param process_decodes2
+ */
+ private void processRows(FacesContext context, int processAction)
+ {
+ UIData parentUIData = getParentUIData();
+ int first = parentUIData.getFirst();
+ int rows = parentUIData.getRows();
+ int last;
+ if (rows == 0)
+ {
+ last = parentUIData.getRowCount();
+ }
+ else
+ {
+ last = first + rows;
+ }
+
+ for (int rowIndex = first; rowIndex < last; rowIndex++)
+ {
+ parentUIData.setRowIndex(rowIndex);
+ if (parentUIData.isRowAvailable())
+ {
+ processColumns(context, processAction);
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ private UIData getParentUIData()
+ {
+ if (_parentUIData == null)
+ {
+ UIComponent parent = getParent();
+ if (!(parent instanceof UIData))
+ {
+ throw new IllegalStateException("UIColumns component must be a child of a UIData component");
+ }
+ _parentUIData = (UIData) parent;
+ }
+ return _parentUIData;
+ }
+
+ private void processColumns(FacesContext context, int processAction)
+ {
+ int first = getFirst();
+ int cols = getRows();
+ int last;
+ if (cols == 0)
+ {
+ last = getRowCount();
+ }
+ else
+ {
+ last = first + cols;
+ }
+
+ for (int colIndex = first; colIndex < last; colIndex++)
+ {
+ setRowIndex(colIndex);
+ if (isRowAvailable())
+ {
+ for (Iterator columnChildIter = getChildren().iterator(); columnChildIter.hasNext();)
+ {
+ UIComponent columnChild = (UIComponent) columnChildIter.next();
+ process(context, columnChild, processAction);
+ }
+ }
+ }
+ setRowIndex(-1);
+ }
+
+ /**
+ * @see javax.faces.component.UIData#processValidators(javax.faces.context.FacesContext)
+ */
+ public void processValidators(FacesContext context)
+ {
+ if (context == null)
+ throw new NullPointerException("context");
+ if (!isRendered())
+ return;
+ setRowIndex(-1);
+ processColumnsFacets(context, PROCESS_VALIDATORS);
+ processRows(context, PROCESS_VALIDATORS);
+ setRowIndex(-1);
+
+ // check if an validation error forces the render response for our data
+ if (context.getRenderResponse())
+ {
+ _isValidChilds = false;
+ }
+ }
+
+ /**
+ * @see javax.faces.component.UIData#processUpdates(javax.faces.context.FacesContext)
+ */
+ public void processUpdates(FacesContext context)
+ {
+ if (context == null)
+ throw new NullPointerException("context");
+ if (!isRendered())
+ return;
+ setRowIndex(-1);
+ processColumnsFacets(context, PROCESS_UPDATES);
+ processRows(context, PROCESS_UPDATES);
+ setRowIndex(-1);
+
+ // check if an validation error forces the render response for our data
+ if (context.getRenderResponse())
+ {
+ _isValidChilds = false;
+ }
+ }
+
+ private void process(FacesContext context, UIComponent component, int processAction)
+ {
+ switch (processAction)
+ {
+ case PROCESS_DECODES:
+ component.processDecodes(context);
+ break;
+ case PROCESS_VALIDATORS:
+ component.processValidators(context);
+ break;
+ case PROCESS_UPDATES:
+ component.processUpdates(context);
+ break;
+ }
+ }
+
+ public void encodeTableBegin(FacesContext context)
+ {
+ if (_isValidChilds)
+ {
+ //Refresh DataModel for rendering:
+ _dataModelMap.clear();
+ _cellStates = null;
+ }
+ }
+
+ public void encodeTableEnd(FacesContext context)
+ {
+ setRowIndex(-1);
}
}