001/* 002 * (C) Copyright 2008 JBoss and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Original file from org.jboss.seam.excel.ui.UIColumn.java in jboss-seam-excel 016 * Anahide Tchertchian 017 */ 018package org.nuxeo.ecm.platform.ui.web.component.seam; 019 020import java.io.IOException; 021import java.util.ArrayList; 022import java.util.Iterator; 023import java.util.List; 024 025import javax.faces.component.UIComponent; 026import javax.faces.context.FacesContext; 027 028import org.jboss.seam.excel.ExcelWorkbook; 029import org.jboss.seam.excel.ExcelWorkbookException; 030import org.jboss.seam.excel.WorksheetItem; 031import org.jboss.seam.excel.ui.UIWorksheet; 032import org.jboss.seam.excel.ui.command.Command; 033 034/** 035 * Overrides default column for better introspection of children. 036 * <p> 037 * If e:column tags are not direct children, the work sheet will not find them. As layout templating adds additional JSF 038 * components, the children tree has to be introspected further on, and other children components need to be processed 039 * (UIAliasHolder components used in layout rendering for instance). 040 * 041 * @since 5.4.2 042 */ 043public class UIColumn extends org.jboss.seam.excel.ui.UIColumn { 044 045 public static final String COMPONENT_TYPE = UIColumn.class.getName(); 046 047 public static final String FOOTER_FACET_NAME = "footer"; 048 049 @SuppressWarnings("rawtypes") 050 @Override 051 public void encodeBegin(FacesContext facesContext) throws IOException { 052 // Get workbook and worksheet 053 ExcelWorkbook excelWorkbook = getWorkbook(getParent()); 054 055 if (excelWorkbook == null) { 056 throw new ExcelWorkbookException("Could not find excel workbook"); 057 } 058 059 // Column width etc. 060 excelWorkbook.applyColumnSettings(this); 061 062 UIWorksheet sheet = (UIWorksheet) getParentByClass(getParent(), UIWorksheet.class); 063 if (sheet == null) { 064 throw new ExcelWorkbookException("Could not find worksheet"); 065 } 066 067 // Add header items (if any) 068 WorksheetItem headerItem = (WorksheetItem) getFacet(HEADER_FACET_NAME); 069 if (headerItem != null) { 070 excelWorkbook.addItem(headerItem); 071 } 072 073 // Execute commands (if any) 074 List<Command> commands = getCommands(getChildren()); 075 for (Command command : commands) { 076 excelWorkbook.executeCommand(command); 077 } 078 079 // Get UiCell template this column's data cells and iterate over sheet 080 // data 081 // XXX: process all components instead of just UICell ones. 082 for (UIComponent child : getChildren()) { 083 Object oldValue = null; 084 Iterator iterator = null; 085 // Store away the old value for the sheet binding var (if there is 086 // one) 087 if (sheet.getVar() != null) { 088 oldValue = FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get(sheet.getVar()); 089 iterator = sheet.getDataIterator(); 090 } else { 091 // No var, no iteration... 092 iterator = new ArrayList().iterator(); 093 } 094 095 while (iterator.hasNext()) { 096 // Store the bound data in the request map and add the cell 097 FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put(sheet.getVar(), 098 iterator.next()); 099 100 encodeChild(facesContext, sheet, excelWorkbook, child); 101 } 102 103 // No iteration, nothing to restore 104 if (sheet.getVar() == null) { 105 return; 106 } 107 // Restore the previously modified request map (if there was a var) 108 if (oldValue == null) { 109 FacesContext.getCurrentInstance().getExternalContext().getRequestMap().remove(sheet.getVar()); 110 } else { 111 FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put(sheet.getVar(), oldValue); 112 } 113 114 } 115 116 // Add footer items (if any) 117 WorksheetItem footerItem = (WorksheetItem) getFacet(FOOTER_FACET_NAME); 118 if (footerItem != null) { 119 excelWorkbook.addItem(footerItem); 120 } 121 122 // Move column pointer to next column 123 excelWorkbook.nextColumn(); 124 125 } 126 127 @SuppressWarnings("rawtypes") 128 protected void encodeChild(FacesContext facesContext, UIWorksheet sheet, ExcelWorkbook excelWorkbook, 129 UIComponent child) throws IOException { 130 // XXX make sure other components are processed 131 if (child instanceof WorksheetItem) { 132 excelWorkbook.addItem((WorksheetItem) child); 133 } else { 134 if (child.isRendered()) { 135 child.encodeBegin(facesContext); 136 // do not let component handling render of its children 137 List subChildren = child.getChildren(); 138 for (int j = 0, size = child.getChildCount(); j < size; j++) { 139 UIComponent subChild = (UIComponent) subChildren.get(j); 140 encodeChild(facesContext, sheet, excelWorkbook, subChild); 141 } 142 child.encodeEnd(facesContext); 143 } 144 } 145 146 } 147 148 @SuppressWarnings("unchecked") 149 public static <T> List<T> getAllChildrenOfType(List<UIComponent> children, Class<T> childType) { 150 List<T> matches = new ArrayList<T>(); 151 for (UIComponent child : children) { 152 if (childType.isAssignableFrom(child.getClass())) { 153 matches.add((T) child); 154 } else { 155 // XXX introspect children 156 List<T> subChildren = getAllChildrenOfType(child.getChildren(), childType); 157 if (subChildren != null && !subChildren.isEmpty()) { 158 matches.addAll(subChildren); 159 } 160 } 161 } 162 return matches; 163 } 164 165 /** 166 * Returns all commands from a child list 167 * 168 * @param children The list to search 169 * @return The commands 170 */ 171 protected static List<Command> getCommands(List<UIComponent> children) { 172 return getAllChildrenOfType(children, Command.class); 173 } 174 175}