Coverage Report - org.mule.routing.inbound.EventGroup
 
Classes in this File Line Coverage Branch Coverage Complexity
EventGroup
72%
57/79
67%
20/30
2
 
 1  
 /*
 2  
  * $Id: EventGroup.java 11531 2008-04-08 15:34:34Z rossmason $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.routing.inbound;
 12  
 
 13  
 import org.mule.api.MuleEvent;
 14  
 import org.mule.api.MuleMessageCollection;
 15  
 import org.mule.util.ClassUtils;
 16  
 import org.mule.DefaultMessageCollection;
 17  
 
 18  
 import java.io.Serializable;
 19  
 import java.util.ArrayList;
 20  
 import java.util.Iterator;
 21  
 import java.util.List;
 22  
 
 23  
 import edu.emory.mathcs.backport.java.util.concurrent.helpers.Utils;
 24  
 
 25  
 import org.apache.commons.collections.IteratorUtils;
 26  
 
 27  
 /**
 28  
  * <code>EventGroup</code> is a holder over events grouped by a common group Id.
 29  
  * This can be used by components such as routers to managed related events.
 30  
  */
 31  
 // @ThreadSafe
 32  
 public class EventGroup implements Comparable, Serializable
 33  
 {
 34  
     /**
 35  
      * Serial version
 36  
      */
 37  
     private static final long serialVersionUID = 953739659615692697L;
 38  
 
 39  2
     public static final MuleEvent[] EMPTY_EVENTS_ARRAY = new MuleEvent[0];
 40  
 
 41  
     private final Object groupId;
 42  
     // @GuardedBy("this")
 43  
     private final List events;
 44  
     private final long created;
 45  
     private final int expectedSize;
 46  
 
 47  
     public EventGroup(Object groupId)
 48  
     {
 49  36
         this(groupId, -1);
 50  36
     }
 51  
 
 52  
     public EventGroup(Object groupId, int expectedSize)
 53  
     {
 54  38
         super();
 55  38
         this.created = Utils.nanoTime();
 56  38
         this.events = new ArrayList(expectedSize > 0 ? expectedSize : 10);
 57  38
         this.expectedSize = expectedSize;
 58  38
         this.groupId = groupId;
 59  38
     }
 60  
 
 61  
     /**
 62  
      * Compare this EventGroup to another one. If the receiver and the argument both
 63  
      * have groupIds that are {@link Comparable}, they are used for the comparison;
 64  
      * otherwise - since the id can be any object - the group creation time stamp is
 65  
      * used as fallback. Older groups are considered "smaller".
 66  
      * 
 67  
      * @see java.lang.Comparable#compareTo(java.lang.Object)
 68  
      */
 69  
     public int compareTo(Object o)
 70  
     {
 71  16
         EventGroup other = (EventGroup) o;
 72  14
         Object otherId = other.getGroupId();
 73  
 
 74  12
         if (groupId instanceof Comparable && otherId instanceof Comparable)
 75  
         {
 76  8
             return ((Comparable) groupId).compareTo(otherId);
 77  
         }
 78  
         else
 79  
         {
 80  4
             long diff = created - other.getCreated();
 81  4
             return (diff > 0 ? 1 : (diff < 0 ? -1 : 0));
 82  
         }
 83  
     }
 84  
 
 85  
     /**
 86  
      * Compares two EventGroups for equality. EventGroups are considered equal when
 87  
      * their groupIds (as returned by {@link #getGroupId()}) are equal.
 88  
      * 
 89  
      * @see java.lang.Object#equals(Object)
 90  
      */
 91  
     // //@Override
 92  
     public boolean equals(Object obj)
 93  
     {
 94  20
         if (this == obj)
 95  
         {
 96  0
             return true;
 97  
         }
 98  
 
 99  20
         if (!(obj instanceof EventGroup))
 100  
         {
 101  0
             return false;
 102  
         }
 103  
 
 104  20
         final EventGroup other = (EventGroup) obj;
 105  20
         if (groupId == null)
 106  
         {
 107  0
             return (other.groupId == null);
 108  
         }
 109  
 
 110  20
         return groupId.equals(other.groupId);
 111  
     }
 112  
 
 113  
     /**
 114  
      * The hashCode of an EventGroup is derived from the object returned by
 115  
      * {@link #getGroupId()}.
 116  
      * 
 117  
      * @see java.lang.Object#hashCode()
 118  
      */
 119  
     // //@Override
 120  
     public int hashCode()
 121  
     {
 122  20
         return groupId.hashCode();
 123  
     }
 124  
 
 125  
     /**
 126  
      * Returns an identifier for this EventGroup. It is recommended that this id is
 127  
      * unique and {@link Comparable} e.g. a UUID.
 128  
      * 
 129  
      * @return the id of this event group
 130  
      */
 131  
     public Object getGroupId()
 132  
     {
 133  26
         return groupId;
 134  
     }
 135  
 
 136  
     /**
 137  
      * Returns an iterator over a snapshot copy of this group's collected events. If
 138  
      * you need to iterate over the group and e.g. remove select events, do so via
 139  
      * {@link #removeEvent(MuleEvent)}. If you need to do so atomically in order to
 140  
      * prevent e.g. concurrent reception/aggregation of the group during iteration,
 141  
      * wrap the iteration in a synchronized block on the group instance.
 142  
      * 
 143  
      * @return an iterator over collected {@link MuleEvent}s.
 144  
      */
 145  
     public Iterator iterator()
 146  
     {
 147  10
         synchronized (this)
 148  
         {
 149  10
             if (events.isEmpty())
 150  
             {
 151  2
                 return IteratorUtils.emptyIterator();
 152  
             }
 153  
             else
 154  
             {
 155  8
                 return IteratorUtils.arrayIterator(this.toArray());
 156  
             }
 157  0
         }
 158  
     }
 159  
 
 160  
     /**
 161  
      * Returns a snapshot of collected events in this group.
 162  
      * 
 163  
      * @return an array of collected {@link MuleEvent}s.
 164  
      */
 165  
     public MuleEvent[] toArray()
 166  
     {
 167  14
         synchronized (this)
 168  
         {
 169  14
             if (events.isEmpty())
 170  
             {
 171  0
                 return EMPTY_EVENTS_ARRAY;
 172  
             }
 173  
 
 174  14
             return (MuleEvent[]) events.toArray(EMPTY_EVENTS_ARRAY);
 175  0
         }
 176  
     }
 177  
 
 178  
     /**
 179  
      * Add the given event to this group.
 180  
      * 
 181  
      * @param event the event to add
 182  
      */
 183  
     public void addEvent(MuleEvent event)
 184  
     {
 185  34
         synchronized (this)
 186  
         {
 187  34
             events.add(event);
 188  34
         }
 189  34
     }
 190  
 
 191  
     /**
 192  
      * Remove the given event from the group.
 193  
      * 
 194  
      * @param event the evnt to remove
 195  
      */
 196  
     public void removeEvent(MuleEvent event)
 197  
     {
 198  0
         synchronized (this)
 199  
         {
 200  0
             events.remove(event);
 201  0
         }
 202  0
     }
 203  
 
 204  
     /**
 205  
      * Return the creation timestamp of the current group.
 206  
      * 
 207  
      * @return the timestamp when this group was instantiated.
 208  
      * @see {@link Utils#nanoTime()}
 209  
      */
 210  
     public long getCreated()
 211  
     {
 212  4
         return created;
 213  
     }
 214  
 
 215  
     /**
 216  
      * Returns the number of events collected so far.
 217  
      * 
 218  
      * @return number of events in this group or 0 if the group is empty.
 219  
      */
 220  
     public int size()
 221  
     {
 222  8
         synchronized (this)
 223  
         {
 224  8
             return events.size();
 225  0
         }
 226  
     }
 227  
 
 228  
     /**
 229  
      * Returns the number of events that this EventGroup is expecting before
 230  
      * correlation can proceed.
 231  
      * 
 232  
      * @return expected number of events or -1 if no expected size was specified.
 233  
      */
 234  
     public int expectedSize()
 235  
     {
 236  0
         return expectedSize;
 237  
     }
 238  
 
 239  
     /**
 240  
      * Removes all events from this group.
 241  
      */
 242  
     public void clear()
 243  
     {
 244  0
         synchronized (this)
 245  
         {
 246  0
             events.clear();
 247  0
         }
 248  0
     }
 249  
 
 250  
     // //@Override
 251  
     public String toString()
 252  
     {
 253  6
         StringBuffer buf = new StringBuffer(80);
 254  6
         buf.append(ClassUtils.getSimpleName(this.getClass()));
 255  6
         buf.append(" {");
 256  6
         buf.append("id=").append(groupId);
 257  6
         buf.append(", expected size=").append(expectedSize);
 258  
 
 259  6
         synchronized (this)
 260  
         {
 261  6
             int currentSize = events.size();
 262  6
             buf.append(", current events=").append(currentSize);
 263  
 
 264  6
             if (currentSize > 0)
 265  
             {
 266  4
                 buf.append(" [");
 267  4
                 Iterator i = events.iterator();
 268  10
                 while (i.hasNext())
 269  
                 {
 270  6
                     MuleEvent event = (MuleEvent) i.next();
 271  6
                     buf.append(event.getMessage().getUniqueId());
 272  6
                     if (i.hasNext())
 273  
                     {
 274  2
                         buf.append(", ");
 275  
                     }
 276  6
                 }
 277  4
                 buf.append(']');
 278  
             }
 279  6
         }
 280  
 
 281  6
         buf.append('}');
 282  
 
 283  6
         return buf.toString();
 284  
     }
 285  
 
 286  
     public MuleMessageCollection toMessageCollection()
 287  
     {
 288  0
         MuleMessageCollection col = new DefaultMessageCollection();
 289  0
         for (Iterator iterator = events.iterator(); iterator.hasNext();)
 290  
         {
 291  0
             MuleEvent event = (MuleEvent) iterator.next();
 292  0
             col.addMessage(event.getMessage());
 293  0
         }
 294  0
         return col;
 295  
     }
 296  
 
 297  
 }