Coverage Report - org.apache.commons.resources.impl.BasicMessageList
 
Classes in this File Line Coverage Branch Coverage Complexity
BasicMessageList
0%
0/72
0%
0/20
1.375
BasicMessageList$1
0%
0/2
N/A
1.375
BasicMessageList$MessageItem
0%
0/12
N/A
1.375
 
 1  
 /*
 2  
  * $Id: BasicMessageList.java 366395 2006-01-06 02:42:19Z niallp $
 3  
  * $Revision: 366395 $
 4  
  * $Date: 2006-01-06 02:42:19 +0000 (Fri, 06 Jan 2006) $
 5  
  *
 6  
  * ====================================================================
 7  
  *
 8  
  *  Copyright 2003-2006 The Apache Software Foundation
 9  
  *
 10  
  *  Licensed under the Apache License, Version 2.0 (the "License");
 11  
  *  you may not use this file except in compliance with the License.
 12  
  *  You may obtain a copy of the License at
 13  
  *
 14  
  *      http://www.apache.org/licenses/LICENSE-2.0
 15  
  *
 16  
  *  Unless required by applicable law or agreed to in writing, software
 17  
  *  distributed under the License is distributed on an "AS IS" BASIS,
 18  
  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 19  
  *  See the License for the specific language governing permissions and
 20  
  *  limitations under the License.
 21  
  *
 22  
  */
 23  
 
 24  
 package org.apache.commons.resources.impl;
 25  
 
 26  
 import java.io.Serializable;
 27  
 import java.util.ArrayList;
 28  
 import java.util.Collections;
 29  
 import java.util.Comparator;
 30  
 import java.util.HashMap;
 31  
 import java.util.Iterator;
 32  
 import java.util.List;
 33  
 import java.util.Map;
 34  
 
 35  
 import org.apache.commons.resources.Message;
 36  
 import org.apache.commons.resources.MessageList;
 37  
 
 38  
 /**
 39  
  * A basic implementation of a MessageList.
 40  
  * <p>
 41  
  * Orginally based on org.apache.struts.action.ActionMessages, Revision 49670.
 42  
  */
 43  
 public class BasicMessageList implements Serializable, MessageList {
 44  
 
 45  
     /**
 46  
      * Compares MessageItems.
 47  
      */
 48  0
     private static final Comparator ACTION_ITEM_COMPARATOR = new Comparator() {
 49  
         public int compare(Object o1, Object o2) {
 50  0
             return ((MessageItem) o1).getOrder() - ((MessageItem) o2).getOrder();
 51  
         }
 52  
     };
 53  
     
 54  
     /**
 55  
      * Have the messages been retrieved from this object?
 56  
      */
 57  0
     private boolean accessed = false;
 58  
 
 59  
     /**
 60  
      * The accumulated set of <code>Message</code> objects (represented
 61  
      * as a List) for each property, keyed by property name.
 62  
      */
 63  0
     private Map messages = new HashMap();
 64  
 
 65  
     /**
 66  
      * The current number of the property/key being added.  This is used
 67  
      * to maintain the order messages are added.
 68  
      */
 69  0
     private int count = 0;
 70  
 
 71  
     // --------------------------------------------------------- Public Methods
 72  
 
 73  
     /**
 74  
      * Create an empty <code>MessageList</code> object.
 75  
      */
 76  
     public BasicMessageList() {
 77  0
         super();
 78  0
     }
 79  
 
 80  
     /**
 81  
      * Create an <code>MessageList</code> object initialized to use
 82  
      * the given value for the "global" message key.
 83  
      *
 84  
      * @param globalMessageKey The new default global message key
 85  
      */
 86  
     public BasicMessageList(String globalMessageKey) {
 87  0
         super();
 88  0
         this.setGlobalMessageKey(globalMessageKey);
 89  0
     }
 90  
 
 91  
     /**
 92  
      * Create an <code>MessageList</code> object initialized with the given
 93  
      * messages.
 94  
      *
 95  
      * @param messages The messages to be initially added to this object.
 96  
      */
 97  
     public BasicMessageList(MessageList messages) {
 98  0
         super();
 99  0
         this.add(messages);
 100  0
     }
 101  
 
 102  
     /**
 103  
      * Create an <code>MessageList</code> object initialized with the given
 104  
      * messages and the given global message key.
 105  
      *
 106  
      * @param globalMessageKey The new default global message key
 107  
      * @param messages The messages to be initially added to this object.
 108  
      * 
 109  
      */
 110  
     public BasicMessageList(String globalMessageKey, MessageList messages) {
 111  0
         super();
 112  0
         this.setGlobalMessageKey(globalMessageKey);
 113  0
         this.add(messages);
 114  0
     }
 115  
 
 116  
     /**
 117  
      * The "global" message key for this MessageList
 118  
      * [GLOBAL_MESSAGE_KEY].
 119  
      */
 120  0
     private String globalMessageKey = GLOBAL_MESSAGE_KEY;
 121  
 
 122  
     /**
 123  
      * @return The default global message key
 124  
      */
 125  
     public String getGlobalMessageKey() {
 126  0
         return this.globalMessageKey;
 127  
     }
 128  
 
 129  
     /**
 130  
      * @param globalMessageKey The new default global message key
 131  
      */
 132  
     public void setGlobalMessageKey(String globalMessageKey) {
 133  0
         this.globalMessageKey = globalMessageKey;
 134  0
     }
 135  
 
 136  
     /**
 137  
      * Add a message to the set of messages for the specified property.  An
 138  
      * order of the property/key is maintained based on the initial addition
 139  
      * of the property/key.
 140  
      *
 141  
      * @param property  Property name (or MessageList.GLOBAL_MESSAGE_KEY)
 142  
      * @param message   The message to be added
 143  
      */
 144  
     public void add(String property, Message message) {
 145  
 
 146  0
         MessageItem item = (MessageItem) messages.get(property);
 147  0
         List list = null;
 148  
 
 149  0
         if (item == null) {
 150  0
             list = new ArrayList();
 151  0
             item = new MessageItem(list, this.count++);
 152  
 
 153  0
             messages.put(property, item);
 154  
         } else {
 155  0
             list = item.getList();
 156  
         }
 157  
 
 158  0
         list.add(message);
 159  
 
 160  0
     }
 161  
 
 162  
     /**
 163  
      * Add a message to the set of messages for the "global" property.  An
 164  
      * order of the property/key is maintained based on the initial addition
 165  
      * of the property/key.
 166  
      *
 167  
      * @param message   The message to be added
 168  
      */
 169  
     public void add(Message message) {
 170  0
         this.add(getGlobalMessageKey(), message);
 171  0
     }
 172  
 
 173  
     /**
 174  
      * Adds the messages from the given <code>MessageList</code> object to
 175  
      * this set of messages. The messages are added in the order they are returned from
 176  
      * the properties() method. If a message's property is already in the current
 177  
      * <code>MessageList</code> object it is added to the end of the list for that
 178  
      * property. If a message's property is not in the current list it is added to the end
 179  
      * of the properties.
 180  
      *
 181  
      * @param messageList The <code>MessageList</code> object to be added.
 182  
      */
 183  
     public void add(MessageList messageList) {
 184  
         // loop over properties
 185  0
         Iterator props = messageList.properties();
 186  0
         while (props.hasNext()) {
 187  0
             String property = (String) props.next();
 188  
 
 189  
             // loop over messages for each property
 190  0
             Iterator msgs = messageList.get(property);
 191  0
             while (msgs.hasNext()) {
 192  0
                 Message msg = (Message) msgs.next();
 193  0
                 this.add(property, msg);
 194  0
             }
 195  
 
 196  0
         }
 197  0
     }
 198  
 
 199  
     /**
 200  
      * Clear all messages recorded by this object.
 201  
      */
 202  
     public void clear() {
 203  0
         this.messages.clear();
 204  0
     }
 205  
     
 206  
     /**
 207  
      * Determines if the MessageList's messages have been accessed one or more
 208  
      * times.  Returns <code>true</code> if the <code>get()</code> or 
 209  
      * <code>get(String)</code> methods are called.  
 210  
      * @return <code>true</code> if the messages have been accessed one or more
 211  
      * times.
 212  
      */
 213  
     public boolean isAccessed() {
 214  0
         return this.accessed;
 215  
     }
 216  
 
 217  
     /**
 218  
      * @return Return <code>true</code> if there are no messages recorded
 219  
      * in this collection, or <code>false</code> otherwise.
 220  
      */
 221  
     public boolean isEmpty() {
 222  0
         return messages.isEmpty();
 223  
     }
 224  
 
 225  
     /**
 226  
      * Return the set of all recorded messages, without distinction
 227  
      * by which property the messages are associated with.  If there are
 228  
      * no messages recorded, an empty enumeration is returned.
 229  
      *
 230  
      * @return All messages.
 231  
      */
 232  
     public Iterator get() {
 233  0
         this.accessed = true;
 234  
         
 235  0
         if (messages.isEmpty()) {
 236  0
             return Collections.EMPTY_LIST.iterator();
 237  
         }
 238  
 
 239  0
         ArrayList results = new ArrayList();
 240  0
         ArrayList actionItems = new ArrayList();
 241  
 
 242  0
         for (Iterator i = messages.values().iterator(); i.hasNext();) {
 243  0
             actionItems.add(i.next());
 244  
         }
 245  
 
 246  
         // Sort MessageItems based on the initial order the
 247  
         // property/key was added to MessageList.
 248  0
         Collections.sort(actionItems, ACTION_ITEM_COMPARATOR);
 249  
 
 250  0
         for (Iterator i = actionItems.iterator(); i.hasNext();) {
 251  0
             MessageItem ami = (MessageItem) i.next();
 252  
 
 253  0
             for (Iterator msgs = ami.getList().iterator(); msgs.hasNext();) {
 254  0
                 results.add(msgs.next());
 255  
             }
 256  0
         }
 257  
 
 258  0
         return results.iterator();
 259  
     }
 260  
 
 261  
     /**
 262  
      * Return the set of messages related to a specific property.
 263  
      * If there are no such messages, an empty enumeration is returned.
 264  
      *
 265  
      * @param property Property name
 266  
      * @return Messages related to a specific property.
 267  
      */
 268  
     public Iterator get(String property) {
 269  0
         this.accessed = true;
 270  
         
 271  0
         MessageItem item = (MessageItem) messages.get(property);
 272  
         
 273  0
         return (item == null)
 274  
             ? Collections.EMPTY_LIST.iterator()
 275  
             : item.getList().iterator();
 276  
     }
 277  
 
 278  
     /**
 279  
      * Return the set of property names for which at least one message has
 280  
      * been recorded.  If there are no messages, an empty Iterator is returned.
 281  
      * If you have recorded global messages, the String value of
 282  
      * <code>MessageList.GLOBAL_MESSAGE</code> will be one of the returned
 283  
      * property names.
 284  
      *
 285  
      * @return The property names.
 286  
      */
 287  
     public Iterator properties() {
 288  0
         return messages.keySet().iterator();
 289  
     }
 290  
 
 291  
     /**
 292  
      * Return the number of messages recorded for all properties (including
 293  
      * global messages).  <strong>NOTE</strong> - it is more efficient to call
 294  
      * <code>isEmpty()</code> if all you care about is whether or not there are
 295  
      * any messages at all.
 296  
      *
 297  
      * @return The number of messages.
 298  
      */
 299  
     public int size() {
 300  
 
 301  0
         int total = 0;
 302  
 
 303  0
         for (Iterator i = messages.values().iterator(); i.hasNext();) {
 304  0
             MessageItem ami = (MessageItem) i.next();
 305  0
             total += ami.getList().size();
 306  0
         }
 307  
 
 308  0
         return total;
 309  
     }
 310  
 
 311  
     /**
 312  
      * Return the number of messages associated with the specified property.
 313  
      *
 314  
      * @param property Property name (or MessageList.GLOBAL_MESSAGE_KEY
 315  
      * @return The number of messages for a specific property.
 316  
      */
 317  
     public int size(String property) {
 318  
 
 319  0
         MessageItem ami = (MessageItem) messages.get(property);
 320  
 
 321  0
         return (ami == null) ? 0 : ami.getList().size();
 322  
     }
 323  
     
 324  
     /**
 325  
      * Returns a String representation of this MessageList's 
 326  
      * [property name]=[message list] mapping.
 327  
      * @see java.lang.Object#toString()
 328  
      */    
 329  
     public String toString() {
 330  0
         return this.messages.toString();
 331  
     }
 332  
 
 333  
     /**
 334  
      * Holds messages for a specified property.
 335  
      */    
 336  
     protected static class MessageItem implements Serializable {
 337  
 
 338  
         /**
 339  
          * The list of <code>Message</code>s.
 340  
          */
 341  0
         private List list = null;
 342  
 
 343  
         /**
 344  
          * The position in the list of messages.
 345  
          */
 346  0
         private int order = 0;
 347  
 
 348  
         /**
 349  
          * Construct a MessageItem with a list of messages
 350  
          * and specified order.
 351  
          * @param list List of Messages.
 352  
          * @param order Order.
 353  
          */
 354  0
         public MessageItem(List list, int order) {
 355  0
             this.list = list;
 356  0
             this.order = order;
 357  0
         }
 358  
 
 359  
         /**
 360  
          * @return The list of messsages.
 361  
          */
 362  
         public List getList() {
 363  0
             return list;
 364  
         }
 365  
 
 366  
         /**
 367  
          * @param list The list of messsages.
 368  
          */
 369  
         public void setList(List list) {
 370  0
             this.list = list;
 371  0
         }
 372  
 
 373  
         /**
 374  
          * @return The order.
 375  
          */
 376  
         public int getOrder() {
 377  0
             return order;
 378  
         }
 379  
 
 380  
         /**
 381  
          * @param order The order.
 382  
          */
 383  
         public void setOrder(int order) {
 384  0
             this.order = order;
 385  0
         }
 386  
 
 387  
     }
 388  
 
 389  
 }