1
2
3
4
5
6
7
8
9
10
11 package org.mule.routing;
12
13 import org.mule.DefaultMessageCollection;
14 import org.mule.DefaultMuleEvent;
15 import org.mule.api.MuleContext;
16 import org.mule.api.MuleEvent;
17 import org.mule.api.MuleException;
18 import org.mule.api.MuleMessageCollection;
19 import org.mule.api.config.MuleProperties;
20 import org.mule.api.store.ListableObjectStore;
21 import org.mule.api.store.ObjectStoreException;
22 import org.mule.api.store.ObjectStoreManager;
23 import org.mule.util.ClassUtils;
24 import org.mule.util.MuleLogger;
25 import org.mule.util.store.DeserializationPostInitialisable;
26
27 import java.io.Serializable;
28 import java.util.Iterator;
29 import java.util.List;
30
31 import org.apache.commons.collections.IteratorUtils;
32
33
34
35
36
37
38 public class EventGroup implements Comparable<EventGroup>, Serializable, DeserializationPostInitialisable
39 {
40
41
42
43 private static final long serialVersionUID = 953739659615692697L;
44
45 public static final MuleEvent[] EMPTY_EVENTS_ARRAY = new MuleEvent[0];
46
47 transient private ObjectStoreManager objectStoreManager = null;
48
49 private final Object groupId;
50 transient ListableObjectStore<MuleEvent> events;
51 private final long created;
52 private final int expectedSize;
53 transient private MuleContext muleContext;
54 private final String storePrefix;
55 private String commonRootId = null;
56 private static boolean hasNoCommonRootId = false;
57
58 public static final String DEFAULT_STORE_PREFIX = "DEFAULT_STORE";
59
60 public EventGroup(Object groupId, MuleContext muleContext)
61 {
62 this(groupId, muleContext, -1, false, DEFAULT_STORE_PREFIX);
63 }
64
65 public EventGroup(Object groupId,
66 MuleContext muleContext,
67 int expectedSize,
68 boolean storeIsPersistent,
69 String storePrefix)
70 {
71 super();
72 this.created = System.nanoTime();
73 this.muleContext = muleContext;
74 this.storePrefix = storePrefix;
75
76 String storeKey = storePrefix + ".eventGroup." + groupId;
77 this.events = getObjectStoreManager().getObjectStore(storeKey, storeIsPersistent);
78
79 this.expectedSize = expectedSize;
80 this.groupId = groupId;
81 }
82
83
84
85
86
87
88
89
90
91 @Override
92 @SuppressWarnings("unchecked")
93 public int compareTo(EventGroup other)
94 {
95 Object otherId = other.getGroupId();
96
97 if (groupId instanceof Comparable<?> && otherId instanceof Comparable<?>)
98 {
99 return ((Comparable<Object>) groupId).compareTo(otherId);
100 }
101 else
102 {
103 long diff = created - other.getCreated();
104 return (diff > 0 ? 1 : (diff < 0 ? -1 : 0));
105 }
106 }
107
108
109
110
111
112
113
114 @Override
115 public boolean equals(Object obj)
116 {
117 if (this == obj)
118 {
119 return true;
120 }
121
122 if (!(obj instanceof EventGroup))
123 {
124 return false;
125 }
126
127 final EventGroup other = (EventGroup) obj;
128 if (groupId == null)
129 {
130 return (other.groupId == null);
131 }
132
133 return groupId.equals(other.groupId);
134 }
135
136
137
138
139
140
141
142 @Override
143 public int hashCode()
144 {
145 return groupId.hashCode();
146 }
147
148
149
150
151
152
153
154 public Object getGroupId()
155 {
156 return groupId;
157 }
158
159
160
161
162
163
164
165
166
167
168
169 @SuppressWarnings("unchecked")
170 public Iterator<MuleEvent> iterator() throws ObjectStoreException
171 {
172 synchronized (events)
173 {
174 if (events.allKeys().isEmpty())
175 {
176 return IteratorUtils.emptyIterator();
177 }
178 else
179 {
180 return IteratorUtils.arrayIterator(this.toArray());
181 }
182 }
183 }
184
185
186
187
188
189
190
191 public MuleEvent[] toArray() throws ObjectStoreException
192 {
193 synchronized (events)
194 {
195 if (events.allKeys().isEmpty())
196 {
197 return EMPTY_EVENTS_ARRAY;
198 }
199 List<Serializable> keys = events.allKeys();
200 MuleEvent[] eventArray = new MuleEvent[keys.size()];
201 for (int i = 0; i < keys.size(); i++)
202 {
203 eventArray[i] = events.retrieve(keys.get(i));
204 }
205 return eventArray;
206 }
207 }
208
209
210
211
212
213
214
215 public void addEvent(MuleEvent event) throws ObjectStoreException
216 {
217 synchronized (events)
218 {
219
220
221 Serializable key=event.getId()+event.getMessage().getCorrelationSequence();
222 events.store(key, event);
223
224 if (!hasNoCommonRootId)
225 {
226 String rootId = event.getMessage().getMessageRootId();
227 if (commonRootId == null)
228 {
229 commonRootId = rootId;
230 }
231 else if (!commonRootId.equals(rootId))
232 {
233 hasNoCommonRootId = true;
234 commonRootId = null;
235 }
236 }
237 }
238 }
239
240
241
242
243
244
245
246
247 public void removeEvent(MuleEvent event) throws ObjectStoreException
248 {
249 synchronized (events)
250 {
251 events.remove(event.getId());
252 }
253 }
254
255
256
257
258
259
260 public long getCreated()
261 {
262 return created;
263 }
264
265
266
267
268
269
270 public int size()
271 {
272 synchronized (events)
273 {
274 try
275 {
276 return events.allKeys().size();
277 }
278 catch (ObjectStoreException e)
279 {
280
281 return -1;
282 }
283 }
284 }
285
286
287
288
289
290
291
292 public int expectedSize()
293 {
294 return expectedSize;
295 }
296
297
298
299
300
301
302 public void clear() throws ObjectStoreException
303 {
304 getObjectStoreManager().disposeStore(events);
305 }
306
307 @Override
308 public String toString()
309 {
310 StringBuffer buf = new StringBuffer(80);
311 buf.append(ClassUtils.getSimpleName(this.getClass()));
312 buf.append(" {");
313 buf.append("id=").append(groupId);
314 buf.append(", expected size=").append(expectedSize);
315
316 try
317 {
318 synchronized (events)
319 {
320 int currentSize;
321
322 currentSize = events.allKeys().size();
323
324 buf.append(", current events=").append(currentSize);
325
326 if (currentSize > 0)
327 {
328 buf.append(" [");
329 Iterator<Serializable> i = events.allKeys().iterator();
330 while (i.hasNext())
331 {
332 Serializable id = i.next();
333 buf.append(events.retrieve(id).getMessage().getUniqueId());
334 if (i.hasNext())
335 {
336 buf.append(", ");
337 }
338 }
339 buf.append(']');
340 }
341 }
342 }
343 catch (ObjectStoreException e)
344 {
345 buf.append("ObjectStoreException " + e + " caught:" + e.getMessage());
346 }
347
348 buf.append('}');
349
350 return buf.toString();
351 }
352
353 public MuleMessageCollection toMessageCollection() throws ObjectStoreException
354 {
355 MuleMessageCollection col;
356 synchronized (events)
357 {
358 if (events.allKeys().isEmpty())
359 {
360 col = new DefaultMessageCollection(null);
361 }
362 col = new DefaultMessageCollection(muleContext);
363
364 for (Serializable id : events.allKeys())
365 {
366 col.addMessage(events.retrieve(id).getMessage());
367 }
368 }
369 return col;
370 }
371
372 public String getCommonRootId()
373 {
374 return commonRootId;
375 }
376
377 public MuleEvent getMessageCollectionEvent()
378 {
379 try
380 {
381 if (size() > 0)
382 {
383
384 DefaultMuleEvent muleEvent = new DefaultMuleEvent(toMessageCollection(),
385 events.retrieve(events.allKeys().get(0)));
386 if (getCommonRootId() != null)
387 {
388 muleEvent.getMessage().setMessageRootId(commonRootId);
389 }
390 return muleEvent;
391 }
392 else
393 {
394 return null;
395 }
396 }
397 catch (ObjectStoreException e)
398 {
399
400 return null;
401 }
402 }
403
404 private ObjectStoreManager getObjectStoreManager()
405 {
406 if (objectStoreManager == null)
407 {
408 objectStoreManager = (ObjectStoreManager) muleContext.getRegistry().get(
409 MuleProperties.OBJECT_STORE_MANAGER);
410 }
411 return objectStoreManager;
412 }
413
414 public void initAfterDeserialisation(MuleContext context) throws MuleException
415 {
416 this.muleContext = context;
417
418 String storeKey = storePrefix + ".eventGroup." + groupId;
419 this.events = getObjectStoreManager().getObjectStore(storeKey, true);
420 }
421 }