org.eclipse.osgi_3.8.2.v20130124-134944

ize() - 1);
        for (Iterator localIterator2 = sameBSN.iterator(); localIterator2.hasNext();)
        {
          ResolverBundle collision = (ResolverBundle)localIterator2.next();
          if ((collision != singleton) && (collision.getBundleDescription().isSingleton()) && (collision.isResolvable()))
          {
            collisionCandidates.add(collision);
            capabilities.add(getIdentity(collision));
          }
        }
        if (hook != null) {
          hook.filterSingletonCollisions(getIdentity(singleton), asCapabilities(new ArrayMap(capabilities, collisionCandidates)));
        }
        result.put(singleton, collisionCandidates);
      }
    }
    return result;
  }
  
  private BundleCapability getIdentity(ResolverBundle bundle)
  {
    List<BundleCapability> identities = bundle.getBundleDescription().getDeclaredCapabilities("osgi.identity");
    return identities.size() == 1 ? (BundleCapability)identities.get(0) : bundle.getCapability();
  }
  
  private void resolveBundles0(ResolverBundle[] bundles, Dictionary<Object, Object>[] platformProperties)
  {
    if (developmentMode) {
      Arrays.sort(bundles);
    }
    Collection<String> processedFragments = new HashSet(bundles.length);
    for (int i = 0; i < bundles.length; i++) {
      attachFragment(bundles[i], processedFragments);
    }
    List<ResolverBundle> cycle = new ArrayList(1);
    for (int i = 0; i < bundles.length; i++)
    {
      if (DEBUG) {
        log("** RESOLVING " + bundles[i] + " **");
      }
      cycle.clear();
      resolveBundle(bundles[i], cycle);
      
      checkCycle(cycle);
    }
    if (unresolvedBundles.size() > 0)
    {
      ResolverBundle[] unresolved = (ResolverBundle[])unresolvedBundles.toArray(new ResolverBundle[unresolvedBundles.size()]);
      for (int i = 0; i < unresolved.length; i++) {
        resolveFragment(unresolved[i]);
      }
    }
    checkUsesConstraints(bundles, platformProperties);
    checkComposites(bundles, platformProperties);
  }
  
  private void checkComposites(ResolverBundle[] bundles, Dictionary<Object, Object>[] platformProperties)
  {
    CompositeResolveHelperRegistry helpers = getCompositeHelpers();
    if (helpers == null) {
      return;
    }
    Set<ResolverBundle> exclude = null;
    for (int i = 0; i < bundles.length; i++)
    {
      CompositeResolveHelper helper = helpers.getCompositeResolveHelper(bundles[i].getBundleDescription());
      if (helper != null) {
        if (bundles[i].isResolved()) {
          if (!helper.giveExports(getExportsWiredTo(bundles[i], null)))
          {
            state.addResolverError(bundles[i].getBundleDescription(), 262144, null, null);
            bundles[i].setResolvable(false);
            
            setBundleUnresolved(bundles[i], false, false);
            if (exclude == null) {
              exclude = new HashSet(1);
            }
            exclude.add(bundles[i]);
          }
        }
      }
    }
    reResolveBundles(exclude, bundles, platformProperties);
  }
  
  private void checkUsesConstraints(ResolverBundle[] bundles, Dictionary<Object, Object>[] platformProperties)
  {
    List<ResolverConstraint> conflictingConstraints = findBestCombination(bundles, platformProperties);
    if (conflictingConstraints == null) {
      return;
    }
    Set<ResolverBundle> conflictedBundles = null;
    for (Iterator localIterator = conflictingConstraints.iterator(); localIterator.hasNext();)
    {
      ResolverConstraint conflict = (ResolverConstraint)localIterator.next();
      if (conflict.isOptional())
      {
        conflict.clearPossibleSuppliers();
      }
      else
      {
        if (conflictedBundles == null) {
          conflictedBundles = new HashSet(conflictingConstraints.size());
        }
        ResolverBundle conflictedBundle;
        ResolverBundle conflictedBundle;
        if (conflict.isFromFragment()) {
          conflictedBundle = (ResolverBundle)bundleMapping.get(conflict.getVersionConstraint().getBundle());
        } else {
          conflictedBundle = conflict.getBundle();
        }
        if (conflictedBundle != null)
        {
          if (DEBUG_USES) {
            System.out.println("Found conflicting constraint: " + conflict + " in bundle " + conflictedBundle);
          }
          conflictedBundles.add(conflictedBundle);
          int type = (conflict instanceof ResolverImport) ? 32 : 64;
          state.addResolverError(conflictedBundle.getBundleDescription(), type, conflict.getVersionConstraint().toString(), conflict.getVersionConstraint());
          conflictedBundle.setResolvable(false);
          
          setBundleUnresolved(conflictedBundle, false, false);
        }
      }
    }
    reResolveBundles(conflictedBundles, bundles, platformProperties);
  }
  
  private void reResolveBundles(Set<ResolverBundle> exclude, ResolverBundle[] bundles, Dictionary<Object, Object>[] platformProperties)
  {
    if ((exclude == null) || (exclude.size() == 0)) {
      return;
    }
    List<ResolverBundle> remainingUnresolved = new ArrayList();
    for (int i = 0; i < bundles.length; i++) {
      if (!exclude.contains(bundles[i]))
      {
        setBundleUnresolved(bundles[i], false, false);
        remainingUnresolved.add(bundles[i]);
      }
    }
    resolveBundles0((ResolverBundle[])remainingUnresolved.toArray(new ResolverBundle[remainingUnresolved.size()]), platformProperties);
  }
  
  private List<ResolverConstraint> findBestCombination(ResolverBundle[] bundles, Dictionary<Object, Object>[] platformProperties)
  {
    Object usesMode = platformProperties.length == 0 ? null : platformProperties[0].get("osgi.resolver.usesMode");
    if (usesMode == null) {
      usesMode = secureAction.getProperty("osgi.resolver.usesMode");
    }
    if (("ignore".equals(usesMode)) || (developmentMode)) {
      return null;
    }
    Set<String> bundleConstraints = new HashSet();
    Set<String> packageConstraints = new HashSet();
    
    List<ResolverConstraint> initialConflicts = getConflicts(bundles, packageConstraints, bundleConstraints);
    if ((initialConflicts == null) || ("tryFirst".equals(usesMode)) || (usesCalculationTimeout))
    {
      groupingChecker.clear();
      
      return initialConflicts;
    }
    ResolverConstraint[][] multipleSuppliers = getMultipleSuppliers(bundles, packageConstraints, bundleConstraints);
    List<ResolverConstraint> conflicts = null;
    int[] bestCombination = new int[multipleSuppliers.length];
    conflicts = findBestCombination(bundles, multipleSuppliers, bestCombination, initialConflicts);
    if (DEBUG_USES)
    {
      System.out.print("Best combination found: ");
      printCombination(bestCombination);
    }
    for (int i = 0; i < bestCombination.length; i++) {
      for (int j = 0; j < multipleSuppliers[i].length; j++)
      {
        ResolverConstraint constraint = multipleSuppliers[i][j];
        constraint.setSelectedSupplier(bestCombination[i]);
        
        VersionSupplier selectedSupplier = constraint.getSelectedSupplier();
        if (selectedSupplier != null) {
          selectedSupplier.setSubstitute(null);
        }
      }
    }
    groupingChecker.clear();
    return conflicts;
  }
  
  private int[] getCombination(ResolverConstraint[][] multipleSuppliers, int[] combination)
  {
    for (int i = 0; i < combination.length; i++) {
      combination[i] = multipleSuppliers[i][0].getSelectedSupplierIndex();
    }
    return combination;
  }
  
  private List<ResolverConstraint> findBestCombination(ResolverBundle[] bundles, ResolverConstraint[][] multipleSuppliers, int[] bestCombination, List<ResolverConstraint> bestConflicts)
  {
    long initialTime = System.currentTimeMillis();
    long timeLimit;
    long timeLimit;
    if (usesTimeout < 0L) {
      timeLimit = Math.min(MAX_USES_TIME_BASE + bundles.length * 30, MAX_USES_TIME_LIMIT);
    } else {
      timeLimit = usesTimeout;
    }
    int bestConflictCount = getConflictCount(bestConflicts);
    ResolverBundle[] bestConflictBundles = getConflictedBundles(bestConflicts);
    while ((bestConflictCount != 0) && (getNextCombination(multipleSuppliers)))
    {
      if (System.currentTimeMillis() - initialTime > timeLimit)
      {
        if (DEBUG_USES) {
          System.out.println("Uses constraint check has timedout.  Using the best solution found so far.");
        }
        usesCalculationTimeout = true;
        break;
      }
      if (DEBUG_USES) {
        printCombination(getCombination(multipleSuppliers, new int[multipleSuppliers.length]));
      }
      List<ResolverConstraint> conflicts = getConflicts(bestConflictBundles, null, null);
      int conflictCount = getConflictCount(conflicts);
      if (conflictCount >= bestConflictCount)
      {
        if (DEBUG_USES) {
          System.out.println("Combination is not better that current best: " + conflictCount + ">=" + bestConflictCount);
        }
      }
      else
      {
        conflicts = getConflicts(bundles, null, null);
        conflictCount = getConflictCount(conflicts);
        if (conflictCount < bestConflictCount)
        {
          bestConflictCount = conflictCount;
          bestConflicts = conflicts;
          getCombination(multipleSuppliers, bestCombination);
          bestConflictBundles = getConflictedBundles(bestConflicts);
          if (DEBUG_USES) {
            System.out.println("Combination selected as current best: number of conflicts: " + bestConflictCount);
          }
        }
        else if (DEBUG_USES)
        {
          System.out.println("Combination is not better that current best: " + conflictCount + ">=" + bestConflictCount);
        }
      }
    }
    return bestConflicts;
  }
  
  private void printCombination(int[] curCombination)
  {
    StringBuffer sb = new StringBuffer();
    sb.append('[');
    for (int i = 0; i < curCombination.length; i++)
    {
      sb.append(curCombination[i]);
      if (i < curCombination.length - 1) {
        sb.append(',');
      }
    }
    sb.append(']');
    System.out.println(sb.toString());
  }
  
  private ResolverBundle[] getConflictedBundles(List<ResolverConstraint> bestConflicts)
  {
    if (bestConflicts == null) {
      return new ResolverBundle[0];
    }
    List<ResolverBundle> conflictedBundles = new ArrayList(bestConflicts.size());
    for (Iterator localIterator = bestConflicts.iterator(); localIterator.hasNext();)
    {
      ResolverConstraint constraint = (ResolverConstraint)localIterator.next();
      if (!conflictedBundles.contains(constraint.getBundle())) {
        conflictedBundles.add(constraint.getBundle());
      }
    }
    return (ResolverBundle[])conflictedBundles.toArray(new ResolverBundle[conflictedBundles.size()]);
  }
  
  private boolean getNextCombination(ResolverConstraint[][] multipleSuppliers)
  {
    int current = 0;
    while (current < multipleSuppliers.length)
    {
      if (multipleSuppliers[current][0].selectNextSupplier())
      {
        for (int i = 1; i < multipleSuppliers[current].length; i++) {
          multipleSuppliers[current][i].selectNextSupplier();
        }
        return true;
      }
      for (int i = 0; i < multipleSuppliers[current].length; i++) {
        multipleSuppliers[current][i].setSelectedSupplier(0);
      }
      current++;
    }
    return false;
  }
  
  private int getConflictCount(List<ResolverConstraint> conflicts)
  {
    if ((conflicts == null) || (conflicts.size() == 0)) {
      return 0;
    }
    int result = 0;
    for (Iterator localIterator = conflicts.iterator(); localIterator.hasNext();)
    {
      ResolverConstraint constraint = (ResolverConstraint)localIterator.next();
      if (!constraint.isOptional()) {
        result++;
      }
    }
    return result;
  }
  
  private List<ResolverConstraint> getConflicts(ResolverBundle[] bundles, Set<String> packageConstraints, Set<String> bundleConstraints)
  {
    groupingChecker.clear();
    List<ResolverConstraint> conflicts = null;
    for (int i = 0; i < bundles.length; i++) {
      conflicts = addConflicts(bundles[i], packageConstraints, bundleConstraints, conflicts);
    }
    return conflicts;
  }
  
  private List<ResolverConstraint> addConflicts(ResolverBundle bundle, Set<String> packageConstraints, Set<String> bundleConstraints, List<ResolverConstraint> conflicts)
  {
    BundleConstraint[] requires = bundle.getRequires();
    for (int i = 0; i < requires.length; i++)
    {
      ResolverBundle selectedSupplier = (ResolverBundle)requires[i].getSelectedSupplier();
      GroupingChecker.PackageRoots[][] conflict = selectedSupplier == null ? null : groupingChecker.isConsistent(bundle, selectedSupplier);
      if (conflict != null)
      {
        addConflictNames(conflict, packageConstraints, bundleConstraints);
        if (conflicts == null) {
          conflicts = new ArrayList(1);
        }
        conflicts.add(requires[i]);
      }
    }
    ResolverImport[] imports = bundle.getImportPackages();
    for (int i = 0; i < imports.length; i++)
    {
      ResolverExport selectedSupplier = (ResolverExport)imports[i].getSelectedSupplier();
      conflict = selectedSupplier == null ? null : groupingChecker.isConsistent(bundle, selectedSupplier);
      if (conflict != null)
      {
        addConflictNames(conflict, packageConstraints, bundleConstraints);
        if (conflicts == null) {
          conflicts = new ArrayList(1);
        }
        conflicts.add(imports[i]);
      }
    }
    GenericConstraint[] genericRequires = bundle.getGenericRequires();
    GenericConstraint[] arrayOfGenericConstraint1;
    GroupingChecker.PackageRoots[][] arrayOfPackageRoots1 = (arrayOfGenericConstraint1 = genericRequires).length;
    for (GroupingChecker.PackageRoots[][] conflict = 0; conflict < arrayOfPackageRoots1; conflict++)
    {
      GenericConstraint capabilityRequirement = arrayOfGenericConstraint1[conflict];
      VersionSupplier[] suppliers = capabilityRequirement.getMatchingCapabilities();
      if (suppliers != null)
      {
        VersionSupplier[] arrayOfVersionSupplier1;
        int j = (arrayOfVersionSupplier1 = suppliers).length;
        for (int i = 0; i < j; i++)
        {
          VersionSupplier supplier = arrayOfVersionSupplier1[i];
          GroupingChecker.PackageRoots[][] conflict = groupingChecker.isConsistent(bundle, (GenericCapability)supplier);
          if (conflict != null)
          {
            addConflictNames(conflict, packageConstraints, bundleConstraints);
            if (conflicts == null) {
              conflicts = new ArrayList(1);
            }
            conflicts.add(capabilityRequirement);
          }
        }
      }
    }
    return conflicts;
  }
  
  private void addConflictNames(GroupingChecker.PackageRoots[][] conflict, Set<String> packageConstraints, Set<String> bundleConstraints)
  {
    if ((packageConstraints == null) || (bundleConstraints == null)) {
      return;
    }
    for (int i = 0; i < conflict.length; i++)
    {
      packageConstraints.add(conflict[i][0].getName());
      packageConstraints.add(conflict[i][1].getName());
      ResolverExport[] exports0 = conflict[i][0].getRoots();
      if (exports0 != null) {
        for (int j = 0; j < exports0.length; j++)
        {
          ResolverBundle exporter = exports0[j].getExporter();
          if ((exporter != null) && (exporter.getName() != null)) {
            bundleConstraints.add(exporter.getName());
          }
        }
      }
      ResolverExport[] exports1 = conflict[i][1].getRoots();
      if (exports1 != null) {
        for (int j = 0; j < exports1.length; j++)
        {
          ResolverBundle exporter = exports1[j].getExporter();
          if ((exporter != null) && (exporter.getName() != null)) {
            bundleConstraints.add(exporter.getName());
          }
        }
      }
    }
  }
  
  private ResolverConstraint[][] getMultipleSuppliers(ResolverBundle[] bundles, Set<String> packageConstraints, Set<String> bundleConstraints)
  {
    List<ResolverImport> multipleImportSupplierList = new ArrayList(1);
    List<BundleConstraint> multipleRequireSupplierList = new ArrayList(1);
    List<GenericConstraint> multipleGenericSupplierList = new ArrayList(1);
    Object localObject1;
    int j = (localObject1 = bundles).length;
    BundleConstraint[] requires;
    ResolverImport[] imports;
    Object genericRequires;
    for (int i = 0; i < j; i++)
    {
      ResolverBundle bundle = localObject1[i];
      requires = bundle.getRequires();
      BundleConstraint[] arrayOfBundleConstraint1;
      int m = (arrayOfBundleConstraint1 = requires).length;
      for (int k = 0; k < m; k++)
      {
        BundleConstraint require = arrayOfBundleConstraint1[k];
        if (require.getNumPossibleSuppliers() > 1) {
          multipleRequireSupplierList.add(require);
        }
      }
      imports = bundle.getImportPackages();
      ResolverImport[] arrayOfResolverImport1;
      int n = (arrayOfResolverImport1 = imports).length;
      Integer eeProfile;
      for (m = 0; m < n; m++)
      {
        ResolverImport importPkg = arrayOfResolverImport1[m];
        if (importPkg.getNumPossibleSuppliers() > 1)
        {
          eeProfile = (Integer)((ResolverExport)importPkg.getSelectedSupplier()).getExportPackageDescription().getDirective("x-equinox-ee");
          if (eeProfile.intValue() < 0)
          {
            multipleImportSupplierList.add(importPkg);
          }
          else
          {
            VersionSupplier[] suppliers = importPkg.getPossibleSuppliers();
            for (int suppliersIndex = 1; suppliersIndex < suppliers.length; suppliersIndex++)
            {
              Integer ee = (Integer)((ResolverExport)suppliers[suppliersIndex]).getExportPackageDescription().getDirective("x-equinox-ee");
              if (ee.intValue() < 0) {
                if ((((ResolverExport)suppliers[suppliersIndex]).getExporter().getRequire(getSystemBundle()) == null) && 
                  (((ResolverExport)suppliers[suppliersIndex]).getExporter().getRequire("system.bundle") == null))
                {
                  multipleImportSupplierList.add(importPkg);
                  break;
                }
              }
            }
          }
        }
      }
      genericRequires = bundle.getGenericRequires();
      int i1 = (eeProfile = genericRequires).length;
      for (n = 0; n < i1; n++)
      {
        GenericConstraint genericRequire = eeProfile[n];
        if ((genericRequire.getNumPossibleSuppliers() > 1) && (genericRequire.supplierHasUses())) {
          multipleGenericSupplierList.add(genericRequire);
        }
      }
    }
    List<ResolverConstraint[]> results = new ArrayList();
    Object multipleRequireSupplierMaps;
    if (multipleImportSupplierList.size() + multipleRequireSupplierList.size() + multipleGenericSupplierList.size() > usesMultipleSuppliersLimit)
    {
      Object multipleImportSupplierMaps = new HashMap();
      for (localObject1 = multipleImportSupplierList.iterator(); ((Iterator)localObject1).hasNext();)
      {
        ResolverImport importPkg = (ResolverImport)((Iterator)localObject1).next();
        addMutipleSupplierConstraint((Map)multipleImportSupplierMaps, importPkg, importPkg.getName());
      }
      multipleRequireSupplierMaps = new HashMap();
      for (requires = multipleRequireSupplierList.iterator(); requires.hasNext();)
      {
        BundleConstraint requireBundle = (BundleConstraint)requires.next();
        addMutipleSupplierConstraint((Map)multipleRequireSupplierMaps, requireBundle, requireBundle.getName());
      }
      Object multipleGenericSupplierMaps = new HashMap();
      for (imports = multipleGenericSupplierList.iterator(); imports.hasNext();)
      {
        GenericConstraint genericRequire = (GenericConstraint)imports.next();
        addMutipleSupplierConstraint((Map)multipleGenericSupplierMaps, genericRequire, genericRequire.getNameSpace());
      }
      addMergedSuppliers(results, (Map)multipleImportSupplierMaps);
      addMergedSuppliers(results, (Map)multipleRequireSupplierMaps);
      addMergedSuppliers(results, (Map)multipleGenericSupplierMaps);
      if ((results.size() > usesMultipleSuppliersLimit) && (packageConstraints != null) && (bundleConstraints != null))
      {
        List<ResolverConstraint[]> tooBig = results;
        results = new ArrayList();
        for (genericRequires = tooBig.iterator(); ((Iterator)genericRequires).hasNext();)
        {
          ResolverConstraint[] constraints = (ResolverConstraint[])((Iterator)genericRequires).next();
          ResolverConstraint constraint = constraints.length > 0 ? constraints[0] : null;
          if ((constraint instanceof ResolverImport))
          {
            if (packageConstraints.contains(constraint.getName())) {
              results.add(constraints);
            }
          }
          else if (((constraint instanceof BundleConstraint)) && 
            (bundleConstraints.contains(constraint.getName()))) {
            results.add(constraints);
          }
        }
      }
    }
    else
    {
      for (multipleRequireSupplierMaps = multipleImportSupplierList.iterator(); ((Iterator)multipleRequireSupplierMaps).hasNext();)
      {
        ResolverConstraint constraint = (ResolverConstraint)((Iterator)multipleRequireSupplierMaps).next();
        results.add(new ResolverConstraint[] { constraint });
      }
      for (multipleRequireSupplierMaps = multipleRequireSupplierList.iterator(); ((Iterator)multipleRequireSupplierMaps).hasNext();)
      {
        ResolverConstraint constraint = (ResolverConstraint)((Iterator)multipleRequireSupplierMaps).next();
        results.add(new ResolverConstraint[] { constraint });
      }
      for (multipleRequireSupplierMaps = multipleGenericSupplierList.iterator(); ((Iterator)multipleRequireSupplierMaps).hasNext();)
      {
        ResolverConstraint constraint = (ResolverConstraint)((Iterator)multipleRequireSupplierMaps).next();
        results.add(new ResolverConstraint[] { constraint });
      }
    }
    return (ResolverConstraint[][])results.toArray(new ResolverConstraint[results.size()][]);
  }
  
  String getSystemBundle()
  {
    Dictionary[] platformProperties = state.getPlatformProperties();
    String systemBundle = platformProperties.length == 0 ? null : (String)platformProperties[0].get("osgi.system.bundle");
    if (systemBundle == null) {
      systemBundle = Constants.getInternalSymbolicName();
    }
    return systemBundle;
  }
  
  private void addMergedSuppliers(List<ResolverConstraint[]> mergedSuppliers, Map<String, List<List<ResolverConstraint>>> constraints)
  {
    Iterator localIterator2;
    for (Iterator localIterator1 = constraints.values().iterator(); localIterator1.hasNext(); localIterator2.hasNext())
    {
      List<List<ResolverConstraint>> mergedConstraintLists = (List)localIterator1.next();
      localIterator2 = mergedConstraintLists.iterator(); continue;List<ResolverConstraint> constraintList = (List)localIterator2.next();
      mergedSuppliers.add((ResolverConstraint[])constraintList.toArray(new ResolverConstraint[constraintList.size()]));
    }
  }
  
  private void addMutipleSupplierConstraint(Map<String, List<List<ResolverConstraint>>> constraints, ResolverConstraint constraint, String key)
  {
    List<List<ResolverConstraint>> mergedConstraintLists = (List)constraints.get(key);
    if (mergedConstraintLists == null)
    {
      mergedConstraintLists = new ArrayList(0);
      List<ResolverConstraint> constraintList = new ArrayList(1);
      constraintList.add(constraint);
      mergedConstraintLists.add(constraintList);
      constraints.put(key, mergedConstraintLists);
      return;
    }
    for (Iterator localIterator = mergedConstraintLists.iterator(); localIterator.hasNext();)
    {
      List<ResolverConstraint> constraintList = (List)localIterator.next();
      ResolverConstraint mergedConstraint = (ResolverConstraint)constraintList.get(0);
      VersionSupplier[] suppliers1 = constraint.getPossibleSuppliers();
      VersionSupplier[] suppliers2 = mergedConstraint.getPossibleSuppliers();
      if (suppliers1.length == suppliers2.length)
      {
        for (int i = 0; i < suppliers1.length; i++) {
          if (suppliers1[i] == suppliers2[i]) {}
        }
        constraintList.add(constraint);
        return;
      }
    }
    List<ResolverConstraint> constraintList = new ArrayList(1);
    constraintList.add(constraint);
    mergedConstraintLists.add(constraintList);
  }
  
  private void checkCycle(List<ResolverBundle> cycle)
  {
    int cycleSize = cycle.size();
    if (cycleSize == 0) {
      return;
    }
    for (Iterator<ResolverBundle> iCycle = cycle.iterator(); iCycle.hasNext();)
    {
      ResolverBundle cycleBundle = (ResolverBundle)iCycle.next();
      if (!cycleBundle.isResolvable())
      {
        iCycle.remove();
      }
      else
      {
        ResolverImport[] imports = cycleBundle.getImportPackages();
        for (int j = 0; j < imports.length; j++)
        {
          while (imports[j].getSelectedSupplier() != null)
          {
            ResolverExport importSupplier = (ResolverExport)imports[j].getSelectedSupplier();
            if (importSupplier.getSubstitute() == null) {
              break;
            }
            imports[j].selectNextSupplier();
          }
          if ((!imports[j].isDynamic()) && (!imports[j].isOptional()) && (imports[j].getSelectedSupplier() == null))
          {
            cycleBundle.setResolvable(false);
            state.addResolverError(imports[j].getVersionConstraint().getBundle(), 1, imports[j].getVersionConstraint().toString(), imports[j].getVersionConstraint());
            iCycle.remove();
            break;
          }
        }
      }
    }
    if (cycle.size() != cycleSize)
    {
      for (int i = 0; i < cycle.size(); i++)
      {
        ResolverBundle cycleBundle = (ResolverBundle)cycle.get(i);
        cycleBundle.clearWires();
      }
      List<ResolverBundle> innerCycle = new ArrayList(cycle.size());
      for (int i = 0; i < cycle.size(); i++) {
        resolveBundle((ResolverBundle)cycle.get(i), innerCycle);
      }
      checkCycle(innerCycle);
    }
    else
    {
      for (int i = 0; i < cycle.size(); i++)
      {
        if ((DEBUG) || (DEBUG_CYCLES)) {
          log("Pushing " + cycle.get(i) + " to RESOLVED");
        }
        setBundleResolved((ResolverBundle)cycle.get(i));
      }
    }
  }
  
  static Collection<BundleCapability> asCapabilities(Collection<? extends BundleCapability> capabilities)
  {
    return capabilities;
  }
  
  private void resolveFragment(ResolverBundle fragment)
  {
    if (!fragment.isFragment()) {
      return;
    }
    if ((fragment.getHost().getNumPossibleSuppliers() > 0) && (
      (!developmentMode) || (state.getResolverErrors(fragment.getBundleDescription()).length == 0))) {
      setBundleResolved(fragment);
    }
  }
  
  private boolean resolveBundle(ResolverBundle bundle, List<ResolverBundle> cycle)
  {
    if (bundle.isFragment()) {
      return false;
    }
    if (!bundle.isResolvable())
    {
      if (DEBUG) {
        log("  - " + bundle + " is unresolvable");
      }
      return false;
    }
    switch (bundle.getState())
    {
    case 2: 
      if (DEBUG) {
        log("  - " + bundle + " already resolved");
      }
      return true;
    case 0: 
      bundle.clearWires();
      setBundleResolving(bundle);
      break;
    case 1: 
      if (cycle.contains(bundle)) {
        return true;
      }
      break;
    }
    boolean failed = false;
    if (!failed)
    {
      GenericConstraint[] genericRequires = bundle.getGenericRequires();
      for (int i = 0; i < genericRequires.length; i++) {
        if (genericRequires[i].isEffective()) {
          if (!resolveGenericReq(genericRequires[i], cycle))
          {
            if ((DEBUG) || (DEBUG_GENERICS)) {
              log("** GENERICS " + genericRequires[i].getVersionConstraint().getName() + "[" + genericRequires[i].getBundleDescription() + "] failed to resolve");
            }
            state.addResolverError(genericRequires[i].getVersionConstraint().getBundle(), 32768, genericRequires[i].getVersionConstraint().toString(), genericRequires[i].getVersionConstraint());
            if (genericRequires[i].isFromFragment())
            {
              if (!developmentMode) {
                bundle.detachFragment((ResolverBundle)bundleMapping.get(genericRequires[i].getVersionConstraint().getBundle()), null);
              }
            }
            else if (!developmentMode)
            {
              failed = true;
              break;
            }
          }
          else if ("osgi.ee".equals(genericRequires[i].getNameSpace()))
          {
            VersionSupplier supplier = genericRequires[i].getSelectedSupplier();
            Integer ee = supplier == null ? null : (Integer)((GenericDescription)supplier.getBaseDescription()).getAttributes().get("x-equinox-ee");
            if ((ee != null) && (((BundleDescriptionImpl)bundle.getBaseDescription()).getEquinoxEE() < 0)) {
              ((BundleDescriptionImpl)bundle.getBundleDescription()).setEquinoxEE(ee.intValue());
            }
          }
        }
      }
    }
    if (!failed)
    {
      BundleConstraint[] requires = bundle.getRequires();
      for (int i = 0; i < requires.length; i++) {
        if (!resolveRequire(requires[i], cycle))
        {
          if ((DEBUG) || (DEBUG_REQUIRES)) {
            log("** REQUIRE " + requires[i].getVersionConstraint().getName() + "[" + requires[i].getBundleDescription() + "] failed to resolve");
          }
          state.addResolverError(requires[i].getVersionConstraint().getBundle(), 2, requires[i].getVersionConstraint().toString(), requires[i].getVersionConstraint());
          if (requires[i].isFromFragment())
          {
            if (!developmentMode) {
              bundle.detachFragment((ResolverBundle)bundleMapping.get(requires[i].getVersionConstraint().getBundle()), requires[i]);
            }
          }
          else if (!developmentMode)
          {
            failed = true;
            break;
          }
        }
      }
    }
    if (!failed)
    {
      ResolverImport[] imports = bundle.getImportPackages();
      for (int i = 0; i < imports.length; i++) {
        if ((!imports[i].isDynamic()) && (!resolveImport(imports[i], cycle)))
        {
          if ((DEBUG) || (DEBUG_IMPORTS)) {
            log("** IMPORT " + imports[i].getName() + "[" + imports[i].getBundleDescription() + "] failed to resolve");
          }
          state.addResolverError(imports[i].getVersionConstraint().getBundle(), 1, imports[i].getVersionConstraint().toString(), imports[i].getVersionConstraint());
          if (imports[i].isFromFragment())
          {
            if (!developmentMode) {
              bundle.detachFragment((ResolverBundle)bundleMapping.get(imports[i].getVersionConstraint().getBundle()), imports[i]);
            }
          }
          else if (!developmentMode)
          {
            failed = true;
            break;
          }
        }
      }
    }
    checkFragmentConstraints(bundle);
    if ((developmentMode) && (!failed) && (state.getResolverErrors(bundle.getBundleDescription()).length > 0)) {
      failed = true;
    }
    if (failed)
    {
      setBundleUnresolved(bundle, false, developmentMode);
      if (DEBUG) {
        log(bundle + " NOT RESOLVED");
      }
    }
    else if (!cycle.contains(bundle))
    {
      setBundleResolved(bundle);
      if (DEBUG) {
        log(bundle + " RESOLVED");
      }
    }
    if (bundle.getState() == 0) {
      bundle.setResolvable(false);
    }
    return bundle.getState() != 0;
  }
  
  private void checkFragmentConstraints(ResolverBundle bundle)
  {
    ResolverBundle[] fragments = bundle.getFragments();
    for (int i = 0; i < fragments.length; i++)
    {
      BundleDescription fragment = fragments[i].getBundleDescription();
      if ((bundle.constraintsConflict(fragment, fragment.getImportPackages(), fragment.getRequiredBundles(), fragment.getGenericRequires())) && (!developmentMode)) {
        bundle.detachFragment(fragments[i], null);
      }
    }
  }
  
  private boolean resolveGenericReq(GenericConstraint constraint, List<ResolverBundle> cycle)
  {
    if (DEBUG_GENERICS) {
      log("Trying to resolve: " + constraint.getBundle() + ", " + constraint.getVersionConstraint());
    }
    VersionSupplier matchingCapability = constraint.getSelectedSupplier();
    if (matchingCapability != null)
    {
      if (!cycle.contains(constraint.getBundle()))
      {
        cycle.add(constraint.getBundle());
        if (DEBUG_CYCLES) {
          log("generic cycle: " + constraint.getBundle() + " -> " + constraint.getSelectedSupplier());
        }
      }
      if (DEBUG_GENERICS) {
        log("  - already wired");
      }
      return true;
    }
    long timestamp;
    List<GenericCapability> candidates;
    do
    {
      timestamp = state.getTimeStamp();
      VersionHashMap<GenericCapability> namespace = (VersionHashMap)resolverGenerics.get(constraint.getNameSpace());
      String name = constraint.getName();
      List<GenericCapability> capabilities;
      if (namespace == null) {
        capabilities = Collections.EMPTY_LIST;
      } else {
        capabilities = (name == null) || (name.indexOf('*') >= 0) ? namespace.getAllValues() : namespace.get(name);
      }
      candidates = new ArrayList(capabilities);
      List<BundleCapability> genCapabilities = new ArrayList(candidates.size());
      for (Iterator<GenericCapability> iCandidates = candidates.iterator(); iCandidates.hasNext();)
      {
        GenericCapability capability = (GenericCapability)iCandidates.next();
        if (!constraint.isSatisfiedBy(capability)) {
          iCandidates.remove();
        } else {
          genCapabilities.add(capability.getCapability());
        }
      }
      if (hook != null) {
        hook.filterMatches(constraint.getRequirement(), asCapabilities(new ArrayMap(genCapabilities, candidates)));
      }
    } while (timestamp != state.getTimeStamp());
    boolean result = false;
    for (List<GenericCapability> capabilities = candidates.iterator(); capabilities.hasNext();)
    {
      GenericCapability capability = (GenericCapability)capabilities.next();
      if (DEBUG_GENERICS) {
        log("CHECKING GENERICS: " + capability.getBaseDescription());
      }
      constraint.addPossibleSupplier(capability);
      if (constraint.getBundle() == capability.getResolverBundle())
      {
        result = true;
      }
      else
      {
        VersionSupplier[] capabilityHosts = { capability.getResolverBundle().isFragment() ? capability.getResolverBundle().getHost().getPossibleSuppliers() : capability.getResolverBundle() };
        boolean foundResolvedMatch = false;
        for (int i = 0; (capabilityHosts != null) && (i < capabilityHosts.length); i++)
        {
          ResolverBundle capabilitySupplier = capabilityHosts[i].getResolverBundle();
          if (capabilitySupplier == constraint.getBundle())
          {
            foundResolvedMatch = true;
          }
          else
          {
            boolean successfulResolve = false;
            if (capabilitySupplier.getState() != 2) {
              if (!"osgi.ee".equals(constraint.getNameSpace())) {
                successfulResolve = resolveBundle(capabilitySupplier, cycle);
              }
            }
            if ((capabilitySupplier.getState() == 2) || (successfulResolve) || (developmentMode))
            {
              foundResolvedMatch |= !capability.getResolverBundle().isFragment();
              if ((capabilitySupplier.getState() == 1) && 
                (!cycle.contains(capabilitySupplier))) {
                cycle.add(capabilitySupplier);
              }
            }
          }
        }
        if (!foundResolvedMatch)
        {
          constraint.removePossibleSupplier(capability);
        }
        else
        {
          if (DEBUG_GENERICS) {
            log("Found match: " + capability.getBaseDescription() + ". Wiring");
          }
          result = true;
        }
      }
    }
    return result;
  }
  
  private boolean resolveRequire(BundleConstraint req, List<ResolverBundle> cycle)
  {
    if (DEBUG_REQUIRES) {
      log("Trying to resolve: " + req.getBundle() + ", " + req.getVersionConstraint());
    }
    if (req.getSelectedSupplier() != null)
    {
      if (!cycle.contains(req.getBundle()))
      {
        cycle.add(req.getBundle());
        if (DEBUG_CYCLES) {
          log("require-bundle cycle: " + req.getBundle() + " -> " + req.getSelectedSupplier());
        }
      }
      if (DEBUG_REQUIRES) {
        log("  - already wired");
      }
      return true;
    }
    long timestamp;
    List<ResolverBundle> candidates;
    do
    {
      timestamp = state.getTimeStamp();
      List<ResolverBundle> bundles = resolverBundles.get(req.getVersionConstraint().getName());
      candidates = new ArrayList(bundles);
      List<BundleCapability> capabilities = new ArrayList(candidates.size());
      for (iCandidates = candidates.iterator(); iCandidates.hasNext();)
      {
        ResolverBundle bundle = (ResolverBundle)iCandidates.next();
        if (!req.isSatisfiedBy(bundle)) {
          iCandidates.remove();
        } else {
          capabilities.add(bundle.getCapability());
        }
      }
      if (hook != null) {
        hook.filterMatches(req.getRequirement(), asCapabilities(new ArrayMap(capabilities, candidates)));
      }
    } while (timestamp != state.getTimeStamp());
    boolean result = false;
    for (Iterator<ResolverBundle> iCandidates = candidates.iterator(); iCandidates.hasNext();)
    {
      ResolverBundle bundle = (ResolverBundle)iCandidates.next();
      if (DEBUG_REQUIRES) {
        log("CHECKING: " + bundle.getBundleDescription());
      }
      req.addPossibleSupplier(bundle);
      if (req.getBundle() != bundle) {
        if ((bundle.getState() != 2) && (!resolveBundle(bundle, cycle)) && (!developmentMode))
        {
          req.removePossibleSupplier(bundle);
          continue;
        }
      }
      if ((req.getBundle() != bundle) && 
        (bundle.getState() == 1)) {
        if (!cycle.contains(req.getBundle()))
        {
          cycle.add(req.getBundle());
          if (DEBUG_CYCLES) {
            log("require-bundle cycle: " + req.getBundle() + " -> " + req.getSelectedSupplier());
          }
        }
      }
      if (DEBUG_REQUIRES) {
        log("Found match: " + bundle.getBundleDescription() + ". Wiring");
      }
      result = true;
    }
    if ((result) || (req.isOptional())) {
      return true;
    }
    return false;
  }
  
  private boolean resolveImport(ResolverImport imp, List<ResolverBundle> cycle)
  {
    if (DEBUG_IMPORTS) {
      log("Trying to resolve: " + imp.getBundle() + ", " + imp.getName());
    }
    if (imp.getSelectedSupplier() != null)
    {
      if (!cycle.contains(imp.getBundle()))
      {
        cycle.add(imp.getBundle());
        if (DEBUG_CYCLES) {
          log("import-package cycle: " + imp.getBundle() + " -> " + imp.getSelectedSupplier() + " from " + imp.getSelectedSupplier().getBundleDescription());
        }
      }
      if (DEBUG_IMPORTS) {
        log("  - already wired");
      }
      return true;
    }
    boolean result = false;
    ResolverExport[] substitutableExps = imp.getBundle().getExports(imp.getName());
    long timestamp;
    List<ResolverExport> candidates;
    do
    {
      timestamp = state.getTimeStamp();
      List<ResolverExport> exports = resolverExports.get(imp.getName());
      candidates = new ArrayList(exports);
      capabilities = new ArrayList(candidates.size());
      for (Iterator<ResolverExport> iCandidates = candidates.iterator(); iCandidates.hasNext();)
      {
        ResolverExport export = (ResolverExport)iCandidates.next();
        if (!imp.isSatisfiedBy(export)) {
          iCandidates.remove();
        } else {
          capabilities.add(export.getCapability());
        }
  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2019. Infinite Loop Ltd