View Javadoc

1   package com.atlassian.plugin.osgi.bridge.external;
2   
3   import org.springframework.beans.factory.FactoryBean;
4   import org.springframework.osgi.context.BundleContextAware;
5   import org.osgi.framework.BundleContext;
6   import org.osgi.framework.ServiceReference;
7   import org.osgi.framework.InvalidSyntaxException;
8   import com.atlassian.plugin.PluginException;
9   
10  import java.util.ArrayList;
11  import java.util.Arrays;
12  
13  /**
14   * Simple factory bean to resolve host components.  Since we know host components won't change during the bundle's
15   * lifetime, we can use a direct reference instead of the fancy proxy stuff from Spring DM.
16   *
17   * @since 2.2.0
18   */
19  public class HostComponentFactoryBean implements FactoryBean, BundleContextAware
20  {
21      private BundleContext bundleContext;
22      private String filter;
23      private Object service;
24  
25      public Object getObject() throws Exception
26      {
27          return findService();
28      }
29  
30      public Class getObjectType()
31      {
32          return (findService() != null ? findService().getClass() : null);
33      }
34  
35      public boolean isSingleton()
36      {
37          return true;
38      }
39  
40      public void setBundleContext(BundleContext bundleContext)
41      {
42          this.bundleContext = bundleContext;
43      }
44  
45      /**
46       * Sets the OSGi service filter.
47       *
48       * @param filter OSGi filter describing the importing OSGi service
49       */
50      public void setFilter(String filter)
51      {
52          this.filter = filter;
53      }
54  
55      /**
56       * Finds a service, if the bundle context is available.
57       *
58       * @return The service, null if not found or the bundle context isn't available yet
59       * @throws com.atlassian.plugin.PluginException
60       *          If either 0 or more than 1 service reference is found
61       */
62      private Object findService() throws PluginException
63      {
64          if (service == null && bundleContext != null)
65          {
66              try
67              {
68                  ServiceReference[] references = bundleContext.getServiceReferences(null, filter);
69                  if (references == null || references.length == 0)
70                  {
71                      throw new PluginException("No service reference for '" + filter + "'");
72                  }
73                  if (references.length > 1)
74                  {
75                      throw new PluginException("Too many service references found for '" + filter + "': " + Arrays.asList(references));
76                  }
77                  service = bundleContext.getService(references[0]);
78              }
79              catch (InvalidSyntaxException e)
80              {
81                  throw new PluginException("Invalid filter syntax '" + filter + "'");
82              }
83          }
84          return service;
85      }
86  }