org.eclipse.osgi_3.7.2.v20120110-1415

2: ifnull +145 -> 467
    //   325: new 761	java/util/ArrayList
    //   328: dup
    //   329: aload_0
    //   330: getfield 1407	org/eclipse/osgi/internal/module/ResolverImpl:unresolvedBundles	Ljava/util/HashSet;
    //   333: invokespecial 1445	java/util/ArrayList:<init>	(Ljava/util/Collection;)V
    //   336: astore 6
    //   338: new 761	java/util/ArrayList
    //   341: dup
    //   342: aload 6
    //   344: invokeinterface 1689 1 0
    //   349: invokespecial 1443	java/util/ArrayList:<init>	(I)V
    //   352: astore 7
    //   354: aload 6
    //   356: invokeinterface 1695 1 0
    //   361: astore 9
    //   363: goto +28 -> 391
    //   366: aload 9
    //   368: invokeinterface 1688 1 0
    //   373: checkcast 789	org/eclipse/osgi/internal/module/ResolverBundle
    //   376: astore 8
    //   378: aload 7
    //   380: aload 8
    //   382: invokevirtual 1548	org/eclipse/osgi/internal/module/ResolverBundle:getBundleDescription	()Lorg/eclipse/osgi/service/resolver/BundleDescription;
    //   385: invokeinterface 1693 2 0
    //   390: pop
    //   391: aload 9
    //   393: invokeinterface 1687 1 0
    //   398: ifne -32 -> 366
    //   401: new 779	org/eclipse/osgi/internal/baseadaptor/ArrayMap
    //   404: dup
    //   405: aload 7
    //   407: aload 6
    //   409: invokespecial 1471	org/eclipse/osgi/internal/baseadaptor/ArrayMap:<init>	(Ljava/util/List;Ljava/util/List;)V
    //   412: astore 8
    //   414: aload 6
    //   416: invokeinterface 1689 1 0
    //   421: istore 9
    //   423: aload_0
    //   424: getfield 1417	org/eclipse/osgi/internal/module/ResolverImpl:hook	Lorg/osgi/framework/hooks/resolver/ResolverHook;
    //   427: aload 8
    //   429: invokeinterface 1758 2 0
    //   434: aload 8
    //   436: invokevirtual 1470	org/eclipse/osgi/internal/baseadaptor/ArrayMap:size	()I
    //   439: iload 9
    //   441: if_icmpge +26 -> 467
    //   444: new 761	java/util/ArrayList
    //   447: dup
    //   448: aload_0
    //   449: getfield 1407	org/eclipse/osgi/internal/module/ResolverImpl:unresolvedBundles	Ljava/util/HashSet;
    //   452: invokespecial 1445	java/util/ArrayList:<init>	(Ljava/util/Collection;)V
    //   455: astore 5
    //   457: aload 5
    //   459: aload 6
    //   461: invokeinterface 1683 2 0
    //   466: pop
    //   467: aload_0
    //   468: getfield 1407	org/eclipse/osgi/internal/module/ResolverImpl:unresolvedBundles	Ljava/util/HashSet;
    //   471: aload_0
    //   472: getfield 1407	org/eclipse/osgi/internal/module/ResolverImpl:unresolvedBundles	Ljava/util/HashSet;
    //   475: invokevirtual 1456	java/util/HashSet:size	()I
    //   478: anewarray 789	org/eclipse/osgi/internal/module/ResolverBundle
    //   481: invokevirtual 1462	java/util/HashSet:toArray	([Ljava/lang/Object;)[Ljava/lang/Object;
    //   484: checkcast 744	[Lorg/eclipse/osgi/internal/module/ResolverBundle;
    //   487: astore 6
    //   489: aload_0
    //   490: iconst_0
    //   491: putfield 1403	org/eclipse/osgi/internal/module/ResolverImpl:usesCalculationTimeout	Z
    //   494: aload_0
    //   495: aload 6
    //   497: aload_2
    //   498: aload 5
    //   500: invokespecial 1630	org/eclipse/osgi/internal/module/ResolverImpl:resolveBundles	([Lorg/eclipse/osgi/internal/module/ResolverBundle;[Ljava/util/Dictionary;Ljava/util/Collection;)V
    //   503: aload_0
    //   504: getfield 1415	org/eclipse/osgi/internal/module/ResolverImpl:resolverExports	Lorg/eclipse/osgi/internal/module/VersionHashMap;
    //   507: invokevirtual 1660	org/eclipse/osgi/internal/module/VersionHashMap:reorder	()V
    //   510: aload_0
    //   511: getfield 1414	org/eclipse/osgi/internal/module/ResolverImpl:resolverBundles	Lorg/eclipse/osgi/internal/module/VersionHashMap;
    //   514: invokevirtual 1660	org/eclipse/osgi/internal/module/VersionHashMap:reorder	()V
    //   517: aload_0
    //   518: invokespecial 1577	org/eclipse/osgi/internal/module/ResolverImpl:reorderGenerics	()V
    //   521: iload_3
    //   522: ifeq +9 -> 531
    //   525: aload_0
    //   526: aload 4
    //   528: invokespecial 1600	org/eclipse/osgi/internal/module/ResolverImpl:resolveOptionalConstraints	([Lorg/eclipse/osgi/internal/module/ResolverBundle;)V
    //   531: getstatic 1394	org/eclipse/osgi/internal/module/ResolverImpl:DEBUG	Z
    //   534: ifeq +22 -> 556
    //   537: ldc_w 693
    //   540: invokestatic 1582	org/eclipse/osgi/internal/module/ResolverImpl:log	(Ljava/lang/String;)V
    //   543: goto +13 -> 556
    //   546: astore 10
    //   548: aload_0
    //   549: aconst_null
    //   550: putfield 1417	org/eclipse/osgi/internal/module/ResolverImpl:hook	Lorg/osgi/framework/hooks/resolver/ResolverHook;
    //   553: aload 10
    //   555: athrow
    //   556: aload_0
    //   557: aconst_null
    //   558: putfield 1417	org/eclipse/osgi/internal/module/ResolverImpl:hook	Lorg/osgi/framework/hooks/resolver/ResolverHook;
    //   561: return
    // Line number table:
    //   Java source line #377	-> byte code offset #0
    //   Java source line #378	-> byte code offset #6
    //   Java source line #379	-> byte code offset #12
    //   Java source line #380	-> byte code offset #19
    //   Java source line #382	-> byte code offset #30
    //   Java source line #383	-> byte code offset #37
    //   Java source line #384	-> byte code offset #41
    //   Java source line #387	-> byte code offset #69
    //   Java source line #390	-> byte code offset #97
    //   Java source line #391	-> byte code offset #116
    //   Java source line #392	-> byte code offset #140
    //   Java source line #393	-> byte code offset #141
    //   Java source line #395	-> byte code offset #148
    //   Java source line #397	-> byte code offset #154
    //   Java source line #398	-> byte code offset #158
    //   Java source line #399	-> byte code offset #163
    //   Java source line #400	-> byte code offset #178
    //   Java source line #401	-> byte code offset #183
    //   Java source line #398	-> byte code offset #190
    //   Java source line #404	-> byte code offset #199
    //   Java source line #405	-> byte code offset #206
    //   Java source line #406	-> byte code offset #213
    //   Java source line #408	-> byte code offset #217
    //   Java source line #409	-> byte code offset #222
    //   Java source line #410	-> byte code offset #247
    //   Java source line #411	-> byte code offset #253
    //   Java source line #412	-> byte code offset #257
    //   Java source line #413	-> byte code offset #268
    //   Java source line #414	-> byte code offset #276
    //   Java source line #415	-> byte code offset #282
    //   Java source line #414	-> byte code offset #302
    //   Java source line #419	-> byte code offset #313
    //   Java source line #420	-> byte code offset #318
    //   Java source line #421	-> byte code offset #325
    //   Java source line #422	-> byte code offset #338
    //   Java source line #423	-> byte code offset #354
    //   Java source line #424	-> byte code offset #378
    //   Java source line #423	-> byte code offset #391
    //   Java source line #425	-> byte code offset #401
    //   Java source line #426	-> byte code offset #414
    //   Java source line #427	-> byte code offset #423
    //   Java source line #428	-> byte code offset #434
    //   Java source line #429	-> byte code offset #444
    //   Java source line #430	-> byte code offset #457
    //   Java source line #434	-> byte code offset #467
    //   Java source line #436	-> byte code offset #489
    //   Java source line #437	-> byte code offset #494
    //   Java source line #439	-> byte code offset #503
    //   Java source line #440	-> byte code offset #510
    //   Java source line #441	-> byte code offset #517
    //   Java source line #442	-> byte code offset #521
    //   Java source line #443	-> byte code offset #525
    //   Java source line #444	-> byte code offset #531
    //   Java source line #445	-> byte code offset #537
    //   Java source line #446	-> byte code offset #546
    //   Java source line #447	-> byte code offset #548
    //   Java source line #448	-> byte code offset #553
    //   Java source line #447	-> byte code offset #556
    //   Java source line #449	-> byte code offset #561
    // Local variable table:
    //   start	length	slot	name	signature
    //   0	562	0	this	ResolverImpl
    //   0	562	1	reRefresh	BundleDescription[]
    //   0	562	2	platformProperties	Dictionary[]
    //   115	13	3	timeout	Object
    //   159	35	3	i	int
    //   246	276	3	resolveOptional	boolean
    //   176	9	4	rb	ResolverBundle
    //   251	276	4	currentlyResolved	ResolverBundle[]
    //   266	42	5	resolvedBundles	BundleDescription[]
    //   316	183	5	hookDisabled	Collection<ResolverBundle>
    //   277	29	6	i	int
    //   336	124	6	resolvableBundles	List<ResolverBundle>
    //   487	9	6	bundles	ResolverBundle[]
    //   352	54	7	resolvableRevisions	List<org.osgi.framework.wiring.BundleRevision>
    //   376	5	8	bundle	ResolverBundle
    //   412	23	8	resolvable	ArrayMap<org.osgi.framework.wiring.BundleRevision, ResolverBundle>
    //   361	31	9	localIterator	Iterator
    //   421	21	9	size	int
    //   546	8	10	localObject1	Object
    //   140	1	19	localNumberFormatException	NumberFormatException
    // Exception table:
    //   from	to	target	type
    //   97	137	140	java/lang/NumberFormatException
    //   69	546	546	finally
  }
  
  private BundleDescription[] addDevConstraints(BundleDescription[] reRefresh)
  {
    if (!developmentMode) {
      return reRefresh;
    }
    Set<BundleDescription> additionalRefresh = new HashSet();
    ResolverBundle[] unresolved = (ResolverBundle[])unresolvedBundles.toArray(new ResolverBundle[unresolvedBundles.size()]);
    for (int i = 0; i < unresolved.length; i++)
    {
      addUnresolvedWithDependents(unresolved[i], additionalRefresh);
      addHostsFromFragmentConstraints(unresolved[i], additionalRefresh);
    }
    if (additionalRefresh.size() == 0) {
      return reRefresh;
    }
    if (reRefresh != null) {
      for (int i = 0; i < reRefresh.length; i++) {
        additionalRefresh.add(reRefresh[i]);
      }
    }
    return (BundleDescription[])additionalRefresh.toArray(new BundleDescription[additionalRefresh.size()]);
  }
  
  private void addUnresolvedWithDependents(ResolverBundle unresolved, Set<BundleDescription> additionalRefresh)
  {
    BundleDescription[] dependents = unresolved.getBundleDescription().getDependents();
    if (dependents.length > 0) {
      additionalRefresh.add(unresolved.getBundleDescription());
    }
  }
  
  private void addHostsFromFragmentConstraints(ResolverBundle unresolved, Set<BundleDescription> additionalRefresh)
  {
    if (!unresolved.isFragment()) {
      return;
    }
    ImportPackageSpecification[] newImports = unresolved.getBundleDescription().getImportPackages();
    BundleSpecification[] newRequires = unresolved.getBundleDescription().getRequiredBundles();
    if ((newImports.length == 0) && (newRequires.length == 0)) {
      return;
    }
    BundleConstraint hostConstraint = unresolved.getHost();
    List<ResolverBundle> hosts = resolverBundles.get(hostConstraint.getVersionConstraint().getName());
    for (Iterator localIterator = hosts.iterator(); localIterator.hasNext();)
    {
      ResolverBundle host = (ResolverBundle)localIterator.next();
      if ((hostConstraint.isSatisfiedBy(host)) && (host.isResolved())) {
        additionalRefresh.add(host.getBundleDescription());
      }
    }
  }
  
  private void resolveOptionalConstraints(ResolverBundle[] bundles)
  {
    for (int i = 0; i < bundles.length; i++) {
      if (bundles[i] != null) {
        resolveOptionalConstraints(bundles[i]);
      }
    }
  }
  
  private void resolveOptionalConstraints(ResolverBundle bundle)
  {
    BundleConstraint[] requires = bundle.getRequires();
    List<ResolverBundle> cycle = new ArrayList();
    boolean resolvedOptional = false;
    for (int i = 0; i < requires.length; i++) {
      if ((requires[i].isOptional()) && (requires[i].getSelectedSupplier() == null))
      {
        cycle.clear();
        resolveRequire(requires[i], cycle);
        if (requires[i].getSelectedSupplier() != null) {
          resolvedOptional = true;
        }
      }
    }
    ResolverImport[] imports = bundle.getImportPackages();
    for (int i = 0; i < imports.length; i++) {
      if ((imports[i].isOptional()) && (imports[i].getSelectedSupplier() == null))
      {
        cycle.clear();
        resolveImport(imports[i], cycle);
        if (imports[i].getSelectedSupplier() != null) {
          resolvedOptional = true;
        }
      }
    }
    if (resolvedOptional)
    {
      state.resolveBundle(bundle.getBundleDescription(), false, null, null, null, null, null, null, null, null);
      stateResolveConstraints(bundle);
      stateResolveBundle(bundle);
    }
  }
  
  private void getCurrentEEs(Dictionary<Object, Object>[] platformProperties)
  {
    CURRENT_EES = new String[platformProperties.length][];
    for (int i = 0; i < platformProperties.length; i++)
    {
      String eeSpecs = (String)platformProperties[i].get("org.osgi.framework.executionenvironment");
      CURRENT_EES[i] = ManifestElement.getArrayFromList(eeSpecs, ",");
    }
  }
  
  private void resolveBundles(ResolverBundle[] bundles, Dictionary<Object, Object>[] platformProperties, Collection<ResolverBundle> hookDisabled)
  {
    ResolverBundle[] arrayOfResolverBundle;
    int j = (arrayOfResolverBundle = bundles).length;
    for (int i = 0; i < j; i++)
    {
      ResolverBundle bundle = arrayOfResolverBundle[i];
      state.removeResolverErrors(bundle.getBundleDescription());
      
      bundle.setResolvable((isResolvable(bundle, platformProperties, hookDisabled)) || (developmentMode));
    }
    selectSingletons(bundles);
    resolveBundles0(bundles, platformProperties);
    if (DEBUG_WIRING) {
      printWirings();
    }
    stateResolveBundles(bundles);
  }
  
  private void selectSingletons(ResolverBundle[] bundles)
  {
    if (developmentMode) {
      return;
    }
    Map<String, Collection<ResolverBundle>> selectedSingletons = new HashMap(bundles.length);
    ResolverBundle[] arrayOfResolverBundle;
    int j = (arrayOfResolverBundle = bundles).length;
    for (int i = 0; i < j; i++)
    {
      ResolverBundle bundle = arrayOfResolverBundle[i];
      if ((bundle.getBundleDescription().isSingleton()) && (bundle.isResolvable()))
      {
        String bsn = bundle.getName();
        Collection<ResolverBundle> selected = (Collection)selectedSingletons.get(bsn);
        if (selected == null)
        {
          selected = new ArrayList(1);
          selectedSingletons.put(bsn, selected);
          
          List<ResolverBundle> sameBSN = resolverBundles.get(bsn);
          if (sameBSN.size() < 2)
          {
            selected.add(bundle);
          }
          else
          {
            for (Iterator localIterator1 = sameBSN.iterator(); localIterator1.hasNext();)
            {
              ResolverBundle singleton = (ResolverBundle)localIterator1.next();
              if ((singleton.getBundleDescription().isSingleton()) && (singleton.getBundleDescription().isResolved())) {
                selected.add(singleton);
              }
            }
            Map<ResolverBundle, Collection<ResolverBundle>> collisionMap = getCollisionMap(sameBSN);
            for (Iterator localIterator2 = sameBSN.iterator(); localIterator2.hasNext();)
            {
              ResolverBundle singleton = (ResolverBundle)localIterator2.next();
              if (!selected.contains(singleton))
              {
                Collection<ResolverBundle> collisions = (Collection)collisionMap.get(singleton);
                if ((collisions != null) && (singleton.isResolvable()))
                {
                  Collection<ResolverBundle> pickOneToResolve = new ArrayList();
                  for (Iterator localIterator3 = collisions.iterator(); localIterator3.hasNext();)
                  {
                    ResolverBundle collision = (ResolverBundle)localIterator3.next();
                    if (selected.contains(collision))
                    {
                      singleton.setResolvable(false);
                      state.addResolverError(singleton.getBundleDescription(), 8, collision.getBundleDescription().toString(), null);
                      break;
                    }
                    if (!pickOneToResolve.contains(collision)) {
                      pickOneToResolve.add(collision);
                    }
                  }
                  for (localIterator3 = collisionMap.entrySet().iterator(); localIterator3.hasNext();)
                  {
                    Map.Entry<ResolverBundle, Collection<ResolverBundle>> collisionEntry = (Map.Entry)localIterator3.next();
                    if ((collisionEntry.getKey() != singleton) && (((Collection)collisionEntry.getValue()).contains(singleton)))
                    {
                      if (selected.contains(collisionEntry.getKey()))
                      {
                        singleton.setResolvable(false);
                        state.addResolverError(singleton.getBundleDescription(), 8, ((ResolverBundle)collisionEntry.getKey()).getBundleDescription().toString(), null);
                        break;
                      }
                      if (!pickOneToResolve.contains(collisionEntry.getKey())) {
                        pickOneToResolve.add((ResolverBundle)collisionEntry.getKey());
                      }
                    }
                  }
                  if (singleton.isResolvable())
                  {
                    pickOneToResolve.add(singleton);
                    selected.add(pickOneToResolve(pickOneToResolve));
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  
  private ResolverBundle pickOneToResolve(Collection<ResolverBundle> pickOneToResolve)
  {
    ResolverBundle selectedVersion = null;
    for (Iterator localIterator = pickOneToResolve.iterator(); localIterator.hasNext();)
    {
      ResolverBundle singleton = (ResolverBundle)localIterator.next();
      if (selectedVersion == null) {
        selectedVersion = singleton;
      }
      boolean higherVersion = selectionPolicy.compare(selectedVersion.getBundleDescription(), singleton.getBundleDescription()) > 0;
      if (higherVersion) {
        selectedVersion = singleton;
      }
    }
    for (localIterator = pickOneToResolve.iterator(); localIterator.hasNext();)
    {
      ResolverBundle singleton = (ResolverBundle)localIterator.next();
      if (singleton != selectedVersion)
      {
        singleton.setResolvable(false);
        state.addResolverError(singleton.getBundleDescription(), 8, selectedVersion.getBundleDescription().toString(), null);
      }
    }
    return selectedVersion;
  }
  
  private Map<ResolverBundle, Collection<ResolverBundle>> getCollisionMap(List<ResolverBundle> sameBSN)
  {
    Map<ResolverBundle, Collection<ResolverBundle>> result = new HashMap();
    for (Iterator localIterator1 = sameBSN.iterator(); localIterator1.hasNext();)
    {
      ResolverBundle singleton = (ResolverBundle)localIterator1.next();
      if ((singleton.getBundleDescription().isSingleton()) && (singleton.isResolvable()))
      {
        List<ResolverBundle> collisionCandidates = new ArrayList(sameBSN.size() - 1);
        List<BundleCapability> capabilities = new ArrayList(sameBSN.size() - 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(collision.getCapability());
          }
        }
        if (hook != null) {
          hook.filterSingletonCollisions(singleton.getCapability(), asCapabilities(new ArrayMap(capabilities, collisionCandidates)));
        }
        result.put(singleton, collisionCandidates);
      }
    }
    return result;
  }
  
  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++) {
        multipleSuppliers[i][j].setSelectedSupplier(bestCombination[i]);
      }
    }
    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 == 0L ? Long.MAX_VALUE : 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() > MAX_MULTIPLE_SUPPLIERS_MERGE)
    {
      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() > MAX_MULTIPLE_SUPPLIERS_MERGE) && (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);
          }
    
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

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