KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mule > MuleManager


1 /*
2  * $Id: MuleManager.java 4219 2006-12-09 10:15:14Z lajos $
3  * --------------------------------------------------------------------------------------
4  * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
5  *
6  * The software in this package is published under the terms of the MuleSource MPL
7  * license, a copy of which has been included with this distribution in the
8  * LICENSE.txt file.
9  */

10
11 package org.mule;
12
13 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
14 import org.apache.commons.collections.MapUtils;
15 import org.apache.commons.collections.list.CursorableLinkedList;
16 import org.apache.commons.lang.StringUtils;
17 import org.apache.commons.logging.Log;
18 import org.apache.commons.logging.LogFactory;
19 import org.mule.config.ConfigurationException;
20 import org.mule.config.MuleConfiguration;
21 import org.mule.config.MuleProperties;
22 import org.mule.config.ThreadingProfile;
23 import org.mule.config.i18n.Message;
24 import org.mule.config.i18n.Messages;
25 import org.mule.impl.container.MultiContainerContext;
26 import org.mule.impl.internal.admin.MuleAdminAgent;
27 import org.mule.impl.internal.notifications.AdminNotification;
28 import org.mule.impl.internal.notifications.AdminNotificationListener;
29 import org.mule.impl.internal.notifications.ComponentNotification;
30 import org.mule.impl.internal.notifications.ComponentNotificationListener;
31 import org.mule.impl.internal.notifications.ConnectionNotification;
32 import org.mule.impl.internal.notifications.ConnectionNotificationListener;
33 import org.mule.impl.internal.notifications.CustomNotification;
34 import org.mule.impl.internal.notifications.CustomNotificationListener;
35 import org.mule.impl.internal.notifications.ManagementNotification;
36 import org.mule.impl.internal.notifications.ManagementNotificationListener;
37 import org.mule.impl.internal.notifications.ManagerNotification;
38 import org.mule.impl.internal.notifications.ManagerNotificationListener;
39 import org.mule.impl.internal.notifications.MessageNotification;
40 import org.mule.impl.internal.notifications.MessageNotificationListener;
41 import org.mule.impl.internal.notifications.ModelNotification;
42 import org.mule.impl.internal.notifications.ModelNotificationListener;
43 import org.mule.impl.internal.notifications.NotificationException;
44 import org.mule.impl.internal.notifications.SecurityNotification;
45 import org.mule.impl.internal.notifications.SecurityNotificationListener;
46 import org.mule.impl.internal.notifications.ServerNotificationManager;
47 import org.mule.impl.model.seda.SedaModel;
48 import org.mule.impl.security.MuleSecurityManager;
49 import org.mule.impl.work.MuleWorkManager;
50 import org.mule.management.stats.AllStatistics;
51 import org.mule.umo.UMOException;
52 import org.mule.umo.UMOInterceptorStack;
53 import org.mule.umo.endpoint.UMOEndpoint;
54 import org.mule.umo.lifecycle.FatalException;
55 import org.mule.umo.lifecycle.InitialisationException;
56 import org.mule.umo.manager.UMOAgent;
57 import org.mule.umo.manager.UMOContainerContext;
58 import org.mule.umo.manager.UMOManager;
59 import org.mule.umo.manager.UMOServerNotification;
60 import org.mule.umo.manager.UMOServerNotificationListener;
61 import org.mule.umo.manager.UMOWorkManager;
62 import org.mule.umo.model.UMOModel;
63 import org.mule.umo.provider.UMOConnector;
64 import org.mule.umo.security.UMOSecurityManager;
65 import org.mule.umo.transformer.UMOTransformer;
66 import org.mule.util.ClassUtils;
67 import org.mule.util.DateUtils;
68 import org.mule.util.SpiUtils;
69 import org.mule.util.StringMessageUtils;
70 import org.mule.util.UUID;
71 import org.mule.util.CollectionUtils;
72 import org.mule.util.queue.CachingPersistenceStrategy;
73 import org.mule.util.queue.QueueManager;
74 import org.mule.util.queue.QueuePersistenceStrategy;
75 import org.mule.util.queue.TransactionalQueueManager;
76
77 import javax.transaction.TransactionManager JavaDoc;
78 import java.net.InetAddress JavaDoc;
79 import java.net.UnknownHostException JavaDoc;
80 import java.nio.charset.Charset JavaDoc;
81 import java.text.DateFormat JavaDoc;
82 import java.util.ArrayList JavaDoc;
83 import java.util.Collections JavaDoc;
84 import java.util.Date JavaDoc;
85 import java.util.HashMap JavaDoc;
86 import java.util.Iterator JavaDoc;
87 import java.util.LinkedHashMap JavaDoc;
88 import java.util.List JavaDoc;
89 import java.util.Map JavaDoc;
90 import java.util.Collection JavaDoc;
91 import java.util.jar.Manifest JavaDoc;
92
93 /**
94  * <code>MuleManager</code> maintains and provides services for a Mule instance.
95  */

96 public class MuleManager implements UMOManager
97 {
98     public static final String JavaDoc DEFAULT_MODEL_NAME = "_default";
99     /**
100      * singleton instance
101      */

102     private static UMOManager instance = null;
103
104     /**
105      * Default configuration
106      */

107     private static MuleConfiguration config = new MuleConfiguration();
108
109     /**
110      * Connectors registry
111      */

112     private Map JavaDoc connectors = new HashMap JavaDoc();
113
114     /**
115      * Endpoints registry
116      */

117     private Map JavaDoc endpointIdentifiers = new HashMap JavaDoc();
118
119     /**
120      * Holds any application scoped environment properties set in the config
121      */

122     private Map JavaDoc applicationProps = new HashMap JavaDoc();
123
124     /**
125      * Holds any registered agents
126      */

127     private Map JavaDoc agents = new LinkedHashMap JavaDoc();
128
129     /**
130      * Holds a list of global endpoints accessible to any client code
131      */

132     private Map JavaDoc endpoints = new HashMap JavaDoc();
133
134     /**
135      * The model being used
136      */

137     private UMOModel model;
138
139     /**
140      * the unique id for this manager
141      */

142     private String JavaDoc id = UUID.getUUID();
143
144     /**
145      * The transaction Manager to use for global transactions
146      */

147     private TransactionManager JavaDoc transactionManager = null;
148
149     /**
150      * Collection for transformers registered in this component
151      */

152     private Map JavaDoc transformers = new HashMap JavaDoc();
153
154     /**
155      * True once the Mule Manager is initialised
156      */

157     private AtomicBoolean initialised = new AtomicBoolean(false);
158
159     /**
160      * True while the Mule Manager is initialising
161      */

162     private AtomicBoolean initialising = new AtomicBoolean(false);
163
164     /**
165      * Determines of the MuleManager has been started
166      */

167     private AtomicBoolean started = new AtomicBoolean(false);
168
169     /**
170      * Determines in the manager is in the process of starting
171      */

172     private AtomicBoolean starting = new AtomicBoolean(false);
173
174     /**
175      * Determines in the manager is in the process of stopping.
176      */

177     private AtomicBoolean stopping = new AtomicBoolean(false);
178
179     /**
180      * Determines if the manager has been disposed
181      */

182     private AtomicBoolean disposed = new AtomicBoolean(false);
183
184     /**
185      * Holds a reference to the deamon running the Manager if any
186      */

187     private static MuleServer server = null;
188
189     /**
190      * Maintains a reference to any interceptor stacks configured on the manager
191      */

192     private Map JavaDoc interceptorsMap = new HashMap JavaDoc();
193
194     /**
195      * the date in milliseconds from when the server was started
196      */

197     private long startDate = 0;
198
199     /**
200      * stats used for management
201      */

202     private AllStatistics stats = new AllStatistics();
203
204     /**
205      * Manages all Server event notificationManager
206      */

207     private ServerNotificationManager notificationManager = null;
208
209     private MultiContainerContext containerContext = null;
210
211     private UMOSecurityManager securityManager;
212
213     /**
214      * The queue manager to use for component queues and vm connector
215      */

216     private QueueManager queueManager;
217
218     private UMOWorkManager workManager;
219
220     /**
221      * logger used by this class
222      */

223     private static Log logger = LogFactory.getLog(MuleManager.class);
224
225     private ShutdownContext shutdownContext = new ShutdownContext(true, null);
226
227     /**
228      * Default Constructor
229      */

230     private MuleManager()
231     {
232         if (config == null)
233         {
234             config = new MuleConfiguration();
235         }
236         containerContext = new MultiContainerContext();
237         securityManager = new MuleSecurityManager();
238         Runtime.getRuntime().addShutdownHook(new ShutdownThread());
239
240         // create the event manager
241
notificationManager = new ServerNotificationManager();
242         notificationManager.registerEventType(ManagerNotification.class, ManagerNotificationListener.class);
243         notificationManager.registerEventType(ModelNotification.class, ModelNotificationListener.class);
244         notificationManager.registerEventType(ComponentNotification.class,
245             ComponentNotificationListener.class);
246         notificationManager.registerEventType(SecurityNotification.class, SecurityNotificationListener.class);
247         notificationManager.registerEventType(ManagementNotification.class,
248             ManagementNotificationListener.class);
249         notificationManager.registerEventType(AdminNotification.class, AdminNotificationListener.class);
250         notificationManager.registerEventType(CustomNotification.class, CustomNotificationListener.class);
251         notificationManager.registerEventType(ConnectionNotification.class,
252             ConnectionNotificationListener.class);
253
254         // This is obviously just a workaround until extension modules can register
255
// their own classes for notifications. Need to revisit this when the
256
// ManagementContext is implemented properly.
257
try
258         {
259             Class JavaDoc spaceNotificationClass = ClassUtils.loadClass(
260                 "org.mule.impl.space.SpaceMonitorNotification", this.getClass());
261             Class JavaDoc spaceListenerClass = ClassUtils.loadClass(
262                 "org.mule.impl.space.SpaceMonitorNotificationListener", this.getClass());
263             notificationManager.registerEventType(spaceNotificationClass, spaceListenerClass);
264         }
265         catch (ClassNotFoundException JavaDoc cnf)
266         {
267             // ignore - apparently not available
268
}
269     }
270
271     /**
272      * Getter method for the current singleton MuleManager
273      *
274      * @return the current singleton MuleManager
275      */

276     public static synchronized UMOManager getInstance()
277     {
278         if (instance == null)
279         {
280             logger.info("Creating new MuleManager instance");
281
282             Class JavaDoc clazz = SpiUtils.findService(UMOManager.class, MuleManager.class.getName(),
283                 MuleManager.class);
284             try
285             {
286                 instance = (UMOManager)clazz.newInstance();
287                 // HACK hit the model, so it's created and initialized
288
instance.getModel();
289             }
290             catch (Exception JavaDoc e)
291             {
292                 throw new MuleRuntimeException(new Message(Messages.FAILED_TO_CREATE_MANAGER_INSTANCE_X,
293                     clazz.getName()), e);
294             }
295         }
296
297         return instance;
298     }
299
300     /**
301      * A static method to determine if there is an instance of the MuleManager. This
302      * should be used instead of <code>
303      * if(MuleManager.getInstance()!=null)
304      * </code>
305      * because getInstance never returns a null. If an istance is not available one
306      * is created. This method queries the instance directly.
307      *
308      * @return true if the manager is instanciated
309      */

310     public static synchronized boolean isInstanciated()
311     {
312         return (instance != null);
313     }
314
315     /**
316      * Sets the current singleton MuleManager
317      *
318      * @deprecated this will go away soon.
319      */

320     public static synchronized void setInstance(UMOManager manager)
321     {
322         instance = manager;
323         if (instance == null)
324         {
325             config = new MuleConfiguration();
326         }
327     }
328
329     /**
330      * Gets all statisitcs for this instance
331      *
332      * @return all statisitcs for this instance
333      */

334     public AllStatistics getStatistics()
335     {
336         return stats;
337     }
338
339     /**
340      * Sets statistics on this instance
341      *
342      * @param stat
343      */

344     public void setStatistics(AllStatistics stat)
345     {
346         this.stats = stat;
347     }
348
349     /**
350      * @return the MuleConfiguration for this MuleManager. This object is immutable
351      * once the manager has initialised.
352      */

353     public static synchronized MuleConfiguration getConfiguration()
354     {
355         return config;
356     }
357
358     /**
359      * Sets the configuration for the <code>MuleManager</code>.
360      *
361      * @param config the configuration object
362      * @throws IllegalAccessError if the <code>MuleManager</code> has already been
363      * initialised.
364      * @deprecated this will go away soon.
365      */

366     public static synchronized void setConfiguration(MuleConfiguration config)
367     {
368         if (config == null)
369         {
370             throw new IllegalArgumentException JavaDoc(
371                 new Message(Messages.X_IS_NULL, "MuleConfiguration object").getMessage());
372         }
373
374         MuleManager.config = config;
375     }
376
377     // Implementation methods
378
// -------------------------------------------------------------------------
379

380     /**
381      * Destroys the MuleManager and all resources it maintains
382      */

383     public synchronized void dispose()
384     {
385         if (disposed.get())
386         {
387             return;
388         }
389         try
390         {
391             if (started.get())
392             {
393                 stop();
394             }
395         }
396         catch (UMOException e)
397         {
398             logger.error("Failed to stop manager: " + e.getMessage(), e);
399         }
400         disposed.set(true);
401         disposeConnectors();
402
403         if (model != null)
404         {
405             model.dispose();
406         }
407         disposeAgents();
408
409         transformers.clear();
410         endpoints.clear();
411         endpointIdentifiers.clear();
412         containerContext.dispose();
413         containerContext = null;
414         // props.clear();
415
fireSystemEvent(new ManagerNotification(this, ManagerNotification.MANAGER_DISPOSED));
416
417         transformers = null;
418         endpoints = null;
419         endpointIdentifiers = null;
420         // props = null;
421
initialised.set(false);
422         if (notificationManager != null)
423         {
424             notificationManager.dispose();
425         }
426         if (workManager != null)
427         {
428             workManager.dispose();
429         }
430
431         if (queueManager != null)
432         {
433             queueManager.close();
434             queueManager = null;
435         }
436
437         if (!config.isEmbedded() && startDate > 0)
438         {
439             if (logger.isInfoEnabled())
440             {
441                 logger.info(getEndSplash());
442             }
443             else
444             {
445                 System.out.println(getEndSplash());
446             }
447         }
448
449         config = new MuleConfiguration();
450         instance = null;
451     }
452
453     /**
454      * Destroys all connectors
455      */

456     private synchronized void disposeConnectors()
457     {
458         fireSystemEvent(new ManagerNotification(this, ManagerNotification.MANAGER_DISPOSING_CONNECTORS));
459         for (Iterator JavaDoc iterator = connectors.values().iterator(); iterator.hasNext();)
460         {
461             UMOConnector c = (UMOConnector)iterator.next();
462             c.dispose();
463         }
464         fireSystemEvent(new ManagerNotification(this, ManagerNotification.MANAGER_DISPOSED_CONNECTORS));
465     }
466
467     /**
468      * {@inheritDoc}
469      */

470     public Object JavaDoc getProperty(Object JavaDoc key)
471     {
472         return applicationProps.get(key);
473     }
474
475     /**
476      * {@inheritDoc}
477      */

478     public Map JavaDoc getProperties()
479     {
480         return applicationProps;
481     }
482
483     /**
484      * {@inheritDoc}
485      */

486     public TransactionManager JavaDoc getTransactionManager()
487     {
488         return transactionManager;
489     }
490
491     /**
492      * {@inheritDoc}
493      */

494     public UMOConnector lookupConnector(String JavaDoc name)
495     {
496         return (UMOConnector)connectors.get(name);
497     }
498
499     /**
500      * {@inheritDoc}
501      */

502     public String JavaDoc lookupEndpointIdentifier(String JavaDoc logicalName, String JavaDoc defaultName)
503     {
504         String JavaDoc name = (String JavaDoc)endpointIdentifiers.get(logicalName);
505         if (name == null)
506         {
507             return defaultName;
508         }
509         return name;
510     }
511
512     /**
513      * {@inheritDoc}
514      */

515     public UMOEndpoint lookupEndpoint(String JavaDoc logicalName)
516     {
517         UMOEndpoint endpoint = (UMOEndpoint)endpoints.get(logicalName);
518         if (endpoint != null)
519         {
520             return (UMOEndpoint)endpoint.clone();
521         }
522         else
523         {
524             return null;
525         }
526     }
527
528     /**
529      * {@inheritDoc}
530      */

531     public UMOEndpoint lookupEndpointByAddress(String JavaDoc address)
532     {
533         UMOEndpoint endpoint = null;
534         if (address != null)
535         {
536             boolean found = false;
537             Iterator JavaDoc iterator = endpoints.keySet().iterator();
538             while (!found && iterator.hasNext())
539             {
540                 endpoint = (UMOEndpoint)endpoints.get(iterator.next());
541                 found = (address.equals(endpoint.getEndpointURI().toString()));
542             }
543         }
544         return endpoint;
545     }
546
547     /**
548      * {@inheritDoc}
549      */

550     public UMOTransformer lookupTransformer(String JavaDoc name)
551     {
552         UMOTransformer trans = (UMOTransformer)transformers.get(name);
553         if (trans != null)
554         {
555             try
556             {
557                 return (UMOTransformer)trans.clone();
558             }
559             catch (Exception JavaDoc e)
560             {
561                 throw new MuleRuntimeException(new Message(Messages.FAILED_TO_CLONE_X, "Transformer: "
562                                                                                        + trans.getName()), e);
563             }
564         }
565         return null;
566     }
567
568     /**
569      * {@inheritDoc}
570      */

571     public void registerConnector(UMOConnector connector) throws UMOException
572     {
573         connectors.put(connector.getName(), connector);
574         if (initialised.get() || initialising.get())
575         {
576             connector.initialise();
577         }
578         if ((started.get() || starting.get()) && !connector.isStarted())
579         {
580             connector.startConnector();
581         }
582     }
583
584     /**
585      * {@inheritDoc}
586      */

587     public void unregisterConnector(String JavaDoc connectorName) throws UMOException
588     {
589         UMOConnector c = (UMOConnector)connectors.remove(connectorName);
590         if (c != null)
591         {
592             c.dispose();
593         }
594     }
595
596     /**
597      * {@inheritDoc}
598      */

599     public void registerEndpointIdentifier(String JavaDoc logicalName, String JavaDoc endpoint)
600     {
601         endpointIdentifiers.put(logicalName, endpoint);
602     }
603
604     /**
605      * {@inheritDoc}
606      */

607     public void unregisterEndpointIdentifier(String JavaDoc logicalName)
608     {
609         endpointIdentifiers.remove(logicalName);
610     }
611
612     /**
613      * {@inheritDoc}
614      */

615     public void registerEndpoint(UMOEndpoint endpoint)
616     {
617         endpoints.put(endpoint.getName(), endpoint);
618     }
619
620     /**
621      * {@inheritDoc}
622      */

623     public void unregisterEndpoint(String JavaDoc endpointName)
624     {
625         UMOEndpoint p = (UMOEndpoint)endpoints.get(endpointName);
626         if (p != null)
627         {
628             endpoints.remove(p);
629         }
630     }
631
632     /**
633      * {@inheritDoc}
634      */

635     public void registerTransformer(UMOTransformer transformer) throws InitialisationException
636     {
637         transformer.initialise();
638         transformers.put(transformer.getName(), transformer);
639         logger.info("Transformer " + transformer.getName() + " has been initialised successfully");
640     }
641
642     /**
643      * {@inheritDoc}
644      */

645     public void unregisterTransformer(String JavaDoc transformerName)
646     {
647         transformers.remove(transformerName);
648     }
649
650     /**
651      * {@inheritDoc}
652      */

653     public void setProperty(Object JavaDoc key, Object JavaDoc value)
654     {
655         applicationProps.put(key, value);
656     }
657
658     public void addProperties(Map JavaDoc props)
659     {
660         applicationProps.putAll(props);
661     }
662
663     /**
664      * {@inheritDoc}
665      */

666     public void setTransactionManager(TransactionManager JavaDoc newManager) throws UMOException
667     {
668         if (transactionManager != null)
669         {
670             throw new ConfigurationException(new Message(Messages.TX_MANAGER_ALREADY_SET));
671         }
672         transactionManager = newManager;
673     }
674
675     /**
676      * {@inheritDoc}
677      */

678     public synchronized void initialise() throws UMOException
679     {
680         validateEncoding();
681         validateOSEncoding();
682
683         if (!initialised.get())
684         {
685             initialising.set(true);
686             startDate = System.currentTimeMillis();
687             // if no work manager has been set create a default one
688
if (workManager == null)
689             {
690                 ThreadingProfile tp = config.getDefaultThreadingProfile();
691                 logger.debug("Creating default work manager using default threading profile: " + tp);
692                 workManager = new MuleWorkManager(tp, "UMOManager");
693                 workManager.start();
694             }
695
696             // Start the event manager
697
notificationManager.start(workManager);
698
699             // Fire message notifications if the option is set. This will fire
700
// inbound and outbound message events that can
701
// consume resources in high throughput systems
702
if (config.isEnableMessageEvents())
703             {
704                 notificationManager.registerEventType(MessageNotification.class,
705                     MessageNotificationListener.class);
706             }
707
708             fireSystemEvent(new ManagerNotification(this, ManagerNotification.MANAGER_INITIALISNG));
709             if (id == null)
710             {
711                 logger.warn("No unique id has been set on this manager");
712             }
713             try
714             {
715                 if (securityManager != null)
716                 {
717                     securityManager.initialise();
718                 }
719                 if (queueManager == null)
720                 {
721                     try
722                     {
723                         TransactionalQueueManager queueMgr = new TransactionalQueueManager();
724                         QueuePersistenceStrategy ps = new CachingPersistenceStrategy(
725                             getConfiguration().getPersistenceStrategy());
726                         queueMgr.setPersistenceStrategy(ps);
727                         queueManager = queueMgr;
728                     }
729                     catch (Exception JavaDoc e)
730                     {
731                         throw new InitialisationException(new Message(Messages.INITIALISATION_FAILURE_X,
732                             "QueueManager"), e);
733                     }
734                 }
735
736                 initialiseConnectors();
737                 initialiseEndpoints();
738                 initialiseAgents();
739                 if (model != null)
740                 {
741                     model.initialise();
742                 }
743
744             }
745             finally
746             {
747                 initialised.set(true);
748                 initialising.set(false);
749                 fireSystemEvent(new ManagerNotification(this, ManagerNotification.MANAGER_INITIALISED));
750             }
751         }
752     }
753
754     protected void validateEncoding() throws FatalException
755     {
756         String JavaDoc encoding = System.getProperty(MuleProperties.MULE_ENCODING_SYSTEM_PROPERTY);
757         if (encoding == null)
758         {
759             encoding = config.getEncoding();
760             System.setProperty(MuleProperties.MULE_ENCODING_SYSTEM_PROPERTY, encoding);
761         }
762         else
763         {
764             config.setEncoding(encoding);
765         }
766         // Check we have a valid and supported encoding
767
if (!Charset.isSupported(config.getEncoding()))
768         {
769             throw new FatalException(new Message(Messages.PROPERTY_X_HAS_INVALID_VALUE_X, "encoding",
770                 config.getEncoding()), this);
771         }
772     }
773
774     protected void validateOSEncoding() throws FatalException
775     {
776         String JavaDoc encoding = System.getProperty(MuleProperties.MULE_OS_ENCODING_SYSTEM_PROPERTY);
777         if (encoding == null)
778         {
779             encoding = config.getOSEncoding();
780             System.setProperty(MuleProperties.MULE_OS_ENCODING_SYSTEM_PROPERTY, encoding);
781         }
782         else
783         {
784             config.setOSEncoding(encoding);
785         }
786         // Check we have a valid and supported encoding
787
if (!Charset.isSupported(config.getOSEncoding()))
788         {
789             throw new FatalException(new Message(Messages.PROPERTY_X_HAS_INVALID_VALUE_X, "osEncoding",
790                 config.getOSEncoding()), this);
791         }
792     }
793
794     protected void registerAdminAgent() throws UMOException
795     {
796         // Allows users to disable all server components and connections
797
// this can be useful for testing
798
boolean disable = MapUtils.getBooleanValue(System.getProperties(),
799             MuleProperties.DISABLE_SERVER_CONNECTIONS_SYSTEM_PROPERTY, false);
800
801         // if endpointUri is blanked out do not setup server components
802
if (StringUtils.isBlank(config.getServerUrl()))
803         {
804             logger.info("Server endpointUri is null, not registering Mule Admin agent");
805             disable = true;
806         }
807
808         if (disable)
809         {
810             unregisterAgent(MuleAdminAgent.AGENT_NAME);
811         }
812         else
813         {
814             if (lookupAgent(MuleAdminAgent.AGENT_NAME) == null)
815             {
816                 registerAgent(new MuleAdminAgent());
817             }
818         }
819     }
820
821     protected void initialiseEndpoints() throws InitialisationException
822     {
823         UMOEndpoint ep;
824         for (Iterator JavaDoc iterator = this.endpoints.values().iterator(); iterator.hasNext();)
825         {
826             ep = (UMOEndpoint)iterator.next();
827             ep.initialise();
828             // the connector has been created for this endpoint so lets
829
// set the create connector to 0 so that every time this endpoint
830
// is referenced we don't create another connector
831
ep.setCreateConnector(0);
832         }
833     }
834
835     /**
836      * Start the <code>MuleManager</code>. This will start the connectors and
837      * sessions.
838      *
839      * @throws UMOException if the the connectors or components fail to start
840      */

841     public synchronized void start() throws UMOException
842     {
843         initialise();
844
845         if (!started.get())
846         {
847             starting.set(true);
848             fireSystemEvent(new ManagerNotification(this, ManagerNotification.MANAGER_STARTING));
849             registerAdminAgent();
850             if (queueManager != null)
851             {
852                 queueManager.start();
853             }
854             startConnectors();
855             startAgents();
856             if (model != null)
857             {
858                 model.start();
859             }
860             started.set(true);
861             starting.set(false);
862             if (!config.isEmbedded())
863             {
864                 if (logger.isInfoEnabled())
865                 {
866                     logger.info(getStartSplash());
867                 }
868                 else
869                 {
870                     System.out.println(getStartSplash());
871                 }
872             }
873             fireSystemEvent(new ManagerNotification(this, ManagerNotification.MANAGER_STARTED));
874         }
875     }
876
877     /**
878      * Start the <code>MuleManager</code>. This will start the connectors and
879      * sessions.
880      *
881      * @param serverUrl the server Url for this instance
882      * @throws UMOException if the the connectors or components fail to start
883      */

884     public void start(String JavaDoc serverUrl) throws UMOException
885     {
886         // this.createClientListener = createRequestListener;
887
config.setServerUrl(serverUrl);
888         start();
889     }
890
891     /**
892      * Starts the connectors
893      *
894      * @throws MuleException if the connectors fail to start
895      */

896     private void startConnectors() throws UMOException
897     {
898         for (Iterator JavaDoc iterator = connectors.values().iterator(); iterator.hasNext();)
899         {
900             UMOConnector c = (UMOConnector)iterator.next();
901             c.startConnector();
902         }
903         logger.info("Connectors have been started successfully");
904     }
905
906     private void initialiseConnectors() throws InitialisationException
907     {
908         for (Iterator JavaDoc iterator = connectors.values().iterator(); iterator.hasNext();)
909         {
910             UMOConnector c = (UMOConnector)iterator.next();
911             c.initialise();
912         }
913         logger.info("Connectors have been initialised successfully");
914     }
915
916     /**
917      * Stops the <code>MuleManager</code> which stops all sessions and connectors
918      *
919      * @throws UMOException if either any of the sessions or connectors fail to stop
920      */

921     public synchronized void stop() throws UMOException
922     {
923         started.set(false);
924         stopping.set(true);
925         fireSystemEvent(new ManagerNotification(this, ManagerNotification.MANAGER_STOPPING));
926
927         stopConnectors();
928         stopAgents();
929
930         if (queueManager != null)
931         {
932             queueManager.stop();
933         }
934
935         logger.debug("Stopping model...");
936         if (model != null)
937         {
938             model.stop();
939         }
940
941         stopping.set(false);
942         fireSystemEvent(new ManagerNotification(this, ManagerNotification.MANAGER_STOPPED));
943     }
944
945     /**
946      * Stops the connectors
947      *
948      * @throws MuleException if any of the connectors fail to stop
949      */

950     private void stopConnectors() throws UMOException
951     {
952         logger.debug("Stopping connectors...");
953         for (Iterator JavaDoc iterator = connectors.values().iterator(); iterator.hasNext();)
954         {
955             UMOConnector c = (UMOConnector)iterator.next();
956             c.stopConnector();
957         }
958         logger.info("Connectors have been stopped successfully");
959     }
960
961     /**
962      * If the <code>MuleManager</code> was started from the <code>MuleServer</code>
963      * daemon then this will be called by the Server
964      *
965      * @param server a reference to the <code>MuleServer</code>.
966      */

967     void setServer(MuleServer server)
968     {
969         MuleManager.server = server;
970     }
971
972     /**
973      * Shuts down the whole server tring to shut down all resources cleanly on the
974      * way
975      *
976      * @param e an exception that caused the <code>shutdown()</code> method to be
977      * called. If e is null the shutdown message will just display a time
978      * when the server was shutdown. Otherwise the exception information
979      * will also be displayed.
980      */

981     public void shutdown(Throwable JavaDoc e, boolean aggressive)
982     {
983         shutdownContext = new ShutdownContext(aggressive, e);
984         System.exit(0);
985     }
986
987     /**
988      * {@inheritDoc}
989      */

990     public UMOModel getModel()
991     {
992         // todo in version two we must not assume the model
993
if (model == null)
994         {
995             model = new SedaModel();
996             model.setName(DEFAULT_MODEL_NAME);
997         }
998         return model;
999     }
1000
1001    /**
1002     * {@inheritDoc}
1003     */

1004    public void setModel(UMOModel model) throws UMOException
1005    {
1006        this.model = model;
1007        if (initialised.get())
1008        {
1009            model.initialise();
1010        }
1011
1012        if (started.get())
1013        {
1014            model.start();
1015        }
1016    }
1017
1018    /**
1019     * {@inheritDoc}
1020     */

1021    public void registerInterceptorStack(String JavaDoc name, UMOInterceptorStack stack)
1022    {
1023        interceptorsMap.put(name, stack);
1024    }
1025
1026    /**
1027     * {@inheritDoc}
1028     */

1029    public UMOInterceptorStack lookupInterceptorStack(String JavaDoc name)
1030    {
1031        return (UMOInterceptorStack)interceptorsMap.get(name);
1032    }
1033
1034    /**
1035     * {@inheritDoc}
1036     */

1037    public Map JavaDoc getConnectors()
1038    {
1039        return Collections.unmodifiableMap(connectors);
1040    }
1041
1042    /**
1043     * {@inheritDoc}
1044     */

1045    public Map JavaDoc getEndpointIdentifiers()
1046    {
1047        return Collections.unmodifiableMap(endpointIdentifiers);
1048    }
1049
1050    /**
1051     * {@inheritDoc}
1052     */

1053    public Map JavaDoc getEndpoints()
1054    {
1055        return Collections.unmodifiableMap(endpoints);
1056    }
1057
1058    /**
1059     * {@inheritDoc}
1060     */

1061    public Map JavaDoc getTransformers()
1062    {
1063        return Collections.unmodifiableMap(transformers);
1064    }
1065
1066    /**
1067     * {@inheritDoc}
1068     */

1069    public boolean isStarted()
1070    {
1071        return started.get();
1072    }
1073
1074    /**
1075     * {@inheritDoc}
1076     */

1077    public boolean isInitialised()
1078    {
1079        return initialised.get();
1080    }
1081
1082    /**
1083     * Determines if the server is currently initialising
1084     *
1085     * @return true if if the server is currently initialising, false otherwise
1086     */

1087    public boolean isInitialising()
1088    {
1089        return initialising.get();
1090    }
1091
1092    /**
1093     * Determines in the manager is in the process of stopping.
1094     */

1095    public boolean isStopping()
1096    {
1097        return stopping.get();
1098    }
1099
1100    /**
1101     * {@inheritDoc}
1102     */

1103    public long getStartDate()
1104    {
1105        return startDate;
1106    }
1107
1108    /**
1109     * Returns a formatted string that is a summary of the configuration of the
1110     * server. This is the brock of information that gets displayed when the server
1111     * starts
1112     *
1113     * @return a string summary of the server information
1114     */

1115    protected String JavaDoc getStartSplash()
1116    {
1117        String JavaDoc notset = new Message(Messages.NOT_SET).getMessage();
1118
1119        // Mule Version, Timestamp, and Server ID
1120
List message = new ArrayList JavaDoc();
1121        Manifest JavaDoc mf = config.getManifest();
1122        Map JavaDoc att = mf.getMainAttributes();
1123        if (att.values().size() > 0)
1124        {
1125            message.add(StringUtils.defaultString(config.getProductDescription(), notset) + " "
1126                        + new Message(Messages.VERSION).getMessage() + " "
1127                        + StringUtils.defaultString(config.getProductVersion(), notset));
1128
1129            message.add(StringUtils.defaultString(config.getVendorName(), notset));
1130            message.add(StringUtils.defaultString(config.getProductMoreInfo(), notset));
1131        }
1132        else
1133        {
1134            message.add(new Message(Messages.VERSION_INFO_NOT_SET).getMessage());
1135        }
1136        message.add(" ");
1137        DateFormat JavaDoc df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
1138        message.add(new Message(Messages.SERVER_STARTED_AT_X, df.format(new Date JavaDoc(getStartDate()))).getMessage());
1139        message.add("Server ID: " + id);
1140
1141        // JDK, OS, and Host
1142
message.add("JDK: " + System.getProperty("java.version") + " (" + System.getProperty("java.vm.info")
1143                    + ")");
1144        String JavaDoc patch = System.getProperty("sun.os.patch.level", null);
1145        message.add("OS: " + System.getProperty("os.name")
1146                    + (patch != null && !"unknown".equalsIgnoreCase(patch) ? " - " + patch : "") + " ("
1147                    + System.getProperty("os.version") + ", " + System.getProperty("os.arch") + ")");
1148        try
1149        {
1150            InetAddress JavaDoc host = InetAddress.getLocalHost();
1151            message.add("Host: " + host.getHostName() + " (" + host.getHostAddress() + ")");
1152        }
1153        catch (UnknownHostException JavaDoc e)
1154        {
1155            // ignore
1156
}
1157
1158        // Mule Agents
1159
message.add(" ");
1160        if (agents.size() == 0)
1161        {
1162            message.add(new Message(Messages.AGENTS_RUNNING).getMessage() + " "
1163                        + new Message(Messages.NONE).getMessage());
1164        }
1165        else
1166        {
1167            message.add(new Message(Messages.AGENTS_RUNNING).getMessage());
1168            UMOAgent umoAgent;
1169            for (Iterator JavaDoc iterator = agents.values().iterator(); iterator.hasNext();)
1170            {
1171                umoAgent = (UMOAgent)iterator.next();
1172                message.add(" " + umoAgent.getDescription());
1173            }
1174        }
1175        return StringMessageUtils.getBoilerPlate(message, '*', 70);
1176    }
1177
1178    private String JavaDoc getEndSplash()
1179    {
1180        List message = new ArrayList JavaDoc(2);
1181        long currentTime = System.currentTimeMillis();
1182        DateFormat JavaDoc df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
1183        message.add(new Message(Messages.SHUTDOWN_NORMALLY_ON_X, df.format(new Date JavaDoc())).getMessage());
1184        long duration = 10;
1185        if (startDate > 0)
1186        {
1187            duration = currentTime - startDate;
1188        }
1189        message.add(new Message(Messages.SERVER_WAS_UP_FOR_X, DateUtils.getFormattedDuration(duration)).getMessage());
1190
1191        return StringMessageUtils.getBoilerPlate(message, '*', 78);
1192    }
1193
1194    /**
1195     * {@inheritDoc}
1196     */

1197    public void registerAgent(UMOAgent agent) throws UMOException
1198    {
1199        agents.put(agent.getName(), agent);
1200        agent.registered();
1201        // Don't allow initialisation while the server is being initalised,
1202
// only when we are done. Otherwise the agent registration
1203
// order can be corrupted.
1204
if (initialised.get())
1205        {
1206            agent.initialise();
1207        }
1208        if ((started.get() || starting.get()))
1209        {
1210            agent.start();
1211        }
1212    }
1213
1214    public UMOAgent lookupAgent(String JavaDoc name)
1215    {
1216        return (UMOAgent)agents.get(name);
1217    }
1218
1219    /**
1220     * {@inheritDoc}
1221     */

1222    public UMOAgent unregisterAgent(String JavaDoc name) throws UMOException
1223    {
1224        if (name == null)
1225        {
1226            return null;
1227        }
1228        UMOAgent agent = (UMOAgent)agents.remove(name);
1229        if (agent != null)
1230        {
1231            agent.dispose();
1232            agent.unregistered();
1233        }
1234        return agent;
1235    }
1236
1237    /**
1238     * Initialises all registered agents
1239     *
1240     * @throws InitialisationException
1241     */

1242    protected void initialiseAgents() throws InitialisationException
1243    {
1244        logger.info("Initialising agents...");
1245
1246        // Do not iterate over the map directly, as 'complex' agents
1247
// may spawn extra agents during initialisation. This will
1248
// cause a ConcurrentModificationException.
1249
// Use a cursorable iteration, which supports on-the-fly underlying
1250
// data structure changes.
1251
Collection JavaDoc agentsSnapshot = agents.values();
1252        CursorableLinkedList agentRegistrationQueue = new CursorableLinkedList(agentsSnapshot);
1253        CursorableLinkedList.Cursor cursor = agentRegistrationQueue.cursor();
1254
1255        // the actual agent object refs are the same, so we are just
1256
// providing different views of the same underlying data
1257

1258        try
1259        {
1260            while (cursor.hasNext())
1261            {
1262                UMOAgent umoAgent = (UMOAgent) cursor.next();
1263
1264                int originalSize = agentsSnapshot.size();
1265                logger.debug("Initialising agent: " + umoAgent.getName());
1266                umoAgent.initialise();
1267                // thank you, we are done with you
1268
cursor.remove();
1269
1270                // Direct calls to MuleManager.registerAgent() modify the original
1271
// agents map, re-check if the above agent registered any
1272
// 'child' agents.
1273
int newSize = agentsSnapshot.size();
1274                int delta = newSize - originalSize;
1275                if (delta > 0)
1276                {
1277                    // TODO there's some mess going on in
1278
// http://issues.apache.org/jira/browse/COLLECTIONS-219
1279
// watch out when upgrading the commons-collections.
1280
Collection JavaDoc tail = CollectionUtils.retainAll(agentsSnapshot, agentRegistrationQueue);
1281                    Collection JavaDoc head = CollectionUtils.subtract(agentsSnapshot, tail);
1282
1283                    // again, above are only refs, all going back to the original agents map
1284

1285                    // re-order the queue
1286
agentRegistrationQueue.clear();
1287                    // 'spawned' agents first
1288
agentRegistrationQueue.addAll(head);
1289                    // and the rest
1290
agentRegistrationQueue.addAll(tail);
1291
1292                    // update agents map with a new order in case we want to re-initialise
1293
// MuleManager on the fly
1294
this.agents.clear();
1295                    for (Iterator JavaDoc it = agentRegistrationQueue.iterator(); it.hasNext();) {
1296                        UMOAgent theAgent = (UMOAgent) it.next();
1297                        this.agents.put(theAgent.getName(), theAgent);
1298                    }
1299                }
1300            }
1301        }
1302        finally
1303        {
1304            // close the cursor as per JavaDoc
1305
cursor.close();
1306        }
1307        logger.info("Agents Successfully Initialised");
1308    }
1309
1310    /**
1311     * {@inheritDoc}
1312     */

1313    protected void startAgents() throws UMOException
1314    {
1315        UMOAgent umoAgent;
1316        logger.info("Starting agents...");
1317        for (Iterator JavaDoc iterator = agents.values().iterator(); iterator.hasNext();)
1318        {
1319            umoAgent = (UMOAgent)iterator.next();
1320            logger.info("Starting agent: " + umoAgent.getDescription());
1321            umoAgent.start();
1322
1323        }
1324        logger.info("Agents Successfully Started");
1325    }
1326
1327    /**
1328     * {@inheritDoc}
1329     */

1330    protected void stopAgents() throws UMOException
1331    {
1332        logger.info("Stopping agents...");
1333        for (Iterator JavaDoc iterator = agents.values().iterator(); iterator.hasNext();)
1334        {
1335            UMOAgent umoAgent = (UMOAgent)iterator.next();
1336            logger.debug("Stopping agent: " + umoAgent.getName());
1337            umoAgent.stop();
1338        }
1339        logger.info("Agents Successfully Stopped");
1340    }
1341
1342    /**
1343     * {@inheritDoc}
1344     */

1345    protected void disposeAgents()
1346    {
1347        UMOAgent umoAgent;
1348        logger.info("disposing agents...");
1349        for (Iterator JavaDoc iterator = agents.values().iterator(); iterator.hasNext();)
1350        {
1351            umoAgent = (UMOAgent)iterator.next();
1352            logger.debug("Disposing agent: " + umoAgent.getName());
1353            umoAgent.dispose();
1354        }
1355        logger.info("Agents Successfully Disposed");
1356    }
1357
1358    /**
1359     * associates a Dependency Injector container or Jndi container with Mule. This
1360     * can be used to integrate container managed resources with Mule resources
1361     *
1362     * @param container a Container context to use. By default, there is a default
1363     * Mule container <code>MuleContainerContext</code> that will assume
1364     * that the reference key for an oblect is a classname and will try to
1365     * instanciate it.
1366     */

1367    public void setContainerContext(UMOContainerContext container) throws UMOException
1368    {
1369        if (container == null)
1370        {
1371            if (containerContext != null)
1372            {
1373                containerContext.dispose();
1374            }
1375            containerContext = new MultiContainerContext();
1376        }
1377        else
1378        {
1379            container.initialise();
1380            containerContext.addContainer(container);
1381        }
1382    }
1383
1384    /**
1385     * associates a Dependency Injector container with Mule. This can be used to
1386     * integrate container managed resources with Mule resources
1387     *
1388     * @return the container associated with the Manager
1389     */

1390    public UMOContainerContext getContainerContext()
1391    {
1392        return containerContext;
1393    }
1394
1395    /**
1396     * {@inheritDoc}
1397     */

1398    public void registerListener(UMOServerNotificationListener l) throws NotificationException
1399    {
1400        registerListener(l, null);
1401    }
1402
1403    public void registerListener(UMOServerNotificationListener l, String JavaDoc resourceIdentifier)
1404        throws NotificationException
1405    {
1406        if (notificationManager == null)
1407        {
1408            throw new NotificationException(new Message(Messages.SERVER_EVENT_MANAGER_NOT_ENABLED));
1409        }
1410        notificationManager.registerListener(l, resourceIdentifier);
1411    }
1412
1413    /**
1414     * {@inheritDoc}
1415     */

1416    public void unregisterListener(UMOServerNotificationListener l)
1417    {
1418        if (notificationManager != null)
1419        {
1420            notificationManager.unregisterListener(l);
1421        }
1422    }
1423
1424    /**
1425     * Fires a mule 'system' event. These are notifications that are fired because
1426     * something within the Mule instance happened such as the Model started or the
1427     * server is being disposed.
1428     *
1429     * @param e the event that occurred
1430     */

1431    protected void fireSystemEvent(UMOServerNotification e)
1432    {
1433        if (notificationManager != null)
1434        {
1435            notificationManager.fireEvent(e);
1436        }
1437        else if (logger.isDebugEnabled())
1438        {
1439            logger.debug("Event Manager is not enabled, ignoring event: " + e);
1440        }
1441    }
1442
1443    /**
1444     * Fires a server notification to all registered
1445     * {@link org.mule.impl.internal.notifications.CustomNotificationListener}
1446     * notificationManager.
1447     *
1448     * @param notification the notification to fire. This must be of type
1449     * {@link org.mule.impl.internal.notifications.CustomNotification}
1450     * otherwise an exception will be thrown.
1451     * @throws UnsupportedOperationException if the notification fired is not a
1452     * {@link org.mule.impl.internal.notifications.CustomNotification}
1453     */

1454    public void fireNotification(UMOServerNotification notification)
1455    {
1456        // if(notification instanceof CustomNotification) {
1457
if (notificationManager != null)
1458        {
1459            notificationManager.fireEvent(notification);
1460        }
1461        else if (logger.isDebugEnabled())
1462        {
1463            logger.debug("Event Manager is not enabled, ignoring notification: " + notification);
1464        }
1465        // } else {
1466
// throw new UnsupportedOperationException(new
1467
// Message(Messages.ONLY_CUSTOM_EVENTS_CAN_BE_FIRED).getMessage());
1468
// }
1469
}
1470
1471    public void setId(String JavaDoc id)
1472    {
1473        this.id = id;
1474    }
1475
1476    public String JavaDoc getId()
1477    {
1478        return id;
1479    }
1480
1481    /**
1482     * Sets the security manager used by this Mule instance to authenticate and
1483     * authorise incoming and outgoing event traffic and service invocations
1484     *
1485     * @param securityManager the security manager used by this Mule instance to
1486     * authenticate and authorise incoming and outgoing event traffic and
1487     * service invocations
1488     */

1489    public void setSecurityManager(UMOSecurityManager securityManager) throws InitialisationException
1490    {
1491        this.securityManager = securityManager;
1492        if (securityManager != null && isInitialised())
1493        {
1494            this.securityManager.initialise();
1495        }
1496    }
1497
1498    /**
1499     * Gets the security manager used by this Mule instance to authenticate and
1500     * authorise incoming and outgoing event traffic and service invocations
1501     *
1502     * @return he security manager used by this Mule instance to authenticate and
1503     * authorise incoming and outgoing event traffic and service invocations
1504     */

1505    public UMOSecurityManager getSecurityManager()
1506    {
1507        return securityManager;
1508    }
1509
1510    /**
1511     * Obtains a workManager instance that can be used to schedule work in a thread
1512     * pool. This will be used primarially by UMOAgents wanting to schedule work.
1513     * This work Manager must <b>never</b> be used by provider implementations as
1514     * they have their own workManager accible on the connector. If a workManager has
1515     * not been set by the time the <code>initialise()</code> method has been
1516     * called a default <code>MuleWorkManager</code> will be created using the
1517     * <i>DefaultThreadingProfile</i> on the <code>MuleConfiguration</code>
1518     * object.
1519     *
1520     * @return a workManager instance used by the current MuleManager
1521     * @see org.mule.config.ThreadingProfile
1522     * @see MuleConfiguration
1523     */

1524    public UMOWorkManager getWorkManager()
1525    {
1526        return workManager;
1527    }
1528
1529    /**
1530     * Obtains a workManager instance that can be used to schedule work in a thread
1531     * pool. This will be used primarially by UMOAgents wanting to schedule work.
1532     * This work Manager must <b>never</b> be used by provider implementations as
1533     * they have their own workManager accible on the connector. If a workManager has
1534     * not been set by the time the <code>initialise()</code> method has been
1535     * called a default <code>MuleWorkManager</code> will be created using the
1536     * <i>DefaultThreadingProfile</i> on the <code>MuleConfiguration</code>
1537     * object.
1538     *
1539     * @param workManager the workManager instance used by the current MuleManager
1540     * @throws IllegalStateException if the workManager has already been set.
1541     * @see org.mule.config.ThreadingProfile
1542     * @see MuleConfiguration
1543     * @see MuleWorkManager
1544     */

1545    public void setWorkManager(UMOWorkManager workManager)
1546    {
1547        if (this.workManager != null)
1548        {
1549            throw new IllegalStateException JavaDoc(new Message(Messages.CANT_SET_X_ONCE_IT_HAS_BEEN_SET,
1550                "workManager").getMessage());
1551        }
1552        this.workManager = workManager;
1553    }
1554
1555    public QueueManager getQueueManager()
1556    {
1557        return queueManager;
1558    }
1559
1560    public void setQueueManager(QueueManager queueManager)
1561    {
1562        this.queueManager = queueManager;
1563    }
1564
1565    /**
1566     * The shutdown thread used by the server when its main thread is terminated
1567     */

1568    private class ShutdownThread extends Thread JavaDoc
1569    {
1570        Throwable JavaDoc t;
1571        boolean aggressive = true;
1572
1573        public ShutdownThread()
1574        {
1575            super();
1576            this.t = shutdownContext.getException();
1577            this.aggressive = shutdownContext.isAggressive();
1578        }
1579
1580        /*
1581         * (non-Javadoc)
1582         *
1583         * @see java.lang.Runnable#run()
1584         */

1585        public void run()
1586        {
1587            dispose();
1588            if (!aggressive)
1589            {
1590                // FIX need to check if there are any outstanding
1591
// operations to be done?
1592
}
1593
1594            if (server != null)
1595            {
1596                if (t != null)
1597                {
1598                    server.shutdown(t);
1599                }
1600                else
1601                {
1602                    server.shutdown();
1603                }
1604            }
1605        }
1606    }
1607
1608    private class ShutdownContext
1609    {
1610        private boolean aggressive = false;
1611        private Throwable JavaDoc exception = null;
1612
1613        public ShutdownContext(boolean aggressive, Throwable JavaDoc exception)
1614        {
1615            this.aggressive = aggressive;
1616            this.exception = exception;
1617        }
1618
1619        public boolean isAggressive()
1620        {
1621            return aggressive;
1622        }
1623
1624        public Throwable JavaDoc getException()
1625        {
1626            return exception;
1627        }
1628    }
1629}
1630
Popular Tags