KickJava   Java API By Example, From Geeks To Geeks.

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


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.File JavaDoc;
15 import java.io.IOException JavaDoc;
16 import java.net.MalformedURLException JavaDoc;
17 import java.net.URL JavaDoc;
18 import java.util.*;
19 import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
20 import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
21 import org.eclipse.osgi.baseadaptor.hooks.*;
22 import org.eclipse.osgi.baseadaptor.loader.BaseClassLoader;
23 import org.eclipse.osgi.framework.adaptor.*;
24 import org.eclipse.osgi.framework.debug.Debug;
25 import org.eclipse.osgi.framework.internal.core.Constants;
26 import org.eclipse.osgi.framework.internal.protocol.bundleentry.Handler;
27 import org.eclipse.osgi.framework.log.FrameworkLogEntry;
28 import org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader;
29 import org.eclipse.osgi.util.ManifestElement;
30 import org.osgi.framework.*;
31
32 /**
33  * The BundleData implementation used by the BaseAdaptor.
34  * @see BaseAdaptor
35  * @see BundleData
36  * @see StorageHook
37  * @see ClassLoadingHook
38  * @since 3.2
39  */

40 public class BaseData implements BundleData {
41     private long id;
42     private BaseAdaptor adaptor;
43     private Bundle bundle;
44     private int startLevel = -1;
45     private int status = 0;
46     private StorageHook[] storageHooks;
47     private String JavaDoc location;
48     private long lastModified;
49     protected BundleFile bundleFile;
50     private boolean dirty = false;
51     protected Dictionary manifest;
52     // This field is only used by PDE source lookup, and is set by a hook (bug 126517). It serves no purpose at runtime.
53
protected String JavaDoc fileName;
54     // This is only used to keep track of when the same native library is loaded more than once
55
protected Collection loadedNativeCode;
56
57     ///////////////////// Begin values from Manifest /////////////////////
58
private String JavaDoc symbolicName;
59     private Version version;
60     private String JavaDoc activator;
61     private String JavaDoc classpath;
62     private String JavaDoc executionEnvironment;
63     private String JavaDoc dynamicImports;
64     private int type;
65
66     ///////////////////// End values from Manifest /////////////////////
67

68     /**
69      * Constructs a new BaseData with the specified id for the specified adaptor
70      * @param id the id of the BaseData
71      * @param adaptor the adaptor of the BaseData
72      */

73     public BaseData(long id, BaseAdaptor adaptor) {
74         this.id = id;
75         this.adaptor = adaptor;
76     }
77
78     /**
79      * This method calls all the configured class loading hooks {@link ClassLoadingHook#createClassLoader(ClassLoader, ClassLoaderDelegate, BundleProtectionDomain, BaseData, String[])}
80      * methods until on returns a non-null value. If none of the class loading hooks returns a non-null value
81      * then the default classloader implementation is used.
82      * @see BundleData#createClassLoader(ClassLoaderDelegate, BundleProtectionDomain, String[])
83      */

84     public BundleClassLoader createClassLoader(ClassLoaderDelegate delegate, BundleProtectionDomain domain, String JavaDoc[] bundleclasspath) {
85         ClassLoadingHook[] hooks = adaptor.getHookRegistry().getClassLoadingHooks();
86         ClassLoader JavaDoc parent = adaptor.getBundleClassLoaderParent();
87         BaseClassLoader cl = null;
88         for (int i = 0; i < hooks.length && cl == null; i++)
89             cl = hooks[i].createClassLoader(parent, delegate, domain, this, bundleclasspath);
90         if (cl == null)
91             cl = new DefaultClassLoader(parent, delegate, domain, this, bundleclasspath);
92         return cl;
93     }
94
95     public final URL JavaDoc getEntry(String JavaDoc path) {
96         BundleEntry entry = getBundleFile().getEntry(path);
97         if (entry == null)
98             return null;
99         if (path.length() == 0 || path.charAt(0) != '/')
100             path = '/' + path;
101         try {
102             //use the constant string for the protocol to prevent duplication
103
return new URL JavaDoc(Constants.OSGI_ENTRY_URL_PROTOCOL, Long.toString(id), 0, path, new Handler(entry));
104         } catch (MalformedURLException JavaDoc e) {
105             return null;
106         }
107     }
108
109     public final Enumeration getEntryPaths(String JavaDoc path) {
110         return getBundleFile().getEntryPaths(path);
111     }
112
113     /**
114      * This method calls each configured classloading hook {@link ClassLoadingHook#findLibrary(BaseData, String)} method
115      * until the first one returns a non-null value.
116      * @see BundleData#findLibrary(String)
117      */

118     public String JavaDoc findLibrary(String JavaDoc libname) {
119         ClassLoadingHook[] hooks = adaptor.getHookRegistry().getClassLoadingHooks();
120         String JavaDoc result = null;
121         for (int i = 0; i < hooks.length; i++) {
122             result = hooks[i].findLibrary(this, libname);
123             if (result != null)
124                 break;
125         }
126         // check to see if this library has been loaded by another class loader
127
if (result != null)
128             synchronized (this) {
129                 if (loadedNativeCode == null)
130                     loadedNativeCode = new ArrayList(1);
131                 if (loadedNativeCode.contains(result)) {
132                     // we must copy the library to a temp space to allow another class loader to load the library
133
String JavaDoc temp = copyToTempLibrary(result);
134                     if (temp != null)
135                         result = temp;
136                 } else {
137                     loadedNativeCode.add(result);
138                 }
139             }
140         return result;
141     }
142
143     private String JavaDoc copyToTempLibrary(String JavaDoc result) {
144         try {
145             return adaptor.getStorage().copyToTempLibrary(this, result);
146         } catch (IOException JavaDoc e) {
147             adaptor.getFrameworkLog().log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, e.getMessage(), 0, e, null));
148         }
149         return null;
150     }
151
152     public void installNativeCode(String JavaDoc[] nativepaths) throws BundleException {
153         adaptor.getStorage().installNativeCode(this, nativepaths);
154     }
155
156     public File JavaDoc getDataFile(String JavaDoc path) {
157         return adaptor.getStorage().getDataFile(this, path);
158     }
159
160     public Dictionary getManifest() throws BundleException {
161         if (manifest == null)
162             manifest = adaptor.getStorage().loadManifest(this);
163         return manifest;
164     }
165
166     public long getBundleID() {
167         return id;
168     }
169
170     public final String JavaDoc getLocation() {
171         return location;
172     }
173
174     /**
175      * Sets the location of this bundledata
176      * @param location the location of this bundledata
177      */

178     public final void setLocation(String JavaDoc location) {
179         this.location = location;
180     }
181
182     public final long getLastModified() {
183         return lastModified;
184     }
185
186     /**
187      * Sets the last modified time stamp of this bundledata
188      * @param lastModified the last modified time stamp of this bundledata
189      */

190     public final void setLastModified(long lastModified) {
191         this.lastModified = lastModified;
192     }
193
194     public void close() throws IOException JavaDoc {
195         if (bundleFile != null)
196             getBundleFile().close(); // only close the bundleFile if it already exists.
197
}
198
199     public void open() throws IOException JavaDoc {
200         getBundleFile().open();
201     }
202
203     public final void setBundle(Bundle bundle) {
204         this.bundle = bundle;
205     }
206
207     /**
208      * Returns the bundle object of this BaseData
209      * @return the bundle object of this BaseData
210      */

211     public final Bundle getBundle() {
212         return bundle;
213     }
214
215     public int getStartLevel() {
216         return startLevel;
217     }
218
219     public int getStatus() {
220         return status;
221     }
222
223     /**
224      * This method calls each configured storage hook {@link StorageHook#forgetStartLevelChange(int)} method.
225      * If one returns true then this bundledata is not marked dirty.
226      * @see BundleData#setStartLevel(int)
227      */

228     public void setStartLevel(int value) {
229         startLevel = setPersistentData(value, true, startLevel);
230     }
231
232     /**
233      * This method calls each configured storage hook {@link StorageHook#forgetStatusChange(int)} method.
234      * If one returns true then this bundledata is not marked dirty.
235      * @see BundleData#setStatus(int)
236      */

237     public void setStatus(int value) {
238         status = setPersistentData(value, false, status);
239     }
240
241     private int setPersistentData(int value, boolean isStartLevel, int orig) {
242         StorageHook[] hooks = getStorageHooks();
243         for (int i = 0; i < hooks.length; i++)
244             if (isStartLevel) {
245                 if (hooks[i].forgetStartLevelChange(value))
246                     return value;
247             } else {
248                 if (hooks[i].forgetStatusChange(value))
249                     return value;
250             }
251         if (value != orig)
252             dirty = true;
253         return value;
254     }
255
256     public void save() throws IOException JavaDoc {
257         adaptor.getStorage().save(this);
258     }
259
260     /**
261      * Returns true if this bundledata is dirty
262      * @return true if this bundledata is dirty
263      */

264     public boolean isDirty() {
265         return dirty;
266     }
267
268     /**
269      * Sets the dirty flag for this BaseData
270      * @param dirty the dirty flag
271      */

272     public void setDirty(boolean dirty) {
273         this.dirty = dirty;
274     }
275
276     public final String JavaDoc getSymbolicName() {
277         return symbolicName;
278     }
279
280     /**
281      * Sets the symbolic name of this BaseData
282      * @param symbolicName the symbolic name
283      */

284     public final void setSymbolicName(String JavaDoc symbolicName) {
285         this.symbolicName = symbolicName;
286     }
287
288     public final Version getVersion() {
289         return version;
290     }
291
292     /**
293      * Sets the version of this BaseData
294      * @param version the version
295      */

296     public final void setVersion(Version version) {
297         this.version = version;
298     }
299
300     public final int getType() {
301         return type;
302     }
303
304     /**
305      * Sets the type of this BaseData
306      * @param type the type
307      */

308     public final void setType(int type) {
309         this.type = type;
310     }
311
312     public final String JavaDoc[] getClassPath() throws BundleException {
313         ManifestElement[] classpathElements = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, classpath);
314         return getClassPath(classpathElements);
315     }
316
317     // TODO make classpath a String[] instead of saving a comma separated string.
318
public String JavaDoc getClassPathString() {
319         return classpath;
320     }
321
322     //TODO make classpath a String[] instead of saving a comma separated string.
323
public void setClassPathString(String JavaDoc classpath) {
324         this.classpath = classpath;
325     }
326
327     public final String JavaDoc getActivator() {
328         return activator;
329     }
330
331     /**
332      * Sets the activator of this BaseData
333      * @param activator the activator
334      */

335     public final void setActivator(String JavaDoc activator) {
336         this.activator = activator;
337     }
338
339     public final String JavaDoc getExecutionEnvironment() {
340         return executionEnvironment;
341     }
342
343     /**
344      * Sets the execution environment of this BaseData
345      * @param executionEnvironment the execution environment
346      */

347     public void setExecutionEnvironment(String JavaDoc executionEnvironment) {
348         this.executionEnvironment = executionEnvironment;
349     }
350
351     public final String JavaDoc getDynamicImports() {
352         return dynamicImports;
353     }
354
355     /**
356      * Sets the dynamic imports of this BaseData
357      * @param dynamicImports the dynamic imports
358      */

359     public void setDynamicImports(String JavaDoc dynamicImports) {
360         this.dynamicImports = dynamicImports;
361     }
362
363     /**
364      * This method calls each configured storage hook {@link StorageHook#matchDNChain(String)} method
365      * until one returns true. If no configured storage hook returns true then false is returned.
366      * @see BundleData#matchDNChain(String)
367      */

368     public final boolean matchDNChain(String JavaDoc pattern) {
369         StorageHook[] hooks = getStorageHooks();
370         for (int i = 0; i < hooks.length; i++)
371             if (hooks[i].matchDNChain(pattern))
372                 return true;
373         return false;
374     }
375
376     /**
377      * Returns the adaptor for this BaseData
378      * @return the adaptor
379      */

380     public final BaseAdaptor getAdaptor() {
381         return adaptor;
382     }
383
384     /**
385      * Returns the BundleFile for this BaseData. The first time this method is called the
386      * configured storage {@link BaseAdaptor#createBundleFile(Object, BaseData)} method is called.
387      * @return the BundleFile
388      * @throws IllegalArgumentException
389      */

390     public synchronized BundleFile getBundleFile() throws IllegalArgumentException JavaDoc {
391         if (bundleFile == null)
392             try {
393                 bundleFile = adaptor.createBundleFile(null, this);
394             } catch (IOException JavaDoc e) {
395                 throw new IllegalArgumentException JavaDoc(e.getMessage());
396             }
397         return bundleFile;
398     }
399
400     private static String JavaDoc[] getClassPath(ManifestElement[] classpath) {
401         if (classpath == null) {
402             if (Debug.DEBUG && Debug.DEBUG_LOADER)
403                 Debug.println(" no classpath"); //$NON-NLS-1$
404
/* create default BundleClassPath */
405             return new String JavaDoc[] {"."}; //$NON-NLS-1$
406
}
407
408         ArrayList result = new ArrayList(classpath.length);
409         for (int i = 0; i < classpath.length; i++) {
410             if (Debug.DEBUG && Debug.DEBUG_LOADER)
411                 Debug.println(" found classpath entry " + classpath[i].getValueComponents()); //$NON-NLS-1$
412
String JavaDoc[] paths = classpath[i].getValueComponents();
413             for (int j = 0; j < paths.length; j++) {
414                 result.add(paths[j]);
415             }
416         }
417
418         return (String JavaDoc[]) result.toArray(new String JavaDoc[result.size()]);
419     }
420
421     /**
422      * Returns the storage hook which is keyed by the specified key
423      * @param key the key of the storage hook to get
424      * @return the storage hook which is keyed by the specified key
425      */

426     public StorageHook getStorageHook(String JavaDoc key) {
427         if (storageHooks == null)
428             return null;
429         for (int i = 0; i < storageHooks.length; i++)
430             if (storageHooks[i].getKey().equals(key))
431                 return storageHooks[i];
432         return null;
433     }
434
435     /**
436      * Sets the instance storage hooks for this base data. This is method
437      * may only be called once for the lifetime of the base data. Once set,
438      * the list of storage hooks remains constant.
439      * @param storageHooks the storage hook to add
440      */

441     public void setStorageHooks(StorageHook[] storageHooks) {
442         if (this.storageHooks != null)
443             return; // only allow this to be set once.
444
this.storageHooks = storageHooks;
445     }
446
447     /**
448      * Returns all the storage hooks associated with this BaseData
449      * @return all the storage hooks associated with this BaseData
450      */

451     public StorageHook[] getStorageHooks() {
452         return storageHooks == null ? new StorageHook[0] : storageHooks;
453     }
454
455     /**
456      * Gets called by BundleFile during {@link BundleFile#getFile(String, boolean)}. This method
457      * will allocate a File object where content of the specified path may be
458      * stored for the current generation of the base data. The returned File object may
459      * not exist if the content has not previously be stored.
460      * @param path the path to the content to extract from the base data
461      * @return a file object where content of the specified path may be stored.
462      */

463     public File JavaDoc getExtractFile(String JavaDoc path) {
464         return adaptor.getStorage().getExtractFile(this, path);
465     }
466
467     /**
468      * This is only used to support PDE source lookup. The field named &quot;fileName&quot;
469      * must be set for PDE to access the absolute path string.
470      * @param fileName an absolute path string to the base bundle file.
471      */

472     // This is only done for PDE source lookup (bug 126517)
473
public void setFileName(String JavaDoc fileName) {
474         this.fileName = fileName;
475     }
476
477     
478     /**
479      * Return a string representation of the bundle that can be used in debug messages.
480      *
481      * @return String representation of the bundle
482      */

483     public String JavaDoc toString() {
484         String JavaDoc name = getSymbolicName();
485         if (name == null)
486             return getLocation();
487         Version ver = getVersion();
488         if (ver == null)
489             return name;
490         return name+"_"+ver; //$NON-NLS-1$
491
}
492 }
493
Popular Tags