1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.kuali.ole.sys.document.web;
17  
18  import java.io.IOException;
19  import java.util.List;
20  import java.util.Map;
21  
22  import javax.servlet.jsp.JspException;
23  import javax.servlet.jsp.PageContext;
24  import javax.servlet.jsp.tagext.JspFragment;
25  import javax.servlet.jsp.tagext.Tag;
26  
27  import org.kuali.ole.sys.document.AccountingDocument;
28  import org.kuali.ole.sys.document.datadictionary.AccountingLineGroupDefinition;
29  import org.kuali.ole.sys.document.datadictionary.TotalDefinition;
30  import org.kuali.ole.sys.document.web.renderers.CellCountCurious;
31  import org.kuali.ole.sys.document.web.renderers.CollectionPropertiesCurious;
32  import org.kuali.ole.sys.document.web.renderers.GroupErrorsRenderer;
33  import org.kuali.ole.sys.document.web.renderers.GroupTitleLineRenderer;
34  import org.kuali.ole.sys.document.web.renderers.Renderer;
35  import org.kuali.ole.sys.document.web.renderers.RepresentedCellCurious;
36  import org.kuali.rice.kew.api.WorkflowDocument;
37  import org.kuali.rice.krad.util.GlobalVariables;
38  
39  
40  
41  
42  public class DefaultAccountingLineGroupImpl implements AccountingLineGroup {
43      protected AccountingLineGroupDefinition groupDefinition;
44      protected JspFragment importLineOverride;
45      protected String collectionPropertyName;
46      protected List<? extends AccountingLineRenderingContext> containers;
47      protected AccountingDocument accountingDocument;
48      protected int cellCount = 0;
49      protected int arbitrarilyHighIndex;
50      protected Map<String, Object> displayedErrors;
51      protected Map<String, Object> displayedWarnings;
52      protected Map<String, Object> displayedInfo;
53      protected boolean canEdit;
54      protected String collectionItemPropertyName;
55      protected List errorKeys;
56      
57      
58  
59  
60      public DefaultAccountingLineGroupImpl() {}
61  
62      
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73      public void initialize(AccountingLineGroupDefinition groupDefinition, AccountingDocument accountingDocument, List<RenderableAccountingLineContainer> containers, String collectionPropertyName, String collectionItemPropertyName, Map<String, Object> displayedErrors, Map<String, Object> displayedWarnings, Map<String, Object> displayedInfo, boolean canEdit) {
74          this.groupDefinition = groupDefinition;
75          this.accountingDocument = accountingDocument;
76          this.containers = containers;
77          this.collectionPropertyName = collectionPropertyName;
78          this.collectionItemPropertyName = collectionItemPropertyName;
79          this.displayedErrors = displayedErrors;
80          this.displayedWarnings = displayedWarnings;
81          this.displayedInfo = displayedInfo;
82          this.canEdit = canEdit;
83      }
84  
85      
86  
87  
88  
89  
90  
91      public void renderEverything(PageContext pageContext, Tag parentTag) throws JspException {
92          if (groupDefinition.isHeaderRendering()) {
93              renderGroupHeader(pageContext, parentTag);
94          }
95          renderAccountingLineContainers(pageContext, parentTag);
96  
97          boolean renderTotals = !accountingDocument.getSourceAccountingLines().isEmpty() || !accountingDocument.getTargetAccountingLines().isEmpty();
98          renderTotals &= groupDefinition.getTotals() != null && groupDefinition.getTotals().size() > 0;
99          if (renderTotals) {
100             renderTotals(pageContext, parentTag);
101         }
102     }
103 
104     
105 
106 
107 
108 
109 
110     public int getWidthInCells() {
111         if (groupDefinition.getForceColumnCount() > 0)
112             return groupDefinition.getForceColumnCount();
113         if (cellCount > 0)
114             return cellCount;
115 
116         int max = 0;
117         for (AccountingLineRenderingContext line : containers) {
118             if (line.getRenderableCellCount() > max) {
119                 max = line.getRenderableCellCount();
120             }
121         }
122         cellCount = max;
123         return cellCount;
124     }
125 
126     
127 
128 
129 
130 
131 
132 
133 
134     protected void renderGroupHeader(PageContext pageContext, Tag parentTag) throws JspException {
135         if (importLineOverride != null) {
136             try {
137                 importLineOverride.invoke(pageContext.getOut());
138             }
139             catch (IOException ioe) {
140                 throw new JspException("Could not render import line override fragment", ioe);
141             }
142         }
143         else {
144             GroupTitleLineRenderer groupTitleLineRenderer = new GroupTitleLineRenderer();
145             groupTitleLineRenderer.setAccountingLineGroupDefinition(groupDefinition);
146             groupTitleLineRenderer.setCellCount(getWidthInCells());
147             groupTitleLineRenderer.setLineCollectionProperty(collectionPropertyName);
148             groupTitleLineRenderer.setAccountingDocument(accountingDocument);
149             groupTitleLineRenderer.setCanEdit(canEdit);
150 
151             boolean isGroupEditable = groupDefinition.getAccountingLineAuthorizer().isGroupEditable(accountingDocument, containers, GlobalVariables.getUserSession().getPerson());            
152             groupTitleLineRenderer.overrideCanUpload(groupDefinition.isImportingAllowed() && isGroupEditable);
153             groupTitleLineRenderer.setGroupActionsRendered(!this.isDocumentEnrouted() && isGroupEditable);
154 
155             groupTitleLineRenderer.render(pageContext, parentTag);
156             groupTitleLineRenderer.clear();
157         }
158 
159         renderErrors(pageContext, parentTag);
160     }
161     
162     
163 
164 
165 
166 
167     protected void renderErrors(PageContext pageContext, Tag parentTag) throws JspException {
168         GroupErrorsRenderer errorRenderer = getErrorRenderer();
169         errorRenderer.setErrorKeyMatch(groupDefinition.getErrorKey());
170         errorRenderer.setColSpan(getWidthInCells());
171         errorRenderer.render(pageContext, parentTag);
172 
173         moveListToMap(errorRenderer.getErrorsRendered(), getDisplayedErrors());
174         moveListToMap(errorRenderer.getWarningsRendered(), getDisplayedWarnings());
175         moveListToMap(errorRenderer.getInfoRendered(), getDisplayedInfo());
176 
177         errorRenderer.clear();
178     }
179     
180     
181 
182 
183 
184 
185     protected void moveListToMap(List<String> theList, Map theMap) {
186         for (String s : theList) {
187             theMap.put(s, "true");
188         }
189     }
190     
191     
192 
193 
194     protected GroupErrorsRenderer getErrorRenderer() {
195         return new GroupErrorsRenderer();
196     }
197 
198     
199 
200 
201 
202 
203 
204     protected void renderAccountingLineContainers(PageContext pageContext, Tag parentTag) throws JspException {
205         for (AccountingLineRenderingContext container : containers) {
206             container.populateValuesForFields();
207             container.populateWithTabIndexIfRequested(arbitrarilyHighIndex);
208             container.renderElement(pageContext, parentTag, container);
209         }
210     }
211 
212     
213 
214 
215 
216 
217 
218 
219     protected void renderTotals(PageContext pageContext, Tag parentTag) throws JspException {
220         int cellCount = getWidthInCells();
221 
222         List<? extends TotalDefinition> groupTotals = groupDefinition.getTotals();
223         for (TotalDefinition definition : groupTotals) {
224             if (definition instanceof NestedFieldTotaling) {
225                 NestedFieldTotaling nestedFieldTotaling = (NestedFieldTotaling) definition;
226 
227                 if (nestedFieldTotaling.isNestedProperty()) {
228                     int index = groupTotals.indexOf(definition);
229                     AccountingLineRenderingContext container = this.containers.get(index);
230                     String containingObjectPropertyName = container.getAccountingLineContainingObjectPropertyName();
231                     nestedFieldTotaling.setContainingPropertyName(containingObjectPropertyName);
232                 }
233             }
234 
235             Renderer renderer = definition.getTotalRenderer();
236             if (renderer instanceof CellCountCurious) {
237                 ((CellCountCurious) renderer).setCellCount(cellCount);
238             }
239 
240             if (renderer instanceof RepresentedCellCurious) {
241                 RepresentedCellCurious representedCellCurious = ((RepresentedCellCurious) renderer);
242                 int columnNumberOfRepresentedCell = this.getRepresentedColumnNumber(representedCellCurious.getRepresentedCellPropertyName());
243                 representedCellCurious.setColumnNumberOfRepresentedCell(columnNumberOfRepresentedCell);
244             }
245             
246             if (renderer instanceof CollectionPropertiesCurious) {
247                 ((CollectionPropertiesCurious)renderer).setCollectionProperty(this.collectionPropertyName);
248                 ((CollectionPropertiesCurious)renderer).setCollectionItemProperty(this.collectionItemPropertyName);
249             }
250 
251             renderer.render(pageContext, parentTag);
252             renderer.clear();
253         }
254     }
255 
256     
257 
258 
259 
260 
261 
262     protected int getRepresentedColumnNumber(String propertyName) {
263         for (AccountingLineRenderingContext container : containers) {
264             List<AccountingLineTableRow> tableRows = container.getRows();
265 
266             for (AccountingLineTableRow row : tableRows) {
267                 List<AccountingLineTableCell> tableCells = row.getCells();
268                 int cumulativeDisplayCellCount = 0;
269 
270                 for (AccountingLineTableCell cell : tableCells) {
271                     cumulativeDisplayCellCount += cell.getColSpan();
272                     List<RenderableElement> fields = cell.getRenderableElement();
273 
274                     for (RenderableElement field : fields) {
275                         if (field instanceof ElementNamable == false) {
276                             continue;
277                         }
278 
279                         if (((ElementNamable) field).getName().equals(propertyName)) {
280                             return cumulativeDisplayCellCount;
281                         }
282                     }
283                 }
284             }
285         }
286 
287         return -1;
288     }
289 
290     
291 
292 
293 
294 
295     public void setCellCount(int cellCount) {
296         this.cellCount = cellCount;
297     }
298 
299     
300 
301 
302 
303 
304     public void setImportLineOverride(JspFragment importLineOverride) {
305         this.importLineOverride = importLineOverride;
306     }
307 
308     
309 
310 
311 
312 
313     public void setArbitrarilyHighIndex(int arbitrarilyHighIndex) {
314         this.arbitrarilyHighIndex = arbitrarilyHighIndex;
315     }
316 
317     
318 
319 
320 
321     public Map getDisplayedWarnings() {
322         return displayedWarnings;
323     }
324 
325     
326 
327 
328 
329     public Map getDisplayedInfo() {
330         return displayedInfo;
331     }
332 
333     
334 
335 
336 
337     public List getErrorKeys() {
338         return errorKeys;
339     }
340 
341     
342 
343 
344 
345     public void setErrorKeys(List errorKeys) {
346         this.errorKeys = errorKeys;
347     }
348 
349     
350 
351 
352     private boolean isDocumentEnrouted() {
353         WorkflowDocument workflowDocument = accountingDocument.getDocumentHeader().getWorkflowDocument();
354 
355         return !workflowDocument.isInitiated() && !workflowDocument.isSaved();
356     }
357     
358     
359 
360 
361     public void updateDeletabilityOfAllLines() {
362         if (this.isDocumentEnrouted()) {
363             if (hasEnoughAccountingLinesForDelete()) {
364                 for (AccountingLineRenderingContext accountingLineRenderingContext : containers) {
365                     if (accountingLineRenderingContext.isEditableLine()) {
366                         accountingLineRenderingContext.makeDeletable();
367                     }
368                 }
369             }
370         } else {
371             
372             for (AccountingLineRenderingContext accountingLineRenderingContext : containers) {
373                 accountingLineRenderingContext.makeDeletable();
374             }
375         }
376     }
377     
378     
379 
380 
381 
382     protected boolean hasEnoughAccountingLinesForDelete() {
383         
384         int editableLineCount = 0;
385         for (AccountingLineRenderingContext accountingLineRenderingContext : containers) {
386             if (!accountingLineRenderingContext.isNewLine() && accountingLineRenderingContext.isEditableLine()) {
387                 editableLineCount += 1;
388             }
389             if (editableLineCount == 2) return true; 
390         }
391         return false;
392     }
393 
394     
395 
396 
397 
398     public String getCollectionItemPropertyName() {
399         return collectionItemPropertyName;
400     }
401 
402     
403 
404 
405 
406     public AccountingLineGroupDefinition getGroupDefinition() {
407         return groupDefinition;
408     }
409 
410     
411 
412 
413 
414     public void setGroupDefinition(AccountingLineGroupDefinition groupDefinition) {
415         this.groupDefinition = groupDefinition;
416     }
417 
418     
419 
420 
421 
422     public Map getDisplayedErrors() {
423         return displayedErrors;
424     }
425 
426     
427 
428 
429 
430     public void setDisplayedErrors(Map displayedErrors) {
431         this.displayedErrors = displayedErrors;
432     }
433 
434     
435 
436 
437 
438     public String getCollectionPropertyName() {
439         return collectionPropertyName;
440     }
441 
442     
443 
444 
445 
446     public void setCollectionPropertyName(String collectionPropertyName) {
447         this.collectionPropertyName = collectionPropertyName;
448     }
449 
450     
451 
452 
453 
454     public void setCollectionItemPropertyName(String collectionItemPropertyName) {
455         this.collectionItemPropertyName = collectionItemPropertyName;
456     }
457 
458 
459     public AccountingDocument getAccountingDocument() {
460         return accountingDocument;
461     }
462 
463     public void setAccountingDocument(AccountingDocument accountingDocument) {
464         this.accountingDocument = accountingDocument;
465     }
466 }