Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: fd53047131f78b8b3134ef9079cf1e946a4fcca9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*******************************************************************************
 * Copyright (c) 2011 Sonatype, Inc. and others. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: 
 * Sonatype, Inc. - initial implementation and ideas 
 ******************************************************************************/
package org.eclipse.equinox.p2.tests.planner;

import java.util.*;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.equinox.internal.p2.director.ProfileChangeRequest;
import org.eclipse.equinox.internal.p2.metadata.query.UpdateQuery;
import org.eclipse.equinox.p2.engine.*;
import org.eclipse.equinox.p2.engine.query.IUProfilePropertyQuery;
import org.eclipse.equinox.p2.metadata.*;
import org.eclipse.equinox.p2.planner.*;
import org.eclipse.equinox.p2.query.*;

public class LuckyHelper {
	private final String INCLUSION_RULES = "org.eclipse.equinox.p2.internal.inclusion.rules"; //$NON-NLS-1$

	ProfileChangeRequest computeProfileChangeRequest(IProfile profile, IPlanner planner, IProfileChangeRequest originalRequest, ProvisioningContext context, IProgressMonitor monitor) {
		//		IProfileRegistry profileRegistry = (IProfileRegistry) session.getProvisioningAgent().getService(IProfileRegistry.SERVICE_NAME);
		IPlanner plan = planner; //(IPlanner) session.getProvisioningAgent().getService(IPlanner.SERVICE_NAME);
		IProfile prof = profile; //profileRegistry.getProfile(getProfileId());

		final String INCLUSION_OPTIONAL = "OPTIONAL"; //$NON-NLS-1$
		final String INCLUSION_STRICT = "STRICT"; //$NON-NLS-1$

		Set<IInstallableUnit> strictRoots = prof.query(new IUProfilePropertyQuery(INCLUSION_RULES, INCLUSION_STRICT), null).toSet();
		Set<IInstallableUnit> optionalRoots = prof.query(new IUProfilePropertyQuery(INCLUSION_RULES, INCLUSION_OPTIONAL), null).toSet();

		//Take into account the changes from the request (potential addition or removals)
		if (originalRequest != null) {
			strictRoots.removeAll(originalRequest.getRemovals());
			optionalRoots.removeAll(originalRequest.getRemovals());
			Collection<IInstallableUnit> added = originalRequest.getAdditions();
			for (IInstallableUnit iuAdded : added) {
				Map props = ((ProfileChangeRequest) originalRequest).getInstallableUnitProfilePropertiesToAdd();
				Map propertyForIU = (Map) props.get(iuAdded);
				if (propertyForIU == null || INCLUSION_STRICT.equals(propertyForIU.get(INCLUSION_RULES))) {
					strictRoots.add(iuAdded);
				} else if (INCLUSION_OPTIONAL.equals(propertyForIU.get(INCLUSION_RULES))) {
					optionalRoots.add(iuAdded);
				}
			}
		}

		Set<IInstallableUnit> tmpRoots = new HashSet<IInstallableUnit>(strictRoots);
		tmpRoots.addAll(optionalRoots);

		CollectionResult<IInstallableUnit> allInitialRoots = new CollectionResult<IInstallableUnit>(tmpRoots);

		ProfileChangeRequest updateFinderRequest = (ProfileChangeRequest) plan.createChangeRequest(prof);
		Collection<IRequirement> limitingRequirements = new ArrayList<IRequirement>();
		limitingRequirements.addAll(originalRequest.getExtraRequirements());

		//Create a profile change request that attempts at installing updates for all the existing roots.
		for (Iterator<IInstallableUnit> iterator = allInitialRoots.query(QueryUtil.ALL_UNITS, null).iterator(); iterator.hasNext();) {
			IInstallableUnit currentlyInstalled = iterator.next();

			//find all the potential updates for the currentlyInstalled iu
			IQueryResult<IInstallableUnit> updatesAvailable = plan.updatesFor(currentlyInstalled, context, null);
			for (Iterator<IInstallableUnit> iterator2 = updatesAvailable.iterator(); iterator2.hasNext();) {
				IInstallableUnit update = iterator2.next();
				updateFinderRequest.add(update);
				updateFinderRequest.setInstallableUnitInclusionRules(update, ProfileInclusionRules.createOptionalInclusionRule(update));
			}

			//force the original IU to optional, but make sure that the solution at least includes it
			updateFinderRequest.setInstallableUnitInclusionRules(currentlyInstalled, ProfileInclusionRules.createOptionalInclusionRule(currentlyInstalled));
			limitingRequirements.add(MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID, currentlyInstalled.getId(), new VersionRange(currentlyInstalled.getVersion(), true, Version.MAX_VERSION, true), null, false, false));
		}
		updateFinderRequest.addExtraRequirements(limitingRequirements);

		IProvisioningPlan updateFinderPlan = plan.getProvisioningPlan(updateFinderRequest, context, null);
		if (updateFinderPlan.getAdditions().query(QueryUtil.ALL_UNITS, null).isEmpty()) {
			return null;
		}

		//Take into account all the removals
		IProfileChangeRequest finalChangeRequest = plan.createChangeRequest(prof);
		finalChangeRequest.addExtraRequirements(originalRequest.getExtraRequirements());
		IQueryResult<IInstallableUnit> removals = updateFinderPlan.getRemovals().query(QueryUtil.ALL_UNITS, null);
		for (Iterator<IInstallableUnit> iterator = removals.iterator(); iterator.hasNext();) {
			IInstallableUnit iu = iterator.next();
			if (!allInitialRoots.query(QueryUtil.createIUQuery(iu), null).isEmpty()) {
				finalChangeRequest.remove(iu);
			}
		}

		//Take into account the additions for stricts
		for (Iterator<IInstallableUnit> iterator = strictRoots.iterator(); iterator.hasNext();) {
			IInstallableUnit formerRoot = iterator.next();
			IQueryResult<IInstallableUnit> update = updateFinderPlan.getAdditions().query(new UpdateQuery(formerRoot), null);
			if (!update.isEmpty())
				finalChangeRequest.addAll(update.toUnmodifiableSet());
			else if (originalRequest.getAdditions().contains(formerRoot)) //deal with the case of the elements added by the request
				finalChangeRequest.add(formerRoot);
		}

		//Take into account the additions for optionals
		for (Iterator<IInstallableUnit> iterator = optionalRoots.iterator(); iterator.hasNext();) {
			IInstallableUnit formerRoot = iterator.next();
			IQueryResult<IInstallableUnit> update = updateFinderPlan.getAdditions().query(new UpdateQuery(formerRoot), null);
			if (!update.isEmpty()) {
				for (Iterator<IInstallableUnit> it = update.iterator(); it.hasNext();) {
					IInstallableUnit updatedOptionalIU = it.next();
					finalChangeRequest.add(updatedOptionalIU);
					finalChangeRequest.setInstallableUnitInclusionRules(updatedOptionalIU, ProfileInclusionRules.createOptionalInclusionRule(updatedOptionalIU));
				}
			} else if (originalRequest.getAdditions().contains(formerRoot)) {
				finalChangeRequest.add(formerRoot);
				finalChangeRequest.setInstallableUnitInclusionRules(formerRoot, ProfileInclusionRules.createOptionalInclusionRule(formerRoot));
			}
		}
		return (ProfileChangeRequest) finalChangeRequest;
	}

}

Back to the top