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