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.HashSet; 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.datadictionary.AccountingLineViewLinesDefinition; 025 import org.kuali.kfs.sys.document.service.AccountingLineFieldRenderingTransformation; 026 027 /** 028 * Represents the rendering for a bunch of elements within the accounting line view 029 */ 030 public class AccountingLineViewLines implements TableJoining, ReadOnlyable { 031 private List<AccountingLineViewLineFillingElement> elements; 032 private AccountingLineViewLinesDefinition definition; 033 034 /** 035 * Gets the definition attribute. 036 * @return Returns the definition. 037 */ 038 public AccountingLineViewLinesDefinition getDefinition() { 039 return definition; 040 } 041 /** 042 * Sets the definition attribute value. 043 * @param definition The definition to set. 044 */ 045 public void setDefinition(AccountingLineViewLinesDefinition definition) { 046 this.definition = definition; 047 } 048 049 /** 050 * @see org.kuali.kfs.sys.document.web.AccountingLineViewRenderableElementContainer#getName() 051 */ 052 public String getName() { 053 return definition.getElementName(); 054 } 055 /** 056 * Gets the elements attribute. 057 * @return Returns the elements. 058 */ 059 public List<AccountingLineViewLineFillingElement> getElements() { 060 return elements; 061 } 062 /** 063 * Sets the elements attribute value. 064 * @param elements The elements to set. 065 */ 066 public void setElements(List<AccountingLineViewLineFillingElement> lines) { 067 this.elements = lines; 068 } 069 070 /** 071 * The interesting implementation...how many does it need? Let's see here...one for each child row... 072 * yes...that's right, one table row for each child row 073 * @see org.kuali.kfs.sys.document.web.AccountingLineViewRenderableElement#getRequestedRowCount() 074 */ 075 public int getRequestedRowCount() { 076 int sum = 0; 077 for (AccountingLineViewLineFillingElement line : elements) { 078 sum += line.getRequestedRowCount(); 079 } 080 return sum; 081 } 082 083 /** 084 * Throws an exception - lines should never be asked to join rows 085 * @see org.kuali.kfs.sys.document.web.TableJoining#joinRow(org.kuali.kfs.sys.document.web.AccountingLineTableRow) 086 */ 087 public void joinRow(AccountingLineTableRow headerRow, AccountingLineTableRow row) { 088 throw new IllegalStateException("Error in line rendering algorithm - lines cannot join a single row."); 089 } 090 091 /** 092 * Attempts to have each child line join the rows that have been given 093 * @see org.kuali.kfs.sys.document.web.TableJoining#joinTable(java.util.List) 094 */ 095 public void joinTable(List<AccountingLineTableRow> rows) { 096 final int maxExpectedLineWidth = getMaxExpectedLineWidth(); 097 098 int count = 0; 099 for (AccountingLineViewLineFillingElement line : elements) { 100 AccountingLineTableRow headerRow = rows.get(count); 101 102 if (line.getRequestedRowCount() > 1) { 103 line.joinRow(headerRow, rows.get(count+1)); 104 padOutOrStretchCells(line, maxExpectedLineWidth, headerRow, rows.get(count+1)); 105 106 count += 2; 107 } else { 108 line.joinRow(headerRow, null); 109 padOutOrStretchCells(line, maxExpectedLineWidth, headerRow, null); 110 111 count += 1; 112 } 113 } 114 } 115 116 /** 117 * Either pads out out the given table rows with an empty cell or stretches the cell to fill the whole line 118 * @param line the line joining the table 119 * @param maxExpectedLineWidth the expected width, in cell count, of the line 120 * @param headerRow the first row to add padding out to 121 * @param row the second row to add padding out to - if we're only filling one row, this will be null 122 */ 123 protected void padOutOrStretchCells(AccountingLineViewLineFillingElement line, int maxExpectedLineWidth, AccountingLineTableRow headerRow, AccountingLineTableRow row) { 124 final int shorterThanMax = maxExpectedLineWidth - line.getDisplayingFieldWidth(); 125 if (shorterThanMax > 0) { 126 if (line.shouldStretchToFillLine() && headerRow.getChildCellCount() == 1) { 127 headerRow.getCells().get(0).setColSpan(maxExpectedLineWidth); 128 if (row != null) { 129 row.getCells().get(0).setColSpan(maxExpectedLineWidth); 130 } 131 } else { 132 PlaceHoldingLayoutElement placeHolder = new PlaceHoldingLayoutElement(shorterThanMax); 133 placeHolder.joinRow(headerRow, row); 134 } 135 } 136 } 137 138 /** 139 * @see org.kuali.kfs.sys.document.web.ReadOnlyable#readOnlyize() 140 */ 141 public void readOnlyize() { 142 for (AccountingLineViewLineFillingElement line : elements) { 143 line.readOnlyize(); 144 } 145 } 146 147 /** 148 * @see org.kuali.kfs.sys.document.web.ReadOnlyable#isReadOnly() 149 */ 150 public boolean isReadOnly() { 151 for (AccountingLineViewLineFillingElement line : elements) { 152 if (!line.isReadOnly()) { 153 return false; 154 } 155 } 156 return true; 157 } 158 159 /** 160 * @see org.kuali.kfs.sys.document.web.TableJoining#removeAllActionBlocks() 161 */ 162 public void removeAllActionBlocks() { 163 for (AccountingLineViewLineFillingElement line : elements) { 164 line.removeAllActionBlocks(); 165 } 166 } 167 168 /** 169 * @see org.kuali.kfs.sys.document.web.TableJoining#removeUnviewableBlocks(java.util.Set) 170 */ 171 public void removeUnviewableBlocks(Set<String> unviewableBlocks) { 172 Set<AccountingLineViewLineFillingElement> linesToRemove = new HashSet<AccountingLineViewLineFillingElement>(); 173 for (AccountingLineViewLineFillingElement line : elements) { 174 if (unviewableBlocks.contains(line.getName())) { 175 linesToRemove.add(line); 176 } else { 177 line.removeUnviewableBlocks(unviewableBlocks); 178 } 179 } 180 elements.removeAll(linesToRemove); 181 } 182 183 /** 184 * @see org.kuali.kfs.sys.document.web.TableJoining#performFieldTransformation(org.kuali.kfs.sys.document.service.AccountingLineFieldRenderingTransformation, org.kuali.kfs.sys.businessobject.AccountingLine, java.util.Map, java.util.Map) 185 */ 186 public void performFieldTransformations(List<AccountingLineFieldRenderingTransformation> fieldTransformations, AccountingLine accountingLine, Map unconvertedValues) { 187 for (AccountingLineViewLineFillingElement line : elements) { 188 line.performFieldTransformations(fieldTransformations, accountingLine, unconvertedValues); 189 } 190 } 191 192 /** 193 * @return the maximum expected width of any of the child line elements in cells 194 */ 195 public int getMaxExpectedLineWidth() { 196 int maxWidth = 0; 197 for (AccountingLineViewLineFillingElement line: elements) { 198 int width = line.getDisplayingFieldWidth(); 199 if (width > maxWidth) { 200 maxWidth = width; 201 } 202 } 203 return maxWidth; 204 } 205 206 /** 207 * Shuffles the responsibility to the child lines 208 * @see org.kuali.kfs.sys.document.web.TableJoining#readOnlyizeReadOnlyBlocks(java.util.Set) 209 */ 210 public void readOnlyizeReadOnlyBlocks(Set<String> readOnlyBlocks) { 211 for (AccountingLineViewLineFillingElement line : elements) { 212 line.readOnlyizeReadOnlyBlocks(readOnlyBlocks); 213 } 214 } 215 216 /** 217 * @see org.kuali.kfs.sys.document.web.TableJoining#setEditableBlocks(java.util.Set) 218 */ 219 public void setEditableBlocks(Set<String> editableBlocks) { 220 for (AccountingLineViewLineFillingElement line : elements) { 221 line.setEditableBlocks(editableBlocks); 222 } 223 } 224 225 /** 226 * @see org.kuali.kfs.sys.document.web.ReadOnlyable#setEditable() 227 */ 228 public void setEditable() { 229 for (AccountingLineViewLineFillingElement line : elements) { 230 line.setEditable(); 231 } 232 } 233 }