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.AccountingDocument;
025    import org.kuali.kfs.sys.document.datadictionary.AccountingLineViewLineDefinition;
026    import org.kuali.kfs.sys.document.service.AccountingLineFieldRenderingTransformation;
027    
028    /**
029     * Represents a single table row to be rendered as part of an accounting line view.
030     */
031    public class AccountingLineViewLine implements ReadOnlyable, AccountingLineViewLineFillingElement {
032        private List<RenderableElement> elements;
033        private AccountingLineViewLineDefinition definition;
034     
035        /**
036         * Gets the definition attribute. 
037         * @return Returns the definition.
038         */
039        public AccountingLineViewLineDefinition getDefinition() {
040            return definition;
041        }
042        /**
043         * Sets the definition attribute value.
044         * @param definition The definition to set.
045         */
046        public void setDefinition(AccountingLineViewLineDefinition definition) {
047            this.definition = definition;
048        }
049        
050        /**
051         * @see org.kuali.kfs.sys.document.web.AccountingLineViewRenderableElementContainer#getName()
052         */
053        public String getName() {
054            return definition.getElementName();
055        }
056        /**
057         * Gets the elements attribute. 
058         * @return Returns the elements.
059         */
060        public List<RenderableElement> getElements() {
061            return elements;
062        }
063        /**
064         * Sets the elements attribute value.
065         * @param elements The elements to set.
066         */
067        public void setElements(List<RenderableElement> fields) {
068            this.elements = fields;
069        }
070        
071        /**
072         * Gets the number of actual rows requested (1)
073         * @see org.kuali.kfs.sys.document.web.AccountingLineViewRenderableElement#getRequestedRowCount()
074         */
075        public int getRequestedRowCount() {
076            return getMaxRequestedRowCount();
077        }
078        
079        /**
080         * Determines the max requested row count in the line. 
081         * @return the number of rows to create for this line
082         */
083        protected int getMaxRequestedRowCount() {
084            for (RenderableElement element : elements) {
085                if (element instanceof TableJoiningWithHeader && !element.isHidden()) {
086                    return 2;
087                }
088            }
089            return 1;
090        }
091        
092        /**
093         * @see org.kuali.kfs.sys.document.web.TableJoining#joinRow(org.kuali.kfs.sys.document.web.AccountingLineTableRow)
094         */
095        public void joinRow(AccountingLineTableRow headerRow, AccountingLineTableRow row) {
096           for (RenderableElement element : elements) {
097               if (element instanceof TableJoining) {
098                   ((TableJoining)element).joinRow(headerRow, row);
099               } else {
100                   headerRow.addCell(createTableCellForNonTableJoining(element));
101               }
102           }
103        }
104        
105        /**
106         * Creates a table cell to wrap the given rendering element
107         * @param element the element to wrap
108         * @return a table cell wrapping that element
109         */
110        protected AccountingLineTableCell createTableCellForNonTableJoining(RenderableElement element) {
111            AccountingLineTableCell cell = new AccountingLineTableCell();
112            cell.addRenderableElement(element);
113            cell.setRowSpan(getRequestedRowCount());
114            return cell;
115        }
116        
117        /**
118         * Always throws an exception - a line may only join a table through a parent lines element
119         * @see org.kuali.kfs.sys.document.web.TableJoining#joinTable(java.util.List)
120         */
121        public void joinTable(List<AccountingLineTableRow> rows) {
122            throw new IllegalStateException("Line elements may not join a table directly; the specified rendering is incorrect");
123        }
124        
125        /**
126         * This element should be padded out
127         * @see org.kuali.kfs.sys.document.web.AccountingLineViewLineFillingElement#stretchToFillLine()
128         */
129        public boolean shouldStretchToFillLine() {
130            return false;
131        }
132        
133        /**
134         * @see org.kuali.kfs.sys.document.web.TableJoining#readOnlyize()
135         */
136        public void readOnlyize() {
137            for (RenderableElement element : elements) {
138                if (element instanceof ReadOnlyable) {
139                    ((ReadOnlyable)element).readOnlyize();
140                }
141            }
142        }
143        
144        /**
145         * @see org.kuali.kfs.sys.document.web.ReadOnlyable#isReadOnly()
146         */
147        public boolean isReadOnly() {
148            for (RenderableElement element : elements) {
149                if (element instanceof ReadOnlyable && !((ReadOnlyable)element).isReadOnly()) {
150                    return false;
151                }
152            }
153            return true;
154        }
155        
156        /**
157         * @see org.kuali.kfs.sys.document.web.TableJoining#removeAllActionBlocks()
158         */
159        public void removeAllActionBlocks() {
160            Set<RenderableElement> actionBlocksToRemove = new HashSet<RenderableElement>();
161            for (RenderableElement element : elements) {
162                if (element.isActionBlock()) {
163                    actionBlocksToRemove.add(element);
164                }
165            }
166            elements.removeAll(actionBlocksToRemove);
167        }
168        
169        /**
170         * @see org.kuali.kfs.sys.document.web.TableJoining#removeUnviewableBlocks()
171         */
172        public void removeUnviewableBlocks(Set<String> unviewableBlocks) {
173            Set<RenderableElement> elementsToRemove = new HashSet<RenderableElement>();
174            for (RenderableElement element : elements) {
175                if (element instanceof TableJoining) {
176                    if (unviewableBlocks.contains(((TableJoining)element).getName())) {
177                        elementsToRemove.add(element);
178                    } else {
179                        ((TableJoining)element).removeUnviewableBlocks(unviewableBlocks);
180                    }
181                }
182            }
183            elements.removeAll(elementsToRemove);
184        }
185        
186        /**
187         * Shuffles responsibility on to any TableJoining children
188         * @see org.kuali.kfs.sys.document.web.TableJoining#readOnlyizeReadOnlyBlocks(java.util.Set)
189         */
190        public void readOnlyizeReadOnlyBlocks(Set<String> readOnlyBlocks) {
191            for (RenderableElement element : elements) {
192                if (element instanceof TableJoining) {
193                    ((TableJoining)element).readOnlyizeReadOnlyBlocks(readOnlyBlocks);
194                }
195            }
196        }
197        
198        /**
199         * @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)
200         */
201        public void performFieldTransformations(List<AccountingLineFieldRenderingTransformation> fieldTransformations, AccountingLine accountingLine, Map unconvertedValues) {
202            for (RenderableElement element : elements) {
203                if (element instanceof TableJoining) {
204                    ((TableJoining)element).performFieldTransformations(fieldTransformations, accountingLine, unconvertedValues);
205                }
206            }
207        }
208        
209        /**
210         * Finds the number of table cells this line expects to take up
211         * @return the number of displayed table cells this line expects to render as
212         */
213        public int getDisplayingFieldWidth() {
214            int count = 0;
215            for (RenderableElement element : elements) {
216                if (!element.isHidden()) {
217                    if (element instanceof AccountingLineViewField && ((AccountingLineViewField)element).getColSpanOverride() > 1) {
218                        count += ((AccountingLineViewField)element).getColSpanOverride();
219                    } else {
220                        count += 1;
221                    }
222                }
223            }
224            return count;
225        }
226        
227        /**
228         * @see org.kuali.kfs.sys.document.web.ReadOnlyable#setEditable()
229         */
230        public void setEditable() {
231            for (RenderableElement element : elements) {
232                if (element instanceof ReadOnlyable) {
233                    ((ReadOnlyable)element).setEditable();
234                }
235            }
236        }
237        
238        /**
239         * @see org.kuali.kfs.sys.document.web.TableJoining#setEditableBlocks(java.util.Set)
240         */
241        public void setEditableBlocks(Set<String> editableBlocks) {
242            for (RenderableElement element : elements) {
243                if (element instanceof TableJoining) {
244                    ((TableJoining)element).setEditableBlocks(editableBlocks);
245                }
246            }
247        }
248    }