View Javadoc

1   package com.atlassian.sal.core.lifecycle;
2   
3   import com.atlassian.plugin.event.PluginEventListener;
4   import com.atlassian.plugin.event.PluginEventManager;
5   import com.atlassian.plugin.event.events.PluginFrameworkStartedEvent;
6   import com.atlassian.plugin.event.impl.DefaultPluginEventManager;
7   import com.atlassian.sal.api.lifecycle.LifecycleAware;
8   import com.atlassian.sal.api.lifecycle.LifecycleManager;
9   import org.apache.commons.lang.Validate;
10  import org.slf4j.Logger;
11  import org.slf4j.LoggerFactory;
12  
13  import java.util.List;
14  import java.util.Map;
15  
16  public abstract class DefaultLifecycleManager implements LifecycleManager
17  {
18      private static final Logger log = LoggerFactory.getLogger(DefaultLifecycleManager.class);
19  
20      //@GuardedBy("this")
21      private boolean started = false;
22      private List<LifecycleAware> listeners;
23      private final PluginEventManager pluginEventManager;
24  
25      public DefaultLifecycleManager(PluginEventManager pluginEventManager)
26      {
27          this.pluginEventManager = pluginEventManager;
28          pluginEventManager.register(this);
29      }
30  
31      /**
32       * This method will be invoked by PluginEventManager when PluginFrameworkStartedEvent event occurs.
33       * PluginEventManager uses methods called "channel" and methods with annotation "@PluginEventListener"
34       * to notify a registered listeners about events.
35       * See {@link DefaultPluginEventManager} for more details on this black magic.
36       * @param event
37       */
38      @PluginEventListener
39      public void onFrameworkStart(final PluginFrameworkStartedEvent event)
40      {
41          start();
42      }
43  
44      public synchronized void start()
45      {
46          if (!started && isApplicationSetUp())
47          {
48              try
49              {
50                  notifyOnStart();
51              } finally
52              {
53                  started = true;
54              }
55  
56          }
57      }
58  
59      /**
60       * Called by spring-osgi when when new LifecycleAware service is installed. Defined in "spring-components.xml" in "META-INF/spring/"
61       *
62       * @param service the service to notify
63       * @param properties ignored
64       */
65      @SuppressWarnings("unchecked")
66      public synchronized void onBind(final LifecycleAware service, final Map properties)
67      {
68          if (started)
69          {
70              notifyLifecycleAwareOfStart(service);
71          }
72      }
73  
74      /**
75       * Unregister from the {@link PluginEventManager}.
76       *
77       * @since 2.3.0
78       */
79      public void destroy()
80      {
81          pluginEventManager.unregister(this);
82      }
83  
84      protected void notifyOnStart()
85      {
86          Validate.notNull(listeners, "The list of LifecycleAware implementations hasn't been set yet and so the manager cannot start.");
87  
88          // calling listeners.iterator() will dynamically update list to get currently installed LifecycleAware components.
89          for (final LifecycleAware entry : listeners)
90          {
91              notifyLifecycleAwareOfStart(entry);
92          }
93      }
94  
95      private void notifyLifecycleAwareOfStart(final LifecycleAware entry)
96      {
97          try
98          {
99              entry.onStart();
100         }
101         catch (final RuntimeException ex)
102         {
103             log.error("Unable to start component: " + entry.getClass().getName(), ex);
104         }
105     }
106 
107     //@GuardedBy("spring-dm")
108     public void setLifecycleAwareListeners(List<LifecycleAware> listeners)
109     {
110         this.listeners = listeners;
111     }
112 }