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