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