Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 61b02019bc5bb053dbea5f650f990c721d91f5e7 (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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*******************************************************************************
 * Copyright (c) 2009-2010 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *     Sonatype, Inc. - ongoing development
 ******************************************************************************/

package org.eclipse.equinox.p2.operations;

import java.util.Collection;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.operations.*;
import org.eclipse.equinox.internal.provisional.p2.director.PlannerHelper;
import org.eclipse.equinox.internal.provisional.p2.director.ProfileChangeRequest;
import org.eclipse.equinox.p2.engine.IProfile;
import org.eclipse.equinox.p2.engine.query.UserVisibleRootQuery;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.query.InstallableUnitQuery;
import org.eclipse.equinox.p2.metadata.query.PatchQuery;
import org.eclipse.equinox.p2.query.IQueryResult;

/**
 * An InstallOperation describes an operation that installs IInstallableUnits into
 * a profile.
 * 
 * The following snippet shows how one might use an InstallOperation to perform a synchronous resolution and
 * then kick off an install in the background:
 * 
 * <pre>
 * InstallOperation op = new InstallOperation(session, new IInstallableUnit [] { myIU });
 * IStatus result = op.resolveModal(monitor);
 * if (result.isOK()) {
 *   op.getProvisioningJob(monitor).schedule();
 * }
 * </pre>
 * 
 * @since 2.0
 * @see ProfileChangeOperation
 * @noextend This class is not intended to be subclassed by clients.
 */
public class InstallOperation extends ProfileChangeOperation {

	private Collection<IInstallableUnit> toInstall;

	/**
	 * Create an install operation on the specified provisioning session that installs
	 * the supplied IInstallableUnits.  Unless otherwise specified, the operation will
	 * be associated with the currently running profile.
	 * 
	 * @param session the session to use for obtaining provisioning services
	 * @param toInstall the IInstallableUnits to be installed into the profile.
	 */
	public InstallOperation(ProvisioningSession session, Collection<IInstallableUnit> toInstall) {
		super(session);
		this.toInstall = toInstall;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.equinox.p2.operations.ProfileChangeOperation#computeProfileChangeRequest(org.eclipse.core.runtime.MultiStatus, org.eclipse.core.runtime.IProgressMonitor)
	 */
	protected void computeProfileChangeRequest(MultiStatus status, IProgressMonitor monitor) {
		request = ProfileChangeRequest.createByProfileId(session.getProvisioningAgent(), profileId);
		IProfile profile;
		profile = session.getProfileRegistry().getProfile(profileId);
		SubMonitor sub = SubMonitor.convert(monitor, Messages.InstallOperation_ComputeProfileChangeProgress, toInstall.size());
		for (IInstallableUnit entryToInstall : toInstall) {
			// If the user is installing a patch, we mark it optional.  This allows
			// the patched IU to be updated later by removing the patch.
			if (PatchQuery.isPatch(entryToInstall))
				request.setInstallableUnitInclusionRules(entryToInstall, PlannerHelper.createOptionalInclusionRule(entryToInstall));

			// Check to see if it is already installed.  This may alter the request.
			IQueryResult<IInstallableUnit> alreadyInstalled = profile.query(new InstallableUnitQuery(entryToInstall.getId()), null);
			// TODO ideally we should only do this check if the iu is a singleton, but in practice many iu's that should
			// be singletons are not, so we don't check this (yet)
			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=230878
			if (!alreadyInstalled.isEmpty()) { //  && installedIU.isSingleton()
				IInstallableUnit installedIU = alreadyInstalled.iterator().next();
				int compareTo = entryToInstall.getVersion().compareTo(installedIU.getVersion());
				// If the iu is a newer version of something already installed, consider this an
				// update request
				if (compareTo > 0) {
					boolean lockedForUpdate = false;
					String value = profile.getInstallableUnitProperty(installedIU, IProfile.PROP_PROFILE_LOCKED_IU);
					if (value != null)
						lockedForUpdate = (Integer.parseInt(value) & IProfile.LOCK_UPDATE) == IProfile.LOCK_UPDATE;
					if (lockedForUpdate) {
						// Add a status telling the user that this implies an update, but the
						// iu should not be updated
						status.merge(PlanAnalyzer.getStatus(IStatusCodes.ALTERED_IGNORED_IMPLIED_UPDATE, entryToInstall));
					} else {
						request.add(entryToInstall);
						request.remove(installedIU);
						// Add a status informing the user that the update has been inferred
						status.merge(PlanAnalyzer.getStatus(IStatusCodes.ALTERED_IMPLIED_UPDATE, entryToInstall));
						// Mark it as a root if it hasn't been already
						if (!UserVisibleRootQuery.isUserVisible(installedIU, profile))
							request.setInstallableUnitProfileProperty(entryToInstall, IProfile.PROP_PROFILE_ROOT_IU, Boolean.toString(true));
					}
				} else if (compareTo < 0) {
					// An implied downgrade.  We will not put this in the plan, add a status informing the user
					status.merge(PlanAnalyzer.getStatus(IStatusCodes.ALTERED_IGNORED_IMPLIED_DOWNGRADE, entryToInstall));
				} else {
					//					if (rootMarkerKey != null) {
					if (UserVisibleRootQuery.isUserVisible(installedIU, profile))
						// It is already a root, nothing to do. We tell the user it was already installed
						status.merge(PlanAnalyzer.getStatus(IStatusCodes.ALTERED_IGNORED_ALREADY_INSTALLED, entryToInstall));
					else {
						// It was already installed but not as a root.  Tell the user that parts of it are already installed and mark
						// it as a root. 
						status.merge(PlanAnalyzer.getStatus(IStatusCodes.ALTERED_PARTIAL_INSTALL, entryToInstall));
						request.setInstallableUnitProfileProperty(entryToInstall, IProfile.PROP_PROFILE_ROOT_IU, Boolean.toString(true));
					}
					//					}
				}
			} else {
				// Install it and mark as a root
				request.add(entryToInstall);
				//				if (rootMarkerKey != null)
				request.setInstallableUnitProfileProperty(entryToInstall, IProfile.PROP_PROFILE_ROOT_IU, Boolean.toString(true));
			}
			sub.worked(1);
		}
		sub.done();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.equinox.p2.operations.ProfileChangeOperation#getResolveJobName()
	 */
	protected String getResolveJobName() {
		return Messages.InstallOperation_ResolveJobName;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.equinox.p2.operations.ProfileChangeOperation#getProvisioningJobName()
	 */
	protected String getProvisioningJobName() {
		return Messages.InstallOperation_InstallJobName;

	}
}

Back to the top