📄 uidata.java
字号:
/* * 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 javax.faces.component;import java.io.IOException;import java.io.Serializable;import java.sql.ResultSet;import java.util.ArrayList;import java.util.Collection;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: schof $) * @version $Revision: 1.31 $ $Date: 2005/04/13 14:18:24 $ * $Log: UIData.java,v $ * Revision 1.31 2005/04/13 14:18:24 schof * Fixes MYFACES-174 (Thanks to Mathias Broeklemann for the patch) * * Revision 1.30 2005/03/24 16:46:02 matzew * MYFACES-142 * * 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 * * Revision 1.27 2004/11/26 22:04:57 svieujot * Make UIData work with Collection and not only List. * This allows component like x:dataList to work with Sets, or any type of collection data model. * * Revision 1.26 2004/09/13 15:59:44 manolito * fixed problems with nested UIData and HtmlDataTable components * * Revision 1.25 2004/07/01 22:00:50 mwessendorf * ASF switch * * Revision 1.24 2004/06/21 12:15:29 manolito * encodeBegin in UIData examines descendants valid flag recursivly now before refreshing DataModel * * Revision 1.23 2004/05/27 12:14:55 manolito * no message * * Revision 1.22 2004/05/21 10:39:27 manolito * new renderedIfEmpty attribute in ext. HtmlDataTable component * * Revision 1.21 2004/05/18 11:21:11 manolito * optimized saving of descendant states: isAllChildrenAndFacetsValid loop no longer needed * */public class UIData extends UIComponentBase implements NamingContainer{ 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -