View Javadoc

1   package com.atlassian.plugin.osgi.factory;
2   
3   import com.atlassian.plugin.PluginArtifact;
4   import com.atlassian.plugin.PluginArtifactBackedPlugin;
5   import com.atlassian.plugin.PluginException;
6   import com.atlassian.plugin.PluginInformation;
7   import com.atlassian.plugin.PluginState;
8   import com.atlassian.plugin.event.PluginEventManager;
9   import com.atlassian.plugin.impl.AbstractPlugin;
10  import com.atlassian.plugin.osgi.util.BundleClassLoaderAccessor;
11  import com.atlassian.plugin.util.resource.AlternativeDirectoryResourceLoader;
12  import org.apache.commons.lang.Validate;
13  import org.osgi.framework.Bundle;
14  import org.osgi.framework.BundleEvent;
15  import org.osgi.framework.BundleException;
16  import org.osgi.framework.Constants;
17  import org.osgi.framework.SynchronousBundleListener;
18  
19  import java.io.InputStream;
20  import java.net.URL;
21  import java.util.Date;
22  
23  /**
24   * Plugin that wraps an OSGi bundle that has no plugin descriptor.
25   */
26  public class OsgiBundlePlugin extends AbstractPlugin implements PluginArtifactBackedPlugin
27  {
28  
29      private final Bundle bundle;
30      private final Date dateLoaded;
31      private final ClassLoader bundleClassLoader;
32      private final SynchronousBundleListener bundleStopListener;
33      private final PluginArtifact pluginArtifact;
34  
35      public OsgiBundlePlugin(final Bundle bundle, final String key, final PluginArtifact pluginArtifact, final PluginEventManager pluginEventManager)
36      {
37          this.pluginArtifact = pluginArtifact;
38          bundleClassLoader = BundleClassLoaderAccessor.getClassLoader(bundle, new AlternativeDirectoryResourceLoader());
39          Validate.notNull(bundle);
40          this.bundle = bundle;
41          // TODO: this should be done at a higher level than this to support start and stop
42          bundleStopListener = new SynchronousBundleListener()
43          {
44              public void bundleChanged(final BundleEvent bundleEvent)
45              {
46                  if (bundleEvent.getBundle() == bundle)
47                  {
48                      if (bundleEvent.getType() == BundleEvent.STOPPING)
49                      {
50                          setPluginState(PluginState.DISABLED);
51                      }
52                  }
53              }
54          };
55          PluginInformation pluginInformation = new PluginInformation();
56          pluginInformation.setDescription((String) bundle.getHeaders().get(Constants.BUNDLE_DESCRIPTION));
57          pluginInformation.setVersion((String) bundle.getHeaders().get(Constants.BUNDLE_VERSION));
58          pluginInformation.setVendorName((String) bundle.getHeaders().get(Constants.BUNDLE_VENDOR));
59          
60          dateLoaded = new Date();
61          setPluginsVersion(2);
62          setName((String) bundle.getHeaders().get(Constants.BUNDLE_NAME));
63          setKey(key);
64          setPluginInformation(pluginInformation);
65          setSystemPlugin(false);
66      }
67  
68  
69      @Override
70      public Date getDateLoaded()
71      {
72          return dateLoaded;
73      }
74  
75      public boolean isUninstallable()
76      {
77          return true;
78      }
79  
80      public boolean isDeleteable()
81      {
82          return true;
83      }
84  
85      public boolean isDynamicallyLoaded()
86      {
87          return true;
88      }
89  
90      public <T> Class<T> loadClass(final String clazz, final Class<?> callingClass) throws ClassNotFoundException
91      {
92          return BundleClassLoaderAccessor.loadClass(bundle, clazz);
93      }
94  
95      public URL getResource(final String name)
96      {
97          return bundleClassLoader.getResource(name);
98      }
99  
100     public InputStream getResourceAsStream(final String name)
101     {
102         return bundleClassLoader.getResourceAsStream(name);
103     }
104 
105     @Override
106     protected void uninstallInternal()
107     {
108         try
109         {
110             if (bundle.getState() != Bundle.UNINSTALLED)
111             {
112                 bundle.uninstall();
113             }
114         }
115         catch (final BundleException e)
116         {
117             throw new PluginException(e);
118         }
119     }
120 
121     @Override
122     protected PluginState enableInternal()
123     {
124         try
125         {
126             bundle.start();
127             bundle.getBundleContext().addBundleListener(bundleStopListener);
128             return PluginState.ENABLED;
129         }
130         catch (final BundleException e)
131         {
132             throw new PluginException(e);
133         }
134     }
135 
136     @Override
137     protected void disableInternal()
138     {
139         try
140         {
141             if (bundle.getState() == Bundle.ACTIVE)
142             {
143                 bundle.stop();
144             }
145         }
146         catch (final BundleException e)
147         {
148             throw new PluginException(e);
149         }
150     }
151 
152     public ClassLoader getClassLoader()
153     {
154         return bundleClassLoader;
155     }
156 
157     public PluginArtifact getPluginArtifact()
158     {
159         return pluginArtifact;
160     }
161 }