1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.util;
17
18 import org.apache.commons.lang.StringEscapeUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.commons.lang.builder.EqualsBuilder;
21 import org.apache.commons.lang.builder.HashCodeBuilder;
22 import org.apache.commons.lang.builder.ToStringBuilder;
23 import org.springframework.util.AutoPopulatingList;
24
25 import java.io.Serializable;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.Iterator;
29 import java.util.LinkedHashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Set;
33
34
35
36
37
38
39
40
41
42
43
44
45 public class MessageMap implements Serializable {
46 private static final long serialVersionUID = -2328635367656516150L;
47
48 private final List<String> errorPath;
49
50 private final Map<String, List<ErrorMessage>> errorMessages;
51 private final Map<String, List<ErrorMessage>> warningMessages;
52 private final Map<String, List<ErrorMessage>> infoMessages;
53 private final List<GrowlMessage> growlMessages;
54
55 public MessageMap() {
56 errorPath = Collections.synchronizedList(new ArrayList<String>());
57 errorMessages = Collections.synchronizedMap(new LinkedHashMap<String, List<ErrorMessage>>());
58 warningMessages = Collections.synchronizedMap(new LinkedHashMap<String, List<ErrorMessage>>());
59 infoMessages = Collections.synchronizedMap(new LinkedHashMap<String, List<ErrorMessage>>());
60 growlMessages = Collections.synchronizedList(new AutoPopulatingList<GrowlMessage>(GrowlMessage.class));
61 }
62
63 public MessageMap(MessageMap messageMap) {
64 this.errorPath = messageMap.errorPath;
65 this.errorMessages = messageMap.errorMessages;
66 this.warningMessages = messageMap.warningMessages;
67 this.infoMessages = messageMap.infoMessages;
68
69 growlMessages = Collections.synchronizedList(new AutoPopulatingList<GrowlMessage>(GrowlMessage.class));
70 }
71
72 public void merge(MessageMap messageMap) {
73 if (messageMap != null) {
74 if (messageMap.hasErrors()) {
75 merge(messageMap.getErrorMessages(), errorMessages);
76 }
77 if (messageMap.hasInfo()) {
78 merge(messageMap.getInfoMessages(), infoMessages);
79 }
80 if (messageMap.hasWarnings()) {
81 merge(messageMap.getWarningMessages(), warningMessages);
82 }
83 if (messageMap.getGrowlMessages() != null) {
84 growlMessages.addAll(messageMap.getGrowlMessages());
85 }
86 }
87
88 }
89
90
91
92
93
94
95
96
97 public void merge(Map<String, List<ErrorMessage>> messagesFrom,
98 Map<String, List<ErrorMessage>> messagesTo) {
99 for (String key : messagesFrom.keySet()) {
100
101 if (messagesTo.containsKey(key)) {
102
103 List<ErrorMessage> tal = messagesFrom.get(key);
104 List<ErrorMessage> parentList = messagesTo.get(key);
105
106 for (Object o : tal) {
107
108 if (!parentList.contains(o)) {
109 parentList.add((ErrorMessage) o);
110 }
111 }
112
113 } else {
114 messagesTo.put(key, messagesFrom.get(key));
115 }
116
117 }
118 }
119
120 public List<ErrorMessage> putError(String propertyName, String errorKey, String... errorParameters) {
121 ErrorMessage message = new ErrorMessage(errorKey, errorParameters);
122 return putMessageInMap(errorMessages, propertyName, message, true, true);
123 }
124
125 public List<ErrorMessage> putWarning(String propertyName, String messageKey,
126 String... messageParameters) {
127 ErrorMessage message = new ErrorMessage(messageKey, messageParameters);
128 return putMessageInMap(warningMessages, propertyName, message, true, true);
129 }
130
131 public List<ErrorMessage> putInfo(String propertyName, String messageKey,
132 String... messageParameters) {
133 ErrorMessage message = new ErrorMessage(messageKey, messageParameters);
134 return putMessageInMap(infoMessages, propertyName, message, true, true);
135 }
136
137 public List<ErrorMessage> putError(String propertyName, ErrorMessage message) {
138 return putMessageInMap(errorMessages, propertyName, message, true, true);
139 }
140
141 public List<ErrorMessage> putWarning(String propertyName, ErrorMessage message) {
142 return putMessageInMap(warningMessages, propertyName, message, true, true);
143 }
144
145 public List<ErrorMessage> putInfo(String propertyName, ErrorMessage message) {
146 return putMessageInMap(infoMessages, propertyName, message, true, true);
147 }
148
149 public List<ErrorMessage> putErrorWithoutFullErrorPath(String propertyName, String errorKey,
150 String... errorParameters) {
151 ErrorMessage message = new ErrorMessage(errorKey, errorParameters);
152 return putMessageInMap(errorMessages, propertyName, message, false, true);
153 }
154
155 public List<ErrorMessage> putWarningWithoutFullErrorPath(String propertyName, String messageKey,
156 String... messageParameters) {
157 ErrorMessage message = new ErrorMessage(messageKey, messageParameters);
158 return putMessageInMap(warningMessages, propertyName, message, false, true);
159 }
160
161 public List<ErrorMessage> putInfoWithoutFullErrorPath(String propertyName, String messageKey,
162 String... messageParameters) {
163 ErrorMessage message = new ErrorMessage(messageKey, messageParameters);
164 return putMessageInMap(infoMessages, propertyName, message, false, true);
165 }
166
167 public List<ErrorMessage> putErrorWithoutFullErrorPath(String propertyName, ErrorMessage message) {
168 return putMessageInMap(errorMessages, propertyName, message, false, true);
169 }
170
171 public List<ErrorMessage> putWarningWithoutFullErrorPath(String propertyName, ErrorMessage message) {
172 return putMessageInMap(warningMessages, propertyName, message, false, true);
173 }
174
175 public List<ErrorMessage> putInfoWithoutFullErrorPath(String propertyName, ErrorMessage message) {
176 return putMessageInMap(infoMessages, propertyName, message, false, true);
177 }
178
179 public List<ErrorMessage> putErrorForSectionId(String sectionId, String errorKey,
180 String... errorParameters) {
181 return putErrorWithoutFullErrorPath(sectionId, errorKey, errorParameters);
182 }
183
184 public List<ErrorMessage> putWarningForSectionId(String sectionId, String messageKey,
185 String... messageParameters) {
186 return putWarningWithoutFullErrorPath(sectionId, messageKey, messageParameters);
187 }
188
189 public List<ErrorMessage> putInfoForSectionId(String sectionId, String messageKey,
190 String... messageParameters) {
191 return putInfoWithoutFullErrorPath(sectionId, messageKey, messageParameters);
192 }
193
194 public List<ErrorMessage> putErrorForSectionId(String sectionId, ErrorMessage message) {
195 return putErrorWithoutFullErrorPath(sectionId, message);
196 }
197
198 public List<ErrorMessage> putWarningForSectionId(String sectionId, ErrorMessage message) {
199 return putWarningWithoutFullErrorPath(sectionId, message);
200 }
201
202 public List<ErrorMessage> putInfoForSectionId(String sectionId, ErrorMessage message) {
203 return putInfoWithoutFullErrorPath(sectionId, message);
204 }
205
206
207
208
209
210
211
212
213
214
215 public List<ErrorMessage> putError(String propertyName, String errorKey, Boolean escapeHtmlMessageParameters, String... errorParameters) {
216 ErrorMessage message = new ErrorMessage(errorKey, errorParameters);
217 return putMessageInMap(errorMessages, propertyName, message, true, escapeHtmlMessageParameters);
218 }
219
220
221
222
223
224
225
226
227
228
229 public List<ErrorMessage> putWarning(String propertyName, String messageKey, Boolean escapeHtmlMessageParameters,
230 String... messageParameters) {
231 ErrorMessage message = new ErrorMessage(messageKey, messageParameters);
232 return putMessageInMap(warningMessages, propertyName, message, true, escapeHtmlMessageParameters);
233 }
234
235
236
237
238
239
240
241
242
243
244 public List<ErrorMessage> putInfo(String propertyName, String messageKey, Boolean escapeHtmlMessageParameters,
245 String... messageParameters) {
246 ErrorMessage message = new ErrorMessage(messageKey, messageParameters);
247 return putMessageInMap(infoMessages, propertyName, message, true, escapeHtmlMessageParameters);
248 }
249
250
251
252
253
254
255
256
257 public void addGrowlMessage(String growlTitle, String messageKey, String... messageParameters) {
258 GrowlMessage growl = new GrowlMessage();
259
260 growl.setTitle(growlTitle);
261 growl.setMessageKey(messageKey);
262 growl.setMessageParameters(messageParameters);
263
264 growlMessages.add(growl);
265 }
266
267
268
269
270
271
272 public void addGrowlMessage(GrowlMessage growl) {
273 growlMessages.add(growl);
274 }
275
276
277
278
279
280
281
282
283
284
285
286
287 protected List<ErrorMessage> putMessageInMap(Map<String, List<ErrorMessage>> messagesMap,
288 String propertyName, ErrorMessage errorMessage, boolean prependFullErrorPath,
289 boolean escapeHtmlMessageParameters) {
290 if (StringUtils.isBlank(propertyName)) {
291 throw new IllegalArgumentException("invalid (blank) propertyName");
292 }
293 if (StringUtils.isBlank(errorMessage.getErrorKey())) {
294 throw new IllegalArgumentException("invalid (blank) errorKey");
295 }
296
297
298 List<ErrorMessage> errorList = null;
299 String propertyKey = getKeyPath(propertyName, prependFullErrorPath);
300 if (messagesMap.containsKey(propertyKey)) {
301 errorList = messagesMap.get(propertyKey);
302 } else {
303 errorList = Collections.synchronizedList(new AutoPopulatingList<ErrorMessage>(ErrorMessage.class));
304 }
305
306 if (escapeHtmlMessageParameters) {
307 if (errorMessage.getMessageParameters() != null) {
308 String[] filteredMessageParameters = new String[errorMessage.getMessageParameters().length];
309 for (int i = 0; i < errorMessage.getMessageParameters().length; i++) {
310 filteredMessageParameters[i] = StringEscapeUtils.escapeHtml(errorMessage.getMessageParameters()[i]);
311 }
312 errorMessage.setMessageParameters(filteredMessageParameters);
313 }
314
315 if (errorMessage.getMessagePrefixParameters() != null) {
316 String[] filteredMessageParameters = new String[errorMessage.getMessagePrefixParameters().length];
317 for (int i = 0; i < errorMessage.getMessagePrefixParameters().length; i++) {
318 filteredMessageParameters[i] = StringEscapeUtils.escapeHtml(
319 errorMessage.getMessagePrefixParameters()[i]);
320 }
321 errorMessage.setMessagePrefixParameters(filteredMessageParameters);
322 }
323
324 if (errorMessage.getMessageSuffixParameters() != null) {
325 String[] filteredMessageParameters = new String[errorMessage.getMessageSuffixParameters().length];
326 for (int i = 0; i < errorMessage.getMessageSuffixParameters().length; i++) {
327 filteredMessageParameters[i] = StringEscapeUtils.escapeHtml(
328 errorMessage.getMessageSuffixParameters()[i]);
329 }
330 errorMessage.setMessageSuffixParameters(filteredMessageParameters);
331 }
332 }
333
334
335 boolean alreadyAdded = false;
336 for (ErrorMessage e : errorList) {
337 if (e.equals(errorMessage)) {
338 alreadyAdded = true;
339 break;
340 }
341 }
342 if (!alreadyAdded) {
343 errorList.add(errorMessage);
344 }
345
346 return messagesMap.put(propertyKey, errorList);
347 }
348
349
350
351
352
353
354
355
356
357
358
359 public boolean replaceError(String propertyName, String targetKey, String replaceKey, String... replaceParameters) {
360 return replaceError(propertyName, targetKey, true, replaceKey, replaceParameters);
361 }
362
363
364
365
366
367
368
369
370
371
372
373
374 public boolean replaceErrorWithoutFullErrorPath(String propertyName, String targetKey, String replaceKey,
375 String... replaceParameters) {
376 return replaceError(propertyName, targetKey, false, replaceKey, replaceParameters);
377 }
378
379
380
381
382
383
384
385
386
387
388
389 private boolean replaceError(String propertyName, String targetKey, boolean withFullErrorPath, String replaceKey,
390 String... replaceParameters) {
391 boolean replaced = false;
392
393 if (StringUtils.isBlank(propertyName)) {
394 throw new IllegalArgumentException("invalid (blank) propertyName");
395 }
396 if (StringUtils.isBlank(targetKey)) {
397 throw new IllegalArgumentException("invalid (blank) targetKey");
398 }
399 if (StringUtils.isBlank(replaceKey)) {
400 throw new IllegalArgumentException("invalid (blank) replaceKey");
401 }
402
403
404 List<ErrorMessage> errorList = null;
405 String propertyKey = getKeyPath(propertyName, withFullErrorPath);
406 if (errorMessages.containsKey(propertyKey)) {
407 errorList = errorMessages.get(propertyKey);
408
409
410 for (int i = 0; i < errorList.size(); ++i) {
411 ErrorMessage em = errorList.get(i);
412
413
414 if (em.getErrorKey().equals(targetKey)) {
415 ErrorMessage rm = new ErrorMessage(replaceKey, replaceParameters);
416 errorList.set(i, rm);
417 replaced = true;
418 }
419 }
420 }
421
422 return replaced;
423 }
424
425
426
427
428
429
430
431
432 public boolean fieldHasMessage(String fieldName, String errorKey) {
433 boolean found = false;
434
435 List<ErrorMessage> fieldMessages = errorMessages.get(fieldName);
436 if (fieldMessages != null) {
437 for (Iterator<ErrorMessage> i = fieldMessages.iterator(); !found && i.hasNext(); ) {
438 ErrorMessage errorMessage = i.next();
439 found = errorMessage.getErrorKey().equals(errorKey);
440 }
441 }
442
443 return found;
444 }
445
446
447
448
449
450
451
452 public int countFieldMessages(String fieldName) {
453 int count = 0;
454
455 List<ErrorMessage> fieldMessages = errorMessages.get(fieldName);
456 if (fieldMessages != null) {
457 count = fieldMessages.size();
458 }
459
460 return count;
461 }
462
463
464
465
466 public boolean containsMessageKey(String messageKey) {
467 ErrorMessage foundMessage = null;
468
469 if (!hasNoErrors()) {
470 for (Iterator<Map.Entry<String, List<ErrorMessage>>> i =
471 getAllPropertiesAndErrors().iterator(); (foundMessage == null) && i.hasNext(); ) {
472 Map.Entry<String, List<ErrorMessage>> e = i.next();
473 List<ErrorMessage> entryErrorList = e.getValue();
474 for (Iterator<ErrorMessage> j = entryErrorList.iterator(); j.hasNext(); ) {
475 ErrorMessage em = j.next();
476 if (messageKey.equals(em.getErrorKey())) {
477 foundMessage = em;
478 }
479 }
480 }
481 }
482
483 return (foundMessage != null);
484 }
485
486 private int getMessageCount(Map<String, List<ErrorMessage>> messageMap) {
487 int messageCount = 0;
488 for (Iterator<String> iter = messageMap.keySet().iterator(); iter.hasNext(); ) {
489 String errorKey = iter.next();
490 List<ErrorMessage> errors = messageMap.get(errorKey);
491 messageCount += errors.size();
492 }
493
494 return messageCount;
495 }
496
497
498
499
500
501
502 public int getErrorCount() {
503 return getMessageCount(errorMessages);
504 }
505
506
507
508
509
510
511 public int getWarningCount() {
512 return getMessageCount(warningMessages);
513 }
514
515
516
517
518
519
520 public int getInfoCount() {
521 return getMessageCount(infoMessages);
522 }
523
524
525
526
527
528 public List<ErrorMessage> getMessages(String path) {
529 return errorMessages.get(path);
530 }
531
532
533
534
535
536
537 public void addToErrorPath(String parentName) {
538 errorPath.add(parentName);
539 }
540
541
542
543
544
545
546 public List<String> getErrorPath() {
547 return errorPath;
548 }
549
550
551
552
553
554
555
556 public boolean removeFromErrorPath(String parentName) {
557 return errorPath.remove(parentName);
558 }
559
560
561
562
563 public void clearErrorPath() {
564 errorPath.clear();
565 }
566
567
568
569
570
571
572
573
574
575
576 public String getKeyPath(String propertyName, boolean prependFullErrorPath) {
577 String keyPath = "";
578
579 if (KRADConstants.GLOBAL_ERRORS.equals(propertyName)) {
580 return KRADConstants.GLOBAL_ERRORS;
581 }
582
583 if (!errorPath.isEmpty() && prependFullErrorPath) {
584 keyPath = StringUtils.join(errorPath.iterator(), ".");
585 keyPath += (keyPath != null && keyPath.endsWith(".")) ? propertyName : "." + propertyName;
586 } else {
587 keyPath = propertyName;
588 }
589
590 return keyPath;
591 }
592
593
594
595
596 public List<String> getPropertiesWithErrors() {
597 List<String> properties = new ArrayList<String>();
598
599 for (Iterator<String> iter = errorMessages.keySet().iterator(); iter.hasNext(); ) {
600 properties.add(iter.next());
601 }
602
603 return properties;
604 }
605
606
607
608
609 public List<String> getPropertiesWithWarnings() {
610 List<String> properties = new ArrayList<String>(warningMessages.keySet());
611 return properties;
612 }
613
614
615
616
617 public List<String> getPropertiesWithInfo() {
618 List<String> properties = new ArrayList<String>(infoMessages.keySet());
619 return properties;
620 }
621
622 public void clearErrorMessages() {
623 errorMessages.clear();
624 }
625
626 public boolean doesPropertyHaveError(String key) {
627 return errorMessages.containsKey(key);
628 }
629
630
631
632
633 public boolean containsKeyMatchingPattern(String pattern) {
634 List<String> simplePatterns = new ArrayList<String>();
635 List<String> wildcardPatterns = new ArrayList<String>();
636 String[] patterns = pattern.split(",");
637 for (int i = 0; i < patterns.length; i++) {
638 String s = patterns[i];
639 if (s.endsWith("*")) {
640 wildcardPatterns.add(s.substring(0, s.length() - 1));
641 } else {
642 simplePatterns.add(s);
643 }
644 }
645 for (Iterator<String> keys = errorMessages.keySet().iterator(); keys.hasNext(); ) {
646 String key = keys.next();
647 if (simplePatterns.contains(key)) {
648 return true;
649 }
650 for (Iterator<String> wildcardIterator = wildcardPatterns.iterator(); wildcardIterator.hasNext(); ) {
651 String wildcard = wildcardIterator.next();
652 if (key.startsWith(wildcard)) {
653 return true;
654 }
655 }
656 }
657 return false;
658 }
659
660 public Set<Map.Entry<String, List<ErrorMessage>>> getAllPropertiesAndErrors() {
661 return errorMessages.entrySet();
662 }
663
664 public List<ErrorMessage> getErrorMessagesForProperty(String propertyName) {
665 return errorMessages.get(propertyName);
666 }
667
668 public List<ErrorMessage> getWarningMessagesForProperty(String propertyName) {
669 return warningMessages.get(propertyName);
670 }
671
672 public List<ErrorMessage> getInfoMessagesForProperty(String propertyName) {
673 return infoMessages.get(propertyName);
674 }
675
676
677
678
679
680
681
682
683
684
685
686
687 public List<List<ErrorMessage>> getErrorMessagesForProperty(String propertyName,
688 boolean allowWildcard) {
689 List<List<ErrorMessage>> foundMessages = new ArrayList<List<ErrorMessage>>();
690 if (allowWildcard) {
691 boolean wildcard = false;
692 if (propertyName.endsWith("*")) {
693 wildcard = true;
694 propertyName = propertyName.substring(0, propertyName.length() - 1);
695 }
696 for (Iterator<String> keys = errorMessages.keySet().iterator(); keys.hasNext(); ) {
697 String key = keys.next();
698 if (!wildcard && propertyName.equals(key)) {
699 foundMessages.add(errorMessages.get(key));
700 break;
701 } else if (wildcard && key.startsWith(propertyName)) {
702 foundMessages.add(errorMessages.get(key));
703 }
704 }
705 } else {
706 foundMessages.add(getErrorMessagesForProperty(propertyName));
707 }
708
709 return foundMessages;
710 }
711
712
713
714
715
716
717
718
719
720
721
722
723 public List<List<ErrorMessage>> getWarningMessagesForProperty(String propertyName,
724 boolean allowWildcard) {
725 List<List<ErrorMessage>> foundMessages = new ArrayList<List<ErrorMessage>>();
726 if (allowWildcard) {
727 boolean wildcard = false;
728 if (propertyName.endsWith("*")) {
729 wildcard = true;
730 propertyName = propertyName.substring(0, propertyName.length() - 1);
731 }
732 for (Iterator<String> keys = warningMessages.keySet().iterator(); keys.hasNext(); ) {
733 String key = keys.next();
734 if (!wildcard && propertyName.equals(key)) {
735 foundMessages.add(warningMessages.get(key));
736 break;
737 } else if (wildcard && key.startsWith(propertyName)) {
738 foundMessages.add(warningMessages.get(key));
739 }
740 }
741 } else {
742 foundMessages.add(getWarningMessagesForProperty(propertyName));
743 }
744
745 return foundMessages;
746 }
747
748
749
750
751
752
753
754
755
756
757
758
759 public List<List<ErrorMessage>> getInfoMessagesForProperty(String propertyName,
760 boolean allowWildcard) {
761 List<List<ErrorMessage>> foundMessages = new ArrayList<List<ErrorMessage>>();
762 if (allowWildcard) {
763 boolean wildcard = false;
764 if (propertyName.endsWith("*")) {
765 wildcard = true;
766 propertyName = propertyName.substring(0, propertyName.length() - 1);
767 }
768 for (Iterator<String> keys = infoMessages.keySet().iterator(); keys.hasNext(); ) {
769 String key = keys.next();
770 if (!wildcard && propertyName.equals(key)) {
771 foundMessages.add(infoMessages.get(key));
772 break;
773 } else if (wildcard && key.startsWith(propertyName)) {
774 foundMessages.add(infoMessages.get(key));
775 }
776 }
777 } else {
778 foundMessages.add(getInfoMessagesForProperty(propertyName));
779 }
780
781 return foundMessages;
782 }
783
784 public boolean hasErrors() {
785 return !errorMessages.isEmpty();
786 }
787
788 public boolean hasNoErrors() {
789 return errorMessages.isEmpty();
790 }
791
792 public boolean hasWarnings() {
793 return !warningMessages.isEmpty();
794 }
795
796 public boolean hasNoWarnings() {
797 return warningMessages.isEmpty();
798 }
799
800 public boolean hasInfo() {
801 return !infoMessages.isEmpty();
802 }
803
804 public boolean hasNoInfo() {
805 return infoMessages.isEmpty();
806 }
807
808 public boolean hasMessages() {
809 if (!errorMessages.isEmpty() || !warningMessages.isEmpty() || !infoMessages.isEmpty()) {
810 return true;
811 }
812 return false;
813 }
814
815 public boolean hasNoMessages() {
816 if (errorMessages.isEmpty() && warningMessages.isEmpty() && infoMessages.isEmpty()) {
817 return true;
818 }
819 return false;
820 }
821
822 public Set<String> getAllPropertiesWithErrors() {
823 return errorMessages.keySet();
824 }
825
826 public Set<String> getAllPropertiesWithWarnings() {
827 return warningMessages.keySet();
828 }
829
830 public Set<String> getAllPropertiesWithInfo() {
831 return infoMessages.keySet();
832 }
833
834 public List<ErrorMessage> removeAllErrorMessagesForProperty(String property) {
835 return errorMessages.remove(property);
836 }
837
838 public List<ErrorMessage> removeAllWarningMessagesForProperty(String property) {
839 return warningMessages.remove(property);
840 }
841
842 public List<ErrorMessage> removeAllInfoMessagesForProperty(String property) {
843 return infoMessages.remove(property);
844 }
845
846 public int getNumberOfPropertiesWithErrors() {
847 return errorMessages.size();
848 }
849
850 public Map<String, List<ErrorMessage>> getErrorMessages() {
851 return this.errorMessages;
852 }
853
854 public Map<String, List<ErrorMessage>> getWarningMessages() {
855 return this.warningMessages;
856 }
857
858 public Map<String, List<ErrorMessage>> getInfoMessages() {
859 return this.infoMessages;
860 }
861
862
863
864
865
866
867
868 public List<GrowlMessage> getGrowlMessages() {
869 return this.growlMessages;
870 }
871
872 @Override
873 public boolean equals(Object o) {
874 return EqualsBuilder.reflectionEquals(this, o);
875 }
876
877 @Override
878 public int hashCode() {
879 return HashCodeBuilder.reflectionHashCode(this);
880 }
881
882 @Override
883 public String toString() {
884 return ToStringBuilder.reflectionToString(this);
885 }
886 }