Coverage Report - org.kuali.rice.krad.util.MessageMap
 
Classes in this File Line Coverage Branch Coverage Complexity
MessageMap
0%
0/239
0%
0/148
2.25
 
 1  
 /**
 2  
  * Copyright 2005-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.krad.util;
 17  
 
 18  
 
 19  
 import org.apache.commons.lang.StringEscapeUtils;
 20  
 import org.apache.commons.lang.StringUtils;
 21  
 import org.apache.commons.lang.builder.EqualsBuilder;
 22  
 import org.apache.commons.lang.builder.HashCodeBuilder;
 23  
 import org.apache.commons.lang.builder.ToStringBuilder;
 24  
 import org.springframework.util.AutoPopulatingList;
 25  
 
 26  
 import java.io.Serializable;
 27  
 import java.util.ArrayList;
 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  
  * Holds errors due to validation. Keys of map represent property paths, and value is a AutoPopulatingList that contains resource string
 37  
  * keys (to retrieve the error message).
 38  
  *
 39  
  * Note, prior to rice 0.9.4, this class implemented {@link java.util.Map}.  The implements has been removed as of rice 0.9.4
 40  
  */
 41  
 public class MessageMap implements Serializable {
 42  
         
 43  
     private static final long serialVersionUID = -2328635367656516150L;
 44  
     
 45  0
     private List<String> errorPath = new ArrayList<String>();
 46  0
     private Map<String, AutoPopulatingList<ErrorMessage>> errorMessages = new LinkedHashMap<String, AutoPopulatingList<ErrorMessage>>();
 47  0
     private Map<String, AutoPopulatingList<ErrorMessage>> warningMessages = new LinkedHashMap<String, AutoPopulatingList<ErrorMessage>>();
 48  0
     private Map<String, AutoPopulatingList<ErrorMessage>> infoMessages = new LinkedHashMap<String, AutoPopulatingList<ErrorMessage>>();
 49  
 
 50  0
     public MessageMap() {}
 51  
 
 52  0
     public MessageMap(MessageMap messageMap) {
 53  0
             this.errorPath = messageMap.errorPath;
 54  0
             this.errorMessages = messageMap.errorMessages;
 55  0
             this.warningMessages = messageMap.warningMessages;
 56  0
             this.infoMessages = messageMap.infoMessages;
 57  0
     }
 58  
 
 59  
 
 60  
     public void merge(MessageMap messageMap){
 61  0
             if(messageMap != null){
 62  0
                     if(messageMap.hasErrors()){
 63  0
                             merge(messageMap.getErrorMessages(), errorMessages);
 64  
                     }
 65  0
                     if(messageMap.hasInfo()){
 66  0
                             merge(messageMap.getInfoMessages(), infoMessages);
 67  
                     }
 68  0
                     if(messageMap.hasWarnings()){
 69  0
                             merge(messageMap.getWarningMessages(), warningMessages);
 70  
                     }
 71  
 
 72  
             }
 73  
 
 74  0
     }
 75  
 
 76  
     /**
 77  
      *
 78  
      * This method takes one message map and merges it into another.  Makes sure there are no duplicates.
 79  
      *
 80  
      * @param messagesFrom
 81  
      * @param messagesTo
 82  
      */
 83  
     protected void merge(Map<String, AutoPopulatingList<ErrorMessage>> messagesFrom, Map<String, AutoPopulatingList<ErrorMessage>> messagesTo){
 84  0
             for(String key : messagesFrom.keySet()){
 85  
 
 86  0
                     if(messagesTo.containsKey(key)){
 87  
                             // now we need to merge the messages
 88  0
                             AutoPopulatingList<ErrorMessage> tal = messagesFrom.get(key);
 89  0
                             AutoPopulatingList<ErrorMessage> parentList = messagesTo.get(key);
 90  
 
 91  0
                             for(Object o :tal){
 92  
 
 93  0
                                      if ( !parentList.contains( o ) ) {
 94  0
                                              parentList.add((ErrorMessage)o);
 95  
                                  }
 96  
                             }
 97  
 
 98  0
                     }else{
 99  0
                             messagesTo.put(key, messagesFrom.get(key));
 100  
                     }
 101  
 
 102  
             }
 103  
 
 104  0
     }
 105  
     /**
 106  
      * Adds an error to the map under the given propertyName and adds an array of message parameters. This will fully prepend the
 107  
      * error key with any value in the errorPath list. This should be used when you do not want to add the error with the prepend
 108  
      * pre-built error path.
 109  
      *
 110  
      * @param propertyName name of the property to add error under
 111  
      * @param errorKey resource key used to retrieve the error text from the error message resource bundle
 112  
      * @param errorParameters zero or more string parameters for the displayed error message
 113  
      * @return AutoPopulatingList
 114  
      */
 115  
     public AutoPopulatingList<ErrorMessage> putError(String propertyName, String errorKey, String... errorParameters) {
 116  0
         return putMessageInMap(errorMessages, propertyName, errorKey, true, true, errorParameters);
 117  
     }
 118  
 
 119  
     public AutoPopulatingList<ErrorMessage> putWarning(String propertyName, String messageKey, String... messageParameters) {
 120  0
         return putMessageInMap(warningMessages, propertyName, messageKey, true, true, messageParameters);
 121  
     }
 122  
 
 123  
     public AutoPopulatingList<ErrorMessage> putInfo(String propertyName, String messageKey, String... messageParameters) {
 124  0
         return putMessageInMap(infoMessages, propertyName, messageKey, true, true, messageParameters);
 125  
     }
 126  
 
 127  
     /**
 128  
      * Adds an error to the map under the given propertyName and adds an array of message parameters. This will fully prepend the
 129  
      * error key with any value in the errorPath list.
 130  
      *
 131  
      * @param propertyName name of the property to add error under
 132  
      * @param errorKey resource key used to retrieve the error text from the error message resource bundle
 133  
      * @param errorParameters zero or more string parameters for the displayed error message
 134  
      * @return AutoPopulatingList
 135  
      */
 136  
     public AutoPopulatingList<ErrorMessage> putErrorWithoutFullErrorPath(String propertyName, String errorKey, String... errorParameters) {
 137  0
         return putMessageInMap(errorMessages, propertyName, errorKey, false, true, errorParameters);
 138  
     }
 139  
 
 140  
     public AutoPopulatingList<ErrorMessage> putWarningWithoutFullErrorPath(String propertyName, String messageKey, String... messageParameters) {
 141  0
         return putMessageInMap(warningMessages, propertyName, messageKey, false, true, messageParameters);
 142  
     }
 143  
 
 144  
     public AutoPopulatingList<ErrorMessage> putInfoWithoutFullErrorPath(String propertyName, String messageKey, String... messageParameters) {
 145  0
         return putMessageInMap(infoMessages, propertyName, messageKey, false, true, messageParameters);
 146  
     }
 147  
 
 148  
     /**
 149  
      * Adds an error related to a particular section identified by its section ID.  For maintenance documents, the section ID is identified
 150  
      * by calling {@link org.kuali.rice.kns.datadictionary.MaintainableSectionDefinition#getId()}
 151  
      *
 152  
      * @param sectionId
 153  
      * @param errorKey
 154  
      * @param errorParameters
 155  
      * @return
 156  
      */
 157  
     public AutoPopulatingList<ErrorMessage> putErrorForSectionId(String sectionId, String errorKey, String... errorParameters) {
 158  0
             return putErrorWithoutFullErrorPath(sectionId, errorKey, errorParameters);
 159  
     }
 160  
 
 161  
     public AutoPopulatingList<ErrorMessage> putWarningForSectionId(String sectionId, String messageKey, String... messageParameters) {
 162  0
             return putWarningWithoutFullErrorPath(sectionId, messageKey, messageParameters);
 163  
     }
 164  
 
 165  
     public AutoPopulatingList<ErrorMessage> putInfoForSectionId(String sectionId, String messageKey, String... messageParameters) {
 166  0
             return putInfoWithoutFullErrorPath(sectionId, messageKey, messageParameters);
 167  
     }
 168  
 
 169  
     /**
 170  
      * adds an error to the map under the given propertyName and adds an array of message parameters.
 171  
      *
 172  
      * @param propertyName name of the property to add error under
 173  
      * @param messageKey resource key used to retrieve the error text from the error message resource bundle
 174  
      * @param withFullErrorPath true if you want the whole parent error path appended, false otherwise
 175  
      * @param escapeHtmlMessageParameters whether to escape HTML characters in the message parameters, provides protection against XSS attacks
 176  
      * @param messageParameters zero or more string parameters for the displayed error message
 177  
      * @return TypeArrayList
 178  
      */
 179  
     private AutoPopulatingList<ErrorMessage> putMessageInMap(Map<String, AutoPopulatingList<ErrorMessage>> messagesMap, String propertyName, String messageKey, boolean withFullErrorPath, boolean escapeHtmlMessageParameters, String... messageParameters) {
 180  0
         if (StringUtils.isBlank(propertyName)) {
 181  0
             throw new IllegalArgumentException("invalid (blank) propertyName");
 182  
         }
 183  0
         if (StringUtils.isBlank(messageKey)) {
 184  0
             throw new IllegalArgumentException("invalid (blank) errorKey");
 185  
         }
 186  
 
 187  
         // check if we have previous errors for this property
 188  0
         AutoPopulatingList<ErrorMessage> errorList = null;
 189  0
         String propertyKey = getKeyPath(propertyName, withFullErrorPath);
 190  0
         if (messagesMap.containsKey(propertyKey)) {
 191  0
             errorList = messagesMap.get(propertyKey);
 192  
         }
 193  
         else {
 194  0
             errorList = new AutoPopulatingList<ErrorMessage>(ErrorMessage.class);
 195  
         }
 196  
 
 197  0
         if (escapeHtmlMessageParameters && messageParameters != null) {
 198  0
                 String[] filteredMessageParameters = new String[messageParameters.length];
 199  0
                 for (int i = 0; i < messageParameters.length; i++) {
 200  0
                         filteredMessageParameters[i] = StringEscapeUtils.escapeHtml(messageParameters[i]);
 201  
                 }
 202  0
                 messageParameters = filteredMessageParameters;
 203  
         }
 204  
 
 205  
         // add error to list
 206  0
         ErrorMessage errorMessage = new ErrorMessage(messageKey, messageParameters);
 207  
         // check if this error has already been added to the list
 208  0
         if ( !errorList.contains( errorMessage ) ) {
 209  0
             errorList.add(errorMessage);
 210  
         }
 211  
 
 212  0
         return messagesMap.put(propertyKey, errorList);
 213  
     }
 214  
 
 215  
     /**
 216  
      * If any error messages with the key targetKey exist in this ErrorMap for the named property, those ErrorMessages will be
 217  
      * replaced with a new ErrorMessage with the given replaceKey and replaceParameters.
 218  
      *
 219  
      * @param propertyName name of the property where existing error will be replaced
 220  
      * @param targetKey error key of message to be replaced
 221  
      * @paran replaceKey error key which will replace targetKey
 222  
      * @param replaceParameters zero or more string parameters for the replacement error message
 223  
      * @return true if the replacement occurred
 224  
      */
 225  
     public boolean replaceError(String propertyName, String targetKey, String replaceKey, String... replaceParameters) {
 226  0
         return replaceError(propertyName, targetKey, true, replaceKey, replaceParameters);
 227  
     }
 228  
 
 229  
     /**
 230  
      * If any error messages with the key targetKey exist in this ErrorMap for the named property, those ErrorMessages will be
 231  
      * replaced with a new ErrorMessage with the given replaceKey and replaceParameters. The targetKey and replaceKey will be
 232  
      * prepended with the current errorPath, if any.
 233  
      *
 234  
      *
 235  
      * @param propertyName name of the property where existing error will be replaced
 236  
      * @param targetKey error key of message to be replaced
 237  
      * @paran replaceKey error key which will replace targetKey
 238  
      * @param replaceParameters zero or more string parameters for the replacement error message
 239  
      * @return true if the replacement occurred
 240  
      */
 241  
     public boolean replaceErrorWithoutFullErrorPath(String propertyName, String targetKey, String replaceKey, String... replaceParameters) {
 242  0
         return replaceError(propertyName, targetKey, false, replaceKey, replaceParameters);
 243  
     }
 244  
 
 245  
 
 246  
     /**
 247  
      * If any error messages with the key targetKey exist in this ErrorMap for the named property, those ErrorMessages will be
 248  
      * replaced with a new ErrorMessage with the given replaceKey and replaceParameters.
 249  
      *
 250  
      * @param propertyName name of the property to add error under
 251  
      * @param targetKey resource key used to retrieve the error text
 252  
      * @param withFullErrorPath true if you want the whole parent error path appended, false otherwise
 253  
      * @param replaceParameters zero or more string parameters for the displayed error message
 254  
      * @return true if the replacement occurred
 255  
      */
 256  
     private boolean replaceError(String propertyName, String targetKey, boolean withFullErrorPath, String replaceKey, String... replaceParameters) {
 257  0
         boolean replaced = false;
 258  
 
 259  0
         if (StringUtils.isBlank(propertyName)) {
 260  0
             throw new IllegalArgumentException("invalid (blank) propertyName");
 261  
         }
 262  0
         if (StringUtils.isBlank(targetKey)) {
 263  0
             throw new IllegalArgumentException("invalid (blank) targetKey");
 264  
         }
 265  0
         if (StringUtils.isBlank(replaceKey)) {
 266  0
             throw new IllegalArgumentException("invalid (blank) replaceKey");
 267  
         }
 268  
 
 269  
         // check if we have previous errors for this property
 270  0
         AutoPopulatingList<ErrorMessage> errorList = null;
 271  0
         String propertyKey = getKeyPath(propertyName, withFullErrorPath);
 272  0
         if (errorMessages.containsKey(propertyKey)) {
 273  0
             errorList = errorMessages.get(propertyKey);
 274  
 
 275  
             // look for the specific targetKey
 276  0
             for (int i = 0; i < errorList.size(); ++i) {
 277  0
                 ErrorMessage em = errorList.get(i);
 278  
 
 279  
                 // replace matching messages
 280  0
                 if (em.getErrorKey().equals(targetKey)) {
 281  0
                     ErrorMessage rm = new ErrorMessage(replaceKey, replaceParameters);
 282  0
                     errorList.set(i, rm);
 283  0
                     replaced = true;
 284  
                 }
 285  
             }
 286  
         }
 287  
 
 288  0
         return replaced;
 289  
     }
 290  
 
 291  
 
 292  
     /**
 293  
      * Returns true if the named field has a message with the given errorKey
 294  
      *
 295  
      * @param errorKey
 296  
      * @param fieldName
 297  
      * @return boolean
 298  
      */
 299  
     public boolean fieldHasMessage(String fieldName, String errorKey) {
 300  0
         boolean found = false;
 301  
 
 302  0
         List<ErrorMessage> fieldMessages = errorMessages.get(fieldName);
 303  0
         if (fieldMessages != null) {
 304  0
             for (Iterator<ErrorMessage> i = fieldMessages.iterator(); !found && i.hasNext();) {
 305  0
                 ErrorMessage errorMessage = i.next();
 306  0
                 found = errorMessage.getErrorKey().equals(errorKey);
 307  0
             }
 308  
         }
 309  
 
 310  0
         return found;
 311  
     }
 312  
 
 313  
     /**
 314  
      * Returns the number of messages for the given field
 315  
      *
 316  
      * @param fieldName
 317  
      * @return int
 318  
      */
 319  
     public int countFieldMessages(String fieldName) {
 320  0
         int count = 0;
 321  
 
 322  0
         List<ErrorMessage> fieldMessages = errorMessages.get(fieldName);
 323  0
         if (fieldMessages != null) {
 324  0
             count = fieldMessages.size();
 325  
         }
 326  
 
 327  0
         return count;
 328  
     }
 329  
 
 330  
 
 331  
     /**
 332  
      * @return true if the given messageKey is associated with some property in this ErrorMap
 333  
      */
 334  
     public boolean containsMessageKey(String messageKey) {
 335  0
         ErrorMessage foundMessage = null;
 336  
 
 337  0
         if (!hasNoErrors()) {
 338  0
             for (Iterator<Map.Entry<String, AutoPopulatingList<ErrorMessage>>> i = getAllPropertiesAndErrors().iterator(); (foundMessage == null) && i.hasNext();) {
 339  0
                     Map.Entry<String, AutoPopulatingList<ErrorMessage>> e = i.next();
 340  0
                 AutoPopulatingList<ErrorMessage> entryErrorList = e.getValue();
 341  0
                 for (Iterator<ErrorMessage> j = entryErrorList.iterator(); j.hasNext();) {
 342  0
                     ErrorMessage em = j.next();
 343  0
                     if (messageKey.equals(em.getErrorKey())) {
 344  0
                         foundMessage = em;
 345  
                     }
 346  0
                 }
 347  0
             }
 348  
         }
 349  
 
 350  0
         return (foundMessage != null);
 351  
     }
 352  
 
 353  
 
 354  
     private int getMessageCount(Map<String, AutoPopulatingList<ErrorMessage>> messageMap) {
 355  0
         int messageCount = 0;
 356  0
         for (Iterator<String> iter = messageMap.keySet().iterator(); iter.hasNext();) {
 357  0
             String errorKey = iter.next();
 358  0
             List<ErrorMessage> errors = messageMap.get(errorKey);
 359  0
             messageCount += errors.size();
 360  0
         }
 361  
 
 362  0
         return messageCount;
 363  
     }
 364  
 
 365  
     /**
 366  
      * Counts the total number of error messages in the map
 367  
      *
 368  
      * @return returns an int for the total number of errors
 369  
      */
 370  
     public int getErrorCount() {
 371  0
             return getMessageCount(errorMessages);
 372  
     }
 373  
 
 374  
     /**
 375  
      * Counts the total number of warning messages in the map
 376  
      *
 377  
      * @return returns an int for the total number of warnings
 378  
      */
 379  
     public int getWarningCount() {
 380  0
             return getMessageCount(warningMessages);
 381  
     }
 382  
 
 383  
     /**
 384  
      * Counts the total number of info messages in the map
 385  
      *
 386  
      * @return returns an int for the total number of info
 387  
      */
 388  
     public int getInfoCount() {
 389  0
             return getMessageCount(infoMessages);
 390  
     }
 391  
 
 392  
     /**
 393  
      * @param path
 394  
      * @return Returns a List of ErrorMessages for the given path
 395  
      */
 396  
     public AutoPopulatingList<ErrorMessage> getMessages(String path) {
 397  0
         return errorMessages.get(path);
 398  
     }
 399  
 
 400  
     /**
 401  
      * Adds a string prefix to the error path.
 402  
      *
 403  
      * @param parentName
 404  
      */
 405  
     public void addToErrorPath(String parentName) {
 406  0
         errorPath.add(parentName);
 407  0
     }
 408  
 
 409  
     /**
 410  
      * This method returns the list that holds the error path values.
 411  
      *
 412  
      * @return List
 413  
      */
 414  
     public List<String> getErrorPath() {
 415  0
         return errorPath;
 416  
     }
 417  
 
 418  
     /**
 419  
      * Removes a string prefix from the error path.
 420  
      *
 421  
      * @param parentName
 422  
      * @return boolean Returns true if the parentName existed, false otherwise.
 423  
      */
 424  
     public boolean removeFromErrorPath(String parentName) {
 425  0
         return errorPath.remove(parentName);
 426  
     }
 427  
 
 428  
     /**
 429  
      * Clears the errorPath.
 430  
      */
 431  
     public void clearErrorPath() {
 432  0
         errorPath.clear();
 433  0
     }
 434  
 
 435  
     /**
 436  
      * This is what's prepended to the beginning of the key. This is built by iterating over all of the entries in the errorPath
 437  
      * list and concatenating them together witha "."
 438  
      *
 439  
      * @return String Returns the keyPath.
 440  
      * @param propertyName
 441  
      * @param prependFullErrorPath
 442  
      */
 443  
     public String getKeyPath(String propertyName, boolean prependFullErrorPath) {
 444  0
         String keyPath = "";
 445  
 
 446  0
         if (KRADConstants.GLOBAL_ERRORS.equals(propertyName)) {
 447  0
             return KRADConstants.GLOBAL_ERRORS;
 448  
         }
 449  
 
 450  0
         if (!errorPath.isEmpty() && prependFullErrorPath) {
 451  0
             keyPath = StringUtils.join(errorPath.iterator(), ".");
 452  0
             keyPath += (keyPath!=null && keyPath.endsWith("."))?propertyName:"." + propertyName;
 453  
         }
 454  
         else {
 455  0
             keyPath = propertyName;
 456  
         }
 457  
 
 458  0
         return keyPath;
 459  
     }
 460  
 
 461  
     /**
 462  
      * @return List of the property names that have errors.
 463  
      */
 464  
     public List<String> getPropertiesWithErrors() {
 465  0
         List<String> properties = new ArrayList<String>();
 466  
 
 467  0
         for (Iterator<String> iter = errorMessages.keySet().iterator(); iter.hasNext();) {
 468  0
             properties.add(iter.next());
 469  
         }
 470  
 
 471  0
         return properties;
 472  
     }
 473  
 
 474  
     /**
 475  
      * @return List of the property names that have warnings.
 476  
      */
 477  
     public List<String> getPropertiesWithWarnings() {
 478  0
         List<String> properties = new ArrayList<String>(warningMessages.keySet());
 479  0
         return properties;
 480  
     }
 481  
 
 482  
     /**
 483  
      * @return List of the property names that have info.
 484  
      */
 485  
     public List<String> getPropertiesWithInfo() {
 486  0
         List<String> properties = new ArrayList<String>(infoMessages.keySet());
 487  0
         return properties;
 488  
     }
 489  
 
 490  
     public void clearErrorMessages() {
 491  0
             errorMessages.clear();
 492  0
     }
 493  
 
 494  
     public boolean doesPropertyHaveError(String key) {
 495  0
             return errorMessages.containsKey(key);
 496  
     }
 497  
 
 498  
     /**
 499  
      * @param pattern comma separated list of keys, optionally ending with * wildcard
 500  
      */
 501  
     public boolean containsKeyMatchingPattern(String pattern) {
 502  0
         List<String> simplePatterns = new ArrayList<String>();
 503  0
         List<String> wildcardPatterns = new ArrayList<String>();
 504  0
         String[] patterns = pattern.split(",");
 505  0
         for (int i = 0; i < patterns.length; i++) {
 506  0
             String s = patterns[i];
 507  0
             if (s.endsWith("*")) {
 508  0
                 wildcardPatterns.add(s.substring(0, s.length() - 1));
 509  
             }
 510  
             else {
 511  0
                 simplePatterns.add(s);
 512  
             }
 513  
         }
 514  0
         for (Iterator<String> keys = errorMessages.keySet().iterator(); keys.hasNext();) {
 515  0
             String key = keys.next();
 516  0
             if (simplePatterns.contains(key)) {
 517  0
                 return true;
 518  
             }
 519  0
             for (Iterator<String> wildcardIterator = wildcardPatterns.iterator(); wildcardIterator.hasNext();) {
 520  0
                 String wildcard = wildcardIterator.next();
 521  0
                 if (key.startsWith(wildcard)) {
 522  0
                     return true;
 523  
                 }
 524  0
             }
 525  0
         }
 526  0
         return false;
 527  
     }
 528  
 
 529  
     public Set<Map.Entry<String, AutoPopulatingList<ErrorMessage>>> getAllPropertiesAndErrors() {
 530  0
             return errorMessages.entrySet();
 531  
     }
 532  
 
 533  
     public AutoPopulatingList<ErrorMessage> getErrorMessagesForProperty(String propertyName) {
 534  0
             return errorMessages.get(propertyName);
 535  
     }
 536  
 
 537  
     public AutoPopulatingList<ErrorMessage> getWarningMessagesForProperty(String propertyName) {
 538  0
             return warningMessages.get(propertyName);
 539  
     }
 540  
 
 541  
     public AutoPopulatingList<ErrorMessage> getInfoMessagesForProperty(String propertyName) {
 542  0
             return infoMessages.get(propertyName);
 543  
     }
 544  
     
 545  
         /**
 546  
          * Gets a list of lists that represent errors that matched by the
 547  
          * propertyName passed in (multiple lists because the wildcard can match
 548  
          * multiple keys). If wildcard is true, the propertyName ends with a
 549  
          * wildcard character. Otherwise, it will only match on the single key and
 550  
          * return a list with one list
 551  
          * 
 552  
          * @param propertyName
 553  
          * @param allowWildcard
 554  
          * @return
 555  
          */
 556  
         public List<AutoPopulatingList<ErrorMessage>> getErrorMessagesForProperty(
 557  
                         String propertyName, boolean allowWildcard) {
 558  0
                 List<AutoPopulatingList<ErrorMessage>> foundMessages = new ArrayList<AutoPopulatingList<ErrorMessage>>();
 559  0
                 if (allowWildcard) {
 560  0
                         boolean wildcard = false;
 561  0
                         if (propertyName.endsWith("*")) {
 562  0
                                 wildcard = true;
 563  0
                                 propertyName = propertyName.substring(0,
 564  
                                                 propertyName.length() - 1);
 565  
                         }
 566  0
                         for (Iterator<String> keys = errorMessages.keySet().iterator(); keys
 567  0
                                         .hasNext();) {
 568  0
                                 String key = keys.next();
 569  0
                                 if (!wildcard && propertyName.equals(key)) {
 570  0
                                         foundMessages.add(errorMessages.get(key));
 571  0
                                         break;
 572  0
                                 } else if (wildcard && key.startsWith(propertyName)) {
 573  0
                                         foundMessages.add(errorMessages.get(key));
 574  
                                 }
 575  0
                         }
 576  0
                 } else {
 577  0
                         foundMessages.add(getErrorMessagesForProperty(propertyName));
 578  
                 }
 579  
 
 580  0
                 return foundMessages;
 581  
         }
 582  
 
 583  
         /**
 584  
          * Gets a list of lists that represent warnings that matched by the
 585  
          * propertyName passed in (multiple lists because the wildcard can match
 586  
          * multiple keys). If wildcard is true, the propertyName ends with a
 587  
          * wildcard character. Otherwise, it will only match on the single key and
 588  
          * return a list with one list.
 589  
          * 
 590  
          * @param propertyName
 591  
          * @param allowWildcard
 592  
          * @return
 593  
          */
 594  
         public List<AutoPopulatingList<ErrorMessage>> getWarningMessagesForProperty(
 595  
                         String propertyName, boolean allowWildcard) {
 596  0
                 List<AutoPopulatingList<ErrorMessage>> foundMessages = new ArrayList<AutoPopulatingList<ErrorMessage>>();
 597  0
                 if (allowWildcard) {
 598  0
                         boolean wildcard = false;
 599  0
                         if (propertyName.endsWith("*")) {
 600  0
                                 wildcard = true;
 601  0
                                 propertyName = propertyName.substring(0,
 602  
                                                 propertyName.length() - 1);
 603  
                         }
 604  0
                         for (Iterator<String> keys = warningMessages.keySet().iterator(); keys
 605  0
                                         .hasNext();) {
 606  0
                                 String key = keys.next();
 607  0
                                 if (!wildcard && propertyName.equals(key)) {
 608  0
                                         foundMessages.add(warningMessages.get(key));
 609  0
                                         break;
 610  0
                                 } else if (wildcard && key.startsWith(propertyName)) {
 611  0
                                         foundMessages.add(warningMessages.get(key));
 612  
                                 }
 613  0
                         }
 614  0
                 } else {
 615  0
                         foundMessages.add(getWarningMessagesForProperty(propertyName));
 616  
                 }
 617  
 
 618  0
                 return foundMessages;
 619  
         }
 620  
 
 621  
         /**
 622  
          * Gets a list of lists that represent info messages that matched by the
 623  
          * propertyName passed in (multiple lists because the wildcard can match
 624  
          * multiple keys). If wildcard is true, the propertyName ends with a
 625  
          * wildcard character. If it is false, it will only match on the single key
 626  
          * and return a list with one list.
 627  
          * 
 628  
          * @param propertyName
 629  
          * @param allowWildcard
 630  
          * @return
 631  
          */
 632  
         public List<AutoPopulatingList<ErrorMessage>> getInfoMessagesForProperty(
 633  
                         String propertyName, boolean allowWildcard) {
 634  0
                 List<AutoPopulatingList<ErrorMessage>> foundMessages = new ArrayList<AutoPopulatingList<ErrorMessage>>();
 635  0
                 if (allowWildcard) {
 636  0
                         boolean wildcard = false;
 637  0
                         if (propertyName.endsWith("*")) {
 638  0
                                 wildcard = true;
 639  0
                                 propertyName = propertyName.substring(0,
 640  
                                                 propertyName.length() - 1);
 641  
                         }
 642  0
                         for (Iterator<String> keys = infoMessages.keySet().iterator(); keys
 643  0
                                         .hasNext();) {
 644  0
                                 String key = keys.next();
 645  0
                                 if (!wildcard && propertyName.equals(key)) {
 646  0
                                         foundMessages.add(infoMessages.get(key));
 647  0
                                         break;
 648  0
                                 } else if (wildcard && key.startsWith(propertyName)) {
 649  0
                                         foundMessages.add(infoMessages.get(key));
 650  
                                 }
 651  0
                         }
 652  0
                 } else {
 653  0
                         foundMessages.add(getInfoMessagesForProperty(propertyName));
 654  
                 }
 655  
 
 656  0
                 return foundMessages;
 657  
         }
 658  
 
 659  
     public boolean hasErrors() {
 660  0
             return !errorMessages.isEmpty();
 661  
     }
 662  
 
 663  
     public boolean hasNoErrors() {
 664  0
             return errorMessages.isEmpty();
 665  
     }
 666  
 
 667  
     public boolean hasWarnings() {
 668  0
             return !warningMessages.isEmpty();
 669  
     }
 670  
 
 671  
     public boolean hasNoWarnings() {
 672  0
             return warningMessages.isEmpty();
 673  
     }
 674  
 
 675  
     public boolean hasInfo() {
 676  0
             return !infoMessages.isEmpty();
 677  
     }
 678  
 
 679  
     public boolean hasNoInfo() {
 680  0
             return infoMessages.isEmpty();
 681  
     }
 682  
 
 683  
     public boolean hasMessages() {
 684  0
         if (!errorMessages.isEmpty()
 685  
                 || !warningMessages.isEmpty()
 686  
                 || !infoMessages.isEmpty()) {
 687  0
             return true;
 688  
         }
 689  0
         return false;
 690  
     }
 691  
 
 692  
     public boolean hasNoMessages() {
 693  0
         if (errorMessages.isEmpty()
 694  
                 && warningMessages.isEmpty()
 695  
                 && infoMessages.isEmpty()) {
 696  0
             return true;
 697  
         }
 698  0
         return false;
 699  
     }
 700  
 
 701  
     public Set<String> getAllPropertiesWithErrors() {
 702  0
             return errorMessages.keySet();
 703  
     }
 704  
 
 705  
     public Set<String> getAllPropertiesWithWarnings() {
 706  0
             return warningMessages.keySet();
 707  
     }
 708  
 
 709  
     public Set<String> getAllPropertiesWithInfo() {
 710  0
             return infoMessages.keySet();
 711  
     }
 712  
 
 713  
     public AutoPopulatingList<ErrorMessage> removeAllErrorMessagesForProperty(String property) {
 714  0
             return errorMessages.remove(property);
 715  
     }
 716  
 
 717  
     public AutoPopulatingList<ErrorMessage> removeAllWarningMessagesForProperty(String property) {
 718  0
             return warningMessages.remove(property);
 719  
     }
 720  
 
 721  
     public AutoPopulatingList<ErrorMessage> removeAllInfoMessagesForProperty(String property) {
 722  0
             return infoMessages.remove(property);
 723  
     }
 724  
 
 725  
     public int getNumberOfPropertiesWithErrors() {
 726  0
             return errorMessages.size();
 727  
     }
 728  
 
 729  
     public Map<String, AutoPopulatingList<ErrorMessage>> getErrorMessages() {
 730  0
         return this.errorMessages;
 731  
     }
 732  
 
 733  
     public Map<String, AutoPopulatingList<ErrorMessage>> getWarningMessages() {
 734  0
         return this.warningMessages;
 735  
     }
 736  
 
 737  
     public Map<String, AutoPopulatingList<ErrorMessage>> getInfoMessages() {
 738  0
         return this.infoMessages;
 739  
     }
 740  
 
 741  
     @Override
 742  
     public boolean equals(Object o) {
 743  0
         return EqualsBuilder.reflectionEquals(this, o);
 744  
     }
 745  
 
 746  
     @Override
 747  
     public int hashCode() {
 748  0
         return HashCodeBuilder.reflectionHashCode(this);
 749  
     }
 750  
 
 751  
     @Override
 752  
     public String toString() {
 753  0
         return ToStringBuilder.reflectionToString(this);
 754  
     }
 755  
 }