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