1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.element;
17
18 import com.google.common.collect.Lists;
19 import com.google.common.collect.Maps;
20 import org.apache.commons.lang.StringUtils;
21 import org.kuali.rice.krad.datadictionary.parse.BeanTag;
22 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
23 import org.kuali.rice.krad.uif.UifConstants;
24 import org.kuali.rice.krad.uif.component.Component;
25 import org.kuali.rice.krad.uif.container.Container;
26 import org.kuali.rice.krad.uif.container.ContainerBase;
27 import org.kuali.rice.krad.uif.container.PageGroup;
28 import org.kuali.rice.krad.uif.field.FieldGroup;
29 import org.kuali.rice.krad.uif.field.InputField;
30 import org.kuali.rice.krad.uif.util.MessageStructureUtils;
31 import org.kuali.rice.krad.uif.view.View;
32 import org.kuali.rice.krad.util.ErrorMessage;
33 import org.kuali.rice.krad.util.GlobalVariables;
34 import org.kuali.rice.krad.util.KRADUtils;
35 import org.kuali.rice.krad.util.MessageMap;
36 import org.springframework.util.AutoPopulatingList;
37
38 import java.beans.PropertyEditor;
39 import java.util.ArrayList;
40 import java.util.Arrays;
41 import java.util.Collection;
42 import java.util.HashSet;
43 import java.util.List;
44 import java.util.Map;
45 import java.util.Set;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 @BeanTag(name = "validationMessages-bean", parent = "Uif-ValidationMessagesBase")
61 public class ValidationMessages extends ContentElementBase {
62 private static final long serialVersionUID = 780940788435330077L;
63
64 private List<String> additionalKeysToMatch;
65
66 private boolean displayMessages;
67
68
69 private List<String> errors;
70 private List<String> warnings;
71 private List<String> infos;
72
73 private Map<String, String> validationDataDefaults;
74
75
76
77
78
79
80
81
82
83
84
85 @Override
86 public void performFinalize(View view, Object model, Component parent) {
87 super.performFinalize(view, model, parent);
88
89 generateMessages(true, view, model, parent);
90 }
91
92
93
94
95
96
97
98
99
100 public void generateMessages(boolean reset, View view, Object model, Component parent) {
101 if (reset) {
102 errors = new ArrayList<String>();
103 warnings = new ArrayList<String>();
104 infos = new ArrayList<String>();
105 }
106
107 List<String> masterKeyList = getKeys(parent);
108 MessageMap messageMap = GlobalVariables.getMessageMap();
109
110 String parentContainerId = "";
111
112 Map<String, Object> parentContext = parent.getContext();
113 Object parentContainer = parentContext == null ? null : parentContext
114 .get(UifConstants.ContextVariableNames.PARENT);
115
116 if (parentContainer != null && (parentContainer instanceof Container
117 || parentContainer instanceof FieldGroup)) {
118 parentContainerId = ((Component) parentContainer).getId();
119 }
120
121
122 if (parentContainer != null && parentContainer instanceof Message && ((Message) parentContainer)
123 .isGenerateSpan()) {
124 parentContainerId = ((Component) parentContainer).getId();
125 }
126
127
128 if (parentContainer != null && parentContainer instanceof Component && StringUtils.isBlank(parentContainerId)) {
129 parentContainer = ((Component) parentContainer).getContext().get("parent");
130 if (parentContainer != null && (parentContainer instanceof Container
131 || parentContainer instanceof FieldGroup)) {
132 parentContainerId = ((Component) parentContainer).getId();
133 }
134 }
135
136
137 this.addDataAttribute(UifConstants.DataAttributes.MESSAGES_FOR, parent.getId());
138
139 if ((parent.getDataAttributes() == null) || (parent.getDataAttributes().get(UifConstants.DataAttributes.PARENT)
140 == null)) {
141 parent.addDataAttribute(UifConstants.DataAttributes.PARENT, parentContainerId);
142 }
143
144
145
146 if (parentContainer != null && parentContainer instanceof FieldGroup) {
147 masterKeyList.add(parentContainerId);
148 }
149
150
151
152 if (parent instanceof PageGroup) {
153 Map<String, PropertyEditor> propertyEditors = view.getViewIndex().getFieldPropertyEditors();
154 Map<String, PropertyEditor> securePropertyEditors = view.getViewIndex().getSecureFieldPropertyEditors();
155 List<String> allPossibleKeys = new ArrayList<String>(propertyEditors.keySet());
156 allPossibleKeys.addAll(securePropertyEditors.keySet());
157
158 this.addNestedGroupKeys(allPossibleKeys, parent);
159 if (additionalKeysToMatch != null) {
160 allPossibleKeys.addAll(additionalKeysToMatch);
161 }
162 if (StringUtils.isNotBlank(parent.getId())) {
163 allPossibleKeys.add(parent.getId());
164 }
165
166 Set<String> messageKeys = new HashSet<String>();
167 messageKeys.addAll(messageMap.getAllPropertiesWithErrors());
168 messageKeys.addAll(messageMap.getAllPropertiesWithWarnings());
169 messageKeys.addAll(messageMap.getAllPropertiesWithInfo());
170
171 messageKeys.removeAll(allPossibleKeys);
172
173 masterKeyList.addAll(messageKeys);
174 }
175
176 for (String key : masterKeyList) {
177 errors.addAll(getMessages(view, key, messageMap.getErrorMessagesForProperty(key, true)));
178 warnings.addAll(getMessages(view, key, messageMap.getWarningMessagesForProperty(key, true)));
179 infos.addAll(getMessages(view, key, messageMap.getInfoMessagesForProperty(key, true)));
180 }
181 }
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196 private List<String> getMessages(View view, String key, List<AutoPopulatingList<ErrorMessage>> lists) {
197 List<String> result = new ArrayList<String>();
198 for (List<ErrorMessage> errorList : lists) {
199 if (errorList != null && StringUtils.isNotBlank(key)) {
200 for (ErrorMessage e : errorList) {
201 String message = KRADUtils.getMessageText(e, true);
202 message = MessageStructureUtils.translateStringMessage(message);
203
204 result.add(message);
205 }
206 }
207 }
208
209 return result;
210 }
211
212
213
214
215
216
217
218
219
220
221 protected List<String> getKeys(Component parent) {
222 List<String> keyList = new ArrayList<String>();
223 if (additionalKeysToMatch != null) {
224 keyList.addAll(additionalKeysToMatch);
225 }
226 if (StringUtils.isNotBlank(parent.getId())) {
227 keyList.add(parent.getId());
228 }
229 if (parent instanceof InputField) {
230 if (((InputField) parent).getBindingInfo() != null && StringUtils.isNotEmpty(
231 ((InputField) parent).getBindingInfo().getBindingPath())) {
232 keyList.add(((InputField) parent).getBindingInfo().getBindingPath());
233 }
234 }
235
236 return keyList;
237 }
238
239
240
241
242
243
244
245
246 private void addNestedGroupKeys(Collection<String> keyList, Component component) {
247 for (Component c : component.getComponentsForLifecycle()) {
248 ValidationMessages ef = null;
249 if (c instanceof ContainerBase) {
250 ef = ((ContainerBase) c).getValidationMessages();
251 } else if (c instanceof FieldGroup) {
252 ef = ((FieldGroup) c).getGroup().getValidationMessages();
253 }
254 if (ef != null) {
255 keyList.addAll(ef.getKeys(c));
256 addNestedGroupKeys(keyList, c);
257 }
258 }
259 }
260
261
262
263
264
265
266
267
268
269 @BeanTagAttribute(name = "additionalKeysToMatch", type = BeanTagAttribute.AttributeType.LISTVALUE)
270 public List<String> getAdditionalKeysToMatch() {
271 return this.additionalKeysToMatch;
272 }
273
274
275
276
277
278
279
280 public void setAdditionalKeysToMatch(String additionalKeysToMatch) {
281 if (StringUtils.isNotBlank(additionalKeysToMatch)) {
282 this.additionalKeysToMatch = Arrays.asList(StringUtils.split(additionalKeysToMatch, ","));
283 }
284 }
285
286
287
288
289 public void setAdditionalKeysToMatch(List<String> additionalKeysToMatch) {
290 this.additionalKeysToMatch = additionalKeysToMatch;
291 }
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306 @BeanTagAttribute(name = "displayMessages")
307 public boolean isDisplayMessages() {
308 return this.displayMessages;
309 }
310
311
312
313
314 public void setDisplayMessages(boolean displayMessages) {
315 this.displayMessages = displayMessages;
316 }
317
318
319
320
321
322
323
324 @BeanTagAttribute(name = "errors", type = BeanTagAttribute.AttributeType.LISTVALUE)
325 public List<String> getErrors() {
326 return this.errors;
327 }
328
329
330
331
332
333
334
335 @BeanTagAttribute(name = "warnings", type = BeanTagAttribute.AttributeType.LISTVALUE)
336 public List<String> getWarnings() {
337 return this.warnings;
338 }
339
340
341
342
343
344
345
346 @BeanTagAttribute(name = "infos", type = BeanTagAttribute.AttributeType.LISTVALUE)
347 public List<String> getInfos() {
348 return this.infos;
349 }
350
351 public Map<String, String> getValidationDataDefaults() {
352 return validationDataDefaults;
353 }
354
355 public void setValidationDataDefaults(Map<String, String> validationDataDefaults) {
356 this.validationDataDefaults = validationDataDefaults;
357 }
358
359 protected void addValidationDataSettingsValue(Map<String, Object> valueMap, Map<String, String> defaults,
360 String key, Object value) {
361 String defaultValue = defaults.get(key);
362 if ((defaultValue != null && !value.toString().equals(defaultValue)) || (defaultValue != null && defaultValue
363 .equals("[]") && value instanceof List && !((List) value).isEmpty()) || defaultValue == null) {
364 valueMap.put(key, value);
365 }
366 }
367
368
369
370
371
372
373 protected void setErrors(List<String> errors) {
374 this.errors = errors;
375 }
376
377
378
379
380
381
382 protected void setWarnings(List<String> warnings) {
383 this.warnings = warnings;
384 }
385
386
387
388
389
390
391 protected void setInfos(List<String> infos) {
392 this.infos = infos;
393 }
394
395
396
397
398 @Override
399 protected <T> void copyProperties(T component) {
400 super.copyProperties(component);
401 ValidationMessages validationMessagesCopy = (ValidationMessages) component;
402
403 if (additionalKeysToMatch != null) {
404 List<String> additionalKeysToMatchCopy = Lists.newArrayListWithExpectedSize(additionalKeysToMatch.size());
405 for (String additionalKeyToMatch : additionalKeysToMatch) {
406 additionalKeysToMatchCopy.add(additionalKeyToMatch);
407 }
408
409 validationMessagesCopy.setAdditionalKeysToMatch(additionalKeysToMatchCopy);
410 }
411
412 validationMessagesCopy.setDisplayMessages(this.displayMessages);
413
414 if (warnings != null) {
415
416 List<String> warningsCopy = Lists.newArrayListWithExpectedSize(warnings.size());
417 for (String warning : warnings) {
418 warningsCopy.add(warning);
419 }
420
421 validationMessagesCopy.setWarnings(warningsCopy);
422 }
423
424 if (errors != null) {
425 List<String> errorsCopy = Lists.newArrayListWithExpectedSize(errors.size());
426 for (String error : errors) {
427 errorsCopy.add(error);
428 }
429
430 validationMessagesCopy.setErrors(errorsCopy);
431 }
432
433 if (infos != null) {
434 List<String> infosCopy = Lists.newArrayListWithExpectedSize(infos.size());
435 for (String info : infos) {
436 infosCopy.add(info);
437 }
438
439 validationMessagesCopy.setInfos(infosCopy);
440 }
441
442 if (this.validationDataDefaults != null) {
443 Map<String, String> validationDataDefaultsCopy = Maps.newHashMapWithExpectedSize(
444 this.validationDataDefaults.size());
445 for (Map.Entry validationDataDefault : validationDataDefaults.entrySet()) {
446 validationDataDefaultsCopy.put(validationDataDefault.getKey().toString(),
447 validationDataDefault.getValue().toString());
448 }
449
450 validationMessagesCopy.setValidationDataDefaults(validationDataDefaultsCopy);
451 }
452 }
453
454 }