1
2
3
4
5
6
7
8
9
10 package org.mule.config.bootstrap;
11
12 import org.mule.api.MuleContext;
13 import org.mule.api.context.MuleContextAware;
14 import org.mule.api.lifecycle.Initialisable;
15 import org.mule.api.lifecycle.InitialisationException;
16 import org.mule.api.registry.MuleRegistry;
17 import org.mule.api.registry.ObjectProcessor;
18 import org.mule.api.registry.RegistrationException;
19 import org.mule.api.registry.Registry;
20 import org.mule.api.transformer.DiscoverableTransformer;
21 import org.mule.api.transformer.Transformer;
22 import org.mule.api.util.StreamCloser;
23 import org.mule.config.i18n.CoreMessages;
24 import org.mule.transformer.types.DataTypeFactory;
25 import org.mule.util.ClassUtils;
26 import org.mule.util.ExceptionUtils;
27 import org.mule.util.PropertiesUtils;
28 import org.mule.util.UUID;
29
30 import java.lang.reflect.InvocationTargetException;
31 import java.net.URL;
32 import java.util.Enumeration;
33 import java.util.LinkedList;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Properties;
37
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 public class SimpleRegistryBootstrap implements Initialisable, MuleContextAware
78 {
79 public static final String SERVICE_PATH = "META-INF/services/org/mule/config/";
80
81 public static final String REGISTRY_PROPERTIES = "registry-bootstrap.properties";
82
83 public String TRANSFORMER_KEY = ".transformer.";
84 public String OBJECT_KEY = ".object.";
85
86 protected final transient Log logger = LogFactory.getLog(getClass());
87
88 protected MuleContext context;
89
90
91 public void setMuleContext(MuleContext context)
92 {
93 this.context = context;
94 }
95
96
97 public void initialise() throws InitialisationException
98 {
99 Enumeration<?> e = ClassUtils.getResources(SERVICE_PATH + REGISTRY_PROPERTIES, getClass());
100 List<Properties> bootstraps = new LinkedList<Properties>();
101
102
103 while (e.hasMoreElements())
104 {
105 try
106 {
107 URL url = (URL) e.nextElement();
108 if (logger.isDebugEnabled())
109 {
110 logger.debug("Reading bootstrap file: " + url.toString());
111 }
112 Properties p = new Properties();
113 p.load(url.openStream());
114 bootstraps.add(p);
115 }
116 catch (Exception e1)
117 {
118 throw new InitialisationException(e1, this);
119 }
120 }
121
122
123 int objectCounter = 1;
124 int transformerCounter = 1;
125 Properties transformers = new Properties();
126 Properties namedObjects = new Properties();
127 Properties unnamedObjects = new Properties();
128
129 for (Properties bootstrap : bootstraps)
130 {
131 for (Map.Entry entry : bootstrap.entrySet())
132 {
133 final String key = (String) entry.getKey();
134 if (key.contains(OBJECT_KEY))
135 {
136 String newKey = key.substring(0, key.lastIndexOf(".")) + objectCounter++;
137 unnamedObjects.put(newKey, entry.getValue());
138 }
139 else if (key.contains(TRANSFORMER_KEY))
140 {
141 String newKey = key.substring(0, key.lastIndexOf(".")) + transformerCounter++;
142 transformers.put(newKey, entry.getValue());
143 }
144 else
145 {
146
147
148
149
150
151
152
153
154 {
155 namedObjects.put(key, entry.getValue());
156 }
157 }
158 }
159 }
160
161 try
162 {
163 registerUnnamedObjects(unnamedObjects, context.getRegistry());
164 registerTransformers(transformers, context.getRegistry());
165 registerObjects(namedObjects, context.getRegistry());
166 }
167 catch (Exception e1)
168 {
169 throw new InitialisationException(e1, this);
170 }
171 }
172
173 private void registerTransformers(Properties props, MuleRegistry registry) throws Exception
174 {
175 String transString;
176 String name = null;
177 String returnClassString;
178 boolean optional = false;
179
180 for (Map.Entry<Object, Object> entry : props.entrySet())
181 {
182 transString = (String)entry.getValue();
183
184 Class<?> returnClass = null;
185 returnClassString = null;
186 int x = transString.indexOf(",");
187 if (x > -1)
188 {
189 Properties p = PropertiesUtils.getPropertiesFromString(transString.substring(x + 1), ',');
190 name = p.getProperty("name", null);
191 returnClassString = p.getProperty("returnClass", null);
192 optional = p.containsKey("optional");
193 }
194
195 final String transClass = (x == -1 ? transString : transString.substring(0, x));
196 try
197 {
198 String mime = null;
199 if (returnClassString != null)
200 {
201 int i = returnClassString.indexOf(":");
202 if(i > -1)
203 {
204 mime = returnClassString.substring(i + 1);
205 returnClassString = returnClassString.substring(0, i);
206 }
207 if (returnClassString.equals("byte[]"))
208 {
209 returnClass = byte[].class;
210 }
211 else
212 {
213 returnClass = ClassUtils.loadClass(returnClassString, getClass());
214 }
215 }
216 Transformer trans = (Transformer) ClassUtils.instanciateClass(transClass);
217 if (!(trans instanceof DiscoverableTransformer))
218 {
219 throw new RegistrationException(CoreMessages.transformerNotImplementDiscoverable(trans));
220 }
221 if (returnClass != null)
222 {
223 trans.setReturnDataType(DataTypeFactory.create(returnClass, mime));
224 }
225 if (name != null)
226 {
227 trans.setName(name);
228 }
229 else
230 {
231
232 name = trans.getName();
233
234
235 trans.setName("_" + name);
236 }
237 registry.registerTransformer(trans);
238 }
239 catch (InvocationTargetException itex)
240 {
241 Throwable cause = ExceptionUtils.getCause(itex);
242 if (cause instanceof NoClassDefFoundError && optional)
243 {
244 if (logger.isDebugEnabled())
245 {
246 logger.debug("Ignoring optional transformer: " + transClass);
247 }
248 }
249 else
250 {
251 throw new Exception(cause);
252 }
253 }
254 catch (NoClassDefFoundError ncdfe)
255 {
256 if (optional)
257 {
258 if (logger.isDebugEnabled())
259 {
260 logger.debug("Ignoring optional transformer: " + transClass);
261 }
262 }
263 else
264 {
265 throw ncdfe;
266 }
267 }
268 catch (ClassNotFoundException cnfe)
269 {
270 if (optional)
271 {
272 if (logger.isDebugEnabled())
273 {
274 logger.debug("Ignoring optional transformer: " + transClass);
275 }
276 }
277 else
278 {
279 throw cnfe;
280 }
281 }
282
283 name = null;
284 returnClass = null;
285 }
286 }
287
288 private void registerObjects(Properties props, Registry registry) throws Exception
289 {
290 for (Map.Entry<Object, Object> entry : props.entrySet())
291 {
292 registerObject((String)entry.getKey(), (String)entry.getValue(), registry);
293 }
294 props.clear();
295 }
296
297 private void registerUnnamedObjects(Properties props, Registry registry) throws Exception
298 {
299 for (Map.Entry<Object, Object> entry : props.entrySet())
300 {
301 final String key = String.format("%s#%s", entry.getKey(), UUID.getUUID());
302 registerObject(key, (String) entry.getValue(), registry);
303 }
304 props.clear();
305 }
306
307 private void registerObject(String key, String value, Registry registry) throws Exception
308 {
309 boolean optional = false;
310 String className = null;
311
312 try
313 {
314 int x = value.indexOf(",");
315 if (x > -1)
316 {
317 Properties p = PropertiesUtils.getPropertiesFromString(value.substring(x + 1), ',');
318 optional = p.containsKey("optional");
319 className = value.substring(0, x);
320 }
321 else
322 {
323 className = value;
324 }
325 Object o = ClassUtils.instanciateClass(className);
326 Class<?> meta = Object.class;
327
328 if (o instanceof ObjectProcessor)
329 {
330 meta = ObjectProcessor.class;
331 }
332 else if (o instanceof StreamCloser)
333 {
334 meta = StreamCloser.class;
335 }
336 else if (o instanceof BootstrapObjectFactory)
337 {
338 o = ((BootstrapObjectFactory)o).create();
339 }
340 registry.registerObject(key, o, meta);
341 }
342 catch (InvocationTargetException itex)
343 {
344 Throwable cause = ExceptionUtils.getCause(itex);
345 if (cause instanceof NoClassDefFoundError && optional)
346 {
347 if (logger.isDebugEnabled())
348 {
349 logger.debug("Ignoring optional object: " + className);
350 }
351 }
352 else
353 {
354 throw new Exception(cause);
355 }
356 }
357 catch (NoClassDefFoundError ncdfe)
358 {
359 if (optional)
360 {
361 if (logger.isDebugEnabled())
362 {
363 logger.debug("Ignoring optional object: " + className);
364 }
365 }
366 else
367 {
368 throw ncdfe;
369 }
370 }
371 catch (ClassNotFoundException cnfe)
372 {
373 if (optional)
374 {
375 if (logger.isDebugEnabled())
376 {
377 logger.debug("Ignoring optional object: " + className);
378 }
379 }
380 else
381 {
382 throw cnfe;
383 }
384 }
385 }
386 }