You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by mm...@apache.org on 2005/03/16 21:10:59 UTC
cvs commit: incubator-myfaces/src/jsfapi/javax/faces/component UIData.java
mmarinschek 2005/03/16 12:10:59
Modified: src/jsfapi/javax/faces/component UIData.java
Log:
fix for MYFACES-38, alien commit for Heath Borders
Revision Changes Path
1.29 +1116 -916 incubator-myfaces/src/jsfapi/javax/faces/component/UIData.java
Index: UIData.java
===================================================================
RCS file: /home/cvs/incubator-myfaces/src/jsfapi/javax/faces/component/UIData.java,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- UIData.java 27 Dec 2004 04:11:11 -0000 1.28
+++ UIData.java 16 Mar 2005 20:10:59 -0000 1.29
@@ -1,12 +1,12 @@
/*
* 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.
@@ -15,14 +15,6 @@
*/
package javax.faces.component;
-import javax.faces.context.FacesContext;
-import javax.faces.el.ValueBinding;
-import javax.faces.event.AbortProcessingException;
-import javax.faces.event.FacesEvent;
-import javax.faces.event.FacesListener;
-import javax.faces.event.PhaseId;
-import javax.faces.model.*;
-import javax.servlet.jsp.jstl.sql.Result;
import java.io.IOException;
import java.io.Serializable;
import java.sql.ResultSet;
@@ -31,11 +23,29 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+
+import javax.faces.context.FacesContext;
+import javax.faces.el.ValueBinding;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.FacesEvent;
+import javax.faces.event.FacesListener;
+import javax.faces.event.PhaseId;
+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 Manfred Geiler (latest modification by $Author$)
* @version $Revision$ $Date$
* $Log$
+ * Revision 1.29 2005/03/16 20:10:59 mmarinschek
+ * fix for MYFACES-38, alien commit for Heath Borders
+ *
* Revision 1.28 2004/12/27 04:11:11 mmarinschek
* Data Table stores the state of facets of children; script tag is rendered with type attribute instead of language attribute, popup works better as a column in a data table
*
@@ -62,910 +72,1100 @@
* optimized saving of descendant states: isAllChildrenAndFacetsValid loop no longer needed
*
*/
-public class UIData
- extends UIComponentBase
- implements NamingContainer
+public class UIData extends UIComponentBase implements NamingContainer
{
- private static final String FOOTER_FACET_NAME = "footer";
- private static final String HEADER_FACET_NAME = "header";
- 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 static final Integer INTEGER_MINUS1 = new Integer(-1);
-
- private int _rowIndex = -1;
- private String _var = null;
- private Object[] _descendantStates;
- private int _descendantEditableValueHolderCount = -1;
-
- //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;
-
- private Boolean _isEmbeddedUIData = null;
- private UIData _embeddingUIData = null;
- private DataModel _dataModel = null;
- private HashMap _dataModelMap = null;
-
-
- public void setFooter(UIComponent footer)
- {
- getFacets().put(FOOTER_FACET_NAME, footer);
- }
-
- public UIComponent getFooter()
- {
- return (UIComponent)getFacets().get(FOOTER_FACET_NAME);
- }
-
- public void setHeader(UIComponent header)
- {
- getFacets().put(HEADER_FACET_NAME, header);
- }
-
- public UIComponent getHeader()
- {
- return (UIComponent)getFacets().get(HEADER_FACET_NAME);
- }
-
- public boolean isRowAvailable()
- {
- return getDataModel().isRowAvailable();
- }
-
- public int getRowCount()
- {
- return getDataModel().getRowCount();
- }
-
- public Object getRowData()
- {
- return getDataModel().getRowData();
- }
-
- public int getRowIndex()
- {
- return _rowIndex;
- }
-
- public void setRowIndex(int rowIndex)
- {
- saveDescendantComponentStates();
-
- _rowIndex = rowIndex;
-
- DataModel dataModel = getDataModel();
- dataModel.setRowIndex(rowIndex);
-
- String var = getVar();
- if (rowIndex == -1)
- {
- if (var != null)
- {
- getFacesContext().getExternalContext().getRequestMap().remove(var);
- }
- }
- else
- {
- if (var != null)
- {
- if (isRowAvailable())
- {
- Object rowData = dataModel.getRowData();
- getFacesContext().getExternalContext().getRequestMap().put(var, rowData);
- }
- else
- {
- getFacesContext().getExternalContext().getRequestMap().remove(var);
- }
- }
- }
-
- restoreDescendantComponentStates();
- }
-
-
- private int getDescendantStatesRowIndex()
- {
- int rowIndex = getRowIndex();
- if (rowIndex == -1)
- {
- return 0;
- }
- else
- {
- return rowIndex - getFirst() + 1;
- }
- }
-
- /**
- * 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 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);
- if (rows < 0) throw new IllegalArgumentException("rows: " + rows);
- }
-
- public void setVar(String var)
- {
- _var = var;
- }
-
- public String getVar()
- {
- return _var;
- }
-
- 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);
- }
-
- public String getClientId(FacesContext context)
- {
- String clientId = super.getClientId(context);
- int rowIndex = getRowIndex();
- if (rowIndex == -1)
- {
- return clientId;
- }
- else
- {
- return clientId + "_" + rowIndex;
- }
- }
-
- public void queueEvent(FacesEvent event)
- {
- super.queueEvent(new FacesEventWrapper(event, getRowIndex(), this));
- }
-
- public void broadcast(FacesEvent event) throws AbortProcessingException
- {
- if (event instanceof FacesEventWrapper)
- {
- FacesEvent originalEvent = ((FacesEventWrapper)event).getWrappedFacesEvent();
- int eventRowIndex = ((FacesEventWrapper)event).getRowIndex();
- int currentRowIndex = getRowIndex();
- setRowIndex(eventRowIndex);
- originalEvent.getComponent().broadcast(originalEvent);
- setRowIndex(currentRowIndex);
- }
- else
- {
- super.broadcast(event);
- }
- }
-
- public void encodeBegin(FacesContext context)
- throws IOException
- {
- if (_firstTimeRendered || isAllChildrenAndFacetsValid())
- {
- _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);
- }
-
-
- 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;
- }
-
-
- 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) throw new NullPointerException("context");
- if (!isRendered()) return;
- setRowIndex(-1);
- processFacets(context, PROCESS_DECODES);
- processColumnFacets(context, PROCESS_DECODES);
- processColumnChildren(context, PROCESS_DECODES);
- setRowIndex(-1);
- try
- {
- decode(context);
- }
- catch (RuntimeException e)
- {
- context.renderResponse();
- throw e;
- }
- }
-
- public void processValidators(FacesContext context)
- {
- if (context == null) throw new NullPointerException("context");
- if (!isRendered()) return;
- setRowIndex(-1);
- processFacets(context, PROCESS_VALIDATORS);
- processColumnFacets(context, PROCESS_VALIDATORS);
- processColumnChildren(context, PROCESS_VALIDATORS);
- setRowIndex(-1);
- }
-
- public void processUpdates(FacesContext context)
- {
- if (context == null) throw new NullPointerException("context");
- if (!isRendered()) return;
- setRowIndex(-1);
- processFacets(context, PROCESS_UPDATES);
- processColumnFacets(context, PROCESS_UPDATES);
- processColumnChildren(context, PROCESS_UPDATES);
- setRowIndex(-1);
- }
-
-
- private void processFacets(FacesContext context, int processAction)
- {
- for (Iterator it = getFacets().values().iterator(); it.hasNext();)
- {
- UIComponent facet = (UIComponent)it.next();
- process(context, facet, processAction);
- }
- }
-
- private void processColumnFacets(FacesContext context, int processAction)
- {
- for (Iterator childIter = getChildren().iterator(); childIter.hasNext();)
- {
- UIComponent child = (UIComponent)childIter.next();
- if (child instanceof UIColumn)
- {
- if (!child.isRendered())
- {
- //Column is not visible
- continue;
- }
- for (Iterator facetsIter = child.getFacets().values().iterator(); facetsIter.hasNext();)
- {
- UIComponent facet = (UIComponent)facetsIter.next();
- process(context, facet, processAction);
- }
- }
- }
- }
-
- private void processColumnChildren(FacesContext context, int processAction)
- {
- int first = getFirst();
- int rows = getRows();
- int last;
- if (rows == 0)
- {
- 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 UIColumn)
- {
- if (!child.isRendered())
- {
- //Column is not visible
- continue;
- }
- for (Iterator columnChildIter = child.getChildren().iterator(); columnChildIter.hasNext();)
- {
- UIComponent columnChild = (UIComponent)columnChildIter.next();
- process(context, columnChild, processAction);
- }
- }
- }
- }
- }
- }
-
- 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;
- }
- }
-
-
- private DataModel getDataModel()
- {
- UIData embeddingUIData = getEmbeddingUIData();
- if (embeddingUIData != null)
- {
- //This UIData is nested in another UIData, so we must not
- //do simple caching of the current DataModel. We must associate
- //the DataModel that we want to cache with the clientId of the
- //embedding UIData. This clientId will be different for every
- //row of the embedding UIData.
- if (_dataModelMap == null)
- {
- _dataModelMap = new HashMap();
- }
- String embeddingClientId = embeddingUIData.getClientId(FacesContext.getCurrentInstance());
- DataModel dataModel = (DataModel) _dataModelMap.get(embeddingClientId);
- if (dataModel == null)
- {
- dataModel = createDataModel();
- _dataModelMap.put(embeddingClientId, dataModel);
- }
- return dataModel;
- }
- else
- {
- //This UIData is not nested within another UIData. So there
- //is no need for the DataModel Map.
- 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 (value instanceof Collection)
- {
- return new ListDataModel( new ArrayList((Collection)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);
- }
- }
-
- /**
- * Looks for an embedding UIData component
- * @return the embedding UIData or null
- */
- private UIData getEmbeddingUIData()
- {
- if (_isEmbeddedUIData == null)
- {
- UIComponent findParentUIData = getParent();
- while (findParentUIData != null &&
- !(findParentUIData instanceof UIData))
- {
- findParentUIData = findParentUIData.getParent();
- }
- if (findParentUIData != null)
- {
- _embeddingUIData = (UIData)findParentUIData;
- _isEmbeddedUIData = Boolean.TRUE;
- }
- else
- {
- _isEmbeddedUIData = Boolean.FALSE;
- }
- }
-
- if (_isEmbeddedUIData.booleanValue())
- {
- return _embeddingUIData;
- }
- else
- {
- return null;
- }
- }
-
-
- private static class FacesEventWrapper
- extends FacesEvent
- {
- private FacesEvent _wrappedFacesEvent;
- private int _rowIndex;
-
- public FacesEventWrapper(FacesEvent facesEvent, int rowIndex,
- UIData redirectComponent)
- {
- super(redirectComponent);
- _wrappedFacesEvent = facesEvent;
- _rowIndex = rowIndex;
- }
-
- public PhaseId getPhaseId()
- {
- return _wrappedFacesEvent.getPhaseId();
- }
-
- public void setPhaseId(PhaseId phaseId)
- {
- _wrappedFacesEvent.setPhaseId(phaseId);
- }
-
- public void queue()
- {
- _wrappedFacesEvent.queue();
- }
-
- public String toString()
- {
- return _wrappedFacesEvent.toString();
- }
-
- public boolean isAppropriateListener(FacesListener faceslistener)
- {
- return _wrappedFacesEvent.isAppropriateListener(faceslistener);
- }
-
- public void processListener(FacesListener faceslistener)
- {
- _wrappedFacesEvent.processListener(faceslistener);
- }
-
- public FacesEvent getWrappedFacesEvent()
- {
- return _wrappedFacesEvent;
- }
-
- public int getRowIndex()
- {
- return _rowIndex;
- }
- }
-
-
- 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 IllegalArgumentException();
- }
-
- 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 EditableValueHolderState
- implements Serializable
- {
- private Object _localValue;
- private boolean _localValueSet;
- private boolean _valid;
- private Object _submittedValue;
-
- public EditableValueHolderState(EditableValueHolder vh)
- {
- _localValue = vh.getLocalValue();
- _localValueSet = vh.isLocalValueSet();
- _valid = vh.isValid();
- _submittedValue = vh.getSubmittedValue();
- }
-
- public void restore(EditableValueHolder vh)
- {
- vh.setValue(_localValue);
- vh.setLocalValueSet(_localValueSet);
- vh.setValid(_valid);
- vh.setSubmittedValue(_submittedValue);
- }
- }
-
-
- public void setValue(Object value)
- {
- _value = value;
- _dataModel = null;
- }
-
-
- public Object saveState(FacesContext context)
- {
- Object values[] = new Object[7];
- values[0] = super.saveState(context);
- values[1] = _first;
- values[2] = _rows;
- values[3] = _value;
- values[4] = _var;
- values[5] = _saveDescendantStates ? _descendantStates : null;
- values[6] = _saveDescendantStates ? new Integer(_descendantEditableValueHolderCount) : INTEGER_MINUS1;
- return ((Object) (values));
- }
-
- public void restoreState(FacesContext context, Object state)
- {
- Object values[] = (Object[])state;
- super.restoreState(context, values[0]);
- _first = (Integer)values[1];
- _rows = (Integer)values[2];
- _value = (Object)values[3];
- _var = (String)values[4];
- _descendantStates = (Object[])values[5];
- _descendantEditableValueHolderCount = ((Integer)values[6]).intValue();
-
- // restore state means component was already rendered at least once:
- _firstTimeRendered = false;
- }
-
-
- //------------------ GENERATED CODE BEGIN (do not modify!) --------------------
-
- public static final String COMPONENT_TYPE = "javax.faces.Data";
- public static final String COMPONENT_FAMILY = "javax.faces.Data";
- private static final String DEFAULT_RENDERER_TYPE = "javax.faces.Table";
- private static final int DEFAULT_FIRST = 0;
- private static final int DEFAULT_ROWS = 0;
-
- private Integer _first = null;
- private Integer _rows = null;
- private Object _value = null;
-
- public UIData()
- {
- setRendererType(DEFAULT_RENDERER_TYPE);
- }
-
- public String getFamily()
- {
- return COMPONENT_FAMILY;
- }
-
- public void setFirst(int first)
- {
- _first = new Integer(first);
- }
-
- public int getFirst()
- {
- if (_first != null) return _first.intValue();
- ValueBinding vb = getValueBinding("first");
- Integer v = vb != null ? (Integer)vb.getValue(getFacesContext()) : null;
- return v != null ? v.intValue() : DEFAULT_FIRST;
- }
-
-
- public int getRows()
- {
- if (_rows != null) return _rows.intValue();
- ValueBinding vb = getValueBinding("rows");
- Integer v = vb != null ? (Integer)vb.getValue(getFacesContext()) : null;
- return v != null ? v.intValue() : DEFAULT_ROWS;
- }
-
- public Object getValue()
- {
- if (_value != null) return _value;
- ValueBinding vb = getValueBinding("value");
- return vb != null ? (Object)vb.getValue(getFacesContext()) : null;
- }
-
-
- //------------------ GENERATED CODE END ---------------------------------------
-
+ private static final int STATE_SIZE = 6;
+ private static final int SUPER_STATE_INDEX = 0;
+ private static final int FIRST_INDEX = 1;
+ private static final int ROWS_INDEX = 2;
+ private static final int VALUE_INDEX = 3;
+ private static final int VAR_INDEX = 4;
+ private static final int ROW_STATE_INDEX = 5;
+
+ private static final String FOOTER_FACET_NAME = "footer";
+ private static final String HEADER_FACET_NAME = "header";
+ 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 static final Integer INTEGER_MINUS1 = new Integer(-1);
+
+ 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;
+
+ private Boolean _isEmbeddedUIData = null;
+ private UIData _embeddingUIData = null;
+ private DataModel _dataModel = null;
+ private HashMap _dataModelMap = null;
+
+ public void setFooter(UIComponent footer)
+ {
+ getFacets().put(FOOTER_FACET_NAME, footer);
+ }
+
+ public UIComponent getFooter()
+ {
+ return (UIComponent) getFacets().get(FOOTER_FACET_NAME);
+ }
+
+ public void setHeader(UIComponent header)
+ {
+ getFacets().put(HEADER_FACET_NAME, header);
+ }
+
+ public UIComponent getHeader()
+ {
+ return (UIComponent) getFacets().get(HEADER_FACET_NAME);
+ }
+
+ public boolean isRowAvailable()
+ {
+ return getDataModel().isRowAvailable();
+ }
+
+ public int getRowCount()
+ {
+ return getDataModel().getRowCount();
+ }
+
+ public Object getRowData()
+ {
+ return getDataModel().getRowData();
+ }
+
+ public int getRowIndex()
+ {
+ return _rowIndex;
+ }
+
+ public void setRowIndex(int rowIndex)
+ {
+ saveDescendantComponentStates(getFacesContext(), this);
+
+ _rowIndex = rowIndex;
+
+ DataModel dataModel = getDataModel();
+ dataModel.setRowIndex(rowIndex);
+
+ String var = getVar();
+ if (rowIndex == -1)
+ {
+ if (var != null)
+ {
+ getFacesContext().getExternalContext().getRequestMap().remove(var);
+ }
+ }
+ else
+ {
+ if (var != null)
+ {
+ if (isRowAvailable())
+ {
+ Object rowData = dataModel.getRowData();
+ getFacesContext().getExternalContext().getRequestMap().put(var, rowData);
+ }
+ else
+ {
+ getFacesContext().getExternalContext().getRequestMap().remove(var);
+ }
+ }
+ }
+
+ restoreDescendantComponentStates(getFacesContext(), this, true);
+ }
+
+ // 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)
+ {
+ 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;
+ }
+ }
+
+ 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)
+ {
+ for (Iterator i = component.getFacetsAndChildren(); i.hasNext();)
+ {
+ UIComponent child = (UIComponent) i.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 (saveState)
+ {
+ //see saveDescendantComponentStates(UIComponent)
+ if (child instanceof UIData)
+ {
+ 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 (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);
+ }
+ }
+
+ 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);
+ if (rows < 0)
+ throw new IllegalArgumentException("rows: " + rows);
+ }
+
+ public void setVar(String var)
+ {
+ _var = var;
+ }
+
+ public String getVar()
+ {
+ return _var;
+ }
+
+ 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);
+ }
+
+ public String getClientId(FacesContext context)
+ {
+ String clientId = super.getClientId(context);
+ int rowIndex = getRowIndex();
+ if (rowIndex == -1)
+ {
+ return clientId;
+ }
+ else
+ {
+ return clientId + "_" + rowIndex;
+ }
+ }
+
+ public void queueEvent(FacesEvent event)
+ {
+ super.queueEvent(new FacesEventWrapper(event, getRowIndex(), this));
+ }
+
+ public void broadcast(FacesEvent event) throws AbortProcessingException
+ {
+ if (event instanceof FacesEventWrapper)
+ {
+ FacesEvent originalEvent = ((FacesEventWrapper) event).getWrappedFacesEvent();
+ int eventRowIndex = ((FacesEventWrapper) event).getRowIndex();
+ int currentRowIndex = getRowIndex();
+ setRowIndex(eventRowIndex);
+ originalEvent.getComponent().broadcast(originalEvent);
+ setRowIndex(currentRowIndex);
+ }
+ else
+ {
+ super.broadcast(event);
+ }
+ }
+
+ public void encodeBegin(FacesContext context) throws IOException
+ {
+ if (_firstTimeRendered || isAllChildrenAndFacetsValid())
+ {
+ _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);
+ }
+
+ public void encodeEnd(FacesContext context) throws IOException
+ {
+ setRowIndex(-1);
+
+ super.encodeEnd(context);
+ }
+
+ 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;
+ }
+
+ 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)
+ throw new NullPointerException("context");
+ if (!isRendered())
+ return;
+ setRowIndex(-1);
+ processFacets(context, PROCESS_DECODES);
+ processColumnFacets(context, PROCESS_DECODES);
+ processColumnChildren(context, PROCESS_DECODES);
+ setRowIndex(-1);
+ try
+ {
+ decode(context);
+ }
+ catch (RuntimeException e)
+ {
+ context.renderResponse();
+ throw e;
+ }
+ }
+
+ public void processValidators(FacesContext context)
+ {
+ if (context == null)
+ throw new NullPointerException("context");
+ if (!isRendered())
+ return;
+ setRowIndex(-1);
+ processFacets(context, PROCESS_VALIDATORS);
+ processColumnFacets(context, PROCESS_VALIDATORS);
+ processColumnChildren(context, PROCESS_VALIDATORS);
+ setRowIndex(-1);
+ }
+
+ public void processUpdates(FacesContext context)
+ {
+ if (context == null)
+ throw new NullPointerException("context");
+ if (!isRendered())
+ return;
+ setRowIndex(-1);
+ processFacets(context, PROCESS_UPDATES);
+ processColumnFacets(context, PROCESS_UPDATES);
+ processColumnChildren(context, PROCESS_UPDATES);
+ setRowIndex(-1);
+ }
+
+ private void processFacets(FacesContext context, int processAction)
+ {
+ for (Iterator it = getFacets().values().iterator(); it.hasNext();)
+ {
+ UIComponent facet = (UIComponent) it.next();
+ process(context, facet, processAction);
+ }
+ }
+
+ private void processColumnFacets(FacesContext context, int processAction)
+ {
+ for (Iterator childIter = getChildren().iterator(); childIter.hasNext();)
+ {
+ UIComponent child = (UIComponent) childIter.next();
+ if (child instanceof UIColumn)
+ {
+ if (!child.isRendered())
+ {
+ //Column is not visible
+ continue;
+ }
+ for (Iterator facetsIter = child.getFacets().values().iterator();
+ facetsIter.hasNext();
+ )
+ {
+ UIComponent facet = (UIComponent) facetsIter.next();
+ process(context, facet, processAction);
+ }
+ }
+ }
+ }
+
+ private void processColumnChildren(FacesContext context, int processAction)
+ {
+ int first = getFirst();
+ int rows = getRows();
+ int last;
+ if (rows == 0)
+ {
+ 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 UIColumn)
+ {
+ if (!child.isRendered())
+ {
+ //Column is not visible
+ continue;
+ }
+ for (Iterator columnChildIter = child.getChildren().iterator();
+ columnChildIter.hasNext();
+ )
+ {
+ UIComponent columnChild = (UIComponent) columnChildIter.next();
+ process(context, columnChild, processAction);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ 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;
+ }
+ }
+
+ private DataModel getDataModel()
+ {
+ UIData embeddingUIData = getEmbeddingUIData();
+ if (embeddingUIData != null)
+ {
+ //This UIData is nested in another UIData, so we must not
+ //do simple caching of the current DataModel. We must associate
+ //the DataModel that we want to cache with the clientId of the
+ //embedding UIData. This clientId will be different for every
+ //row of the embedding UIData.
+ if (_dataModelMap == null)
+ {
+ _dataModelMap = new HashMap();
+ }
+ String embeddingClientId =
+ embeddingUIData.getClientId(FacesContext.getCurrentInstance());
+ DataModel dataModel = (DataModel) _dataModelMap.get(embeddingClientId);
+ if (dataModel == null)
+ {
+ dataModel = createDataModel();
+ _dataModelMap.put(embeddingClientId, dataModel);
+ }
+ return dataModel;
+ }
+ else
+ {
+ //This UIData is not nested within another UIData. So there
+ //is no need for the DataModel Map.
+ 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 (value instanceof Collection)
+ {
+ return new ListDataModel(new ArrayList((Collection) 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);
+ }
+ }
+
+ /**
+ * Looks for an embedding UIData component
+ * @return the embedding UIData or null
+ */
+ private UIData getEmbeddingUIData()
+ {
+ if (_isEmbeddedUIData == null)
+ {
+ UIComponent findParentUIData = getParent();
+ while (findParentUIData != null && !(findParentUIData instanceof UIData))
+ {
+ findParentUIData = findParentUIData.getParent();
+ }
+ if (findParentUIData != null)
+ {
+ _embeddingUIData = (UIData) findParentUIData;
+ _isEmbeddedUIData = Boolean.TRUE;
+ }
+ else
+ {
+ _isEmbeddedUIData = Boolean.FALSE;
+ }
+ }
+
+ if (_isEmbeddedUIData.booleanValue())
+ {
+ return _embeddingUIData;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ private static class UIDataRowIndexState
+ {
+ private UIData _uiData;
+ private int _rowIndex;
+
+ public UIDataRowIndexState(UIData uiData)
+ {
+ _uiData = uiData;
+ _rowIndex = _uiData._rowIndex;
+ }
+
+ public void restore()
+ {
+ _uiData._rowIndex = _rowIndex;
+ }
+ }
+
+ private static class FacesEventWrapper extends FacesEvent
+ {
+ private FacesEvent _wrappedFacesEvent;
+ private int _rowIndex;
+
+ public FacesEventWrapper(FacesEvent facesEvent, int rowIndex, UIData redirectComponent)
+ {
+ super(redirectComponent);
+ _wrappedFacesEvent = facesEvent;
+ _rowIndex = rowIndex;
+ }
+
+ public PhaseId getPhaseId()
+ {
+ return _wrappedFacesEvent.getPhaseId();
+ }
+
+ public void setPhaseId(PhaseId phaseId)
+ {
+ _wrappedFacesEvent.setPhaseId(phaseId);
+ }
+
+ public void queue()
+ {
+ _wrappedFacesEvent.queue();
+ }
+
+ public String toString()
+ {
+ return _wrappedFacesEvent.toString();
+ }
+
+ public boolean isAppropriateListener(FacesListener faceslistener)
+ {
+ return _wrappedFacesEvent.isAppropriateListener(faceslistener);
+ }
+
+ public void processListener(FacesListener faceslistener)
+ {
+ _wrappedFacesEvent.processListener(faceslistener);
+ }
+
+ public FacesEvent getWrappedFacesEvent()
+ {
+ return _wrappedFacesEvent;
+ }
+
+ public int getRowIndex()
+ {
+ return _rowIndex;
+ }
+ }
+
+ 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 IllegalArgumentException();
+ }
+
+ 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 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 Object _localValue;
+ private boolean _localValueSet;
+ private boolean _valid;
+ private Object _submittedValue;
+
+ public EditableValueHolderState(EditableValueHolder vh)
+ {
+ _localValue = vh.getLocalValue();
+ _localValueSet = vh.isLocalValueSet();
+ _valid = vh.isValid();
+ _submittedValue = vh.getSubmittedValue();
+ }
+
+ public EditableValueHolderState(EditableValueHolderState state)
+ {
+ _localValue = state._localValue;
+ _localValueSet = state._localValueSet;
+ _valid = state._valid;
+ _submittedValue = state._submittedValue;
+ }
+
+ public void restore(EditableValueHolder vh)
+ {
+ vh.setValue(_localValue);
+ vh.setLocalValueSet(_localValueSet);
+ vh.setValid(_valid);
+ vh.setSubmittedValue(_submittedValue);
+ }
+
+ }
+
+ public void setValue(Object value)
+ {
+ _value = value;
+ _dataModel = null;
+ }
+
+ public Object saveState(FacesContext context)
+ {
+ Object[] values = new Object[STATE_SIZE];
+ values[SUPER_STATE_INDEX] = super.saveState(context);
+ values[FIRST_INDEX] = _first;
+ values[ROWS_INDEX] = _rows;
+ values[VALUE_INDEX] = _value;
+ values[VAR_INDEX] = _var;
+ values[ROW_STATE_INDEX] = _rowState;
+ return ((Object) (values));
+ }
+
+ public void restoreState(FacesContext context, Object state)
+ {
+ Object[] values = (Object[]) state;
+ super.restoreState(context, values[0]);
+ _first = (Integer) values[FIRST_INDEX];
+ _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;
+ }
+
+ //------------------ GENERATED CODE BEGIN (do not modify!) --------------------
+
+ public static final String COMPONENT_TYPE = "javax.faces.Data";
+ public static final String COMPONENT_FAMILY = "javax.faces.Data";
+ private static final String DEFAULT_RENDERER_TYPE = "javax.faces.Table";
+ private static final int DEFAULT_FIRST = 0;
+ private static final int DEFAULT_ROWS = 0;
+
+ private Integer _first = null;
+ private Integer _rows = null;
+ private Object _value = null;
+
+ public UIData()
+ {
+ setRendererType(DEFAULT_RENDERER_TYPE);
+ }
+
+ public String getFamily()
+ {
+ return COMPONENT_FAMILY;
+ }
+
+ public void setFirst(int first)
+ {
+ _first = new Integer(first);
+ }
+
+ public int getFirst()
+ {
+ if (_first != null)
+ return _first.intValue();
+ ValueBinding vb = getValueBinding("first");
+ Integer v = vb != null ? (Integer) vb.getValue(getFacesContext()) : null;
+ return v != null ? v.intValue() : DEFAULT_FIRST;
+ }
+
+ public int getRows()
+ {
+ if (_rows != null)
+ return _rows.intValue();
+ ValueBinding vb = getValueBinding("rows");
+ Integer v = vb != null ? (Integer) vb.getValue(getFacesContext()) : null;
+ return v != null ? v.intValue() : DEFAULT_ROWS;
+ }
+
+ public Object getValue()
+ {
+ if (_value != null)
+ return _value;
+ ValueBinding vb = getValueBinding("value");
+ return vb != null ? (Object) vb.getValue(getFacesContext()) : null;
+ }
+ //------------------ GENERATED CODE END ---------------------------------------
}