📄 htmldatatablehack.java
字号:
package org.apache.myfaces.component.html.ext;import javax.faces.component.EditableValueHolder;import javax.faces.component.UIComponent;import javax.faces.component.UIData;import javax.faces.context.FacesContext;import javax.faces.el.ValueBinding;import javax.faces.model.*;import javax.servlet.jsp.jstl.sql.Result;import java.io.Serializable;import java.sql.ResultSet;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;/** * Reimplement all UIData functionality to be able to have (protected) access * the internal DataModel. * * @author Manfred Geiler (latest modification by $Author: mmarinschek $) * @version $Revision: 1.5 $ $Date: 2005/01/26 17:48:19 $ */abstract class HtmlDataTableHack extends javax.faces.component.html.HtmlDataTable{ protected DataModel _dataModel = null; protected HashMap _dataModelMap = null; //init to false, so that no descendant states are saved for a newly created UIData transient protected boolean _saveDescendantStates = false; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Every field and method from here is identical to UIData !!!!!!!!! private static final Class OBJECT_ARRAY_CLASS = (new Object[0]).getClass(); private static final Integer INTEGER_MINUS1 = new Integer(-1); private int _rowIndex = -1; private Object[] _descendantStates; private int _descendantEditableValueHolderCount = -1; private Boolean _isEmbeddedUIData = null; private UIData _embeddingUIData = null; 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; // 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 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();)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -