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 }