001 /* 002 * Copyright 2011 The Kuali Foundation. 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.kfs.sys.document.web; 017 018 import java.util.ArrayList; 019 import java.util.List; 020 import java.util.Map; 021 import java.util.Set; 022 023 import org.kuali.kfs.sys.businessobject.AccountingLine; 024 import org.kuali.kfs.sys.document.AccountingDocument; 025 import org.kuali.kfs.sys.document.datadictionary.AccountingLineViewColumnsDefinition; 026 import org.kuali.kfs.sys.document.service.AccountingLineFieldRenderingTransformation; 027 028 /** 029 * A layout element that renders elements 030 */ 031 public class AccountingLineViewColumns implements AccountingLineViewLineFillingElement { 032 private List<AccountingLineViewField> fields; 033 private AccountingLineViewColumnsDefinition definition; 034 035 /** 036 * Constructs a AccountingLineViewColumns 037 * @param definition the data dictionary validation of this columns layout element 038 * @param fields the fields to render within this columns layout element 039 */ 040 public AccountingLineViewColumns(AccountingLineViewColumnsDefinition definition, List<AccountingLineViewField> fields) { 041 this.definition = definition; 042 this.fields = fields; 043 } 044 045 /** 046 * Returns the name of this element 047 * @see org.kuali.kfs.sys.document.web.TableJoining#getName() 048 */ 049 public String getName() { 050 return definition.getName(); 051 } 052 053 /** 054 * 055 * @see org.kuali.kfs.sys.document.web.TableJoining#getRequestedRowCount() 056 */ 057 public int getRequestedRowCount() { 058 return 1; 059 } 060 061 /** 062 * This element should be stretched 063 * @see org.kuali.kfs.sys.document.web.AccountingLineViewLineFillingElement#stretchToFillLine() 064 */ 065 public boolean shouldStretchToFillLine() { 066 return true; 067 } 068 069 /** 070 * Joins the header row with a line filling cell, which includes within it an inner table that shows all the child fields 071 * @see org.kuali.kfs.sys.document.web.TableJoining#joinRow(org.kuali.kfs.sys.document.web.AccountingLineTableRow, org.kuali.kfs.sys.document.web.AccountingLineTableRow) 072 */ 073 public void joinRow(AccountingLineTableRow headerLabelRow, AccountingLineTableRow row) { 074 AccountingLineTableCell cell = new AccountingLineTableCell(); 075 076 AccountingLineTable columnsTable = new AccountingLineTable(); 077 078 List<AccountingLineTableRow> rows = createRowsForFields(); 079 080 columnsTable.setRows(rows); 081 cell.addRenderableElement(columnsTable); 082 headerLabelRow.addCell(cell); 083 } 084 085 /** 086 * Creates rows for the inner tables for each field inside this columsn definition 087 * @return a List of created AccountingLineTableRows 088 */ 089 protected List<AccountingLineTableRow> createRowsForFields() { 090 List<AccountingLineTableRow> rows = new ArrayList<AccountingLineTableRow>(); 091 092 int countForThisRow = 0; 093 AccountingLineTableRow row = new AccountingLineTableRow(); 094 for (AccountingLineViewField field : fields) { 095 row.addCell(createHeaderCellForField(field)); 096 row.addCell(createCellForField(field)); 097 countForThisRow += 1; 098 099 if (countForThisRow == definition.getColumnCount()) { 100 rows.add(row); 101 countForThisRow = 0; 102 row = new AccountingLineTableRow(); 103 } 104 } 105 if (countForThisRow > 0) { // oops! we stopped mid-row and now need to fill it out 106 while (countForThisRow < definition.getColumnCount()) { 107 row.addCell(createPaddingCell()); 108 countForThisRow += 1; 109 } 110 rows.add(row); 111 } 112 113 return rows; 114 } 115 116 /** 117 * Creates a header cell for for the given field 118 * @param field the field to create a header cell for 119 * @return a header cell 120 */ 121 protected AccountingLineTableCell createHeaderCellForField(AccountingLineViewField field) { 122 AccountingLineTableCell headerCell = new AccountingLineTableCell(); 123 headerCell.setRendersAsHeader(true); 124 headerCell.addRenderableElement(field.createHeaderLabel()); 125 return headerCell; 126 } 127 128 /** 129 * Creates the "field" cell for the given field 130 * @param field the field to create a cell for 131 * @return the cell withe field in it 132 */ 133 protected AccountingLineTableCell createCellForField(AccountingLineViewField field) { 134 AccountingLineTableCell cell = new AccountingLineTableCell(); 135 cell.addRenderableElement(field); 136 return cell; 137 } 138 139 /** 140 * Creates an empty cell to pad out the place typically held for a cell 141 * @return an empty table cell that spans two columns 142 */ 143 protected AccountingLineTableCell createPaddingCell() { 144 AccountingLineTableCell cell = new AccountingLineTableCell(); 145 cell.setColSpan(2); 146 cell.setNeverEmpty(true); 147 return cell; 148 } 149 150 /** 151 * An exception state; line filling elements can only join tables through lines 152 * @see org.kuali.kfs.sys.document.web.TableJoining#joinTable(java.util.List) 153 */ 154 public void joinTable(List<AccountingLineTableRow> rows) { 155 throw new IllegalStateException("Line elements may not join a table directly; the specified rendering is incorrect"); 156 } 157 158 /** 159 * Has fields perform the transformations 160 * @see org.kuali.kfs.sys.document.web.TableJoining#performFieldTransformations(java.util.List, org.kuali.kfs.sys.businessobject.AccountingLine, java.util.Map, java.util.Map) 161 */ 162 public void performFieldTransformations(List<AccountingLineFieldRenderingTransformation> fieldTransformations, AccountingLine accountingLine, Map unconvertedValues) { 163 int count = 0; 164 for (AccountingLineViewField field : fields) { 165 for (AccountingLineFieldRenderingTransformation transformation : fieldTransformations) { 166 transformation.transformField(accountingLine, field.getField(), field.getDefinition(), unconvertedValues); 167 } 168 } 169 } 170 171 /** 172 * Removes any child action blocks; surviving blocks are instructed to remove child blocks they have 173 * @see org.kuali.kfs.sys.document.web.TableJoining#removeAllActionBlocks() 174 */ 175 public void removeAllActionBlocks() { 176 List<AccountingLineViewField> fieldsToRemove = new ArrayList<AccountingLineViewField>(); 177 for (AccountingLineViewField field : fields) { 178 if (field.isActionBlock()) { 179 fieldsToRemove.add(field); 180 } else { 181 field.removeAllActionBlocks(); 182 } 183 } 184 fields.removeAll(fieldsToRemove); 185 } 186 187 /** 188 * Goes through all child fields; removes any fields which match unviewable blocks or otherwise, has the field remove unviewable blocks 189 * @see org.kuali.kfs.sys.document.web.TableJoining#removeUnviewableBlocks(java.util.Set) 190 */ 191 public void removeUnviewableBlocks(Set<String> unviewableBlocks) { 192 List<AccountingLineViewField> unviewableFields = new ArrayList<AccountingLineViewField>(); 193 for (AccountingLineViewField field : fields) { 194 if (unviewableBlocks.contains(field.getName())) { 195 unviewableFields.add(field); 196 } else { 197 field.removeUnviewableBlocks(unviewableBlocks); 198 } 199 } 200 fields.removeAll(unviewableFields); 201 } 202 203 /** 204 * Has each field readOnlyize 205 * @see org.kuali.kfs.sys.document.web.TableJoining#readOnlyizeReadOnlyBlocks(java.util.Set) 206 */ 207 public void readOnlyizeReadOnlyBlocks(Set<String> readOnlyBlocks) { 208 for (AccountingLineViewField field : fields) { 209 field.readOnlyizeReadOnlyBlocks(readOnlyBlocks); 210 } 211 } 212 213 /** 214 * Gets the fields attribute. 215 * @return Returns the fields. 216 */ 217 public List<AccountingLineViewField> getFields() { 218 return fields; 219 } 220 221 /** 222 * Sets the fields attribute value. 223 * @param fields The fields to set. 224 */ 225 public void setFields(List<AccountingLineViewField> fields) { 226 this.fields = fields; 227 } 228 229 /** 230 * @see org.kuali.kfs.sys.document.web.ReadOnlyable#isReadOnly() 231 */ 232 public boolean isReadOnly() { 233 for (AccountingLineViewField field : fields) { 234 if (!field.isReadOnly()) return false; 235 } 236 return true; 237 } 238 239 /** 240 * @see org.kuali.kfs.sys.document.web.ReadOnlyable#readOnlyize() 241 */ 242 public void readOnlyize() { 243 for (AccountingLineViewField field : fields) { 244 field.readOnlyize(); 245 } 246 } 247 248 /** 249 * Always returns 1; this will build an inner table in one cell 250 * @see org.kuali.kfs.sys.document.web.AccountingLineViewLineFillingElement#getDisplayingFieldWidth() 251 */ 252 public int getDisplayingFieldWidth() { 253 return 1; 254 } 255 256 /** 257 * @see org.kuali.kfs.sys.document.web.TableJoining#setEditableBlocks(java.util.Set) 258 */ 259 public void setEditableBlocks(Set<String> editableBlocks) { 260 for (AccountingLineViewField field : fields) { 261 field.setEditableBlocks(editableBlocks); 262 } 263 } 264 265 /** 266 * @see org.kuali.kfs.sys.document.web.ReadOnlyable#setEditable() 267 */ 268 public void setEditable() { 269 for (AccountingLineViewField field : fields) { 270 field.setEditable(); 271 } 272 } 273 274 }