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 Object parentContainer = parent.getContext().get("parent");
112
113 if (parentContainer != null && (parentContainer instanceof Container
114 || parentContainer instanceof FieldGroup)) {
115 parentContainerId = ((Component) parentContainer).getId();
116 }
117
118
119 if (parentContainer != null && parentContainer instanceof Message && ((Message) parentContainer)
120 .isGenerateSpan()) {
121 parentContainerId = ((Component) parentContainer).getId();
122 }
123
124
125 this.addDataAttribute(UifConstants.DataAttributes.MESSAGES_FOR, parent.getId());
126
127 if (parent.getDataAttributes().get(UifConstants.DataAttributes.PARENT) == null) {
128 parent.addDataAttribute(UifConstants.DataAttributes.PARENT, parentContainerId);
129 }
130
131
132
133 if (parentContainer != null && parentContainer instanceof FieldGroup) {
134 masterKeyList.add(parentContainerId);
135 }
136
137
138
139 if (parent instanceof PageGroup) {
140 Map<String, PropertyEditor> propertyEditors = view.getViewIndex().getFieldPropertyEditors();
141 Map<String, PropertyEditor> securePropertyEditors = view.getViewIndex().getSecureFieldPropertyEditors();
142 List<String> allPossibleKeys = new ArrayList<String>(propertyEditors.keySet());
143 allPossibleKeys.addAll(securePropertyEditors.keySet());
144
145 this.addNestedGroupKeys(allPossibleKeys, parent);
146 if (additionalKeysToMatch != null) {
147 allPossibleKeys.addAll(additionalKeysToMatch);
148 }
149 if (StringUtils.isNotBlank(parent.getId())) {
150 allPossibleKeys.add(parent.getId());
151 }
152
153 Set<String> messageKeys = new HashSet<String>();
154 messageKeys.addAll(messageMap.getAllPropertiesWithErrors());
155 messageKeys.addAll(messageMap.getAllPropertiesWithWarnings());
156 messageKeys.addAll(messageMap.getAllPropertiesWithInfo());
157
158 messageKeys.removeAll(allPossibleKeys);
159
160 masterKeyList.addAll(messageKeys);
161 }
162
163 for (String key : masterKeyList) {
164 errors.addAll(getMessages(view, key, messageMap.getErrorMessagesForProperty(key, true)));
165 warnings.addAll(getMessages(view, key, messageMap.getWarningMessagesForProperty(key, true)));
166 infos.addAll(getMessages(view, key, messageMap.getInfoMessagesForProperty(key, true)));
167 }
168 }
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183 private List<String> getMessages(View view, String key, List<AutoPopulatingList<ErrorMessage>> lists) {
184 List<String> result = new ArrayList<String>();
185 for (List<ErrorMessage> errorList : lists) {
186 if (errorList != null && StringUtils.isNotBlank(key)) {
187 for (ErrorMessage e : errorList) {
188 String message = KRADUtils.getMessageText(e, true);
189 message = MessageStructureUtils.translateStringMessage(message);
190
191 result.add(message);
192 }
193 }
194 }
195
196 return result;
197 }
198
199
200
201
202
203
204
205
206
207
208 protected List<String> getKeys(Component parent) {
209 List<String> keyList = new ArrayList<String>();
210 if (additionalKeysToMatch != null) {
211 keyList.addAll(additionalKeysToMatch);
212 }
213 if (StringUtils.isNotBlank(parent.getId())) {
214 keyList.add(parent.getId());
215 }
216 if (parent instanceof InputField) {
217 if (((InputField) parent).getBindingInfo() != null && StringUtils.isNotEmpty(
218 ((InputField) parent).getBindingInfo().getBindingPath())) {
219 keyList.add(((InputField) parent).getBindingInfo().getBindingPath());
220 }
221 }
222
223 return keyList;
224 }
225
226
227
228
229
230
231
232
233 private void addNestedGroupKeys(Collection<String> keyList, Component component) {
234 for (Component c : component.getComponentsForLifecycle()) {
235 ValidationMessages ef = null;
236 if (c instanceof ContainerBase) {
237 ef = ((ContainerBase) c).getValidationMessages();
238 } else if (c instanceof FieldGroup) {
239 ef = ((FieldGroup) c).getGroup().getValidationMessages();
240 }
241 if (ef != null) {
242 keyList.addAll(ef.getKeys(c));
243 addNestedGroupKeys(keyList, c);
244 }
245 }
246 }
247
248
249
250
251
252
253
254
255
256 @BeanTagAttribute(name = "additionalKeysToMatch", type = BeanTagAttribute.AttributeType.LISTVALUE)
257 public List<String> getAdditionalKeysToMatch() {
258 return this.additionalKeysToMatch;
259 }
260
261
262
263
264
265
266
267 public void setAdditionalKeysToMatch(String additionalKeysToMatch) {
268 if (StringUtils.isNotBlank(additionalKeysToMatch)) {
269 this.additionalKeysToMatch = Arrays.asList(StringUtils.split(additionalKeysToMatch, ","));
270 }
271 }
272
273
274
275
276 public void setAdditionalKeysToMatch(List<String> additionalKeysToMatch) {
277 this.additionalKeysToMatch = additionalKeysToMatch;
278 }
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293 @BeanTagAttribute(name = "displayMessages")
294 public boolean isDisplayMessages() {
295 return this.displayMessages;
296 }
297
298
299
300
301 public void setDisplayMessages(boolean displayMessages) {
302 this.displayMessages = displayMessages;
303 }
304
305
306
307
308
309
310
311 @BeanTagAttribute(name = "errors", type = BeanTagAttribute.AttributeType.LISTVALUE)
312 public List<String> getErrors() {
313 return this.errors;
314 }
315
316
317
318
319
320
321
322 @BeanTagAttribute(name = "warnings", type = BeanTagAttribute.AttributeType.LISTVALUE)
323 public List<String> getWarnings() {
324 return this.warnings;
325 }
326
327
328
329
330
331
332
333 @BeanTagAttribute(name = "infos", type = BeanTagAttribute.AttributeType.LISTVALUE)
334 public List<String> getInfos() {
335 return this.infos;
336 }
337
338 public Map<String, String> getValidationDataDefaults() {
339 return validationDataDefaults;
340 }
341
342 public void setValidationDataDefaults(Map<String, String> validationDataDefaults) {
343 this.validationDataDefaults = validationDataDefaults;
344 }
345
346 protected void addValidationDataSettingsValue(Map<String, Object> valueMap, Map<String, String> defaults,
347 String key, Object value) {
348 String defaultValue = defaults.get(key);
349 if ((defaultValue != null && !value.toString().equals(defaultValue)) || (defaultValue != null && defaultValue
350 .equals("[]") && value instanceof List && !((List) value).isEmpty()) || defaultValue == null) {
351 valueMap.put(key, value);
352 }
353 }
354
355 public void setErrors(List<String> errors) {
356 this.errors = errors;
357 }
358
359 public void setWarnings(List<String> warnings) {
360 this.warnings = warnings;
361 }
362
363 public void setInfos(List<String> infos) {
364 this.infos = infos;
365 }
366
367
368
369
370 @Override
371 protected <T> void copyProperties(T component) {
372 super.copyProperties(component);
373 ValidationMessages validationMessagesCopy = (ValidationMessages) component;
374
375 if (additionalKeysToMatch != null) {
376 List<String> additionalKeysToMatchCopy = Lists.newArrayListWithExpectedSize(additionalKeysToMatch.size());
377 for(String additionalKeyToMatch : additionalKeysToMatch) {
378 additionalKeysToMatchCopy.add(additionalKeyToMatch);
379 }
380
381 validationMessagesCopy.setAdditionalKeysToMatch(additionalKeysToMatchCopy);
382 }
383
384 validationMessagesCopy.setDisplayMessages(this.isDisplayMessages());
385
386 if (warnings != null) {
387
388 List<String> warningsCopy = Lists.newArrayListWithExpectedSize(warnings.size());
389 for(String warning : warnings) {
390 warningsCopy.add(warning);
391 }
392
393 validationMessagesCopy.setWarnings(warningsCopy);
394 }
395
396 if (errors != null) {
397 List<String> errorsCopy = Lists.newArrayListWithExpectedSize(errors.size());
398 for(String error : errors) {
399 errorsCopy.add(error);
400 }
401
402 validationMessagesCopy.setErrors(errorsCopy);
403 }
404
405 if (infos != null) {
406 List<String> infosCopy = Lists.newArrayListWithExpectedSize(infos.size());
407 for(String info : infos) {
408 infosCopy.add(info);
409 }
410
411 validationMessagesCopy.setInfos(infosCopy);
412 }
413
414 if (this.getValidationDataDefaults() != null) {
415 Map<String, String> validationDataDefaultsCopy = Maps.newHashMapWithExpectedSize(
416 this.getValidationDataDefaults().size());
417 for(Map.Entry validationDataDefault : getValidationDataDefaults().entrySet()) {
418 validationDataDefaultsCopy.put(validationDataDefault.getKey().toString(),validationDataDefault.getValue().toString());
419 }
420
421 validationMessagesCopy.setValidationDataDefaults(validationDataDefaultsCopy);
422 }
423 }
424
425 }