1
2
3
4
5
6
7
8
9
10
11 package org.mule.routing.inbound;
12
13 import org.mule.umo.MessagingException;
14 import org.mule.umo.UMOEvent;
15
16 import java.util.Arrays;
17 import java.util.Comparator;
18
19 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
20 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentMap;
21
22
23
24
25
26
27
28
29 public abstract class AbstractEventResequencer extends SelectiveConsumer
30 {
31 protected static final String NO_CORRELATION_ID = "no-id";
32
33 private final ConcurrentMap eventGroups = new ConcurrentHashMap();
34 private volatile Comparator comparator;
35
36 public AbstractEventResequencer()
37 {
38 super();
39 }
40
41 public Comparator getComparator()
42 {
43 return comparator;
44 }
45
46 public void setComparator(Comparator eventComparator)
47 {
48 this.comparator = eventComparator;
49 }
50
51
52 public UMOEvent[] process(UMOEvent event) throws MessagingException
53 {
54 UMOEvent[] result = null;
55
56 if (this.isMatch(event))
57 {
58
59 boolean miss = false;
60
61
62 final Object groupId = this.getEventGroupIdForEvent(event);
63
64
65 while (true)
66 {
67 if (miss)
68 {
69 try
70 {
71
72 Thread.sleep(1);
73 }
74 catch (InterruptedException interrupted)
75 {
76 Thread.currentThread().interrupt();
77 }
78 }
79
80
81 EventGroup group = this.getEventGroup(groupId);
82
83
84 if (group == null)
85 {
86
87 group = this.addEventGroup(this.createEventGroup(event, groupId));
88 }
89
90
91 synchronized (group)
92 {
93
94 if (group != this.getEventGroup(groupId))
95 {
96
97 miss = true;
98 continue;
99 }
100
101
102 group.addEvent(event);
103
104 if (this.shouldResequenceEvents(group))
105 {
106 result = this.resequenceEvents(group);
107 this.removeEventGroup(group);
108 }
109
110
111 break;
112 }
113 }
114 }
115
116 return result;
117 }
118
119
120
121
122 protected EventGroup createEventGroup(UMOEvent event, Object groupId)
123 {
124 return new EventGroup(groupId);
125 }
126
127
128
129
130 protected Object getEventGroupIdForEvent(UMOEvent event)
131 {
132 String groupId = event.getMessage().getCorrelationId();
133
134 if (groupId == null)
135 {
136 groupId = NO_CORRELATION_ID;
137 }
138
139 return groupId;
140 }
141
142
143
144
145 protected EventGroup getEventGroup(Object groupId)
146 {
147 return (EventGroup) eventGroups.get(groupId);
148 }
149
150
151
152
153 protected EventGroup addEventGroup(EventGroup group)
154 {
155 EventGroup previous = (EventGroup) eventGroups.putIfAbsent(group.getGroupId(), group);
156
157
158 return (previous != null ? previous : group);
159 }
160
161
162
163
164 protected void removeEventGroup(EventGroup group)
165 {
166 eventGroups.remove(group.getGroupId());
167 }
168
169
170
171
172
173
174
175
176
177 protected UMOEvent[] resequenceEvents(EventGroup events)
178 {
179 if (events == null || events.size() == 0)
180 {
181 return EventGroup.EMPTY_EVENTS_ARRAY;
182 }
183
184 UMOEvent[] result = events.toArray();
185 Comparator cmp = this.getComparator();
186
187 if (cmp != null)
188 {
189 Arrays.sort(result, cmp);
190 }
191 else
192 {
193 logger.debug("Event comparator is null, events were not reordered");
194 }
195
196 return result;
197 }
198
199
200
201
202
203
204
205 protected abstract boolean shouldResequenceEvents(EventGroup events);
206
207 }