1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.kuali.rice.krad.uif.container;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.krad.datadictionary.parse.BeanTag;
20  import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
21  import org.kuali.rice.krad.datadictionary.parse.BeanTags;
22  import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
23  import org.kuali.rice.krad.datadictionary.validator.Validator;
24  import org.kuali.rice.krad.uif.UifConstants;
25  import org.kuali.rice.krad.uif.UifPropertyPaths;
26  import org.kuali.rice.krad.uif.component.Component;
27  import org.kuali.rice.krad.uif.component.DataBinding;
28  import org.kuali.rice.krad.uif.component.DelayedCopy;
29  import org.kuali.rice.krad.uif.field.Field;
30  import org.kuali.rice.krad.uif.field.FieldGroup;
31  import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
32  import org.kuali.rice.krad.uif.lifecycle.initialize.AssignIdsTask;
33  import org.kuali.rice.krad.uif.util.LifecycleAwareList;
34  import org.kuali.rice.krad.uif.util.LifecycleElement;
35  import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
36  import org.kuali.rice.krad.uif.view.ExpressionEvaluator;
37  import org.kuali.rice.krad.uif.view.View;
38  import org.kuali.rice.krad.uif.view.ViewModel;
39  import org.kuali.rice.krad.uif.widget.Disclosure;
40  import org.kuali.rice.krad.uif.widget.Scrollpane;
41  import org.kuali.rice.krad.util.KRADUtils;
42  
43  import java.util.ArrayList;
44  import java.util.Collections;
45  import java.util.HashSet;
46  import java.util.List;
47  import java.util.Set;
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  @BeanTags({@BeanTag(name = "group-bean", parent = "Uif-GroupBase"),
70          @BeanTag(name = "boxGroupBase-bean", parent = "Uif-BoxGroupBase"),
71          @BeanTag(name = "verticalBoxGroup-bean", parent = "Uif-VerticalBoxGroup"),
72          @BeanTag(name = "verticalBoxSection-bean", parent = "Uif-VerticalBoxSection"),
73          @BeanTag(name = "verticalBoxSubSection-bean", parent = "Uif-VerticalBoxSubSection"),
74          @BeanTag(name = "disclosure-verticalBoxSection-bean", parent = "Uif-Disclosure-VerticalBoxSection"),
75          @BeanTag(name = "disclosure-verticalBoxSubSection-bean", parent = "Uif-Disclosure-VerticalBoxSubSection"),
76          @BeanTag(name = "horizontalBoxGroup-bean", parent = "Uif-HorizontalBoxGroup"),
77          @BeanTag(name = "horizontalBoxSection-bean", parent = "Uif-HorizontalBoxSection"),
78          @BeanTag(name = "horizontalBoxSubSection-bean", parent = "Uif-HorizontalBoxSubSection"),
79          @BeanTag(name = "disclosure-horizontalBoxSection-bean", parent = "Uif-Disclosure-HorizontalBoxSection"),
80          @BeanTag(name = "disclosure-horizontalBoxSubSection-bean", parent = "Uif-Disclosure-HorizontalBoxSubSection"),
81          @BeanTag(name = "gridGroup-bean", parent = "Uif-GridGroup"),
82          @BeanTag(name = "gridSection-bean", parent = "Uif-GridSection"),
83          @BeanTag(name = "gridSubSection-bean", parent = "Uif-GridSubSection"),
84          @BeanTag(name = "disclosure-gridSection-bean", parent = "Uif-Disclosure-GridSection"),
85          @BeanTag(name = "cssGridGroup-bean", parent = "Uif-CssGridGroup"),
86          @BeanTag(name = "cssGridSection-bean", parent = "Uif-CssGridSection"),
87          @BeanTag(name = "cssGridSubSection-bean", parent = "Uif-CssGridSubSection"),
88          @BeanTag(name = "cssGridSection-1FieldLabelColumn-bean", parent = "Uif-CssGridSection-1FieldLabelColumn"),
89          @BeanTag(name = "cssGridSection-2FieldLabelColumn-bean", parent = "Uif-CssGridSection-2FieldLabelColumn"),
90          @BeanTag(name = "cssGridSection-3FieldLabelColumn-bean", parent = "Uif-CssGridSection-3FieldLabelColumn"),
91          @BeanTag(name = "cssGridSubSection-1FieldLabelColumn-bean", parent = "Uif-CssGridSubSection-1FieldLabelColumn"),
92          @BeanTag(name = "cssGridSubSection-2FieldLabelColumn-bean", parent = "Uif-CssGridSubSection-2FieldLabelColumn"),
93          @BeanTag(name = "cssGridSubSection-3FieldLabelColumn-bean", parent = "Uif-CssGridSubSection-3FieldLabelColumn"),
94          @BeanTag(name = "listGroup-bean", parent = "Uif-ListGroup"),
95          @BeanTag(name = "listSection-bean", parent = "Uif-ListSection"),
96          @BeanTag(name = "listSubSection-bean", parent = "Uif-ListSubSection"),
97          @BeanTag(name = "disclosure-listSection-bean", parent = "Uif-Disclosure-ListSection"),
98          @BeanTag(name = "disclosure-listSubSection-bean", parent = "Uif-Disclosure-ListSubSection"),
99          @BeanTag(name = "collectionGridItem-bean", parent = "Uif-CollectionGridItem"),
100         @BeanTag(name = "collectionVerticalBoxItem-bean", parent = "Uif-CollectionVerticalBoxItem"),
101         @BeanTag(name = "collectionHorizontalBoxItem-bean", parent = "Uif-CollectionHorizontalBoxItem"),
102         @BeanTag(name = "headerUpperGroup-bean", parent = "Uif-HeaderUpperGroup"),
103         @BeanTag(name = "headerRightGroup-bean", parent = "Uif-HeaderRightGroup"),
104         @BeanTag(name = "headerLowerGroup-bean", parent = "Uif-HeaderLowerGroup"),
105         @BeanTag(name = "footer-bean", parent = "Uif-FooterBase"),
106         @BeanTag(name = "formFooter-bean", parent = "Uif-FormFooter"),
107         @BeanTag(name = "actionsGroup-bean", parent = "Uif-ActionsGroup"),
108         @BeanTag(name = "disclosureActionsGroup-bean", parent = "Uif-DisclosureActionsGroup"),
109         @BeanTag(name = "disclosureActions-reqMessageGroup-bean", parent = "Uif-DisclosureActions-ReqMessageGroup"),
110         @BeanTag(name = "inactiveItemsActionsGroup-bean", parent = "Uif-InactiveItemsActionsGroup"),
111         @BeanTag(name = "documentInfoGroup-bean", parent = "Uif-DocumentInfoGroup"),
112         @BeanTag(name = "documentOverviewSection-bean", parent = "Uif-DocumentOverviewSection"),
113         @BeanTag(name = "documentAdHocRecipientsSection-bean", parent = "Uif-DocumentAdHocRecipientsSection"),
114         @BeanTag(name = "documentRouteLogSection-bean", parent = "Uif-DocumentRouteLogSection"),
115         @BeanTag(name = "documentPageFooter-bean", parent = "Uif-DocumentPageFooter"),
116         @BeanTag(name = "incidentDetailGroup-bean", parent = "Uif-IncidentDetailGroup"),
117         @BeanTag(name = "incidentStackTraceGroup-bean", parent = "Uif-IncidentStackTraceGroup"),
118         @BeanTag(name = "incidentReportFooter-bean", parent = "Uif-IncidentReportFooter"),
119         @BeanTag(name = "initiatedDocumentFooter-bean", parent = "InitiatedDocumentFooter"),
120         @BeanTag(name = "inquiryFooter-bean", parent = "Uif-InquiryFooter"),
121         @BeanTag(name = "lookupCriteriaGroup-bean", parent = "Uif-LookupCriteriaGroup"),
122         @BeanTag(name = "lookupPageHeaderGroup-bean", parent = "Uif-LookupPageHeaderGroup"),
123         @BeanTag(name = "lookupCriteriaFooter-bean", parent = "Uif-LookupCriteriaFooter"),
124         @BeanTag(name = "lookupResultsFooter-bean", parent = "Uif-LookupResultsFooter"),
125         @BeanTag(name = "maintenanceGridGroup-bean", parent = "Uif-MaintenanceGridGroup"),
126         @BeanTag(name = "maintenanceHorizontalBoxGroup-bean", parent = "Uif-MaintenanceHorizontalBoxGroup"),
127         @BeanTag(name = "maintenanceVerticalBoxGroup-bean", parent = "Uif-MaintenanceVerticalBoxGroup"),
128         @BeanTag(name = "maintenanceGridSection-bean", parent = "Uif-MaintenanceGridSection"),
129         @BeanTag(name = "maintenanceGridSubSection-bean", parent = "Uif-MaintenanceGridSubSection"),
130         @BeanTag(name = "maintenanceHorizontalBoxSection-bean", parent = "Uif-MaintenanceHorizontalBoxSection"),
131         @BeanTag(name = "maintenanceVerticalBoxSection-bean", parent = "Uif-MaintenanceVerticalBoxSection"),
132         @BeanTag(name = "maintenanceHorizontalBoxSubSection-bean", parent = "Uif-MaintenanceHorizontalBoxSubSection"),
133         @BeanTag(name = "maintenanceVerticalBoxSubSection-bean", parent = "Uif-MaintenanceVerticalBoxSubSection")})
134 public class GroupBase extends ContainerBase implements Group {
135     private static final long serialVersionUID = 7953641325356535509L;
136 
137     private String fieldBindByNamePrefix;
138     private String fieldBindingObjectPath;
139 
140     @DelayedCopy
141     private Disclosure disclosure;
142     private Scrollpane scrollpane;
143 
144     private List<? extends Component> items;
145 
146     private String wrapperTag;
147 
148     
149 
150 
151     public GroupBase() {
152         items = Collections.emptyList();
153     }
154 
155     
156 
157 
158 
159 
160 
161 
162 
163 
164 
165     @Override
166     public void performInitialization(Object model) {
167         if (isClosedAjaxDisclosure()) {
168             this.setItems(new ArrayList<Component>());
169             this.setFooter(null);
170         }
171 
172         super.performInitialization(model);
173 
174         for (Component component : getItems()) {
175             
176             
177             if (component instanceof DataBinding) {
178                 DataBinding dataBinding = (DataBinding) component;
179 
180                 if (StringUtils.isNotBlank(getFieldBindByNamePrefix())) {
181                     String bindByNamePrefixToSet = getFieldBindByNamePrefix();
182 
183                     if (StringUtils.isNotBlank(dataBinding.getBindingInfo().getBindByNamePrefix())) {
184                         bindByNamePrefixToSet += "." + dataBinding.getBindingInfo().getBindByNamePrefix();
185                     }
186                     dataBinding.getBindingInfo().setBindByNamePrefix(bindByNamePrefixToSet);
187                 }
188 
189                 if (StringUtils.isNotBlank(fieldBindingObjectPath) && StringUtils.isBlank(
190                         dataBinding.getBindingInfo().getBindingObjectPath())) {
191                     dataBinding.getBindingInfo().setBindingObjectPath(fieldBindingObjectPath);
192                 }
193             }
194             
195             else if (component instanceof FieldGroup) {
196                 FieldGroup fieldGroup = (FieldGroup) component;
197 
198                 if (fieldGroup.getGroup() != null) {
199                     if (StringUtils.isBlank(fieldGroup.getGroup().getFieldBindByNamePrefix())) {
200                         fieldGroup.getGroup().setFieldBindByNamePrefix(fieldBindByNamePrefix);
201                     }
202                     if (StringUtils.isBlank(fieldGroup.getGroup().getFieldBindingObjectPath())) {
203                         fieldGroup.getGroup().setFieldBindingObjectPath(fieldBindingObjectPath);
204                     }
205                 }
206             } else if (component instanceof Group) {
207                 Group subGroup = (Group) component;
208                 if (StringUtils.isNotBlank(getFieldBindByNamePrefix())) {
209                     if (StringUtils.isNotBlank(subGroup.getFieldBindByNamePrefix())) {
210                         subGroup.setFieldBindByNamePrefix(
211                                 getFieldBindByNamePrefix() + "." + subGroup.getFieldBindByNamePrefix());
212                     } else {
213                         subGroup.setFieldBindByNamePrefix(getFieldBindByNamePrefix());
214                     }
215                 }
216                 if (StringUtils.isNotBlank(getFieldBindingObjectPath())) {
217                     if (StringUtils.isNotBlank(subGroup.getFieldBindingObjectPath())) {
218                         subGroup.setFieldBindingObjectPath(
219                                 getFieldBindingObjectPath() + "." + subGroup.getFieldBindingObjectPath());
220                     } else {
221                         subGroup.setFieldBindingObjectPath(getFieldBindingObjectPath());
222                     }
223                 }
224             }
225         }
226     }
227 
228     
229 
230 
231 
232 
233     @Override
234     public void performFinalize(Object model, LifecycleElement parent) {
235         super.performFinalize(model, parent);
236 
237         if (StringUtils.isBlank(wrapperTag) && StringUtils.isNotBlank(this.getHeaderText()) && this.getHeader()
238                 .isRender()) {
239             wrapperTag = UifConstants.WrapperTags.SECTION;
240         } else if (StringUtils.isBlank(wrapperTag)) {
241             wrapperTag = UifConstants.WrapperTags.DIV;
242         }
243     }
244 
245     
246 
247 
248     @Override
249     public Set<Class<? extends Component>> getSupportedComponents() {
250         Set<Class<? extends Component>> supportedComponents = new HashSet<Class<? extends Component>>();
251         supportedComponents.add(Field.class);
252         supportedComponents.add(Group.class);
253 
254         return supportedComponents;
255     }
256 
257     
258 
259 
260     @Override
261     public String getComponentTypeName() {
262         return "group";
263     }
264 
265     
266 
267 
268 
269 
270 
271 
272 
273 
274 
275 
276 
277     @Override
278     @BeanTagAttribute(name = "fieldBindByNamePrefix")
279     public String getFieldBindByNamePrefix() {
280         return this.fieldBindByNamePrefix;
281     }
282 
283     
284 
285 
286 
287 
288     public void setFieldBindByNamePrefix(String fieldBindByNamePrefix) {
289         this.fieldBindByNamePrefix = fieldBindByNamePrefix;
290     }
291 
292     
293 
294 
295 
296 
297 
298 
299 
300 
301 
302 
303 
304 
305 
306 
307     @BeanTagAttribute(name = "fieldBindingObjectPath")
308     public String getFieldBindingObjectPath() {
309         return this.fieldBindingObjectPath;
310     }
311 
312     
313 
314 
315 
316 
317     public void setFieldBindingObjectPath(String fieldBindingObjectPath) {
318         this.fieldBindingObjectPath = fieldBindingObjectPath;
319     }
320 
321     
322 
323 
324 
325 
326 
327     @BeanTagAttribute(name = "Disclosure", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
328     public Disclosure getDisclosure() {
329         return this.disclosure;
330     }
331 
332     
333 
334 
335 
336 
337     public void setDisclosure(Disclosure disclosure) {
338         this.disclosure = disclosure;
339     }
340 
341     
342 
343 
344 
345 
346 
347     @BeanTagAttribute(name = "scrollpane", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
348     public Scrollpane getScrollpane() {
349         return this.scrollpane;
350     }
351 
352     
353 
354 
355 
356 
357     public void setScrollpane(Scrollpane scrollpane) {
358         this.scrollpane = scrollpane;
359     }
360 
361     
362 
363 
364     @Override
365     @BeanTagAttribute(name = "items", type = BeanTagAttribute.AttributeType.LISTBEAN)
366     public List<? extends Component> getItems() {
367         if (items == Collections.EMPTY_LIST && isMutable(true)) {
368             items = new LifecycleAwareList<Component>(this);
369         }
370 
371         return this.items;
372     }
373 
374     
375 
376 
377 
378 
379     @SuppressWarnings("unchecked")
380     @Override
381     public void setItems(List<? extends Component> items) {
382         if (items == null) {
383             this.items = Collections.emptyList();
384         } else if (items.contains(this)) {
385             throw new IllegalArgumentException("Attempted to add group to itself");
386         } else {
387             this.items = new LifecycleAwareList<Component>(this, (List<Component>) items);
388         }
389     }
390 
391     
392 
393 
394 
395 
396 
397     @BeanTagAttribute(name = "wrapperTag")
398     public String getWrapperTag() {
399         return wrapperTag;
400     }
401 
402     
403 
404 
405     public void setWrapperTag(String wrapperTag) {
406         this.wrapperTag = wrapperTag;
407     }
408 
409     
410 
411 
412 
413 
414     protected boolean isClosedAjaxDisclosure() {
415         ViewModel model = (ViewModel) ViewLifecycle.getModel();
416         View view = ViewLifecycle.getView();
417 
418         if (this.getDisclosure() == null) {
419             return false;
420         }
421 
422         ViewLifecycle.getExpressionEvaluator().populatePropertyExpressionsFromGraph(this, false);
423         
424         
425         if (this.getDisclosure() != null && StringUtils.isNotBlank(this.getDisclosure().getPropertyExpression(
426                 UifPropertyPaths.DEFAULT_OPEN))) {
427             ExpressionEvaluator expressionEvaluator = ViewLifecycle.getExpressionEvaluator();
428 
429             String expression = this.getDisclosure().getPropertyExpression(UifPropertyPaths.DEFAULT_OPEN);
430             expression = expressionEvaluator.replaceBindingPrefixes(view, this, expression);
431 
432             expression = expressionEvaluator.evaluateExpressionTemplate(this.getDisclosure().getContext(), expression);
433             ObjectPropertyUtils.setPropertyValue(this.getDisclosure(), UifPropertyPaths.DEFAULT_OPEN, expression);
434         }
435 
436         if (disclosure.getId() == null) {
437             disclosure.setId(AssignIdsTask.generateId(disclosure, view));
438         }
439 
440         
441         if (this.getDisclosure() != null) {
442             KRADUtils.syncClientSideStateForComponent(this.getDisclosure(), model.getClientStateForSyncing());
443         }
444 
445         boolean closed = !this.getDisclosure().isDefaultOpen();
446 
447         boolean open = (closed && ViewLifecycle.isRefreshComponent(ViewLifecycle.getPhase().getViewPhase(),
448                 this.getViewPath())) || !closed;
449 
450         if (open) {
451             this.getDisclosure().setDefaultOpen(true);
452         }
453 
454         
455         return !this.isRetrieveViaAjax() && this.getDisclosure().isAjaxRetrievalWhenOpened() && !open;
456     }
457 
458     
459 
460 
461     @Override
462     public void completeValidation(ValidationTrace tracer) {
463         tracer.addBean(this);
464 
465         
466         for (int i = 0; i < getItems().size(); i++) {
467             if (getItems().get(i).getClass() == PageGroup.class || getItems().get(i).getClass()
468                     == NavigationGroup.class) {
469                 String currentValues[] = {"item(" + i + ").class =" + getItems().get(i).getClass()};
470                 tracer.createError("Items in Group cannot be PageGroup or NaviagtionGroup", currentValues);
471             }
472         }
473 
474         
475         if (getLayoutManager() == null) {
476             if (Validator.checkExpressions(this, "layoutManager")) {
477                 String currentValues[] = {"layoutManager = " + getLayoutManager()};
478                 tracer.createError("LayoutManager must be set", currentValues);
479             }
480         }
481 
482         super.completeValidation(tracer.getCopy());
483     }
484 
485     
486 
487 
488 
489 
490     public boolean isRenderLoading() {
491         return disclosure != null && disclosure.isAjaxRetrievalWhenOpened() && (!disclosure.isRender() || !disclosure
492                 .isDefaultOpen());
493     }
494 
495 }