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