1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport;
12
13 import org.mule.api.context.WorkManager;
14 import org.mule.api.transport.Connectable;
15 import org.mule.api.transport.ConnectionStrategy;
16 import org.mule.api.transport.Connector;
17 import org.mule.api.transport.MessageReceiver;
18 import org.mule.config.i18n.MessageFactory;
19 import org.mule.util.ClassUtils;
20
21 import javax.resource.spi.work.Work;
22 import javax.resource.spi.work.WorkException;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26
27
28
29
30 public abstract class AbstractConnectionStrategy implements ConnectionStrategy
31 {
32
33
34
35 protected transient Log logger = LogFactory.getLog(getClass());
36
37 private volatile boolean doThreading = false;
38
39 private WorkManager workManager;
40
41 private final Object reconnectLock = new Object();
42
43 public final void connect(final Connectable connectable) throws FatalConnectException
44 {
45 if (doThreading)
46 {
47 try
48 {
49 WorkManager wm = getWorkManager();
50 if (wm == null)
51 {
52 throw new FatalConnectException(MessageFactory.createStaticMessage("No WorkManager is available"), connectable);
53 }
54
55 wm.scheduleWork(new Work()
56 {
57 public void release()
58 {
59
60 }
61
62 public void run()
63 {
64 try
65 {
66 synchronized (reconnectLock)
67 {
68 doConnect(connectable);
69 }
70 }
71 catch (FatalConnectException e)
72 {
73 synchronized (reconnectLock)
74 {
75 resetState();
76 }
77
78
79 if (connectable instanceof Connector)
80 {
81 ((Connector) connectable).handleException(e);
82 }
83
84 else if (connectable instanceof AbstractMessageReceiver)
85 {
86 ((AbstractMessageReceiver) connectable).handleException(e);
87 }
88
89 }
90 }
91 });
92 }
93 catch (WorkException e)
94 {
95 synchronized (reconnectLock)
96 {
97 resetState();
98 }
99 throw new FatalConnectException(e, connectable);
100 }
101 }
102 else
103 {
104 try
105 {
106 synchronized (reconnectLock)
107 {
108 doConnect(connectable);
109 }
110 }
111 finally
112 {
113 synchronized (reconnectLock)
114 {
115 resetState();
116 }
117 }
118 }
119 }
120
121 public boolean isDoThreading()
122 {
123 return doThreading;
124 }
125
126 public void setDoThreading(boolean doThreading)
127 {
128 this.doThreading = doThreading;
129 }
130
131
132 public WorkManager getWorkManager()
133 {
134 return workManager;
135 }
136
137 public void setWorkManager(WorkManager workManager)
138 {
139 this.workManager = workManager;
140 }
141
142 protected abstract void doConnect(Connectable connectable) throws FatalConnectException;
143
144
145
146
147 public abstract void resetState();
148
149 protected String getDescription(Connectable connectable)
150 {
151 if (connectable instanceof MessageReceiver)
152 {
153 return ((MessageReceiver) connectable).getEndpointURI().toString();
154 }
155 else
156 {
157 return connectable.toString();
158 }
159 }
160
161 public int hashCode()
162 {
163 return ClassUtils.hash(new Object[]{doThreading ? Boolean.TRUE : Boolean.FALSE, workManager});
164 }
165
166 public boolean equals(Object obj)
167 {
168 if (this == obj) return true;
169 if (obj == null || getClass() != obj.getClass()) return false;
170
171 final AbstractConnectionStrategy other = (AbstractConnectionStrategy) obj;
172 return ClassUtils.equal(new Boolean(doThreading), new Boolean(other.doThreading))
173 && ClassUtils.equal(workManager, other.workManager);
174
175 }
176
177 }