View Javadoc

1   package com.atlassian.plugin.osgi.factory;
2   
3   import com.atlassian.plugin.Permissions;
4   import com.atlassian.plugin.PluginArtifact;
5   import com.atlassian.plugin.PluginArtifactBackedPlugin;
6   import com.atlassian.plugin.PluginException;
7   import com.atlassian.plugin.PluginInformation;
8   import com.atlassian.plugin.PluginPermission;
9   import com.atlassian.plugin.PluginState;
10  import com.atlassian.plugin.impl.AbstractPlugin;
11  import com.atlassian.plugin.osgi.util.BundleClassLoaderAccessor;
12  import com.atlassian.plugin.osgi.util.OsgiSystemBundleUtil;
13  import com.atlassian.plugin.util.resource.AlternativeDirectoryResourceLoader;
14  import com.google.common.collect.ImmutableSet;
15  import org.osgi.framework.Bundle;
16  import org.osgi.framework.BundleEvent;
17  import org.osgi.framework.BundleException;
18  import org.osgi.framework.Constants;
19  import org.osgi.framework.SynchronousBundleListener;
20  
21  import java.io.InputStream;
22  import java.net.URL;
23  import java.util.Date;
24  
25  import static com.google.common.base.Preconditions.checkNotNull;
26  
27  /**
28   * Plugin that wraps an OSGi bundle that has no plugin descriptor.
29   */
30  public final class OsgiBundlePlugin extends AbstractPlugin implements PluginArtifactBackedPlugin
31  {
32  
33      private final Bundle bundle;
34      private final Date dateLoaded;
35      private final ClassLoader bundleClassLoader;
36      private final SynchronousBundleListener bundleStartStopListener;
37      private final PluginArtifact pluginArtifact;
38  
39      public OsgiBundlePlugin(final Bundle bundle, final String key, final PluginArtifact pluginArtifact)
40      {
41          this.bundle = checkNotNull(bundle);
42          this.pluginArtifact = checkNotNull(pluginArtifact);
43          this.bundleClassLoader = BundleClassLoaderAccessor.getClassLoader(bundle, new AlternativeDirectoryResourceLoader());
44          bundleStartStopListener = new SynchronousBundleListener()
45          {
46              public void bundleChanged(final BundleEvent bundleEvent)
47              {
48                  if (bundleEvent.getBundle() == bundle)
49                  {
50                      if (bundleEvent.getType() == BundleEvent.STOPPING)
51                      {
52                          setPluginState(PluginState.DISABLED);
53                      }
54                      else if (bundleEvent.getType() == BundleEvent.STARTED)
55                      {
56                          setPluginState(PluginState.ENABLED);
57                      }
58                  }
59              }
60          };
61          PluginInformation pluginInformation = new PluginInformation();
62          pluginInformation.setDescription((String) bundle.getHeaders().get(Constants.BUNDLE_DESCRIPTION));
63          pluginInformation.setVersion((String) bundle.getHeaders().get(Constants.BUNDLE_VERSION));
64          pluginInformation.setVendorName((String) bundle.getHeaders().get(Constants.BUNDLE_VENDOR));
65          pluginInformation.setPermissions(ImmutableSet.of(PluginPermission.EXECUTE_JAVA));
66          
67          dateLoaded = new Date();
68          setPluginsVersion(2);
69          setName((String) bundle.getHeaders().get(Constants.BUNDLE_NAME));
70          setKey(key);
71          setPluginInformation(pluginInformation);
72          setSystemPlugin(false);
73      }
74  
75  
76      @Override
77      public Date getDateLoaded()
78      {
79          return dateLoaded;
80      }
81  
82      public boolean isUninstallable()
83      {
84          return true;
85      }
86  
87      public boolean isDeleteable()
88      {
89          return true;
90      }
91  
92      public boolean isDynamicallyLoaded()
93      {
94          return true;
95      }
96  
97      public <T> Class<T> loadClass(final String clazz, final Class<?> callingClass) throws ClassNotFoundException
98      {
99          return BundleClassLoaderAccessor.loadClass(bundle, clazz);
100     }
101 
102     public URL getResource(final String name)
103     {
104         return bundleClassLoader.getResource(name);
105     }
106 
107     public InputStream getResourceAsStream(final String name)
108     {
109         return bundleClassLoader.getResourceAsStream(name);
110     }
111 
112     @Override
113     protected void uninstallInternal()
114     {
115         try
116         {
117             if (bundle.getState() != Bundle.UNINSTALLED)
118             {
119                 bundle.uninstall();
120             }
121         }
122         catch (final BundleException e)
123         {
124             throw new PluginException(e);
125         }
126     }
127 
128     @Override
129     protected PluginState enableInternal()
130     {
131         getLog().debug("Enabling OSGi bundled plugin '{}'", getKey());
132         try
133         {
134             if (bundle.getHeaders().get(Constants.FRAGMENT_HOST) == null)
135             {
136                 getLog().debug("Plugin '{}' bundle is NOT a fragment, starting.", getKey());
137                 bundle.start();
138                 OsgiSystemBundleUtil.getSystemBundleContext(bundle).addBundleListener(bundleStartStopListener);
139             }
140             else
141             {
142                 getLog().debug("Plugin '{}' bundle is a fragment, not doing anything.", getKey());
143             }
144             return PluginState.ENABLED;
145         }
146         catch (final BundleException e)
147         {
148             throw new PluginException(e);
149         }
150     }
151 
152     @Override
153     protected void disableInternal()
154     {
155         try
156         {
157             if (bundle.getState() == Bundle.ACTIVE)
158             {
159                 OsgiSystemBundleUtil.getSystemBundleContext(bundle).removeBundleListener(bundleStartStopListener);
160                 bundle.stop();
161             }
162         }
163         catch (final BundleException e)
164         {
165             throw new PluginException(e);
166         }
167     }
168 
169     public ClassLoader getClassLoader()
170     {
171         return bundleClassLoader;
172     }
173 
174     public PluginArtifact getPluginArtifact()
175     {
176         return pluginArtifact;
177     }
178 }