1
2
3
4
5
6
7
8
9
10
11 package org.mule.processor;
12
13 import org.mule.api.MessagingException;
14 import org.mule.api.MuleEvent;
15 import org.mule.api.MuleException;
16 import org.mule.api.config.ThreadingProfile;
17 import org.mule.api.context.WorkManager;
18 import org.mule.api.context.WorkManagerSource;
19 import org.mule.api.lifecycle.Startable;
20 import org.mule.api.lifecycle.Stoppable;
21 import org.mule.api.processor.MessageProcessor;
22 import org.mule.config.i18n.CoreMessages;
23 import org.mule.interceptor.ProcessingTimeInterceptor;
24 import org.mule.work.AbstractMuleEventWork;
25 import org.mule.work.MuleWorkManager;
26
27
28
29
30
31
32
33
34 public class AsyncInterceptingMessageProcessor extends AbstractInterceptingMessageProcessor
35 implements Startable, Stoppable
36 {
37 protected WorkManagerSource workManagerSource;
38 protected boolean doThreading = true;
39 protected WorkManager workManager;
40
41 public AsyncInterceptingMessageProcessor(WorkManagerSource workManagerSource)
42 {
43 this.workManagerSource = workManagerSource;
44 }
45
46 public AsyncInterceptingMessageProcessor(ThreadingProfile threadingProfile,
47 String name,
48 int shutdownTimeout)
49 {
50 this.doThreading = threadingProfile.isDoThreading();
51 workManager = threadingProfile.createWorkManager(name, shutdownTimeout);
52 workManagerSource = new WorkManagerSource()
53 {
54 public WorkManager getWorkManager() throws MuleException
55 {
56 return workManager;
57 }
58 };
59 }
60
61 public void start() throws MuleException
62 {
63 if (workManager != null)
64 {
65 workManager.start();
66 }
67 }
68
69 public void stop() throws MuleException
70 {
71 if (workManager != null)
72 {
73 workManager.dispose();
74 }
75 }
76
77 public MuleEvent process(MuleEvent event) throws MuleException
78 {
79 if (next == null)
80 {
81 return event;
82 }
83 else if (isProcessAsync(event))
84 {
85 processNextAsync(event);
86 return null;
87 }
88 else
89 {
90 MuleEvent response = processNext(event);
91 return response;
92 }
93 }
94
95 protected MuleEvent processNextTimed(MuleEvent event) throws MuleException
96 {
97 if (next == null)
98 {
99 return event;
100 }
101 else
102 {
103 if (logger.isTraceEnabled())
104 {
105 logger.trace("Invoking next MessageProcessor: '" + next.getClass().getName() + "' ");
106 }
107
108 MuleEvent response;
109 if (event.getFlowConstruct() != null)
110 {
111 response = new ProcessingTimeInterceptor(next, event.getFlowConstruct()).process(event);
112 }
113 else
114 {
115 response = processNext(event);
116 }
117 return response;
118 }
119 }
120
121 protected boolean isProcessAsync(MuleEvent event) throws MessagingException
122 {
123 if (event.isSynchronous() || event.isTransacted())
124 {
125 throw new MessagingException(
126 CoreMessages.createStaticMessage("Unable to process a synchonrous event asyncronously"),
127 event);
128 }
129 return doThreading && !event.isSynchronous();
130 }
131
132 protected void processNextAsync(MuleEvent event) throws MuleException
133 {
134 try
135 {
136 workManagerSource.getWorkManager().scheduleWork(new AsyncMessageProcessorWorker(event),
137 WorkManager.INDEFINITE, null, new AsyncWorkListener(next));
138 }
139 catch (Exception e)
140 {
141 new MessagingException(CoreMessages.errorSchedulingMessageProcessorForAsyncInvocation(next),
142 event, e);
143 }
144 }
145
146 class AsyncMessageProcessorWorker extends AbstractMuleEventWork
147 {
148 public AsyncMessageProcessorWorker(MuleEvent event)
149 {
150 super(event);
151 }
152
153 @Override
154 protected void doRun()
155 {
156 try
157 {
158 processNextTimed(event);
159 }
160 catch (Exception e)
161 {
162 event.getFlowConstruct().getExceptionListener().handleException(e, event);
163 }
164 }
165 }
166
167 }