You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sc...@apache.org on 2005/07/05 18:28:02 UTC
svn commit: r209297 -
/myfaces/api/trunk/src/java/javax/faces/component/UIData.java
Author: schof
Date: Tue Jul 5 09:28:01 2005
New Revision: 209297
URL: http://svn.apache.org/viewcvs?rev=209297&view=rev
Log:
Patch by Mathias Broekelmann (for MYFACES-228)
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=209297&r1=209296&r2=209297&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 5 09:28:01 2005
@@ -64,21 +64,17 @@
private int _rowIndex = -1;
private String _var = null;
- // private Object[] _descendantStates;
- // private int _descendantEditableValueHolderCount = -1;
- private UIDataRowState _rowState = new UIDataRowState();
-
- //init to false, so that no descendant states are saved for a newly created UIData
- transient private boolean _saveDescendantStates = false;
-
- //Flag to detect if component is rendered for the first time (restoreState sets it to false)
- transient private boolean _firstTimeRendered = true;
+ // holds the states of the child components of this UIData
+ private Map _rowState = new HashMap();
private Boolean _isEmbeddedUIData = null;
private UIData _embeddingUIData = null;
private DataModel _dataModel = null;
- private HashMap _dataModelMap = null;
+ private Map _dataModelMap = null;
+
+ // will be set to false if the data should not be refreshed at the beginning of the encode phase
+ private boolean _isValidChilds = true;
public void setFooter(UIComponent footer)
{
@@ -122,7 +118,14 @@
public void setRowIndex(int rowIndex)
{
- saveDescendantComponentStates(getFacesContext(), this);
+ if (_rowIndex == rowIndex)
+ {
+ return;
+ }
+
+ FacesContext facesContext = getFacesContext();
+
+ saveDescendantComponentStates(facesContext, this);
_rowIndex = rowIndex;
@@ -134,7 +137,7 @@
{
if (var != null)
{
- getFacesContext().getExternalContext().getRequestMap().remove(var);
+ facesContext.getExternalContext().getRequestMap().remove(var);
}
}
else
@@ -144,349 +147,51 @@
if (isRowAvailable())
{
Object rowData = dataModel.getRowData();
- getFacesContext().getExternalContext().getRequestMap().put(var, rowData);
+ facesContext.getExternalContext().getRequestMap().put(var, rowData);
}
else
{
- getFacesContext().getExternalContext().getRequestMap().remove(var);
+ facesContext.getExternalContext().getRequestMap().remove(var);
}
}
}
- restoreDescendantComponentStates(getFacesContext(), this, true);
+ restoreDescendantComponentStates(facesContext, this);
}
- // private int getDescendantStatesRowIndex()
- // {
- // int rowIndex = getRowIndex();
- // if (rowIndex == -1)
- // {
- // return 0;
- // }
- // else
- // {
- // return rowIndex - getFirst() + 1;
- // }
- // }
-
private void saveDescendantComponentStates(FacesContext context, UIComponent component)
{
for (Iterator i = component.getFacetsAndChildren(); i.hasNext();)
{
- //TODO: what if child is an EditableValueHolder AND a UIData?
-
UIComponent child = (UIComponent) i.next();
- if (child instanceof UIData)
+ if (child.isRendered())
{
- UIData childUIData = (UIData) child;
- _rowState._clientIdsToChildUIDataStates.put(
- childUIData.getClientId(context),
- childUIData._rowState);
- continue;
- }
-
- if (child instanceof EditableValueHolder)
- {
- EditableValueHolder childEVH = (EditableValueHolder) child;
- _rowState._clientIdsToChildEVHStates.put(
- child.getClientId(context),
- new EditableValueHolderState(childEVH));
- }
-
- saveDescendantComponentStates(context, child);
- }
- }
-
- // /**
- // * The descendant Component states algorithm we implement here is pretty fast
- // * but does not support modification of the components tree during the lifecycle.
- // * TODO: should we offer an alternative implementation with a clientId based Map ?
- // */
- // private void saveDescendantComponentStates()
- // {
- // if (_descendantEditableValueHolderCount == -1)
- // {
- // //This is the first time we save the descendant components state
- // refreshDescendantDataStates();
- // }
- // else if (_descendantEditableValueHolderCount == 0)
- // {
- // //There are no EditableValueHolder children
- // return;
- // }
- // else
- // {
- // int rowIndex = getDescendantStatesRowIndex();
- // EditableValueHolderState[] rowState = null;
- // // make sure that the underlying data did not change size
- // // (i.e. someone added a row to the DataModel)
- // // BUG: #925693
- // if(rowIndex < _descendantStates.length) {
- // rowState = (EditableValueHolderState[])_descendantStates[rowIndex];
- // } else {
- // // changed size during the lifecycle - should refresh
- // refreshDescendantDataStates();
- // rowState = (EditableValueHolderState[])_descendantStates[rowIndex];
- // }
- // if (rowState == null)
- // {
- // rowState = new EditableValueHolderState[_descendantEditableValueHolderCount];
- // _descendantStates[rowIndex] = rowState;
- // }
- // saveDescendantComponentStates(this, rowState, 0, 0);
- // }
- // }
-
- // private void refreshDescendantDataStates() {
- // List list = new ArrayList();
- // saveDescendantComponentStates(this, list,0);
- // _descendantEditableValueHolderCount = list.size();
- // if (_descendantEditableValueHolderCount > 0)
- // {
- // EditableValueHolderState[] rowState
- // = (EditableValueHolderState[])list.toArray(new EditableValueHolderState[list.size()]);
- // int rows = getRows();
- // if (rows <= 0)
- // {
- // rows = getRowCount() - getFirst();
- // }
- // _descendantStates = new Object[rows + 1];
- // int rowIndex = getDescendantStatesRowIndex();
- // _descendantStates[rowIndex] = rowState;
- // }
- // }
-
- // private static void saveDescendantComponentStates(UIComponent component, List list, int level)
- // {
- // for (Iterator it = getChildrenAndOptionalFacetsIterator(level,component); it.hasNext();)
- // {
- // UIComponent child = (UIComponent)it.next();
- // if (child instanceof EditableValueHolder)
- // {
- // list.add(new EditableValueHolderState((EditableValueHolder)child));
- // }
- // saveDescendantComponentStates(child, list, level+1);
- // }
- // }
-
- // private static Iterator getChildrenAndOptionalFacetsIterator(int level, UIComponent component)
- // {
- // Iterator it = null;
- //
- // if(level>1)
- // {
- // it = component.getFacetsAndChildren();
- // }
- // else
- // {
- // it = component.getChildren().iterator();
- // }
- // return it;
- // }
-
- // private static int saveDescendantComponentStates(UIComponent component,
- // EditableValueHolderState[] states,
- // int counter, int level)
- // {
- //
- // for (Iterator it = getChildrenAndOptionalFacetsIterator(level, component); it.hasNext();)
- // {
- // UIComponent child = (UIComponent)it.next();
- // if (child instanceof EditableValueHolder)
- // {
- // states[counter++] = new EditableValueHolderState((EditableValueHolder)child);
- // }
- // counter = saveDescendantComponentStates(child, states, counter,level+1);
- // }
- // return counter;
- // }
-
- private static String getInitialClientId(FacesContext context, UIComponent component)
- {
- /*
- * The initialized value of oldRowIndex doesn't matter. If we dont' find a
- * parentUIData, we'll throw an exception, and the value won't be used.
- * If we do find it, the value will be set to the parentUIData's rowIndex.
- * This is just to satisfy the compiler.
- */
- int oldRowIndex = 0;
- UIData parentUIData = null;
-
- for (UIComponent parent = component.getParent(); parent != null; parent = parent.getParent())
- {
- if (parent instanceof UIData)
- {
- parentUIData = (UIData) parent;
- oldRowIndex = parentUIData._rowIndex;
- parentUIData._rowIndex = -1;
- break;
+ _rowState.put(child.getClientId(context), new ChildStateHolder(context, child));
+ saveDescendantComponentStates(context, child);
}
}
-
- if (parentUIData == null)
- {
- throw new IllegalStateException(
- "Couldn't find a parent UIData for " + component.getClientId(context));
- }
-
- //TODO: Hack? This assumes that the component's internal clientId cache will be flushed.
- component.setId(component.getId());
- String clientId = component.getClientId(context);
-
- parentUIData._rowIndex = oldRowIndex;
-
- component.setId(component.getId());
-
- return clientId;
}
- private void restoreDescendantComponentStates(
- FacesContext context,
- UIComponent component,
- boolean saveState)
+ private void restoreDescendantComponentStates(FacesContext context, UIComponent component)
{
for (Iterator i = component.getFacetsAndChildren(); i.hasNext();)
{
UIComponent child = (UIComponent) i.next();
- //clear this descendant's clientId:
+ //reset clientId to null
child.setId(child.getId());
- //HACK: This assumes that setId always clears the cached clientId. Can we be sure?
-
- if (saveState)
+ if (child.isRendered())
{
- //see saveDescendantComponentStates(UIComponent)
- if (child instanceof UIData)
+ String clientId = child.getClientId(context);
+ ChildStateHolder childStateHolder = (ChildStateHolder) _rowState.get(clientId);
+ if (childStateHolder != null)
{
- UIData childUIData = (UIData) child;
- Object state =
- _rowState._clientIdsToChildUIDataStates.get(
- childUIData.getClientId(context));
- if (state == null)
- {
- UIDataRowState initialState =
- (UIDataRowState) _rowState._clientIdsToChildUIDataStates.get(getInitialClientId(context, child));
-
- if (initialState == null)
- {
- throw new IllegalStateException(
- "No initial state defined for clientId: " + child.getClientId(context));
- }
-
- state = new UIDataRowState(initialState);
- }
-
-
-
- childUIData._rowState = (UIDataRowState) state;
-
- restoreDescendantComponentStates(context, component, false);
- continue;
- }
-
- if (!_firstTimeRendered && child instanceof EditableValueHolder)
- {
- EditableValueHolder childEVH = (EditableValueHolder) child;
- Object state =
- _rowState._clientIdsToChildEVHStates.get(child.getClientId(context));
- if (state == null)
- {
- state =
- _rowState._clientIdsToChildEVHStates.get(
- getInitialClientId(context, child));
- }
- ((EditableValueHolderState) state).restore(childEVH);
+ childStateHolder.restoreState(context, child);
}
+ restoreDescendantComponentStates(context, child);
}
-
- restoreDescendantComponentStates(context, child, saveState);
}
}
- // private void restoreDescendantComponentStates()
- // {
- // if (_descendantEditableValueHolderCount == -1)
- // {
- // throw new IllegalStateException("saveDescendantComponentStates not called yet?");
- // }
- // else if (_descendantEditableValueHolderCount > 0)
- // {
- // // There is at least one descendant component to be restored
- //
- // // Get zero-based index (instead of -1 based UIData zeroBasedRowIdx):
- // int zeroBasedRowIdx = getDescendantStatesRowIndex();
- //
- // // Is there a reason to restore the state of a new descendant?
- // // BUG: 925693
- // // manolito: Yes, descendants for a row not yet saved, must be
- // // reset to initial row state!
- // int stateRowsCount = _descendantStates.length;
- //
- // EditableValueHolderState[] initialStates = null;
- // if (stateRowsCount > 0)
- // {
- // // No state saved yet for this row, let's restore initial values:
- // initialStates = (EditableValueHolderState[]) _descendantStates[0];
- // }
- //
- // if (zeroBasedRowIdx < stateRowsCount)
- // {
- // // There is a saved state for this row, so restore these values:
- // EditableValueHolderState[] rowState =
- // (EditableValueHolderState[]) _descendantStates[zeroBasedRowIdx];
- // restoreDescendantComponentStates(this, rowState, initialStates, 0, 0);
- // }
- // else
- // {
- // // No state saved yet for this row, let's restore initial values:
- // restoreDescendantComponentStates(this, initialStates, initialStates, 0, 0);
- // }
- // }
- // else
- // {
- // // There are no states to restore, so only recurse to set the
- // // right clientIds for all descendants
- // restoreDescendantComponentStates(this, null, null, 0, 0);
- // }
- // }
-
- // private static int restoreDescendantComponentStates(UIComponent component,
- // EditableValueHolderState[] states,
- // EditableValueHolderState[] initialStates,
- // int counter, int level)
- // {
- //
- // for (Iterator it = getChildrenAndOptionalFacetsIterator(level, component); it.hasNext();)
- // {
- // UIComponent child = (UIComponent)it.next();
- // //clear this descendant's clientId:
- // child.setId(child.getId()); //HACK: This assumes that setId always clears the cached clientId. Can we be sure?
- // if (child instanceof EditableValueHolder)
- // {
- // if (states != null)
- // {
- // states[counter].restore((EditableValueHolder)child);
- // }
- // else if (initialStates != null)
- // {
- // initialStates[counter].restore((EditableValueHolder)child);
- // }
- // else
- // {
- // // No state saved yet and no initial state !?
- // // Should never be possible, but let's reset the component
- // // state to null values
- // ((EditableValueHolder)child).setValue(null);
- // ((EditableValueHolder)child).setLocalValueSet(false);
- // ((EditableValueHolder)child).setValid(true);
- // ((EditableValueHolder)child).setSubmittedValue(null);
- // }
- // counter++;
- // }
- // counter = restoreDescendantComponentStates(child, states, initialStates, counter, level+1);
- // }
- // return counter;
- // }
-
public void setRows(int rows)
{
_rows = new Integer(rows);
@@ -559,19 +264,13 @@
public void encodeBegin(FacesContext context) throws IOException
{
- if (_firstTimeRendered || isAllChildrenAndFacetsValid())
+ if (_isValidChilds)
{
- _saveDescendantStates = false; // no need to save children states
//Refresh DataModel for rendering:
_dataModel = null;
if (_dataModelMap != null)
_dataModelMap.clear();
}
- else
- {
- _saveDescendantStates = true;
- // save children states (valid flag, submittedValues, etc.)
- }
super.encodeBegin(context);
}
@@ -582,58 +281,6 @@
super.encodeEnd(context);
}
- private boolean isAllChildrenAndFacetsValid()
- {
- int first = getFirst();
- int rows = getRows();
- int last;
- if (rows == 0)
- {
- last = getRowCount();
- }
- else
- {
- last = first + rows;
- }
- int setRowIndex = getRowIndex();
- try
- {
- for (int rowIndex = first; rowIndex < last; rowIndex++)
- {
- setRowIndex(rowIndex);
- if (isRowAvailable())
- {
- if (!isAllEditableValueHoldersValidRecursive(getFacetsAndChildren()))
- {
- return false;
- }
- }
- }
- }
- finally
- {
- setRowIndex(setRowIndex);
- }
- return true;
- }
-
- 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 processDecodes(FacesContext context)
{
if (context == null)
@@ -667,6 +314,12 @@
processColumnFacets(context, PROCESS_VALIDATORS);
processColumnChildren(context, PROCESS_VALIDATORS);
setRowIndex(-1);
+
+ // check if an validation error forces the render response for our data
+ if (context.getRenderResponse())
+ {
+ _isValidChilds = false;
+ }
}
public void processUpdates(FacesContext context)
@@ -680,6 +333,11 @@
processColumnFacets(context, PROCESS_UPDATES);
processColumnChildren(context, PROCESS_UPDATES);
setRowIndex(-1);
+
+ if (context.getRenderResponse())
+ {
+ _isValidChilds = false;
+ }
}
private void processFacets(FacesContext context, int processAction)
@@ -703,9 +361,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);
@@ -742,9 +398,8 @@
//Column is not visible
continue;
}
- for (Iterator columnChildIter = child.getChildren().iterator();
- columnChildIter.hasNext();
- )
+ for (Iterator columnChildIter = child.getChildren().iterator(); columnChildIter
+ .hasNext();)
{
UIComponent columnChild = (UIComponent) columnChildIter.next();
process(context, columnChild, processAction);
@@ -759,13 +414,13 @@
{
switch (processAction)
{
- case PROCESS_DECODES :
+ case PROCESS_DECODES:
component.processDecodes(context);
break;
- case PROCESS_VALIDATORS :
+ case PROCESS_VALIDATORS:
component.processValidators(context);
break;
- case PROCESS_UPDATES :
+ case PROCESS_UPDATES:
component.processUpdates(context);
break;
}
@@ -785,8 +440,7 @@
{
_dataModelMap = new HashMap();
}
- String embeddingClientId =
- embeddingUIData.getClientId(FacesContext.getCurrentInstance());
+ String embeddingClientId = embeddingUIData.getClientId(FacesContext.getCurrentInstance());
DataModel dataModel = (DataModel) _dataModelMap.get(embeddingClientId);
if (dataModel == null)
{
@@ -988,69 +642,24 @@
{
if (obj == null)
return; //Clearing is allowed
- throw new UnsupportedOperationException(
- this.getClass().getName() + " UnsupportedOperationException");
+ throw new UnsupportedOperationException(this.getClass().getName()
+ + " UnsupportedOperationException");
}
};
- private static class UIDataRowState implements Cloneable, Serializable
- {
- private HashMap _clientIdsToChildUIDataStates = new HashMap();
- private HashMap _clientIdsToChildEVHStates = new HashMap();
-
- public UIDataRowState()
- {
- }
-
- public UIDataRowState(UIDataRowState initial)
- {
- for (Iterator i = initial._clientIdsToChildEVHStates.entrySet().iterator(); i.hasNext();)
- {
- Map.Entry entry = (Map.Entry) i.next();
- EditableValueHolderState initialState = (EditableValueHolderState) entry.getValue();
- _clientIdsToChildEVHStates.put(entry.getKey(), new EditableValueHolderState(initialState));
- }
-
- for (Iterator i = initial._clientIdsToChildUIDataStates.entrySet().iterator(); i.hasNext();)
- {
- Map.Entry entry = (Map.Entry) i.next();
- UIDataRowState initialState = (UIDataRowState) entry.getValue();
- _clientIdsToChildEVHStates.put(entry.getKey(), new UIDataRowState(initialState));
- }
- }
- }
-
- private static class EditableValueHolderState implements Serializable
+ private static class ChildStateHolder implements Serializable
{
- private Object _localValue;
- private boolean _localValueSet;
- private boolean _valid;
- private Object _submittedValue;
+ private final Object _state;
- public EditableValueHolderState(EditableValueHolder vh)
+ public ChildStateHolder(FacesContext context, StateHolder stateHolder)
{
- _localValue = vh.getLocalValue();
- _localValueSet = vh.isLocalValueSet();
- _valid = vh.isValid();
- _submittedValue = vh.getSubmittedValue();
+ _state = stateHolder.saveState(context);
}
- public EditableValueHolderState(EditableValueHolderState state)
+ public void restoreState(FacesContext context, StateHolder stateHolder)
{
- _localValue = state._localValue;
- _localValueSet = state._localValueSet;
- _valid = state._valid;
- _submittedValue = state._submittedValue;
+ stateHolder.restoreState(context, _state);
}
-
- public void restore(EditableValueHolder vh)
- {
- vh.setValue(_localValue);
- vh.setLocalValueSet(_localValueSet);
- vh.setValid(_valid);
- vh.setSubmittedValue(_submittedValue);
- }
-
}
public void setValue(Object value)
@@ -1067,7 +676,10 @@
values[ROWS_INDEX] = _rows;
values[VALUE_INDEX] = _value;
values[VAR_INDEX] = _var;
- values[ROW_STATE_INDEX] = _rowState;
+ if (!_isValidChilds)
+ {
+ values[ROW_STATE_INDEX] = _rowState;
+ }
return ((Object) (values));
}
@@ -1079,10 +691,11 @@
_rows = (Integer) values[ROWS_INDEX];
_value = (Object) values[VALUE_INDEX];
_var = (String) values[VAR_INDEX];
- _rowState = (UIDataRowState) values[ROW_STATE_INDEX];
-
- // restore state means component was already rendered at least once:
- _firstTimeRendered = false;
+ Map rowState = (Map) values[ROW_STATE_INDEX];
+ if (rowState != null)
+ {
+ _rowState = rowState;
+ }
}
//------------------ GENERATED CODE BEGIN (do not modify!) --------------------