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