1
2
3
4
5
6
7
8
9
10
11 package org.mule.config.spring;
12
13 import org.mule.api.MuleContext;
14 import org.mule.api.MuleRuntimeException;
15 import org.mule.api.lifecycle.Disposable;
16 import org.mule.api.lifecycle.Initialisable;
17 import org.mule.api.lifecycle.InitialisationException;
18 import org.mule.api.lifecycle.LifecycleException;
19 import org.mule.api.lifecycle.LifecyclePhase;
20 import org.mule.api.lifecycle.Startable;
21 import org.mule.api.lifecycle.Stoppable;
22 import org.mule.api.registry.RegistrationException;
23 import org.mule.config.i18n.MessageFactory;
24 import org.mule.lifecycle.RegistryLifecycleManager;
25 import org.mule.lifecycle.phases.ContainerManagedLifecyclePhase;
26 import org.mule.lifecycle.phases.MuleContextStartPhase;
27 import org.mule.lifecycle.phases.MuleContextStopPhase;
28 import org.mule.lifecycle.phases.NotInLifecyclePhase;
29 import org.mule.registry.AbstractRegistry;
30 import org.mule.util.StringUtils;
31
32 import java.util.Collection;
33 import java.util.Collections;
34 import java.util.HashMap;
35 import java.util.Map;
36 import java.util.concurrent.atomic.AtomicBoolean;
37
38 import org.springframework.beans.FatalBeanException;
39 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
40 import org.springframework.context.ApplicationContext;
41 import org.springframework.context.ConfigurableApplicationContext;
42
43 public class SpringRegistry extends AbstractRegistry
44 {
45 public static final String REGISTRY_ID = "org.mule.Registry.Spring";
46
47
48
49
50
51 public static final String SPRING_APPLICATION_CONTEXT = "springApplicationContext";
52
53 protected ApplicationContext applicationContext;
54
55
56
57 protected AtomicBoolean springContextInitialised = new AtomicBoolean(false);
58
59 public SpringRegistry(MuleContext muleContext)
60 {
61 super(REGISTRY_ID, muleContext);
62 }
63
64 public SpringRegistry(String id, MuleContext muleContext)
65 {
66 super(id, muleContext);
67 }
68
69 public SpringRegistry(ApplicationContext applicationContext, MuleContext muleContext)
70 {
71 super(REGISTRY_ID, muleContext);
72 this.applicationContext = applicationContext;
73 }
74
75 public SpringRegistry(String id, ApplicationContext applicationContext, MuleContext muleContext)
76 {
77 super(id, muleContext);
78 this.applicationContext = applicationContext;
79 }
80
81 public SpringRegistry(ConfigurableApplicationContext applicationContext, ApplicationContext parentContext, MuleContext muleContext)
82 {
83 super(REGISTRY_ID, muleContext);
84 applicationContext.setParent(parentContext);
85 this.applicationContext = applicationContext;
86 }
87
88 public SpringRegistry(String id, ConfigurableApplicationContext applicationContext, ApplicationContext parentContext, MuleContext muleContext)
89 {
90 super(id, muleContext);
91 applicationContext.setParent(parentContext);
92 this.applicationContext = applicationContext;
93 }
94
95 @Override
96 protected void doInitialise() throws InitialisationException
97 {
98 if (applicationContext instanceof ConfigurableApplicationContext)
99 {
100 ((ConfigurableApplicationContext) applicationContext).refresh();
101 }
102
103 springContextInitialised.set(true);
104 }
105
106 @Override
107 public void doDispose()
108 {
109
110
111 if (!this.springContextInitialised.get())
112 {
113 return;
114 }
115
116 if (applicationContext instanceof ConfigurableApplicationContext
117 && ((ConfigurableApplicationContext) applicationContext).isActive())
118 {
119 ((ConfigurableApplicationContext) applicationContext).close();
120 }
121
122
123 applicationContext = null;
124
125 this.springContextInitialised.set(false);
126 }
127
128 @Override
129 protected RegistryLifecycleManager createLifecycleManager()
130 {
131 Map<String, LifecyclePhase> phases = new HashMap<String, LifecyclePhase>(3);
132 phases.put(Initialisable.PHASE_NAME, new SpringContextInitialisePhase());
133 phases.put(Startable.PHASE_NAME, new MuleContextStartPhase());
134 phases.put(Stoppable.PHASE_NAME, new MuleContextStopPhase());
135 phases.put(Disposable.PHASE_NAME, new SpringContextDisposePhase());
136 return new RegistryLifecycleManager(getRegistryId(), this, phases);
137 }
138
139 public Object lookupObject(String key)
140 {
141 if (StringUtils.isBlank(key))
142 {
143 logger.warn(
144 MessageFactory.createStaticMessage("Detected a lookup attempt with an empty or null key"),
145 new Throwable().fillInStackTrace());
146 return null;
147 }
148
149 if (key.equals(SPRING_APPLICATION_CONTEXT) && applicationContext != null)
150 {
151 return applicationContext;
152 }
153 else
154 {
155 try
156 {
157 return applicationContext.getBean(key);
158 }
159 catch (NoSuchBeanDefinitionException e)
160 {
161 logger.debug(e);
162 return null;
163 }
164 }
165 }
166
167 public <T> Collection<T> lookupObjects(Class<T> type)
168 {
169 return lookupByType(type).values();
170 }
171
172 @SuppressWarnings("unchecked")
173 public <T> Map<String, T> lookupByType(Class<T> type)
174 {
175 try
176 {
177 return applicationContext.getBeansOfType(type);
178 }
179 catch (FatalBeanException fbex)
180 {
181
182 String message = String.format("Failed to lookup beans of type %s from the Spring registry", type);
183 throw new MuleRuntimeException(MessageFactory.createStaticMessage(message), fbex);
184 }
185 catch (Exception e)
186 {
187 logger.debug(e);
188 return Collections.emptyMap();
189 }
190
191 }
192
193
194
195
196
197 public void registerObject(String key, Object value) throws RegistrationException
198 {
199 throw new UnsupportedOperationException("Registry is read-only so objects cannot be registered or unregistered.");
200 }
201
202 public void registerObject(String key, Object value, Object metadata) throws RegistrationException
203 {
204 throw new UnsupportedOperationException("Registry is read-only so objects cannot be registered or unregistered.");
205 }
206
207 public void registerObjects(Map objects) throws RegistrationException
208 {
209 throw new UnsupportedOperationException("Registry is read-only so objects cannot be registered or unregistered.");
210 }
211
212 public void unregisterObject(String key)
213 {
214 throw new UnsupportedOperationException("Registry is read-only so objects cannot be registered or unregistered.");
215 }
216
217 public void unregisterObject(String key, Object metadata) throws RegistrationException
218 {
219 throw new UnsupportedOperationException("Registry is read-only so objects cannot be registered or unregistered.");
220 }
221
222
223
224
225
226 public boolean isReadOnly()
227 {
228 return true;
229 }
230
231 public boolean isRemote()
232 {
233 return false;
234 }
235
236
237
238
239
240
241
242
243 class SpringContextInitialisePhase extends ContainerManagedLifecyclePhase
244 {
245 public SpringContextInitialisePhase()
246 {
247 super(Initialisable.PHASE_NAME, Initialisable.class, Disposable.PHASE_NAME);
248 registerSupportedPhase(NotInLifecyclePhase.PHASE_NAME);
249 }
250
251
252
253
254
255
256
257 @Override
258 public void applyLifecycle(Object o) throws LifecycleException
259 {
260
261 }
262 }
263
264
265
266
267
268
269 class SpringContextDisposePhase extends ContainerManagedLifecyclePhase
270 {
271 public SpringContextDisposePhase()
272 {
273 super(Disposable.PHASE_NAME, Disposable.class, Initialisable.PHASE_NAME);
274 registerSupportedPhase(NotInLifecyclePhase.PHASE_NAME);
275
276 registerSupportedPhase(LifecyclePhase.ALL_PHASES);
277 }
278
279 @Override
280 public void applyLifecycle(Object o) throws LifecycleException
281 {
282 doDispose();
283 }
284 }
285
286 }