1
2
3
4
5
6
7
8
9
10
11 package org.mule.source;
12
13 import org.mule.api.MuleEvent;
14 import org.mule.api.MuleException;
15 import org.mule.api.construct.FlowConstruct;
16 import org.mule.api.construct.FlowConstructAware;
17 import org.mule.api.lifecycle.Disposable;
18 import org.mule.api.lifecycle.Initialisable;
19 import org.mule.api.lifecycle.InitialisationException;
20 import org.mule.api.lifecycle.Lifecycle;
21 import org.mule.api.lifecycle.LifecycleException;
22 import org.mule.api.lifecycle.Startable;
23 import org.mule.api.lifecycle.Stoppable;
24 import org.mule.api.processor.MessageProcessor;
25 import org.mule.api.source.CompositeMessageSource;
26 import org.mule.api.source.MessageSource;
27 import org.mule.config.i18n.CoreMessages;
28 import org.mule.util.ObjectUtils;
29
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.List;
33 import java.util.concurrent.atomic.AtomicBoolean;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37
38
39
40
41
42
43
44
45
46
47
48 public class StartableCompositeMessageSource
49 implements CompositeMessageSource, Lifecycle, FlowConstructAware
50 {
51 protected static final Log log = LogFactory.getLog(StartableCompositeMessageSource.class);
52
53 protected MessageProcessor listener;
54 protected AtomicBoolean initialised = new AtomicBoolean(false);
55 protected AtomicBoolean started = new AtomicBoolean(false);
56 protected final List<MessageSource> sources = Collections.synchronizedList(new ArrayList<MessageSource>());
57 protected AtomicBoolean starting = new AtomicBoolean(false);
58 protected FlowConstruct flowConstruct;
59 private final MessageProcessor internalListener = new InternalMessageProcessor();
60
61 public void addSource(MessageSource source) throws MuleException
62 {
63 synchronized (sources)
64 {
65 sources.add(source);
66 }
67 source.setListener(internalListener);
68 if (initialised.get())
69 {
70 if (source instanceof FlowConstructAware)
71 {
72 ((FlowConstructAware) source).setFlowConstruct(flowConstruct);
73 }
74 if (source instanceof Initialisable)
75 {
76 ((Initialisable) source).initialise();
77 }
78 }
79 if (started.get() && source instanceof Startable)
80 {
81 ((Startable) source).start();
82 }
83 }
84
85 public void removeSource(MessageSource source) throws MuleException
86 {
87 if (started.get())
88 {
89 if (source instanceof Stoppable)
90 {
91 ((Stoppable) source).stop();
92 }
93 if (source instanceof Disposable)
94 {
95 ((Disposable) source).dispose();
96 }
97 }
98 synchronized (sources)
99 {
100 sources.remove(source);
101 }
102 }
103
104 public void setMessageSources(List<MessageSource> sources) throws MuleException
105 {
106 this.sources.clear();
107 for (MessageSource messageSource : sources)
108 {
109 addSource(messageSource);
110 }
111 }
112
113 public void initialise() throws InitialisationException
114 {
115 if (listener == null)
116 {
117 throw new InitialisationException(CoreMessages.objectIsNull("listener"), this);
118 }
119 synchronized (sources)
120 {
121 for (MessageSource source : sources)
122 {
123 if (source instanceof FlowConstructAware)
124 {
125 ((FlowConstructAware) source).setFlowConstruct(flowConstruct);
126 }
127 if (source instanceof Initialisable)
128 {
129 ((Initialisable) source).initialise();
130 }
131 }
132 }
133 initialised.set(true);
134 }
135
136 public void start() throws MuleException
137 {
138 if (listener == null)
139 {
140 throw new LifecycleException(CoreMessages.objectIsNull("listener"), this);
141 }
142
143 synchronized (sources)
144 {
145 starting.set(true);
146 for (MessageSource source : sources)
147 {
148 if (source instanceof Startable)
149 {
150 ((Startable) source).start();
151 }
152 }
153
154 started.set(true);
155 starting.set(false);
156 }
157 }
158
159 public void stop() throws MuleException
160 {
161 synchronized (sources)
162 {
163 for (MessageSource source : sources)
164 {
165 if (source instanceof Stoppable)
166 {
167 ((Stoppable) source).stop();
168 }
169 }
170
171 started.set(false);
172 }
173 }
174
175 public void dispose()
176 {
177 synchronized (sources)
178 {
179 for (MessageSource source : sources)
180 {
181 if (source instanceof Disposable)
182 {
183 ((Disposable) source).dispose();
184 }
185 }
186 }
187 }
188
189 public void setListener(MessageProcessor listener)
190 {
191 this.listener = listener;
192 }
193
194 public void setFlowConstruct(FlowConstruct pattern)
195 {
196 this.flowConstruct = pattern;
197
198 }
199
200 @Override
201 public List<MessageSource> getSources()
202 {
203 return sources;
204 }
205
206 @Override
207 public String toString()
208 {
209 return String.format("%s [listener=%s, sources=%s, started=%s]", getClass().getSimpleName(),
210 listener, sources, started);
211 }
212
213 private class InternalMessageProcessor implements MessageProcessor
214 {
215 public InternalMessageProcessor()
216 {
217 super();
218 }
219
220 public MuleEvent process(MuleEvent event) throws MuleException
221 {
222 if (started.get() || starting.get())
223 {
224 return listener.process(event);
225 }
226 else
227 {
228
229 throw new IllegalStateException(String.format(
230 "A message was receieved from MessageSource, but CompositeMessageSource is stopped.%n"
231 + " Message: %s%n" + " CompositeMessageSource: %s", event, this));
232 }
233 }
234
235 @Override
236 public String toString()
237 {
238 return ObjectUtils.toString(this);
239 }
240 }
241 }