1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.layout;
17
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Queue;
25
26 import org.apache.commons.lang.StringUtils;
27 import org.kuali.rice.krad.datadictionary.Copyable;
28 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
29 import org.kuali.rice.krad.datadictionary.uif.UifDictionaryBeanBase;
30 import org.kuali.rice.krad.uif.UifConstants;
31 import org.kuali.rice.krad.uif.UifConstants.ViewStatus;
32 import org.kuali.rice.krad.uif.component.Component;
33 import org.kuali.rice.krad.uif.component.PropertyReplacer;
34 import org.kuali.rice.krad.uif.component.ReferenceCopy;
35 import org.kuali.rice.krad.uif.container.Container;
36 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
37 import org.kuali.rice.krad.uif.lifecycle.ViewLifecyclePhase;
38 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleTask;
39 import org.kuali.rice.krad.uif.util.LifecycleAwareList;
40 import org.kuali.rice.krad.uif.util.LifecycleAwareMap;
41 import org.kuali.rice.krad.uif.util.LifecycleElement;
42 import org.kuali.rice.krad.uif.view.View;
43
44
45
46
47
48
49
50
51
52
53
54 public abstract class LayoutManagerBase extends UifDictionaryBeanBase implements LayoutManager {
55 private static final long serialVersionUID = -2657663560459456814L;
56
57 private String id;
58 private String viewPath;
59 private Map<String, String> phasePathMapping;
60
61 private String template;
62 private String templateName;
63
64 private String style;
65
66 private List<String> libraryCssClasses;
67 private List<String> cssClasses;
68 private List<String> additionalCssClasses;
69
70 @ReferenceCopy(newCollectionInstance = true)
71 private Map<String, Object> context;
72
73 private List<PropertyReplacer> propertyReplacers;
74
75 private String viewStatus = UifConstants.ViewStatus.CREATED;
76
77 public LayoutManagerBase() {
78 super();
79
80 phasePathMapping = new HashMap<String, String>();
81 context = Collections.emptyMap();
82 cssClasses = Collections.emptyList();
83 libraryCssClasses = Collections.emptyList();
84 additionalCssClasses = Collections.emptyList();
85 }
86
87
88
89
90 public void checkMutable(boolean legalDuringInitialization) {
91 if (UifConstants.ViewStatus.CACHED.equals(viewStatus)) {
92 ViewLifecycle.reportIllegalState("Cached layout manager " + getClass() + " " + getId()
93 + " is immutable, use copy() to get a mutable instance");
94 return;
95 }
96
97 if (ViewLifecycle.isActive()) {
98 return;
99 }
100
101 if (UifConstants.ViewStatus.CREATED.equals(viewStatus)) {
102 if (!legalDuringInitialization) {
103 ViewLifecycle.reportIllegalState(
104 "View has not been fully initialized, attempting to change layout manager "
105 + getClass() + " " + getId());
106 return;
107 }
108 } else {
109 ViewLifecycle.reportIllegalState("Layout manager " + getClass() + " " + getId()
110 + " has been initialized, but the lifecycle is not active.");
111 return;
112 }
113 }
114
115
116
117
118 public boolean isMutable(boolean legalDuringInitialization) {
119 return (UifConstants.ViewStatus.CREATED.equals(viewStatus) && legalDuringInitialization)
120 || ViewLifecycle.isActive();
121 }
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 public String getViewStatus() {
137 return this.viewStatus;
138 }
139
140
141
142
143
144
145
146 @Override
147 public void setViewStatus(ViewLifecyclePhase phase) {
148 if (!viewStatus.equals(phase.getStartViewStatus()) &&
149 !viewStatus.equals(phase.getEndViewStatus())) {
150 ViewLifecycle.reportIllegalState("Component " + getClass().getName() + " is not in expected status "
151 + phase.getStartViewStatus() + " marking the completion of a lifecycle phase, found " + viewStatus
152 + "\nPhase: " + phase);
153 }
154
155 this.viewStatus = phase.getEndViewStatus();
156 }
157
158
159
160
161 @Override
162 public void notifyCompleted(ViewLifecyclePhase phase) {
163 }
164
165
166
167
168 @Override
169 public void performInitialization(Object model) {
170 checkMutable(false);
171
172
173 if (StringUtils.isBlank(id)) {
174 Container container = (Container) ViewLifecycle.getPhase().getElement();
175 id = container.getId() + "_layout";
176 }
177 }
178
179
180
181
182 @Override
183 public void performApplyModel(Object model, LifecycleElement component) {
184 checkMutable(false);
185 }
186
187
188
189
190 @Override
191 public void performFinalize(Object model, LifecycleElement component) {
192 checkMutable(false);
193
194
195 List<String> finalCssClasses = new ArrayList<String>();
196
197 View view = ViewLifecycle.getView();
198
199 if (this.libraryCssClasses != null && view.isUseLibraryCssClasses()) {
200 finalCssClasses.addAll(libraryCssClasses);
201 }
202
203 if (this.cssClasses != null) {
204 finalCssClasses.addAll(cssClasses);
205 }
206
207 if (this.additionalCssClasses != null) {
208 finalCssClasses.addAll(additionalCssClasses);
209 }
210
211 cssClasses = finalCssClasses;
212 }
213
214
215
216
217 @Override
218 public void initializePendingTasks(ViewLifecyclePhase phase, Queue<ViewLifecycleTask<?>> pendingTasks) {
219 }
220
221
222
223
224
225
226 @Override
227 public Class<? extends Container> getSupportedContainer() {
228 return Container.class;
229 }
230
231
232
233
234 @Override
235 @BeanTagAttribute(name = "id")
236 public String getId() {
237 return this.id;
238 }
239
240
241
242
243 @Override
244 public void setId(String id) {
245 checkMutable(true);
246 this.id = id;
247 }
248
249
250
251
252 @Override
253 public String getViewPath() {
254 return this.viewPath;
255 }
256
257
258
259
260 @Override
261 public void setViewPath(String viewPath) {
262 checkMutable(true);
263 this.viewPath = viewPath;
264 }
265
266
267
268
269 @Override
270 public Map<String, String> getPhasePathMapping() {
271 return phasePathMapping;
272 }
273
274
275
276
277 @Override
278 public void setPhasePathMapping(Map<String, String> phasePathMapping) {
279 this.phasePathMapping = phasePathMapping;
280 }
281
282
283
284
285 @Override
286 @BeanTagAttribute(name = "template")
287 public String getTemplate() {
288 return this.template;
289 }
290
291
292
293
294 @Override
295 public void setTemplate(String template) {
296 checkMutable(true);
297 this.template = template;
298 }
299
300
301
302
303 @BeanTagAttribute(name = "tempateName")
304 public String getTemplateName() {
305 return templateName;
306 }
307
308
309
310
311 public void setTemplateName(String templateName) {
312 checkMutable(true);
313 this.templateName = templateName;
314 }
315
316
317
318
319 @Override
320 @BeanTagAttribute(name = "Style")
321 public String getStyle() {
322 return this.style;
323 }
324
325
326
327
328 @Override
329 public void setStyle(String style) {
330 checkMutable(true);
331 this.style = style;
332 }
333
334
335
336
337
338
339
340
341
342
343
344 public List<String> getLibraryCssClasses() {
345 if (libraryCssClasses == Collections.EMPTY_LIST && isMutable(true)) {
346 libraryCssClasses = new LifecycleAwareList<String>(this);
347 }
348
349 return libraryCssClasses;
350 }
351
352
353
354
355
356
357 public void setLibraryCssClasses(List<String> libraryCssClasses) {
358 checkMutable(true);
359
360 if (libraryCssClasses == null) {
361 this.libraryCssClasses = Collections.emptyList();
362 } else {
363 this.libraryCssClasses = new LifecycleAwareList<String>(this, libraryCssClasses);
364 }
365 }
366
367
368
369
370 @BeanTagAttribute(name = "cssClasses", type = BeanTagAttribute.AttributeType.LISTVALUE)
371 public List<String> getCssClasses() {
372 if (cssClasses == Collections.EMPTY_LIST && isMutable(true)) {
373 cssClasses = new LifecycleAwareList<String>(this);
374 }
375
376 return cssClasses;
377 }
378
379
380
381
382 public void setCssClasses(List<String> cssClasses) {
383 checkMutable(true);
384 if (cssClasses == null) {
385 this.cssClasses = Collections.emptyList();
386 } else {
387 this.cssClasses = new LifecycleAwareList<String>(this, cssClasses);
388 }
389 }
390
391
392
393
394 @BeanTagAttribute(name = "additionalCssClasses", type = BeanTagAttribute.AttributeType.LISTVALUE)
395 public List<String> getAdditionalCssClasses() {
396 if (additionalCssClasses == Collections.EMPTY_LIST && isMutable(true)) {
397 additionalCssClasses = new LifecycleAwareList<String>(this);
398 }
399
400 return additionalCssClasses;
401 }
402
403
404
405
406 public void setAdditionalCssClasses(List<String> additionalCssClasses) {
407 checkMutable(true);
408 if (additionalCssClasses == null) {
409 this.additionalCssClasses = Collections.emptyList();
410 } else {
411 this.additionalCssClasses = new LifecycleAwareList<String>(this, additionalCssClasses);
412 }
413 }
414
415
416
417
418
419
420
421 public String getStyleClassesAsString() {
422 if (cssClasses != null) {
423 return StringUtils.join(cssClasses, " ");
424 }
425
426 return "";
427 }
428
429
430
431
432
433
434
435
436
437 public void setStyleClasses(String styleClasses) {
438 checkMutable(true);
439 String[] classes = StringUtils.split(styleClasses);
440 this.cssClasses = Arrays.asList(classes);
441 }
442
443
444
445
446 @Override
447 public void addStyleClass(String styleClass) {
448 checkMutable(false);
449 if (cssClasses == null || cssClasses.isEmpty()) {
450 cssClasses = new ArrayList<String>();
451 }
452
453 if (!cssClasses.contains(styleClass)) {
454 cssClasses.add(styleClass);
455 }
456 }
457
458
459
460
461 @Override
462 public void appendToStyle(String styleRules) {
463 checkMutable(false);
464 if (style == null) {
465 style = "";
466 }
467 style = style + styleRules;
468 }
469
470
471
472
473 @Override
474 @BeanTagAttribute(name = "context", type = BeanTagAttribute.AttributeType.MAPBEAN)
475 public Map<String, Object> getContext() {
476 if (context == Collections.EMPTY_MAP && isMutable(true)) {
477 context = new LifecycleAwareMap<String, Object>(this);
478 }
479
480 return context;
481 }
482
483
484
485
486 @Override
487 public void setContext(Map<String, Object> context) {
488 checkMutable(true);
489
490 if (context == null) {
491 this.context = Collections.emptyMap();
492 } else {
493 this.context = new LifecycleAwareMap<String, Object>(this, context);
494 }
495 }
496
497
498
499
500 @Override
501 public void pushObjectToContext(String objectName, Object object) {
502 checkMutable(false);
503 if (context == Collections.EMPTY_MAP && isMutable(true)) {
504 context = new LifecycleAwareMap<String, Object>(this);
505 }
506
507 context.put(objectName, object);
508 }
509
510
511
512
513 @Override
514 public void pushAllToContext(Map<String, Object> sourceContext) {
515 checkMutable(false);
516 if (sourceContext == null || sourceContext.isEmpty()) {
517 return;
518 }
519
520 if (context == Collections.EMPTY_MAP && isMutable(true)) {
521 context = new LifecycleAwareMap<String, Object>(this);
522 }
523
524 this.context.putAll(sourceContext);
525 }
526
527
528
529
530 @Override
531 @BeanTagAttribute(name = "propertyReplacers", type = BeanTagAttribute.AttributeType.LISTBEAN)
532 public List<PropertyReplacer> getPropertyReplacers() {
533 return this.propertyReplacers;
534 }
535
536
537
538
539 @Override
540 public void setPropertyReplacers(List<PropertyReplacer> propertyReplacers) {
541 checkMutable(true);
542 this.propertyReplacers = propertyReplacers;
543 }
544
545
546
547
548 @Override
549 public boolean skipLifecycle() {
550 return false;
551 }
552
553 @Override
554 public LayoutManagerBase clone() throws CloneNotSupportedException {
555 LayoutManagerBase copy = (LayoutManagerBase) super.clone();
556
557
558
559 if (UifConstants.ViewStatus.INITIALIZED.equals(viewStatus)) {
560 copy.viewStatus = UifConstants.ViewStatus.INITIALIZED;
561 } else {
562 copy.viewStatus = UifConstants.ViewStatus.CREATED;
563 }
564
565 return copy;
566 }
567
568
569
570
571
572
573 @Override
574 public void preventModification() {
575 if (!UifConstants.ViewStatus.CREATED.equals(viewStatus)
576 && !UifConstants.ViewStatus.CACHED.equals(viewStatus)) {
577 ViewLifecycle.reportIllegalState("View status is " + viewStatus + " prior to caching "
578 + getClass().getName() + " " + getId() + ", expected C or X");
579 }
580
581 viewStatus = UifConstants.ViewStatus.CACHED;
582 }
583
584
585
586
587
588
589 public boolean isInitialized() {
590 return StringUtils.equals(viewStatus, ViewStatus.INITIALIZED) || isModelApplied();
591 }
592
593
594
595
596
597
598 public boolean isModelApplied() {
599 return StringUtils.equals(viewStatus, ViewStatus.MODEL_APPLIED) || isFinal();
600 }
601
602
603
604
605
606
607 public boolean isFinal() {
608 return StringUtils.equals(viewStatus, ViewStatus.FINAL);
609 }
610
611 }