public static void closeBundleLoader(BundleLoaderProxy proxy) { if (proxy == null) return; // First close the BundleLoader BundleLoader loader = proxy.getBasicBundleLoader(); if (loader != null) loader.close(); proxy.setStale(); // if proxy is not null then make sure to unset user object // associated with the proxy in the state BundleDescription description = proxy.getBundleDescription(); description.setUserObject(null); }
final PackageSource createExportPackageSource( ExportPackageDescription export, KeyedHashSet visited) { BundleLoaderProxy exportProxy = getLoaderProxy(export.getExporter()); if (exportProxy == null) // TODO log error!! return null; PackageSource requiredSource = exportProxy.getBundleLoader().findRequiredSource(export.getName(), visited); PackageSource exportSource = exportProxy.createPackageSource(export, false); if (requiredSource == null) return exportSource; return createMultiSource(export.getName(), new PackageSource[] {requiredSource, exportSource}); }
private void initializeExports(ExportPackageDescription[] exports, Collection exportNames) { for (int i = 0; i < exports.length; i++) { if (proxy.forceSourceCreation(exports[i])) { if (!exportNames.contains(exports[i].getName())) { // must force filtered and reexport sources to be created early // to prevent lazy normal package source creation. // We only do this for the first export of a package name. proxy.createPackageSource(exports[i], true); } } exportNames.add(exports[i].getName()); } }
final void addExportedProvidersFor( String symbolicName, String packageName, ArrayList result, KeyedHashSet visited) { if (!visited.add(bundle)) return; // See if we locally provide the package. PackageSource local = null; if (isExportedPackage(packageName)) local = proxy.getPackageSource(packageName); else if (isSubstitutedExport(packageName)) { result.add(findImportedSource(packageName, visited)); return; // should not continue to required bundles in this case } // Must search required bundles that are exported first. if (requiredBundles != null) { int size = reexportTable == null ? 0 : reexportTable.length; int reexportIndex = 0; for (int i = 0; i < requiredBundles.length; i++) { if (local != null) { // always add required bundles first if we locally provide the package // This allows a bundle to provide a package from a required bundle without // re-exporting the whole required bundle. requiredBundles[i] .getBundleLoader() .addExportedProvidersFor(symbolicName, packageName, result, visited); } else if (reexportIndex < size && reexportTable[reexportIndex] == i) { reexportIndex++; requiredBundles[i] .getBundleLoader() .addExportedProvidersFor(symbolicName, packageName, result, visited); } } } // now add the locally provided package. if (local != null && local.isFriend(symbolicName)) result.add(local); }
private PackageSource findRequiredSource(String pkgName, KeyedHashSet visited) { if (requiredBundles == null) return null; synchronized (requiredSources) { PackageSource result = (PackageSource) requiredSources.getByKey(pkgName); if (result != null) return result.isNullSource() ? null : result; } if (visited == null) visited = new KeyedHashSet(false); visited.add(bundle); // always add ourselves so we do not recurse back to ourselves ArrayList result = new ArrayList(3); for (int i = 0; i < requiredBundles.length; i++) { BundleLoader requiredLoader = requiredBundles[i].getBundleLoader(); requiredLoader.addExportedProvidersFor(proxy.getSymbolicName(), pkgName, result, visited); } // found some so cache the result for next time and return PackageSource source; if (result.size() == 0) { // did not find it in our required bundles lets record the failure // so we do not have to do the search again for this package. source = NullPackageSource.getNullPackageSource(pkgName); } else if (result.size() == 1) { // if there is just one source, remember just the single source source = (PackageSource) result.get(0); } else { // if there was more than one source, build a multisource and cache that. PackageSource[] srcs = (PackageSource[]) result.toArray(new PackageSource[result.size()]); source = createMultiSource(pkgName, srcs); } synchronized (requiredSources) { requiredSources.add(source); } return source.isNullSource() ? null : source; }
/* * Gets the package source for the pkgName. This will include the local package source * if the bundle exports the package. This is used to compare the PackageSource of a * package from two different bundles. */ public final PackageSource getPackageSource(String pkgName) { PackageSource result = findSource(pkgName); if (!isExportedPackage(pkgName)) return result; // if the package is exported then we need to get the local source PackageSource localSource = proxy.getPackageSource(pkgName); if (result == null) return localSource; if (localSource == null) return result; return createMultiSource(pkgName, new PackageSource[] {result, localSource}); }
public synchronized void attachFragment(BundleFragment fragment) throws BundleException { ExportPackageDescription[] exports = proxy.getBundleDescription().getSelectedExports(); if (classloader == null) { initializeExports(exports, exportedPackages); return; } String[] classpath = fragment.getBundleData().getClassPath(); if (classpath != null) classloader.attachFragment( fragment.getBundleData(), fragment.getProtectionDomain(), classpath); initializeExports(exports, exportedPackages); }
public synchronized KeyedHashSet getImportedSources(KeyedHashSet visited) { if ((loaderFlags & FLAG_IMPORTSINIT) != 0) return importedSources; BundleDescription bundleDesc = proxy.getBundleDescription(); ExportPackageDescription[] packages = bundleDesc.getResolvedImports(); if (packages != null && packages.length > 0) { if (importedSources == null) importedSources = new KeyedHashSet(packages.length, false); for (int i = 0; i < packages.length; i++) { if (packages[i].getExporter() == bundleDesc) continue; // ignore imports resolved to this bundle PackageSource source = createExportPackageSource(packages[i], visited); if (source != null) importedSources.add(source); } } loaderFlags |= FLAG_IMPORTSINIT; return importedSources; }
private PackageSource findDynamicSource(String pkgName) { if (isDynamicallyImported(pkgName)) { ExportPackageDescription exportPackage = bundle .getFramework() .getAdaptor() .getState() .linkDynamicImport(proxy.getBundleDescription(), pkgName); if (exportPackage != null) { PackageSource source = createExportPackageSource(exportPackage, null); synchronized (this) { if (importedSources == null) importedSources = new KeyedHashSet(false); } synchronized (importedSources) { importedSources.add(source); } return source; } } return null; }
/** * BundleLoader runtime constructor. This object is created lazily when the first request for a * resource is made to this bundle. * * @param bundle Bundle object for this loader. * @param proxy the BundleLoaderProxy for this loader. * @exception org.osgi.framework.BundleException */ protected BundleLoader(BundleHost bundle, BundleLoaderProxy proxy) throws BundleException { this.bundle = bundle; this.proxy = proxy; try { bundle.getBundleData().open(); /* make sure the BundleData is open */ } catch (IOException e) { throw new BundleException(Msg.BUNDLE_READ_EXCEPTION, e); } BundleDescription description = proxy.getBundleDescription(); // init the require bundles list. BundleDescription[] required = description.getResolvedRequires(); if (required.length > 0) { // get a list of re-exported symbolic names HashSet reExportSet = new HashSet(required.length); BundleSpecification[] requiredSpecs = description.getRequiredBundles(); if (requiredSpecs != null && requiredSpecs.length > 0) for (int i = 0; i < requiredSpecs.length; i++) if (requiredSpecs[i].isExported()) reExportSet.add(requiredSpecs[i].getName()); requiredBundles = new BundleLoaderProxy[required.length]; int[] reexported = new int[required.length]; int reexportIndex = 0; for (int i = 0; i < required.length; i++) { requiredBundles[i] = getLoaderProxy(required[i]); if (reExportSet.contains(required[i].getSymbolicName())) reexported[reexportIndex++] = i; } if (reexportIndex > 0) { reexportTable = new int[reexportIndex]; System.arraycopy(reexported, 0, reexportTable, 0, reexportIndex); } else { reexportTable = null; } requiredSources = new KeyedHashSet(10, false); } else { requiredBundles = null; reexportTable = null; requiredSources = null; } // init the provided packages set ExportPackageDescription[] exports = description.getSelectedExports(); if (exports != null && exports.length > 0) { exportedPackages = Collections.synchronizedCollection( exports.length > 10 ? (Collection) new HashSet(exports.length) : new ArrayList(exports.length)); initializeExports(exports, exportedPackages); } else { exportedPackages = Collections.synchronizedCollection(new ArrayList(0)); } ExportPackageDescription substituted[] = description.getSubstitutedExports(); if (substituted.length > 0) { substitutedPackages = substituted.length > 10 ? (Collection) new HashSet(substituted.length) : new ArrayList(substituted.length); for (int i = 0; i < substituted.length; i++) substitutedPackages.add(substituted[i].getName()); } else { substitutedPackages = null; } // This is the fastest way to access to the description for fragments since the // hostdescription.getFragments() is slow BundleFragment[] fragmentObjects = bundle.getFragments(); BundleDescription[] fragments = new BundleDescription[fragmentObjects == null ? 0 : fragmentObjects.length]; for (int i = 0; i < fragments.length; i++) fragments[i] = fragmentObjects[i].getBundleDescription(); // init the dynamic imports tables if (description.hasDynamicImports()) addDynamicImportPackage(description.getImportPackages()); // ...and its fragments for (int i = 0; i < fragments.length; i++) if (fragments[i].isResolved() && fragments[i].hasDynamicImports()) addDynamicImportPackage(fragments[i].getImportPackages()); // Initialize the policy handler String buddyList = null; try { buddyList = (String) bundle.getBundleData().getManifest().get(Constants.BUDDY_LOADER); } catch (BundleException e) { // do nothing; buddyList == null } policy = buddyList != null ? new PolicyHandler(this, buddyList, bundle.getFramework().getPackageAdmin()) : null; if (policy != null) policy.open(bundle.getFramework().getSystemBundleContext()); }