1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport;
12
13 import org.mule.api.MuleException;
14 import org.mule.api.MuleRuntimeException;
15 import org.mule.api.context.WorkManager;
16 import org.mule.api.endpoint.ImmutableEndpoint;
17 import org.mule.api.transport.Connectable;
18 import org.mule.api.transport.ConnectionStrategy;
19 import org.mule.api.transport.Connector;
20 import org.mule.config.i18n.CoreMessages;
21 import org.mule.context.notification.ConnectionNotification;
22 import org.mule.util.ClassUtils;
23
24 import java.beans.ExceptionListener;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29
30
31
32 public abstract class AbstractConnectable implements Connectable, ExceptionListener
33 {
34
35
36
37
38 protected transient Log logger = LogFactory.getLog(getClass());
39
40 protected final ImmutableEndpoint endpoint;
41 protected final AbstractConnector connector;
42
43 protected boolean disposed = false;
44
45 protected ConnectionStrategy connectionStrategy;
46
47 protected volatile boolean connecting = false;
48 protected volatile boolean connected = false;
49
50 public AbstractConnectable(ImmutableEndpoint endpoint)
51 {
52 this.endpoint = endpoint;
53 this.connector = (AbstractConnector) endpoint.getConnector();
54
55 connectionStrategy = endpoint.getConnectionStrategy();
56 if (connectionStrategy instanceof AbstractConnectionStrategy)
57 {
58
59
60
61 final AbstractConnectionStrategy connStrategy = (AbstractConnectionStrategy) connectionStrategy;
62 if (connStrategy.isDoThreading())
63 {
64 if (logger.isDebugEnabled())
65 {
66 logger.debug("Overriding doThreading to false on " + connStrategy);
67 }
68 connStrategy.setDoThreading(false);
69 }
70 }
71
72 if (isDoThreading())
73 {
74 try
75 {
76 connector.getDispatcherWorkManager();
77 }
78 catch (MuleException e)
79 {
80 disposeAndLogException();
81 throw new MuleRuntimeException(CoreMessages.failedToStart("WorkManager"), e);
82 }
83 }
84 }
85
86 protected void disposeAndLogException()
87 {
88 try
89 {
90 dispose();
91 }
92 catch (Throwable t)
93 {
94 logger.error("Could not dispose of the message dispatcher!", t);
95 }
96 }
97
98
99
100
101
102
103 public void exceptionThrown(Exception e)
104 {
105 try
106 {
107 getConnector().handleException(e);
108 }
109 finally
110 {
111 dispose();
112 }
113 }
114
115 public boolean validate()
116 {
117
118 return !disposed;
119 }
120
121 public void activate()
122 {
123
124 }
125
126 public void passivate()
127 {
128
129 }
130
131
132
133
134 public final synchronized void dispose()
135 {
136 if (!disposed)
137 {
138 try
139 {
140 try
141 {
142 this.disconnect();
143 }
144 catch (Exception e)
145 {
146
147 logger.warn(e.getMessage(), e);
148 }
149
150 this.doDispose();
151 }
152 finally
153 {
154 disposed = true;
155 }
156 }
157 }
158
159 public Connector getConnector()
160 {
161 return connector;
162 }
163
164 public ImmutableEndpoint getEndpoint()
165 {
166 return endpoint;
167 }
168
169 public synchronized void connect() throws Exception
170 {
171 if (disposed)
172 {
173 throw new IllegalStateException("Requester/dispatcher has been disposed; cannot connect to resource");
174 }
175
176 if (connected)
177 {
178 return;
179 }
180
181 if (!connecting)
182 {
183 connecting = true;
184
185 if (logger.isDebugEnabled())
186 {
187 logger.debug("Connecting: " + this);
188 }
189
190 connectionStrategy.connect(this);
191
192 logger.info("Connected: " + this);
193 return;
194 }
195
196 try
197 {
198
199 connectionStrategy.connect(connector);
200
201 this.doConnect();
202 connected = true;
203 connecting = false;
204
205 connector.fireNotification(new ConnectionNotification(this, getConnectEventId(endpoint),
206 ConnectionNotification.CONNECTION_CONNECTED));
207 }
208 catch (Exception e)
209 {
210 connected = false;
211 connecting = false;
212
213 connector.fireNotification(new ConnectionNotification(this, getConnectEventId(endpoint),
214 ConnectionNotification.CONNECTION_FAILED));
215
216 if (e instanceof ConnectException)
217 {
218 throw (ConnectException) e;
219 }
220 else
221 {
222 throw new ConnectException(e, this);
223 }
224 }
225 }
226
227 public synchronized void disconnect() throws Exception
228 {
229 if (!connected)
230 {
231 return;
232 }
233
234 if (logger.isDebugEnabled())
235 {
236 logger.debug("Disconnecting: " + this);
237 }
238
239 this.doDisconnect();
240 connected = false;
241
242 logger.info("Disconnected: " + this);
243
244 connector.fireNotification(new ConnectionNotification(this, getConnectEventId(endpoint),
245 ConnectionNotification.CONNECTION_DISCONNECTED));
246 }
247
248 protected String getConnectEventId(ImmutableEndpoint endpoint)
249 {
250 return connector.getName() + ".dispatcher(" + endpoint.getEndpointURI().getUri() + ")";
251 }
252
253 public final boolean isConnected()
254 {
255 return connected;
256 }
257
258 protected boolean isDoThreading ()
259 {
260 return connector.getDispatcherThreadingProfile().isDoThreading();
261 }
262
263
264
265
266
267
268 public String getConnectionDescription()
269 {
270 return endpoint.getEndpointURI().toString();
271 }
272
273 public synchronized void reconnect() throws Exception
274 {
275 disconnect();
276 connect();
277 }
278
279 protected abstract void doDispose();
280
281 protected abstract void doConnect() throws Exception;
282
283 protected abstract void doDisconnect() throws Exception;
284
285
286 public String toString()
287 {
288 final StringBuffer sb = new StringBuffer(80);
289 sb.append(ClassUtils.getSimpleName(this.getClass()));
290 sb.append("{this=").append(Integer.toHexString(System.identityHashCode(this)));
291 sb.append(", endpoint=").append(endpoint.getEndpointURI().getUri());
292 sb.append(", disposed=").append(disposed);
293 sb.append('}');
294 return sb.toString();
295 }
296 }