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 java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.HashSet;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Set;
24
25 import org.apache.commons.lang.StringUtils;
26 import org.kuali.rice.krad.datadictionary.parse.BeanTag;
27 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
28 import org.kuali.rice.krad.datadictionary.parse.BeanTags;
29 import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
30 import org.kuali.rice.krad.datadictionary.validator.Validator;
31 import org.kuali.rice.krad.uif.UifConstants;
32 import org.kuali.rice.krad.uif.UifPropertyPaths;
33 import org.kuali.rice.krad.uif.component.Component;
34 import org.kuali.rice.krad.uif.component.DataBinding;
35 import org.kuali.rice.krad.uif.component.DelayedCopy;
36 import org.kuali.rice.krad.uif.field.Field;
37 import org.kuali.rice.krad.uif.field.FieldGroup;
38 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
39 import org.kuali.rice.krad.uif.util.ExpressionUtils;
40 import org.kuali.rice.krad.uif.util.LifecycleElement;
41 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
42 import org.kuali.rice.krad.uif.view.ExpressionEvaluator;
43 import org.kuali.rice.krad.uif.view.View;
44 import org.kuali.rice.krad.uif.view.ViewModel;
45 import org.kuali.rice.krad.uif.widget.Disclosure;
46 import org.kuali.rice.krad.uif.widget.Help;
47 import org.kuali.rice.krad.uif.widget.Scrollpane;
48 import org.kuali.rice.krad.util.KRADUtils;
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 @BeanTags({@BeanTag(name = "group", parent = "Uif-GroupBase"),
71 @BeanTag(name = "boxGroup", parent = "Uif-BoxGroupBase"),
72 @BeanTag(name = "verticalGroup", parent = "Uif-VerticalBoxGroup"),
73 @BeanTag(name = "verticalSection", parent = "Uif-VerticalBoxSection"),
74 @BeanTag(name = "verticalSubSection", parent = "Uif-VerticalBoxSubSection"),
75 @BeanTag(name = "disclosureVerticalSection", parent = "Uif-Disclosure-VerticalBoxSection"),
76 @BeanTag(name = "disclosureVerticalSubSection", parent = "Uif-Disclosure-VerticalBoxSubSection"),
77 @BeanTag(name = "horizontalGroup", parent = "Uif-HorizontalBoxGroup"),
78 @BeanTag(name = "horizontalSection", parent = "Uif-HorizontalBoxSection"),
79 @BeanTag(name = "horizontalSubSection", parent = "Uif-HorizontalBoxSubSection"),
80 @BeanTag(name = "disclosureHorizontalSection", parent = "Uif-Disclosure-HorizontalBoxSection"),
81 @BeanTag(name = "disclosureHorizontalSubSection", parent = "Uif-Disclosure-HorizontalBoxSubSection"),
82 @BeanTag(name = "grid", parent = "Uif-GridGroup"),
83 @BeanTag(name = "gridSection", parent = "Uif-GridSection"),
84 @BeanTag(name = "gridSubSection", parent = "Uif-GridSubSection"),
85 @BeanTag(name = "disclosureGridSection", parent = "Uif-Disclosure-GridSection"),
86 @BeanTag(name = "cssGrid", parent = "Uif-CssGridGroup"),
87 @BeanTag(name = "section", parent = "Uif-CssGridSection"),
88 @BeanTag(name = "subSection", parent = "Uif-CssGridSubSection"),
89 @BeanTag(name = "section1Col", parent = "Uif-CssGridSection-1FieldLabelColumn"),
90 @BeanTag(name = "section2Col", parent = "Uif-CssGridSection-2FieldLabelColumn"),
91 @BeanTag(name = "section3Col", parent = "Uif-CssGridSection-3FieldLabelColumn"),
92 @BeanTag(name = "subSection1Col", parent = "Uif-CssGridSubSection-1FieldLabelColumn"),
93 @BeanTag(name = "subSection2Col", parent = "Uif-CssGridSubSection-2FieldLabelColumn"),
94 @BeanTag(name = "subSection3Col", parent = "Uif-CssGridSubSection-3FieldLabelColumn"),
95 @BeanTag(name = "list", parent = "Uif-ListGroup"),
96 @BeanTag(name = "listSection", parent = "Uif-ListSection"),
97 @BeanTag(name = "listSubSection", parent = "Uif-ListSubSection"),
98 @BeanTag(name = "disclosureListSection", parent = "Uif-Disclosure-ListSection"),
99 @BeanTag(name = "disclosureListSubSection", parent = "Uif-Disclosure-ListSubSection"),
100 @BeanTag(name = "collectionGridItem", parent = "Uif-CollectionGridItem"),
101 @BeanTag(name = "collectionVerticalBoxItem", parent = "Uif-CollectionVerticalBoxItem"),
102 @BeanTag(name = "collectionHorizontalBoxItem", parent = "Uif-CollectionHorizontalBoxItem"),
103 @BeanTag(name = "headerUpperGroup", parent = "Uif-HeaderUpperGroup"),
104 @BeanTag(name = "headerRightGroup", parent = "Uif-HeaderRightGroup"),
105 @BeanTag(name = "headerLowerGroup", parent = "Uif-HeaderLowerGroup"),
106 @BeanTag(name = "footer", parent = "Uif-FooterBase"),
107 @BeanTag(name = "formFooter", parent = "Uif-FormFooter"),
108 @BeanTag(name = "maintenanceGrid", parent = "Uif-MaintenanceGridGroup"),
109 @BeanTag(name = "maintenanceHorizontalGroup", parent = "Uif-MaintenanceHorizontalBoxGroup"),
110 @BeanTag(name = "maintenanceVerticalGroup", parent = "Uif-MaintenanceVerticalBoxGroup"),
111 @BeanTag(name = "maintenanceGridSection", parent = "Uif-MaintenanceGridSection"),
112 @BeanTag(name = "maintenanceGridSubSection", parent = "Uif-MaintenanceGridSubSection"),
113 @BeanTag(name = "maintenanceHorizontalSection", parent = "Uif-MaintenanceHorizontalBoxSection"),
114 @BeanTag(name = "maintenanceVerticalSection", parent = "Uif-MaintenanceVerticalBoxSection"),
115 @BeanTag(name = "maintenanceHorizontalSubSection", parent = "Uif-MaintenanceHorizontalBoxSubSection"),
116 @BeanTag(name = "maintenanceVerticalSubSection", parent = "Uif-MaintenanceVerticalBoxSubSection")})
117 public class GroupBase extends ContainerBase implements Group {
118 private static final long serialVersionUID = 7953641325356535509L;
119
120 private String fieldBindByNamePrefix;
121 private String fieldBindingObjectPath;
122
123 @DelayedCopy
124 private Disclosure disclosure;
125 private Scrollpane scrollpane;
126
127 private List<? extends Component> items;
128
129 private String wrapperTag;
130
131
132
133
134 public GroupBase() {
135 items = Collections.emptyList();
136 }
137
138
139
140
141 @Override
142 public void performInitialization(Object model) {
143 if (isAjaxDisclosureGroup()) {
144 this.setItems(new ArrayList<Component>());
145 }
146
147 super.performInitialization(model);
148
149 Iterator<? extends Component> itemIterator = getItems().iterator();
150 while (itemIterator.hasNext()) {
151 Component component = itemIterator.next();
152
153 if (component == null) {
154 continue;
155 }
156
157 String excludeUnless = component.getExcludeUnless();
158 if (StringUtils.isNotBlank(excludeUnless) &&
159 !Boolean.TRUE.equals(ObjectPropertyUtils.getPropertyValue(model, excludeUnless))) {
160 itemIterator.remove();
161 continue;
162 }
163
164 String excludeIf = component.getExcludeIf();
165 if (StringUtils.isNotBlank(excludeIf) &&
166 Boolean.TRUE.equals(ObjectPropertyUtils.getPropertyValue(model, excludeIf))) {
167 itemIterator.remove();
168 continue;
169 }
170
171
172
173 if (component instanceof DataBinding) {
174 DataBinding dataBinding = (DataBinding) component;
175
176 if (StringUtils.isNotBlank(getFieldBindByNamePrefix())) {
177 String bindByNamePrefixToSet = getFieldBindByNamePrefix();
178
179 if (StringUtils.isNotBlank(dataBinding.getBindingInfo().getBindByNamePrefix())) {
180 bindByNamePrefixToSet += "." + dataBinding.getBindingInfo().getBindByNamePrefix();
181 }
182 dataBinding.getBindingInfo().setBindByNamePrefix(bindByNamePrefixToSet);
183 }
184
185 if (StringUtils.isNotBlank(fieldBindingObjectPath) && StringUtils.isBlank(
186 dataBinding.getBindingInfo().getBindingObjectPath())) {
187 dataBinding.getBindingInfo().setBindingObjectPath(fieldBindingObjectPath);
188 }
189 }
190
191 else if (component instanceof FieldGroup) {
192 FieldGroup fieldGroup = (FieldGroup) component;
193
194 if (fieldGroup.getGroup() != null) {
195 if (StringUtils.isBlank(fieldGroup.getGroup().getFieldBindByNamePrefix())) {
196 fieldGroup.getGroup().setFieldBindByNamePrefix(fieldBindByNamePrefix);
197 }
198 if (StringUtils.isBlank(fieldGroup.getGroup().getFieldBindingObjectPath())) {
199 fieldGroup.getGroup().setFieldBindingObjectPath(fieldBindingObjectPath);
200 }
201 }
202 } else if (component instanceof Group) {
203 Group subGroup = (Group) component;
204 if (StringUtils.isNotBlank(getFieldBindByNamePrefix())) {
205 if (StringUtils.isNotBlank(subGroup.getFieldBindByNamePrefix())) {
206 subGroup.setFieldBindByNamePrefix(
207 getFieldBindByNamePrefix() + "." + subGroup.getFieldBindByNamePrefix());
208 } else {
209 subGroup.setFieldBindByNamePrefix(getFieldBindByNamePrefix());
210 }
211 }
212 if (StringUtils.isNotBlank(getFieldBindingObjectPath())) {
213 if (StringUtils.isNotBlank(subGroup.getFieldBindingObjectPath())) {
214 subGroup.setFieldBindingObjectPath(
215 getFieldBindingObjectPath() + "." + subGroup.getFieldBindingObjectPath());
216 } else {
217 subGroup.setFieldBindingObjectPath(getFieldBindingObjectPath());
218 }
219 }
220 }
221 }
222 }
223
224
225
226
227 @Override
228 public void afterEvaluateExpression() {
229 super.afterEvaluateExpression();
230
231 if (getReadOnly() == null) {
232 Component parent = ViewLifecycle.getPhase().getParent();
233 setReadOnly(parent == null ? null : parent.getReadOnly());
234 }
235 }
236
237
238
239
240
241
242 @Override
243 public void performFinalize(Object model, LifecycleElement parent) {
244 super.performFinalize(model, parent);
245
246 if (StringUtils.isBlank(wrapperTag) && StringUtils.isNotBlank(this.getHeaderText()) && this.getHeader()
247 .isRender()) {
248 wrapperTag = UifConstants.WrapperTags.SECTION;
249 } else if (StringUtils.isBlank(wrapperTag)) {
250 wrapperTag = UifConstants.WrapperTags.DIV;
251 }
252
253 setNestedComponentId(getInstructionalMessage(), this.getId() + UifConstants.IdSuffixes.INSTRUCTIONAL);
254 setNestedComponentId(getHeader(), this.getId() + UifConstants.IdSuffixes.HEADER_WRAPPER);
255 setNestedComponentId(getHelp(), this.getId() + UifConstants.IdSuffixes.HELP_WRAPPER);
256
257 if (getHelp() != null && getHelp().getHelpAction() != null) {
258 setNestedComponentId(getHelp().getHelpAction(), this.getId() + UifConstants.IdSuffixes.HELP);
259 }
260 }
261
262
263
264
265
266
267
268 protected void setNestedComponentId(Component component, String newId) {
269 if (component != null) {
270 component.setId(newId);
271 }
272 }
273
274
275
276
277 @Override
278 public Set<Class<? extends Component>> getSupportedComponents() {
279 Set<Class<? extends Component>> supportedComponents = new HashSet<Class<? extends Component>>();
280 supportedComponents.add(Field.class);
281 supportedComponents.add(Group.class);
282
283 return supportedComponents;
284 }
285
286
287
288
289 @Override
290 public String getComponentTypeName() {
291 return "group";
292 }
293
294
295
296
297 @Override
298 @BeanTagAttribute
299 public String getFieldBindByNamePrefix() {
300 return this.fieldBindByNamePrefix;
301 }
302
303
304
305
306 @Override
307 public void setFieldBindByNamePrefix(String fieldBindByNamePrefix) {
308 this.fieldBindByNamePrefix = fieldBindByNamePrefix;
309 }
310
311
312
313
314 @BeanTagAttribute
315 public String getFieldBindingObjectPath() {
316 return this.fieldBindingObjectPath;
317 }
318
319
320
321
322 @Override
323 public void setFieldBindingObjectPath(String fieldBindingObjectPath) {
324 this.fieldBindingObjectPath = fieldBindingObjectPath;
325 }
326
327
328
329
330 @BeanTagAttribute
331 public Disclosure getDisclosure() {
332 return this.disclosure;
333 }
334
335
336
337
338 @Override
339 public void setDisclosure(Disclosure disclosure) {
340 this.disclosure = disclosure;
341 }
342
343
344
345
346 @BeanTagAttribute
347 public Scrollpane getScrollpane() {
348 return this.scrollpane;
349 }
350
351
352
353
354 @Override
355 public void setScrollpane(Scrollpane scrollpane) {
356 this.scrollpane = scrollpane;
357 }
358
359
360
361
362 @Override
363 @BeanTagAttribute
364 public List<? extends Component> getItems() {
365 if (items == Collections.EMPTY_LIST && isMutable(true)) {
366 items = new ArrayList<Component>();
367 }
368
369 return this.items;
370 }
371
372
373
374
375 @Override
376 public void setItems(List<? extends Component> items) {
377 if (items == null) {
378 this.items = Collections.emptyList();
379 } else if (items.contains(this)) {
380 throw new IllegalArgumentException("Attempted to add group to itself");
381 } else {
382 this.items = items;
383 }
384 }
385
386
387
388
389
390
391
392 @BeanTagAttribute
393 public String getWrapperTag() {
394 return wrapperTag;
395 }
396
397
398
399
400 public void setWrapperTag(String wrapperTag) {
401 this.wrapperTag = wrapperTag;
402 }
403
404
405
406
407
408
409 protected boolean isAjaxDisclosureGroup() {
410 ViewModel model = (ViewModel) ViewLifecycle.getModel();
411 View view = ViewLifecycle.getView();
412
413 ExpressionUtils.populatePropertyExpressionsFromGraph(this);
414
415
416 if (this.getDisclosure() != null && StringUtils.isNotBlank(this.getDisclosure().getPropertyExpression(
417 UifPropertyPaths.DEFAULT_OPEN))){
418 ExpressionEvaluator expressionEvaluator = ViewLifecycle.getExpressionEvaluator();
419
420 String expression = this.getDisclosure().getPropertyExpression(UifPropertyPaths.DEFAULT_OPEN);
421 expression = expressionEvaluator.replaceBindingPrefixes(view, this, expression);
422
423 expression = expressionEvaluator.evaluateExpressionTemplate(this.getDisclosure().getContext(), expression);
424 ObjectPropertyUtils.setPropertyValue(this.getDisclosure(), UifPropertyPaths.DEFAULT_OPEN, expression);
425 }
426
427
428 if (this.getDisclosure() != null) {
429 KRADUtils.syncClientSideStateForComponent(this.getDisclosure(), model.getClientStateForSyncing());
430 }
431
432
433
434 return !this.isRetrieveViaAjax() && this.getDisclosure() != null && this.getDisclosure()
435 .isAjaxRetrievalWhenOpened() && !this.getDisclosure().isDefaultOpen();
436 }
437
438
439
440
441 @Override
442 public void completeValidation(ValidationTrace tracer) {
443 tracer.addBean(this);
444
445
446 for (int i = 0; i < getItems().size(); i++) {
447 if (getItems().get(i).getClass() == PageGroup.class || getItems().get(i).getClass()
448 == TabNavigationGroup.class) {
449 String currentValues[] = {"item(" + i + ").class =" + getItems().get(i).getClass()};
450 tracer.createError("Items in Group cannot be PageGroup or NaviagtionGroup", currentValues);
451 }
452 }
453
454
455 if (getLayoutManager() == null) {
456 if (Validator.checkExpressions(this, "layoutManager")) {
457 String currentValues[] = {"layoutManager = " + getLayoutManager()};
458 tracer.createError("LayoutManager must be set", currentValues);
459 }
460 }
461
462 super.completeValidation(tracer.getCopy());
463 }
464
465
466
467
468 @Override
469 public boolean isRenderLoading() {
470 return disclosure != null && disclosure.isAjaxRetrievalWhenOpened() && (!disclosure.isRender() || !disclosure
471 .isDefaultOpen());
472 }
473
474 }