1
2
3
4
5
6
7
8
9
10 package org.mule.registry;
11
12 import org.mule.api.MuleContext;
13 import org.mule.api.MuleException;
14 import org.mule.api.agent.Agent;
15 import org.mule.api.endpoint.ImmutableEndpoint;
16 import org.mule.api.lifecycle.Disposable;
17 import org.mule.api.lifecycle.InitialisationException;
18 import org.mule.api.model.Model;
19 import org.mule.api.registry.InjectProcessor;
20 import org.mule.api.registry.MuleRegistry;
21 import org.mule.api.registry.ObjectProcessor;
22 import org.mule.api.registry.PreInitProcessor;
23 import org.mule.api.registry.RegistrationException;
24 import org.mule.api.service.Service;
25 import org.mule.api.transformer.Transformer;
26 import org.mule.api.transport.Connector;
27 import org.mule.config.i18n.MessageFactory;
28 import org.mule.lifecycle.phases.NotInLifecyclePhase;
29 import org.mule.util.CollectionUtils;
30 import org.mule.util.StringUtils;
31
32 import java.util.Collection;
33 import java.util.HashMap;
34 import java.util.Map;
35 import java.util.Map.Entry;
36 import java.util.Set;
37 import java.util.concurrent.locks.Lock;
38 import java.util.concurrent.locks.ReadWriteLock;
39 import java.util.concurrent.locks.ReentrantReadWriteLock;
40
41 import org.apache.commons.collections.Predicate;
42 import org.apache.commons.collections.functors.InstanceofPredicate;
43 import org.apache.commons.logging.Log;
44
45
46
47
48
49 public class TransientRegistry extends AbstractRegistry
50 {
51 public static final String REGISTRY_ID = "org.mule.Registry.Transient";
52
53 private final RegistryMap registryMap = new RegistryMap(logger);
54
55 public TransientRegistry(MuleContext muleContext)
56 {
57 this(REGISTRY_ID, muleContext);
58 }
59
60 public TransientRegistry(String id, MuleContext muleContext)
61 {
62 super(id, muleContext);
63 putDefaultEntriesIntoRegistry();
64 }
65
66 private void putDefaultEntriesIntoRegistry()
67 {
68 Map<String, Object> processors = new HashMap<String, Object>();
69 processors.put("_muleContextProcessor", new MuleContextProcessor(muleContext));
70
71 processors.put("_muleExpressionEvaluatorProcessor", new ExpressionEvaluatorProcessor(muleContext));
72 processors.put("_muleExpressionEnricherProcessor", new ExpressionEnricherProcessor(muleContext));
73 processors.put("_muleLifecycleStateInjectorProcessor", new LifecycleStateInjectorProcessor(getLifecycleManager().getState()));
74 processors.put("_muleLifecycleManager", getLifecycleManager());
75 registryMap.putAll(processors);
76 }
77
78 @Override
79 protected void doInitialise() throws InitialisationException
80 {
81 applyProcessors(lookupObjects(Connector.class), null);
82 applyProcessors(lookupObjects(Transformer.class), null);
83 applyProcessors(lookupObjects(ImmutableEndpoint.class), null);
84 applyProcessors(lookupObjects(Agent.class), null);
85 applyProcessors(lookupObjects(Model.class), null);
86 applyProcessors(lookupObjects(Service.class), null);
87 applyProcessors(lookupObjects(Object.class), null);
88 }
89
90 @Override
91 protected void doDispose()
92 {
93 registryMap.clear();
94 }
95
96 protected Map<String, Object> applyProcessors(Map<String, Object> objects)
97 {
98 if (objects == null)
99 {
100 return null;
101 }
102
103 Map<String, Object> results = new HashMap<String, Object>();
104 for (Map.Entry<String, Object> entry : objects.entrySet())
105 {
106
107 Collection<ObjectProcessor> processors = lookupObjects(ObjectProcessor.class);
108 for (ObjectProcessor processor : processors)
109 {
110 Object result = processor.process(entry.getValue());
111 if (result != null)
112 {
113 results.put(entry.getKey(), result);
114 }
115 }
116 }
117 return results;
118 }
119
120
121 public void registerObjects(Map<String, Object> objects) throws RegistrationException
122 {
123 if (objects == null)
124 {
125 return;
126 }
127
128 for (Map.Entry<String, Object> entry : objects.entrySet())
129 {
130 registerObject(entry.getKey(), entry.getValue());
131 }
132 }
133
134 @SuppressWarnings("unchecked")
135 public <T> Map<String, T> lookupByType(Class<T> type)
136 {
137 final Map<String, T> results = new HashMap<String, T>();
138 try
139 {
140 registryMap.lockForReading();
141
142 for (Map.Entry<String, Object> entry : registryMap.entrySet())
143 {
144 final Class<?> clazz = entry.getValue().getClass();
145 if (type.isAssignableFrom(clazz))
146 {
147 results.put(entry.getKey(), (T) entry.getValue());
148 }
149 }
150 }
151 finally
152 {
153 registryMap.unlockForReading();
154 }
155
156 return results;
157 }
158
159 public <T> T lookupObject(String key)
160 {
161 return registryMap.<T>get(key);
162 }
163
164 @SuppressWarnings("unchecked")
165 public <T> Collection<T> lookupObjects(Class<T> returntype)
166 {
167 return (Collection<T>) registryMap.select(new InstanceofPredicate(returntype));
168 }
169
170
171
172
173
174
175
176
177
178
179 Object applyLifecycle(Object object) throws MuleException
180 {
181 getLifecycleManager().applyCompletedPhases(object);
182 return object;
183 }
184
185 Object applyLifecycle(Object object, String phase) throws MuleException
186 {
187 getLifecycleManager().applyPhase(object, NotInLifecyclePhase.PHASE_NAME, phase);
188 return object;
189 }
190
191 Object applyProcessors(Object object, Object metadata)
192 {
193 Object theObject = object;
194
195 if(!hasFlag(metadata, MuleRegistry.INJECT_PROCESSORS_BYPASS_FLAG))
196 {
197
198 Collection<InjectProcessor> injectProcessors = lookupObjects(InjectProcessor.class);
199 for (InjectProcessor processor : injectProcessors)
200 {
201 theObject = processor.process(theObject);
202 }
203 }
204
205 if(!hasFlag(metadata, MuleRegistry.PRE_INIT_PROCESSORS_BYPASS_FLAG))
206 {
207
208 Collection<PreInitProcessor> processors = lookupObjects(PreInitProcessor.class);
209 for (PreInitProcessor processor : processors)
210 {
211 theObject = processor.process(theObject);
212 if(theObject==null)
213 {
214 return null;
215 }
216 }
217 }
218 return theObject;
219 }
220
221
222
223
224
225
226
227 public void registerObject(String key, Object value) throws RegistrationException
228 {
229 registerObject(key, value, Object.class);
230 }
231
232
233
234
235 public void registerObject(String key, Object object, Object metadata) throws RegistrationException
236 {
237 checkDisposed();
238 if (StringUtils.isBlank(key))
239 {
240 throw new RegistrationException(MessageFactory.createStaticMessage("Attempt to register object with no key"));
241 }
242
243 if (logger.isDebugEnabled())
244 {
245 logger.debug(String.format("registering key/object %s/%s", key, object));
246 }
247
248 logger.debug("applying processors");
249 object = applyProcessors(object, metadata);
250 if (object == null)
251 {
252 return;
253 }
254
255 registryMap.putAndLogWarningIfDuplicate(key, object);
256
257 try
258 {
259 if (!hasFlag(metadata, MuleRegistry.LIFECYCLE_BYPASS_FLAG))
260 {
261 if(logger.isDebugEnabled())
262 {
263 logger.debug("applying lifecycle to object: " + object);
264 }
265 getLifecycleManager().applyCompletedPhases(object);
266 }
267 }
268 catch (MuleException e)
269 {
270 throw new RegistrationException(e);
271 }
272 }
273
274 protected void checkDisposed() throws RegistrationException
275 {
276 if(getLifecycleManager().isPhaseComplete(Disposable.PHASE_NAME))
277 {
278 throw new RegistrationException(MessageFactory.createStaticMessage("Cannot register objects on the registry as the context is disposed"));
279 }
280 }
281
282 protected boolean hasFlag(Object metaData, int flag)
283 {
284 return !(metaData == null || !(metaData instanceof Integer)) && ((Integer) metaData & flag) != 0;
285 }
286
287
288
289
290
291
292
293
294
295
296 public void unregisterObject(String key, Object metadata) throws RegistrationException
297 {
298 Object obj = registryMap.remove(key);
299
300 try
301 {
302 if (!hasFlag(metadata, MuleRegistry.LIFECYCLE_BYPASS_FLAG))
303 {
304 getLifecycleManager().applyPhase(obj, lifecycleManager.getCurrentPhase(), Disposable.PHASE_NAME);
305 }
306 }
307 catch (MuleException e)
308 {
309 throw new RegistrationException(e);
310 }
311
312 }
313
314 public void unregisterObject(String key) throws RegistrationException
315 {
316 unregisterObject(key, Object.class);
317 }
318
319
320
321
322
323 public boolean isReadOnly()
324 {
325 return false;
326 }
327
328 public boolean isRemote()
329 {
330 return false;
331 }
332
333
334
335
336
337
338 private static class RegistryMap
339 {
340 private final Map<String, Object> registry = new HashMap<String, Object>();
341 private final ReadWriteLock registryLock = new ReentrantReadWriteLock();
342
343 private Log logger;
344
345 public RegistryMap(Log log)
346 {
347 super();
348 logger = log;
349 }
350
351 public Collection<?> select(Predicate predicate)
352 {
353 Lock readLock = registryLock.readLock();
354 try
355 {
356 readLock.lock();
357 return CollectionUtils.select(registry.values(), predicate);
358 }
359 finally
360 {
361 readLock.unlock();
362 }
363 }
364
365 public void clear()
366 {
367 Lock writeLock = registryLock.writeLock();
368 try
369 {
370 writeLock.lock();
371 registry.clear();
372 }
373 finally
374 {
375 writeLock.unlock();
376 }
377 }
378
379 public void putAndLogWarningIfDuplicate(String key, Object object)
380 {
381 Lock writeLock = registryLock.writeLock();
382 try
383 {
384 writeLock.lock();
385
386 if (registry.containsKey(key))
387 {
388
389
390
391 logger.warn("TransientRegistry already contains an object named '" + key + "'. The previous object will be overwritten.");
392 }
393 registry.put(key, object);
394 }
395 finally
396 {
397 writeLock.unlock();
398 }
399 }
400
401 public void putAll(Map<String, Object> map)
402 {
403 Lock writeLock = registryLock.writeLock();
404 try
405 {
406 writeLock.lock();
407 registry.putAll(map);
408 }
409 finally
410 {
411 writeLock.unlock();
412 }
413 }
414
415 @SuppressWarnings("unchecked")
416 public <T> T get(String key)
417 {
418 Lock readLock = registryLock.readLock();
419 try
420 {
421 readLock.lock();
422 return (T) registry.get(key);
423 }
424 finally
425 {
426 readLock.unlock();
427 }
428 }
429
430 public Object remove(String key)
431 {
432 Lock writeLock = registryLock.writeLock();
433 try
434 {
435 writeLock.lock();
436 return registry.remove(key);
437 }
438 finally
439 {
440 writeLock.unlock();
441 }
442 }
443
444 public Set<Entry<String, Object>> entrySet()
445 {
446 return registry.entrySet();
447 }
448
449 public void lockForReading()
450 {
451 registryLock.readLock().lock();
452 }
453
454 public void unlockForReading()
455 {
456 registryLock.readLock().unlock();
457 }
458 }
459 }