1 9 package org.eclipse.osgi.internal.module; 10 11 import java.util.*; 12 import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor; 13 import org.eclipse.osgi.framework.debug.Debug; 14 import org.eclipse.osgi.framework.debug.FrameworkDebugOptions; 15 import org.eclipse.osgi.internal.module.GroupingChecker.PackageRoots; 16 import org.eclipse.osgi.internal.resolver.BundleDescriptionImpl; 17 import org.eclipse.osgi.internal.resolver.ExportPackageDescriptionImpl; 18 import org.eclipse.osgi.service.resolver.*; 19 import org.eclipse.osgi.util.ManifestElement; 20 import org.osgi.framework.*; 21 22 public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver { 23 private static final String RESOLVER = FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME + "/resolver"; private static final String OPTION_DEBUG = RESOLVER + "/debug"; private static final String OPTION_WIRING = RESOLVER + "/wiring"; private static final String OPTION_IMPORTS = RESOLVER + "/imports"; private static final String OPTION_REQUIRES = RESOLVER + "/requires"; private static final String OPTION_GENERICS = RESOLVER + "/generics"; private static final String OPTION_GROUPING = RESOLVER + "/grouping"; private static final String OPTION_CYCLES = RESOLVER + "/cycles"; public static boolean DEBUG = false; 33 public static boolean DEBUG_WIRING = false; 34 public static boolean DEBUG_IMPORTS = false; 35 public static boolean DEBUG_REQUIRES = false; 36 public static boolean DEBUG_GENERICS = false; 37 public static boolean DEBUG_GROUPING = false; 38 public static boolean DEBUG_CYCLES = false; 39 private static int MAX_MULTIPLE_SUPPLIERS_MERGE = 10; 40 private static long MAX_COMBINATIONS = 1000000; 41 42 private static String [][] CURRENT_EES; 43 44 private State state; 46 private PermissionChecker permissionChecker; 48 private MappedList removalPending = new MappedList(); 50 private boolean initialized = false; 52 53 private VersionHashMap resolverExports = null; 55 private VersionHashMap resolverBundles = null; 57 private VersionHashMap resolverGenerics = null; 59 private ArrayList unresolvedBundles = null; private HashMap bundleMapping = null; 63 private GroupingChecker groupingChecker; 64 private Comparator selectionPolicy; 65 private boolean developmentMode = false; 66 67 public ResolverImpl(BundleContext context, boolean checkPermissions) { 68 this.permissionChecker = new PermissionChecker(context, checkPermissions, this); 69 } 70 71 PermissionChecker getPermissionChecker() { 72 return permissionChecker; 73 } 74 75 private void initialize() { 77 resolverExports = new VersionHashMap(this); 78 resolverBundles = new VersionHashMap(this); 79 resolverGenerics = new VersionHashMap(this); 80 unresolvedBundles = new ArrayList(); 81 bundleMapping = new HashMap(); 82 BundleDescription[] bundles = state.getBundles(); 83 groupingChecker = new GroupingChecker(); 84 85 ArrayList fragmentBundles = new ArrayList(); 86 for (int i = 0; i < bundles.length; i++) 88 initResolverBundle(bundles[i], fragmentBundles, false); 89 Object [] removedBundles = removalPending.getAllValues(); 91 for (int i = 0; i < removedBundles.length; i++) 92 initResolverBundle((BundleDescription) removedBundles[i], fragmentBundles, true); 93 for (Iterator iter = fragmentBundles.iterator(); iter.hasNext();) { 95 ResolverBundle fragment = (ResolverBundle) iter.next(); 96 BundleDescription[] hosts = ((HostSpecification) fragment.getHost().getVersionConstraint()).getHosts(); 97 for (int i = 0; i < hosts.length; i++) { 98 ResolverBundle host = (ResolverBundle) bundleMapping.get(hosts[i]); 99 if (host != null) 100 host.attachFragment(fragment, false); 102 } 103 } 104 rewireBundles(); setDebugOptions(); 106 initialized = true; 107 } 108 109 private void initResolverBundle(BundleDescription bundleDesc, ArrayList fragmentBundles, boolean pending) { 110 ResolverBundle bundle = new ResolverBundle(bundleDesc, this); 111 bundleMapping.put(bundleDesc, bundle); 112 if (!pending || bundleDesc.isResolved()) { 113 resolverExports.put(bundle.getExportPackages()); 114 resolverBundles.put(bundle.getName(), bundle); 115 resolverGenerics.put(bundle.getGenericCapabilities()); 116 } 117 if (bundleDesc.isResolved()) { 118 bundle.setState(ResolverBundle.RESOLVED); 119 if (bundleDesc.getHost() != null) 120 fragmentBundles.add(bundle); 121 } else { 122 if (!pending) 123 unresolvedBundles.add(bundle); 124 } 125 } 126 127 private void rewireBundles() { 129 ArrayList visited = new ArrayList(bundleMapping.size()); 130 for (Iterator iter = bundleMapping.values().iterator(); iter.hasNext();) { 131 ResolverBundle rb = (ResolverBundle) iter.next(); 132 if (!rb.getBundle().isResolved() || rb.isFragment()) 133 continue; 134 rewireBundle(rb, visited); 135 } 136 } 137 138 private void rewireBundle(ResolverBundle rb, ArrayList visited) { 139 if (visited.contains(rb)) 140 return; 141 visited.add(rb); 142 BundleConstraint[] requires = rb.getRequires(); 144 for (int i = 0; i < requires.length; i++) { 145 rewireRequire(requires[i], visited); 146 } 147 ResolverImport[] imports = rb.getImportPackages(); 149 for (int i = 0; i < imports.length; i++) { 150 rewireImport(imports[i], visited); 151 } 152 GenericConstraint[] genericRequires = rb.getGenericRequires(); 154 for (int i = 0; i < genericRequires.length; i++) 155 rewireGeneric(genericRequires[i], visited); 156 } 157 158 private void rewireGeneric(GenericConstraint constraint, ArrayList visited) { 159 if (constraint.getMatchingCapabilities() != null) 160 return; 161 GenericDescription[] suppliers = ((GenericSpecification) constraint.getVersionConstraint()).getSuppliers(); 162 if (suppliers == null) 163 return; 164 Object [] matches = resolverGenerics.get(constraint.getName()); 165 for (int i = 0; i < matches.length; i++) { 166 GenericCapability match = (GenericCapability) matches[i]; 167 for (int j = 0; j < suppliers.length; j++) 168 if (match.getBaseDescription() == suppliers[j]) 169 constraint.setMatchingCapability(match); 170 } 171 GenericCapability[] matchingCapabilities = constraint.getMatchingCapabilities(); 172 if (matchingCapabilities != null) 173 for (int i = 0; i < matchingCapabilities.length; i++) 174 rewireBundle(matchingCapabilities[i].getResolverBundle(), visited); 175 } 176 177 private void rewireRequire(BundleConstraint req, ArrayList visited) { 178 if (req.getSelectedSupplier() != null) 179 return; 180 ResolverBundle matchingBundle = (ResolverBundle) bundleMapping.get(req.getVersionConstraint().getSupplier()); 181 req.addPossibleSupplier(matchingBundle); 182 if (matchingBundle == null && !req.isOptional()) { 183 System.err.println("Could not find matching bundle for " + req.getVersionConstraint()); } 186 if (matchingBundle != null) { 187 rewireBundle(matchingBundle, visited); 188 } 189 } 190 191 private void rewireImport(ResolverImport imp, ArrayList visited) { 192 if (imp.isDynamic() || imp.getSelectedSupplier() != null) 193 return; 194 ResolverExport matchingExport = null; 196 ExportPackageDescription importSupplier = (ExportPackageDescription) imp.getVersionConstraint().getSupplier(); 197 ResolverBundle exporter = importSupplier == null ? null : (ResolverBundle) bundleMapping.get(importSupplier.getExporter()); 198 Object [] matches = resolverExports.get(imp.getName()); 199 for (int j = 0; j < matches.length; j++) { 200 ResolverExport export = (ResolverExport) matches[j]; 201 if (export.getExporter() == exporter && importSupplier == export.getExportPackageDescription()) { 202 matchingExport = export; 203 break; 204 } 205 } 206 imp.addPossibleSupplier(matchingExport); 207 if (matchingExport == null && exporter != null) { 209 ResolverExport reprovidedExport = new ResolverExport(exporter, importSupplier); 210 if (exporter.getExport(imp.getName()) == null) { 211 exporter.addExport(reprovidedExport); 212 resolverExports.put(reprovidedExport.getName(), reprovidedExport); 213 } 214 imp.addPossibleSupplier(reprovidedExport); 215 } 216 if (imp.getSelectedSupplier() == null && !imp.isOptional()) { 218 System.err.println("Could not find matching export for " + imp.getVersionConstraint()); } 221 if (imp.getSelectedSupplier() != null) { 222 rewireBundle(((ResolverExport) imp.getSelectedSupplier()).getExporter(), visited); 223 } 224 } 225 226 private boolean isResolvable(BundleDescription bundle, Dictionary[] platformProperties, ArrayList rejectedSingletons) { 229 if (rejectedSingletons.contains(bundle)) 231 return false; 232 if (bundle.isSingleton()) { 234 Object [] sameName = resolverBundles.get(bundle.getName()); 235 if (sameName.length > 1) for (int i = 0; i < sameName.length; i++) { 237 if (sameName[i] == bundle || !((ResolverBundle) sameName[i]).getBundle().isSingleton()) 238 continue; if (((ResolverBundle) sameName[i]).getBundle().isResolved()) { 240 rejectedSingletons.add(bundle); 241 return false; } 243 } 244 } 245 String [] ees = bundle.getExecutionEnvironments(); 247 boolean matchedEE = ees.length == 0; 248 if (!matchedEE) 249 for (int i = 0; i < ees.length && !matchedEE; i++) 250 for (int j = 0; j < CURRENT_EES.length && !matchedEE; j++) 251 for (int k = 0; k < CURRENT_EES[j].length && !matchedEE; k++) 252 if (CURRENT_EES[j][k].equals(ees[i])) { 253 ((BundleDescriptionImpl) bundle).setEquinoxEE(j); 254 matchedEE = true; 255 } 256 if (!matchedEE) { 257 StringBuffer bundleEE = new StringBuffer (Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT.length() + 20); 258 bundleEE.append(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT).append(": "); for (int i = 0; i < ees.length; i++) { 260 if (i > 0) 261 bundleEE.append(","); bundleEE.append(ees[i]); 263 } 264 state.addResolverError(bundle, ResolverError.MISSING_EXECUTION_ENVIRONMENT, bundleEE.toString(), null); 265 return false; 266 } 267 268 String platformFilter = bundle.getPlatformFilter(); 270 if (platformFilter == null) 271 return true; 272 if (platformProperties == null) 273 return false; 274 try { 275 Filter filter = FrameworkUtil.createFilter(platformFilter); 276 for (int i = 0; i < platformProperties.length; i++) 277 if (filter.matchCase(platformProperties[i])) 279 return true; 280 } catch (InvalidSyntaxException e) { 281 } 283 state.addResolverError(bundle, ResolverError.PLATFORM_FILTER, platformFilter, null); 284 return false; 285 } 286 287 private void attachFragment(ResolverBundle bundle, ArrayList rejectedSingletons) { 289 if (!bundle.isFragment() || !bundle.isResolvable() || rejectedSingletons.contains(bundle.getBundle())) 290 return; 291 boolean foundMatch = false; 294 BundleConstraint hostConstraint = bundle.getHost(); 295 Object [] hosts = resolverBundles.get(hostConstraint.getVersionConstraint().getName()); 296 for (int i = 0; i < hosts.length; i++) 297 if (((ResolverBundle) hosts[i]).isResolvable() && hostConstraint.isSatisfiedBy((ResolverBundle) hosts[i])) { 298 foundMatch = true; 299 resolverExports.put(((ResolverBundle) hosts[i]).attachFragment(bundle, true)); 300 } 301 if (!foundMatch) 302 state.addResolverError(bundle.getBundle(), ResolverError.MISSING_FRAGMENT_HOST, bundle.getHost().getVersionConstraint().toString(), bundle.getHost().getVersionConstraint()); 303 } 304 305 public synchronized void resolve(BundleDescription[] reRefresh, Dictionary[] platformProperties) { 306 if (DEBUG) 307 ResolverImpl.log("*** BEGIN RESOLUTION ***"); if (state == null) 309 throw new IllegalStateException ("RESOLVER_NO_STATE"); 311 if (!initialized) 312 initialize(); 313 developmentMode = platformProperties.length == 0 ? false : org.eclipse.osgi.framework.internal.core.Constants.DEVELOPMENT_MODE.equals(platformProperties[0].get(org.eclipse.osgi.framework.internal.core.Constants.OSGI_RESOLVER_MODE)); 314 reRefresh = addDevConstraints(reRefresh); 315 if (reRefresh != null) 317 for (int i = 0; i < reRefresh.length; i++) { 318 ResolverBundle rb = (ResolverBundle) bundleMapping.get(reRefresh[i]); 319 if (rb != null) 320 unresolveBundle(rb, false); 321 } 322 resolverExports.reorder(); 324 resolverBundles.reorder(); 325 resolverGenerics.reorder(); 326 getCurrentEEs(platformProperties); 328 ArrayList rejectedSingletons = new ArrayList(); 330 boolean resolveOptional = platformProperties.length == 0 ? false : "true".equals(platformProperties[0].get("osgi.resolveOptional")); ResolverBundle[] currentlyResolved = null; 332 if (resolveOptional) { 333 BundleDescription[] resolvedBundles = state.getResolvedBundles(); 334 currentlyResolved = new ResolverBundle[resolvedBundles.length]; 335 for (int i = 0; i < resolvedBundles.length; i++) 336 currentlyResolved[i] = (ResolverBundle) bundleMapping.get(resolvedBundles[i]); 337 } 338 ResolverBundle[] bundles = (ResolverBundle[]) unresolvedBundles.toArray(new ResolverBundle[unresolvedBundles.size()]); 340 resolveBundles(bundles, platformProperties, rejectedSingletons); 341 if (selectSingletons(bundles, rejectedSingletons)) { 342 bundles = (ResolverBundle[]) unresolvedBundles.toArray(new ResolverBundle[unresolvedBundles.size()]); 345 resolveBundles(bundles, platformProperties, rejectedSingletons); 346 } 347 for (Iterator rejected = rejectedSingletons.iterator(); rejected.hasNext();) { 348 BundleDescription reject = (BundleDescription) rejected.next(); 349 BundleDescription sameName = state.getBundle(reject.getSymbolicName(), null); 350 state.addResolverError(reject, ResolverError.SINGLETON_SELECTION, sameName.toString(), null); 351 } 352 if (resolveOptional) 353 resolveOptionalConstraints(currentlyResolved); 354 if (DEBUG) 355 ResolverImpl.log("*** END RESOLUTION ***"); } 357 358 private BundleDescription[] addDevConstraints(BundleDescription[] reRefresh) { 359 if (!developmentMode) 360 return reRefresh; HashSet additionalRefresh = new HashSet(); 364 ResolverBundle[] unresolved = (ResolverBundle[]) unresolvedBundles.toArray(new ResolverBundle[unresolvedBundles.size()]); 365 for (int i = 0; i < unresolved.length; i++) { 366 addUnresolvedWithDependents(unresolved[i], additionalRefresh); 367 addHostsFromFragmentConstraints(unresolved[i], additionalRefresh); 368 } 369 if (additionalRefresh.size() == 0) 370 return reRefresh; if (reRefresh != null) 373 for (int i = 0; i < reRefresh.length; i++) 374 additionalRefresh.add(reRefresh[i]); 375 return (BundleDescription[]) additionalRefresh.toArray(new BundleDescription[additionalRefresh.size()]); 376 } 377 378 private void addUnresolvedWithDependents(ResolverBundle unresolved, HashSet additionalRefresh) { 379 BundleDescription[] dependents = unresolved.getBundle().getDependents(); 380 if (dependents.length > 0) 381 additionalRefresh.add(unresolved.getBundle()); 382 } 383 384 private void addHostsFromFragmentConstraints(ResolverBundle unresolved, Set additionalRefresh) { 385 if (!unresolved.isFragment()) 386 return; 387 ImportPackageSpecification[] newImports = unresolved.getBundle().getImportPackages(); 388 BundleSpecification[] newRequires = unresolved.getBundle().getRequiredBundles(); 389 if (newImports.length == 0 && newRequires.length == 0) 390 return; BundleConstraint hostConstraint = unresolved.getHost(); 392 Object [] hosts = resolverBundles.get(hostConstraint.getVersionConstraint().getName()); 393 for (int j = 0; j < hosts.length; j++) 394 if (hostConstraint.isSatisfiedBy((ResolverBundle) hosts[j]) && ((ResolverBundle) hosts[j]).isResolved()) 395 additionalRefresh.add(((ResolverBundle) hosts[j]).getBundle()); 398 399 } 400 401 private void resolveOptionalConstraints(ResolverBundle[] bundles) { 402 for (int i = 0; i < bundles.length; i++) { 403 if (bundles[i] != null) 404 resolveOptionalConstraints(bundles[i]); 405 } 406 } 407 408 private void resolveOptionalConstraints(ResolverBundle bundle) { 410 BundleConstraint[] requires = bundle.getRequires(); 411 ArrayList cycle = new ArrayList(); 412 boolean resolvedOptional = false; 413 for (int i = 0; i < requires.length; i++) 414 if (requires[i].isOptional() && requires[i].getSelectedSupplier() == null) { 415 cycle.clear(); 416 resolveRequire(requires[i], cycle); 417 if (requires[i].getSelectedSupplier() != null) 418 resolvedOptional = true; 419 } 420 ResolverImport[] imports = bundle.getImportPackages(); 421 for (int i = 0; i < imports.length; i++) 422 if (imports[i].isOptional() && imports[i].getSelectedSupplier() == null) { 423 cycle.clear(); 424 resolveImport(imports[i], cycle); 425 if (imports[i].getSelectedSupplier() != null) 426 resolvedOptional = true; 427 } 428 if (resolvedOptional) { 429 state.resolveBundle(bundle.getBundle(), false, null, null, null, null); 430 stateResolveConstraints(bundle); 431 stateResolveBundle(bundle); 432 } 433 } 434 435 private void getCurrentEEs(Dictionary[] platformProperties) { 436 CURRENT_EES = new String [platformProperties.length][]; 437 for (int i = 0; i < platformProperties.length; i++) { 438 String eeSpecs = (String ) platformProperties[i].get(Constants.FRAMEWORK_EXECUTIONENVIRONMENT); 439 CURRENT_EES[i] = ManifestElement.getArrayFromList(eeSpecs, ","); } 441 } 442 443 private void resolveBundles(ResolverBundle[] bundles, Dictionary[] platformProperties, ArrayList rejectedSingletons) { 444 for (int i = 0; i < bundles.length; i++) { 447 state.removeResolverErrors(bundles[i].getBundle()); 448 bundles[i].setResolvable(isResolvable(bundles[i].getBundle(), platformProperties, rejectedSingletons) || developmentMode); 451 bundles[i].clearRefs(); 452 } 453 resolveBundles0(bundles, platformProperties, rejectedSingletons); 454 if (DEBUG_WIRING) 455 printWirings(); 456 stateResolveBundles(bundles); 458 } 459 460 private void resolveBundles0(ResolverBundle[] bundles, Dictionary[] platformProperties, ArrayList rejectedSingletons) { 461 if (developmentMode) 462 Arrays.sort(bundles); 464 for (int i = 0; i < bundles.length; i++) 466 attachFragment(bundles[i], rejectedSingletons); 467 468 ArrayList cycle = new ArrayList(1); for (int i = 0; i < bundles.length; i++) { 472 if (DEBUG) 473 ResolverImpl.log("** RESOLVING " + bundles[i] + " **"); cycle.clear(); 475 resolveBundle(bundles[i], cycle); 476 checkCycle(cycle); 479 } 480 if (unresolvedBundles.size() > 0) { 482 ResolverBundle[] unresolved = (ResolverBundle[]) unresolvedBundles.toArray(new ResolverBundle[unresolvedBundles.size()]); 483 for (int i = 0; i < unresolved.length; i++) 484 resolveFragment(unresolved[i]); 485 } 486 checkUsesConstraints(bundles, platformProperties, rejectedSingletons); 487 } 488 489 private void checkUsesConstraints(ResolverBundle[] bundles, Dictionary[] platformProperties, ArrayList rejectedSingletons) { 490 ArrayList conflictingConstraints = findBestCombination(bundles); 491 Set conflictedBundles = null; 492 if (conflictingConstraints != null) { 493 for (Iterator conflicts = conflictingConstraints.iterator(); conflicts.hasNext();) { 494 ResolverConstraint conflict = (ResolverConstraint) conflicts.next(); 495 if (conflict.isOptional()) { 496 conflict.clearPossibleSuppliers(); 497 continue; 498 } 499 conflictedBundles = new HashSet(conflictingConstraints.size()); 500 ResolverBundle conflictedBundle; 501 if (conflict.isFromFragment()) 502 conflictedBundle = (ResolverBundle) bundleMapping.get(conflict.getVersionConstraint().getBundle()); 503 else 504 conflictedBundle = conflict.getBundle(); 505 if (conflictedBundle != null) { 506 conflictedBundles.add(conflictedBundle); 507 int type = conflict instanceof ResolverImport ? ResolverError.IMPORT_PACKAGE_USES_CONFLICT : ResolverError.REQUIRE_BUNDLE_USES_CONFLICT; 508 state.addResolverError(conflictedBundle.getBundle(), type, conflict.getVersionConstraint().toString(), conflict.getVersionConstraint()); 509 conflictedBundle.setResolvable(false); 510 conflictedBundle.clearRefs(); 511 setBundleUnresolved(conflictedBundle, false, developmentMode); 512 } 513 } 514 if (conflictedBundles != null && conflictedBundles.size() > 0) { 515 ArrayList remainingUnresolved = new ArrayList(); 516 for (int i = 0; i < bundles.length; i++) { 517 if (!conflictedBundles.contains(bundles[i])) { 518 setBundleUnresolved(bundles[i], false, developmentMode); 519 remainingUnresolved.add(bundles[i]); 520 } 521 } 522 resolveBundles0((ResolverBundle[]) remainingUnresolved.toArray(new ResolverBundle[remainingUnresolved.size()]), platformProperties, rejectedSingletons); 523 } 524 } 525 } 526 527 private ArrayList findBestCombination(ResolverBundle[] bundles) { 528 HashSet bundleConstraints = new HashSet(); 529 HashSet packageConstraints = new HashSet(); 530 ArrayList initialConflicts = getConflicts(bundles, packageConstraints, bundleConstraints); 532 if (initialConflicts == null) { 533 groupingChecker.clear(); 534 return null; } 536 ResolverConstraint[][] multipleSuppliers = getMultipleSuppliers(bundles, packageConstraints, bundleConstraints); 537 ArrayList conflicts = null; 538 if (multipleSuppliers.length > 0 && getNumCombinations(multipleSuppliers) < MAX_COMBINATIONS) { 539 int[] bestCombination = new int[multipleSuppliers.length]; 540 conflicts = findBestCombination(bundles, multipleSuppliers, bestCombination, initialConflicts); 541 for (int i = 0; i < bestCombination.length; i++) { 542 for (int j = 0; j < multipleSuppliers[i].length; j++) 543 multipleSuppliers[i][j].setSelectedSupplier(bestCombination[i]); 544 } 545 } else { 546 conflicts = initialConflicts; 548 } 549 groupingChecker.clear(); 551 return conflicts; 552 } 553 554 private long getNumCombinations(ResolverConstraint[][] multipleSuppliers) { 555 if (multipleSuppliers == null || multipleSuppliers.length == 0) 556 return 0; 557 long numCombinations = multipleSuppliers[0][0].getNumPossibleSuppliers(); 558 for (int i = 1; i < multipleSuppliers.length; i++) 559 if (multipleSuppliers[i].length > 0) 560 numCombinations *= multipleSuppliers[i][0].getNumPossibleSuppliers(); 561 return numCombinations; 562 } 563 564 private int[] getCombination(ResolverConstraint[][] multipleSuppliers, int[] combination) { 565 for (int i = 0; i < combination.length; i++) 566 combination[i] = multipleSuppliers[i][0].getSelectedSupplierIndex(); 567 return combination; 568 } 569 570 private ArrayList findBestCombination(ResolverBundle[] bundles, ResolverConstraint[][] multipleSuppliers, int[] bestCombination, ArrayList bestConflicts) { 571 int bestConflictCount = getConflictCount(bestConflicts); 575 ResolverBundle[] bestConflictBundles = getConflictedBundles(bestConflicts); 576 while (bestConflictCount != 0 && getNextCombination(multipleSuppliers)) { 577 if (DEBUG_GROUPING) 578 printCombination(getCombination(multipleSuppliers, new int[multipleSuppliers.length])); 579 ArrayList conflicts = getConflicts(bestConflictBundles, null, null); 583 int conflictCount = getConflictCount(conflicts); 584 if (conflictCount >= bestConflictCount) 585 continue; 588 conflicts = getConflicts(bundles, null, null); 591 conflictCount = getConflictCount(conflicts); 592 if (conflictCount < bestConflictCount) { 593 bestConflictCount = conflictCount; 595 bestConflicts = conflicts; 596 getCombination(multipleSuppliers, bestCombination); 597 bestConflictBundles = getConflictedBundles(bestConflicts); 598 } 599 } 600 return bestConflicts; 601 } 602 603 private void printCombination(int[] curCombination) { 604 StringBuffer sb = new StringBuffer (); 605 sb.append('['); 606 for (int i = 0; i < curCombination.length; i++) { 607 sb.append(curCombination[i]); 608 if (i < curCombination.length - 1) 609 sb.append(','); 610 } 611 sb.append(']'); 612 System.out.println(sb.toString()); 613 } 614 615 private ResolverBundle[] getConflictedBundles(ArrayList bestConflicts) { 616 if (bestConflicts == null) 617 return new ResolverBundle[0]; 618 ArrayList conflictedBundles = new ArrayList(bestConflicts.size()); 619 for (Iterator iConflicts = bestConflicts.iterator(); iConflicts.hasNext();) { 620 ResolverConstraint constraint = (ResolverConstraint) iConflicts.next(); 621 if (!conflictedBundles.contains(constraint.getBundle())) 622 conflictedBundles.add(constraint.getBundle()); 623 } 624 return (ResolverBundle[]) conflictedBundles.toArray(new ResolverBundle[conflictedBundles.size()]); 625 } 626 627 private boolean getNextCombination(ResolverConstraint[][] multipleSuppliers) { 628 int current = 0; 629 while (current < multipleSuppliers.length) { 630 if (multipleSuppliers[current][0].selectNextSupplier()) { 631 for (int i = 1; i < multipleSuppliers[current].length; i++) 632 multipleSuppliers[current][i].selectNextSupplier(); 633 return true; } 635 for (int i = 0; i < multipleSuppliers[current].length; i++) 636 multipleSuppliers[current][i].setSelectedSupplier(0); current++; } 639 return false; 640 } 641 642 private int getConflictCount(ArrayList conflicts) { 644 if (conflicts == null || conflicts.size() == 0) 645 return 0; 646 int result = 0; 647 for (Iterator iConflicts = conflicts.iterator(); iConflicts.hasNext();) 648 if (!((ResolverConstraint) iConflicts.next()).isOptional()) 649 result += 1; 650 return result; 651 } 652 653 private ArrayList getConflicts(ResolverBundle[] bundles, HashSet packageConstraints, HashSet bundleConstraints) { 654 groupingChecker.clear(); 655 ArrayList conflicts = null; 656 for (int i = 0; i < bundles.length; i++) 657 conflicts = addConflicts(bundles[i], packageConstraints, bundleConstraints, conflicts); 658 return conflicts; 659 } 660 661 private ArrayList addConflicts(ResolverBundle bundle, HashSet packageConstraints, HashSet bundleConstraints, ArrayList conflicts) { 662 boolean foundConflict = false; 663 BundleConstraint[] requires = bundle.getRequires(); 664 for (int i = 0; i < requires.length; i++) { 665 ResolverBundle selectedSupplier = (ResolverBundle) requires[i].getSelectedSupplier(); 666 PackageRoots[][] conflict = selectedSupplier == null ? null : groupingChecker.isConsistent(bundle, selectedSupplier); 667 if (conflict != null) { 668 addConflictNames(conflict, packageConstraints, bundleConstraints); 669 if (!foundConflict) { 670 if (conflicts == null) 671 conflicts = new ArrayList(1); 672 conflicts.add(requires[i]); 673 foundConflict = !requires[i].isOptional(); } 675 } 676 } 677 ResolverImport[] imports = bundle.getImportPackages(); 678 for (int i = 0; i < imports.length; i++) { 679 ResolverExport selectedSupplier = (ResolverExport) imports[i].getSelectedSupplier(); 680 PackageRoots[][] conflict = selectedSupplier == null ? null : groupingChecker.isConsistent(bundle, selectedSupplier); 681 if (conflict != null) { 682 addConflictNames(conflict, packageConstraints, bundleConstraints); 683 if (!foundConflict) { 684 if (conflicts == null) 685 conflicts = new ArrayList(1); 686 conflicts.add(imports[i]); 687 foundConflict = !imports[i].isOptional(); } 689 } 690 } 691 return conflicts; 692 } 693 694 private void addConflictNames(PackageRoots[][] conflict, HashSet packageConstraints, HashSet bundleConstraints) { 696 if (packageConstraints == null || bundleConstraints == null) 697 return; 698 for (int i = 0; i < conflict.length; i++) { 699 packageConstraints.add(conflict[i][0].getName()); 700 packageConstraints.add(conflict[i][1].getName()); 701 ResolverExport[] exports0 = conflict[i][0].getRoots(); 702 if (exports0 != null) 703 for (int j = 0; j < exports0.length; j++) { 704 ResolverBundle exporter = exports0[j].getExporter(); 705 if (exporter != null && exporter.getName() != null) 706 bundleConstraints.add(exporter.getName()); 707 } 708 ResolverExport[] exports1 = conflict[i][1].getRoots(); 709 if (exports1 != null) 710 for (int j = 0; j < exports1.length; j++) { 711 ResolverBundle exporter = exports1[j].getExporter(); 712 if (exporter != null && exporter.getName() != null) 713 bundleConstraints.add(exporter.getName()); 714 } 715 } 716 } 717 718 private ResolverConstraint[][] getMultipleSuppliers(ResolverBundle[] bundles, HashSet packageConstraints, HashSet bundleConstraints) { 721 ArrayList multipleImportSupplierList = new ArrayList(1); 722 ArrayList multipleRequireSupplierList = new ArrayList(1); 723 for (int i = 0; i < bundles.length; i++) { 724 BundleConstraint[] requires = bundles[i].getRequires(); 725 for (int j = 0; j < requires.length; j++) 726 if (requires[j].getNumPossibleSuppliers() > 1) 727 multipleRequireSupplierList.add(requires[j]); 728 ResolverImport[] imports = bundles[i].getImportPackages(); 729 for (int j = 0; j < imports.length; j++) { 730 if (imports[j].getNumPossibleSuppliers() > 1) { 731 Integer eeProfile = (Integer ) ((ResolverExport) imports[j].getSelectedSupplier()).getExportPackageDescription().getDirective(ExportPackageDescriptionImpl.EQUINOX_EE); 732 if (eeProfile.intValue() < 0) { 733 multipleImportSupplierList.add(imports[j]); 735 } else { 736 VersionSupplier[] suppliers = imports[j].getPossibleSuppliers(); 742 for (int suppliersIndex = 1; suppliersIndex < suppliers.length; suppliersIndex++) { 743 Integer ee = (Integer ) ((ResolverExport) suppliers[suppliersIndex]).getExportPackageDescription().getDirective(ExportPackageDescriptionImpl.EQUINOX_EE); 744 if (ee.intValue() >= 0) 745 continue; 746 if (((ResolverExport) suppliers[suppliersIndex]).getExporter().getRequire(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME) == null) 747 if (((ResolverExport) suppliers[suppliersIndex]).getExporter().getRequire(Constants.SYSTEM_BUNDLE_SYMBOLICNAME) == null) { 748 multipleImportSupplierList.add(imports[j]); 749 break; 750 } 751 } 752 } 753 } 754 } 755 } 756 ArrayList results = new ArrayList(); 757 if (multipleImportSupplierList.size() + multipleRequireSupplierList.size() > MAX_MULTIPLE_SUPPLIERS_MERGE) { 758 HashMap multipleImportSupplierMaps = new HashMap(1); 761 for (Iterator iMultipleImportSuppliers = multipleImportSupplierList.iterator(); iMultipleImportSuppliers.hasNext();) 762 addMutipleSupplierConstraint(multipleImportSupplierMaps, (ResolverConstraint) iMultipleImportSuppliers.next()); 763 HashMap multipleRequireSupplierMaps = new HashMap(1); 764 for (Iterator iMultipleRequireSuppliers = multipleRequireSupplierList.iterator(); iMultipleRequireSuppliers.hasNext();) 765 addMutipleSupplierConstraint(multipleRequireSupplierMaps, (ResolverConstraint) iMultipleRequireSuppliers.next()); 766 addMergedSuppliers(results, multipleImportSupplierMaps); 767 addMergedSuppliers(results, multipleRequireSupplierMaps); 768 if (results.size() > MAX_MULTIPLE_SUPPLIERS_MERGE && packageConstraints != null && bundleConstraints != null) { 770 Iterator iResults = results.iterator(); 772 results = new ArrayList(); 773 while (iResults.hasNext()) { 774 ResolverConstraint[] constraints = (ResolverConstraint[]) iResults.next(); 775 ResolverConstraint constraint = constraints.length > 0 ? constraints[0] : null; 776 if (constraint instanceof ResolverImport) { 777 if (packageConstraints.contains(constraint.getName())) 778 results.add(constraints); 779 } else if (constraint instanceof BundleConstraint) { 780 if (bundleConstraints.contains(constraint.getName())) 781 results.add(constraints); 782 } 783 } 784 } 785 } else { 786 for (Iterator iMultipleImportSuppliers = multipleImportSupplierList.iterator(); iMultipleImportSuppliers.hasNext();) 788 results.add(new ResolverConstraint[] {(ResolverConstraint) iMultipleImportSuppliers.next()}); 789 for (Iterator iMultipleRequireSuppliers = multipleRequireSupplierList.iterator(); iMultipleRequireSuppliers.hasNext();) 790 results.add(new ResolverConstraint[] {(ResolverConstraint) iMultipleRequireSuppliers.next()}); 791 } 792 return (ResolverConstraint[][]) results.toArray(new ResolverConstraint[results.size()][]); 793 } 794 795 private void addMergedSuppliers(ArrayList mergedSuppliers, HashMap constraints) { 796 for (Iterator iConstraints = constraints.values().iterator(); iConstraints.hasNext();) { 797 ArrayList mergedConstraintLists = (ArrayList) iConstraints.next(); 798 for (Iterator mergedLists = mergedConstraintLists.iterator(); mergedLists.hasNext();) { 799 ArrayList constraintList = (ArrayList) mergedLists.next(); 800 mergedSuppliers.add(constraintList.toArray(new ResolverConstraint[constraintList.size()])); 801 } 802 } 803 } 804 805 private void addMutipleSupplierConstraint(HashMap constraints, ResolverConstraint constraint) { 806 ArrayList mergedConstraintLists = (ArrayList) constraints.get(constraint.getName()); 807 if (mergedConstraintLists == null) { 808 mergedConstraintLists = new ArrayList(1); 809 ArrayList constraintList = new ArrayList(1); 810 constraintList.add(constraint); 811 mergedConstraintLists.add(constraintList); 812 constraints.put(constraint.getName(), mergedConstraintLists); 813 return; 814 } 815 for (Iterator mergedLists = mergedConstraintLists.iterator(); mergedLists.hasNext();) { 816 ArrayList constraintList = (ArrayList) mergedLists.next(); 817 ResolverConstraint mergedConstraint = (ResolverConstraint) constraintList.get(0); 818 VersionSupplier[] suppliers1 = constraint.getPossibleSuppliers(); 819 VersionSupplier[] suppliers2 = mergedConstraint.getPossibleSuppliers(); 820 if (suppliers1.length != suppliers2.length) 821 continue; 822 for (int i = 0; i < suppliers1.length; i++) 823 if (suppliers1[i] != suppliers2[i]) 824 continue; 825 constraintList.add(constraint); 826 return; 827 } 828 ArrayList constraintList = new ArrayList(1); 829 constraintList.add(constraint); 830 mergedConstraintLists.add(constraintList); 831 } 832 833 private void checkCycle(ArrayList cycle) { 834 int cycleSize = cycle.size(); 835 if (cycleSize == 0) 836 return; 837 cycleLoop: for (Iterator iCycle = cycle.iterator(); iCycle.hasNext();) { 838 ResolverBundle cycleBundle = (ResolverBundle) iCycle.next(); 839 if (!cycleBundle.isResolvable()) { 840 iCycle.remove(); continue cycleLoop; 842 } 843 ResolverImport[] imports = cycleBundle.getImportPackages(); 845 for (int j = 0; j < imports.length; j++) { 846 while (imports[j].getSelectedSupplier() != null) { 848 ResolverExport importSupplier = (ResolverExport) imports[j].getSelectedSupplier(); 849 if (importSupplier.isDropped()) 850 imports[j].selectNextSupplier(); 851 else 852 break; 853 } 854 if (!imports[j].isDynamic() && !imports[j].isOptional() && imports[j].getSelectedSupplier() == null) { 855 cycleBundle.setResolvable(false); 856 cycleBundle.clearRefs(); 857 state.addResolverError(imports[j].getVersionConstraint().getBundle(), ResolverError.MISSING_IMPORT_PACKAGE, imports[j].getVersionConstraint().toString(), imports[j].getVersionConstraint()); 858 iCycle.remove(); 859 continue cycleLoop; 860 } 861 } 862 } 863 if (cycle.size() != cycleSize) { 864 for (int i = 0; i < cycle.size(); i++) { 866 ResolverBundle cycleBundle = (ResolverBundle) cycle.get(i); 867 cycleBundle.clearWires(); 868 cycleBundle.clearRefs(); 869 } 870 ArrayList innerCycle = new ArrayList(cycle.size()); 871 for (int i = 0; i < cycle.size(); i++) 872 resolveBundle((ResolverBundle) cycle.get(i), innerCycle); 873 checkCycle(innerCycle); 874 } else { 875 for (int i = 0; i < cycle.size(); i++) { 876 if (DEBUG || DEBUG_CYCLES) 877 ResolverImpl.log("Pushing " + cycle.get(i) + " to RESOLVED"); setBundleResolved((ResolverBundle) cycle.get(i)); 879 } 880 } 881 } 882 883 private boolean selectSingletons(ResolverBundle[] bundles, ArrayList rejectedSingletons) { 884 if (developmentMode) 885 return false; boolean result = false; 887 for (int i = 0; i < bundles.length; i++) { 888 BundleDescription bundleDesc = bundles[i].getBundle(); 889 if (!bundleDesc.isSingleton() || !bundleDesc.isResolved() || rejectedSingletons.contains(bundleDesc)) 890 continue; 891 Object [] sameName = resolverBundles.get(bundleDesc.getName()); 892 if (sameName.length > 1) { for (int j = 0; j < sameName.length; j++) { 894 BundleDescription sameNameDesc = ((VersionSupplier) sameName[j]).getBundle(); 895 ResolverBundle sameNameBundle = (ResolverBundle) sameName[j]; 896 if (sameName[j] == bundles[i] || !sameNameDesc.isSingleton() || !sameNameDesc.isResolved() || rejectedSingletons.contains(sameNameDesc)) 897 continue; result = true; 899 boolean rejectedPolicy = selectionPolicy != null ? selectionPolicy.compare(sameNameDesc, bundleDesc) < 0 : sameNameDesc.getVersion().compareTo(bundleDesc.getVersion()) > 0; 900 int sameNameRefs = sameNameBundle.getRefs(); 901 int curRefs = bundles[i].getRefs(); 902 if ((sameNameRefs == curRefs && rejectedPolicy) || sameNameRefs > curRefs) { 906 if (!rejectedSingletons.contains(bundles[i].getBundle())) 908 rejectedSingletons.add(bundles[i].getBundle()); 909 break; 910 } 911 if (!rejectedSingletons.contains(sameNameDesc)) 913 rejectedSingletons.add(sameNameDesc); 914 } 915 } 916 } 917 for (Iterator rejects = rejectedSingletons.iterator(); rejects.hasNext();) 919 unresolveBundle((ResolverBundle) bundleMapping.get(rejects.next()), false); 920 return result; 921 } 922 923 private void resolveFragment(ResolverBundle fragment) { 924 if (!fragment.isFragment()) 925 return; 926 if (fragment.getHost().getNumPossibleSuppliers() > 0) 927 if (!developmentMode || state.getResolverErrors(fragment.getBundle()).length == 0) 928 setBundleResolved(fragment); 929 } 930 931 private boolean resolveBundle(ResolverBundle bundle, ArrayList cycle) { 933 if (bundle.isFragment()) 934 return false; 935 if (!bundle.isResolvable()) { 936 if (DEBUG) 937 ResolverImpl.log(" - " + bundle + " is unresolvable"); return false; 939 } 940 switch (bundle.getState()) { 941 case ResolverBundle.RESOLVED : 942 if (DEBUG) 944 ResolverImpl.log(" - " + bundle + " already resolved"); return true; 946 case ResolverBundle.UNRESOLVED : 947 bundle.clearWires(); 949 setBundleResolving(bundle); 950 break; 951 case ResolverBundle.RESOLVING : 952 if (cycle.contains(bundle)) 953 return true; 954 break; 955 default : 956 break; 957 } 958 959 boolean failed = false; 960 961 if (!failed) { 962 GenericConstraint[] genericRequires = bundle.getGenericRequires(); 963 for (int i = 0; i < genericRequires.length; i++) { 964 if (!resolveGenericReq(genericRequires[i], cycle)) { 965 if (DEBUG || DEBUG_GENERICS) 966 ResolverImpl.log("** GENERICS " + genericRequires[i].getVersionConstraint().getName() + "[" + genericRequires[i].getBundleDescription() + "] failed to resolve"); state.addResolverError(genericRequires[i].getVersionConstraint().getBundle(), ResolverError.MISSING_GENERIC_CAPABILITY, genericRequires[i].getVersionConstraint().toString(), genericRequires[i].getVersionConstraint()); 968 if (genericRequires[i].isFromFragment()) { 969 if (!developmentMode) resolverExports.remove(bundle.detachFragment((ResolverBundle) bundleMapping.get(genericRequires[i].getVersionConstraint().getBundle()), null)); 971 continue; 972 } 973 if (!developmentMode) { 974 failed = true; 976 break; 977 } 978 } 979 } 980 } 981 982 if (!failed) { 983 BundleConstraint[] requires = bundle.getRequires(); 985 for (int i = 0; i < requires.length; i++) { 986 if (!resolveRequire(requires[i], cycle)) { 987 if (DEBUG || DEBUG_REQUIRES) 988 ResolverImpl.log("** REQUIRE " + requires[i].getVersionConstraint().getName() + "[" + requires[i].getBundleDescription() + "] failed to resolve"); state.addResolverError(requires[i].getVersionConstraint().getBundle(), ResolverError.MISSING_REQUIRE_BUNDLE, requires[i].getVersionConstraint().toString(), requires[i].getVersionConstraint()); 990 if (requires[i].isFromFragment()) { 992 if (!developmentMode) resolverExports.remove(bundle.detachFragment((ResolverBundle) bundleMapping.get(requires[i].getVersionConstraint().getBundle()), requires[i])); 994 continue; 995 } 996 if (!developmentMode) { 997 failed = true; 999 break; 1000 } 1001 } 1002 } 1003 } 1004 1005 if (!failed) { 1006 ResolverImport[] imports = bundle.getImportPackages(); 1008 for (int i = 0; i < imports.length; i++) { 1009 if (!imports[i].isDynamic() && !resolveImport(imports[i], cycle)) { 1011 if (DEBUG || DEBUG_IMPORTS) 1012 ResolverImpl.log("** IMPORT " + imports[i].getName() + "[" + imports[i].getBundleDescription() + "] failed to resolve"); state.addResolverError(imports[i].getVersionConstraint().getBundle(), ResolverError.MISSING_IMPORT_PACKAGE, imports[i].getVersionConstraint().toString(), imports[i].getVersionConstraint()); 1015 if (imports[i].isFromFragment()) { 1016 if (!developmentMode) resolverExports.remove(bundle.detachFragment((ResolverBundle) bundleMapping.get(imports[i].getVersionConstraint().getBundle()), imports[i])); 1018 continue; 1019 } 1020 if (!developmentMode) { 1021 failed = true; 1023 break; 1024 } 1025 } 1026 } 1027 } 1028 1029 checkFragmentConstraints(bundle); 1031 1032 if (developmentMode && !failed && state.getResolverErrors(bundle.getBundle()).length > 0) 1034 failed = true; 1035 1036 if (failed) { 1039 setBundleUnresolved(bundle, false, developmentMode); 1040 if (DEBUG) 1041 ResolverImpl.log(bundle + " NOT RESOLVED"); } else if (!cycle.contains(bundle)) { 1043 setBundleResolved(bundle); 1044 if (DEBUG) 1045 ResolverImpl.log(bundle + " RESOLVED"); } 1047 1048 if (bundle.getState() == ResolverBundle.UNRESOLVED) 1049 bundle.setResolvable(false); 1051 return bundle.getState() != ResolverBundle.UNRESOLVED; 1052 } 1053 1054 private void checkFragmentConstraints(ResolverBundle bundle) { 1055 ResolverBundle[] fragments = bundle.getFragments(); 1058 for (int i = 0; i < fragments.length; i++) { 1059 BundleDescription fragment = fragments[i].getBundle(); 1060 if (bundle.constraintsConflict(fragment, fragment.getImportPackages(), fragment.getRequiredBundles(), fragment.getGenericRequires()) && !developmentMode) 1061 resolverExports.remove(bundle.detachFragment(fragments[i], null)); 1063 } 1064 } 1065 1066 private boolean resolveGenericReq(GenericConstraint constraint, ArrayList cycle) { 1067 if (DEBUG_REQUIRES) 1068 ResolverImpl.log("Trying to resolve: " + constraint.getBundle() + ", " + constraint.getVersionConstraint()); GenericCapability[] matchingCapabilities = constraint.getMatchingCapabilities(); 1070 if (matchingCapabilities != null) { 1071 for (int i = 0; i < matchingCapabilities.length; i++) 1073 if (matchingCapabilities[i].getResolverBundle().getState() == ResolverBundle.RESOLVING) 1074 if (!cycle.contains(constraint.getBundle())) 1075 cycle.add(constraint.getBundle()); 1076 if (DEBUG_REQUIRES) 1077 ResolverImpl.log(" - already wired"); return true; } 1080 Object [] capabilities = resolverGenerics.get(constraint.getVersionConstraint().getName()); 1081 boolean result = false; 1082 for (int i = 0; i < capabilities.length; i++) { 1083 GenericCapability capability = (GenericCapability) capabilities[i]; 1084 if (DEBUG_GENERICS) 1085 ResolverImpl.log("CHECKING GENERICS: " + capability.getBaseDescription()); if (constraint.isSatisfiedBy(capability)) { 1088 capability.getResolverBundle().addRef(constraint.getBundle()); 1089 if (result && (((GenericSpecification) constraint.getVersionConstraint()).getResolution() & GenericSpecification.RESOLUTION_MULTIPLE) == 0) 1090 continue; constraint.setMatchingCapability(capability); if (constraint.getBundle() == capability.getResolverBundle()) { 1093 result = true; continue; 1095 } 1096 VersionSupplier[] capabilityHosts = capability.isFromFragment() ? capability.getResolverBundle().getHost().getPossibleSuppliers() : new ResolverBundle[] {capability.getResolverBundle()}; 1097 boolean foundResolvedMatch = false; 1098 for (int j = 0; capabilityHosts != null && j < capabilityHosts.length; j++) { 1099 ResolverBundle capabilitySupplier = (ResolverBundle) capabilityHosts[j]; 1100 if (capabilitySupplier == constraint.getBundle()) { 1101 foundResolvedMatch = true; 1103 continue; 1104 } 1105 if (capabilitySupplier.getState() == ResolverBundle.RESOLVED || (resolveBundle(capabilitySupplier, cycle) || developmentMode)) { 1107 foundResolvedMatch |= !capability.isFromFragment() ? true : capability.getResolverBundle().getHost().getPossibleSuppliers() != null; 1108 if (capabilitySupplier.getState() == ResolverBundle.RESOLVING) 1110 if (!cycle.contains(capabilitySupplier)) 1111 cycle.add(capabilitySupplier); 1112 } 1113 } 1114 if (!foundResolvedMatch) { 1115 constraint.removeMatchingCapability(capability); 1116 continue; } 1118 if (DEBUG_GENERICS) 1119 ResolverImpl.log("Found match: " + capability.getBaseDescription() + ". Wiring"); result = true; 1121 } 1122 } 1123 return result ? true : (((GenericSpecification) constraint.getVersionConstraint()).getResolution() & GenericSpecification.RESOLUTION_OPTIONAL) != 0; 1124 } 1125 1126 private boolean resolveRequire(BundleConstraint req, ArrayList cycle) { 1128 if (DEBUG_REQUIRES) 1129 ResolverImpl.log("Trying to resolve: " + req.getBundle() + ", " + req.getVersionConstraint()); if (req.getSelectedSupplier() != null) { 1131 if (!cycle.contains(req.getBundle())) { 1133 cycle.add(req.getBundle()); 1134 if (DEBUG_CYCLES) 1135 ResolverImpl.log("require-bundle cycle: " + req.getBundle() + " -> " + req.getSelectedSupplier()); } 1137 if (DEBUG_REQUIRES) 1138 ResolverImpl.log(" - already wired"); return true; } 1141 Object [] bundles = resolverBundles.get(req.getVersionConstraint().getName()); 1142 boolean result = false; 1143 for (int i = 0; i < bundles.length; i++) { 1144 ResolverBundle bundle = (ResolverBundle) bundles[i]; 1145 if (DEBUG_REQUIRES) 1146 ResolverImpl.log("CHECKING: " + bundle.getBundle()); if (req.isSatisfiedBy(bundle)) { 1149 bundle.addRef(req.getBundle()); 1150 req.addPossibleSupplier(bundle); 1152 if (req.getBundle() != bundle) { 1153 if (bundle.getState() != ResolverBundle.RESOLVED && !resolveBundle(bundle, cycle) && !developmentMode) { 1155 req.removePossibleSupplier(bundle); 1156 continue; } 1158 } 1159 if (req.getBundle() != bundle) { 1161 if (bundle.getState() == ResolverBundle.RESOLVING) 1162 if (!cycle.contains(req.getBundle())) { 1164 cycle.add(req.getBundle()); 1165 if (DEBUG_CYCLES) 1166 ResolverImpl.log("require-bundle cycle: " + req.getBundle() + " -> " + req.getSelectedSupplier()); } 1168 } 1169 if (DEBUG_REQUIRES) 1170 ResolverImpl.log("Found match: " + bundle.getBundle() + ". Wiring"); result = true; 1172 } 1173 } 1174 if (result || req.isOptional()) 1175 return true; 1177 return false; 1178 } 1179 1180 private boolean resolveImport(ResolverImport imp, ArrayList cycle) { 1182 if (DEBUG_IMPORTS) 1183 ResolverImpl.log("Trying to resolve: " + imp.getBundle() + ", " + imp.getName()); if (imp.getSelectedSupplier() != null) { 1185 if (!cycle.contains(imp.getBundle())) { 1187 cycle.add(imp.getBundle()); 1188 if (DEBUG_CYCLES) 1189 ResolverImpl.log("import-package cycle: " + imp.getBundle() + " -> " + imp.getSelectedSupplier() + " from " + imp.getSelectedSupplier().getBundle()); } 1191 if (DEBUG_IMPORTS) 1192 ResolverImpl.log(" - already wired"); return true; } 1195 boolean result = false; 1196 Object [] exports = resolverExports.get(imp.getName()); 1197 exportsloop: for (int i = 0; i < exports.length; i++) { 1198 ResolverExport export = (ResolverExport) exports[i]; 1199 if (DEBUG_IMPORTS) 1200 ResolverImpl.log("CHECKING: " + export.getExporter().getBundle() + ", " + export.getName()); if (imp.isSatisfiedBy(export)) { 1203 int originalState = export.getExporter().getState(); 1204 if (imp.isDynamic() && originalState != ResolverBundle.RESOLVED) 1205 continue; if (imp.getBundle() == export.getExporter() && !export.getExportPackageDescription().isRoot()) 1207 continue; if (imp.getSelectedSupplier() != null && ((ResolverExport) imp.getSelectedSupplier()).getExporter() == imp.getBundle()) 1209 break; export.getExporter().addRef(imp.getBundle()); 1211 imp.addPossibleSupplier(export); 1213 ResolverExport[] importerExps = null; 1214 if (imp.getBundle() != export.getExporter()) { 1215 importerExps = imp.getBundle().getExports(imp.getName()); 1217 for (int j = 0; j < importerExps.length; j++) { 1218 if (importerExps[j].getExportPackageDescription().isRoot() && !export.getExportPackageDescription().isRoot()) 1219 continue exportsloop; if (importerExps[j].getExportPackageDescription().isRoot()) resolverExports.remove(importerExps[j]); } 1223 if ((originalState != ResolverBundle.RESOLVED && !resolveBundle(export.getExporter(), cycle) && !developmentMode) || export.isDropped()) { 1225 imp.removePossibleSupplier(export); 1227 for (int j = 0; j < importerExps.length; j++) 1229 resolverExports.put(importerExps[j].getName(), importerExps[j]); 1230 continue; } 1232 } else if (export.isDropped()) 1233 continue; 1235 if (imp.getBundle() != export.getExporter()) 1237 if (export.getExporter().getState() == ResolverBundle.RESOLVING) { 1238 if (!cycle.contains(imp.getBundle())) { 1240 cycle.add(imp.getBundle()); 1241 if (DEBUG_CYCLES) 1242 ResolverImpl.log("import-package cycle: " + imp.getBundle() + " -> " + imp.getSelectedSupplier() + " from " + imp.getSelectedSupplier().getBundle()); } 1244 } 1245 if (DEBUG_IMPORTS) 1246 ResolverImpl.log("Found match: " + export.getExporter() + ". Wiring " + imp.getBundle() + ":" + imp.getName()); result = true; 1248 } 1249 } 1250 1251 if (result) 1252 return true; 1253 if (resolveImportReprovide(imp, cycle)) 1254 return true; 1255 if (imp.isOptional()) 1256 return true; return false; 1258 } 1259 1260 private boolean resolveImportReprovide(ResolverImport imp, ArrayList cycle) { 1262 String bsn = ((ImportPackageSpecification) imp.getVersionConstraint()).getBundleSymbolicName(); 1263 if (bsn == null) 1266 return false; 1267 if (DEBUG_IMPORTS) 1268 ResolverImpl.log("Checking reprovides: " + imp.getName()); Object [] bundles = resolverBundles.get(bsn); 1271 for (int i = 0; i < bundles.length; i++) 1272 if (resolveBundle((ResolverBundle) bundles[i], cycle)) 1273 if (resolveImportReprovide0(imp, (ResolverBundle) bundles[i], (ResolverBundle) bundles[i], cycle, new ArrayList(5))) 1274 return true; 1275 return false; 1276 } 1277 1278 private boolean resolveImportReprovide0(ResolverImport imp, ResolverBundle reexporter, ResolverBundle rb, ArrayList cycle, ArrayList visited) { 1279 if (visited.contains(rb)) 1280 return false; visited.add(rb); 1282 BundleConstraint[] requires = rb.getRequires(); 1283 for (int i = 0; i < requires.length; i++) { 1284 if (!((BundleSpecification) requires[i].getVersionConstraint()).isExported()) 1285 continue; if (requires[i].getSelectedSupplier() == null) 1288 continue; 1289 ResolverExport[] exports = ((ResolverBundle) requires[i].getSelectedSupplier()).getExports(imp.getName()); 1290 for (int j = 0; j < exports.length; j++) { 1291 Map directives = exports[j].getExportPackageDescription().getDirectives(); 1292 directives.remove(Constants.USES_DIRECTIVE); 1293 ExportPackageDescription epd = state.getFactory().createExportPackageDescription(exports[j].getName(), exports[j].getVersion(), directives, exports[j].getExportPackageDescription().getAttributes(), false, reexporter.getBundle()); 1294 if (imp.getVersionConstraint().isSatisfiedBy(epd)) { 1295 if (DEBUG_IMPORTS) 1297 ResolverImpl.log(" - Creating re-export for reprovide: " + reexporter + ":" + epd.getName()); ResolverExport re = new ResolverExport(reexporter, epd); 1299 reexporter.addExport(re); 1300 resolverExports.put(re.getName(), re); 1301 imp.addPossibleSupplier(re); 1303 return true; 1304 } 1305 } 1306 if (resolveImportReprovide0(imp, reexporter, (ResolverBundle) requires[i].getSelectedSupplier(), cycle, visited)) 1308 return true; 1309 } 1310 return false; 1311 } 1312 1313 private void setBundleUnresolved(ResolverBundle bundle, boolean removed, boolean keepFragsAttached) { 1315 if (bundle.getState() == ResolverBundle.UNRESOLVED && !developmentMode) 1316 return; 1318 if (removed || !keepFragsAttached) { 1321 resolverExports.remove(bundle.getExportPackages()); 1323 resolverGenerics.remove(bundle.getGenericCapabilities()); 1324 bundle.detachAllFragments(); 1325 bundle.initialize(false); 1326 if (!removed) { 1327 resolverExports.put(bundle.getExportPackages()); 1329 resolverGenerics.put(bundle.getGenericCapabilities()); 1330 } 1331 } 1332 if (!removed && (!developmentMode || !unresolvedBundles.contains(bundle))) 1334 unresolvedBundles.add(bundle); 1335 bundle.setState(ResolverBundle.UNRESOLVED); 1336 } 1337 1338 private void setBundleResolved(ResolverBundle bundle) { 1340 if (bundle.getState() == ResolverBundle.RESOLVED) 1341 return; 1342 unresolvedBundles.remove(bundle); 1343 bundle.setState(ResolverBundle.RESOLVED); 1344 } 1345 1346 private void setBundleResolving(ResolverBundle bundle) { 1348 if (bundle.getState() == ResolverBundle.RESOLVING) 1349 return; 1350 unresolvedBundles.remove(bundle); 1351 bundle.setState(ResolverBundle.RESOLVING); 1352 } 1353 1354 private void stateResolveBundles(ResolverBundle[] resolvedBundles) { 1356 for (int i = 0; i < resolvedBundles.length; i++) { 1357 if (!resolvedBundles[i].getBundle().isResolved()) 1358 stateResolveBundle(resolvedBundles[i]); 1359 } 1360 } 1361 1362 private void stateResolveConstraints(ResolverBundle rb) { 1363 ResolverImport[] imports = rb.getImportPackages(); 1364 for (int i = 0; i < imports.length; i++) { 1365 ResolverExport export = (ResolverExport) imports[i].getSelectedSupplier(); 1366 BaseDescription supplier = export == null ? null : export.getExportPackageDescription(); 1367 state.resolveConstraint(imports[i].getVersionConstraint(), supplier); 1368 } 1369 BundleConstraint[] requires = rb.getRequires(); 1370 for (int i = 0; i < requires.length; i++) { 1371 ResolverBundle bundle = (ResolverBundle) requires[i].getSelectedSupplier(); 1372 BaseDescription supplier = bundle == null ? null : bundle.getBundle(); 1373 state.resolveConstraint(requires[i].getVersionConstraint(), supplier); 1374 } 1375 GenericConstraint[] genericRequires = rb.getGenericRequires(); 1376 for (int i = 0; i < genericRequires.length; i++) { 1377 GenericCapability[] matchingCapabilities = genericRequires[i].getMatchingCapabilities(); 1378 if (matchingCapabilities == null) 1379 state.resolveConstraint(genericRequires[i].getVersionConstraint(), null); 1380 else 1381 for (int j = 0; j < matchingCapabilities.length; j++) 1382 state.resolveConstraint(genericRequires[i].getVersionConstraint(), matchingCapabilities[j].getBaseDescription()); 1383 } 1384 } 1385 1386 private void stateResolveFragConstraints(ResolverBundle rb) { 1387 ResolverBundle host = (ResolverBundle) rb.getHost().getSelectedSupplier(); 1388 ImportPackageSpecification[] imports = rb.getBundle().getImportPackages(); 1389 for (int i = 0; i < imports.length; i++) { 1390 ResolverImport hostImport = host == null ? null : host.getImport(imports[i].getName()); 1391 ResolverExport export = (ResolverExport) (hostImport == null ? null : hostImport.getSelectedSupplier()); 1392 BaseDescription supplier = export == null ? null : export.getExportPackageDescription(); 1393 state.resolveConstraint(imports[i], supplier); 1394 } 1395 BundleSpecification[] requires = rb.getBundle().getRequiredBundles(); 1396 for (int i = 0; i < requires.length; i++) { 1397 BundleConstraint hostRequire = host == null ? null : host.getRequire(requires[i].getName()); 1398 ResolverBundle bundle = (ResolverBundle) (hostRequire == null ? null : hostRequire.getSelectedSupplier()); 1399 BaseDescription supplier = bundle == null ? null : bundle.getBundle(); 1400 state.resolveConstraint(requires[i], supplier); 1401 } 1402 } 1403 1404 private void stateResolveBundle(ResolverBundle rb) { 1405 if (!rb.isResolved() && !developmentMode) 1407 return; 1408 if (rb.isFragment()) 1409 stateResolveFragConstraints(rb); 1410 else 1411 stateResolveConstraints(rb); 1412 ResolverExport[] exports = rb.getSelectedExports(); 1414 ArrayList selectedExports = new ArrayList(exports.length); 1415 for (int i = 0; i < exports.length; i++) { 1416 selectedExports.add(exports[i].getExportPackageDescription()); 1417 } 1418 ExportPackageDescription[] selectedExportsArray = (ExportPackageDescription[]) selectedExports.toArray(new ExportPackageDescription[selectedExports.size()]); 1419 1420 ResolverImport[] imports = rb.getImportPackages(); 1422 ArrayList exportsWiredTo = new ArrayList(imports.length); 1423 for (int i = 0; i < imports.length; i++) 1424 if (imports[i].getSelectedSupplier() != null) 1425 exportsWiredTo.add(imports[i].getSelectedSupplier().getBaseDescription()); 1426 ExportPackageDescription[] exportsWiredToArray = (ExportPackageDescription[]) exportsWiredTo.toArray(new ExportPackageDescription[exportsWiredTo.size()]); 1427 1428 BundleConstraint[] requires = rb.getRequires(); 1430 ArrayList bundlesWiredTo = new ArrayList(requires.length); 1431 for (int i = 0; i < requires.length; i++) 1432 if (requires[i].getSelectedSupplier() != null) 1433 bundlesWiredTo.add(requires[i].getSelectedSupplier().getBaseDescription()); 1434 BundleDescription[] bundlesWiredToArray = (BundleDescription[]) bundlesWiredTo.toArray(new BundleDescription[bundlesWiredTo.size()]); 1435 1436 BundleDescription[] hostBundles = null; 1437 if (rb.isFragment()) { 1438 VersionSupplier[] matchingBundles = rb.getHost().getPossibleSuppliers(); 1439 if (matchingBundles != null && matchingBundles.length > 0) { 1440 hostBundles = new BundleDescription[matchingBundles.length]; 1441 for (int i = 0; i < matchingBundles.length; i++) { 1442 hostBundles[i] = matchingBundles[i].getBundle(); 1443 if (rb.isNewFragmentExports() && hostBundles[i].isResolved()) { 1444 ResolverExport[] hostExports = ((ResolverBundle) matchingBundles[i]).getSelectedExports(); 1446 ExportPackageDescription[] hostExportsArray = new ExportPackageDescription[hostExports.length]; 1447 for (int j = 0; j < hostExports.length; j++) 1448 hostExportsArray[j] = hostExports[j].getExportPackageDescription(); 1449 state.resolveBundle(hostBundles[i], true, null, hostExportsArray, hostBundles[i].getResolvedRequires(), hostBundles[i].getResolvedImports()); 1450 } 1451 } 1452 } 1453 } 1454 1455 state.resolveBundle(rb.getBundle(), rb.isResolved(), hostBundles, selectedExportsArray, bundlesWiredToArray, exportsWiredToArray); 1457 } 1458 1459 public synchronized ExportPackageDescription resolveDynamicImport(BundleDescription importingBundle, String requestedPackage) { 1461 if (state == null) 1462 throw new IllegalStateException ("RESOLVER_NO_STATE"); 1464 if (!initialized) 1466 initialize(); 1467 1468 ResolverBundle rb = (ResolverBundle) bundleMapping.get(importingBundle); 1469 if (rb.getExport(requestedPackage) != null) 1470 return null; ResolverImport[] resolverImports = rb.getImportPackages(); 1472 boolean found = false; 1475 for (int j = 0; j < resolverImports.length; j++) { 1476 if (!resolverImports[j].isDynamic()) 1478 continue; 1479 String importName = resolverImports[j].getName(); 1480 if (importName.equals("*") || (importName.endsWith(".*") && requestedPackage.startsWith(importName.substring(0, importName.length() - 2)))) { resolverImports[j].setName(requestedPackage); 1484 } 1485 if (requestedPackage.equals(resolverImports[j].getName())) { 1487 found = true; 1488 groupingChecker.populateRoots(resolverImports[j].getBundle()); 1490 if (resolveImport(resolverImports[j], new ArrayList())) { 1491 found = false; 1492 while (!found && resolverImports[j].getSelectedSupplier() != null) { 1493 if (groupingChecker.isDynamicConsistent(resolverImports[j].getBundle(), (ResolverExport) resolverImports[j].getSelectedSupplier()) != null) 1494 resolverImports[j].selectNextSupplier(); else 1496 found = true; } 1498 resolverImports[j].setName(null); 1499 if (!found) { 1500 resolverImports[j].setPossibleSuppliers(null); 1502 return null; 1503 } 1504 if (DEBUG_IMPORTS) 1506 ResolverImpl.log("Resolved dynamic import: " + rb + ":" + resolverImports[j].getName() + " -> " + ((ResolverExport) resolverImports[j].getSelectedSupplier()).getExporter() + ":" + requestedPackage); ExportPackageDescription matchingExport = ((ResolverExport) resolverImports[j].getSelectedSupplier()).getExportPackageDescription(); 1508 if (importName.endsWith("*")) resolverImports[j].setPossibleSuppliers(null); 1512 return matchingExport; 1513 } 1514 } 1515 resolverImports[j].setName(null); 1517 } 1518 if (!found) { 1520 Map directives = new HashMap(1); 1521 directives.put(Constants.RESOLUTION_DIRECTIVE, ImportPackageSpecification.RESOLUTION_DYNAMIC); 1522 ImportPackageSpecification packageSpec = state.getFactory().createImportPackageSpecification(requestedPackage, null, null, null, directives, null, importingBundle); 1523 ResolverImport newImport = new ResolverImport(rb, packageSpec); 1524 if (resolveImport(newImport, new ArrayList())) { 1525 while (newImport.getSelectedSupplier() != null) { 1526 if (groupingChecker.isDynamicConsistent(rb, (ResolverExport) newImport.getSelectedSupplier()) != null) 1527 newImport.selectNextSupplier(); 1528 else 1529 break; 1530 } 1531 return ((ResolverExport) newImport.getSelectedSupplier()).getExportPackageDescription(); 1532 } 1533 } 1534 if (DEBUG || DEBUG_IMPORTS) 1535 ResolverImpl.log("Failed to resolve dynamic import: " + requestedPackage); return null; } 1538 1539 public void bundleAdded(BundleDescription bundle) { 1540 if (!initialized) 1541 return; 1542 1543 boolean alreadyThere = false; 1544 for (int i = 0; i < unresolvedBundles.size(); i++) { 1545 ResolverBundle rb = (ResolverBundle) unresolvedBundles.get(i); 1546 if (rb.getBundle() == bundle) { 1547 alreadyThere = true; 1548 } 1549 } 1550 if (!alreadyThere) { 1551 ResolverBundle rb = new ResolverBundle(bundle, this); 1552 bundleMapping.put(bundle, rb); 1553 unresolvedBundles.add(rb); 1554 resolverExports.put(rb.getExportPackages()); 1555 resolverBundles.put(rb.getName(), rb); 1556 resolverGenerics.put(rb.getGenericCapabilities()); 1557 } 1558 } 1559 1560 public void bundleRemoved(BundleDescription bundle, boolean pending) { 1561 if (pending) 1563 removalPending.put(new Long (bundle.getBundleId()), bundle); 1564 if (!initialized) 1565 return; 1566 ResolverBundle rb = (ResolverBundle) bundleMapping.get(bundle); 1567 if (rb == null) 1568 return; 1569 1570 if (!pending) { 1571 bundleMapping.remove(bundle); 1572 groupingChecker.clear(rb); 1573 } 1574 if (!pending || !bundle.isResolved()) { 1575 resolverExports.remove(rb.getExportPackages()); 1576 resolverBundles.remove(rb); 1577 resolverGenerics.remove(rb.getGenericCapabilities()); 1578 } 1579 unresolvedBundles.remove(rb); 1580 } 1581 1582 private void unresolveBundle(ResolverBundle bundle, boolean removed) { 1583 if (bundle == null) 1584 return; 1585 Object [] removedBundles = removalPending.remove(new Long (bundle.getBundle().getBundleId())); 1587 for (int i = 0; i < removedBundles.length; i++) { 1588 ResolverBundle re = (ResolverBundle) bundleMapping.get(removedBundles[i]); 1589 unresolveBundle(re, true); 1590 state.removeBundleComplete((BundleDescription) removedBundles[i]); 1591 resolverExports.remove(re.getExportPackages()); 1592 resolverBundles.remove(re); 1593 resolverGenerics.remove(re.getGenericCapabilities()); 1594 bundleMapping.remove(removedBundles[i]); 1595 groupingChecker.clear(re); 1596 if (removedBundles[i] == bundle.getBundle()) 1598 removed = true; 1599 } 1600 1601 if (!bundle.getBundle().isResolved() && !developmentMode) 1602 return; 1603 setBundleUnresolved(bundle, removed, false); 1606 BundleDescription[] dependents = bundle.getBundle().getDependents(); 1608 state.resolveBundle(bundle.getBundle(), false, null, null, null, null); 1609 for (int i = 0; i < dependents.length; i++) 1611 unresolveBundle((ResolverBundle) bundleMapping.get(dependents[i]), false); 1612 } 1613 1614 public void bundleUpdated(BundleDescription newDescription, BundleDescription existingDescription, boolean pending) { 1615 bundleRemoved(existingDescription, pending); 1616 bundleAdded(newDescription); 1617 } 1618 1619 public void flush() { 1620 resolverExports = null; 1621 resolverBundles = null; 1622 resolverGenerics = null; 1623 unresolvedBundles = null; 1624 bundleMapping = null; 1625 Object [] removed = removalPending.getAllValues(); 1626 for (int i = 0; i < removed.length; i++) 1627 state.removeBundleComplete((BundleDescription) removed[i]); 1628 removalPending.clear(); 1629 initialized = false; 1630 } 1631 1632 public State getState() { 1633 return state; 1634 } 1635 1636 public void setState(State newState) { 1637 state = newState; 1638 flush(); 1639 } 1640 1641 private void setDebugOptions() { 1642 FrameworkDebugOptions options = FrameworkDebugOptions.getDefault(); 1643 if (options == null) 1645 return; 1646 DEBUG = options.getBooleanOption(OPTION_DEBUG, false); 1647 DEBUG_WIRING = options.getBooleanOption(OPTION_WIRING, false); 1648 DEBUG_IMPORTS = options.getBooleanOption(OPTION_IMPORTS, false); 1649 DEBUG_REQUIRES = options.getBooleanOption(OPTION_REQUIRES, false); 1650 DEBUG_GENERICS = options.getBooleanOption(OPTION_GENERICS, false); 1651 DEBUG_GROUPING = options.getBooleanOption(OPTION_GROUPING, false); 1652 DEBUG_CYCLES = options.getBooleanOption(OPTION_CYCLES, false); 1653 } 1654 1655 private void printWirings() { 1657 ResolverImpl.log("****** Result Wirings ******"); Object [] bundles = resolverBundles.getAllValues(); 1659 for (int j = 0; j < bundles.length; j++) { 1660 ResolverBundle rb = (ResolverBundle) bundles[j]; 1661 if (rb.getBundle().isResolved()) { 1662 continue; 1663 } 1664 ResolverImpl.log(" * WIRING for " + rb); BundleConstraint[] requireBundles = rb.getRequires(); 1667 if (requireBundles.length == 0) { 1668 ResolverImpl.log(" (r) no requires"); } else { 1670 for (int i = 0; i < requireBundles.length; i++) { 1671 if (requireBundles[i].getSelectedSupplier() == null) { 1672 ResolverImpl.log(" (r) " + rb.getBundle() + " -> NULL!!!"); } else { 1674 ResolverImpl.log(" (r) " + rb.getBundle() + " -> " + requireBundles[i].getSelectedSupplier()); } 1676 } 1677 } 1678 BundleConstraint hostSpec = rb.getHost(); 1680 if (hostSpec != null) { 1681 VersionSupplier[] hosts = hostSpec.getPossibleSuppliers(); 1682 if (hosts != null) 1683 for (int i = 0; i < hosts.length; i++) { 1684 ResolverImpl.log(" (h) " + rb.getBundle() + " -> " + hosts[i].getBundle()); } 1686 } 1687 ResolverImport[] imports = rb.getImportPackages(); 1689 if (imports.length == 0) { 1690 ResolverImpl.log(" (w) no imports"); continue; 1692 } 1693 for (int i = 0; i < imports.length; i++) { 1694 if (imports[i].isDynamic() && imports[i].getSelectedSupplier() == null) { 1695 ResolverImpl.log(" (w) " + imports[i].getBundle() + ":" + imports[i].getName() + " -> DYNAMIC"); } else if (imports[i].isOptional() && imports[i].getSelectedSupplier() == null) { 1697 ResolverImpl.log(" (w) " + imports[i].getBundle() + ":" + imports[i].getName() + " -> OPTIONAL (could not be wired)"); } else if (imports[i].getSelectedSupplier() == null) { 1699 ResolverImpl.log(" (w) " + imports[i].getBundle() + ":" + imports[i].getName() + " -> NULL!!!"); } else { 1701 ResolverImpl.log(" (w) " + imports[i].getBundle() + ":" + imports[i].getName() + " -> " + ((ResolverExport) imports[i].getSelectedSupplier()).getExporter() + ":" + imports[i].getSelectedSupplier().getName()); } 1704 } 1705 } 1706 } 1707 1708 static void log(String message) { 1709 Debug.println(message); 1710 } 1711 1712 VersionHashMap getResolverExports() { 1713 return resolverExports; 1714 } 1715 1716 public void setSelectionPolicy(Comparator selectionPolicy) { 1717 this.selectionPolicy = selectionPolicy; 1718 } 1719 1720 public Comparator getSelectionPolicy() { 1721 return selectionPolicy; 1722 } 1723} 1724 | Popular Tags |