/**
  * Recursively adds the given {@link BundleDescription} and its dependents to the given {@link
  * Set}
  *
  * @param desc the {@link BundleDescription} to compute dependencies for
  * @param set the {@link Set} to collect results in
  * @param includeOptional if optional dependencies should be included
  * @param excludeFragments a collection of <b>fragment</b> bundle symbolic names to exclude from
  *     the dependency resolution
  */
 private static void addBundleAndDependencies(
     BundleDescription desc,
     Set<String> set,
     boolean includeOptional,
     Set<String> excludeFragments) {
   if (desc != null && set.add(desc.getSymbolicName())) {
     BundleSpecification[] required = desc.getRequiredBundles();
     for (int i = 0; i < required.length; i++) {
       if (includeOptional || !required[i].isOptional()) {
         addBundleAndDependencies(
             (BundleDescription) required[i].getSupplier(),
             set,
             includeOptional,
             excludeFragments);
       }
     }
     ImportPackageSpecification[] importedPkgs = desc.getImportPackages();
     for (int i = 0; i < importedPkgs.length; i++) {
       ExportPackageDescription exporter =
           (ExportPackageDescription) importedPkgs[i].getSupplier();
       // Continue if the Imported Package is unresolved of the package is optional and don't want
       // optional packages
       if (exporter == null
           || (!includeOptional
               && Constants.RESOLUTION_OPTIONAL.equals(
                   importedPkgs[i].getDirective(Constants.RESOLUTION_DIRECTIVE)))) {
         continue;
       }
       addBundleAndDependencies(exporter.getExporter(), set, includeOptional, excludeFragments);
     }
     BundleDescription[] fragments = desc.getFragments();
     for (int i = 0; i < fragments.length; i++) {
       if (!fragments[i].isResolved()) {
         continue;
       }
       String id = fragments[i].getSymbolicName();
       if (!excludeFragments.contains(id)) {
         addBundleAndDependencies(fragments[i], set, includeOptional, excludeFragments);
       }
     }
     HostSpecification host = desc.getHost();
     if (host != null) {
       addBundleAndDependencies(
           (BundleDescription) host.getSupplier(), set, includeOptional, excludeFragments);
     }
   }
 }
Ejemplo n.º 2
0
  /**
   * 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());
  }