View Javadoc
1   package com.atlassian.plugin.osgi.spring;
2   
3   import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextEvent;
4   import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextEventMulticasterAdapter;
5   import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextListener;
6   import org.osgi.framework.BundleContext;
7   import org.osgi.framework.InvalidSyntaxException;
8   import org.osgi.framework.ServiceEvent;
9   import org.osgi.framework.ServiceReference;
10  import org.springframework.context.ApplicationListener;
11  import org.springframework.context.event.SimpleApplicationEventMulticaster;
12  
13  /**
14   * Finds ApplicationListener bridge and uses it to CC all event broadcasts
15   *
16   * @since 2.2.1
17   */
18  public class PluginBridgeEventMulticaster extends OsgiBundleApplicationContextEventMulticasterAdapter {
19      private volatile OsgiBundleApplicationContextListener bridgeListener;
20  
21      /**
22       * Look for the application listener bridge from atlassian-plugins-osgi-bridge. Can't use Spring DM stuff as it
23       * creates a circular dependency.
24       */
25      public PluginBridgeEventMulticaster(final BundleContext bundleContext) {
26          super(new SimpleApplicationEventMulticaster());
27  
28          String filter = "(&(objectClass=" + OsgiBundleApplicationContextListener.class.getName() + ")(plugin-bridge=true))";
29  
30          ServiceReference[] refs;
31          try {
32              refs = bundleContext.getAllServiceReferences(ApplicationListener.class.getName(), filter);
33              if (refs != null && refs.length == 1) {
34                  bridgeListener = (OsgiBundleApplicationContextListener) bundleContext.getService(refs[0]);
35              }
36  
37              // Add listener to catch the extremely rare case of a late deployment or upgrade
38              bundleContext.addServiceListener(serviceEvent -> {
39                  switch (serviceEvent.getType()) {
40                      case ServiceEvent.MODIFIED:
41                          // falling through intentionally
42                      case ServiceEvent.REGISTERED:
43                          bridgeListener = (OsgiBundleApplicationContextListener) bundleContext.getService(serviceEvent.getServiceReference());
44                          break;
45                      case ServiceEvent.UNREGISTERING:
46                          bridgeListener = null;
47                          break;
48                  }
49              }, filter);
50          } catch (InvalidSyntaxException e) {
51              // Should never happen
52              throw new RuntimeException("Invalid LDAP filter", e);
53          }
54      }
55  
56      @Override
57      public void multicastEvent(OsgiBundleApplicationContextEvent applicationEvent) {
58          super.multicastEvent(applicationEvent);
59          if (bridgeListener != null)
60              bridgeListener.onOsgiApplicationEvent(applicationEvent);
61      }
62  }