KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > plugins > PluginDescriptor


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.core.internal.plugins;
13
14 import java.io.IOException JavaDoc;
15 import java.lang.reflect.Constructor JavaDoc;
16 import java.net.URL JavaDoc;
17 import java.util.*;
18 import org.eclipse.core.internal.boot.PlatformURLHandler;
19 import org.eclipse.core.internal.runtime.*;
20 import org.eclipse.core.internal.runtime.InternalPlatform;
21 import org.eclipse.core.runtime.*;
22 import org.eclipse.osgi.service.resolver.BundleDescription;
23 import org.eclipse.osgi.service.resolver.BundleSpecification;
24 import org.eclipse.osgi.util.ManifestElement;
25 import org.eclipse.osgi.util.NLS;
26 import org.osgi.framework.*;
27
28
29 /**
30  * @deprecated Marking as deprecated to remove the warnings
31  */

32 public class PluginDescriptor implements IPluginDescriptor {
33
34     private static final String JavaDoc PLUGIN_CLASS = "Plugin-Class"; //$NON-NLS-1$
35
protected Plugin pluginObject = null; // plugin object
36
private Bundle bundleOsgi;
37
38     //The three following fields can't be replaced by a test to the bundle state.
39
private boolean active = false; // plugin is active
40
private volatile boolean activePending = false; // being activated
41
private boolean deactivated = false; // plugin deactivated due to startup errors
42
private ResourceBundle resources = null;
43     private PluginClassLoader classLoader;
44
45     // constants
46
static final String JavaDoc PLUGIN_URL = PlatformURLHandler.PROTOCOL + PlatformURLHandler.PROTOCOL_SEPARATOR + "/" + PlatformURLPluginConnection.PLUGIN + "/"; //$NON-NLS-1$ //$NON-NLS-2$
47
static final String JavaDoc VERSION_SEPARATOR = "_"; //$NON-NLS-1$
48

49     synchronized public void doPluginDeactivation() {
50         pluginObject = null;
51         active = false;
52         activePending = false;
53         deactivated = false;
54     }
55
56     /**
57      * @see IPluginDescriptor
58      */

59     public IExtension getExtension(String JavaDoc id) {
60         IExtension[] exts = getExtensions();
61         for (int i = 0; i < exts.length; i++) {
62             if (exts[i].getSimpleIdentifier().equals(id))
63                 return exts[i];
64         }
65         return null;
66     }
67
68     /**
69      * @see IPluginDescriptor
70      */

71     public IExtensionPoint getExtensionPoint(String JavaDoc extensionPointId) {
72         return InternalPlatform.getDefault().getRegistry().getExtensionPoint(getId(), extensionPointId);
73     }
74
75     /**
76      * @see IPluginDescriptor
77      */

78     public IExtensionPoint[] getExtensionPoints() {
79         return InternalPlatform.getDefault().getRegistry().getExtensionPoints(getId());
80     }
81
82     /**
83      * @see IPluginDescriptor
84      */

85     public IExtension[] getExtensions() {
86         return org.eclipse.core.internal.runtime.InternalPlatform.getDefault().getRegistry().getExtensions(getId());
87     }
88
89     /**
90      * @see IPluginDescriptor
91      */

92     public URL JavaDoc getInstallURL() {
93         try {
94             return new URL JavaDoc(PLUGIN_URL + toString() + '/');
95         } catch (IOException JavaDoc e) {
96             throw new IllegalStateException JavaDoc(); // unchecked
97
}
98     }
99
100     /**
101      * @see IPluginDescriptor
102      */

103     public String JavaDoc getLabel() {
104         return (String JavaDoc) bundleOsgi.getHeaders().get(Constants.BUNDLE_NAME);
105     }
106
107     /**
108      * @see IPluginDescriptor
109      */

110     public ClassLoader JavaDoc getPluginClassLoader() {
111         synchronized (this) {
112             if (classLoader == null)
113                 classLoader = new PluginClassLoader(this);
114         }
115         return classLoader;
116     }
117
118     public PluginRegistry getPluginRegistry() {
119         return (PluginRegistry) org.eclipse.core.internal.plugins.InternalPlatform.getPluginRegistry();
120     }
121
122     /**
123      * @see IPluginDescriptor
124      */

125     public String JavaDoc getProviderName() {
126         return (String JavaDoc) bundleOsgi.getHeaders().get(Constants.BUNDLE_VENDOR);
127     }
128
129     /**
130      * @see IPluginDescriptor
131      */

132     public ResourceBundle getResourceBundle() throws MissingResourceException {
133         if (resources==null)
134             resources = ResourceTranslator.getResourceBundle(bundleOsgi);
135         return resources;
136     }
137
138     /**
139      * @see IPluginDescriptor
140      */

141     public String JavaDoc getResourceString(String JavaDoc value) {
142         return ResourceTranslator.getResourceString(bundleOsgi, value);
143     }
144
145     /**
146      * @see IPluginDescriptor
147      */

148     public String JavaDoc getResourceString(String JavaDoc value, ResourceBundle b) {
149         return ResourceTranslator.getResourceString(bundleOsgi, value, b);
150     }
151
152     /**
153      * @see IPluginDescriptor
154      */

155     public ILibrary[] getRuntimeLibraries() {
156         Bundle[] allBundles;
157         Bundle[] fragments = InternalPlatform.getDefault().getFragments(bundleOsgi);
158         if (fragments != null) {
159             allBundles = new Bundle[fragments.length + 1];
160             allBundles[0] = bundleOsgi;
161             System.arraycopy(fragments, 0, allBundles, 1, fragments.length);
162         } else
163             allBundles = new Bundle[] {bundleOsgi};
164         ArrayList allLibraries = new ArrayList();
165         // keep track of whether or not we have already added a "." to this classpath
166
boolean addedDot = false;
167         for (int i = 0; i < allBundles.length; i++)
168             try {
169                 ManifestElement[] classpathElements = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, (String JavaDoc) allBundles[i].getHeaders("").get(Constants.BUNDLE_CLASSPATH)); //$NON-NLS-1$
170
// if there is no bundle classpath header, then we have to
171
// add "." to the classpath
172
if (classpathElements == null) {
173                     if (addedDot)
174                         continue;
175                     allLibraries.add(new Library(".")); //$NON-NLS-1$
176
addedDot = true;
177                 } else
178                     for (int j = 0; j < classpathElements.length; j++)
179                         allLibraries.add(new Library(classpathElements[j].getValue()));
180             } catch (BundleException e) {
181                 //Ignore because by the time we get here the errors will have already been logged.
182
}
183         return (ILibrary[]) allLibraries.toArray(new ILibrary[allLibraries.size()]);
184     }
185
186     /**
187      * @see IPluginDescriptor
188      */

189     public String JavaDoc getUniqueIdentifier() {
190         return getId();
191     }
192
193     /**
194      * @see #toString()
195      */

196     public static String JavaDoc getUniqueIdentifierFromString(String JavaDoc pluginString) {
197         int ix = pluginString.indexOf(VERSION_SEPARATOR);
198         return ix == -1 ? pluginString : pluginString.substring(0, ix);
199     }
200
201     /**
202      * @see IPluginDescriptor
203      */

204     public PluginVersionIdentifier getVersionIdentifier() {
205         String JavaDoc version = (String JavaDoc) bundleOsgi.getHeaders("").get(Constants.BUNDLE_VERSION); //$NON-NLS-1$
206
try {
207             return new PluginVersionIdentifier(version);
208         } catch (Exception JavaDoc e) {
209             return new PluginVersionIdentifier("1.0.0"); //$NON-NLS-1$
210
}
211     }
212
213     /**
214      * @see #toString()
215      */

216     public static PluginVersionIdentifier getVersionIdentifierFromString(String JavaDoc pluginString) {
217         return new PluginVersionIdentifier(pluginString);
218     }
219
220     public IPluginPrerequisite[] getPluginPrerequisites() {
221         BundleDescription description = Platform.getPlatformAdmin().getState(false).getBundle(bundleOsgi.getBundleId());
222         BundleSpecification[] specs = description.getRequiredBundles();
223
224         IPluginPrerequisite[] resolvedPrerequisites = new IPluginPrerequisite[specs.length];
225         for (int j = 0; j < specs.length; j++)
226             resolvedPrerequisites[j] = new PluginPrerequisite(specs[j]);
227         return resolvedPrerequisites;
228     }
229
230     /**
231      * Returns true if the plugin is active or is currently in the process of being
232      * activated, and false otherwse.
233      * NOTE: This method is not synchronized because it is called from within a
234      * sync block in PluginClassLoader.
235      */

236     boolean hasActivationStarted() {
237         return activePending || active;
238     }
239
240     /**
241      * @see IPluginDescriptor
242      */

243     public synchronized boolean isPluginActivated() {
244         //note that this method is synchronized for good reason.
245
//During plugin activation, neither true nor false would be valid
246
//return values for this method, so it must block until activation
247
//completes. For example, returning false during activation
248
//would break the registry shutdown procedure, because a
249
//plugin being activated during shutdown would never be shut down.
250
return bundleOsgi.getState() == Bundle.ACTIVE;
251     }
252
253     /*
254      * NOTE: This method is not synchronized because it is called from within a
255      * sync block in PluginClassLoader.
256      */

257     public boolean isPluginDeactivated() {
258         return deactivated;
259     }
260
261     private void logError(IStatus status) {
262         InternalPlatform.getDefault().getLog(org.eclipse.core.internal.runtime.InternalPlatform.getDefault().getBundleContext().getBundle()).log(status);
263     }
264
265     /**
266      * Returns <code>true</code> if we should continue with the plugin activation.
267      */

268     private boolean pluginActivationEnter() throws CoreException {
269         if (deactivated) {
270             // had permanent error on startup
271
String JavaDoc errorMsg = NLS.bind(Messages.plugin_pluginDisabled, getId());
272             throwException(errorMsg, null);
273         }
274         if (active || activePending) {
275             // already up and running
276
return false;
277         }
278         activePending = true;
279         // go ahead and try to activate
280
return true;
281     }
282
283     private void pluginActivationExit(boolean errorExit) {
284         if (errorExit) {
285             active = false;
286             deactivated = true;
287         } else
288             active = true;
289         // we are done with the activation
290
activePending = false;
291     }
292
293     private void throwException(String JavaDoc message, Throwable JavaDoc exception) throws CoreException {
294         IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, Platform.PLUGIN_ERROR, message, exception);
295         logError(status);
296         throw new CoreException(status);
297     }
298
299     /**
300      * @see #getUniqueIdentifierFromString(String)
301      * @see #getVersionIdentifierFromString(String)
302      */

303     public String JavaDoc toString() {
304         return getUniqueIdentifier() + VERSION_SEPARATOR + getVersionIdentifier().toString();
305     }
306
307     /**
308      * @see IPluginDescriptor
309      */

310     public final URL JavaDoc find(IPath path) {
311         URL JavaDoc result = FindSupport.find(bundleOsgi, path);
312         if (result != null)
313             try {
314                 result = Platform.resolve(result);
315             } catch (IOException JavaDoc e) {
316                 // if the URL cannot be resolved for some reason, return the original result.
317
}
318         return result;
319     }
320
321     /**
322      * @see IPluginDescriptor
323      */

324     public final URL JavaDoc find(IPath path, Map override) {
325         URL JavaDoc result = FindSupport.find(bundleOsgi, path, override);
326         if (result != null)
327             try {
328                 result = Platform.resolve(result);
329             } catch (IOException JavaDoc e) {
330                 // if the URL cannot be resolved for some reason, return the original result.
331
}
332         return result;
333     }
334
335     /**
336      * @see IPluginDescriptor
337      */

338     public Plugin getPlugin() throws CoreException {
339         if (pluginObject == null)
340             doPluginActivation();
341         return pluginObject;
342     }
343
344     synchronized void doPluginActivation() throws CoreException {
345         //This class is only called when getPlugin() is invoked.
346
// It needs to handle the case where it is called multiple times during the activation
347
// processing itself (as a result of other classes from this
348
// plugin being directly referenced by the plugin class)
349

350         // NOTE: there is a remote scenario where the plugin class can
351
// deadlock, if it starts separate thread(s) within its
352
// constructor or startup() method, and waits on those
353
// threads before returning (ie. calls join()).
354

355         // sanity checking
356
if ((bundleOsgi.getState() & (Bundle.RESOLVED | Bundle.STARTING | Bundle.ACTIVE)) == 0)
357             throw new IllegalArgumentException JavaDoc();
358         try {
359             // ensure the bundle has been activated
360
InternalPlatform.start(bundleOsgi);
361         } catch (BundleException e) {
362             throwException(NLS.bind(Messages.plugin_startupProblems, e), e);
363         }
364         if (pluginObject != null)
365             return;
366         boolean errorExit = true;
367         // check if already activated or pending
368
if (pluginActivationEnter()) {
369             try {
370                 internalDoPluginActivation();
371                 errorExit = false;
372             } finally {
373                 pluginActivationExit(errorExit);
374             }
375         } else {
376             //Create a fake plugin object for all new bundles that do not use the Plugin class in their activator hierarchy
377
if (active && pluginObject == null) {
378                 active = false;
379                 pluginObject = new DefaultPlugin(this);
380                 active = true;
381             }
382         }
383
384     }
385
386     private String JavaDoc getPluginClass() {
387         return (String JavaDoc) bundleOsgi.getHeaders("").get(PLUGIN_CLASS); //$NON-NLS-1$
388
}
389
390     private String JavaDoc getId() {
391         return bundleOsgi.getSymbolicName();
392     }
393
394     private void internalDoPluginActivation() throws CoreException {
395         String JavaDoc errorMsg;
396         // load the runtime class
397
String JavaDoc pluginClassName = getPluginClass();
398         Class JavaDoc runtimeClass = null;
399         try {
400             if (pluginClassName == null || pluginClassName.equals("")) {//$NON-NLS-1$
401
runtimeClass = DefaultPlugin.class;
402                 pluginClassName = DefaultPlugin.class.getName();
403             }
404             else
405                 runtimeClass = bundleOsgi.loadClass(pluginClassName);
406         } catch (ClassNotFoundException JavaDoc e) {
407             errorMsg = NLS.bind(Messages.plugin_loadClassError, getId(), pluginClassName);
408             throwException(errorMsg, e);
409         }
410
411         // find the correct constructor
412
Constructor JavaDoc construct = null;
413         try {
414             construct = runtimeClass.getConstructor(new Class JavaDoc[] {IPluginDescriptor.class});
415         } catch (NoSuchMethodException JavaDoc eNoConstructor) {
416             errorMsg = NLS.bind(Messages.plugin_instantiateClassError, getId(), pluginClassName);
417             throwException(errorMsg, eNoConstructor);
418         }
419
420         // create a new instance
421
try {
422             pluginObject = (Plugin) construct.newInstance(new Object JavaDoc[] {this});
423         } catch (ClassCastException JavaDoc e) {
424             errorMsg = NLS.bind(Messages.plugin_notPluginClass, pluginClassName);
425             throwException(errorMsg, e);
426         } catch (Exception JavaDoc e) {
427             errorMsg = NLS.bind(Messages.plugin_instantiateClassError, getId(), pluginClassName);
428             throwException(errorMsg, e);
429         }
430     }
431
432     public PluginDescriptor(org.osgi.framework.Bundle b) {
433         bundleOsgi = b;
434         if ((b.getState() & Bundle.ACTIVE) != 0)
435             active = true;
436     }
437
438     public Bundle getBundle() {
439         return bundleOsgi;
440     }
441
442     public void setPlugin(Plugin object) {
443         pluginObject = object;
444     }
445
446     public synchronized void setActive() {
447         this.active = true;
448     }
449     
450     public boolean hasPluginObject() {
451         return pluginObject!=null;
452     }
453
454     public void markAsDeactivated() {
455         deactivated = true;
456     }
457 }
458
Popular Tags