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.Iterator;
35 import java.util.Map;
36
37 import org.apache.commons.collections.functors.InstanceofPredicate;
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40
41
42
43
44
45 public class TransientRegistry extends AbstractRegistry
46 {
47
48 protected transient final Log logger = LogFactory.getLog(TransientRegistry.class);
49 public static final String REGISTRY_ID = "org.mule.Registry.Transient";
50
51
52 private final Map<String, Object> registry = new HashMap<String, Object>();
53
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 synchronized(registry)
64 {
65 registry.put("_muleContextProcessor", new MuleContextProcessor(muleContext));
66
67 registry.put("_muleExpressionEvaluatorProcessor", new ExpressionEvaluatorProcessor(muleContext));
68 registry.put("_muleLifecycleStateInjectorProcessor", new LifecycleStateInjectorProcessor(getLifecycleManager().getState()));
69 registry.put("_muleLifecycleManager", getLifecycleManager());
70 }
71 }
72
73 @java.lang.Override
74 protected void doInitialise() throws InitialisationException
75 {
76 applyProcessors(lookupObjects(Connector.class), null);
77 applyProcessors(lookupObjects(Transformer.class), null);
78 applyProcessors(lookupObjects(ImmutableEndpoint.class), null);
79 applyProcessors(lookupObjects(Agent.class), null);
80 applyProcessors(lookupObjects(Model.class), null);
81 applyProcessors(lookupObjects(Service.class), null);
82 applyProcessors(lookupObjects(Object.class), null);
83 }
84
85 @Override
86 protected void doDispose()
87 {
88 registry.clear();
89 }
90
91 protected Map applyProcessors(Map<String, Object> objects)
92 {
93 if (objects == null)
94 {
95 return null;
96 }
97 Map<String, Object> results = new HashMap<String, Object>();
98 for (Map.Entry<String, Object> entry : objects.entrySet())
99 {
100
101 Collection<ObjectProcessor> processors = lookupObjects(ObjectProcessor.class);
102 for (ObjectProcessor processor : processors)
103 {
104 Object result = processor.process(entry.getValue());
105
106 if(result != null)
107 {
108 results.put(entry.getKey(), result);
109 }
110 }
111 }
112 return results;
113 }
114
115
116 public void registerObjects(Map objects) throws RegistrationException
117 {
118 if (objects == null)
119 {
120 return;
121 }
122
123 for (Iterator iterator = objects.entrySet().iterator(); iterator.hasNext();)
124 {
125 Map.Entry entry = (Map.Entry) iterator.next();
126 registerObject(entry.getKey().toString(), entry.getValue());
127 }
128 }
129
130 @SuppressWarnings("unchecked")
131 public <T> Map<String, T> lookupByType(Class<T> type)
132 {
133 synchronized(registry)
134 {
135 final Map<String, T> results = new HashMap<String, T>();
136 for (Map.Entry<String, Object> entry : registry.entrySet())
137 {
138 final Class clazz = entry.getValue().getClass();
139 if (type.isAssignableFrom(clazz))
140 {
141 results.put(entry.getKey(), (T) entry.getValue());
142 }
143 }
144
145 return results;
146 }
147 }
148
149 @SuppressWarnings("unchecked")
150 public <T> T lookupObject(String key)
151 {
152 synchronized(registry)
153 {
154 return (T) registry.get(key);
155 }
156 }
157
158 @SuppressWarnings("unchecked")
159 public <T> Collection<T> lookupObjects(Class<T> returntype)
160 {
161 synchronized(registry)
162 {
163 return CollectionUtils.select(registry.values(), new InstanceofPredicate(returntype));
164 }
165 }
166
167
168
169
170
171
172
173
174
175
176 Object applyLifecycle(Object object) throws MuleException
177 {
178 getLifecycleManager().applyCompletedPhases(object);
179 return object;
180 }
181
182 Object applyLifecycle(Object object, String phase) throws MuleException
183 {
184 getLifecycleManager().applyPhase(object, NotInLifecyclePhase.PHASE_NAME, phase);
185 return object;
186 }
187
188
189
190 Object applyProcessors(Object object, Object metadata)
191 {
192 Object theObject = object;
193
194 if(!hasFlag(metadata, MuleRegistry.INJECT_PROCESSORS_BYPASS_FLAG))
195 {
196
197 Collection<InjectProcessor> injectProcessors = lookupObjects(InjectProcessor.class);
198 for (InjectProcessor processor : injectProcessors)
199 {
200 theObject = processor.process(theObject);
201 }
202 }
203
204 if(!hasFlag(metadata, MuleRegistry.PRE_INIT_PROCESSORS_BYPASS_FLAG))
205 {
206
207 Collection<PreInitProcessor> processors = lookupObjects(PreInitProcessor.class);
208 for (PreInitProcessor processor : processors)
209 {
210 theObject = processor.process(theObject);
211 if(theObject==null)
212 {
213 return null;
214 }
215 }
216 }
217 return theObject;
218 }
219
220
221
222
223
224
225
226 public void registerObject(String key, Object value) throws RegistrationException
227 {
228 registerObject(key, value, Object.class);
229 }
230
231
232
233
234
235
236 public void registerObject(String key, Object object, Object metadata) throws RegistrationException
237 {
238 checkDisposed();
239 if (StringUtils.isBlank(key))
240 {
241 throw new RegistrationException(MessageFactory.createStaticMessage("Attempt to register object with no key"));
242 }
243
244 if (logger.isDebugEnabled())
245 {
246 logger.debug(String.format("registering key/object %s/%s", key, object));
247 }
248
249 logger.debug("applying processors");
250 object = applyProcessors(object, metadata);
251
252 if (object==null)
253 {
254 return;
255 }
256
257 synchronized(registry)
258 {
259 if (registry.containsKey(key))
260 {
261
262
263
264 logger.warn("TransientRegistry already contains an object named '" + key + "'. The previous object will be overwritten.");
265 }
266 registry.put(key, object);
267 }
268
269 try
270 {
271 if (!hasFlag(metadata, MuleRegistry.LIFECYCLE_BYPASS_FLAG))
272 {
273 if(logger.isDebugEnabled())
274 {
275 logger.debug("applying lifecycle to object: " + object);
276 }
277 getLifecycleManager().applyCompletedPhases(object);
278 }
279 }
280 catch (MuleException e)
281 {
282 throw new RegistrationException(e);
283 }
284 }
285
286
287 protected void checkDisposed() throws RegistrationException
288 {
289 if(getLifecycleManager().isPhaseComplete(Disposable.PHASE_NAME))
290 {
291 throw new RegistrationException(MessageFactory.createStaticMessage("Cannot register objects on the registry as the context is disposed"));
292 }
293 }
294
295 protected boolean hasFlag(Object metaData, int flag)
296 {
297 return !(metaData == null || !(metaData instanceof Integer)) && ((Integer) metaData & flag) != 0;
298 }
299
300
301
302
303
304
305
306
307
308
309 public void unregisterObject(String key, Object metadata) throws RegistrationException
310 {
311 Object obj;
312 synchronized (registry)
313 {
314 obj = registry.remove(key);
315 }
316
317 try
318 {
319 if(!hasFlag(metadata, MuleRegistry.LIFECYCLE_BYPASS_FLAG))
320 {
321 getLifecycleManager().applyPhase(obj, lifecycleManager.getCurrentPhase(), Disposable.PHASE_NAME);
322 }
323 }
324 catch (MuleException e)
325 {
326 throw new RegistrationException(e);
327 }
328
329 }
330
331 public void unregisterObject(String key) throws RegistrationException
332 {
333 unregisterObject(key, Object.class);
334 }
335
336
337
338
339
340 public boolean isReadOnly()
341 {
342 return false;
343 }
344
345 public boolean isRemote()
346 {
347 return false;
348 }
349
350 }