Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal Rapicault2009-04-18 20:32:55 +0000
committerPascal Rapicault2009-04-18 20:32:55 +0000
commit101af48fe53dfac2854546a87c7cb22e88ad9abd (patch)
treec7d5da16072b72bd11a70fa420c2dd813815af42 /bundles/org.eclipse.equinox.p2.director
parent574079e890f27d1f7055543db56962a41990a5b6 (diff)
downloadrt.equinox.p2-101af48fe53dfac2854546a87c7cb22e88ad9abd.tar.gz
rt.equinox.p2-101af48fe53dfac2854546a87c7cb22e88ad9abd.tar.xz
rt.equinox.p2-101af48fe53dfac2854546a87c7cb22e88ad9abd.zip
Bug 262503 - [planner] Replace ResolutionHelper with SAT4J based solutionafter_bug262503
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.director')
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java79
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/SimplePlanner.java166
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/resolution/ResolutionHelper.java87
3 files changed, 272 insertions, 60 deletions
diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java
index 616d604f3..5fabf3aca 100644
--- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java
+++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java
@@ -56,6 +56,8 @@ public class Projector {
private Collection alreadyInstalledIUs;
private boolean considerMetaRequirements;
+ private IInstallableUnit entryPoint;
+ private Map fragments = new HashMap();
static class AbstractVariable {
public String toString() {
@@ -126,8 +128,9 @@ public class Projector {
this.considerMetaRequirements = considerMetaRequirements;
}
- public void encode(IInstallableUnit metaIu, IInstallableUnit[] alreadyExistingRoots, IInstallableUnit[] newRoots, IProgressMonitor monitor) {
+ public void encode(IInstallableUnit entryPointIU, IInstallableUnit[] alreadyExistingRoots, IInstallableUnit[] newRoots, IProgressMonitor monitor) {
alreadyInstalledIUs = Arrays.asList(alreadyExistingRoots);
+ this.entryPoint = entryPointIU;
try {
long start = 0;
if (DEBUG) {
@@ -159,15 +162,15 @@ public class Projector {
throw new OperationCanceledException();
}
IInstallableUnit iuToEncode = (IInstallableUnit) iusToEncode.next();
- if (iuToEncode != metaIu) {
+ if (iuToEncode != entryPointIU) {
processIU(iuToEncode, false);
}
}
createConstraintsForSingleton();
- createMustHave(metaIu, alreadyExistingRoots, newRoots);
+ createMustHave(entryPointIU, alreadyExistingRoots, newRoots);
- createOptimizationFunction(metaIu);
+ createOptimizationFunction(entryPointIU);
if (DEBUG) {
long stop = System.currentTimeMillis();
Tracing.debug("Projection complete: " + (stop - start)); //$NON-NLS-1$
@@ -312,6 +315,9 @@ public class Projector {
if (!isApplicable(req))
return;
List matches = getApplicableMatches(req);
+ if (isHostRequirement(iu, req)) {
+ rememberHostMatches(iu, matches);
+ }
if (!req.isOptional()) {
if (matches.isEmpty()) {
missingRequirement(iu, req);
@@ -380,7 +386,7 @@ public class Projector {
private void expandRequirementsWithPatches(IInstallableUnit iu, Collector applicablePatches, boolean isRootIu) throws ContradictionException {
//Unmodified dependencies
- Map unchangedRequirements = new HashMap(iu.getRequiredCapabilities().length);
+ Map unchangedRequirements = new HashMap(getRequiredCapabilities(iu).length);
for (Iterator iterator = applicablePatches.iterator(); iterator.hasNext();) {
IInstallableUnitPatch patch = (IInstallableUnitPatch) iterator.next();
IRequiredCapability[][] reqs = mergeRequirements(iu, patch);
@@ -413,6 +419,9 @@ public class Projector {
if (isApplicable(reqs[i][1])) {
IRequiredCapability req = reqs[i][1];
List matches = getApplicableMatches(req);
+ if (isHostRequirement(iu, req)) {
+ rememberHostMatches(iu, matches);
+ }
if (!req.isOptional()) {
if (matches.isEmpty()) {
missingRequirement(patch, req);
@@ -443,6 +452,9 @@ public class Projector {
if (isApplicable(reqs[i][0])) {
IRequiredCapability req = reqs[i][0];
List matches = getApplicableMatches(req);
+ if (isHostRequirement(iu, req)) {
+ rememberHostMatches(iu, matches);
+ }
if (!req.isOptional()) {
if (matches.isEmpty()) {
dependencyHelper.implication(new Object[] {iu}).implies(patch).named(new Explanation.HardRequirement(iu, null));
@@ -487,6 +499,9 @@ public class Projector {
}
IRequiredCapability req = (IRequiredCapability) entry.getKey();
List matches = getApplicableMatches(req);
+ if (isHostRequirement(iu, req)) {
+ rememberHostMatches(iu, matches);
+ }
if (!req.isOptional()) {
if (matches.isEmpty()) {
if (requiredPatches.isEmpty()) {
@@ -749,6 +764,8 @@ public class Projector {
Object var = i.next();
if (var instanceof IInstallableUnit) {
IInstallableUnit iu = (IInstallableUnit) var;
+ if (iu == entryPoint)
+ continue;
solution.add(iu);
}
}
@@ -770,16 +787,6 @@ public class Projector {
return solution;
}
- public Set getExplanationFor(IInstallableUnit iu) {
- //TODO if the iu is resolved then return null.
- //TODO if the iu is in an unknown state, then return a special value in the set
- try {
- return dependencyHelper.whyNot(iu);
- } catch (TimeoutException e) {
- return Collections.EMPTY_SET;
- }
- }
-
public Set getExplanation(IProgressMonitor monitor) {
ExplanationJob job = new ExplanationJob();
job.schedule();
@@ -807,4 +814,46 @@ public class Projector {
}
return job.getExplanationResult();
}
+
+ public Map getFragmentAssociation() {
+ Map resolvedFragments = new HashMap(fragments.size());
+ for (Iterator iterator = fragments.entrySet().iterator(); iterator.hasNext();) {
+ Entry fragment = (Entry) iterator.next();
+ if (!dependencyHelper.getBooleanValueFor(fragment.getKey()))
+ continue;
+ Set potentialHosts = (Set) fragment.getValue();
+ List resolvedHost = new ArrayList(potentialHosts.size());
+ for (Iterator iterator2 = potentialHosts.iterator(); iterator2.hasNext();) {
+ Object host = iterator2.next();
+ if (dependencyHelper.getBooleanValueFor(host))
+ resolvedHost.add(host);
+ }
+ if (resolvedHost.size() != 0)
+ resolvedFragments.put(fragment.getKey(), resolvedHost);
+ }
+ return resolvedFragments;
+ }
+
+ private void rememberHostMatches(IInstallableUnit fragment, List matches) {
+ Set existingMatches = (Set) fragments.get(fragment);
+ if (existingMatches == null) {
+ existingMatches = new HashSet();
+ fragments.put(fragment, existingMatches);
+ existingMatches.addAll(matches);
+ }
+ existingMatches.retainAll(matches);
+ }
+
+ private boolean isHostRequirement(IInstallableUnit iu, IRequiredCapability req) {
+ if (!(iu instanceof IInstallableUnitFragment))
+ return false;
+ IInstallableUnitFragment fragment = (IInstallableUnitFragment) iu;
+ IRequiredCapability[] reqs = fragment.getHost();
+ for (int i = 0; i < reqs.length; i++) {
+ if (req == reqs[i])
+ return true;
+ }
+ return true;
+ }
+
} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/SimplePlanner.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/SimplePlanner.java
index b2b1814eb..8efd839fd 100644
--- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/SimplePlanner.java
+++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/SimplePlanner.java
@@ -343,9 +343,7 @@ public class SimplePlanner implements IPlanner {
LogHelper.log(s);
s = Status.OK_STATUS;
- Collection newState = projector.extractSolution();
- newState.remove(updatedPlan[0]);
- return newState;
+ return projector;
} finally {
sub.done();
}
@@ -355,22 +353,17 @@ public class SimplePlanner implements IPlanner {
SubMonitor sub = SubMonitor.convert(monitor, ExpandWork);
sub.setTaskName(Messages.Director_Task_Resolving_Dependencies);
try {
- //Get the solution of the initial request
+ //Get the solution for the initial request
Object resolutionResult = getSolutionFor(profileChangeRequest, context, sub.newChild(ExpandWork / 2));
if (resolutionResult instanceof ProvisioningPlan)
return (ProvisioningPlan) resolutionResult;
- //Compute the set of operands based on the solution obtained previously
- Collection newState = (Collection) resolutionResult;
+ Collection newState = ((Projector) resolutionResult).extractSolution();
Collection fullState = new ArrayList();
fullState.addAll(newState);
- ResolutionHelper newStateHelper = new ResolutionHelper(createSelectionContext(profileChangeRequest.getProfileProperties()), null);
- newState = newStateHelper.attachCUs(newState);
+ newState = ResolutionHelper.attachFragments(newState, ((Projector) resolutionResult).getFragmentAssociation());
- ResolutionHelper oldStateHelper = new ResolutionHelper(createSelectionContext(profileChangeRequest.getProfile().getProperties()), null);
- Collection oldState = oldStateHelper.attachCUs(profileChangeRequest.getProfile().query(InstallableUnitQuery.ANY, new Collector(), null).toCollection());
-
- ProvisioningPlan temporaryPlan = generateProvisioningPlan(oldState, newState, profileChangeRequest, null);
+ ProvisioningPlan temporaryPlan = generatePlan((Projector) resolutionResult, newState, profileChangeRequest);
//Create a plan for installing necessary pieces to complete the installation (e.g touchpoint actions)
return createInstallerPlan(profileChangeRequest.getProfile(), profileChangeRequest, fullState, newState, temporaryPlan, context, sub.newChild(ExpandWork / 2));
@@ -472,14 +465,7 @@ public class SimplePlanner implements IPlanner {
return new ProvisioningPlan(externalInstallerStatus, initialRequest, new ProvisioningPlan(externalInstallerStatus, agentRequest, null));
}
- Collection newState = (Collection) externalInstallerPlan;
- ResolutionHelper newStateHelper = new ResolutionHelper(createSelectionContext(agentRequest.getProfileProperties()), null);
- newState = newStateHelper.attachCUs(newState);
-
- ResolutionHelper oldStateHelper = new ResolutionHelper(createSelectionContext(agentProfile.getProperties()), null);
- Collection oldState = oldStateHelper.attachCUs(agentRequest.getProfile().query(InstallableUnitQuery.ANY, new Collector(), null).toCollection());
-
- initialPlan.setInstallerPlan(generateProvisioningPlan(oldState, newState, agentRequest, null));
+ initialPlan.setInstallerPlan(generatePlan((Projector) externalInstallerPlan, null, agentRequest));
return initialPlan;
}
@@ -517,35 +503,57 @@ public class SimplePlanner implements IPlanner {
agentRequest.removeInstallableUnits(new IInstallableUnit[] {previousMetaRequirementIU});
agentRequest.addInstallableUnits(new IInstallableUnit[] {metaRequirementIU});
- ProvisioningContext agentCtx = initialContext; //TODO I believe that we are passing too much here
+ ProvisioningContext agentCtx = new ProvisioningContext(new URI[0]);
ArrayList extraIUs = new ArrayList(unattachedState);
- extraIUs.addAll(profile.available(InstallableUnitQuery.ANY, new Collector(), new NullProgressMonitor()).toCollection());
agentCtx.setExtraIUs(extraIUs);
- agentCtx.setProperty(INCLUDE_PROFILE_IUS, Boolean.FALSE.toString());
Object agentSolution = getSolutionFor(agentRequest, agentCtx, monitor.newChild(3));
if (agentSolution instanceof ProvisioningPlan && ((ProvisioningPlan) agentSolution).getStatus().getSeverity() == IStatus.ERROR) {
MultiStatus agentStatus = new MultiStatus(DirectorActivator.PI_DIRECTOR, 0, Messages.Planner_actions_and_software_incompatible, null);
agentStatus.add(((ProvisioningPlan) agentSolution).getStatus());
return new ProvisioningPlan(agentStatus, initialRequest, new ProvisioningPlan(agentStatus, agentRequest, null));
}
- Collection agentState = (Collection) agentSolution;
- agentState.remove(metaRequirementIU);
- ResolutionHelper agentStateHelper = new ResolutionHelper(createSelectionContext(initialRequest.getProfileProperties()), null);
- agentState = agentStateHelper.attachCUs(agentState);
- ResolutionHelper initialStateHelper = new ResolutionHelper(createSelectionContext(initialRequest.getProfile().getProperties()), null);
- Collection initialState = initialStateHelper.attachCUs(initialRequest.getProfile().query(InstallableUnitQuery.ANY, new Collector(), null).toCollection());
- ProvisioningPlan agentPlan = generateProvisioningPlan(initialState, agentState, agentRequest, null);
+ //Compute the installer plan. It is the difference between what is currently in the profile and the solution we just computed
+ Collection agentState = ((Projector) agentSolution).extractSolution();
+ agentState.remove(metaRequirementIU); //Remove the fake IU
+ agentState = ResolutionHelper.attachFragments(agentState, ((Projector) agentSolution).getFragmentAssociation());
- ResolutionHelper newStateHelper = new ResolutionHelper(createSelectionContext(initialRequest.getProfileProperties()), null);
- expectedState = newStateHelper.attachCUs(expectedState);
+ ProvisioningContext NO_REPO_CONTEXT = new ProvisioningContext(new URI[0]);
+ NO_REPO_CONTEXT.setArtifactRepositories(new URI[0]);
+ //...This computes the attachment of what is currently in the profile
+ Object initialSolution = getSolutionFor(new ProfileChangeRequest(new EverythingOptionalProfile(initialRequest.getProfile())), NO_REPO_CONTEXT, new NullProgressMonitor());
+ if (initialSolution instanceof ProvisioningPlan) {
+ LogHelper.log(new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, "The resolution of the previous state contained in profile " + initialRequest.getProfile().getProfileId() + " version " + initialRequest.getProfile().getTimestamp() + " failed to resolve.")); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ }
+ Collection initialState = ((Projector) initialSolution).extractSolution();
+ initialState = ResolutionHelper.attachFragments(initialState, ((Projector) initialSolution).getFragmentAssociation());
- ResolutionHelper oldStateHelper = new ResolutionHelper(createSelectionContext(initialRequest.getProfileProperties()), null); //Here we purposefully use the new properties
- Set iusAfterActionInstall = new HashSet((Collection) agentSolution);
- iusAfterActionInstall.addAll(initialRequest.getProfile().query(InstallableUnitQuery.ANY, new Collector(), null).toCollection());
- Collection oldState = oldStateHelper.attachCUs(iusAfterActionInstall);
+ ProvisioningPlan agentPlan = generateProvisioningPlan(initialState, agentState, initialRequest, null);
+
+ //Compute the installation plan. It is the difference between the state after the installer plan has run and the expectedState.
+ return generateProvisioningPlan(agentState, expectedState, initialRequest, agentPlan);
+ }
+
+ //Compute the set of operands based on the solution obtained previously
+ private ProvisioningPlan generatePlan(Projector newSolution, Collection newState, ProfileChangeRequest request) {
+ //Compute the attachment of the new state if not provided
+ if (newState == null) {
+ newState = newSolution.extractSolution();
+ newState = ResolutionHelper.attachFragments(newState, newSolution.getFragmentAssociation());
+ }
+ ProvisioningContext NO_REPO_CONTEXT = new ProvisioningContext(new URI[0]);
+ NO_REPO_CONTEXT.setArtifactRepositories(new URI[0]);
+
+ //Compute the attachment of the previous state
+ Object initialSolution = getSolutionFor(new ProfileChangeRequest(new EverythingOptionalProfile(request.getProfile())), NO_REPO_CONTEXT, new NullProgressMonitor());
+ if (initialSolution instanceof ProvisioningPlan) {
+ LogHelper.log(new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, "The resolution of the previous state contained in profile " + request.getProfile().getProfileId() + " version " + request.getProfile().getTimestamp() + " failed to resolve.")); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ }
+ Collection initialState = ((Projector) initialSolution).extractSolution();
+ initialState = ResolutionHelper.attachFragments(initialState, ((Projector) initialSolution).getFragmentAssociation());
- return generateProvisioningPlan(oldState, expectedState, initialRequest, agentPlan);
+ //Generate the plan
+ return generateProvisioningPlan(initialState, newState, request, null);
}
private IInstallableUnit getPreviousIUForMetaRequirements(IProfile profile, String iuId, IProgressMonitor monitor) {
@@ -601,17 +609,18 @@ public class SimplePlanner implements IPlanner {
profileChangeRequest.setInstallableUnitProfileProperty((IInstallableUnit) object.getKey(), INCLUSION_RULES, PlannerHelper.createStrictInclusionRule((IInstallableUnit) object.getKey()));
}
//Remove the iu properties associated to the ius removed and the iu properties being removed as well
- for (Iterator iterator = alreadyInstalled.iterator(); iterator.hasNext();) {
- IInstallableUnit iu = (IInstallableUnit) iterator.next();
- for (int i = 0; i < removed.length; i++) {
- if (iu.equals(removed[i])) {
- profileChangeRequest.removeInstallableUnitProfileProperty(removed[i], INCLUSION_RULES);
- iterator.remove();
- break;
+ if (removed.length != 0) {
+ for (Iterator iterator = alreadyInstalled.iterator(); iterator.hasNext();) {
+ IInstallableUnit iu = (IInstallableUnit) iterator.next();
+ for (int i = 0; i < removed.length; i++) {
+ if (iu.equals(removed[i])) {
+ profileChangeRequest.removeInstallableUnitProfileProperty(removed[i], INCLUSION_RULES);
+ iterator.remove();
+ break;
+ }
}
}
}
-
ArrayList gatheredRequirements = new ArrayList();
//Process all the IUs being added
@@ -700,4 +709,71 @@ public class SimplePlanner implements IPlanner {
Collection results = resultsMap.values();
return (IInstallableUnit[]) results.toArray(new IInstallableUnit[results.size()]);
}
+
+ //helper class to trick the resolver to believe that everything is optional
+ private static class EverythingOptionalProfile implements IProfile {
+ private IProfile profile;
+
+ public EverythingOptionalProfile(IProfile p) {
+ profile = p;
+ }
+
+ public Collector available(Query query, Collector collector, IProgressMonitor monitor) {
+ return profile.available(query, collector, monitor);
+ }
+
+ public Map getInstallableUnitProperties(IInstallableUnit iu) {
+ return profile.getInstallableUnitProperties(iu);
+ }
+
+ public String getInstallableUnitProperty(IInstallableUnit iu, String key) {
+ if (INCLUSION_RULES.equals(key))
+ return PlannerHelper.createOptionalInclusionRule(iu);
+ return profile.getInstallableUnitProperty(iu, key);
+ }
+
+ public Map getLocalProperties() {
+ return profile.getLocalProperties();
+ }
+
+ public String getLocalProperty(String key) {
+ return profile.getLocalProperty(key);
+ }
+
+ public IProfile getParentProfile() {
+ return profile.getParentProfile();
+ }
+
+ public String getProfileId() {
+ return profile.getProfileId();
+ }
+
+ public Map getProperties() {
+ return profile.getProperties();
+ }
+
+ public String getProperty(String key) {
+ return profile.getProperty(key);
+ }
+
+ public String[] getSubProfileIds() {
+ return profile.getSubProfileIds();
+ }
+
+ public long getTimestamp() {
+ return profile.getTimestamp();
+ }
+
+ public boolean hasSubProfiles() {
+ return profile.hasSubProfiles();
+ }
+
+ public boolean isRootProfile() {
+ return profile.isRootProfile();
+ }
+
+ public Collector query(Query query, Collector collector, IProgressMonitor monitor) {
+ return profile.query(query, collector, monitor);
+ }
+ }
}
diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/resolution/ResolutionHelper.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/resolution/ResolutionHelper.java
index 04bca9d51..ff706c6aa 100644
--- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/resolution/ResolutionHelper.java
+++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/resolution/ResolutionHelper.java
@@ -11,6 +11,7 @@
package org.eclipse.equinox.internal.p2.resolution;
import java.util.*;
+import java.util.Map.Entry;
import org.eclipse.equinox.internal.p2.director.DirectorActivator;
import org.eclipse.equinox.internal.p2.director.RecommendationDescriptor;
import org.eclipse.equinox.internal.provisional.p2.core.Version;
@@ -186,6 +187,92 @@ public class ResolutionHelper {
return result;
}
+ public static Collection attachFragments(Collection toAttach, Map fragmentsToIUs) {
+ Map fragmentBindings = new HashMap();
+ //Build a map inverse of the one provided in input (host --> List of fragments)
+ Map iusToFragment = new HashMap(fragmentsToIUs.size());
+ for (Iterator iterator = fragmentsToIUs.entrySet().iterator(); iterator.hasNext();) {
+ Entry mapping = (Entry) iterator.next();
+ IInstallableUnitFragment fragment = (IInstallableUnitFragment) mapping.getKey();
+ List existingMatches = (List) mapping.getValue();
+
+ for (Iterator iterator2 = existingMatches.iterator(); iterator2.hasNext();) {
+ Object host = iterator2.next();
+ List potentialFragments = (List) iusToFragment.get(host);
+ if (potentialFragments == null) {
+ potentialFragments = new ArrayList();
+ iusToFragment.put(host, potentialFragments);
+ }
+ potentialFragments.add(fragment);
+ }
+ }
+
+ for (Iterator iterator = iusToFragment.entrySet().iterator(); iterator.hasNext();) {
+ Entry entry = (Entry) iterator.next();
+ IInstallableUnit hostIU = (IInstallableUnit) entry.getKey();
+ List potentialIUFragments = (List) entry.getValue();
+ ArrayList applicableFragments = new ArrayList();
+ for (Iterator iterator2 = potentialIUFragments.iterator(); iterator2.hasNext();) {
+ IInstallableUnit dependentIU = (IInstallableUnitFragment) iterator2.next();
+ if (hostIU.equals(dependentIU) || !dependentIU.isFragment())
+ continue;
+
+ IInstallableUnitFragment potentialFragment = (IInstallableUnitFragment) dependentIU;
+
+ // Check to make sure the host meets the requirements of the fragment
+ IRequiredCapability reqsFromFragment[] = potentialFragment.getHost();
+ boolean match = true;
+ boolean requirementMatched = false;
+ for (int l = 0; l < reqsFromFragment.length && match == true; l++) {
+ requirementMatched = false;
+ if (hostIU.satisfies(reqsFromFragment[l]))
+ requirementMatched = true;
+ if (requirementMatched == false) {
+ match = false;
+ break;
+ }
+
+ }
+ if (match) {
+ applicableFragments.add(potentialFragment);
+ }
+ }
+
+ IInstallableUnitFragment theFragment = null;
+ int specificityLevel = 0;
+ for (Iterator iterator4 = applicableFragments.iterator(); iterator4.hasNext();) {
+ IInstallableUnitFragment fragment = (IInstallableUnitFragment) iterator4.next();
+ if (fragment.getHost().length > specificityLevel) {
+ theFragment = fragment;
+ specificityLevel = fragment.getHost().length;
+ }
+ }
+ if (theFragment != null)
+ fragmentBindings.put(hostIU, theFragment);
+ }
+ //build the collection of resolved IUs
+ Collection result = new HashSet(toAttach.size());
+ for (Iterator iterator = toAttach.iterator(); iterator.hasNext();) {
+ IInstallableUnit iu = (IInstallableUnit) iterator.next();
+ if (iu == null)
+ continue;
+ //just return fragments as they are
+ if (iu.isFragment()) {
+ result.add(iu);
+ continue;
+ }
+ //return a new IU that combines the IU with its bound fragments
+ IInstallableUnitFragment fragment = (IInstallableUnitFragment) fragmentBindings.get(iu);
+ IInstallableUnitFragment[] fragments;
+ if (fragment == null)
+ fragments = NO_FRAGMENTS;
+ else
+ fragments = new IInstallableUnitFragment[] {fragment};
+ result.add(MetadataFactory.createResolvedInstallableUnit(iu, fragments));
+ }
+ return result;
+ }
+
public boolean isResolved(IInstallableUnit iu) {
return state.getBundle(iu.getId(), Version.toOSGiVersion(iu.getVersion())).isResolved();
}

Back to the top