Source code: org/mule/providers/AbstractConnector.java
1 /*
2 * $Header: /cvsroot/mule/mule/src/java/org/mule/providers/AbstractConnector.java,v 1.11 2003/10/20 21:44:38 rossmason Exp $
3 * $Revision: 1.11 $
4 * $Date: 2003/10/20 21:44:38 $
5 * ------------------------------------------------------------------------------------------------------
6 *
7 * Copyright (c) Cubis Limited. All rights reserved.
8 * http://www.cubis.co.uk
9 *
10 * The software in this package is published under the terms of the BSD
11 * style license a copy of which has been included with this distribution in
12 * the LICENSE.txt file.
13 *
14 */
15
16 package org.mule.providers;
17
18 import java.util.HashMap;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.mule.MuleManager;
23 import org.mule.MuleRuntimeException;
24 import org.mule.umo.UMOExceptionStrategy;
25 import org.mule.umo.provider.UMOConnector;
26 import org.mule.util.ExceptionListener;
27 import org.mule.util.NamedThreadPool;
28 import org.mule.util.Utility;
29
30 /**
31 * <p><code>AbstractConnector</code> provides base functionality for all connectors provided with Mule. Connectors are
32 * the mechanism used to connect to external systems and protocols in order to send and receive
33 * data.
34 * </p>
35 * <p>The <code>AbstractConnector</code> provides getter and setter methods for connector properties, name,
36 * transport name and protocol. It also provides methods to stop and start connecotors and sets up a dispatcher
37 * threadpool which allows deriving connectors the possibility to dispatch work to separate threads. This
38 * functionality is controlled with the <i>transport.connector.doThreading</i> property.
39 * </p>
40 *
41 * @author <a href="mailto:ross.mason@cubis.co.uk">Ross Mason</a>
42 * @version $Revision: 1.11 $
43 */
44 public abstract class AbstractConnector implements UMOConnector, ExceptionListener
45 {
46 /** The property name that specifies if a dispatch threadpool should be created */
47 public static final String DO_THREADING_PROPERTY = "transport.connector.doThreading";
48
49 /** Determines whether a dispatch threadpool should be created */
50 protected boolean doThreading = true;
51
52 /** The dispatcher threadpool */
53 private NamedThreadPool dispatchers = null;
54
55 /** Specifies if the connector started */
56 protected boolean started = false;
57
58 /** logger used by this class */
59 protected static transient Log log = LogFactory.getLog(AbstractConnector.class);
60
61 /** The name that identifies the connector */
62 protected String name = null;
63
64 /** The proptocol name the connector uses to communicate with the external system */
65 protected String protocol = null;
66
67 /** Holds the transport name of the connector i.e. the transport name maybe email but the
68 * protocol might be POP3 */
69 protected String transportName = null;
70
71 /** Holds any configuration properties for the connector */
72 protected HashMap properties = null;
73
74 /** The exception strategy used by this connector */
75 protected UMOExceptionStrategy exceptionStrategy = null;
76
77 /** Determines in the connector is alive and well */
78 protected boolean alive = true;
79
80 /* (non-Javadoc)
81 * @see org.mule.providers.UMOConnector#getName()
82 */
83 public String getName()
84 {
85 return name;
86 }
87
88 /* (non-Javadoc)
89 * @see org.mule.providers.UMOConnector#getProperties()
90 */
91 public HashMap getProperties()
92 {
93 return properties;
94 }
95
96 /* (non-Javadoc)
97 * @see org.mule.providers.UMOConnector#setName(java.lang.String)
98 */
99 public void setName(String newName)
100 {
101 if (log.isDebugEnabled())
102 log.debug("Set UMOConnector name to: " + newName);
103 name = newName;
104
105 }
106
107 /* (non-Javadoc)
108 * @see org.mule.providers.UMOConnector#setProperties(java.util.HashMap)
109 */
110 public void setProperties(HashMap newProps)
111 {
112 properties = newProps;
113 }
114 /* (non-Javadoc)
115 * @see org.mule.providers.UMOConnector#create(java.util.HashMap)
116 */
117 public synchronized void create(HashMap properties) throws Exception
118 {
119
120 Object temp = properties.remove("transport.name");
121 doThreading = Utility.getBooleanProperty(properties, DO_THREADING_PROPERTY, true);
122
123 if (doThreading)
124 {
125 int threads = MuleManager.getInstance().getConfiguration().getMaxThreadsActive();
126
127 dispatchers = new NamedThreadPool(threads, Thread.NORM_PRIORITY, getName() + ":Dispatcher");
128
129 dispatchers.setExceptionListener(this);
130 }
131
132 if (temp != null)
133 {
134 setTransportName((String) temp);
135 }
136
137 setProtocol(getProtocol());
138
139 setProperties(properties);
140
141 create();
142
143 }
144
145 /**
146 * A template method to perform any additional creating work by the deriving class
147 * @throws Exception if the derived create method fails
148 */
149 public abstract void create() throws Exception;
150
151 /* (non-Javadoc)
152 * @see org.mule.providers.UMOConnector#getProtocol()
153 */
154 public abstract String getProtocol();
155
156 /* (non-Javadoc)
157 * @see org.mule.providers.UMOConnector#getTransportName()
158 */
159 public String getTransportName()
160 {
161 return transportName;
162 }
163
164 /* (non-Javadoc)
165 * @see org.mule.providers.UMOConnector#setProtocol(java.lang.String)
166 */
167 public void setProtocol(String protocol)
168 {
169
170 this.protocol = protocol.toUpperCase();
171 if (log.isDebugEnabled())
172 log.debug("Set UMOConnector protocol to: " + this.protocol);
173 }
174
175 /* (non-Javadoc)
176 * @see org.mule.providers.UMOConnector#setTransportName(java.lang.String)
177 */
178 public void setTransportName(String name)
179 {
180 transportName = name.toUpperCase();
181 if (log.isDebugEnabled())
182 log.debug("Set UMOConnector transportName to: " + transportName);
183
184 }
185
186 /**
187 * @param key the property name
188 * @param value the value to assign to the property name
189 */
190 protected void setProperty(Object key, Object value)
191 {
192 properties.put(key, value);
193 if (log.isDebugEnabled())
194 log.debug("Set property on UMOConnector: " + key);
195 }
196
197 /**
198 * @param key the property name
199 * @param defaultValue the value if no property exists with the key
200 * @return the property value or the defaultValue
201 */
202 protected Object getProperty(Object key, Object defaultValue)
203 {
204 return Utility.getProperty(properties, key, defaultValue);
205 }
206
207 /**
208 * @param key the property name
209 * @return the corresponding property
210 */
211 protected Object getProperty(Object key)
212 {
213 return properties.get(key);
214 }
215
216 // /* (non-Javadoc)
217 // * @see java.lang.Object#clone()
218 // */
219 // public Object clone() throws CloneNotSupportedException
220 // {
221 // UMOConnector clone = null;
222 // try {
223 // clone = (UMOConnector) getClass().newInstance();
224 // clone.setName(name);
225 // clone.setProtocol(protocol);
226 // clone.setTransportName(transportName);
227 // clone.setProperties(properties);
228 // return clone;
229 // } catch (Exception e) {
230 // //This shuold never happen
231 // log.warn("Clone instanciation exception: " + e, e);
232 // }
233 // return null;
234 // }
235
236 /* (non-Javadoc)
237 * @see org.mule.umo.provider.UMOConnector#start()
238 */
239 public void start() throws Exception
240 {
241 if (!started)
242 {
243 startConnector();
244 started = true;
245 }
246 }
247
248 /* (non-Javadoc)
249 * @see org.mule.umo.provider.UMOConnector#isStarted()
250 */
251 public boolean isStarted()
252 {
253 return started;
254 }
255
256
257 /* (non-Javadoc)
258 * @see org.mule.umo.provider.UMOConnector#stop()
259 */
260 public void stop() throws Exception
261 {
262 if (started)
263 {
264 stopConnector();
265 started = false;
266 }
267 }
268
269 /* (non-Javadoc)
270 * @see org.mule.umo.provider.UMOConnector#shutdown()
271 */
272 public void shutdown() throws Exception
273 {
274 alive = false;
275 shutdownConnector();
276 }
277
278 /* (non-Javadoc)
279 * @see org.mule.umo.provider.UMOConnector#isAlive()
280 */
281 public boolean isAlive()
282 {
283 return alive;
284 }
285
286 /* (non-Javadoc)
287 * @see org.mule.umo.provider.UMOConnector#getSession()
288 */
289 public Object getSession()
290 {
291 return null;
292 }
293
294 /* (non-Javadoc)
295 * @see org.mule.umo.provider.UMOConnector#handleException(java.lang.Object, java.lang.Throwable)
296 */
297 public void handleException(Object message, Throwable exception)
298 {
299 if (exceptionStrategy == null)
300 {
301 throw new MuleRuntimeException(
302 "Exception occurred in connector: "
303 + getName()
304 + ". Exception handler is not set. Message is: "
305 + message,
306 exception);
307 }
308 else
309 {
310 exceptionStrategy.handleException(message, exception);
311 }
312 }
313
314 /* (non-Javadoc)
315 * @see org.mule.util.ExceptionListener#onException(java.lang.Throwable)
316 */
317 public void onException(Throwable throwable)
318 {
319 handleException("Dispatcher failed while processing event: " + throwable, throwable);
320
321 }
322
323 /**
324 * @return the ExceptionStrategy for this connector
325 * @see UMOExceptionStrategy
326 */
327 public UMOExceptionStrategy getExceptionStrategy()
328 {
329 return exceptionStrategy;
330 }
331
332 /**
333 * @param strategy the ExceptionStrategy to use with this connector
334 * @see UMOExceptionStrategy
335 */
336 public void setExceptionStrategy(UMOExceptionStrategy strategy)
337 {
338 exceptionStrategy = strategy;
339 }
340
341 /**
342 * Template method to perform any work when starting the connectoe
343 * @throws Exception if the method fails
344 */
345 protected abstract void startConnector() throws Exception;
346
347 /**
348 * Template method to perform any work when stopping the connectoe
349 * @throws Exception if the method fails
350 */
351 protected abstract void stopConnector() throws Exception;
352
353 /**
354 * Template method to perform any work when destroying the connectoe
355 * @throws Exception if the method fails
356 */
357 protected abstract void shutdownConnector() throws Exception;
358
359 /**
360 * @return true if the connector is using dispatch threads
361 */
362 public boolean isDoThreading()
363
364 {
365 return doThreading;
366 }
367
368 /**
369 * @param b the value of the doThreading property
370 */
371 public void setDoThreading(boolean b)
372 {
373 doThreading = b;
374 }
375
376 /**
377 * Dispatches a thread in the connector threadpool
378 * @param thread The worker thread to dispatch
379 */
380 protected void dispatch(Thread thread)
381 {
382 if (isDoThreading())
383 {
384 dispatchers.invokeLater(thread);
385 }
386 else
387 {
388 thread.start();
389 }
390
391 }
392
393 }