KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > osgi > framework > adaptor > core > DefaultClassLoader


1 /*******************************************************************************
2  * Copyright (c) 2004, 2005 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.framework.adaptor.core;
13
14 import java.io.*;
15 import java.net.MalformedURLException JavaDoc;
16 import java.net.URL JavaDoc;
17 import java.security.*;
18 import java.security.cert.Certificate JavaDoc;
19 import java.util.*;
20 import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate;
21 import org.eclipse.osgi.framework.debug.Debug;
22 import org.eclipse.osgi.util.NLS;
23 import org.osgi.framework.BundleException;
24 import org.osgi.framework.FrameworkEvent;
25
26 /**
27  * A concrete implementation of BundleClassLoader. This implementation
28  * consolidates all Bundle-ClassPath entries into a single ClassLoader.
29  * <p>
30  * Clients may extend this class.
31  * </p>
32  * @since 3.1
33  */

34 public class DefaultClassLoader extends AbstractClassLoader {
35     /**
36      * A PermissionCollection for AllPermissions; shared across all ProtectionDomains when security is disabled
37      */

38     static final PermissionCollection ALLPERMISSIONS;
39     static {
40         AllPermission allPerm = new AllPermission();
41         ALLPERMISSIONS = allPerm.newPermissionCollection();
42         if (ALLPERMISSIONS != null)
43             ALLPERMISSIONS.add(allPerm);
44     }
45     /**
46      * The BundleData object for this BundleClassLoader
47      */

48     protected AbstractBundleData hostdata;
49
50     /**
51      * The ClasspathEntries for this BundleClassLoader. Each ClasspathEntry object
52      * represents on Bundle-ClassPath entry.
53      */

54     protected ClasspathEntry[] classpathEntries;
55
56     /**
57      * A list of fragment classpaths for this classloader
58      */

59     protected Vector fragClasspaths; //TODO This should be an array or an arraylist if the synchronization is not required
60

61     /**
62      * The buffer size to use when loading classes. This value is used
63      * only if we cannot determine the size of the class we are loading.
64      */

65     protected int buffersize = 8 * 1024; //TODO Could not that be a constant?
66

67     /**
68      * BundleClassLoader constructor.
69      * @param delegate The ClassLoaderDelegate for this ClassLoader.
70      * @param domain The ProtectionDomain for this ClassLoader.
71      * @param classpath An array of Bundle-ClassPath entries to
72      * use for loading classes and resources. This is specified by the
73      * Bundle-ClassPath manifest entry.
74      * @param parent The parent ClassLoader.
75      * @param bundledata The BundleData for this ClassLoader
76      */

77     public DefaultClassLoader(ClassLoaderDelegate delegate, ProtectionDomain domain, String JavaDoc[] classpath, ClassLoader JavaDoc parent, AbstractBundleData bundledata) {
78         super(delegate, domain, classpath, parent);
79         this.hostdata = bundledata;
80
81         try {
82             hostdata.open(); /* make sure the BundleData is open */
83         } catch (IOException e) {
84             hostdata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, hostdata.getBundle(), e);
85         }
86     }
87
88     /**
89      * @see org.eclipse.osgi.framework.adaptor.BundleClassLoader#initialize()
90      */

91     public void initialize() {
92         classpathEntries = buildClasspath(hostclasspath, hostdata, hostdomain);
93     }
94
95     /**
96      * @see org.eclipse.osgi.framework.adaptor.BundleClassLoader#attachFragment(BundleData, ProtectionDomain, String[])
97      */

98     public void attachFragment(org.eclipse.osgi.framework.adaptor.BundleData bundledata, ProtectionDomain domain, String JavaDoc[] classpath) {
99         AbstractBundleData abstractbundledata = (AbstractBundleData) bundledata;
100         try {
101             bundledata.open(); /* make sure the BundleData is open */
102         } catch (IOException e) {
103
104             abstractbundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, abstractbundledata.getBundle(), e);
105         }
106         ClasspathEntry[] fragEntries = buildClasspath(classpath, abstractbundledata, domain);
107         FragmentClasspath fragClasspath = new FragmentClasspath(fragEntries, abstractbundledata, domain);
108         insertFragment(fragClasspath);
109     }
110
111     /**
112      * Inserts a fragment classpath to into the list of fragments for this host.
113      * Fragments are inserted into the list according to the fragment's
114      * Bundle ID.
115      * @param fragClasspath The FragmentClasspath to insert.
116      */

117     protected synchronized void insertFragment(FragmentClasspath fragClasspath) {
118         if (fragClasspaths == null) {
119             // First fragment to attach. Simply create the list and add the fragment.
120
fragClasspaths = new Vector(10);
121             fragClasspaths.addElement(fragClasspath);
122             return;
123         }
124
125         // Find a place in the fragment list to insert this fragment.
126
int size = fragClasspaths.size();
127         long fragID = fragClasspath.bundledata.getBundleID();
128         for (int i = 0; i < size; i++) {
129             long otherID = ((FragmentClasspath) fragClasspaths.elementAt(i)).bundledata.getBundleID();
130             if (fragID < otherID) {
131                 fragClasspaths.insertElementAt(fragClasspath, i);
132                 return;
133             }
134         }
135         // This fragment has the highest ID; put it at the end of the list.
136
fragClasspaths.addElement(fragClasspath);
137     }
138
139     /**
140      * Returns a string of the symbolic name and version
141      * @return a string of the symbolic name and version
142      */

143     protected String JavaDoc getBundleSymbolicName() {
144         return hostdata.getSymbolicName() + "_" + hostdata.getVersion(); //$NON-NLS-1$
145
}
146
147     /**
148      * Returns the host BundleData for this classloader
149      * @return the host BundleData for this classloader
150      */

151     public AbstractBundleData getHostData() {
152         return hostdata;
153     }
154
155     /**
156      * Returns a list of FragmentClasspath objects for the currently attached fragments
157      * @return a list of FragmentClasspath objects for the currently attached fragments
158      */

159     public FragmentClasspath[] getFragClasspaths() {
160         if (fragClasspaths == null)
161             return null;
162         return (FragmentClasspath[]) fragClasspaths.toArray(new FragmentClasspath[fragClasspaths.size()]);
163     }
164
165     /**
166      * Gets a ClasspathEntry object for the specified ClassPath entry.
167      * @param cp The ClassPath entry to get the ClasspathEntry for.
168      * @param bundledata The BundleData that the ClassPath entry is for.
169      * @param domain The ProtectionDomain for the ClassPath entry.
170      * @return The ClasspathEntry object for the ClassPath entry.
171      */

172     protected ClasspathEntry getClasspath(String JavaDoc cp, AbstractBundleData bundledata, ProtectionDomain domain) {
173         BundleFile bundlefile = null;
174         File file;
175         // check for internal library jars
176
if ((file = bundledata.getBaseBundleFile().getFile(cp)) != null)
177             bundlefile = createBundleFile(file, bundledata);
178         // check for intenral library directories in a bundle jar file
179
if (bundlefile == null && bundledata.getBaseBundleFile().containsDir(cp))
180             bundlefile = new BundleFile.NestedDirBundleFile(bundledata.getBaseBundleFile(), cp);
181         // if in dev mode, try using the cp as an absolute path
182
if (bundlefile == null && DevClassPathHelper.inDevelopmentMode())
183             return getExternalClassPath(cp, bundledata, domain);
184         if (bundlefile != null)
185             return createClassPathEntry(bundlefile, domain);
186         return null;
187     }
188
189     /**
190      * Gets a ClasspathEntry object for the specified classpath entry which is external to the
191      * bundledata.
192      * @param cp The ClassPath entry to get the ClasspathEntry for.
193      * @param bundledata The BundleData that the ClassPath entry is for.
194      * @param domain The ProtectionDomain for the ClassPath entry.
195      * @return The ClasspathEntry object for the ClassPath entry.
196      */

197     protected ClasspathEntry getExternalClassPath(String JavaDoc cp, AbstractBundleData bundledata, ProtectionDomain domain) {
198         File file = new File(cp);
199         if (!file.isAbsolute())
200             return null;
201         BundleFile bundlefile = createBundleFile(file, bundledata);
202         if (bundlefile != null)
203             return createClassPathEntry(bundlefile, domain);
204         return null;
205     }
206
207     /**
208      * Creates a BundleFile object for a classpath entry
209      * @param file the file object used to create a BundleFile
210      * @param bundledata the bundle data
211      * @return a BundleFile object for a classpath entry
212      */

213     protected BundleFile createBundleFile(File file, AbstractBundleData bundledata) {
214         if (file == null || !file.exists())
215             return null;
216         try {
217             return hostdata.getAdaptor().createBundleFile(file, bundledata);
218         } catch (IOException e) {
219             bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundledata.getBundle(), e);
220         }
221         return null;
222     }
223
224     /**
225      * @see ClassLoader#findClass(java.lang.String)
226      */

227     protected synchronized Class JavaDoc findClass(String JavaDoc name) throws ClassNotFoundException JavaDoc {
228         // must call findLoadedClass here even if it was called earlier,
229
// the findLoadedClass and defineClass calls must be atomic
230
Class JavaDoc result = findLoadedClass(name);
231         if (result != null)
232             return result;
233         for (int i = 0; i < classpathEntries.length; i++) {
234             if (classpathEntries[i] != null) {
235                 result = findClassImpl(name, classpathEntries[i]);
236                 if (result != null)
237                     return result;
238             }
239         }
240         // look in fragments.
241
if (fragClasspaths != null) {
242             int size = fragClasspaths.size();
243             for (int i = 0; i < size; i++) {
244                 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i);
245                 for (int j = 0; j < fragCP.classpathEntries.length; j++) {
246                     result = findClassImpl(name, fragCP.classpathEntries[j]);
247                     if (result != null)
248                         return result;
249                 }
250             }
251         }
252         throw new ClassNotFoundException JavaDoc(name);
253     }
254
255     /**
256      * Finds a class in the BundleFile. If a class is found then the class
257      * is defined using the ProtectionDomain bundledomain.
258      * @param name The name of the class to find.
259      * @param classpathEntry The ClasspathEntry to find the class in.
260      * @return The loaded class object or null if the class is not found.
261      */

262     protected Class JavaDoc findClassImpl(String JavaDoc name, ClasspathEntry classpathEntry) {
263         if (Debug.DEBUG && Debug.DEBUG_LOADER) {
264             Debug.println("BundleClassLoader[" + hostdata + "].findClass(" + name + ")"); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
265
}
266
267         String JavaDoc filename = name.replace('.', '/').concat(".class"); //$NON-NLS-1$
268

269         BundleEntry entry = classpathEntry.getBundleFile().getEntry(filename);
270
271         if (entry == null) {
272             return null;
273         }
274
275         InputStream in;
276         try {
277             in = entry.getInputStream();
278         } catch (IOException e) {
279             return null;
280         }
281
282         int length = (int) entry.getSize();
283         byte[] classbytes;
284         int bytesread = 0;
285         int readcount;
286
287         if (Debug.DEBUG && Debug.DEBUG_LOADER) {
288             Debug.println(" about to read " + length + " bytes from " + filename); //$NON-NLS-1$ //$NON-NLS-2$
289
}
290
291         try {
292             try {
293                 if (length > 0) {
294                     classbytes = new byte[length];
295
296                     readloop: for (; bytesread < length; bytesread += readcount) {
297                         readcount = in.read(classbytes, bytesread, length - bytesread);
298
299                         if (readcount <= 0) /* if we didn't read anything */{
300                             break readloop; /* leave the loop */
301                         }
302                     }
303                 } else /* BundleEntry does not know its own length! */{
304                     length = buffersize;
305                     classbytes = new byte[length];
306
307                     readloop: while (true) {
308                         for (; bytesread < length; bytesread += readcount) {
309                             readcount = in.read(classbytes, bytesread, length - bytesread);
310
311                             if (readcount <= 0) /* if we didn't read anything */{
312                                 break readloop; /* leave the loop */
313                             }
314                         }
315
316                         byte[] oldbytes = classbytes;
317                         length += buffersize;
318                         classbytes = new byte[length];
319                         System.arraycopy(oldbytes, 0, classbytes, 0, bytesread);
320                     }
321                 }
322             } catch (IOException e) {
323                 if (Debug.DEBUG && Debug.DEBUG_LOADER) {
324                     Debug.println(" IOException reading " + filename + " from " + hostdata); //$NON-NLS-1$ //$NON-NLS-2$
325
}
326
327                 return null;
328             }
329         } finally {
330             try {
331                 in.close();
332             } catch (IOException ee) {
333                 // nothing to do here
334
}
335         }
336
337         if (Debug.DEBUG && Debug.DEBUG_LOADER) {
338             Debug.println(" read " + bytesread + " bytes from " + filename); //$NON-NLS-1$ //$NON-NLS-2$
339
Debug.println(" defining class " + name); //$NON-NLS-1$
340
}
341
342         try {
343             return (defineClass(name, classbytes, 0, bytesread, classpathEntry));
344         } catch (Error JavaDoc e) {
345             if (Debug.DEBUG && Debug.DEBUG_LOADER) {
346                 Debug.println(" error defining class " + name); //$NON-NLS-1$
347
}
348
349             throw e;
350         }
351     }
352
353     /**
354      * Defines a class for this classloader
355      * @param name the name of the class
356      * @param classbytes the class bytes
357      * @param off the offset in the class bytes array
358      * @param len the legth of the class bytes
359      * @param classpathEntry the classpath entry used for the class
360      * @return a loaded Class object
361      * @throws ClassFormatError if the class has a format error
362      */

363     protected Class JavaDoc defineClass(String JavaDoc name, byte[] classbytes, int off, int len, ClasspathEntry classpathEntry) throws ClassFormatError JavaDoc {
364         if (name != null && name.startsWith("java.")) { //$NON-NLS-1$
365
// To work around the security issue that prevents any
366
// other classloader except for the bootstrap classloader
367
// from loading packages that start with java.
368
name = null;
369         }
370         return defineClass(name, classbytes, off, len, classpathEntry.getProtectionDomain());
371     }
372
373     /**
374      * @see ClassLoader#findResource(java.lang.String)
375      */

376     protected URL JavaDoc findResource(String JavaDoc name) {
377         URL JavaDoc result = null;
378         for (int i = 0; i < classpathEntries.length; i++) {
379             if (classpathEntries[i] != null) {
380                 result = findResourceImpl(name, classpathEntries[i].getBundleFile());
381                 if (result != null)
382                     return result;
383             }
384         }
385         // look in fragments
386
if (fragClasspaths != null) {
387             int size = fragClasspaths.size();
388             for (int i = 0; i < size; i++) {
389                 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i);
390                 for (int j = 0; j < fragCP.classpathEntries.length; j++) {
391                     result = findResourceImpl(name, fragCP.classpathEntries[j].getBundleFile());
392                     if (result != null)
393                         return result;
394                 }
395             }
396         }
397         return null;
398     }
399
400     /**
401      * Looks in the specified BundleFile for the resource.
402      * @param name The name of the resource to find.
403      * @param bundlefile The BundleFile to look in.
404      * @return A URL to the resource or null if the resource does not exist.
405      */

406     protected URL JavaDoc findResourceImpl(String JavaDoc name, BundleFile bundlefile) {
407         return findResourceImpl(name, bundlefile, 0);
408     }
409
410     /**
411      * Looks in the specified BundleFile for the resource.
412      * @param name The name of the resource to find.
413      * @param bundlefile The BundleFile to look in.
414      * @param index the index of the resource.
415      * @return A URL to the resource or null if the resource does not exist.
416      */

417     protected URL JavaDoc findResourceImpl(String JavaDoc name, BundleFile bundlefile, int index) {
418         return bundlefile.getResourceURL(name, hostdata.getBundleID(), index);
419     }
420
421     /**
422      * @see org.eclipse.osgi.framework.adaptor.BundleClassLoader#findLocalResources(String)
423      */

424     public Enumeration findLocalResources(String JavaDoc resource) {
425         Vector resources = new Vector(6); // use a Vector instead of ArrayList because we need an enumeration
426
for (int i = 0; i < classpathEntries.length; i++) {
427             if (classpathEntries[i] != null) {
428                 URL JavaDoc url = findResourceImpl(resource, classpathEntries[i].getBundleFile(), resources.size());
429                 if (url != null)
430                     resources.addElement(url);
431             }
432         }
433         // look in fragments
434
if (fragClasspaths != null) {
435             int size = fragClasspaths.size();
436             for (int i = 0; i < size; i++) {
437                 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i);
438                 for (int j = 0; j < fragCP.classpathEntries.length; j++) {
439                     URL JavaDoc url = findResourceImpl(resource, fragCP.classpathEntries[j].getBundleFile(), resources.size());
440                     if (url != null)
441                         resources.addElement(url);
442                 }
443             }
444         }
445         if (resources.size() > 0)
446             return resources.elements();
447         return null;
448     }
449
450     /**
451      * @see AbstractClassLoader#findLocalObject(String)
452      */

453     public Object JavaDoc findLocalObject(String JavaDoc object) {
454         BundleEntry result = null;
455         for (int i = 0; i < classpathEntries.length; i++) {
456             if (classpathEntries[i] != null) {
457                 result = findObjectImpl(object, classpathEntries[i].getBundleFile());
458                 if (result != null) {
459                     return result;
460                 }
461             }
462         }
463         // look in fragments
464
if (fragClasspaths != null) {
465             int size = fragClasspaths.size();
466             for (int i = 0; i < size; i++) {
467                 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i);
468                 for (int j = 0; j < fragCP.classpathEntries.length; j++) {
469                     result = findObjectImpl(object, fragCP.classpathEntries[j].getBundleFile());
470                     if (result != null) {
471                         return result;
472                     }
473                 }
474             }
475         }
476         return null;
477     }
478
479     /**
480      * @see AbstractClassLoader#findLocalObjects(String)
481      */

482     public Enumeration findLocalObjects(String JavaDoc object) {
483         Vector objects = new Vector(6); // use a Vector instead of ArrayList because we need an enumeration
484
for (int i = 0; i < classpathEntries.length; i++) {
485             if (classpathEntries[i] != null) {
486                 Object JavaDoc result = findObjectImpl(object, classpathEntries[i].getBundleFile());
487                 if (result != null)
488                     objects.addElement(result);
489             }
490         }
491         // look in fragments
492
if (fragClasspaths != null) {
493             int size = fragClasspaths.size();
494             for (int i = 0; i < size; i++) {
495                 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i);
496                 for (int j = 0; j < fragCP.classpathEntries.length; j++) {
497                     Object JavaDoc result = findObjectImpl(object, fragCP.classpathEntries[j].getBundleFile());
498                     if (result != null)
499                         objects.addElement(result);
500                 }
501             }
502         }
503         if (objects.size() > 0)
504             return objects.elements();
505         return null;
506     }
507
508     /**
509      * Looks in the specified BundleFile for the entry.
510      * @param object The name of the entry to find.
511      * @param bundleFile The BundleFile to look in.
512      * @return a bundle entry for the specified entry or <code>null</code> if the
513      * entry does not exist
514      */

515     protected BundleEntry findObjectImpl(String JavaDoc object, BundleFile bundleFile) {
516         return bundleFile.getEntry(object);
517     }
518
519     /**
520      * @see org.eclipse.osgi.framework.adaptor.BundleClassLoader#close()
521      */

522     public void close() {
523         super.close();
524         if (classpathEntries != null) {
525             for (int i = 0; i < classpathEntries.length; i++) {
526                 if (classpathEntries[i] != null) {
527                     try {
528                         classpathEntries[i].getBundleFile().close();
529                     } catch (IOException e) {
530                         hostdata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, hostdata.getBundle(), e);
531                     }
532                 }
533             }
534         }
535         if (fragClasspaths != null) {
536             int size = fragClasspaths.size();
537             for (int i = 0; i < size; i++) {
538                 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i);
539                 fragCP.close();
540             }
541         }
542     }
543
544     /**
545      * Builds the classpath entry objects for this classloader
546      * @param classpath a list of classpath entries to build
547      * @param bundledata the bundle data
548      * @param domain the ProtectionDomain for the classpath entry objects
549      * @return
550      */

551     protected ClasspathEntry[] buildClasspath(String JavaDoc[] classpath, AbstractBundleData bundledata, ProtectionDomain domain) {
552         ArrayList result = new ArrayList(classpath.length);
553         // if in dev mode add the dev entries
554
addDefaultDevEntries(result, bundledata, domain);
555         // add the regular classpath entries.
556
for (int i = 0; i < classpath.length; i++)
557             findClassPathEntry(result, classpath[i], bundledata, domain);
558         return (ClasspathEntry[]) result.toArray(new ClasspathEntry[result.size()]);
559     }
560
561     /**
562      * Adds the default development classpath entries
563      * @param result a list of current classpath entries. This list is modified by this method to add
564      * a new classpath entry.
565      * @param bundledata the bundle data
566      * @param domain the ProtectionDomain for the classpath entry
567      */

568     protected void addDefaultDevEntries(ArrayList result, AbstractBundleData bundledata, ProtectionDomain domain) {
569         String JavaDoc[] devClassPath = !DevClassPathHelper.inDevelopmentMode() ? null : DevClassPathHelper.getDevClassPath(bundledata.getSymbolicName());
570         if (devClassPath == null)
571             return; // not in dev mode return
572
for (int i = 0; i < devClassPath.length; i++)
573             findClassPathEntry(result, devClassPath[i], bundledata, domain);
574     }
575
576     /**
577      * Finds a classpath entry for this classloader
578      * @param result a list of current classpath entries. This list is modified by this method to add
579      * a new classpath entry.
580      * @param entry the path to the entry to find
581      * @param bundledata the bundle data
582      * @param domain the ProtectionDomain for the classpath entry
583      */

584     protected void findClassPathEntry(ArrayList result, String JavaDoc entry, AbstractBundleData bundledata, ProtectionDomain domain) {
585         if (!addClassPathEntry(result, entry, bundledata, domain)) {
586             String JavaDoc[] devCP = !DevClassPathHelper.inDevelopmentMode() ? null : DevClassPathHelper.getDevClassPath(bundledata.getSymbolicName());
587             if (devCP == null || devCP.length == 0) {
588                 BundleException be = new BundleException(NLS.bind(AdaptorMsg.BUNDLE_CLASSPATH_ENTRY_NOT_FOUND_EXCEPTION, entry, bundledata.getLocation()));
589                 bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.INFO, bundledata.getBundle(), be);
590             }
591         }
592     }
593
594     /**
595      * Adds a classpath entry to this classloader
596      * @param result a list of current classpath entries. This list is modified by this method to add
597      * a new classpath entry.
598      * @param entry the path to the entry to add
599      * @param bundledata the bundle data
600      * @param domain the ProtectionDomain for the classpath entry
601      * @return true if a classpath entry was added to the result; false if the classpath entry could
602      * not be found
603      */

604     protected boolean addClassPathEntry(ArrayList result, String JavaDoc entry, AbstractBundleData bundledata, ProtectionDomain domain) {
605         if (entry.equals(".")) { //$NON-NLS-1$
606
result.add(createClassPathEntry(bundledata.getBaseBundleFile(), domain));
607             return true;
608         }
609         Object JavaDoc element = getClasspath(entry, bundledata, domain);
610         if (element != null) {
611             result.add(element);
612             return true;
613         }
614         // need to check in fragments for the classpath entry.
615
// only check for fragments if the bundledata is the hostdata.
616
if (fragClasspaths != null && hostdata == bundledata) {
617             int size = fragClasspaths.size();
618             for (int i = 0; i < size; i++) {
619                 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i);
620                 element = getClasspath(entry, fragCP.bundledata, fragCP.domain);
621                 if (element != null) {
622                     result.add(element);
623                     return true;
624                 }
625             }
626         }
627         return false;
628     }
629
630     /**
631      * Creates a ClasspathEntry from a BundleFile and ProtectionDomain.
632      * @param bundlefile the BundleFile.
633      * @param domain the ProtectionDomain
634      * @return the ClasspathEntry
635      */

636     protected ClasspathEntry createClassPathEntry(BundleFile bundlefile, ProtectionDomain domain) {
637         return new ClasspathEntry(bundlefile, domain);
638     }
639
640     /**
641      * A data structure to hold information about a fragment classpath.
642      */

643     protected class FragmentClasspath {
644         /** The ClasspathEntries of the fragments Bundle-Classpath */
645         protected ClasspathEntry[] classpathEntries;
646         /** The BundleData of the fragment */
647         protected AbstractBundleData bundledata;
648         /** The ProtectionDomain of the fragment */
649         protected ProtectionDomain domain;
650
651         protected FragmentClasspath(ClasspathEntry[] classpathEntries, AbstractBundleData bundledata, ProtectionDomain domain) {
652             this.classpathEntries = classpathEntries;
653             this.bundledata = bundledata;
654             this.domain = domain;
655         }
656
657         protected void close() {
658             for (int i = 0; i < classpathEntries.length; i++) {
659                 try {
660                     classpathEntries[i].getBundleFile().close();
661                 } catch (IOException e) {
662                     bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundledata.getBundle(), e);
663                 }
664             }
665         }
666
667         public AbstractBundleData getBundleData() {
668             return bundledata;
669         }
670     }
671
672     /**
673      * A data structure to hold information about a classpath entry.
674      */

675     protected class ClasspathEntry {
676         protected BundleFile bundlefile;
677         protected ProtectionDomain domain;
678
679         protected ClasspathEntry(BundleFile bundlefile, ProtectionDomain domain) {
680             this.bundlefile = bundlefile;
681             this.domain = createProtectionDomain(domain);
682         }
683
684         public BundleFile getBundleFile() {
685             return bundlefile;
686         }
687
688         public ProtectionDomain getProtectionDomain() {
689             return domain;
690         }
691
692         /*
693          * Creates a ProtectionDomain using the permissions of the specified baseDomain
694          */

695         protected ProtectionDomain createProtectionDomain(ProtectionDomain baseDomain) {
696             // create a protection domain which knows about the codesource for this classpath entry (bug 89904)
697
try {
698                 // use the permissions supplied by the domain passed in from the framework
699
PermissionCollection permissions;
700                 if (baseDomain != null)
701                     permissions = baseDomain.getPermissions();
702                 else
703                     // no domain specified. Better use a collection that has all permissions
704
// this is done just incase someone sets the security manager later
705
permissions = ALLPERMISSIONS;
706                 return new ClasspathDomain(bundlefile.getBaseFile().toURL(), permissions);
707             } catch (MalformedURLException JavaDoc e) {
708                 // Failed to create our own domain; just return the baseDomain
709
return baseDomain;
710             }
711         }
712     }
713
714     /*
715      * Very simple protection domain that uses a URL to create a CodeSource for a ProtectionDomain
716      */

717     protected class ClasspathDomain extends ProtectionDomain {
718         public ClasspathDomain(URL JavaDoc codeLocation, PermissionCollection permissions) {
719             super(new CodeSource(codeLocation, (Certificate JavaDoc[]) null), permissions);
720         }
721     }
722 }
723
Popular Tags