/** * Copyright © 2002 Instituto Superior Técnico * * This file is part of FenixEdu Academic. * * FenixEdu Academic is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * FenixEdu Academic is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with FenixEdu Academic. If not, see <http://www.gnu.org/licenses/>. */ package org.fenixedu.academic.ui.faces.components; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.Map; import javax.faces.component.UIComponent; import javax.faces.component.UIData; import javax.faces.context.FacesContext; import javax.faces.el.ValueBinding; public class UIDataRepeater extends UIData { private static final String COMPONENT_FAMILY = "DataRepeater"; private String rowIndexVar; private String rowCountVar; public UIDataRepeater() { super(); } @Override public String getFamily() { return COMPONENT_FAMILY; } @Override public String getClientId(FacesContext context) { String clientId = super.getClientId(context); int rowIndex = getRowIndex(); if (rowIndex == -1) { return clientId; } else { return clientId + "_" + rowIndex; } } @Override public void processDecodes(FacesContext context) { 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(); // For some reason its necessary to touch Id property, // otherwise the child control will not call getClientId // on // parent (NamingContainer) child.setId(child.getId()); if (!child.isRendered()) { continue; } child.processDecodes(context); } } } setRowIndex(-1); super.processDecodes(context); } @Override public void processUpdates(FacesContext context) { 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(); // For some reason its necessary to touch Id property, // otherwise the child control will not call getClientId // on // parent (NamingContainer) child.setId(child.getId()); if (!child.isRendered()) { continue; } child.processUpdates(context); } } } setRowIndex(-1); super.processUpdates(context); } @Override public void processValidators(FacesContext context) { 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(); // For some reason its necessary to touch Id property, // otherwise the child control will not call getClientId // on // parent (NamingContainer) child.setId(child.getId()); if (!child.isRendered()) { continue; } child.processValidators(context); } } } setRowIndex(-1); super.processValidators(context); } @Override public void setRowIndex(int rowIndex) { super.setRowIndex(rowIndex); String rowIndexVar = getRowIndexVar(); String rowCountVar = getRowCountVar(); if (rowIndexVar != null || rowCountVar != null) { Map requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestMap(); if (rowIndex >= 0) { // regular row index, update request scope variables if (rowIndexVar != null) { requestMap.put(getRowIndexVar(), new Integer(rowIndex)); } if (rowCountVar != null) { requestMap.put(getRowCountVar(), new Integer(getRowCount())); } } else { // rowIndex == -1 means end of loop --> remove request scope // variables if (rowIndexVar != null) { requestMap.remove(getRowIndexVar()); } if (rowCountVar != null) { requestMap.remove(getRowCountVar()); } } } } public void setRowIndexVar(String rowIndexVar) { this.rowIndexVar = rowIndexVar; } public String getRowIndexVar() { if (this.rowIndexVar != null) { return this.rowIndexVar; } ValueBinding vb = getValueBinding("rowIndexVar"); return vb != null ? (String) vb.getValue(getFacesContext()) : null; } public void setRowCountVar(String rowCountVar) { this.rowCountVar = rowCountVar; } public String getRowCountVar() { if (this.rowCountVar != null) { return this.rowCountVar; } ValueBinding vb = getValueBinding("rowCountVar"); return vb != null ? (String) vb.getValue(getFacesContext()) : null; } @Override public Object saveState(FacesContext stateToSave) { Object state[] = new Object[3]; state[0] = super.saveState(stateToSave); state[1] = getRowCountVar(); state[2] = getRowIndexVar(); return state; } @Override public void restoreState(FacesContext context, Object stateToRestore) { Object state[] = (Object[]) stateToRestore; super.restoreState(context, state[0]); setRowCountVar((String) state[1]); setRowIndexVar((String) state[2]); } @Override public Object getValue() { return super.getValue() instanceof Collection ? new ArrayList((Collection) super.getValue()) : super.getValue(); } }