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
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 }