KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > osgi > baseadaptor > BaseAdaptor


1 /*******************************************************************************
2  * Copyright (c) 2005, 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.osgi.baseadaptor;
13
14 import java.io.*;
15 import java.net.URL JavaDoc;
16 import java.net.URLConnection JavaDoc;
17 import java.util.Properties JavaDoc;
18 import org.eclipse.core.runtime.adaptor.LocationManager;
19 import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
20 import org.eclipse.osgi.baseadaptor.hooks.*;
21 import org.eclipse.osgi.framework.adaptor.*;
22 import org.eclipse.osgi.framework.debug.Debug;
23 import org.eclipse.osgi.framework.internal.core.*;
24 import org.eclipse.osgi.framework.internal.core.Constants;
25 import org.eclipse.osgi.framework.log.FrameworkLog;
26 import org.eclipse.osgi.framework.log.FrameworkLogEntry;
27 import org.eclipse.osgi.internal.baseadaptor.*;
28 import org.eclipse.osgi.service.resolver.PlatformAdmin;
29 import org.eclipse.osgi.service.resolver.State;
30 import org.eclipse.osgi.util.NLS;
31 import org.osgi.framework.*;
32
33 /**
34  * A Framework adaptor implementation that allows additional functionality to be
35  * hooked in. Hooks are configured using {@link HookConfigurator}
36  * objects. A framework extension may add hook configurators which can be used
37  * to add hooks to the {@link HookRegistry}.
38  * @see HookConfigurator
39  * @see HookRegistry
40  * @see AdaptorHook
41  * @since 3.2
42  */

43 public class BaseAdaptor implements FrameworkAdaptor{
44     // System property used to set the parent classloader type (boot is the default)
45
private static final String JavaDoc PROP_PARENT_CLASSLOADER = "osgi.parentClassloader"; //$NON-NLS-1$
46
// A parent classloader type that specifies the application classloader
47
private static final String JavaDoc PARENT_CLASSLOADER_APP = "app"; //$NON-NLS-1$
48
// A parent classloader type that specifies the extension classlaoder
49
private static final String JavaDoc PARENT_CLASSLOADER_EXT = "ext"; //$NON-NLS-1$
50
// A parent classloader type that specifies the boot classlaoder
51
private static final String JavaDoc PARENT_CLASSLOADER_BOOT = "boot"; //$NON-NLS-1$
52
// A parent classloader type that specifies the framework classlaoder
53
private static final String JavaDoc PARENT_CLASSLOADER_FWK = "fwk"; //$NON-NLS-1$
54
// The BundleClassLoader parent to use when creating BundleClassLoaders.
55
private static ClassLoader JavaDoc bundleClassLoaderParent;
56     static {
57         // check property for specified parent
58
String JavaDoc type = FrameworkProperties.getProperty(BaseAdaptor.PROP_PARENT_CLASSLOADER, BaseAdaptor.PARENT_CLASSLOADER_BOOT);
59         if (BaseAdaptor.PARENT_CLASSLOADER_FWK.equalsIgnoreCase(type))
60             bundleClassLoaderParent = FrameworkAdaptor.class.getClassLoader();
61         else if (BaseAdaptor.PARENT_CLASSLOADER_APP.equalsIgnoreCase(type))
62             bundleClassLoaderParent = ClassLoader.getSystemClassLoader();
63         else if (BaseAdaptor.PARENT_CLASSLOADER_EXT.equalsIgnoreCase(type)) {
64             ClassLoader JavaDoc appCL = ClassLoader.getSystemClassLoader();
65             if (appCL != null)
66                 bundleClassLoaderParent = appCL.getParent();
67         }
68         // default to boot classloader
69
if (bundleClassLoaderParent == null)
70             bundleClassLoaderParent = new ParentClassLoader();
71     }
72
73     // Empty parent classloader. This is used by default as the BundleClassLoader parent.
74
private static class ParentClassLoader extends ClassLoader JavaDoc {
75         protected ParentClassLoader() {
76             super(null);
77         }
78     }
79
80     private EventPublisher eventPublisher;
81     private ServiceRegistry serviceRegistry;
82     private boolean stopping;
83     private HookRegistry hookRegistry;
84     private FrameworkLog log;
85     private BundleContext context;
86     private BaseStorage storage;
87     private BundleWatcher bundleWatcher;
88
89     /**
90      * Constructs a BaseAdaptor.
91      * @param args arguments passed to the adaptor by the framework.
92      */

93     public BaseAdaptor(String JavaDoc[] args) {
94         if (LocationManager.getConfigurationLocation() == null)
95             LocationManager.initializeLocations();
96         hookRegistry = new HookRegistry(this);
97         FrameworkLogEntry[] errors = hookRegistry.initialize();
98         if (errors.length > 0)
99             for (int i = 0; i < errors.length; i++)
100                 getFrameworkLog().log(errors[i]);
101         // get the storage after the registry has been initialized
102
storage = getStorage();
103         // TODO consider passing args to BaseAdaptorHooks
104
}
105
106     /**
107      * This method will call all configured adaptor hooks {@link AdaptorHook#initialize(BaseAdaptor)} method.
108      * @see FrameworkAdaptor#initialize(EventPublisher)
109      */

110     public void initialize(EventPublisher publisher) {
111         this.eventPublisher = publisher;
112         serviceRegistry = new ServiceRegistryImpl();
113         ((ServiceRegistryImpl) serviceRegistry).initialize();
114         // set the adaptor for the adaptor hooks
115
AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
116         for (int i = 0; i < adaptorHooks.length; i++)
117             adaptorHooks[i].initialize(this);
118     }
119
120     /**
121      * @see FrameworkAdaptor#initializeStorage()
122      */

123     public void initializeStorage() throws IOException {
124         storage.initialize(this);
125     }
126
127     /**
128      * @see FrameworkAdaptor#compactStorage()
129      */

130     public void compactStorage() throws IOException {
131         storage.compact();
132     }
133
134     /**
135      * This method will call all the configured adaptor hook {@link AdaptorHook#addProperties(Properties)} methods.
136      * @see FrameworkAdaptor#getProperties()
137      */

138     public Properties JavaDoc getProperties() {
139         Properties JavaDoc props = new Properties JavaDoc();
140         String JavaDoc resource = FrameworkProperties.getProperty(Constants.OSGI_PROPERTIES, Constants.DEFAULT_OSGI_PROPERTIES);
141         try {
142             InputStream in = null;
143             File file = new File(resource);
144             if (file.exists())
145                 in = new FileInputStream(file);
146             if (in == null)
147                 in = getClass().getResourceAsStream(resource);
148             if (in != null) {
149                 try {
150                     props.load(new BufferedInputStream(in));
151                 } finally {
152                     try {
153                         in.close();
154                     } catch (IOException ee) {
155                         // nothing to do
156
}
157                 }
158             } else {
159                 if (Debug.DEBUG && Debug.DEBUG_GENERAL)
160                     Debug.println("Skipping osgi.properties: " + resource); //$NON-NLS-1$
161
}
162         } catch (IOException e) {
163             if (Debug.DEBUG && Debug.DEBUG_GENERAL)
164                 Debug.println("Unable to load osgi.properties: " + e.getMessage()); //$NON-NLS-1$
165
}
166         // add the storage properties
167
storage.addProperties(props);
168         // add the properties from each adaptor hook
169
AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
170         for (int i = 0; i < adaptorHooks.length; i++)
171             adaptorHooks[i].addProperties(props);
172         return props;
173     }
174
175     /**
176      * @see FrameworkAdaptor#getInstalledBundles()
177      */

178     public BundleData[] getInstalledBundles() {
179         return storage.getInstalledBundles();
180     }
181
182     /**
183      * This method will call each configured adaptor hook {@link AdaptorHook#mapLocationToURLConnection(String)} method
184      * until one returns a non-null value. If none of the adaptor hooks return a non-null value then the
185      * string is used to construct a new URL object to open a new url connection.
186      *
187      * @see FrameworkAdaptor#mapLocationToURLConnection(String)
188      */

189     public URLConnection JavaDoc mapLocationToURLConnection(String JavaDoc location) throws BundleException {
190         try {
191             URLConnection JavaDoc result = null;
192             // try the adaptor hooks first;
193
AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
194             for (int i = 0; i < adaptorHooks.length; i++) {
195                 result = adaptorHooks[i].mapLocationToURLConnection(location);
196                 if (result != null)
197                     return result;
198             }
199             // just do the default
200
return (new URL JavaDoc(location).openConnection());
201         } catch (IOException e) {
202             throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_URL_CREATE_EXCEPTION, location), e);
203         }
204     }
205
206     /**
207      * @see FrameworkAdaptor#installBundle(String, URLConnection)
208      */

209     public BundleOperation installBundle(String JavaDoc location, URLConnection JavaDoc source) {
210         return storage.installBundle(location, source);
211     }
212
213     /**
214      * @see FrameworkAdaptor#updateBundle(BundleData, URLConnection)
215      */

216     public BundleOperation updateBundle(BundleData bundledata, URLConnection JavaDoc source) {
217         return storage.updateBundle((BaseData) bundledata, source);
218     }
219
220     /**
221      * @see FrameworkAdaptor#uninstallBundle(BundleData)
222      */

223     public BundleOperation uninstallBundle(BundleData bundledata) {
224         return storage.uninstallBundle((BaseData) bundledata);
225     }
226
227     /**
228      * @see FrameworkAdaptor#getTotalFreeSpace()
229      */

230     public long getTotalFreeSpace() throws IOException {
231         return storage.getFreeSpace();
232     }
233
234     /**
235      * @see FrameworkAdaptor#getPermissionStorage()
236      */

237     public PermissionStorage getPermissionStorage() throws IOException {
238         return storage.getPermissionStorage();
239     }
240
241     /**
242      * @see FrameworkAdaptor#getServiceRegistry()
243      */

244     public ServiceRegistry getServiceRegistry() {
245         return serviceRegistry;
246     }
247
248     /**
249      * This method calls all the configured adaptor hook {@link AdaptorHook#frameworkStart(BundleContext)} methods.
250      * @see FrameworkAdaptor#frameworkStart(BundleContext)
251      */

252     public void frameworkStart(BundleContext fwContext) throws BundleException {
253         this.context = fwContext;
254         stopping = false;
255         BundleResourceHandler.setContext(fwContext);
256         // always start the storage first
257
storage.frameworkStart(fwContext);
258         AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
259         for (int i = 0; i < adaptorHooks.length; i++)
260             adaptorHooks[i].frameworkStart(fwContext);
261     }
262
263     /**
264      * This method calls all the configured adaptor hook {@link AdaptorHook#frameworkStop(BundleContext)} methods.
265      * @see FrameworkAdaptor#frameworkStop(BundleContext)
266      */

267     public void frameworkStop(BundleContext fwContext) throws BundleException {
268         // first inform all configured adaptor hooks
269
AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
270         for (int i = 0; i < adaptorHooks.length; i++)
271             adaptorHooks[i].frameworkStop(fwContext);
272         // stop the storage last
273
storage.frameworkStop(fwContext);
274         fwContext = null;
275     }
276
277     /**
278      * This method calls all the configured adaptor hook {@link AdaptorHook#frameworkStopping(BundleContext)} methods.
279      * @see FrameworkAdaptor#frameworkStopping(BundleContext)
280      */

281     public void frameworkStopping(BundleContext fwContext) {
282         stopping = true;
283         // always tell storage of stopping first
284
storage.frameworkStopping(fwContext);
285         // inform all configured adaptor hooks last
286
AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
287         for (int i = 0; i < adaptorHooks.length; i++)
288             adaptorHooks[i].frameworkStopping(fwContext);
289     }
290
291     /**
292      * @see FrameworkAdaptor#getInitialBundleStartLevel()
293      */

294     public int getInitialBundleStartLevel() {
295         return storage.getInitialBundleStartLevel();
296     }
297
298     /**
299      * @see FrameworkAdaptor#setInitialBundleStartLevel(int)
300      */

301     public void setInitialBundleStartLevel(int value) {
302         storage.setInitialBundleStartLevel(value);
303     }
304
305     /**
306      * This method calls all configured adaptor hook {@link AdaptorHook#createFrameworkLog()} methods
307      * until the first one returns a non-null value. If none of the adaptor hooks return a non-null
308      * value then a framework log implementation which does nothing is returned.
309      * @see FrameworkAdaptor#getFrameworkLog()
310      */

311     public FrameworkLog getFrameworkLog() {
312         if (log != null)
313             return log;
314         AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
315         for (int i = 0; i < adaptorHooks.length; i++) {
316             log = adaptorHooks[i].createFrameworkLog();
317             if (log != null)
318                 return log;
319         }
320         log = new FrameworkLog() {
321             public void log(FrameworkEvent frameworkEvent) {
322                 log(new FrameworkLogEntry(frameworkEvent.getBundle().getSymbolicName() == null ? frameworkEvent.getBundle().getLocation() : frameworkEvent.getBundle().getSymbolicName(), FrameworkLogEntry.ERROR, 0, "FrameworkEvent.ERROR", 0, frameworkEvent.getThrowable(), null)); //$NON-NLS-1$
323
}
324
325             public void log(FrameworkLogEntry logEntry) {
326                 System.err.print(logEntry.getEntry() + " "); //$NON-NLS-1$
327
System.err.println(logEntry.getMessage());
328                 if (logEntry.getThrowable() != null)
329                     logEntry.getThrowable().printStackTrace(System.err);
330             }
331
332             public void setWriter(Writer newWriter, boolean append) {
333                 // do nothing
334
}
335
336             public void setFile(File newFile, boolean append) throws IOException {
337                 // do nothing
338
}
339
340             public File getFile() {
341                 // do nothing
342
return null;
343             }
344
345             public void setConsoleLog(boolean consoleLog) {
346                 // do nothing
347
}
348
349             public void close() {
350                 // do nothing
351
}
352         };
353         return log;
354     }
355
356     /**
357      * @see FrameworkAdaptor#createSystemBundleData()
358      */

359     public BundleData createSystemBundleData() throws BundleException {
360         return new SystemBundleData(this);
361     }
362
363     /**
364      * @see FrameworkAdaptor#getBundleWatcher()
365      */

366     public BundleWatcher getBundleWatcher() {
367         if (bundleWatcher != null)
368             return bundleWatcher;
369         final BundleWatcher[] watchers = hookRegistry.getWatchers();
370         if (watchers.length == 0)
371             return null;
372         bundleWatcher = new BundleWatcher() {
373             public void watchBundle(Bundle bundle, int type) {
374                 for (int i = 0; i < watchers.length; i++)
375                     watchers[i].watchBundle(bundle, type);
376             }
377         };
378         return bundleWatcher;
379     }
380
381     /**
382      * @see FrameworkAdaptor#getPlatformAdmin()
383      */

384     public PlatformAdmin getPlatformAdmin() {
385         return storage.getStateManager();
386     }
387
388     /**
389      * @see FrameworkAdaptor#getState()
390      */

391     public State getState() {
392         return storage.getStateManager().getSystemState();
393     }
394
395     /**
396      * This method calls all the configured classloading hooks {@link ClassLoadingHook#getBundleClassLoaderParent()} methods
397      * until one returns a non-null value.
398      * @see FrameworkAdaptor#getBundleClassLoaderParent()
399      */

400     public ClassLoader JavaDoc getBundleClassLoaderParent() {
401         // ask the configured adaptor hooks first
402
ClassLoader JavaDoc result = null;
403         ClassLoadingHook[] cpManagerHooks = getHookRegistry().getClassLoadingHooks();
404         for (int i = 0; i < cpManagerHooks.length; i++) {
405             result = cpManagerHooks[i].getBundleClassLoaderParent();
406             if (result != null)
407                 return result;
408         }
409         // none of the configured adaptor hooks gave use a parent loader; use the default
410
return bundleClassLoaderParent;
411     }
412
413     /**
414      * This method calls all the configured adaptor hooks {@link AdaptorHook#handleRuntimeError(Throwable)} methods.
415      * @see FrameworkAdaptor#handleRuntimeError(Throwable)
416      */

417     public void handleRuntimeError(Throwable JavaDoc error) {
418         AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
419         for (int i = 0; i < adaptorHooks.length; i++)
420             adaptorHooks[i].handleRuntimeError(error);
421     }
422
423     /**
424      * This method calls all the configured adaptor hooks {@link AdaptorHook#matchDNChain(String, String[])} methods
425      * until one returns a true value.
426      * @see FrameworkAdaptor#matchDNChain(String, String[])
427      */

428     public boolean matchDNChain(String JavaDoc pattern, String JavaDoc[] dnChain) {
429         AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
430         for (int i = 0; i < adaptorHooks.length; i++)
431             if (adaptorHooks[i].matchDNChain(pattern, dnChain))
432                 return true;
433         return false;
434     }
435
436     /**
437      * Returns true if the {@link #frameworkStopping(BundleContext)} method has been called
438      * @return true if the framework is stopping
439      */

440     public boolean isStopping() {
441         return stopping;
442     }
443
444     /**
445      * Returns the event publisher for this BaseAdaptor
446      * @return the event publisher for this BaseAdaptor
447      */

448     public EventPublisher getEventPublisher() {
449         return eventPublisher;
450     }
451
452     /**
453      * Returns the <code>HookRegistry</code> object for this adaptor.
454      * @return the <code>HookRegistry</code> object for this adaptor.
455      */

456     public HookRegistry getHookRegistry() {
457         return hookRegistry;
458     }
459
460     /**
461      * Returns the system bundle's context
462      * @return the system bundle's context
463      */

464     public BundleContext getContext() {
465         return context;
466     }
467
468     /**
469      * Creates a bundle file object for the given content and base data.
470      * This method must delegate to each configured bundle file factory
471      * {@link BundleFileFactoryHook#createBundleFile(Object, BaseData, boolean)} method until one
472      * factory returns a non-null value. If no bundle file factory returns a non-null value
473      * then the the default behavior will be performed.
474      * <p>
475      * If the specified content is <code>null</code> then the base content of the specified
476      * bundledata must be found before calling any bundle file factories.
477      * </p>
478      * <p>
479      * After the bundle file has been created each configured bundle file wrapper factory
480      * {@link BundleFileWrapperFactoryHook#wrapBundleFile(BundleFile, Object, BaseData, boolean)}
481      * method is called to wrap the bundle file.
482      * </p>
483      * @param content The object which contains the content of a bundle file. A value of
484      * <code>null</code> indicates that the storage must find the base content for the
485      * specified BaseData.
486      * @param data The BaseData associated with the content
487      * @return a BundleFile object.
488      * @throws IOException if an error occured while creating the BundleFile
489      */

490     public BundleFile createBundleFile(Object JavaDoc content, BaseData data) throws IOException {
491         return storage.createBundleFile(content, data);
492     }
493
494     /**
495      * Returns true if the persistent storage is read-only
496      * @return true if the persistent storage is read-only
497      */

498     public boolean isReadOnly() {
499         return storage.isReadOnly();
500     }
501
502     /*
503      * This is an experimental method to allow adaptors to replace the storage implementation by
504      * extending BaseAdaptor and overriding this method. This method is experimental.
505      * @return a base storage object.
506      */

507     protected BaseStorage getStorage() {
508         if (storage != null)
509             return storage;
510         // this bit of code assumes the registry is initialized with a BaseStorageHook
511
// we want to make sure we are using the same BaseStorage instance as the BaseStorageHook
512
StorageHook[] hooks = hookRegistry.getStorageHooks();
513         for (int i = 0; i < hooks.length && storage == null; i++)
514             if (hooks[i] instanceof BaseStorageHook)
515                 storage = ((BaseStorageHook)hooks[i]).getStorage();
516         return storage;
517     }
518 }
519
Popular Tags