/**
  * 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);
     }
   }
 }
 private Object[] getDependencies(BundleDescription desc) {
   // use map to store dependencies so if Import-Package is supplied by same BundleDescription as
   // supplier of Require-Bundle, it only shows up once
   // Also, have to use BundleSpecficiation instead of BundleDescroption to show re-exported icon
   // on re-exported Required-Bundles
   // Have to use ImportPackageSpecification to determine if an import is optional and should be
   // filtered.
   HashMap<Object, Object> dependencies = new HashMap<Object, Object>();
   BundleSpecification[] requiredBundles = desc.getRequiredBundles();
   for (int i = 0; i < requiredBundles.length; i++) {
     BaseDescription bd = requiredBundles[i].getSupplier();
     if (bd != null) dependencies.put(bd, requiredBundles[i]);
     else dependencies.put(requiredBundles[i], requiredBundles[i]);
   }
   ImportPackageSpecification[] importedPkgs = desc.getImportPackages();
   for (int i = 0; i < importedPkgs.length; i++) {
     BaseDescription bd = importedPkgs[i].getSupplier();
     if (bd != null && bd instanceof ExportPackageDescription) {
       BundleDescription exporter = ((ExportPackageDescription) bd).getExporter();
       if (exporter != null) {
         Object obj = dependencies.get(exporter);
         if (obj == null) {
           dependencies.put(exporter, importedPkgs[i]);
         } else if (!Constants.RESOLUTION_OPTIONAL.equals(
                 importedPkgs[i].getDirective(Constants.RESOLUTION_DIRECTIVE))
             && obj instanceof ImportPackageSpecification
             && Constants.RESOLUTION_OPTIONAL.equals(
                 ((ImportPackageSpecification) obj)
                     .getDirective(Constants.RESOLUTION_DIRECTIVE))) {
           // if we have a non-optional Import-Package dependency on a bundle which we already
           // depend on, check to make sure our
           // current dependency is not optional.  If it is, replace the optional dependency with
           // the non-optional one
           dependencies.put(exporter, importedPkgs[i]);
         }
       }
     }
     // ignore unresolved packages
   }
   // include fragments which are "linked" to this bundle
   BundleDescription frags[] = desc.getFragments();
   for (int i = 0; i < frags.length; i++) {
     if (!frags[i].equals(fFragmentDescription)) dependencies.put(frags[i], frags[i]);
   }
   return dependencies.values().toArray();
 }
  /**
   * Build the table of plug-in dependencies. Iterate over all the plug-ins in the plug-in registry
   * and the cycle through the list of pre-requisites and create the parent/child relationships in
   * the nodes.
   */
  private Map getDependencyGraph() {
    if (dependencyGraph != null) return dependencyGraph;
    // Build up the dependency graph (see PluginDependencyGraphNode) so
    // we have the information readily available for any plug-in.
    State state = Platform.getPlatformAdmin().getState(false);
    BundleDescription[] plugins = state.getBundles();
    dependencyGraph = new HashMap();
    for (int i = 0; i < plugins.length; i++) {
      BundleDescription descriptor = plugins[i];
      PluginDependencyGraphNode node =
          (PluginDependencyGraphNode) dependencyGraph.get(new Long(descriptor.getBundleId()));
      if (node == null) {
        node = new PluginDependencyGraphNode(descriptor);
        dependencyGraph.put(new Long(descriptor.getBundleId()), node);
      }

      // Cycle through the prerequisites
      BundleSpecification[] requires = descriptor.getRequiredBundles();
      for (int j = 0; j < requires.length; j++) {
        BundleDescription childDesc = (BundleDescription) requires[j].getSupplier();
        // if the child doesn't exist then move to the next child
        if (childDesc == null) continue;

        // if the child entry is not in the table yet then add it
        PluginDependencyGraphNode childNode =
            (PluginDependencyGraphNode) dependencyGraph.get(new Long(childDesc.getBundleId()));
        if (childNode == null) {
          childNode = new PluginDependencyGraphNode(childDesc);
          dependencyGraph.put(new Long(childDesc.getBundleId()), childNode);
        }

        // Add the child to this node's children and set this node as an ancestor
        // of the child node
        node.addChild(childNode);
        childNode.addAncestor(node);
      }
    }
    return dependencyGraph;
  }
Exemplo n.º 4
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());
  }