1
2
3
4
5
6
7
8
9
10
11 package org.mule;
12
13 import org.mule.api.DefaultMuleException;
14 import org.mule.api.MuleContext;
15 import org.mule.api.MuleException;
16 import org.mule.api.config.ConfigurationBuilder;
17 import org.mule.api.config.ConfigurationException;
18 import org.mule.config.ExceptionHelper;
19 import org.mule.config.i18n.CoreMessages;
20 import org.mule.config.i18n.Message;
21 import org.mule.context.DefaultMuleContextFactory;
22 import org.mule.util.ClassUtils;
23 import org.mule.util.IOUtils;
24 import org.mule.util.MuleUrlStreamHandlerFactory;
25 import org.mule.util.PropertiesUtils;
26 import org.mule.util.StringMessageUtils;
27 import org.mule.util.SystemUtils;
28
29 import java.net.URL;
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.Date;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Properties;
36
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39
40
41
42
43
44 public class MuleServer implements Runnable
45 {
46 public static final String CLI_OPTIONS[][] = {
47 {"builder", "true", "Configuration Builder Type"},
48 {"config", "true", "Configuration File"},
49 {"idle", "false", "Whether to run in idle (unconfigured) mode"},
50 {"main", "true", "Main Class"},
51 {"mode", "true", "Run Mode"},
52 {"props", "true", "Startup Properties"},
53 {"debug", "false", "Configure Mule for JPDA remote debugging."}
54 };
55
56
57
58
59 protected static final String CLASSNAME_DEFAULT_CONFIG_BUILDER = "org.mule.config.builders.AutoConfigurationBuilder";
60
61
62
63
64
65 protected static final String CLASSNAME_DEFAULT_IDLE_CONFIG_BUILDER = "org.mule.config.builders.MuleIdleConfigurationBuilder";
66
67
68
69
70
71
72 protected static final String CLASSNAME_SPRING_CONFIG_BUILDER = "org.mule.config.spring.SpringXmlConfigurationBuilder";
73
74
75
76
77 private static final Log logger = LogFactory.getLog(MuleServer.class);
78
79 public static final String DEFAULT_CONFIGURATION = "mule-config.xml";
80
81
82
83
84 private String configurationResources = null;
85
86
87
88
89
90 private static String configBuilderClassName = null;
91
92
93
94
95
96 private static String startupPropertiesFile = null;
97
98
99
100
101 private static MuleShutdownHook muleShutdownHook;
102
103 protected Map options = Collections.EMPTY_MAP;
104
105
106
107
108
109
110
111 protected static MuleContext muleContext = null;
112
113
114
115
116
117
118 public static void main(String[] args) throws Exception
119 {
120 MuleServer server = new MuleServer(args);
121 server.start(false, true);
122
123 }
124
125 public MuleServer()
126 {
127 init(new String[]{});
128 }
129
130 public MuleServer(String configResources)
131 {
132
133 init(new String[]{"-config", configResources});
134 }
135
136
137
138
139 public MuleServer(String[] args) throws IllegalArgumentException
140 {
141 init(args);
142 }
143
144 protected void init(String[] args) throws IllegalArgumentException
145 {
146 Map options;
147
148 try
149 {
150 muleShutdownHook = new MuleShutdownHook(logger);
151 registerShutdownHook(muleShutdownHook);
152 options = SystemUtils.getCommandLineOptions(args, CLI_OPTIONS);
153 }
154 catch (DefaultMuleException me)
155 {
156 throw new IllegalArgumentException(me.toString());
157 }
158
159
160
161 MuleUrlStreamHandlerFactory.installUrlStreamHandlerFactory();
162
163 String config = (String) options.get("config");
164
165 if (config == null && !options.containsKey("idle"))
166 {
167 logger.warn("A configuration file was not set, using default: " + DEFAULT_CONFIGURATION);
168
169 URL configUrl = IOUtils.getResourceAsUrl(DEFAULT_CONFIGURATION, MuleServer.class, true, false);
170 if (configUrl != null)
171 {
172 config = configUrl.toExternalForm();
173 }
174 else
175 {
176 System.out.println(CoreMessages.configNotFoundUsage());
177 System.exit(-1);
178 }
179 }
180
181 if (config != null)
182 {
183 setConfigurationResources(config);
184 }
185
186
187 String cfgBuilderClassName = (String) options.get("builder");
188
189 if (options.containsKey("idle"))
190 {
191 setConfigurationResources("IDLE");
192 cfgBuilderClassName = CLASSNAME_DEFAULT_IDLE_CONFIG_BUILDER;
193 }
194
195
196 if (cfgBuilderClassName != null)
197 {
198 try
199 {
200
201 if (cfgBuilderClassName.equalsIgnoreCase("spring"))
202 {
203 cfgBuilderClassName = CLASSNAME_SPRING_CONFIG_BUILDER;
204 }
205 setConfigBuilderClassName(cfgBuilderClassName);
206 }
207 catch (Exception e)
208 {
209 logger.fatal(e);
210 final Message message = CoreMessages.failedToLoad("Builder: " + cfgBuilderClassName);
211 System.err.println(StringMessageUtils.getBoilerPlate("FATAL: " + message.toString()));
212 System.exit(1);
213 }
214 }
215
216
217 String propertiesFile = (String) options.get("props");
218 if (propertiesFile != null)
219 {
220 setStartupPropertiesFile(propertiesFile);
221 }
222 }
223
224
225
226
227
228
229
230 public void start(boolean ownThread, boolean registerShutdownHook)
231 {
232 if (registerShutdownHook)
233 {
234 registerShutdownHook(muleShutdownHook);
235 }
236 if (ownThread)
237 {
238 Thread serverThread = new Thread(this, "MuleServer");
239 serverThread.setDaemon(true);
240 serverThread.start();
241 }
242 else
243 {
244 run();
245 }
246 }
247
248
249
250
251
252 public void run()
253 {
254 try
255 {
256 logger.info("Mule Server initializing...");
257 initialize();
258 logger.info("Mule Server starting...");
259 muleContext.start();
260 }
261 catch (Throwable e)
262 {
263 shutdown(e);
264 }
265 }
266
267
268
269
270
271
272
273
274
275
276 public static void setConfigBuilderClassName(String builderClassName) throws ClassNotFoundException
277 {
278 if (builderClassName != null)
279 {
280 Class cls = ClassUtils.loadClass(builderClassName, MuleServer.class);
281 if (ConfigurationBuilder.class.isAssignableFrom(cls))
282 {
283 MuleServer.configBuilderClassName = builderClassName;
284 }
285 else
286 {
287 throw new IllegalArgumentException("Not a usable ConfigurationBuilder class: "
288 + builderClassName);
289 }
290 }
291 else
292 {
293 MuleServer.configBuilderClassName = null;
294 }
295 }
296
297
298
299
300
301
302
303 public static String getConfigBuilderClassName()
304 {
305 if (configBuilderClassName != null)
306 {
307 return configBuilderClassName;
308 }
309 else
310 {
311 return CLASSNAME_DEFAULT_CONFIG_BUILDER;
312 }
313 }
314
315
316
317
318
319
320 public void initialize() throws Exception
321 {
322 Runtime.getRuntime().addShutdownHook(new ShutdownThread());
323
324 if (configurationResources == null)
325 {
326 logger.warn("A configuration file was not set, using default: " + DEFAULT_CONFIGURATION);
327 configurationResources = DEFAULT_CONFIGURATION;
328 }
329
330 ConfigurationBuilder cfgBuilder;
331
332 try
333 {
334
335 cfgBuilder = (ConfigurationBuilder) ClassUtils.instanciateClass(getConfigBuilderClassName(),
336 new Object[]{configurationResources}, MuleServer.class);
337 }
338 catch (Exception e)
339 {
340 throw new ConfigurationException(CoreMessages.failedToLoad(getConfigBuilderClassName()), e);
341 }
342
343 if (!cfgBuilder.isConfigured())
344 {
345 Properties startupProperties= null;
346 if (getStartupPropertiesFile() != null)
347 {
348 startupProperties = PropertiesUtils.loadProperties(getStartupPropertiesFile(), getClass());
349 }
350 DefaultMuleContextFactory muleContextFactory = new DefaultMuleContextFactory();
351 muleContext = muleContextFactory.createMuleContext(cfgBuilder, startupProperties);
352 }
353 }
354
355
356
357
358
359
360 public void shutdown(Throwable e)
361 {
362 Message msg = CoreMessages.fatalErrorWhileRunning();
363 MuleException muleException = ExceptionHelper.getRootMuleException(e);
364 if (muleException != null)
365 {
366 logger.fatal(muleException.getDetailedMessage());
367 }
368 else
369 {
370 logger.fatal(msg.toString() + " " + e.getMessage(), e);
371 }
372 List msgs = new ArrayList();
373 msgs.add(msg.getMessage());
374 Throwable root = ExceptionHelper.getRootException(e);
375 msgs.add(root.getMessage() + " (" + root.getClass().getName() + ")");
376 msgs.add(" ");
377 msgs.add(CoreMessages.fatalErrorInShutdown());
378 if (muleContext != null)
379 {
380 msgs.add(CoreMessages.serverStartedAt(muleContext.getStartDate()));
381 }
382 msgs.add(CoreMessages.serverShutdownAt(new Date()));
383
384 String shutdownMessage = StringMessageUtils.getBoilerPlate(msgs, '*', 80);
385 logger.fatal(shutdownMessage);
386
387
388 if (muleContext != null)
389 {
390 muleContext.dispose();
391 }
392 System.exit(0);
393 }
394
395
396
397
398 public void shutdown()
399 {
400 logger.info("Mule server shutting dow due to normal shutdown request");
401 List msgs = new ArrayList();
402 msgs.add(CoreMessages.normalShutdown());
403 msgs.add(CoreMessages.serverStartedAt(muleContext.getStartDate()).getMessage());
404 msgs.add(CoreMessages.serverShutdownAt(new Date()).getMessage());
405 String shutdownMessage = StringMessageUtils.getBoilerPlate(msgs, '*', 80);
406 logger.info(shutdownMessage);
407
408
409 muleContext.dispose();
410 System.exit(0);
411 }
412
413 public Log getLogger()
414 {
415 return logger;
416 }
417
418 public void registerShutdownHook(MuleShutdownHook muleShutdownHook)
419 {
420 Runtime.getRuntime().removeShutdownHook(muleShutdownHook);
421 Runtime.getRuntime().addShutdownHook(muleShutdownHook);
422 }
423
424
425
426
427
428
429
430
431
432
433 public String getConfigurationResources()
434 {
435 return configurationResources;
436 }
437
438
439
440
441
442
443 public void setConfigurationResources(String configurationResources)
444 {
445 this.configurationResources = configurationResources;
446 }
447
448 public static String getStartupPropertiesFile()
449 {
450 return startupPropertiesFile;
451 }
452
453 public static void setStartupPropertiesFile(String startupPropertiesFile)
454 {
455 MuleServer.startupPropertiesFile = startupPropertiesFile;
456 }
457
458 public static MuleContext getMuleContext()
459 {
460 return muleContext;
461 }
462
463 public static void setMuleContext(MuleContext muleContext)
464 {
465 MuleServer.muleContext = muleContext;
466 }
467
468
469
470
471
472
473 private static class ShutdownThread extends Thread
474 {
475 public void run()
476 {
477 if (muleContext !=null && !muleContext.isDisposed() && !muleContext.isDisposing())
478 {
479 muleContext.dispose();
480 }
481 }
482 }
483 }