1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.modifier;
17
18 import com.google.common.collect.Lists;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.log4j.Logger;
21 import org.kuali.rice.krad.datadictionary.parse.BeanTag;
22 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
23 import org.kuali.rice.krad.datadictionary.parse.BeanTags;
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.container.Group;
28 import org.kuali.rice.krad.uif.element.Header;
29 import org.kuali.rice.krad.uif.field.DataField;
30 import org.kuali.rice.krad.uif.field.Field;
31 import org.kuali.rice.krad.uif.field.SpaceField;
32 import org.kuali.rice.krad.uif.layout.GridLayoutManager;
33 import org.kuali.rice.krad.uif.view.ExpressionEvaluator;
34 import org.kuali.rice.krad.uif.util.ComponentFactory;
35 import org.kuali.rice.krad.uif.util.ComponentUtils;
36 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
37 import org.kuali.rice.krad.uif.view.View;
38
39 import java.util.ArrayList;
40 import java.util.HashMap;
41 import java.util.HashSet;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.Set;
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 @BeanTags({@BeanTag(name = "compareFieldCreate-modifier-bean", parent = "Uif-CompareFieldCreate-Modifier"),
62 @BeanTag(name = "maintenanceCompare-modifier-bean", parent = "Uif-MaintenanceCompare-Modifier")})
63 public class CompareFieldCreateModifier extends ComponentModifierBase {
64 private static final Logger LOG = Logger.getLogger(CompareFieldCreateModifier.class);
65
66 private static final long serialVersionUID = -6285531580512330188L;
67
68 private int defaultOrderSequence;
69 private boolean generateCompareHeaders;
70
71 private Header headerFieldPrototype;
72 private List<ComparableInfo> comparables;
73
74 public CompareFieldCreateModifier() {
75 defaultOrderSequence = 1;
76 generateCompareHeaders = true;
77
78 comparables = new ArrayList<ComparableInfo>();
79 }
80
81
82
83
84
85
86
87 @Override
88 public void performInitialization(View view, Object model, Component component) {
89 super.performInitialization(view, model, component);
90
91 if (headerFieldPrototype != null) {
92 view.getViewHelperService().performComponentInitialization(view, model, headerFieldPrototype);
93 }
94 }
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 @SuppressWarnings("unchecked")
114 @Override
115 public void performModification(View view, Object model, Component component) {
116 if ((component != null) && !(component instanceof Group)) {
117 throw new IllegalArgumentException(
118 "Compare field initializer only support Group components, found type: " + component.getClass());
119 }
120
121 if (component == null) {
122 return;
123 }
124
125 Group group = (Group) component;
126
127
128 List<Component> comparisonItems = new ArrayList<Component>();
129
130
131 List<ComparableInfo> groupComparables = (List<ComparableInfo>) ComponentUtils.sort(comparables,
132 defaultOrderSequence);
133
134
135 Map<String, Object> context = new HashMap<String, Object>();
136
137 Map<String, Object> viewContext = view.getContext();
138 if (viewContext != null) {
139 context.putAll(view.getContext());
140 }
141
142 context.put(UifConstants.ContextVariableNames.COMPONENT, component);
143
144 ExpressionEvaluator expressionEvaluator =
145 view.getViewHelperService().getExpressionEvaluator();
146
147 for (ComparableInfo comparable : groupComparables) {
148 expressionEvaluator.evaluateExpressionsOnConfigurable(view, comparable, context);
149 }
150
151
152 if (isGenerateCompareHeaders()) {
153
154 SpaceField spaceField = ComponentFactory.getSpaceField();
155 view.assignComponentIds(spaceField);
156
157 comparisonItems.add(spaceField);
158
159 for (ComparableInfo comparable : groupComparables) {
160 Header compareHeaderField = ComponentUtils.copy(headerFieldPrototype, comparable.getIdSuffix());
161 compareHeaderField.setHeaderText(comparable.getHeaderText());
162
163 comparisonItems.add(compareHeaderField);
164 }
165
166
167 if (group.getLayoutManager() instanceof GridLayoutManager) {
168 ((GridLayoutManager) group.getLayoutManager()).setRenderFirstRowHeader(true);
169 }
170 }
171
172
173
174 boolean performValueChangeComparison = false;
175 String compareValueObjectBindingPath = null;
176 for (ComparableInfo comparable : groupComparables) {
177 if (comparable.isCompareToForValueChange()) {
178 performValueChangeComparison = true;
179 compareValueObjectBindingPath = comparable.getBindingObjectPath();
180 }
181 }
182
183
184 boolean changeIconShowedOnHeader = false;
185 for (Component item : group.getItems()) {
186 int defaultSuffix = 0;
187 boolean suppressLabel = false;
188
189 for (ComparableInfo comparable : groupComparables) {
190 String idSuffix = comparable.getIdSuffix();
191 if (StringUtils.isBlank(idSuffix)) {
192 idSuffix = UifConstants.IdSuffixes.COMPARE + defaultSuffix;
193 }
194
195 Component compareItem = ComponentUtils.copy(item, idSuffix);
196
197 ComponentUtils.setComponentPropertyDeep(compareItem, UifPropertyPaths.BIND_OBJECT_PATH,
198 comparable.getBindingObjectPath());
199 if (comparable.isReadOnly()) {
200 compareItem.setReadOnly(true);
201 if (compareItem.getPropertyExpressions().containsKey("readOnly")) {
202 compareItem.getPropertyExpressions().remove("readOnly");
203 }
204 }
205
206
207 if (suppressLabel && (compareItem instanceof Field)) {
208 ((Field) compareItem).getFieldLabel().setRender(false);
209 }
210
211
212 if (performValueChangeComparison && comparable.isHighlightValueChange() && !comparable
213 .isCompareToForValueChange()) {
214 boolean valueChanged = performValueComparison(group, compareItem, model,
215 compareValueObjectBindingPath);
216
217
218 if (valueChanged && !changeIconShowedOnHeader && isGenerateCompareHeaders()) {
219 Group groupToSetHeader = null;
220 if (group.getDisclosure() != null && group.getDisclosure().isRender()) {
221 groupToSetHeader = group;
222 } else if (group.getContext().get(UifConstants.ContextVariableNames.PARENT) != null) {
223
224 groupToSetHeader = (Group) group.getContext().get(UifConstants.ContextVariableNames.PARENT);
225 }
226
227 if (groupToSetHeader.getDisclosure().isRender()) {
228 groupToSetHeader.getDisclosure().setOnDocumentReadyScript(
229 "showChangeIconOnDisclosure('" + groupToSetHeader.getId() + "');");
230 } else if (groupToSetHeader.getHeader() != null) {
231 groupToSetHeader.getHeader().setOnDocumentReadyScript(
232 "showChangeIconOnHeader('" + groupToSetHeader.getHeader().getId() + "');");
233 }
234
235 changeIconShowedOnHeader = true;
236 }
237 }
238
239 comparisonItems.add(compareItem);
240 defaultSuffix++;
241
242 suppressLabel = true;
243 }
244 }
245
246
247 group.setItems(comparisonItems);
248 }
249
250
251
252
253
254
255
256
257
258
259
260
261
262 protected boolean performValueComparison(Group group, Component compareItem, Object model,
263 String compareValueObjectBindingPath) {
264
265 List<DataField> itemFields = ComponentUtils.getComponentsOfTypeDeep(compareItem, DataField.class);
266 boolean valueChanged = false;
267 for (DataField field : itemFields) {
268 String fieldBindingPath = field.getBindingInfo().getBindingPath();
269 Object fieldValue = ObjectPropertyUtils.getPropertyValue(model, fieldBindingPath);
270
271 String compareBindingPath = StringUtils.replaceOnce(fieldBindingPath,
272 field.getBindingInfo().getBindingObjectPath(), compareValueObjectBindingPath);
273 Object compareValue = ObjectPropertyUtils.getPropertyValue(model, compareBindingPath);
274
275 if (!((fieldValue == null) && (compareValue == null))) {
276
277 if ((fieldValue == null) || (compareValue == null)) {
278 valueChanged = true;
279 } else {
280
281 valueChanged = !fieldValue.equals(compareValue);
282 }
283 }
284 if (valueChanged) {
285
286 String onReadyScript = "showChangeIcon('" + field.getId() + "');";
287 field.setOnDocumentReadyScript(onReadyScript);
288 }
289
290 }
291 return valueChanged;
292 }
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308 protected String getIdSuffix(ComparableInfo comparable, int index) {
309 String idSuffix = comparable.getIdSuffix();
310 if (StringUtils.isBlank(idSuffix)) {
311 idSuffix = "_" + index;
312 }
313
314 return idSuffix;
315 }
316
317
318
319
320 @Override
321 public Set<Class<? extends Component>> getSupportedComponents() {
322 Set<Class<? extends Component>> components = new HashSet<Class<? extends Component>>();
323 components.add(Group.class);
324
325 return components;
326 }
327
328
329
330
331 public List<Component> getComponentPrototypes() {
332 List<Component> components = new ArrayList<Component>();
333
334 components.add(headerFieldPrototype);
335
336 return components;
337 }
338
339
340
341
342
343
344
345
346 @BeanTagAttribute(name = "defaultOrderSequence")
347 public int getDefaultOrderSequence() {
348 return this.defaultOrderSequence;
349 }
350
351
352
353
354
355
356 public void setDefaultOrderSequence(int defaultOrderSequence) {
357 this.defaultOrderSequence = defaultOrderSequence;
358 }
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373 @BeanTagAttribute(name = "generateCompareHeaders")
374 public boolean isGenerateCompareHeaders() {
375 return this.generateCompareHeaders;
376 }
377
378
379
380
381
382
383 public void setGenerateCompareHeaders(boolean generateCompareHeaders) {
384 this.generateCompareHeaders = generateCompareHeaders;
385 }
386
387
388
389
390
391
392
393 @BeanTagAttribute(name = "headerFieldPrototype", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
394 public Header getHeaderFieldPrototype() {
395 return this.headerFieldPrototype;
396 }
397
398
399
400
401
402
403 public void setHeaderFieldPrototype(Header headerFieldPrototype) {
404 this.headerFieldPrototype = headerFieldPrototype;
405 }
406
407
408
409
410
411
412
413
414
415
416
417
418 @BeanTagAttribute(name = "comparables", type = BeanTagAttribute.AttributeType.LISTBEAN)
419 public List<ComparableInfo> getComparables() {
420 return this.comparables;
421 }
422
423
424
425
426
427
428 public void setComparables(List<ComparableInfo> comparables) {
429 this.comparables = comparables;
430 }
431
432
433
434
435
436 @Override
437 protected <T> void copyProperties(T componentModifier) {
438 super.copyProperties(componentModifier);
439 CompareFieldCreateModifier compareFieldCreateModifierCopy = (CompareFieldCreateModifier) componentModifier;
440 compareFieldCreateModifierCopy.setDefaultOrderSequence(this.defaultOrderSequence);
441 compareFieldCreateModifierCopy.setGenerateCompareHeaders(this.generateCompareHeaders);
442
443 if(comparables != null) {
444 List<ComparableInfo> comparables = Lists.newArrayListWithExpectedSize(getComparables().size());
445 for (ComparableInfo comparable : this.comparables) {
446 comparables.add((ComparableInfo)comparable.copy());
447 }
448 compareFieldCreateModifierCopy.setComparables(comparables);
449 }
450
451 if (this.headerFieldPrototype != null) {
452 compareFieldCreateModifierCopy.setHeaderFieldPrototype((Header)this.headerFieldPrototype.copy());
453 }
454 }
455 }