View | Details | Raw Unified | Return to bug 331068 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/pde/internal/core/target/AbstractBundleContainer.java (-2 / +12 lines)
Lines 41-52 Link Here
41
	/**
41
	/**
42
	 * Resolved bundles or <code>null</code> if unresolved
42
	 * Resolved bundles or <code>null</code> if unresolved
43
	 */
43
	 */
44
	private IResolvedBundle[] fBundles;
44
	protected IResolvedBundle[] fBundles;
45
45
46
	/**
46
	/**
47
	 * List of features contained in this bundle container or <code>null</code> if unresolved
47
	 * List of features contained in this bundle container or <code>null</code> if unresolved
48
	 */
48
	 */
49
	private IFeatureModel[] fFeatures;
49
	protected IFeatureModel[] fFeatures;
50
50
51
	/**
51
	/**
52
	 * Status generated when this container was resolved, possibly <code>null</code>
52
	 * Status generated when this container was resolved, possibly <code>null</code>
Lines 551-554 Link Here
551
		}
551
		}
552
		return fVMArgs;
552
		return fVMArgs;
553
	}
553
	}
554
555
	/**
556
	 * Associate this bundle container with the given target.  This allows for the container and 
557
	 * the target to share configuration information etc.  
558
	 * 
559
	 * @param target the target to which this container is being added.
560
	 */
561
	protected void associateWithTarget(ITargetDefinition target) {
562
		// Do nothing by default
563
	}
554
}
564
}
(-)src/org/eclipse/pde/internal/core/target/IUBundleContainer.java (-865 / +219 lines)
Lines 8-38 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Sonatype, Inc. - ongoing development
10
 *     Sonatype, Inc. - ongoing development
11
 *     EclipseSource, Inc. - ongoing development
11
 *******************************************************************************/
12
 *******************************************************************************/
12
package org.eclipse.pde.internal.core.target;
13
package org.eclipse.pde.internal.core.target;
13
14
14
import java.io.File;
15
import java.io.File;
15
import java.net.URI;
16
import java.net.URI;
16
import java.net.URISyntaxException;
17
import java.util.*;
17
import java.util.*;
18
import org.eclipse.core.runtime.*;
18
import org.eclipse.core.runtime.*;
19
import org.eclipse.core.runtime.preferences.IPreferencesService;
20
import org.eclipse.equinox.internal.p2.director.PermissiveSlicer;
19
import org.eclipse.equinox.internal.p2.director.PermissiveSlicer;
21
import org.eclipse.equinox.internal.p2.engine.ProfileMetadataRepository;
20
import org.eclipse.equinox.p2.engine.IProfile;
22
import org.eclipse.equinox.p2.core.IAgentLocation;
23
import org.eclipse.equinox.p2.core.ProvisionException;
24
import org.eclipse.equinox.p2.engine.*;
25
import org.eclipse.equinox.p2.engine.query.IUProfilePropertyQuery;
26
import org.eclipse.equinox.p2.metadata.*;
21
import org.eclipse.equinox.p2.metadata.*;
27
import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription;
28
import org.eclipse.equinox.p2.planner.IPlanner;
29
import org.eclipse.equinox.p2.planner.IProfileChangeRequest;
30
import org.eclipse.equinox.p2.query.*;
22
import org.eclipse.equinox.p2.query.*;
31
import org.eclipse.equinox.p2.repository.*;
32
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager;
33
import org.eclipse.equinox.p2.repository.artifact.IFileArtifactRepository;
23
import org.eclipse.equinox.p2.repository.artifact.IFileArtifactRepository;
34
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
35
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
36
import org.eclipse.equinox.p2.touchpoint.eclipse.query.OSGiBundleQuery;
24
import org.eclipse.equinox.p2.touchpoint.eclipse.query.OSGiBundleQuery;
37
import org.eclipse.osgi.util.NLS;
25
import org.eclipse.osgi.util.NLS;
38
import org.eclipse.pde.internal.core.PDECore;
26
import org.eclipse.pde.internal.core.PDECore;
Lines 57-120 Link Here
57
	private static final String FEATURE_ID_SUFFIX = ".feature.group"; //$NON-NLS-1$
45
	private static final String FEATURE_ID_SUFFIX = ".feature.group"; //$NON-NLS-1$
58
46
59
	/**
47
	/**
60
	 * IU identifiers.
48
	 * Whether this container must have all required IUs of the selected IUs available and included
49
	 * in the target to resolve successfully.  If this option is true, the planner will be used to resolve
50
	 * otherwise the slicer is used.  The planner can describe any missing requirements as errors.
61
	 */
51
	 */
62
	private String[] fIds;
52
	public static final int INCLUDE_REQUIRED = 1;
63
53
64
	/**
54
	/**
65
	 * IU versions
55
	 * Whether this container should download and include environment (platform) specific units for all
56
	 * available platforms (vs only the current target definition's environment settings).  Only supported 
57
	 * by the slicer so {@link fIncludeAllRequired} must be turned off for this setting to be used.
66
	 */
58
	 */
67
	private Version[] fVersions;
59
	public static final int INCLUDE_ALL_ENVIRONMENTS = 2;
68
60
69
	/**
61
	/**
70
	 * Cached IU's referenced by this bundle container, or <code>null</code> if not
62
	 * Whether this container should download and include source bundles for the selected units if the associated
71
	 * resolved.
63
	 * source is available in the repository.
72
	 */
64
	 */
73
	private IInstallableUnit[] fUnits;
65
	public static final int INCLUDE_SOURCE = 4;
74
66
75
	/**
67
	/**
76
	 * Cached id/version pairs listing the features that were downloaded to the bundle pool during resolution.  <code>null</code> if not resolved.
68
	 * IU identifiers.
77
	 */
69
	 */
78
	private NameVersionDescriptor[] fFeatures;
70
	private String[] fIds;
79
71
80
	/**
72
	/**
81
	 * Repositories to consider, or <code>null</code> if default.
73
	 * IU versions
82
	 */
74
	 */
83
	private URI[] fRepos;
75
	private Version[] fVersions;
84
76
85
	/**
77
	/**
86
	 * Whether this container must have all required IUs of the selected IUs available and included
78
	 * Cached IU's referenced by this bundle container, or <code>null</code> if not
87
	 * in the target to resolve successfully.  If this option is true, the planner will be used to resolve
79
	 * resolved.
88
	 * otherwise the slicer is used.  The planner can describe any missing requirements as errors.
89
	 * <p>
90
	 * <code>true</code> by default
91
	 * </p>
92
	 */
80
	 */
93
	private boolean fIncludeAllRequired = true;
81
	private IInstallableUnit[] fUnits;
94
82
95
	/**
83
	/**
96
	 * Whether this container should download and include environment (platform) specific units for all
84
	 * Repositories to consider, or <code>null</code> if default.
97
	 * available platforms (vs only the current target definition's environment settings).  Only supported 
98
	 * by the slicer so {@link fIncludeAllRequired} must be turned off for this setting to be used.
99
	 * <p>
100
	 * <code>false</code> by default
101
	 * </p>
102
	 */
85
	 */
103
	private boolean fIncludeMultipleEnvironments = false;
86
	private URI[] fRepos;
104
87
105
	/**
88
	/**
106
	 * Whether this container should download and include source bundles for the selected units if the associated
89
	 * A set of bitmask flags that indicate how this container gets elements from its
107
	 * source is available in the repository.
90
	 * associated p2 repository.
108
	 * <p>
109
	 * <code>false</code>by default
110
	 */
91
	 */
111
	private boolean fIncludeSource = false;
92
	private int fFlags;
112
93
113
	/**
94
	/**
114
	 * Constant ID for a root installable unit that is installed into the profile if {@link #fIncludeSource} is set
95
	 *  The p2 synchronizer to use in managing this container.
115
	 * to <code>true</code>.  The source units found in the repository will be set as required IUs on the root unit.
116
	 */
96
	 */
117
	private static final String SOURCE_IU_ID = "org.eclipse.pde.core.target.source.bundles"; //$NON-NLS-1$
97
	private P2TargetUtils fSynchronizer;
118
98
119
	private static final boolean DEBUG_PROFILE;
99
	private static final boolean DEBUG_PROFILE;
120
100
Lines 130-137 Link Here
130
	 * @param repositories metadata repositories used to search for IU's or <code>null</code> if
110
	 * @param repositories metadata repositories used to search for IU's or <code>null</code> if
131
	 *   default set
111
	 *   default set
132
	 */
112
	 */
133
	IUBundleContainer(String[] ids, String[] versions, URI[] repositories) {
113
	IUBundleContainer(String[] ids, String[] versions, URI[] repositories, int flags) {
134
		fIds = ids;
114
		fIds = ids;
115
		fFlags = flags;
135
		fVersions = new Version[versions.length];
116
		fVersions = new Version[versions.length];
136
		for (int i = 0; i < versions.length; i++) {
117
		for (int i = 0; i < versions.length; i++) {
137
			fVersions[i] = Version.create(versions[i]);
118
			fVersions[i] = Version.create(versions[i]);
Lines 151-159 Link Here
151
	 * @param repositories metadata repositories used to search for IU's or <code>null</code> if
132
	 * @param repositories metadata repositories used to search for IU's or <code>null</code> if
152
	 *   default set
133
	 *   default set
153
	 */
134
	 */
154
	IUBundleContainer(IInstallableUnit[] units, URI[] repositories) {
135
	IUBundleContainer(IInstallableUnit[] units, URI[] repositories, int flags) {
155
		fUnits = units;
156
		fIds = new String[units.length];
136
		fIds = new String[units.length];
137
		fFlags = flags;
157
		fVersions = new Version[units.length];
138
		fVersions = new Version[units.length];
158
		for (int i = 0; i < units.length; i++) {
139
		for (int i = 0; i < units.length; i++) {
159
			fIds[i] = units[i].getId();
140
			fIds[i] = units[i].getId();
Lines 184-792 Link Here
184
	 * @see org.eclipse.pde.internal.core.target.AbstractBundleContainer#resolveFeatures(org.eclipse.pde.internal.core.target.provisional.ITargetDefinition, org.eclipse.core.runtime.IProgressMonitor)
165
	 * @see org.eclipse.pde.internal.core.target.AbstractBundleContainer#resolveFeatures(org.eclipse.pde.internal.core.target.provisional.ITargetDefinition, org.eclipse.core.runtime.IProgressMonitor)
185
	 */
166
	 */
186
	protected IFeatureModel[] resolveFeatures(ITargetDefinition definition, IProgressMonitor monitor) throws CoreException {
167
	protected IFeatureModel[] resolveFeatures(ITargetDefinition definition, IProgressMonitor monitor) throws CoreException {
187
		if (fFeatures == null || fFeatures.length == 0 || !(definition instanceof TargetDefinition)) {
168
		fSynchronizer.synchronize(monitor);
169
		return fFeatures;
170
	}
171
172
	/**
173
	 * Update this container's cache of feature objects based on the given profile.
174
	 * NOTE: this method expects the synchronizer to be synchronized and is called
175
	 * as a result of a synchronization operation.
176
	 */
177
	IFeatureModel[] cacheFeatures() throws CoreException {
178
		Set features = new HashSet();
179
		for (int i = 0; i < fUnits.length; i++) {
180
			IInstallableUnit unit = fUnits[i];
181
			String id = unit.getId();
182
			// if theIU was explicitly added and the naming convention says it is a feature, then add it. 
183
			// This is less than optimal but there is no clear way of identifying an IU as a feature.
184
			if (isRoot(id, unit.getVersion()) && id.endsWith(FEATURE_ID_SUFFIX)) {
185
				id = id.substring(0, id.length() - FEATURE_ID_SUFFIX.length());
186
				String version = unit.getVersion().toString();
187
				features.add(new NameVersionDescriptor(id, version, NameVersionDescriptor.TYPE_FEATURE));
188
			}
189
		}
190
		if (features.isEmpty()) {
188
			return new IFeatureModel[0];
191
			return new IFeatureModel[0];
189
		}
192
		}
190
193
191
		// Note: By creating a map of the container features, we are limiting the user to only one version of a feature in this container
194
		// Now get feature models for all known features
195
		TargetDefinition definition = (TargetDefinition) fSynchronizer.getTargetDefinition();
196
		IFeatureModel[] allFeatures = definition.getFeatureModels(getLocation(false), new NullProgressMonitor());
192
197
193
		// Get all the features in the bundle pool
198
		// Build a final set of the models for the features in the profile.
194
		IFeatureModel[] allFeatures = ((TargetDefinition) definition).getFeatureModels(getLocation(false), monitor);
199
		List result = new ArrayList();
195
196
		// Create a map of the container features for quick lookups
197
		HashMap containerFeatures = new HashMap();
198
		for (int i = 0; i < fFeatures.length; i++) {
199
			containerFeatures.put(fFeatures[i].getId(), fFeatures[i]);
200
		}
201
202
		List includedFeatures = new ArrayList();
203
		for (int i = 0; i < allFeatures.length; i++) {
200
		for (int i = 0; i < allFeatures.length; i++) {
204
			NameVersionDescriptor candidate = (NameVersionDescriptor) containerFeatures.get(allFeatures[i].getFeature().getId());
201
			NameVersionDescriptor candidate = new NameVersionDescriptor(allFeatures[i].getFeature().getId(), allFeatures[i].getFeature().getVersion(), NameVersionDescriptor.TYPE_FEATURE);
205
			if (candidate != null) {
202
			if (features.contains(candidate)) {
206
				if (candidate.getVersion().equals(allFeatures[i].getFeature().getVersion())) {
203
				result.add(allFeatures[i]);
207
					includedFeatures.add(allFeatures[i]);
208
				}
209
			}
204
			}
210
		}
205
		}
211
		return (IFeatureModel[]) includedFeatures.toArray(new IFeatureModel[includedFeatures.size()]);
206
		fFeatures = (IFeatureModel[]) result.toArray(new IFeatureModel[result.size()]);
207
		return fFeatures;
208
	}
209
210
	private boolean isRoot(String id, Version version) {
211
		for (int i = 0; i < fIds.length; i++) {
212
			String fid = fIds[i];
213
			if (fid.equals(id) && fVersions[i].equals(version))
214
				return true;
215
		}
216
		return false;
212
	}
217
	}
213
218
214
	/* (non-Javadoc)
219
	/* (non-Javadoc)
215
	 * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#resolveBundles(org.eclipse.pde.internal.core.target.provisional.ITargetDefinition, org.eclipse.core.runtime.IProgressMonitor)
220
	 * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#resolveBundles(org.eclipse.pde.internal.core.target.provisional.ITargetDefinition, org.eclipse.core.runtime.IProgressMonitor)
216
	 */
221
	 */
217
	protected IResolvedBundle[] resolveBundles(ITargetDefinition definition, IProgressMonitor monitor) throws CoreException {
222
	protected IResolvedBundle[] resolveBundles(ITargetDefinition definition, IProgressMonitor monitor) throws CoreException {
218
		// Resolving may change the included features, clear the cached values
223
		fSynchronizer.synchronize(monitor);
219
		fFeatures = null;
224
		return fBundles;
220
221
		SubMonitor subMon = SubMonitor.convert(monitor, 100);
222
223
		// Attempt to restore from the profile first, as it is local and faster
224
		IResolvedBundle[] result = resolveWithProfile(definition, subMon.newChild(25));
225
		if (result != null) {
226
			subMon.done();
227
			return result;
228
		}
229
230
		// Unable to load from profile, resolve normally
231
		try {
232
			if (fIncludeAllRequired) {
233
				result = resolveWithPlanner(definition, subMon.newChild(75));
234
			} else {
235
				result = resolveWithSlicer(definition, subMon.newChild(75));
236
			}
237
			// If there is a problem generating the profile, delete it so it doesn't get used by #resolveWithProfile()
238
			if (result == null || result.length == 0 || subMon.isCanceled()) {
239
				AbstractTargetHandle handle = ((AbstractTargetHandle) definition.getHandle());
240
				P2TargetUtils.deleteProfile(handle);
241
			}
242
			return result;
243
		} catch (CoreException e) {
244
			AbstractTargetHandle handle = ((AbstractTargetHandle) definition.getHandle());
245
			P2TargetUtils.deleteProfile(handle);
246
			throw e;
247
		}
248
249
	}
225
	}
250
226
251
	/**
227
	/**
252
	 * Used to resolve the contents of this container if the container has been resolved and saved to a profile file.  If the
228
	 * Update this container's cache of top level IUs based on the given profile.
253
	 * profile contains the correct bundles, there is no need to do a full resolve.  If this method has a problem (missing
229
	 * NOTE: this method expects the synchronizer to be synchronized and is called
254
	 * file, unable to compute all dependent bundles), this method will return <code>null</code> and the caller should 
230
	 * as a result of a synchronization operation.
255
	 * use {@link #resolveWithPlanner(ITargetDefinition, IProgressMonitor)} or {@link #resolveWithSlicer(ITargetDefinition, IProgressMonitor)} 
231
	 */
256
	 * to do a full resolve.
232
	IInstallableUnit[] cacheIUs() throws CoreException {
257
	 * 
233
		IProfile profile = fSynchronizer.getProfile();
258
	 * @param definition definition being resolved
234
		ArrayList result = new ArrayList();
259
	 * @param monitor for reporting progress
260
	 * @return set of bundles included in this container or <code>null</code> if the profile is out of date
261
	 * @throws CoreException if an unexpected problem occurs trying to read from the profile
262
	 */
263
	private IResolvedBundle[] resolveWithProfile(ITargetDefinition definition, IProgressMonitor monitor) throws CoreException {
264
		if (DEBUG_PROFILE) {
265
			System.out.println("Target resolution using profile (" + definition.getName() + ")"); //$NON-NLS-1$//$NON-NLS-2$
266
		}
267
268
		IProfile profile = P2TargetUtils.getProfile(definition);
269
		if (profile == null) {
270
			if (DEBUG_PROFILE) {
271
				System.out.println("No profile found"); //$NON-NLS-1$
272
			}
273
			return null;
274
		}
275
276
		SubMonitor subMonitor = SubMonitor.convert(monitor, Messages.IUBundleContainer_LoadingFromProfileJob, 20);
277
278
		// Always create our own units because the slicer will return existing units even though the profile is empty
279
		if (DEBUG_PROFILE) {
280
			System.out.print("Required Units: "); //$NON-NLS-1$
281
			for (int i = 0; i < fIds.length; i++) {
282
				System.out.print(fIds[i] + ", "); //$NON-NLS-1$
283
			}
284
			System.out.println();
285
		}
286
287
		fUnits = new IInstallableUnit[fIds.length];
288
		for (int i = 0; i < fIds.length; i++) {
235
		for (int i = 0; i < fIds.length; i++) {
289
			IQuery query = QueryUtil.createIUQuery(fIds[i], fVersions[i]);
236
			IQuery query = QueryUtil.createIUQuery(fIds[i], fVersions[i]);
290
			IQueryResult queryResult = profile.query(query, null);
237
			IQueryResult queryResult = profile.query(query, null);
291
			if (queryResult.isEmpty()) {
238
			if (queryResult.isEmpty())
292
				if (DEBUG_PROFILE) {
239
				throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.IUBundleContainer_1, fIds[i])));
293
					System.out.println("Required unit not found in profile: " + fIds[i]); //$NON-NLS-1$
240
			result.add(queryResult.iterator().next());
294
				}
295
				fUnits = null;
296
				return null;
297
			}
298
			fUnits[i] = (IInstallableUnit) queryResult.iterator().next();
299
		}
300
		// check that the include source flag matches what the profile represents
301
		if (fIncludeSource != (getCurrentSourceIU(profile) != null))
302
			return null;
303
304
		// OK.  Everything looks good.  Now gather the features and bundles and be done.
305
		ResolvedBundle[] resolvedBundles = updateAfterResolve(profile, definition);
306
307
		subMonitor.worked(10);
308
		subMonitor.done();
309
		if (DEBUG_PROFILE) {
310
			if (resolvedBundles == null || resolvedBundles.length == 0)
311
				System.out.println("No bundles loaded from profile"); //$NON-NLS-1$
312
			else
313
				System.out.println("Loading from profile successful. " + resolvedBundles.length + " bundles found"); //$NON-NLS-1$ //$NON-NLS-2$
314
			System.out.println();
315
		}
316
		return resolvedBundles;
317
	}
318
319
	/**
320
	 * Used to resolve the contents of this container if the user is including all required software.  The p2 planner is used
321
	 * to determine the complete set of IUs required to run the selected software.  If all requirements are met, the bundles
322
	 * are downloaded from the repository into the bundle pool and added to the target definition.
323
	 * 
324
	 * @param definition definition being resolved
325
	 * @param monitor for reporting progress
326
	 * @return set of bundles included in this container
327
	 * @throws CoreException if there is a problem with the requirements or there is a problem downloading
328
	 */
329
	private IResolvedBundle[] resolveWithPlanner(ITargetDefinition definition, IProgressMonitor monitor) throws CoreException {
330
		SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 10);
331
		subMonitor.beginTask(Messages.IUBundleContainer_0, 200);
332
333
		// retrieve profile
334
		IProfile profile = P2TargetUtils.getProfile(definition);
335
		profile.getTimestamp();
336
		subMonitor.worked(10);
337
338
		if (subMonitor.isCanceled()) {
339
			return new IResolvedBundle[0];
340
		}
341
342
		// resolve IUs
343
		IInstallableUnit[] units = getInstallableUnits(profile);
344
345
		if (subMonitor.isCanceled()) {
346
			return new IResolvedBundle[0];
347
		}
348
349
		// create the provisioning plan
350
		IPlanner planner = P2TargetUtils.getPlanner();
351
		IProfileChangeRequest request = planner.createChangeRequest(profile);
352
		// first remove everything that was explicitly installed.  Then add it back.  This has the net effect of 
353
		// removing everything that is no longer needed.
354
		computeRemovals(profile, request, units);
355
		request.addAll(Arrays.asList(units));
356
		for (int i = 0; i < units.length; i++) {
357
			IInstallableUnit unit = units[i];
358
			request.setInstallableUnitProfileProperty(unit, P2TargetUtils.PROP_INSTALLED_IU, Boolean.toString(true));
359
		}
360
361
		ProvisioningContext context = new ProvisioningContext(P2TargetUtils.getAgent());
362
		context.setMetadataRepositories(resolveRepositories());
363
		context.setArtifactRepositories(resolveArtifactRepositories());
364
365
		if (subMonitor.isCanceled()) {
366
			return new IResolvedBundle[0];
367
		}
368
369
		IProvisioningPlan plan = planner.getProvisioningPlan(request, context, new SubProgressMonitor(subMonitor, 20));
370
		IStatus status = plan.getStatus();
371
		if (!status.isOK()) {
372
			throw new CoreException(status);
373
		}
374
		IProvisioningPlan installerPlan = plan.getInstallerPlan();
375
		if (installerPlan != null) {
376
			// this plan requires an update to the installer first, log the fact and attempt
377
			// to continue, we don't want to update the running SDK while provisioning a target
378
			PDECore.log(new Status(IStatus.INFO, PDECore.PLUGIN_ID, Messages.IUBundleContainer_6));
379
		}
380
		subMonitor.worked(10);
381
382
		if (subMonitor.isCanceled()) {
383
			return new IResolvedBundle[0];
384
		}
385
386
		// execute the provisioning plan
387
		IPhaseSet phases = PhaseSetFactory.createDefaultPhaseSetExcluding(new String[] {PhaseSetFactory.PHASE_CHECK_TRUST, PhaseSetFactory.PHASE_CONFIGURE, PhaseSetFactory.PHASE_UNCONFIGURE});
388
		IEngine engine = P2TargetUtils.getEngine();
389
		plan.setProfileProperty(P2TargetUtils.PROP_PROVISION_MODE, TargetDefinitionPersistenceHelper.MODE_PLANNER);
390
		plan.setProfileProperty(P2TargetUtils.PROP_ALL_ENVIRONMENTS, Boolean.toString(false));
391
		IStatus result = engine.perform(plan, phases, new SubProgressMonitor(subMonitor, 140));
392
393
		if (subMonitor.isCanceled()) {
394
			return new IResolvedBundle[0];
395
		}
396
		if (!result.isOK()) {
397
			throw new CoreException(result);
398
		}
399
400
		// Now that we have a plan with all the binary and explicit bundles, do a second pass and add 
401
		// in all the source.
402
		try {
403
			planInSourceBundles(profile, context, subMonitor);
404
		} catch (CoreException e) {
405
			// XXX Review required: is adding in the source critical or optional?
406
			// We failed adding in the source so remove the intermediate profile and rethrow
407
			P2TargetUtils.getProfileRegistry().removeProfile(profile.getProfileId(), profile.getTimestamp());
408
			throw e;
409
		}
410
411
		ResolvedBundle[] resolvedBundles = updateAfterResolve(profile, definition);
412
		subMonitor.worked(10);
413
		subMonitor.done();
414
		return resolvedBundles;
415
	}
416
417
	/** 
418
	 * Update the given change request to remove anything that was explicitly installed
419
	 * including the internal source IU.  
420
	 */
421
	private void computeRemovals(IProfile profile, IProfileChangeRequest request, IInstallableUnit[] units) {
422
		// if include source is off then ensure that the source IU is removed.
423
		if (!fIncludeSource) {
424
			IInstallableUnit sourceIU = getCurrentSourceIU(profile);
425
			if (sourceIU != null)
426
				request.remove(sourceIU);
427
		}
428
		// remove everything that is marked as roots.  The plan will have the new roots added in anyway.
429
		IQuery query = new IUProfilePropertyQuery(P2TargetUtils.PROP_INSTALLED_IU, Boolean.toString(true));
430
		IQueryResult installedIUs = profile.query(query, null);
431
		request.removeAll(installedIUs.toSet());
432
	}
433
434
	// run a second pass of the planner to add in the source bundles for everything that's
435
	// in the current profile.
436
	private void planInSourceBundles(IProfile profile, ProvisioningContext context, IProgressMonitor monitor) throws CoreException {
437
		if (!fIncludeSource)
438
			return;
439
440
		SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 10);
441
		subMonitor.beginTask(Messages.IUBundleContainer_ProvisioningSourceBundles, 200);
442
443
		// create an IU that optionally and greedily requires the related source bundles.
444
		// Completely replace any source IU that may already be in place
445
		IInstallableUnit currentSourceIU = getCurrentSourceIU(profile);
446
447
		// determine the new version number.  start at 1
448
		Version sourceVersion = Version.createOSGi(1, 0, 0);
449
		if (currentSourceIU != null) {
450
			Integer major = (Integer) currentSourceIU.getVersion().getSegment(0);
451
			sourceVersion = Version.createOSGi(major.intValue() + 1, 0, 0);
452
		}
453
		IInstallableUnit sourceIU = createSourceIU(profile, sourceVersion);
454
455
		// call the planner again to add in the new source IU and all available source bundles
456
		IPlanner planner = P2TargetUtils.getPlanner();
457
		IProfileChangeRequest request = planner.createChangeRequest(profile);
458
		if (currentSourceIU != null)
459
			request.remove(currentSourceIU);
460
		request.add(sourceIU);
461
		IProvisioningPlan plan = planner.getProvisioningPlan(request, context, new SubProgressMonitor(subMonitor, 20));
462
		IStatus status = plan.getStatus();
463
		if (!status.isOK()) {
464
			throw new CoreException(status);
465
		}
466
		if (subMonitor.isCanceled()) {
467
			return;
468
		}
469
470
		long oldTimestamp = profile.getTimestamp();
471
472
		// execute the provisioning plan
473
		IPhaseSet phases = PhaseSetFactory.createDefaultPhaseSetExcluding(new String[] {PhaseSetFactory.PHASE_CHECK_TRUST, PhaseSetFactory.PHASE_CONFIGURE, PhaseSetFactory.PHASE_UNCONFIGURE, PhaseSetFactory.PHASE_UNINSTALL});
474
		IEngine engine = P2TargetUtils.getEngine();
475
		plan.setProfileProperty(P2TargetUtils.PROP_PROVISION_MODE, TargetDefinitionPersistenceHelper.MODE_PLANNER);
476
		plan.setProfileProperty(P2TargetUtils.PROP_ALL_ENVIRONMENTS, Boolean.toString(false));
477
		IStatus result = engine.perform(plan, phases, new SubProgressMonitor(subMonitor, 140));
478
479
		if (subMonitor.isCanceled()) {
480
			return;
481
		}
482
		if (!result.isOK()) {
483
			throw new CoreException(result);
484
		}
485
486
		// remove the old (intermediate) profile version now we have a new one with source.
487
		P2TargetUtils.getProfileRegistry().removeProfile(profile.getProfileId(), oldTimestamp);
488
		subMonitor.worked(10);
489
		subMonitor.done();
490
	}
491
492
	// Create and return an IU that has optional and greedy requirements on all source bundles
493
	// related to bundle IUs in the given queryable. 
494
	/**
495
	 * Creates and returns an IU that has optional and greedy requirements on all source bundles
496
	 * related to bundle IUs in the given queryable.
497
	 * @param queryable location to search for source bundle IUs
498
	 * @param iuVersion version to set on the returned installable unit
499
	 * @return a new installable unit with requirements on the available source IUs
500
	 */
501
	private IInstallableUnit createSourceIU(IQueryable queryable, Version iuVersion) {
502
		// compute the set of source bundles we could possibly need for the bundles in the profile
503
		IRequirement bundleRequirement = MetadataFactory.createRequirement("org.eclipse.equinox.p2.eclipse.type", "bundle", null, null, false, false, false); //$NON-NLS-1$ //$NON-NLS-2$
504
		IQueryResult profileIUs = queryable.query(QueryUtil.createIUAnyQuery(), null);
505
		ArrayList requirements = new ArrayList();
506
		for (Iterator i = profileIUs.iterator(); i.hasNext();) {
507
			IInstallableUnit profileIU = (IInstallableUnit) i.next();
508
			if (profileIU.satisfies(bundleRequirement)) {
509
				String id = profileIU.getId() + ".source"; //$NON-NLS-1$
510
				Version version = profileIU.getVersion();
511
				VersionRange range = new VersionRange(version, true, version, true);
512
				IRequirement sourceRequirement = MetadataFactory.createRequirement("osgi.bundle", id, range, null, true, false, true); //$NON-NLS-1$
513
				requirements.add(sourceRequirement);
514
			}
515
		}
241
		}
516
242
		fUnits = (IInstallableUnit[]) result.toArray(new IInstallableUnit[result.size()]);
517
		InstallableUnitDescription sourceDescription = new MetadataFactory.InstallableUnitDescription();
243
		return fUnits;
518
		sourceDescription.setSingleton(true);
519
		sourceDescription.setId(SOURCE_IU_ID);
520
		sourceDescription.setVersion(iuVersion);
521
		sourceDescription.addRequirements(requirements);
522
		IProvidedCapability capability = MetadataFactory.createProvidedCapability(IInstallableUnit.NAMESPACE_IU_ID, SOURCE_IU_ID, iuVersion);
523
		sourceDescription.setCapabilities(new IProvidedCapability[] {capability});
524
		return MetadataFactory.createInstallableUnit(sourceDescription);
525
	}
526
527
	/**
528
	 * Lookup and return the source IU in the given queryable or <code>null</code> if not found.
529
	 * @param queryable location to look for source IUs
530
	 * @return the source IU or <code>null</code>
531
	 */
532
	private IInstallableUnit getCurrentSourceIU(IQueryable queryable) {
533
		IQuery query = QueryUtil.createIUQuery(SOURCE_IU_ID);
534
		IQueryResult list = queryable.query(query, null);
535
		IInstallableUnit currentSourceIU = null;
536
		if (!list.isEmpty())
537
			currentSourceIU = (IInstallableUnit) list.iterator().next();
538
		return currentSourceIU;
539
	}
244
	}
540
245
541
	/**
246
	/**
542
	 * Used to resolve the contents of this container when the user has chosen to manage the dependencies in the target
247
	 * Update this container's cache of bundle objects based on the given profile.
543
	 * themselves.  The selected IUs and any required software that can be found will be retrieved from the repositories 
248
	 * NOTE: this method expects the synchronizer to be synchronized and is called
544
	 * and added to the target.  Any missing required software will be ignored.
249
	 * as a result of a synchronization operation.
545
	 * 
250
	 */
546
	 * @param definition definition being resolved
251
	IResolvedBundle[] cacheBundles() throws CoreException {
547
	 * @param monitor for reporting progress
252
		// slice the profile to find the bundles attributed to this container.
548
	 * @return set of resolved bundles included in this container
253
		// Look only for strict dependencies if we are using the slicer.
549
	 * @throws CoreException if there is a problem interacting with the repositories
254
		// We can always consider all platforms since the profile wouldn't contain it if it was not interesting
550
	 */
255
		boolean onlyStrict = !fSynchronizer.getIncludeAllRequired();
551
	private IResolvedBundle[] resolveWithSlicer(ITargetDefinition definition, IProgressMonitor monitor) throws CoreException {
256
		IProfile metadata = fSynchronizer.getProfile();
552
		SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 10);
257
		PermissiveSlicer slicer = new PermissiveSlicer(metadata, new HashMap(), true, false, true, onlyStrict, false);
553
		subMonitor.beginTask(Messages.IUBundleContainer_0, 180);
258
		IQueryable slice = slicer.slice(fUnits, new NullProgressMonitor());
554
555
		// retrieve profile
556
		IProfile profile = P2TargetUtils.getProfile(definition);
557
		subMonitor.worked(10);
558
559
		if (subMonitor.isCanceled()) {
560
			return new IResolvedBundle[0];
561
		}
562
563
		// resolve IUs
564
		IInstallableUnit[] units = getInstallableUnits(profile);
565
566
		if (subMonitor.isCanceled()) {
567
			return new IResolvedBundle[0];
568
		}
569
570
		URI[] repositories = resolveRepositories();
571
		int repoCount = repositories.length;
572
		if (repoCount == 0) {
573
			return new IResolvedBundle[0];
574
		}
575
576
		IProgressMonitor loadMonitor = new SubProgressMonitor(subMonitor, 10);
577
		loadMonitor.beginTask(null, repoCount * 10);
578
		List metadataRepos = new ArrayList(repoCount);
579
		MultiStatus repoStatus = new MultiStatus(PDECore.PLUGIN_ID, 0, Messages.IUBundleContainer_ProblemsLoadingRepositories, null);
580
		IMetadataRepositoryManager manager = P2TargetUtils.getRepoManager();
581
		for (int i = 0; i < repoCount; ++i) {
582
			try {
583
				IMetadataRepository repo = manager.loadRepository(repositories[i], new SubProgressMonitor(loadMonitor, 10));
584
				metadataRepos.add(repo);
585
			} catch (ProvisionException e) {
586
				repoStatus.add(e.getStatus());
587
			}
588
		}
589
		loadMonitor.done();
590
591
		IQueryable allMetadata;
592
		if (metadataRepos.size() == 0) {
593
			throw new CoreException(repoStatus);
594
		} else if (metadataRepos.size() == 1) {
595
			allMetadata = (IQueryable) metadataRepos.get(0);
596
		} else {
597
			allMetadata = QueryUtil.compoundQueryable(metadataRepos);
598
		}
599
600
		// do an initial slice to add everything the user requested
601
		IQueryResult queryResult = slice(units, allMetadata, definition, subMonitor);
602
		if (subMonitor.isCanceled() || queryResult == null || queryResult.isEmpty()) {
603
			return new IResolvedBundle[0];
604
		}
605
606
		// If we are including source then create a source IU to bring in the relevant source
607
		// bundles and run the slicer again.
608
		if (fIncludeSource) {
609
			// Build an IU that represents all the source bundles and slice again to add them in if available
610
			IInstallableUnit sourceIU = createSourceIU(queryResult, Version.createOSGi(1, 0, 0));
611
			IInstallableUnit[] units2 = new IInstallableUnit[units.length + 1];
612
			System.arraycopy(units, 0, units2, 0, units.length);
613
			units2[units.length] = sourceIU;
614
615
			queryResult = slice(units2, allMetadata, definition, subMonitor);
616
			if (subMonitor.isCanceled() || queryResult == null || queryResult.isEmpty()) {
617
				return new IResolvedBundle[0];
618
			}
619
		}
620
621
		IEngine engine = P2TargetUtils.getEngine();
622
		ProvisioningContext context = new ProvisioningContext(P2TargetUtils.getAgent());
623
		context.setMetadataRepositories(repositories);
624
		context.setArtifactRepositories(resolveArtifactRepositories());
625
		IProvisioningPlan plan = engine.createPlan(profile, context);
626
627
		Set newSet = queryResult.toSet();
628
		Iterator itor = newSet.iterator();
629
		while (itor.hasNext()) {
630
			plan.addInstallableUnit((IInstallableUnit) itor.next());
631
		}
632
		for (int i = 0; i < units.length; i++) {
633
			IInstallableUnit unit = units[i];
634
			plan.setInstallableUnitProfileProperty(unit, P2TargetUtils.PROP_INSTALLED_IU, Boolean.toString(true));
635
		}
636
637
		// remove all units that are in the current profile but not in the new slice
638
		Set toRemove = profile.query(QueryUtil.ALL_UNITS, null).toSet();
639
		toRemove.removeAll(newSet);
640
		for (Iterator i = toRemove.iterator(); i.hasNext();) {
641
			plan.removeInstallableUnit((IInstallableUnit) i.next());
642
		}
643
644
		plan.setProfileProperty(P2TargetUtils.PROP_PROVISION_MODE, TargetDefinitionPersistenceHelper.MODE_SLICER);
645
		plan.setProfileProperty(P2TargetUtils.PROP_ALL_ENVIRONMENTS, Boolean.toString(getIncludeAllEnvironments()));
646
647
		// execute the provisioning plan
648
		IPhaseSet phases = PhaseSetFactory.createDefaultPhaseSetExcluding(new String[] {PhaseSetFactory.PHASE_CHECK_TRUST, PhaseSetFactory.PHASE_CONFIGURE, PhaseSetFactory.PHASE_UNCONFIGURE});
649
		IStatus result = engine.perform(plan, phases, new SubProgressMonitor(subMonitor, 140));
650
651
		if (subMonitor.isCanceled()) {
652
			return new IResolvedBundle[0];
653
		}
654
		if (!result.isOK()) {
655
			throw new CoreException(result);
656
		}
657
658
		ResolvedBundle[] resolvedBundles = updateAfterResolve(profile, definition);
659
660
		subMonitor.worked(10);
661
		subMonitor.done();
662
		return resolvedBundles;
663
	}
664
665
	private ResolvedBundle[] updateAfterResolve(IProfile profile, ITargetDefinition definition) throws CoreException {
666
		// Cache the feature list
667
		queryForFeatures(profile);
668
259
669
		// query for bundles
260
		// query for bundles
670
		IFileArtifactRepository repository = null;
261
		IFileArtifactRepository artifacts = null;
671
		try {
262
		try {
672
			repository = P2TargetUtils.getBundlePool(profile);
263
			artifacts = P2TargetUtils.getBundlePool();
673
		} catch (CoreException e) {
264
		} catch (CoreException e) {
674
			if (DEBUG_PROFILE) {
265
			if (DEBUG_PROFILE) {
675
				System.out.println("Bundle pool repository could not be loaded"); //$NON-NLS-1$
266
				System.out.println("Bundle pool repository could not be loaded"); //$NON-NLS-1$
676
			}
267
			}
677
			return null;
268
			return fBundles = null;
678
		}
269
		}
679
270
680
		Map bundles = generateResolvedBundles(profile, repository, true);
271
		Map bundles = generateResolvedBundles(slice, metadata, artifacts);
681
		if (bundles == null || bundles.isEmpty()) {
272
		if (bundles.isEmpty()) {
682
			if (DEBUG_PROFILE) {
273
			if (DEBUG_PROFILE) {
683
				System.out.println("Profile does not contain any bundles or artifacts were missing"); //$NON-NLS-1$
274
				System.out.println("Profile does not contain any bundles or artifacts were missing"); //$NON-NLS-1$
684
			}
275
			}
685
			return null;
276
			return fBundles = null;
686
		}
687
688
		removeDuplicateBundles(definition, bundles);
689
		if (bundles.isEmpty()) {
690
			return null;
691
		}
277
		}
692
278
693
		return (ResolvedBundle[]) bundles.values().toArray(new ResolvedBundle[bundles.size()]);
279
		fBundles = (ResolvedBundle[]) bundles.values().toArray(new ResolvedBundle[bundles.size()]);
694
	}
280
		return fBundles;
695
696
	private IQueryResult slice(IInstallableUnit[] units, IQueryable allMetadata, ITargetDefinition definition, SubProgressMonitor subMonitor) throws CoreException {
697
		// slice IUs and all prerequisites
698
		PermissiveSlicer slicer = null;
699
		if (getIncludeAllEnvironments()) {
700
			slicer = new PermissiveSlicer(allMetadata, new HashMap(), true, false, true, true, false);
701
		} else {
702
			Map props = new HashMap();
703
			props.put("osgi.os", definition.getOS() != null ? definition.getOS() : Platform.getOS()); //$NON-NLS-1$
704
			props.put("osgi.ws", definition.getWS() != null ? definition.getWS() : Platform.getWS()); //$NON-NLS-1$
705
			props.put("osgi.arch", definition.getArch() != null ? definition.getArch() : Platform.getOSArch()); //$NON-NLS-1$
706
			props.put("osgi.nl", definition.getNL() != null ? definition.getNL() : Platform.getNL()); //$NON-NLS-1$
707
			props.put(IProfile.PROP_INSTALL_FEATURES, Boolean.TRUE.toString());
708
			slicer = new PermissiveSlicer(allMetadata, props, true, false, false, true, false);
709
		}
710
		IQueryable slice = slicer.slice(units, new SubProgressMonitor(subMonitor, 10));
711
		if (!slicer.getStatus().isOK()) {
712
			throw new CoreException(slicer.getStatus());
713
		}
714
		IQueryResult queryResult = null;
715
		if (slice != null)
716
			queryResult = slice.query(QueryUtil.createIUAnyQuery(), new SubProgressMonitor(subMonitor, 10));
717
		return queryResult;
718
	}
719
720
	/**
721
	 * Queries the given given queryable and finds all feature group IUs.  The feature id/versions of the features
722
	 * are cached in {@link #fFeatures}.
723
	 * 
724
	 * @param queryable profile/slicer/etc. to query for features
725
	 */
726
	private void queryForFeatures(IQueryable queryable) {
727
		// Query for features, cache the result for calls to resolveFeatures()
728
		// Get any IU with the group property, this will return any feature groups
729
		IQuery featureQuery = QueryUtil.createMatchQuery("properties[$0] == $1", new Object[] {MetadataFactory.InstallableUnitDescription.PROP_TYPE_GROUP, Boolean.TRUE.toString()}); //$NON-NLS-1$
730
		IQueryResult featureResult = queryable.query(featureQuery, null);
731
		List features = new ArrayList();
732
		for (Iterator iterator = featureResult.iterator(); iterator.hasNext();) {
733
			IInstallableUnit unit = (IInstallableUnit) iterator.next();
734
			String id = unit.getId();
735
			if (id.endsWith(FEATURE_ID_SUFFIX)) {
736
				id = id.substring(0, id.length() - FEATURE_ID_SUFFIX.length());
737
			}
738
			String version = unit.getVersion().toString();
739
			features.add(new NameVersionDescriptor(id, version, NameVersionDescriptor.TYPE_FEATURE));
740
		}
741
		fFeatures = (NameVersionDescriptor[]) features.toArray(new NameVersionDescriptor[features.size()]);
742
	}
281
	}
743
282
744
	/**
283
	/*
745
	 * Returns the IU's this container references. Checks in the profile first to avoid
284
	 * Respond to the notification that the synchronizer associated with this container has changed
746
	 * going out to repositories.
285
	 * This is a callback method used by the synchronizer.
747
	 * 
286
	 * It should NOT be called any other time.
748
	 * @param profile profile to check first
749
	 * @return IU's
750
	 * @exception CoreException if unable to retrieve IU's
751
	 */
287
	 */
752
	public synchronized IInstallableUnit[] getInstallableUnits(IProfile profile) throws CoreException {
288
	void synchronizerChanged() throws CoreException {
753
		if (fUnits == null) {
289
		// cache the IUs first as they are used to slice the profile for the other caches.
754
			fUnits = new IInstallableUnit[fIds.length];
290
		cacheIUs();
755
			for (int i = 0; i < fIds.length; i++) {
291
		cacheBundles();
756
				IQuery query = QueryUtil.createIUQuery(fIds[i], fVersions[i]);
292
		cacheFeatures();
757
				IQueryResult queryResult = profile.query(query, null);
758
				if (queryResult.isEmpty()) {
759
					// try repositories
760
					URI[] repositories = resolveRepositories();
761
					for (int j = 0; j < repositories.length; j++) {
762
						try {
763
							IMetadataRepository repository = P2TargetUtils.getRepository(repositories[j]);
764
							queryResult = repository.query(query, null);
765
							if (!queryResult.isEmpty()) {
766
								break;
767
							}
768
						} catch (ProvisionException e) {
769
							// Ignore and move on to the next site
770
						}
771
					}
772
				}
773
				if (queryResult.isEmpty()) {
774
					// not found
775
					fUnits = null;
776
					throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.IUBundleContainer_1, fIds[i])));
777
				}
778
				fUnits[i] = (IInstallableUnit) queryResult.iterator().next();
779
			}
780
		}
781
		return fUnits;
782
	}
783
784
	private IMetadataRepository[] getRepos() throws CoreException {
785
		URI[] repos = resolveRepositories();
786
		IMetadataRepository[] result = new IMetadataRepository[repos.length];
787
		for (int i = 0; i < repos.length; i++)
788
			result[i] = P2TargetUtils.getRepository(repos[i]);
789
		return result;
790
	}
293
	}
791
294
792
	/**
295
	/**
Lines 794-804 Link Here
794
	 * 
297
	 * 
795
	 * @param toUpdate the set of IU ids in this container to consider updating.  If null
298
	 * @param toUpdate the set of IU ids in this container to consider updating.  If null
796
	 * then update everything
299
	 * then update everything
797
	 * @return a bitmasked int indicating how/if this container changed.  See {@link UpdateTargetJob#DIRTY} and {@link UpdateTargetJob#UPDATED}. 
300
	 * @return a bitmasked int indicating how/if this container changed.  See DIRTY and UPDATED. 
798
	 * @exception CoreException if unable to retrieve IU's
301
	 * @exception CoreException if unable to retrieve IU's
799
	 */
302
	 */
800
	public synchronized int update(Set toUpdate) throws CoreException {
303
	public synchronized int update(Set toUpdate) throws CoreException {
801
		IQueryable source = new CompoundQueryable(getRepos());
304
		IQueryable source = fSynchronizer.getQueryableMetadata(fRepos, null);
802
		int dirty = 0;
305
		int dirty = 0;
803
		int updated = 0;
306
		int updated = 0;
804
		for (int i = 0; i < fIds.length; i++) {
307
		for (int i = 0; i < fIds.length; i++) {
Lines 811-817 Link Here
811
			if (!it.hasNext())
314
			if (!it.hasNext())
812
				throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.IUBundleContainer_1, fIds[i])));
315
				throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.IUBundleContainer_1, fIds[i])));
813
			IInstallableUnit iu = (IInstallableUnit) it.next();
316
			IInstallableUnit iu = (IInstallableUnit) it.next();
814
			fUnits[i] = iu;
815
			// if the version is different from the spec (up or down), record the change.
317
			// if the version is different from the spec (up or down), record the change.
816
			if (!iu.getVersion().equals(fVersions[i])) {
318
			if (!iu.getVersion().equals(fVersions[i])) {
817
				updated = UpdateTargetJob.UPDATED;
319
				updated = UpdateTargetJob.UPDATED;
Lines 826-912 Link Here
826
	}
328
	}
827
329
828
	/**
330
	/**
829
	 * Checks all other bundle containers in the given target and removes any bundles provided by them from
830
	 * the map.  This prevents targets containing more than one IUBundleContainer from having duplicate bundles.
831
	 * 
832
	 * @param definition target definition to look for other containers in
833
	 * @param bundles collection of bundles arranged by mapping BundleInfo to IResolvedBundle
834
	 */
835
	private void removeDuplicateBundles(ITargetDefinition definition, Map bundles) {
836
		// remove all bundles from previous IU containers (so we don't get duplicates from multi-locations
837
		IBundleContainer[] containers = definition.getBundleContainers();
838
		for (int i = 0; i < containers.length; i++) {
839
			IBundleContainer container = containers[i];
840
			if (container == this) {
841
				break;
842
			}
843
			if (container instanceof IUBundleContainer) {
844
				IUBundleContainer bc = (IUBundleContainer) container;
845
				IResolvedBundle[] included = bc.getBundles();
846
				if (included != null) {
847
					for (int j = 0; j < included.length; j++) {
848
						bundles.remove(included[j].getBundleInfo());
849
					}
850
				}
851
			}
852
		}
853
	}
854
855
	/**
856
	 * Collects all available installable units from the given source that represent OSGI
331
	 * Collects all available installable units from the given source that represent OSGI
857
	 * bundles.  A IResolvedBundle is created for each and a map containing all results
332
	 * bundles.  A IResolvedBundle is created for each and a map containing all results
858
	 * mapping BundleInfo to IResolvedBundle is returned.
333
	 * mapping BundleInfo to IResolvedBundle is returned.
859
	 * <p>
334
	 * <p>
860
	 * If there is an artifact missing for a unit it will either be ignored (not added to the returned map),
335
	 * If there is an artifact missing for a unit it will be ignored (not added to the returned map).
861
	 * or <code>null</code> will be returned depending on the ignoreMissingFiles parameter. 
336
	 * If this container is setup to automatically include source, an corresponding source bundles
337
	 * found in the given profile will also be added as resolved bundles. 
862
	 * </p>
338
	 * </p>
863
	 * @param source A queryable profile or slice that the bundle units will be obtained from
339
	 * @param source the bundle units to be converted
864
	 * @param ignoreMissingFiles if <code>true</code> ius that have missing artifacts will be ignored and not added to the map, if <code>false</code>, <code>null</code> will be returned
340
	 * @param metadata the metadata backing the conversion
865
	 * @return map of BundleInfo to IResolvedBundle or <code>null</code> if a missing file is found and not ignored
341
	 * @param artifacts the underlying artifact repo against which the bundles are validated
342
	 * @return map of BundleInfo to IResolvedBundle
866
	 * @throws CoreException
343
	 * @throws CoreException
867
	 */
344
	 */
868
	private Map generateResolvedBundles(IQueryable source, IFileArtifactRepository repo, boolean ignoreMissingFiles) throws CoreException {
345
	private Map generateResolvedBundles(IQueryable source, IQueryable metadata, IFileArtifactRepository artifacts) throws CoreException {
869
		OSGiBundleQuery query = new OSGiBundleQuery();
346
		OSGiBundleQuery query = new OSGiBundleQuery();
870
		IQueryResult queryResult = source.query(query, null);
347
		IQueryResult queryResult = source.query(query, null);
871
		Map bundles = new LinkedHashMap();
348
		Map bundles = new LinkedHashMap();
872
		for (Iterator iterator = queryResult.iterator(); iterator.hasNext();) {
349
		for (Iterator i = queryResult.iterator(); i.hasNext();) {
873
			IInstallableUnit unit = (IInstallableUnit) iterator.next();
350
			IInstallableUnit unit = (IInstallableUnit) i.next();
874
			Collection artifacts = unit.getArtifacts();
351
			generateBundle(unit, artifacts, bundles);
875
			for (Iterator iterator2 = artifacts.iterator(); iterator2.hasNext();) {
352
			if (getIncludeSource()) {
876
				File file = repo.getArtifactFile((IArtifactKey) iterator2.next());
353
				// bit of a hack using the bundle naming convention for finding source bundles
877
				if (file == null) {
354
				// but this matches what we do when adding source to the profile so...
878
					// Missing file
355
				IQuery sourceQuery = QueryUtil.createIUQuery(unit.getId() + ".source", unit.getVersion()); //$NON-NLS-1$
879
					if (!ignoreMissingFiles) {
356
				IQueryResult result = metadata.query(sourceQuery, null);
880
						if (DEBUG_PROFILE) {
357
				if (!result.isEmpty()) {
881
							System.out.println("Backing file missing for: " + unit.getId()); //$NON-NLS-1$
358
					generateBundle((IInstallableUnit) result.iterator().next(), artifacts, bundles);
882
						}
883
						return null;
884
					}
885
				} else {
886
					IResolvedBundle bundle = generateBundle(file);
887
					if (bundle != null) {
888
						bundles.put(bundle.getBundleInfo(), bundle);
889
					}
890
				}
359
				}
891
			}
360
			}
892
		}
361
		}
893
		return bundles;
362
		return bundles;
894
	}
363
	}
895
364
365
	private void generateBundle(IInstallableUnit unit, IFileArtifactRepository repo, Map bundles) throws CoreException {
366
		Collection artifacts = unit.getArtifacts();
367
		for (Iterator iterator2 = artifacts.iterator(); iterator2.hasNext();) {
368
			File file = repo.getArtifactFile((IArtifactKey) iterator2.next());
369
			if (file != null) {
370
				IResolvedBundle bundle = generateBundle(file);
371
				if (bundle != null) {
372
					bundles.put(bundle.getBundleInfo(), bundle);
373
				}
374
			}
375
		}
376
	}
377
896
	/* (non-Javadoc)
378
	/* (non-Javadoc)
897
	 * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#isContentEqual(org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer)
379
	 * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#isContentEqual(org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer)
898
	 */
380
	 */
899
	public boolean isContentEqual(AbstractBundleContainer container) {
381
	public boolean isContentEqual(AbstractBundleContainer container) {
900
		if (container instanceof IUBundleContainer) {
382
		if (container instanceof IUBundleContainer) {
901
			IUBundleContainer iuContainer = (IUBundleContainer) container;
383
			IUBundleContainer iuContainer = (IUBundleContainer) container;
902
			if (iuContainer.getIncludeAllRequired() == getIncludeAllRequired()) {
384
			boolean result = true;
903
				// include all targets only matters if include all required is turned off
385
			result &= iuContainer.getIncludeAllRequired() == getIncludeAllRequired();
904
				if (getIncludeAllRequired() || iuContainer.getIncludeAllEnvironments() == getIncludeAllEnvironments()) {
386
			result &= iuContainer.getIncludeAllEnvironments() == getIncludeAllEnvironments();
905
					return isEqualOrNull(fIds, iuContainer.fIds) && isEqualOrNull(fVersions, iuContainer.fVersions) && isEqualOrNull(fRepos, iuContainer.fRepos);
387
			result &= iuContainer.getIncludeSource() == getIncludeSource();
906
				}
388
			return result && isEqualOrNull(fIds, iuContainer.fIds) && isEqualOrNull(fVersions, iuContainer.fVersions) && isEqualOrNull(fRepos, iuContainer.fRepos);
907
			}
908
			if (fIncludeSource != iuContainer.getIncludeSource())
909
				return false;
910
		}
389
		}
911
		return false;
390
		return false;
912
	}
391
	}
Lines 947-1087 Link Here
947
	}
426
	}
948
427
949
	/**
428
	/**
950
	 * Returns the repositories to consider when resolving IU's (will return default set of
429
	 * Removes an installable unit from this container.  The container will no longer be resolved.
951
	 * repositories if current repository settings are <code>null</code>).
952
	 *  
953
	 * @return URI's of repositories to use when resolving bundles
954
	 * @exception CoreException
955
	 */
956
	private URI[] resolveRepositories() throws CoreException {
957
		if (fRepos == null) {
958
			IMetadataRepositoryManager manager = P2TargetUtils.getRepoManager();
959
			return manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL);
960
		}
961
		return fRepos;
962
	}
963
964
	/**
965
	 * Returns the artifact repositories to consider when getting artifacts.  Returns a default set of
966
	 * repositories if current repository settings are <code>null</code>).
967
	 *  
430
	 *  
968
	 * @return URI's of repositories to use when getting artifacts
431
	 * @param unit unit to remove from the list of root IUs
969
	 * @exception CoreException
970
	 */
971
	private URI[] resolveArtifactRepositories() throws CoreException {
972
		URI[] repositories = fRepos;
973
		if (fRepos == null) {
974
			IArtifactRepositoryManager manager = P2TargetUtils.getArtifactRepositoryManager();
975
			repositories = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL);
976
		}
977
		if (!useAdditionalLocalArtifacts())
978
			return repositories;
979
		Set additionalRepos = new HashSet(Arrays.asList(repositories));
980
		findProfileRepos(additionalRepos);
981
		findWorkspaceRepos(additionalRepos);
982
		return (URI[]) additionalRepos.toArray(new URI[additionalRepos.size()]);
983
	}
984
985
	/**
986
	 * @return whether to use local artifact repositories when provisioning the target
987
	 */
988
	private boolean useAdditionalLocalArtifacts() {
989
		// TODO consider using a preference here or another strategy if users are able to spec 
990
		// what local repos are to be considered.
991
		return true;
992
	}
993
994
	/** 
995
	 * Add the artifact repos from the PDE target bundle pools from all known repos.  For example, the list 
996
	 * of "recent workspaces" maintained by the IDE is a good source.
997
	 * 
998
	 * @param additionalRepos the set to which additional repos are added.
999
	 */
1000
	private void findWorkspaceRepos(Set additionalRepos) {
1001
		IPreferencesService prefs = P2TargetUtils.getPreferences();
1002
		if (prefs == null)
1003
			return;
1004
		String recent = prefs.getString("org.eclipse.ui.ide", "RECENT_WORKSPACES", null, null); //$NON-NLS-1$ //$NON-NLS-2$
1005
		if (recent == null)
1006
			return;
1007
		String[] recents = recent.split("\n"); //$NON-NLS-1$
1008
		for (int i = 0; i < recents.length; i++) {
1009
			String bundlePool = recents[i] + "/.metadata/.plugins/org.eclipse.pde.core/.bundle_pool"; //$NON-NLS-1$
1010
			if (new File(bundlePool).exists()) {
1011
				URI uri;
1012
				try {
1013
					uri = new URI("file", bundlePool, null); //$NON-NLS-1$
1014
					additionalRepos.add(uri);
1015
				} catch (URISyntaxException e) {
1016
					// should never happen
1017
				}
1018
			}
1019
		}
1020
	}
1021
1022
	/** 
1023
	 * Look through the current p2 profile (_SELF_) and add the artifact repos that make up its
1024
	 * bundle pool, dropins location, ...  This helps in the cases that you are targeting stuff that 
1025
	 * makes up your current IDE.
1026
	 * 
1027
	 * @param additionalRepos the set to which additional repos are added.
1028
	 */
432
	 */
1029
	private void findProfileRepos(Set additionalRepos) {
433
	public synchronized void removeInstallableUnit(IInstallableUnit unit) {
1030
		try {
434
		List newIds = new ArrayList(fIds.length);
1031
			// NOTE: be sure to use the global p2 agent here as we are looking for SELF.
435
		List newVersions = new ArrayList(fIds.length);
1032
			IProfileRegistry profileRegistry = (IProfileRegistry) P2TargetUtils.getGlobalAgent().getService(IProfileRegistry.SERVICE_NAME);
436
		for (int i = 0; i < fIds.length; i++) {
1033
			if (profileRegistry == null)
437
			if (fIds[i].equals(unit.getId()) && fVersions[i].equals(unit.getVersion())) {
1034
				return;
438
				newIds.add(fIds[i]);
1035
			IProfile self = profileRegistry.getProfile(IProfileRegistry.SELF);
439
				newVersions.add(fVersions[i]);
1036
			if (self == null)
1037
				return;
1038
1039
			IAgentLocation location = (IAgentLocation) P2TargetUtils.getGlobalAgent().getService(IAgentLocation.SERVICE_NAME);
1040
			URI dataArea = location.getDataArea("org.eclipse.equinox.p2.engine"); //$NON-NLS-1$
1041
			dataArea = URIUtil.append(dataArea, "profileRegistry/" + self.getProfileId() + ".profile"); //$NON-NLS-1$//$NON-NLS-2$
1042
			ProfileMetadataRepository profileRepo = new ProfileMetadataRepository(P2TargetUtils.getGlobalAgent(), dataArea, null);
1043
			Collection repos = profileRepo.getReferences();
1044
			for (Iterator i = repos.iterator(); i.hasNext();) {
1045
				Object element = i.next();
1046
				if (element instanceof IRepositoryReference) {
1047
					IRepositoryReference reference = (IRepositoryReference) element;
1048
					if (reference.getType() == IRepository.TYPE_ARTIFACT && reference.getLocation() != null)
1049
						additionalRepos.add(reference.getLocation());
1050
				}
1051
			}
440
			}
1052
		} catch (CoreException e) {
1053
			// if there is a problem, move on.  Could log something here 
1054
			return;
1055
		}
441
		}
1056
	}
442
		fIds = (String[]) newIds.toArray(new String[newIds.size()]);
443
		fVersions = (Version[]) newVersions.toArray(new Version[newVersions.size()]);
1057
444
1058
	/**
445
		// Need to mark the container as unresolved
1059
	 * Sets whether all required units must be available to resolve this container.  When <code>true</code>
446
		clearResolutionStatus();
1060
	 * the resolve operation will use the planner to determine the complete set of IUs required to
1061
	 * make the selected IUs runnable.  If any dependencies are missing, the resolve operation will return an
1062
	 * error explaining what problems exist.  When <code>false</code> the resolve operation will use the slicer
1063
	 * to determine what units to include.  Any required units that are not available in the repositories will
1064
	 * be ignored.
1065
	 * <p>
1066
	 * Since there is only one profile per target and the planner and slicer resolve methods are incompatible
1067
	 * it is highly recommended that the parent target be passed to this method so all other IUBundleContainers
1068
	 * in the target can be updated with the new setting. 
1069
	 * </p>
1070
	 * @param include whether all required units must be available to resolve this container
1071
	 * @param definition parent target, used to update other IUBundleContainers with this setting, can be <code>null</code>
1072
	 */
1073
	public void setIncludeAllRequired(boolean include, ITargetDefinition definition) {
1074
		fIncludeAllRequired = include;
1075
		if (definition != null) {
1076
			IBundleContainer[] containers = definition.getBundleContainers();
1077
			if (containers != null) {
1078
				for (int i = 0; i < containers.length; i++) {
1079
					if (containers[i] instanceof IUBundleContainer && containers[i] != this) {
1080
						((IUBundleContainer) containers[i]).setIncludeAllRequired(include, null);
1081
					}
1082
				}
1083
			}
1084
		}
1085
	}
447
	}
1086
448
1087
	/**
449
	/**
Lines 1095-1129 Link Here
1095
	 * @return whether all required units must be available to resolve this container
457
	 * @return whether all required units must be available to resolve this container
1096
	 */
458
	 */
1097
	public boolean getIncludeAllRequired() {
459
	public boolean getIncludeAllRequired() {
1098
		return fIncludeAllRequired;
460
		// if this container has not been associated with a container, return its own value
1099
	}
461
		if (fSynchronizer == null)
1100
462
			return (fFlags & INCLUDE_REQUIRED) == INCLUDE_REQUIRED;
1101
	/**
463
		return fSynchronizer.getIncludeAllRequired();
1102
	 * Sets whether all environment (platform) specific installable units should
1103
	 * be included in this container when it is resolved.  This feature is not supported
1104
	 * by the planner so will only have an effect if the include all required setting
1105
	 * is turned off ({@link #getIncludeAllRequired()}).
1106
	 * <p>
1107
	 * There is only one profile per target and this setting can only be set for the
1108
	 * entire target definition.  It is highly recommended that the parent target be passed
1109
	 * to this method so all other IUBundleContainers in the target can be updated with the 
1110
	 * new setting. 
1111
	 * </p>
1112
	 * @param include whether environment specific units should be included
1113
	 * @param definition parent target, used to update other IUBundleContainers with this setting, can be <code>null</code>
1114
	 */
1115
	public void setIncludeAllEnvironments(boolean include, ITargetDefinition definition) {
1116
		fIncludeMultipleEnvironments = include;
1117
		if (definition != null) {
1118
			IBundleContainer[] containers = definition.getBundleContainers();
1119
			if (containers != null) {
1120
				for (int i = 0; i < containers.length; i++) {
1121
					if (containers[i] instanceof IUBundleContainer && containers[i] != this) {
1122
						((IUBundleContainer) containers[i]).setIncludeAllEnvironments(include, null);
1123
					}
1124
				}
1125
			}
1126
		}
1127
	}
464
	}
1128
465
1129
	/**
466
	/**
Lines 1135-1151 Link Here
1135
	 * @return whether environment specific units should be included
472
	 * @return whether environment specific units should be included
1136
	 */
473
	 */
1137
	public boolean getIncludeAllEnvironments() {
474
	public boolean getIncludeAllEnvironments() {
1138
		return fIncludeMultipleEnvironments;
475
		// if this container has not been associated with a container, return its own value
1139
	}
476
		if (fSynchronizer == null)
1140
477
			return (fFlags & INCLUDE_ALL_ENVIRONMENTS) == INCLUDE_ALL_ENVIRONMENTS;
1141
	/**
478
		return fSynchronizer.getIncludeAllEnvironments();
1142
	 * Set whether or not the source bundles corresponding to any binary bundles should
1143
	 * be automatically included in the target.
1144
	 * 
1145
	 * @param value whether or not to include source
1146
	 */
1147
	public void setIncludeSource(boolean value) {
1148
		fIncludeSource = value;
1149
	}
479
	}
1150
480
1151
	/**
481
	/**
Lines 1155-1184 Link Here
1155
	 * @return whether or not source is included automatically
485
	 * @return whether or not source is included automatically
1156
	 */
486
	 */
1157
	public boolean getIncludeSource() {
487
	public boolean getIncludeSource() {
1158
		return fIncludeSource;
488
		// if this container has not been associated with a container, return its own value
489
		if (fSynchronizer == null)
490
			return (fFlags & INCLUDE_SOURCE) == INCLUDE_SOURCE;
491
		return fSynchronizer.getIncludeSource();
1159
	}
492
	}
1160
493
1161
	/**
494
	/**
1162
	 * Removes an installable unit from this container.  The container will no longer be resolved.
495
	 * Returns the installable units defined by this container
1163
	 *  
496
	 * 
1164
	 * @param unit unit to remove from the list of root IUs
497
	 * @return the discovered IUs
498
	 * @exception CoreException if unable to retrieve IU's
1165
	 */
499
	 */
1166
	public void removeInstallableUnit(IInstallableUnit unit) {
500
	public IInstallableUnit[] getInstallableUnits() throws CoreException {
1167
		List newUnits = new ArrayList(fUnits.length);
501
		if (fUnits == null)
1168
		for (int i = 0; i < fUnits.length; i++) {
502
			return new IInstallableUnit[0];
1169
			if (!fUnits[i].equals(unit)) {
503
		return fUnits;
1170
				newUnits.add(fUnits[i]);
1171
			}
1172
		}
1173
		fUnits = (IInstallableUnit[]) newUnits.toArray(new IInstallableUnit[newUnits.size()]);
1174
		fIds = new String[fUnits.length];
1175
		fVersions = new Version[fUnits.length];
1176
		for (int i = 0; i < fUnits.length; i++) {
1177
			fIds[i] = fUnits[i].getId();
1178
			fVersions[i] = fUnits[i].getVersion();
1179
		}
1180
		// Need to mark the container as unresolved
1181
		clearResolutionStatus();
1182
	}
504
	}
1183
505
1184
	/**
506
	/**
Lines 1199-1202 Link Here
1199
		return fVersions;
521
		return fVersions;
1200
	}
522
	}
1201
523
524
	/**
525
	 * Return the synchronizer for this container.  If there isn't one and a target definition is 
526
	 * supplied, then get/create the one used by the target and the other containers.
527
	 */
528
	P2TargetUtils getSynchronizer(ITargetDefinition definition) {
529
		if (fSynchronizer != null) {
530
			return fSynchronizer;
531
		}
532
		if (definition == null)
533
			return null;
534
		return fSynchronizer = P2TargetUtils.getSynchronizer(definition);
535
	}
536
537
	/**
538
	 * Callback method used by the synchronizer to associate containers with 
539
	 * synchronizers.
540
	 */
541
	void setSynchronizer(P2TargetUtils value) {
542
		fSynchronizer = value;
543
	}
544
545
	/**
546
	 * Associate this container with the given target.  The include settings for this container
547
	 * override the settings for all other IU containers in the target.  Last one wins.
548
	 */
549
	protected void associateWithTarget(ITargetDefinition target) {
550
		super.associateWithTarget(target);
551
		fSynchronizer = getSynchronizer(target);
552
		fSynchronizer.setIncludeAllRequired((fFlags & INCLUDE_REQUIRED) == INCLUDE_REQUIRED);
553
		fSynchronizer.setIncludeAllEnvironments((fFlags & INCLUDE_ALL_ENVIRONMENTS) == INCLUDE_ALL_ENVIRONMENTS);
554
		fSynchronizer.setIncludeSource((fFlags & INCLUDE_SOURCE) == INCLUDE_SOURCE);
555
	}
1202
}
556
}
(-)src/org/eclipse/pde/internal/core/target/Messages.java (+1 lines)
Lines 34-39 Link Here
34
	public static String IUBundleContainer_0;
34
	public static String IUBundleContainer_0;
35
	public static String IUBundleContainer_1;
35
	public static String IUBundleContainer_1;
36
	public static String IUBundleContainer_10;
36
	public static String IUBundleContainer_10;
37
	public static String IUBundleContainer_11;
37
	public static String IUBundleContainer_2;
38
	public static String IUBundleContainer_2;
38
	public static String IUBundleContainer_3;
39
	public static String IUBundleContainer_3;
39
	public static String IUBundleContainer_4;
40
	public static String IUBundleContainer_4;
(-)src/org/eclipse/pde/internal/core/target/Messages.properties (-2 / +3 lines)
Lines 25-38 Link Here
25
FeatureBundleContainer_5=Plug-ins directory does not exist for feature {0}
25
FeatureBundleContainer_5=Plug-ins directory does not exist for feature {0}
26
IUBundleContainer_0=Provisioning target
26
IUBundleContainer_0=Provisioning target
27
IUBundleContainer_1=Unable to locate installable unit {0}
27
IUBundleContainer_1=Unable to locate installable unit {0}
28
IUBundleContainer_10=Provisioning Agent service not found
28
IUBundleContainer_10=Provisioning Agent Location service not found
29
IUBundleContainer_11=Global Provisioning Agent service not found
29
IUBundleContainer_2=Metadata repository service not found
30
IUBundleContainer_2=Metadata repository service not found
30
IUBundleContainer_3=Artifact respository service not found
31
IUBundleContainer_3=Artifact respository service not found
31
IUBundleContainer_4=Provisioning engine not found
32
IUBundleContainer_4=Provisioning engine not found
32
IUBundleContainer_5=Provisioning planner not found
33
IUBundleContainer_5=Provisioning planner not found
33
IUBundleContainer_6=Target provisioning skipped install plan
34
IUBundleContainer_6=Target provisioning skipped install plan
34
IUBundleContainer_7=Provisioning agent not found
35
IUBundleContainer_7=Provisioning agent not found
35
IUBundleContainer_8=Profile registry service not found
36
IUBundleContainer_8=Profile Registry service not found
36
IUBundleContainer_9=Garbage Collector service not found
37
IUBundleContainer_9=Garbage Collector service not found
37
IUBundleContainer_LoadingFromProfileJob=Loading target information from profile
38
IUBundleContainer_LoadingFromProfileJob=Loading target information from profile
38
IUBundleContainer_NoBundlePool=No location for downloaded bundles could be found.
39
IUBundleContainer_NoBundlePool=No location for downloaded bundles could be found.
(-)src/org/eclipse/pde/internal/core/target/P2TargetUtils.java (-145 / +979 lines)
Lines 12-38 Link Here
12
12
13
import java.io.File;
13
import java.io.File;
14
import java.net.URI;
14
import java.net.URI;
15
import java.net.URISyntaxException;
15
import java.util.*;
16
import java.util.*;
16
import org.eclipse.core.runtime.*;
17
import org.eclipse.core.runtime.*;
17
import org.eclipse.core.runtime.preferences.IPreferencesService;
18
import org.eclipse.core.runtime.preferences.IPreferencesService;
19
import org.eclipse.equinox.internal.p2.director.PermissiveSlicer;
20
import org.eclipse.equinox.internal.p2.engine.*;
21
import org.eclipse.equinox.internal.p2.engine.phases.*;
18
import org.eclipse.equinox.internal.p2.garbagecollector.GarbageCollector;
22
import org.eclipse.equinox.internal.p2.garbagecollector.GarbageCollector;
19
import org.eclipse.equinox.p2.core.*;
23
import org.eclipse.equinox.p2.core.*;
20
import org.eclipse.equinox.p2.engine.*;
24
import org.eclipse.equinox.p2.engine.*;
21
import org.eclipse.equinox.p2.engine.query.IUProfilePropertyQuery;
25
import org.eclipse.equinox.p2.engine.query.IUProfilePropertyQuery;
22
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
26
import org.eclipse.equinox.p2.engine.spi.ProvisioningAction;
27
import org.eclipse.equinox.p2.metadata.*;
28
import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription;
23
import org.eclipse.equinox.p2.metadata.Version;
29
import org.eclipse.equinox.p2.metadata.Version;
24
import org.eclipse.equinox.p2.planner.IPlanner;
30
import org.eclipse.equinox.p2.planner.IPlanner;
25
import org.eclipse.equinox.p2.query.IQueryResult;
31
import org.eclipse.equinox.p2.planner.IProfileChangeRequest;
26
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager;
32
import org.eclipse.equinox.p2.query.*;
27
import org.eclipse.equinox.p2.repository.artifact.IFileArtifactRepository;
33
import org.eclipse.equinox.p2.repository.*;
28
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
34
import org.eclipse.equinox.p2.repository.artifact.*;
29
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
35
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
36
import org.eclipse.osgi.util.NLS;
30
import org.eclipse.pde.internal.core.PDECore;
37
import org.eclipse.pde.internal.core.PDECore;
31
import org.eclipse.pde.internal.core.target.provisional.*;
38
import org.eclipse.pde.internal.core.target.provisional.*;
32
import org.osgi.framework.*;
39
import org.osgi.framework.*;
33
40
34
public class P2TargetUtils {
41
public class P2TargetUtils {
35
42
43
	private static final String SOURCE_IU_ID = "org.eclipse.pde.core.target.source.bundles"; //$NON-NLS-1$
44
36
	/**
45
	/**
37
	 * URI to the local directory where the p2 agent keeps its information.
46
	 * URI to the local directory where the p2 agent keeps its information.
38
	 */
47
	 */
Lines 81-86 Link Here
81
	static final String PROP_ALL_ENVIRONMENTS = PDECore.PLUGIN_ID + ".all_environments"; //$NON-NLS-1$	
90
	static final String PROP_ALL_ENVIRONMENTS = PDECore.PLUGIN_ID + ".all_environments"; //$NON-NLS-1$	
82
91
83
	/**
92
	/**
93
	 * Profile property that keeps track of the target sequence number
94
	 */
95
	static final String PROP_SEQUENCE_NUMBER = PDECore.PLUGIN_ID + ".sequence"; //$NON-NLS-1$	
96
97
	/**
98
	 * Profile property that tracks whether or not source to be auto-included
99
	 */
100
	static final String PROP_AUTO_INCLUDE_SOURCE = PDECore.PLUGIN_ID + ".autoIncludeSource"; //$NON-NLS-1$	
101
102
	/** 
103
	 * The profile to be synchronized
104
	 */
105
	private IProfile fProfile;
106
107
	/**
108
	 * The target to be synchronized.
109
	 */
110
	private ITargetDefinition fTarget;
111
112
	/**
113
	 * Whether this container must have all required IUs of the selected IUs available and included
114
	 * in the target to resolve successfully.  If this option is true, the planner will be used to resolve
115
	 * otherwise the slicer is used.  The planner can describe any missing requirements as errors.
116
	 * <p>
117
	 * <code>true</code> by default
118
	 * </p>
119
	 */
120
	private boolean fIncludeAllRequired = true;
121
122
	/**
123
	 * Whether this container should download and include environment (platform) specific units for all
124
	 * available platforms (vs only the current target definition's environment settings).  Only supported 
125
	 * by the slicer so {@link fIncludeAllRequired} must be turned off for this setting to be used.
126
	 * <p>
127
	 * <code>false</code> by default
128
	 * </p>
129
	 */
130
	private boolean fIncludeMultipleEnvironments = false;
131
132
	/**
133
	 * Whether this container should download and include source bundles for the selected units if the associated
134
	 * source is available in the repository.
135
	 * <p>
136
	 * <code>false</code>by default
137
	 */
138
	private boolean fIncludeSource = false;
139
140
	public P2TargetUtils(ITargetDefinition target) {
141
		fTarget = target;
142
	}
143
144
	/**
84
	 * Deletes any profiles associated with target definitions that no longer exist
145
	 * Deletes any profiles associated with target definitions that no longer exist
85
	 * and returns a list of profile identifiers that were deleted.
146
	 * and returns a list of profile identifiers that were deleted.
86
	 */
147
	 */
Lines 93-100 Link Here
93
			for (int i = 0; i < profiles.length; i++) {
154
			for (int i = 0; i < profiles.length; i++) {
94
				IProfile profile = profiles[i];
155
				IProfile profile = profiles[i];
95
				String id = profile.getProfileId();
156
				String id = profile.getProfileId();
96
				if (id.startsWith(P2TargetUtils.PROFILE_ID_PREFIX)) {
157
				if (id.startsWith(PROFILE_ID_PREFIX)) {
97
					String memento = id.substring(P2TargetUtils.PROFILE_ID_PREFIX.length());
158
					String memento = id.substring(PROFILE_ID_PREFIX.length());
98
					ITargetHandle handle = tps.getTarget(memento);
159
					ITargetHandle handle = tps.getTarget(memento);
99
					if (!handle.exists()) {
160
					if (!handle.exists()) {
100
						deleteProfile(handle);
161
						deleteProfile(handle);
Lines 154-160 Link Here
154
		try {
215
		try {
155
			IProfile[] profiles = getProfileRegistry().getProfiles();
216
			IProfile[] profiles = getProfileRegistry().getProfiles();
156
			for (int i = 0; i < profiles.length; i++) {
217
			for (int i = 0; i < profiles.length; i++) {
157
				if (profiles[i].getProfileId().startsWith(P2TargetUtils.PROFILE_ID_PREFIX)) {
218
				if (profiles[i].getProfileId().startsWith(PROFILE_ID_PREFIX)) {
158
					getGarbageCollector().runGC(profiles[i]);
219
					getGarbageCollector().runGC(profiles[i]);
159
				}
220
				}
160
			}
221
			}
Lines 169-175 Link Here
169
	 * 
230
	 * 
170
	 * @return environment properties
231
	 * @return environment properties
171
	 */
232
	 */
172
	private static String generateEnvironmentProperties(ITargetDefinition target) {
233
	private String generateEnvironmentProperties(ITargetDefinition target) {
173
		// TODO: are there constants for these keys?
234
		// TODO: are there constants for these keys?
174
		StringBuffer env = new StringBuffer();
235
		StringBuffer env = new StringBuffer();
175
		String ws = target.getWS();
236
		String ws = target.getWS();
Lines 200-206 Link Here
200
	 * 
261
	 * 
201
	 * @return NL profile property
262
	 * @return NL profile property
202
	 */
263
	 */
203
	private static String generateNLProperty(ITargetDefinition target) {
264
	private String generateNLProperty(ITargetDefinition target) {
204
		String nl = target.getNL();
265
		String nl = target.getNL();
205
		if (nl == null) {
266
		if (nl == null) {
206
			nl = Platform.getNL();
267
			nl = Platform.getNL();
Lines 246-252 Link Here
246
	public static IProvisioningAgent getGlobalAgent() throws CoreException {
307
	public static IProvisioningAgent getGlobalAgent() throws CoreException {
247
		IProvisioningAgent agent = (IProvisioningAgent) PDECore.getDefault().acquireService(IProvisioningAgent.SERVICE_NAME);
308
		IProvisioningAgent agent = (IProvisioningAgent) PDECore.getDefault().acquireService(IProvisioningAgent.SERVICE_NAME);
248
		if (agent == null)
309
		if (agent == null)
249
			throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_10));
310
			throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_11));
250
		return agent;
311
		return agent;
251
	}
312
	}
252
313
Lines 278-299 Link Here
278
	}
339
	}
279
340
280
	/**
341
	/**
281
	 * Returns the local bundle pool (repository) where bundles are stored for the
342
	 * Returns the local bundle pool (repository) where bundles are stored
282
	 * given profile.
283
	 * 
343
	 * 
284
	 * @param profile profile bundles are stored
285
	 * @return local file artifact repository
344
	 * @return local file artifact repository
286
	 * @throws CoreException
345
	 * @throws CoreException
287
	 */
346
	 */
288
	public static IFileArtifactRepository getBundlePool(IProfile profile) throws CoreException {
347
	public static IFileArtifactRepository getBundlePool() throws CoreException {
289
		String path = profile.getProperty(IProfile.PROP_CACHE);
348
		URI uri = BUNDLE_POOL.toFile().toURI();
290
		if (path == null) {
291
			// We should always be setting the bundle pool, so if the bundle pool location is missing there isn't much we can do 
292
			throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_NoBundlePool));
293
		}
294
		URI uri = new File(path).toURI();
295
		IArtifactRepositoryManager manager = getArtifactRepositoryManager();
349
		IArtifactRepositoryManager manager = getArtifactRepositoryManager();
296
		return (IFileArtifactRepository) manager.loadRepository(uri, null);
350
		try {
351
			if (manager.contains(uri))
352
				return (IFileArtifactRepository) manager.loadRepository(uri, null);
353
		} catch (CoreException e) {
354
			// could not load or there wasn't one, fall through to create 
355
		}
356
		String repoName = "PDE Target Bundle Pool"; //$NON-NLS-1$
357
		IArtifactRepository result = manager.createRepository(uri, repoName, IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, null);
358
		return (IFileArtifactRepository) result;
297
	}
359
	}
298
360
299
	/**
361
	/**
Lines 331-337 Link Here
331
	 * @throws CoreException if none
393
	 * @throws CoreException if none
332
	 */
394
	 */
333
	public static IPlanner getPlanner() throws CoreException {
395
	public static IPlanner getPlanner() throws CoreException {
334
		IPlanner planner = (IPlanner) P2TargetUtils.getAgent().getService(IPlanner.class.getName());
396
		IPlanner planner = (IPlanner) getAgent().getService(IPlanner.class.getName());
335
		if (planner == null) {
397
		if (planner == null) {
336
			throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_5));
398
			throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_5));
337
		}
399
		}
Lines 350-454 Link Here
350
	/**
412
	/**
351
	 * Returns the profile for the this target handle, creating one if required.
413
	 * Returns the profile for the this target handle, creating one if required.
352
	 * 
414
	 * 
353
	 * @return profile
415
	 * @return whether or not the profile and target definitions match
354
	 * @throws CoreException in unable to retrieve profile
416
	 * @throws CoreException in unable to retrieve profile
355
	 */
417
	 */
356
	public static IProfile getProfile(ITargetDefinition target) throws CoreException {
418
	private boolean checkProfile() throws CoreException {
357
		IProfileRegistry registry = getProfileRegistry();
419
		// make sure we have a profile to validate
358
		if (registry == null) {
420
		if (fProfile == null) {
359
			throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.AbstractTargetHandle_0));
421
			return false;
422
		}
423
424
		// check that the target and profiles are in sync. If they are then life is good.
425
		// If they are not equal, there is still a chance that everything is ok.
426
		String profileNumber = fProfile.getProperty(PROP_SEQUENCE_NUMBER);
427
		if (Integer.toString(fTarget.currentSequenceNumber()).equals(profileNumber)) {
428
			return true;
429
		}
430
431
		// check if all environments setting is the same
432
		boolean all = false;
433
		String value = fProfile.getProperty(PROP_ALL_ENVIRONMENTS);
434
		if (value != null) {
435
			all = Boolean.valueOf(value).booleanValue();
436
			if (!Boolean.toString(getIncludeAllEnvironments()).equals(value)) {
437
				return false;
438
			}
360
		}
439
		}
361
		AbstractTargetHandle handle = ((AbstractTargetHandle) target.getHandle());
440
362
		String id = P2TargetUtils.getProfileId(handle);
441
		// ensure environment & NL settings are still the same (else we need a new profile)
363
		IProfile profile = registry.getProfile(id);
442
		String property = null;
364
		if (profile != null) {
443
		if (!all) {
365
			boolean recreate = false;
444
			property = generateEnvironmentProperties(fTarget);
366
			// check if all environments setting is the same
445
			value = fProfile.getProperty(IProfile.PROP_ENVIRONMENTS);
367
			boolean all = false;
446
			if (!property.equals(value)) {
368
			String value = profile.getProperty(P2TargetUtils.PROP_ALL_ENVIRONMENTS);
447
				return false;
369
			if (value != null) {
448
			}
370
				all = Boolean.valueOf(value).booleanValue();
449
		}
371
				if (!Boolean.toString(isAllEnvironments(target)).equals(value)) {
450
		property = generateNLProperty(fTarget);
372
					recreate = true;
451
		value = fProfile.getProperty(IProfile.PROP_NL);
373
				}
452
		if (!property.equals(value)) {
374
			}
453
			return false;
375
			// ensure environment & NL settings are still the same (else we need a new profile)
454
		}
376
			String property = null;
455
377
			if (!recreate && !all) {
456
		// check provisioning mode: slice versus plan
378
				property = generateEnvironmentProperties(target);
457
		if (!getProvisionMode(fTarget).equals(fProfile.getProperty(PROP_PROVISION_MODE))) {
379
				value = profile.getProperty(IProfile.PROP_ENVIRONMENTS);
458
			return false;
380
				if (!property.equals(value)) {
459
		}
381
					recreate = true;
460
382
				}
461
		// check that the include source flag matches what the profile represents
383
			}
462
		if (getIncludeSource() != Boolean.valueOf(fProfile.getProperty(PROP_AUTO_INCLUDE_SOURCE)).booleanValue()) {
384
			// check provisioning mode: slice versus plan
463
			return false;
385
			String mode = getProvisionMode(target);
464
		}
386
			if (mode != null) {
465
387
				value = profile.getProperty(P2TargetUtils.PROP_PROVISION_MODE);
466
		// check top level IU's. If any have been removed from the containers that are
388
				if (!mode.equals(value)) {
467
		// still in the profile, we need to recreate (rather than uninstall)
389
					recreate = true;
468
		IUProfilePropertyQuery propertyQuery = new IUProfilePropertyQuery(PROP_INSTALLED_IU, Boolean.toString(true));
469
		IQueryResult queryResult = fProfile.query(propertyQuery, null);
470
		Iterator iterator = queryResult.iterator();
471
		Set installedIUs = new HashSet();
472
		while (iterator.hasNext()) {
473
			IInstallableUnit unit = (IInstallableUnit) iterator.next();
474
			installedIUs.add(new NameVersionDescriptor(unit.getId(), unit.getVersion().toString()));
475
		}
476
		IBundleContainer[] containers = fTarget.getBundleContainers();
477
		if (containers == null) {
478
			return installedIUs.isEmpty();
479
		}
480
		for (int i = 0; i < containers.length; i++) {
481
			if (containers[i] instanceof IUBundleContainer) {
482
				IUBundleContainer bc = (IUBundleContainer) containers[i];
483
				String[] ids = bc.getIds();
484
				Version[] versions = bc.getVersions();
485
				for (int j = 0; j < versions.length; j++) {
486
					// if there is something in a container but not in the profile, recreate
487
					if (!installedIUs.remove(new NameVersionDescriptor(ids[j], versions[j].toString()))) {
488
						return false;
489
					}
390
				}
490
				}
391
			}
491
			}
492
		}
493
		if (!installedIUs.isEmpty()) {
494
			return false;
495
		}
392
496
393
			if (!recreate) {
497
		// Phew! seems like the profile checks out.  
394
				property = generateNLProperty(target);
498
		return true;
395
				value = profile.getProperty(IProfile.PROP_NL);
499
	}
396
				if (!property.equals(value)) {
500
397
					recreate = true;
501
	/**
398
				}
502
	 * Sets whether all required units must be available to resolve this container.  When <code>true</code>
399
			}
503
	 * the resolve operation will use the planner to determine the complete set of IUs required to
400
			if (!recreate) {
504
	 * make the selected IUs runnable.  If any dependencies are missing, the resolve operation will return an
401
				// check top level IU's. If any have been removed from the containers that are
505
	 * error explaining what problems exist.  When <code>false</code> the resolve operation will use the slicer
402
				// still in the profile, we need to recreate (rather than uninstall)
506
	 * to determine what units to include.  Any required units that are not available in the repositories will
403
				IUProfilePropertyQuery propertyQuery = new IUProfilePropertyQuery(P2TargetUtils.PROP_INSTALLED_IU, Boolean.toString(true));
507
	 * be ignored.
404
				IQueryResult queryResult = profile.query(propertyQuery, null);
508
	 * <p>
405
				Iterator iterator = queryResult.iterator();
509
	 * Since there is only one profile per target and the planner and slicer resolve methods are incompatible.
406
				if (iterator.hasNext()) {
510
	 * </p>
407
					Set installedIUs = new HashSet();
511
	 * @param value whether all required units must be available to resolve this container
408
					while (iterator.hasNext()) {
512
	 */
409
						IInstallableUnit unit = (IInstallableUnit) iterator.next();
513
	public void setIncludeAllRequired(boolean value) {
410
						installedIUs.add(new NameVersionDescriptor(unit.getId(), unit.getVersion().toString()));
514
		fIncludeAllRequired = value;
411
					}
515
	}
412
					IBundleContainer[] containers = target.getBundleContainers();
516
413
					if (containers != null) {
517
	/**
414
						for (int i = 0; i < containers.length; i++) {
518
	 * Returns whether all required units must be available to resolve this container.  When <code>true</code>
415
							if (containers[i] instanceof IUBundleContainer) {
519
	 * the resolve operation will use the planner to determine the complete set of IUs required to
416
								IUBundleContainer bc = (IUBundleContainer) containers[i];
520
	 * make the selected IUs runnable.  If any dependencies are missing, the resolve operation will return an
417
								String[] ids = bc.getIds();
521
	 * error explaining what problems exist.  When <code>false</code> the resolve operation will use the slicer
418
								Version[] versions = bc.getVersions();
522
	 * to determine what units to include.  Any required units that are not available in the repositories will
419
								for (int j = 0; j < versions.length; j++) {
523
	 * be ignored.
420
									installedIUs.remove(new NameVersionDescriptor(ids[j], versions[j].toString()));
524
	 *  
421
								}
525
	 * @return whether all required units must be available to resolve this container
422
							}
526
	 */
423
						}
527
	public boolean getIncludeAllRequired() {
424
					}
528
		return fIncludeAllRequired;
425
					if (!installedIUs.isEmpty()) {
529
	}
426
						recreate = true;
530
427
					}
531
	/**
532
	 * Sets whether all environment (platform) specific installable units should
533
	 * be included in this container when it is resolved.  This feature is not supported
534
	 * by the planner so will only have an effect if the include all required setting
535
	 * is turned off ({@link #getIncludeAllRequired()}).
536
	 * <p>
537
	 * There is only one profile per target and this setting can only be set for the
538
	 * entire target definition.  
539
	 * </p>
540
	 * @param value whether environment specific units should be included
541
	 */
542
	public void setIncludeAllEnvironments(boolean value) {
543
		fIncludeMultipleEnvironments = value;
544
	}
545
546
	/**
547
	 * Returns whether all environment (platform) specific installable units should
548
	 * be included in this container when it is resolved.  This feature is not supported
549
	 * by the planner so will only have an effect if the include all required setting
550
	 * is turned off ({@link #getIncludeAllRequired()}).
551
	 * 
552
	 * @return whether environment specific units should be included
553
	 */
554
	public boolean getIncludeAllEnvironments() {
555
		return fIncludeMultipleEnvironments;
556
	}
557
558
	/**
559
	 * Set whether or not the source bundles corresponding to any binary bundles should
560
	 * be automatically included in the target.
561
	 * 
562
	 * @param value whether or not to include source
563
	 */
564
	public void setIncludeSource(boolean value) {
565
		fIncludeSource = value;
566
	}
567
568
	/**
569
	 * Returns whether or not source bundles corresponding to selected binary bundles 
570
	 * are automatically included in the target.
571
	 * 
572
	 * @return whether or not source is included automatically
573
	 */
574
	public boolean getIncludeSource() {
575
		return fIncludeSource;
576
	}
577
578
	/**
579
	 * Return whether or not the given target has a matching profile that is in sync
580
	 * @param target the target to check
581
	 * @return whether or not the target has been resolved at the p2 level
582
	 */
583
	public static boolean isResolved(ITargetDefinition target) {
584
		P2TargetUtils synchronizer = getSynchronizer(target);
585
		if (synchronizer == null)
586
			return false;
587
		try {
588
			return synchronizer.checkProfile();
589
		} catch (CoreException e) {
590
			return false;
591
		}
592
	}
593
594
	/**
595
	 * Get the synchronizer to use for the given target.  If there is already one on a
596
	 * container in the target, use that one.  Otherwise, create a new one.  Either way, 
597
	 * ensure that all other IU containers in the target are using the same synchronizer.
598
	 * 
599
	 * @param target the target for which we are getting the synchronizer
600
	 * @return the discovered or created synchronizer
601
	 */
602
	static synchronized P2TargetUtils getSynchronizer(ITargetDefinition target) {
603
		IBundleContainer[] containers = target.getBundleContainers();
604
		P2TargetUtils result = null;
605
		// if there are no containers then just create/return the synchronizer
606
		if (containers == null) {
607
			return new P2TargetUtils(target);
608
		}
609
610
		// Otherwise, look for a pre-existing synchronizer
611
		for (int i = 0; i < containers.length; i++) {
612
			if (containers[i] instanceof IUBundleContainer) {
613
				result = ((IUBundleContainer) containers[i]).getSynchronizer(null);
614
				if (result != null) {
615
					break;
428
				}
616
				}
429
			}
617
			}
430
			if (recreate) {
618
		}
431
				P2TargetUtils.deleteProfile(handle);
619
432
				profile = null;
620
		// still no luck?  create a new one
433
			}
621
		if (result == null) {
434
		}
622
			result = new P2TargetUtils(target);
435
		if (profile == null) {
623
		}
436
			// create profile
624
437
			Map properties = new HashMap();
625
		// finally set all the other IU containers to use the same synchronizer
438
			properties.put(IProfile.PROP_INSTALL_FOLDER, P2TargetUtils.INSTALL_FOLDERS.append(Long.toString(LocalTargetHandle.nextTimeStamp())).toOSString());
626
		for (int i = 0; i < containers.length; i++) {
439
			properties.put(IProfile.PROP_CACHE, P2TargetUtils.BUNDLE_POOL.toOSString());
627
			if (containers[i] instanceof IUBundleContainer) {
440
			properties.put(IProfile.PROP_INSTALL_FEATURES, Boolean.TRUE.toString());
628
				((IUBundleContainer) containers[i]).setSynchronizer(result);
441
			// set up environment & NL properly so OS specific fragments are down loaded/installed
629
			}
442
			properties.put(IProfile.PROP_ENVIRONMENTS, generateEnvironmentProperties(target));
630
		}
443
			properties.put(IProfile.PROP_NL, generateNLProperty(target));
631
		return result;
444
			String mode = getProvisionMode(target);
632
	}
445
			if (mode != null) {
633
446
				properties.put(P2TargetUtils.PROP_PROVISION_MODE, mode);
634
	/**
447
				properties.put(P2TargetUtils.PROP_ALL_ENVIRONMENTS, Boolean.toString(isAllEnvironments(target)));
635
	 * Return the set of IUs in all IU containers associated with this synchronizer.
636
	 * This is a helper method so we don't have to expose the profile itself.
637
	 * 
638
	 * @param target the target definition to query
639
	 * @param monitor the progress monitor to use
640
	 * @return the set of associated IUs
641
	 * @throws CoreException if there is a problem discovering the IUs
642
	 */
643
	public static IQueryResult getIUs(ITargetDefinition target, IProgressMonitor monitor) throws CoreException {
644
		P2TargetUtils synchronizer = getSynchronizer(target);
645
		if (synchronizer == null)
646
			return null;
647
		synchronizer.synchronize(monitor);
648
		return synchronizer.getProfile().query(QueryUtil.createIUAnyQuery(), null);
649
	}
650
651
	/**
652
	 * Synchronize the profile and the target definition managed by this synchronizer.  On return the profile will 
653
	 * be resolved and correctly match the given target.  The IUBundleContainers associated with 
654
	 * the target will be notified of any changes in the underlying p2 profile and given an 
655
	 * opportunity to update themselves accordingly.
656
	 * 
657
	 * NOTE: this is a potentially *very* heavyweight operation.
658
	 * 
659
	 * NOTE: this method is synchronized as it is effectively a "test and set" caching method. Two
660
	 * threads getting the profile at the same time should not execute concurrently or the profiles
661
	 * will get out of sync.
662
	 * 
663
	 * @throws CoreException if there was a problem synchronizing
664
	 */
665
	public synchronized void synchronize(IProgressMonitor monitor) throws CoreException {
666
		// Happiness if we have a profile and it checks out or if we can load one and it checks out.
667
		if (fProfile == null) {
668
			fProfile = getProfileRegistry().getProfile(getProfileId(fTarget));
669
			if (fProfile != null && checkProfile()) {
670
				// if we just loaded the profile for the first time, refresh the container caches
671
				notify(monitor);
672
				return;
673
			}
674
		} else if (checkProfile()) {
675
			return;
676
		}
677
678
		long timestamp = -1;
679
		// If we could not find a profile, create one.
680
		if (fProfile == null)
681
			createProfile();
682
		else
683
			timestamp = fProfile.getTimestamp();
684
685
		// Now resolve the profile and refresh the relate IU containers
686
		if (getIncludeAllRequired())
687
			resolveWithPlanner(monitor);
688
		else
689
			resolveWithSlicer(monitor);
690
691
		// If we are updating a profile then delete the old snapshot on success.
692
		if (timestamp != -1)
693
			getProfileRegistry().removeProfile(getProfileId(fTarget), timestamp);
694
		notify(monitor);
695
	}
696
697
	private void createProfile() throws CoreException, ProvisionException {
698
		// create a new profile
699
		IProfileRegistry registry = getProfileRegistry();
700
		if (registry == null) {
701
			throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.AbstractTargetHandle_0));
702
		}
703
		Map properties = new HashMap();
704
		properties.put(IProfile.PROP_INSTALL_FOLDER, INSTALL_FOLDERS.append(Long.toString(LocalTargetHandle.nextTimeStamp())).toOSString());
705
		properties.put(IProfile.PROP_CACHE, BUNDLE_POOL.toOSString());
706
		properties.put(IProfile.PROP_INSTALL_FEATURES, Boolean.TRUE.toString());
707
		properties.put(IProfile.PROP_ENVIRONMENTS, generateEnvironmentProperties(fTarget));
708
		properties.put(IProfile.PROP_NL, generateNLProperty(fTarget));
709
		properties.put(PROP_SEQUENCE_NUMBER, Integer.toString(fTarget.currentSequenceNumber()));
710
		properties.put(PROP_PROVISION_MODE, getProvisionMode(fTarget));
711
		properties.put(PROP_ALL_ENVIRONMENTS, Boolean.toString(getIncludeAllEnvironments()));
712
		properties.put(PROP_AUTO_INCLUDE_SOURCE, Boolean.toString(getIncludeSource()));
713
		fProfile = registry.addProfile(getProfileId(fTarget), properties);
714
	}
715
716
	/**
717
	 * Signal the relevant bundle containers that the given profile has changed.
718
	 */
719
	private void notify(IProgressMonitor monitor) throws CoreException {
720
		// flush the target caches first since some of them are used in rebuilding
721
		// the container caches (e.g., featureModels)
722
		((TargetDefinition) fTarget).flushCaches(P2TargetUtils.BUNDLE_POOL.toOSString());
723
		// Now proactively recompute all the related container caches.
724
		IBundleContainer[] containers = fTarget.getBundleContainers();
725
		for (int i = 0; i < containers.length; i++) {
726
			IBundleContainer container = containers[i];
727
			if (container instanceof IUBundleContainer) {
728
				((IUBundleContainer) container).synchronizerChanged();
448
			}
729
			}
449
			profile = registry.addProfile(id, properties);
450
		}
730
		}
451
		return profile;
452
	}
731
	}
453
732
454
	/**
733
	/**
Lines 466-471 Link Here
466
	}
745
	}
467
746
468
	/**
747
	/**
748
	 * Returns the profile identifier for this target handle. There is one profile
749
	 * per target definition.
750
	 * 
751
	 * @return definition the target to lookup
752
	 * @throws CoreException in unable to generate identifier
753
	 */
754
	public static String getProfileId(ITargetDefinition definition) {
755
		try {
756
			return getProfileId(definition.getHandle());
757
		} catch (CoreException e) {
758
			// gotta make sure that this never happens.  all we're doing here is computing a string.
759
			return null;
760
		}
761
	}
762
763
	/**
469
	 * Returns the profile registry or <code>null</code>
764
	 * Returns the profile registry or <code>null</code>
470
	 * 
765
	 * 
471
	 * @return profile registry or <code>null</code>
766
	 * @return profile registry or <code>null</code>
Lines 485-504 Link Here
485
	 * 
780
	 * 
486
	 * @return provisioning mode or <code>null</code>
781
	 * @return provisioning mode or <code>null</code>
487
	 */
782
	 */
488
	private static String getProvisionMode(ITargetDefinition target) {
783
	private String getProvisionMode(ITargetDefinition target) {
489
		IBundleContainer[] containers = target.getBundleContainers();
784
		return getIncludeAllRequired() ? TargetDefinitionPersistenceHelper.MODE_PLANNER : TargetDefinitionPersistenceHelper.MODE_SLICER;
490
		if (containers != null) {
491
			for (int i = 0; i < containers.length; i++) {
492
				if (containers[i] instanceof IUBundleContainer) {
493
					IUBundleContainer iu = (IUBundleContainer) containers[i];
494
					if (iu.getIncludeAllRequired()) {
495
						return TargetDefinitionPersistenceHelper.MODE_PLANNER;
496
					}
497
					return TargetDefinitionPersistenceHelper.MODE_SLICER;
498
				}
499
			}
500
		}
501
		return null;
502
	}
785
	}
503
786
504
	/**
787
	/**
Lines 516-552 Link Here
516
	}
799
	}
517
800
518
	/**
801
	/**
519
	 * Returns the metadata repository with the given URI.
802
	 * Return a queryable on the metadata defined in the given repo locations
520
	 * 
803
	 * 
521
	 * @param uri location
804
	 * @param repos the repos to lookup
522
	 * @return repository
805
	 * @param monitor the progress monitor
523
	 * @throws CoreException
806
	 * @return the set of metadata repositories found
807
	 * @throws CoreException if there is a problem getting the repositories
524
	 */
808
	 */
525
	public static IMetadataRepository getRepository(URI uri) throws CoreException {
809
	static IQueryable getQueryableMetadata(URI[] repos, IProgressMonitor monitor) throws CoreException {
526
		IMetadataRepositoryManager manager = getRepoManager();
810
		IMetadataRepositoryManager manager = getRepoManager();
527
		IMetadataRepository repo = manager.loadRepository(uri, null);
811
		if (repos == null) {
528
		return repo;
812
			repos = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL);
813
		}
814
815
		IProgressMonitor loadMonitor = new SubProgressMonitor(monitor, 10);
816
		int repoCount = repos.length;
817
		loadMonitor.beginTask(null, repoCount * 10);
818
		List result = new ArrayList(repoCount);
819
		MultiStatus repoStatus = new MultiStatus(PDECore.PLUGIN_ID, 0, Messages.IUBundleContainer_ProblemsLoadingRepositories, null);
820
		for (int i = 0; i < repoCount; ++i) {
821
			try {
822
				result.add(manager.loadRepository(repos[i], new SubProgressMonitor(loadMonitor, 10)));
823
			} catch (ProvisionException e) {
824
				repoStatus.add(e.getStatus());
825
			}
826
		}
827
		loadMonitor.done();
828
829
		if (result.size() != repos.length) {
830
			throw new CoreException(repoStatus);
831
		}
832
		if (result.size() == 1) {
833
			return (IQueryable) result.get(0);
834
		}
835
		return QueryUtil.compoundQueryable(result);
529
	}
836
	}
530
837
531
	/**
838
	/**
532
	 * Returns whether software site containers are configured to provision for all environments
839
	 * Used to resolve the contents of this container if the user is including all required software.  The p2 planner is used
533
	 * versus a single environment.
840
	 * to determine the complete set of IUs required to run the selected software.  If all requirements are met, the bundles
841
	 * are downloaded from the repository into the bundle pool and added to the target definition.
534
	 * 
842
	 * 
535
	 * @return whether all environments will be provisioned
843
	 * @param monitor for reporting progress
844
	 * @throws CoreException if there is a problem with the requirements or there is a problem downloading
536
	 */
845
	 */
537
	private static boolean isAllEnvironments(ITargetDefinition target) {
846
	private void resolveWithPlanner(IProgressMonitor monitor) throws CoreException {
847
		SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 10);
848
		subMonitor.beginTask(Messages.IUBundleContainer_0, 200);
849
850
		// Get the root IUs for every relevant container in the target definition
851
		IInstallableUnit[] units = getRootIUs(fTarget);
852
		if (subMonitor.isCanceled()) {
853
			return;
854
		}
855
856
		// create the provisioning plan
857
		IPlanner planner = getPlanner();
858
		IProfileChangeRequest request = planner.createChangeRequest(fProfile);
859
		// first remove everything that was explicitly installed.  Then add it back.  This has the net effect of 
860
		// removing everything that is no longer needed.
861
		computeRemovals(fProfile, request, getIncludeSource());
862
		request.addAll(Arrays.asList(units));
863
		for (int i = 0; i < units.length; i++) {
864
			IInstallableUnit unit = units[i];
865
			request.setInstallableUnitProfileProperty(unit, PROP_INSTALLED_IU, Boolean.toString(true));
866
		}
867
868
		ProvisioningContext context = new ProvisioningContext(getAgent());
869
		context.setMetadataRepositories(getMetadataRepositories(fTarget));
870
		context.setArtifactRepositories(getArtifactRepositories(fTarget));
871
872
		if (subMonitor.isCanceled()) {
873
			return;
874
		}
875
876
		IProvisioningPlan plan = planner.getProvisioningPlan(request, context, new SubProgressMonitor(subMonitor, 20));
877
		IStatus status = plan.getStatus();
878
		if (!status.isOK()) {
879
			throw new CoreException(status);
880
		}
881
		setPlanProperties(plan, fTarget, TargetDefinitionPersistenceHelper.MODE_PLANNER);
882
		IProvisioningPlan installerPlan = plan.getInstallerPlan();
883
		if (installerPlan != null) {
884
			// this plan requires an update to the installer first, log the fact and attempt
885
			// to continue, we don't want to update the running SDK while provisioning a target
886
			PDECore.log(new Status(IStatus.INFO, PDECore.PLUGIN_ID, Messages.IUBundleContainer_6));
887
		}
888
		subMonitor.worked(10);
889
		if (subMonitor.isCanceled()) {
890
			return;
891
		}
892
893
		// execute the provisioning plan
894
		IPhaseSet phases = createPhaseSet();
895
		IEngine engine = getEngine();
896
		IStatus result = engine.perform(plan, phases, new SubProgressMonitor(subMonitor, 140));
897
		if (subMonitor.isCanceled()) {
898
			return;
899
		}
900
		if (!result.isOK()) {
901
			throw new CoreException(result);
902
		}
903
904
		// Now that we have a plan with all the binary and explicit bundles, do a second pass and add 
905
		// in all the source.
906
		try {
907
			planInSourceBundles(fProfile, context, subMonitor);
908
		} catch (CoreException e) {
909
			// XXX Review required: is adding in the source critical or optional?
910
			// We failed adding in the source so remove the intermediate profile and rethrow
911
			getProfileRegistry().removeProfile(fProfile.getProfileId(), fProfile.getTimestamp());
912
			throw e;
913
		}
914
		subMonitor.worked(10);
915
		subMonitor.done();
916
	}
917
918
	private void setPlanProperties(IProvisioningPlan plan, ITargetDefinition definition, String mode) {
919
		plan.setProfileProperty(PROP_PROVISION_MODE, mode);
920
		plan.setProfileProperty(PROP_ALL_ENVIRONMENTS, Boolean.toString(getIncludeSource()));
921
		plan.setProfileProperty(PROP_AUTO_INCLUDE_SOURCE, Boolean.toString(getIncludeSource()));
922
		plan.setProfileProperty(PROP_SEQUENCE_NUMBER, Integer.toString(definition.currentSequenceNumber()));
923
	}
924
925
	private IPhaseSet createPhaseSet() {
926
		ArrayList phases = new ArrayList(4);
927
		phases.add(new Collect(100));
928
		phases.add(new Property(1));
929
		phases.add(new Uninstall(50, true));
930
		phases.add(new Install(50));
931
		phases.add(new CollectNativesPhase(100));
932
		return new PhaseSet((Phase[]) phases.toArray(new Phase[phases.size()]));
933
	}
934
935
	/** 
936
	 * Update the given change request to remove anything that was explicitly installed
937
	 * including the internal source IU.  
938
	 */
939
	private void computeRemovals(IProfile profile, IProfileChangeRequest request, boolean includeSource) {
940
		// if include source is off then ensure that the source IU is removed.
941
		if (!includeSource) {
942
			IInstallableUnit sourceIU = getCurrentSourceIU(profile);
943
			if (sourceIU != null)
944
				request.remove(sourceIU);
945
		}
946
		// remove everything that is marked as roots.  The plan will have the new roots added in anyway.
947
		IQuery query = new IUProfilePropertyQuery(PROP_INSTALLED_IU, Boolean.toString(true));
948
		IQueryResult installedIUs = profile.query(query, null);
949
		request.removeAll(installedIUs.toSet());
950
	}
951
952
	// run a second pass of the planner to add in the source bundles for everything that's
953
	// in the current profile.
954
	private void planInSourceBundles(IProfile fProfile, ProvisioningContext context, IProgressMonitor monitor) throws CoreException {
955
		SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 10);
956
		subMonitor.beginTask("Provisioning source bundles", 200);
957
958
		// create an IU that optionally and greedily requires the related source bundles.
959
		// Completely replace any source IU that may already be in place
960
		IInstallableUnit currentSourceIU = getCurrentSourceIU(fProfile);
961
962
		// determine the new version number.  start at 1
963
		Version sourceVersion = Version.createOSGi(1, 0, 0);
964
		if (currentSourceIU != null) {
965
			Integer major = (Integer) currentSourceIU.getVersion().getSegment(0);
966
			sourceVersion = Version.createOSGi(major.intValue() + 1, 0, 0);
967
		}
968
		IInstallableUnit sourceIU = createSourceIU(fProfile, sourceVersion);
969
970
		// call the planner again to add in the new source IU and all available source bundles
971
		IPlanner planner = getPlanner();
972
		IProfileChangeRequest request = planner.createChangeRequest(fProfile);
973
		if (currentSourceIU != null)
974
			request.remove(currentSourceIU);
975
		request.add(sourceIU);
976
		IProvisioningPlan plan = planner.getProvisioningPlan(request, context, new SubProgressMonitor(subMonitor, 20));
977
		IStatus status = plan.getStatus();
978
		if (!status.isOK()) {
979
			throw new CoreException(status);
980
		}
981
		if (subMonitor.isCanceled()) {
982
			return;
983
		}
984
985
		// execute the provisioning plan
986
		long oldTimestamp = fProfile.getTimestamp();
987
		IPhaseSet phases = PhaseSetFactory.createDefaultPhaseSetExcluding(new String[] {PhaseSetFactory.PHASE_CHECK_TRUST, PhaseSetFactory.PHASE_CONFIGURE, PhaseSetFactory.PHASE_UNCONFIGURE, PhaseSetFactory.PHASE_UNINSTALL});
988
		IEngine engine = getEngine();
989
		plan.setProfileProperty(PROP_PROVISION_MODE, TargetDefinitionPersistenceHelper.MODE_PLANNER);
990
		plan.setProfileProperty(PROP_ALL_ENVIRONMENTS, Boolean.toString(false));
991
		IStatus result = engine.perform(plan, phases, new SubProgressMonitor(subMonitor, 140));
992
993
		if (subMonitor.isCanceled()) {
994
			return;
995
		}
996
		if (!result.isOK()) {
997
			throw new CoreException(result);
998
		}
999
1000
		// remove the old (intermediate) profile version now we have a new one with source.
1001
		getProfileRegistry().removeProfile(fProfile.getProfileId(), oldTimestamp);
1002
		subMonitor.worked(10);
1003
		subMonitor.done();
1004
	}
1005
1006
	// Create and return an IU that has optional and greedy requirements on all source bundles
1007
	// related to bundle IUs in the given queryable. 
1008
	private IInstallableUnit createSourceIU(IQueryable queryable, Version iuVersion) {
1009
		// compute the set of source bundles we could possibly need for the bundles in the profile
1010
		IRequirement bundleRequirement = MetadataFactory.createRequirement("org.eclipse.equinox.p2.eclipse.type", "bundle", null, null, false, false, false); //$NON-NLS-1$ //$NON-NLS-2$
1011
		IQueryResult profileIUs = queryable.query(QueryUtil.createIUAnyQuery(), null);
1012
		ArrayList requirements = new ArrayList();
1013
		for (Iterator i = profileIUs.iterator(); i.hasNext();) {
1014
			IInstallableUnit profileIU = (IInstallableUnit) i.next();
1015
			if (profileIU.satisfies(bundleRequirement)) {
1016
				String id = profileIU.getId() + ".source"; //$NON-NLS-1$
1017
				Version version = profileIU.getVersion();
1018
				VersionRange range = new VersionRange(version, true, version, true);
1019
				IRequirement sourceRequirement = MetadataFactory.createRequirement("osgi.bundle", id, range, null, true, false, true); //$NON-NLS-1$
1020
				requirements.add(sourceRequirement);
1021
			}
1022
		}
1023
1024
		InstallableUnitDescription sourceDescription = new MetadataFactory.InstallableUnitDescription();
1025
		sourceDescription.setSingleton(true);
1026
		sourceDescription.setId(SOURCE_IU_ID);
1027
		sourceDescription.setVersion(iuVersion);
1028
		sourceDescription.addRequirements(requirements);
1029
		IProvidedCapability capability = MetadataFactory.createProvidedCapability(IInstallableUnit.NAMESPACE_IU_ID, SOURCE_IU_ID, iuVersion);
1030
		sourceDescription.setCapabilities(new IProvidedCapability[] {capability});
1031
		return MetadataFactory.createInstallableUnit(sourceDescription);
1032
	}
1033
1034
	// Lookup and return (if any) the source IU in the given queryable.
1035
	private IInstallableUnit getCurrentSourceIU(IQueryable queryable) {
1036
		IQuery query = QueryUtil.createIUQuery(SOURCE_IU_ID);
1037
		IQueryResult list = queryable.query(query, null);
1038
		IInstallableUnit currentSourceIU = null;
1039
		if (!list.isEmpty())
1040
			currentSourceIU = (IInstallableUnit) list.iterator().next();
1041
		return currentSourceIU;
1042
	}
1043
1044
	/**
1045
	 * Used to resolve the contents of this container when the user has chosen to manage the dependencies in the target
1046
	 * themselves.  The selected IUs and any required software that can be found will be retrieved from the repositories 
1047
	 * and added to the target.  Any missing required software will be ignored.
1048
	 * 
1049
	 * @param monitor for reporting progress
1050
	 * @throws CoreException if there is a problem interacting with the repositories
1051
	 */
1052
	private void resolveWithSlicer(IProgressMonitor monitor) throws CoreException {
1053
		SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 10);
1054
		subMonitor.beginTask(Messages.IUBundleContainer_0, 180);
1055
1056
		// resolve IUs
1057
		IInstallableUnit[] units = getRootIUs(fTarget);
1058
		if (subMonitor.isCanceled()) {
1059
			return;
1060
		}
1061
1062
		URI[] repositories = getMetadataRepositories(fTarget);
1063
		int repoCount = repositories.length;
1064
		if (repoCount == 0) {
1065
			return;
1066
		}
1067
		IQueryable allMetadata = getQueryableMetadata(repositories, subMonitor);
1068
1069
		// do an initial slice to add everything the user requested
1070
		IQueryResult queryResult = slice(units, allMetadata, fTarget, subMonitor);
1071
		if (subMonitor.isCanceled() || queryResult == null || queryResult.isEmpty()) {
1072
			return;
1073
		}
1074
1075
		// If we are including source then create a source IU to bring in the relevant source
1076
		// bundles and run the slicer again.
1077
		if (getIncludeSource()) {
1078
			// Build an IU that represents all the source bundles and slice again to add them in if available
1079
			IInstallableUnit sourceIU = createSourceIU(queryResult, Version.createOSGi(1, 0, 0));
1080
			IInstallableUnit[] units2 = new IInstallableUnit[units.length + 1];
1081
			System.arraycopy(units, 0, units2, 0, units.length);
1082
			units2[units.length] = sourceIU;
1083
1084
			queryResult = slice(units2, allMetadata, fTarget, subMonitor);
1085
			if (subMonitor.isCanceled() || queryResult == null || queryResult.isEmpty()) {
1086
				return;
1087
			}
1088
		}
1089
1090
		IEngine engine = getEngine();
1091
		ProvisioningContext context = new ProvisioningContext(getAgent());
1092
		context.setMetadataRepositories(repositories);
1093
		context.setArtifactRepositories(getArtifactRepositories(fTarget));
1094
		IProvisioningPlan plan = engine.createPlan(fProfile, context);
1095
		setPlanProperties(plan, fTarget, TargetDefinitionPersistenceHelper.MODE_SLICER);
1096
1097
		Set newSet = queryResult.toSet();
1098
		Iterator itor = newSet.iterator();
1099
		while (itor.hasNext()) {
1100
			plan.addInstallableUnit((IInstallableUnit) itor.next());
1101
		}
1102
		for (int i = 0; i < units.length; i++) {
1103
			IInstallableUnit unit = units[i];
1104
			plan.setInstallableUnitProfileProperty(unit, PROP_INSTALLED_IU, Boolean.toString(true));
1105
		}
1106
1107
		// remove all units that are in the current profile but not in the new slice
1108
		Set toRemove = fProfile.query(QueryUtil.ALL_UNITS, null).toSet();
1109
		toRemove.removeAll(newSet);
1110
		for (Iterator i = toRemove.iterator(); i.hasNext();) {
1111
			plan.removeInstallableUnit((IInstallableUnit) i.next());
1112
		}
1113
1114
		// execute the provisioning plan
1115
		IPhaseSet phases = createPhaseSet();
1116
		IStatus result = engine.perform(plan, phases, new SubProgressMonitor(subMonitor, 140));
1117
		if (!result.isOK()) {
1118
			throw new CoreException(result);
1119
		}
1120
1121
		subMonitor.worked(10);
1122
		subMonitor.done();
1123
	}
1124
1125
	private IQueryResult slice(IInstallableUnit[] units, IQueryable allMetadata, ITargetDefinition definition, SubProgressMonitor subMonitor) throws CoreException {
1126
		// slice IUs and all prerequisites
1127
		PermissiveSlicer slicer = null;
1128
		if (getIncludeAllEnvironments()) {
1129
			slicer = new PermissiveSlicer(allMetadata, new HashMap(), true, false, true, true, false);
1130
		} else {
1131
			Map props = new HashMap();
1132
			props.put("osgi.os", definition.getOS() != null ? definition.getOS() : Platform.getOS()); //$NON-NLS-1$
1133
			props.put("osgi.ws", definition.getWS() != null ? definition.getWS() : Platform.getWS()); //$NON-NLS-1$
1134
			props.put("osgi.arch", definition.getArch() != null ? definition.getArch() : Platform.getOSArch()); //$NON-NLS-1$
1135
			props.put("osgi.nl", definition.getNL() != null ? definition.getNL() : Platform.getNL()); //$NON-NLS-1$
1136
			props.put(IProfile.PROP_INSTALL_FEATURES, Boolean.TRUE.toString());
1137
			slicer = new PermissiveSlicer(allMetadata, props, true, false, false, true, false);
1138
		}
1139
		IQueryable slice = slicer.slice(units, new SubProgressMonitor(subMonitor, 10));
1140
		if (!slicer.getStatus().isOK()) {
1141
			throw new CoreException(slicer.getStatus());
1142
		}
1143
		IQueryResult queryResult = null;
1144
		if (slice != null)
1145
			queryResult = slice.query(QueryUtil.createIUAnyQuery(), new SubProgressMonitor(subMonitor, 10));
1146
		return queryResult;
1147
	}
1148
1149
	/**
1150
	 * Returns the artifact repositories to consider when getting artifacts.  Returns a default set of
1151
	 * repositories if current repository settings are <code>null</code>).
1152
	 *  
1153
	 * @return URI's of repositories to use when getting artifacts
1154
	 * @exception CoreException
1155
	 */
1156
	private URI[] getArtifactRepositories(ITargetDefinition target) throws CoreException {
1157
		Set result = new HashSet();
538
		IBundleContainer[] containers = target.getBundleContainers();
1158
		IBundleContainer[] containers = target.getBundleContainers();
539
		if (containers != null) {
1159
		IArtifactRepositoryManager manager = getArtifactRepositoryManager();
540
			for (int i = 0; i < containers.length; i++) {
1160
		for (int i = 0; i < containers.length; i++) {
541
				if (containers[i] instanceof IUBundleContainer) {
1161
			IBundleContainer container = containers[i];
542
					IUBundleContainer iu = (IUBundleContainer) containers[i];
1162
			if (container instanceof IUBundleContainer) {
543
					if (iu.getIncludeAllEnvironments()) {
1163
				URI[] repos = ((IUBundleContainer) container).getRepositories();
544
						return true;
1164
				if (repos == null) {
545
					}
1165
					repos = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL);
546
				}
1166
				}
1167
				result.addAll(Arrays.asList(repos));
547
			}
1168
			}
548
		}
1169
		}
549
		return false;
1170
		if (useAdditionalLocalArtifacts()) {
1171
			// get all the artifact repos we know in the manager currently
1172
			result.addAll(Arrays.asList(manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL)));
1173
1174
			// Add in the IDE profile bundle pool and all known workspaces
1175
			findProfileRepos(result);
1176
			findWorkspaceRepos(result);
1177
		}
1178
		return (URI[]) result.toArray(new URI[result.size()]);
1179
	}
1180
1181
	/**
1182
	 * return whether or not to use local artifact repositories when provisioning the target
1183
	 */
1184
	private boolean useAdditionalLocalArtifacts() {
1185
		// XXX consider using a preference here or another strategy if users are able to spec 
1186
		// what local repos are to be considered.
1187
		return true;
1188
	}
1189
1190
	/** 
1191
	 * Add the artifact repos from the PDE target bundle pools from all known repos.  For example, the list 
1192
	 * of "recent workspaces" maintained by the IDE is a good source.
1193
	 * 
1194
	 * @param additionalRepos the set to which additional repos are added.
1195
	 */
1196
	private void findWorkspaceRepos(Set additionalRepos) {
1197
		IPreferencesService prefs = getPreferences();
1198
		if (prefs == null)
1199
			return;
1200
		String recent = prefs.getString("org.eclipse.ui.ide", "RECENT_WORKSPACES", null, null); //$NON-NLS-1$ //$NON-NLS-2$
1201
		if (recent == null)
1202
			return;
1203
		String[] recents = recent.split("\n"); //$NON-NLS-1$
1204
		for (int i = 0; i < recents.length; i++) {
1205
			String bundlePool = recents[i] + "/.metadata/.plugins/org.eclipse.pde.core/.bundle_pool"; //$NON-NLS-1$
1206
			if (new File(bundlePool).exists()) {
1207
				URI uri;
1208
				try {
1209
					uri = new URI("file", bundlePool, null); //$NON-NLS-1$
1210
					additionalRepos.add(uri);
1211
				} catch (URISyntaxException e) {
1212
					// should never happen
1213
				}
1214
			}
1215
		}
1216
	}
1217
1218
	/** 
1219
	 * Look through the current p2 profile (_SELF_) and add the artifact repos that make up its
1220
	 * bundle pool, dropins location, ...  This helps in the cases that you are targeting stuff that 
1221
	 * makes up your current IDE.
1222
	 * 
1223
	 * @param additionalRepos the set to which additional repos are added.
1224
	 */
1225
	private void findProfileRepos(Set additionalRepos) {
1226
		try {
1227
			// NOTE: be sure to use the global p2 agent here as we are looking for SELF.
1228
			IProfileRegistry profileRegistry = (IProfileRegistry) getGlobalAgent().getService(IProfileRegistry.SERVICE_NAME);
1229
			if (profileRegistry == null)
1230
				return;
1231
			IProfile self = profileRegistry.getProfile(IProfileRegistry.SELF);
1232
			if (self == null)
1233
				return;
1234
1235
			IAgentLocation location = (IAgentLocation) getGlobalAgent().getService(IAgentLocation.SERVICE_NAME);
1236
			URI dataArea = location.getDataArea("org.eclipse.equinox.p2.engine"); //$NON-NLS-1$
1237
			dataArea = URIUtil.append(dataArea, "profileRegistry/" + self.getProfileId() + ".profile"); //$NON-NLS-1$//$NON-NLS-2$
1238
			ProfileMetadataRepository profileRepo = new ProfileMetadataRepository(getGlobalAgent(), dataArea, null);
1239
			Collection repos = profileRepo.getReferences();
1240
			for (Iterator i = repos.iterator(); i.hasNext();) {
1241
				Object element = i.next();
1242
				if (element instanceof IRepositoryReference) {
1243
					IRepositoryReference reference = (IRepositoryReference) element;
1244
					if (reference.getType() == IRepository.TYPE_ARTIFACT && reference.getLocation() != null)
1245
						additionalRepos.add(reference.getLocation());
1246
				}
1247
			}
1248
		} catch (CoreException e) {
1249
			// if there is a problem, move on.  Could log something here 
1250
			return;
1251
		}
1252
	}
1253
1254
	/**
1255
	 * Returns the IU's for the given target related to the given containers
1256
	 * 
1257
	 * @param containers the bundle containers to filter with
1258
	 * @return the discovered IUs
1259
	 * @exception CoreException if unable to retrieve IU's
1260
	 */
1261
	private IInstallableUnit[] getRootIUs(ITargetDefinition definition) throws CoreException {
1262
		HashSet result = new HashSet();
1263
		IBundleContainer[] containers = definition.getBundleContainers();
1264
		for (int i = 0; i < containers.length; i++) {
1265
			IBundleContainer container = containers[i];
1266
			if (container instanceof IUBundleContainer) {
1267
				IUBundleContainer iuContainer = (IUBundleContainer) container;
1268
				IQueryable repos = getQueryableMetadata(iuContainer.getRepositories(), new NullProgressMonitor());
1269
				String[] ids = iuContainer.getIds();
1270
				Version[] versions = iuContainer.getVersions();
1271
				for (int j = 0; j < ids.length; j++) {
1272
					IQuery query = QueryUtil.createIUQuery(ids[j], versions[j]);
1273
					IQueryResult queryResult = repos.query(query, null);
1274
					if (queryResult.isEmpty())
1275
						throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.IUBundleContainer_1, ids[j])));
1276
					result.add(queryResult.iterator().next());
1277
				}
1278
			}
1279
		}
1280
		return (IInstallableUnit[]) result.toArray(new IInstallableUnit[result.size()]);
1281
	}
1282
1283
	/**
1284
	 * Returns the repositories to consider when resolving IU's (will return default set of
1285
	 * repositories if current repository settings are <code>null</code>).
1286
	 *  
1287
	 * @return URI's of repositories to use when resolving bundles
1288
	 * @exception CoreException
1289
	 */
1290
	private URI[] getMetadataRepositories(ITargetDefinition target) throws CoreException {
1291
		Set result = new HashSet();
1292
		IBundleContainer[] containers = target.getBundleContainers();
1293
		IMetadataRepositoryManager manager = getRepoManager();
1294
		for (int i = 0; i < containers.length; i++) {
1295
			IBundleContainer container = containers[i];
1296
			if (container instanceof IUBundleContainer) {
1297
				URI[] repos = ((IUBundleContainer) container).getRepositories();
1298
				if (repos == null) {
1299
					repos = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL);
1300
				}
1301
				result.addAll(Arrays.asList(repos));
1302
			}
1303
		}
1304
		return (URI[]) result.toArray(new URI[result.size()]);
550
	}
1305
	}
551
1306
1307
	private static final String NATIVE_ARTIFACTS = "nativeArtifacts"; //$NON-NLS-1$
1308
	private static final String NATIVE_TYPE = "org.eclipse.equinox.p2.native"; //$NON-NLS-1$
1309
	private static final String PARM_OPERAND = "operand"; //$NON-NLS-1$
1310
1311
	protected static class CollectNativesAction extends ProvisioningAction {
1312
		public IStatus execute(Map parameters) {
1313
			InstallableUnitOperand operand = (InstallableUnitOperand) parameters.get(PARM_OPERAND);
1314
			IInstallableUnit installableUnit = operand.second();
1315
			if (installableUnit == null)
1316
				return Status.OK_STATUS;
1317
1318
			IArtifactRepositoryManager manager;
1319
			try {
1320
				Collection toDownload = installableUnit.getArtifacts();
1321
				if (toDownload == null)
1322
					return Status.OK_STATUS;
1323
1324
				List artifactRequests = (List) parameters.get(NATIVE_ARTIFACTS);
1325
				IArtifactRepository destinationArtifactRepository = getBundlePool();
1326
				manager = getArtifactRepositoryManager();
1327
				for (Iterator i = toDownload.iterator(); i.hasNext();) {
1328
					IArtifactKey keyToDownload = (IArtifactKey) i.next();
1329
					IArtifactRequest request = manager.createMirrorRequest(keyToDownload, destinationArtifactRepository, null, null);
1330
					artifactRequests.add(request);
1331
				}
1332
			} catch (CoreException e) {
1333
				return e.getStatus();
1334
			}
1335
			return Status.OK_STATUS;
1336
		}
1337
1338
		public IStatus undo(Map parameters) {
1339
			// nothing to do for now
1340
			return Status.OK_STATUS;
1341
		}
1342
	}
1343
1344
	protected static class CollectNativesPhase extends InstallableUnitPhase {
1345
		public CollectNativesPhase(int weight) {
1346
			super(NATIVE_ARTIFACTS, weight);
1347
		}
1348
1349
		protected List getActions(InstallableUnitOperand operand) {
1350
			IInstallableUnit unit = operand.second();
1351
			if (unit != null && unit.getTouchpointType().getId().equals(NATIVE_TYPE)) {
1352
				return Collections.singletonList(new CollectNativesAction());
1353
			}
1354
			return null;
1355
		}
1356
1357
		protected IStatus initializePhase(IProgressMonitor monitor, IProfile profile, Map parameters) {
1358
			parameters.put(NATIVE_ARTIFACTS, new ArrayList());
1359
			parameters.put(PARM_PROFILE, profile);
1360
			return null;
1361
		}
1362
1363
		protected IStatus completePhase(IProgressMonitor monitor, IProfile profile, Map parameters) {
1364
			List artifactRequests = (List) parameters.get(NATIVE_ARTIFACTS);
1365
			ProvisioningContext context = (ProvisioningContext) parameters.get(PARM_CONTEXT);
1366
			IProvisioningAgent agent = (IProvisioningAgent) parameters.get(PARM_AGENT);
1367
			DownloadManager dm = new DownloadManager(context, agent);
1368
			for (Iterator i = artifactRequests.iterator(); i.hasNext();) {
1369
				dm.add((IArtifactRequest) i.next());
1370
			}
1371
			return dm.start(monitor);
1372
		}
1373
	}
1374
1375
	IProfile getProfile() {
1376
		return fProfile;
1377
	}
1378
1379
	ITargetDefinition getTargetDefinition() {
1380
		return fTarget;
1381
	}
1382
1383
	long getTimestamp() {
1384
		return fProfile.getTimestamp();
1385
	}
552
}
1386
}
(-)src/org/eclipse/pde/internal/core/target/TargetDefinition.java (+39 lines)
Lines 75-80 Link Here
75
	private IFeatureModel[] fFeatureModels;
75
	private IFeatureModel[] fFeatureModels;
76
	private IResolvedBundle[] fOtherBundles;
76
	private IResolvedBundle[] fOtherBundles;
77
77
78
	private int fSequenceNumber = -1;
79
78
	/**
80
	/**
79
	 * Constructs a target definition based on the given handle. 
81
	 * Constructs a target definition based on the given handle. 
80
	 */
82
	 */
Lines 142-147 Link Here
142
	 * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setArch(java.lang.String)
144
	 * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setArch(java.lang.String)
143
	 */
145
	 */
144
	public void setArch(String arch) {
146
	public void setArch(String arch) {
147
		incrementSequenceNumber();
145
		fArch = arch;
148
		fArch = arch;
146
	}
149
	}
147
150
Lines 149-154 Link Here
149
	 * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setNL(java.lang.String)
152
	 * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setNL(java.lang.String)
150
	 */
153
	 */
151
	public void setNL(String nl) {
154
	public void setNL(String nl) {
155
		incrementSequenceNumber();
152
		fNL = nl;
156
		fNL = nl;
153
	}
157
	}
154
158
Lines 163-168 Link Here
163
	 * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setOS(java.lang.String)
167
	 * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setOS(java.lang.String)
164
	 */
168
	 */
165
	public void setOS(String os) {
169
	public void setOS(String os) {
170
		incrementSequenceNumber();
166
		fOS = os;
171
		fOS = os;
167
	}
172
	}
168
173
Lines 190-195 Link Here
190
	 * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setWS(java.lang.String)
195
	 * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setWS(java.lang.String)
191
	 */
196
	 */
192
	public void setWS(String ws) {
197
	public void setWS(String ws) {
198
		incrementSequenceNumber();
193
		fWS = ws;
199
		fWS = ws;
194
	}
200
	}
195
201
Lines 197-202 Link Here
197
	 * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setBundleContainers(org.eclipse.pde.internal.core.target.provisional.IBundleContainer[])
203
	 * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setBundleContainers(org.eclipse.pde.internal.core.target.provisional.IBundleContainer[])
198
	 */
204
	 */
199
	public void setBundleContainers(IBundleContainer[] containers) {
205
	public void setBundleContainers(IBundleContainer[] containers) {
206
		incrementSequenceNumber();
200
		// Clear the feature model cache as it is based on the bundle container locations
207
		// Clear the feature model cache as it is based on the bundle container locations
201
		fFeatureModels = null;
208
		fFeatureModels = null;
202
		fOtherBundles = null;
209
		fOtherBundles = null;
Lines 210-215 Link Here
210
		if (containers == null) {
217
		if (containers == null) {
211
			fIncluded = null;
218
			fIncluded = null;
212
			fOptional = null;
219
			fOptional = null;
220
		} else {
221
			for (int i = 0; i < containers.length; i++) {
222
				((AbstractBundleContainer) containers[i]).associateWithTarget(this);
223
			}
224
		}
225
	}
226
227
	public void flushCaches(String location) {
228
		// Clear the feature model cache as it is based on the bundle container locations
229
		fFeatureModels = null;
230
		fOtherBundles = null;
231
		if (location == null) {
232
			fFeaturesInLocation = new HashMap();
233
		} else {
234
			fFeaturesInLocation.remove(location);
235
		}
236
		if (fContainers == null) {
237
			fIncluded = null;
238
			fOptional = null;
213
		}
239
		}
214
	}
240
	}
215
241
Lines 623-628 Link Here
623
			fProgramArgs = null;
649
			fProgramArgs = null;
624
			fVMArgs = null;
650
			fVMArgs = null;
625
			fWS = null;
651
			fWS = null;
652
			fSequenceNumber = 0;
626
			TargetDefinitionPersistenceHelper.initFromXML(this, stream);
653
			TargetDefinitionPersistenceHelper.initFromXML(this, stream);
627
		} catch (ParserConfigurationException e) {
654
		} catch (ParserConfigurationException e) {
628
			abort(Messages.TargetDefinition_0, e);
655
			abort(Messages.TargetDefinition_0, e);
Lines 1001-1004 Link Here
1001
	public void setUIMode(int mode) {
1028
	public void setUIMode(int mode) {
1002
		fUIMode = mode;
1029
		fUIMode = mode;
1003
	}
1030
	}
1031
1032
	public int currentSequenceNumber() {
1033
		return fSequenceNumber;
1034
	}
1035
1036
	public int incrementSequenceNumber() {
1037
		return ++fSequenceNumber;
1038
	}
1039
1040
	void setSequenceNumber(int value) {
1041
		fSequenceNumber = value;
1042
	}
1004
}
1043
}
(-)src/org/eclipse/pde/internal/core/target/TargetDefinitionPersistenceHelper.java (+3 lines)
Lines 72-77 Link Here
72
	static final String ATTR_OPTIONAL = "optional"; //$NON-NLS-1$
72
	static final String ATTR_OPTIONAL = "optional"; //$NON-NLS-1$
73
	static final String ATTR_VERSION = "version"; //$NON-NLS-1$
73
	static final String ATTR_VERSION = "version"; //$NON-NLS-1$
74
	static final String ATTR_CONFIGURATION = "configuration"; //$NON-NLS-1$
74
	static final String ATTR_CONFIGURATION = "configuration"; //$NON-NLS-1$
75
	static final String ATTR_SEQUENCE_NUMBER = "sequenceNumber"; //$NON-NLS-1$
75
	static final String CONTENT = "content"; //$NON-NLS-1$
76
	static final String CONTENT = "content"; //$NON-NLS-1$
76
	static final String ATTR_USE_ALL = "useAllPlugins"; //$NON-NLS-1$
77
	static final String ATTR_USE_ALL = "useAllPlugins"; //$NON-NLS-1$
77
	static final String PLUGINS = "plugins"; //$NON-NLS-1$
78
	static final String PLUGINS = "plugins"; //$NON-NLS-1$
Lines 107-112 Link Here
107
			rootElement.setAttribute(ATTR_INCLUDE_MODE, FEATURE);
108
			rootElement.setAttribute(ATTR_INCLUDE_MODE, FEATURE);
108
		}
109
		}
109
110
111
		rootElement.setAttribute(ATTR_SEQUENCE_NUMBER, Integer.toString(definition.currentSequenceNumber()));
112
110
		IBundleContainer[] containers = definition.getBundleContainers();
113
		IBundleContainer[] containers = definition.getBundleContainers();
111
		if (containers != null && containers.length > 0) {
114
		if (containers != null && containers.length > 0) {
112
			Element containersElement = doc.createElement(LOCATIONS);
115
			Element containersElement = doc.createElement(LOCATIONS);
(-)src/org/eclipse/pde/internal/core/target/TargetPersistence35Helper.java (-9 / +5 lines)
Lines 224-241 Link Here
224
			String[] iuIDs = (String[]) ids.toArray(new String[ids.size()]);
224
			String[] iuIDs = (String[]) ids.toArray(new String[ids.size()]);
225
			String[] iuVer = (String[]) versions.toArray(new String[versions.size()]);
225
			String[] iuVer = (String[]) versions.toArray(new String[versions.size()]);
226
			URI[] uris = (URI[]) repos.toArray(new URI[repos.size()]);
226
			URI[] uris = (URI[]) repos.toArray(new URI[repos.size()]);
227
			container = new IUBundleContainer(iuIDs, iuVer, uris);
227
			int flags = IUBundleContainer.INCLUDE_REQUIRED;
228
			if (includeMode != null && includeMode.trim().length() > 0) {
228
			if (includeMode != null && includeMode.trim().length() > 0) {
229
				if (includeMode.equals(TargetDefinitionPersistenceHelper.MODE_PLANNER)) {
229
				if (includeMode.equals(TargetDefinitionPersistenceHelper.MODE_SLICER)) {
230
					((IUBundleContainer) container).setIncludeAllRequired(true, null);
230
					flags = 0;
231
				} else if (includeMode.equals(TargetDefinitionPersistenceHelper.MODE_SLICER)) {
232
					((IUBundleContainer) container).setIncludeAllRequired(false, null);
233
				}
231
				}
234
			}
232
			}
235
			if (includeAllPlatforms != null && includeAllPlatforms.trim().length() > 0) {
233
			flags |= Boolean.valueOf(includeAllPlatforms).booleanValue() ? IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS : 0;
236
				((IUBundleContainer) container).setIncludeAllEnvironments(Boolean.valueOf(includeAllPlatforms).booleanValue(), null);
234
			container = new IUBundleContainer(iuIDs, iuVer, uris, flags);
237
			}
238
239
		}
235
		}
240
236
241
		NodeList list = location.getChildNodes();
237
		NodeList list = location.getChildNodes();
(-)src/org/eclipse/pde/internal/core/target/TargetPersistence36Helper.java (-10 / +15 lines)
Lines 148-153 Link Here
148
				}
148
				}
149
			}
149
			}
150
		}
150
		}
151
152
		// Set the sequence number at the very end
153
		String sequenceNumber = root.getAttribute(TargetDefinitionPersistenceHelper.ATTR_SEQUENCE_NUMBER);
154
		try {
155
			((TargetDefinition) definition).setSequenceNumber(Integer.parseInt(sequenceNumber));
156
		} catch (NumberFormatException e) {
157
			((TargetDefinition) definition).setSequenceNumber(0);
158
		}
151
	}
159
	}
152
160
153
	/**
161
	/**
Lines 215-233 Link Here
215
			String[] iuIDs = (String[]) ids.toArray(new String[ids.size()]);
223
			String[] iuIDs = (String[]) ids.toArray(new String[ids.size()]);
216
			String[] iuVer = (String[]) versions.toArray(new String[versions.size()]);
224
			String[] iuVer = (String[]) versions.toArray(new String[versions.size()]);
217
			URI[] uris = (URI[]) repos.toArray(new URI[repos.size()]);
225
			URI[] uris = (URI[]) repos.toArray(new URI[repos.size()]);
218
			container = new IUBundleContainer(iuIDs, iuVer, uris);
226
227
			int flags = IUBundleContainer.INCLUDE_REQUIRED;
219
			if (includeMode != null && includeMode.trim().length() > 0) {
228
			if (includeMode != null && includeMode.trim().length() > 0) {
220
				if (includeMode.equals(TargetDefinitionPersistenceHelper.MODE_PLANNER)) {
229
				if (includeMode.equals(TargetDefinitionPersistenceHelper.MODE_SLICER)) {
221
					((IUBundleContainer) container).setIncludeAllRequired(true, null);
230
					flags = 0;
222
				} else if (includeMode.equals(TargetDefinitionPersistenceHelper.MODE_SLICER)) {
223
					((IUBundleContainer) container).setIncludeAllRequired(false, null);
224
				}
231
				}
225
			}
232
			}
226
			if (includeAllPlatforms != null && includeAllPlatforms.trim().length() > 0) {
233
			flags |= Boolean.valueOf(includeAllPlatforms).booleanValue() ? IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS : 0;
227
				((IUBundleContainer) container).setIncludeAllEnvironments(Boolean.valueOf(includeAllPlatforms).booleanValue(), null);
234
			flags |= Boolean.valueOf(includeSource).booleanValue() ? IUBundleContainer.INCLUDE_SOURCE : 0;
228
			}
235
			container = new IUBundleContainer(iuIDs, iuVer, uris, flags);
229
			((IUBundleContainer) container).setIncludeSource(Boolean.valueOf(includeSource).booleanValue());
230
231
		}
236
		}
232
		return container;
237
		return container;
233
	}
238
	}
(-)src/org/eclipse/pde/internal/core/target/TargetPlatformService.java (-4 / +4 lines)
Lines 593-606 Link Here
593
	/* (non-Javadoc)
593
	/* (non-Javadoc)
594
	 * @see org.eclipse.pde.internal.core.target.provisional.ITargetPlatformService#newIUContainer(org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit[], java.net.URI[])
594
	 * @see org.eclipse.pde.internal.core.target.provisional.ITargetPlatformService#newIUContainer(org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit[], java.net.URI[])
595
	 */
595
	 */
596
	public IBundleContainer newIUContainer(IInstallableUnit[] units, URI[] repositories) {
596
	public IBundleContainer newIUContainer(IInstallableUnit[] units, URI[] repositories, int flags) {
597
		return new IUBundleContainer(units, repositories);
597
		return new IUBundleContainer(units, repositories, flags);
598
	}
598
	}
599
599
600
	/* (non-Javadoc)
600
	/* (non-Javadoc)
601
	 * @see org.eclipse.pde.internal.core.target.provisional.ITargetPlatformService#newIUContainer(java.lang.String[], java.lang.String[], java.net.URI[])
601
	 * @see org.eclipse.pde.internal.core.target.provisional.ITargetPlatformService#newIUContainer(java.lang.String[], java.lang.String[], java.net.URI[])
602
	 */
602
	 */
603
	public IBundleContainer newIUContainer(String[] unitIds, String[] versions, URI[] repositories) {
603
	public IBundleContainer newIUContainer(String[] unitIds, String[] versions, URI[] repositories, int flags) {
604
		return new IUBundleContainer(unitIds, versions, repositories);
604
		return new IUBundleContainer(unitIds, versions, repositories, flags);
605
	}
605
	}
606
}
606
}
(-)src/org/eclipse/pde/internal/core/target/provisional/ITargetDefinition.java (+8 lines)
Lines 320-323 Link Here
320
	 * @return implicit dependencies or <code>null</code>
320
	 * @return implicit dependencies or <code>null</code>
321
	 */
321
	 */
322
	public NameVersionDescriptor[] getImplicitDependencies();
322
	public NameVersionDescriptor[] getImplicitDependencies();
323
324
	/**
325
	 * Returns the current sequence number of this target.  Sequence numbers change
326
	 * whenever something in the target that affects the set of features and bundles that 
327
	 * would be resolved.
328
	 * @return the current sequence number
329
	 */
330
	public int currentSequenceNumber();
323
}
331
}
(-)src/org/eclipse/pde/internal/core/target/provisional/ITargetPlatformService.java (-4 / +5 lines)
Lines 10-20 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.pde.internal.core.target.provisional;
11
package org.eclipse.pde.internal.core.target.provisional;
12
12
13
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
14
15
import java.net.URI;
13
import java.net.URI;
16
import org.eclipse.core.resources.IFile;
14
import org.eclipse.core.resources.IFile;
17
import org.eclipse.core.runtime.*;
15
import org.eclipse.core.runtime.*;
16
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
18
17
19
/**
18
/**
20
 * A service to manage target platform definitions available to the workspace.
19
 * A service to manage target platform definitions available to the workspace.
Lines 139-147 Link Here
139
	 * @param units installable units
138
	 * @param units installable units
140
	 * @param repositories URI's describing repository locations or <code>null</code> to use
139
	 * @param repositories URI's describing repository locations or <code>null</code> to use
141
	 * 	default repositories
140
	 * 	default repositories
141
	 * @param flags bitmask of flags to control IU resolution
142
	 * @return bundle container
142
	 * @return bundle container
143
	 */
143
	 */
144
	public IBundleContainer newIUContainer(IInstallableUnit[] units, URI[] repositories);
144
	public IBundleContainer newIUContainer(IInstallableUnit[] units, URI[] repositories, int flags);
145
145
146
	/**
146
	/**
147
	 * Creates and returns a bundle container that contains all bundles contained in
147
	 * Creates and returns a bundle container that contains all bundles contained in
Lines 152-160 Link Here
152
	 * @param versions version identifiers
152
	 * @param versions version identifiers
153
	 * @param repositories URI's describing repository locations or <code>null</code> to use
153
	 * @param repositories URI's describing repository locations or <code>null</code> to use
154
	 * 	default repositories
154
	 * 	default repositories
155
	 * @param flags bitmask of flags to control IU resolution
155
	 * @return bundle container
156
	 * @return bundle container
156
	 */
157
	 */
157
	public IBundleContainer newIUContainer(String[] unitIds, String[] versions, URI[] repositories);
158
	public IBundleContainer newIUContainer(String[] unitIds, String[] versions, URI[] repositories, int flags);
158
159
159
	/**
160
	/**
160
	 * Creates and returns a bundle container that contains all bundles referenced by
161
	 * Creates and returns a bundle container that contains all bundles referenced by
(-)META-INF/MANIFEST.MF (-1 / +1 lines)
Lines 108-114 Link Here
108
 org.eclipse.pde.launching;bundle-version="[3.6.0,4.0.0)";visibility:=reexport,
108
 org.eclipse.pde.launching;bundle-version="[3.6.0,4.0.0)";visibility:=reexport,
109
 org.eclipse.ui.console;bundle-version="[3.5.0,4.0.0)",
109
 org.eclipse.ui.console;bundle-version="[3.5.0,4.0.0)",
110
 org.eclipse.equinox.simpleconfigurator;bundle-version="[1.0.200,2.0.0)",
110
 org.eclipse.equinox.simpleconfigurator;bundle-version="[1.0.200,2.0.0)",
111
 org.eclipse.equinox.p2.repository.tools
111
 org.eclipse.equinox.p2.repository.tools;bundle-version="2.0.100"
112
Eclipse-LazyStart: true
112
Eclipse-LazyStart: true
113
Import-Package: com.ibm.icu.text,
113
Import-Package: com.ibm.icu.text,
114
 org.eclipse.jdt.debug.core
114
 org.eclipse.jdt.debug.core
(-)src/org/eclipse/pde/internal/ui/PDEUIMessages.java (+4 lines)
Lines 2732-2739 Link Here
2732
2732
2733
	public static String TargetPlatformPreferencePage2_28;
2733
	public static String TargetPlatformPreferencePage2_28;
2734
2734
2735
	public static String TargetPlatformPreferencePage2_29;
2736
2735
	public static String TargetPlatformPreferencePage2_3;
2737
	public static String TargetPlatformPreferencePage2_3;
2736
2738
2739
	public static String TargetPlatformPreferencePage2_30;
2740
2737
	public static String TargetPlatformPreferencePage2_4;
2741
	public static String TargetPlatformPreferencePage2_4;
2738
2742
2739
	public static String TargetPlatformPreferencePage2_5;
2743
	public static String TargetPlatformPreferencePage2_5;
(-)src/org/eclipse/pde/internal/ui/pderesources.properties (-1 / +3 lines)
Lines 1588-1594 Link Here
1588
ExportTargetExportPlugins = Exporting plugins...
1588
ExportTargetExportPlugins = Exporting plugins...
1589
ExportActiveTargetDefinition = Exporting Target Definition
1589
ExportActiveTargetDefinition = Exporting Target Definition
1590
ExportActiveTargetDefinition_message = Please choose a destination directory to export all target content
1590
ExportActiveTargetDefinition_message = Please choose a destination directory to export all target content
1591
ExportTargetCurrentTarget = Active &Target: 
1591
ExportTargetCurrentTarget = &Target: 
1592
ExportTargetChooseFolder = &Destination:
1592
ExportTargetChooseFolder = &Destination:
1593
ExportTargetBrowse = &Browse...
1593
ExportTargetBrowse = &Browse...
1594
ExportTargetSelectDestination = Select Destination
1594
ExportTargetSelectDestination = Select Destination
Lines 1825-1831 Link Here
1825
TargetPlatformPreferencePage2_26=Garbage Collection
1825
TargetPlatformPreferencePage2_26=Garbage Collection
1826
TargetPlatformPreferencePage2_27=Garbage collecting target definition bundle pool
1826
TargetPlatformPreferencePage2_27=Garbage collecting target definition bundle pool
1827
TargetPlatformPreferencePage2_28=Target Version
1827
TargetPlatformPreferencePage2_28=Target Version
1828
TargetPlatformPreferencePage2_29=Clean Up
1828
TargetPlatformPreferencePage2_3=Add&...
1829
TargetPlatformPreferencePage2_3=Add&...
1830
TargetPlatformPreferencePage2_30=Export...
1829
TargetPlatformPreferencePage2_4=New Target Definition
1831
TargetPlatformPreferencePage2_4=New Target Definition
1830
TargetPlatformPreferencePage2_5=&Edit...
1832
TargetPlatformPreferencePage2_5=&Edit...
1831
TargetPlatformPreferencePage2_6=Edit Target Definition
1833
TargetPlatformPreferencePage2_6=Edit Target Definition
(-)src/org/eclipse/pde/internal/ui/preferences/TargetPlatformPreferencePage.java (+23 lines)
Lines 35-40 Link Here
35
import org.eclipse.pde.internal.ui.shared.target.StyledBundleLabelProvider;
35
import org.eclipse.pde.internal.ui.shared.target.StyledBundleLabelProvider;
36
import org.eclipse.pde.internal.ui.util.SWTUtil;
36
import org.eclipse.pde.internal.ui.util.SWTUtil;
37
import org.eclipse.pde.internal.ui.util.SharedLabelProvider;
37
import org.eclipse.pde.internal.ui.util.SharedLabelProvider;
38
import org.eclipse.pde.internal.ui.wizards.exports.TargetDefinitionExportWizard;
38
import org.eclipse.pde.internal.ui.wizards.target.*;
39
import org.eclipse.pde.internal.ui.wizards.target.*;
39
import org.eclipse.swt.SWT;
40
import org.eclipse.swt.SWT;
40
import org.eclipse.swt.events.*;
41
import org.eclipse.swt.events.*;
Lines 173-178 Link Here
173
	//private Button fDuplicateButton;
174
	//private Button fDuplicateButton;
174
	private Button fRemoveButton;
175
	private Button fRemoveButton;
175
	private Button fMoveButton;
176
	private Button fMoveButton;
177
	private Button fExportButton;
176
178
177
	// Text displaying additional information
179
	// Text displaying additional information
178
	private TableViewer fDetails;
180
	private TableViewer fDetails;
Lines 336-341 Link Here
336
			}
338
			}
337
		});
339
		});
338
340
341
		fExportButton = SWTFactory.createPushButton(buttonComposite, PDEUIMessages.TargetPlatformPreferencePage2_30, null);
342
		fExportButton.addSelectionListener(new SelectionAdapter() {
343
			public void widgetSelected(SelectionEvent e) {
344
				handleExport();
345
			}
346
		});
347
339
		updateButtons();
348
		updateButtons();
340
349
341
		Composite detailsComposite = SWTFactory.createComposite(comp, 1, 1, GridData.FILL_HORIZONTAL, 0, 0);
350
		Composite detailsComposite = SWTFactory.createComposite(comp, 1, 1, GridData.FILL_HORIZONTAL, 0, 0);
Lines 514-519 Link Here
514
	}
523
	}
515
524
516
	/**
525
	/**
526
	 * Export the currently selected target.
527
	 */
528
	private void handleExport() {
529
		if (fTableViewer.getSelection().isEmpty())
530
			return;
531
		ITargetDefinition target = (ITargetDefinition) ((IStructuredSelection) fTableViewer.getSelection()).getFirstElement();
532
		TargetDefinitionExportWizard wizard = new TargetDefinitionExportWizard(target);
533
		wizard.setWindowTitle(PDEUIMessages.ExportActiveTargetDefinition);
534
		WizardDialog dialog = new WizardDialog(fExportButton.getShell(), wizard);
535
		dialog.open();
536
	}
537
538
	/**
517
	 * Removes the selected targets
539
	 * Removes the selected targets
518
	 */
540
	 */
519
	private void handleRemove() {
541
	private void handleRemove() {
Lines 580-585 Link Here
580
		IStructuredSelection selection = (IStructuredSelection) fTableViewer.getSelection();
602
		IStructuredSelection selection = (IStructuredSelection) fTableViewer.getSelection();
581
		int size = selection.size();
603
		int size = selection.size();
582
		fEditButton.setEnabled(size == 1);
604
		fEditButton.setEnabled(size == 1);
605
		fExportButton.setEnabled(size == 1);
583
		fRemoveButton.setEnabled(size > 0);
606
		fRemoveButton.setEnabled(size > 0);
584
		//fDuplicateButton.setEnabled(size == 1);
607
		//fDuplicateButton.setEnabled(size == 1);
585
		if (selection.getFirstElement() != null) {
608
		if (selection.getFirstElement() != null) {
(-)src/org/eclipse/pde/internal/ui/search/dialogs/FilteredIUSelectionDialog.java (-5 / +11 lines)
Lines 13-19 Link Here
13
import java.util.Comparator;
13
import java.util.Comparator;
14
import java.util.Iterator;
14
import java.util.Iterator;
15
import org.eclipse.core.runtime.*;
15
import org.eclipse.core.runtime.*;
16
import org.eclipse.equinox.p2.core.IProvisioningAgent;
17
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
16
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
18
import org.eclipse.equinox.p2.metadata.IProvidedCapability;
17
import org.eclipse.equinox.p2.metadata.IProvidedCapability;
19
import org.eclipse.equinox.p2.query.IQuery;
18
import org.eclipse.equinox.p2.query.IQuery;
Lines 24-29 Link Here
24
import org.eclipse.jface.viewers.*;
23
import org.eclipse.jface.viewers.*;
25
import org.eclipse.pde.internal.core.PDECore;
24
import org.eclipse.pde.internal.core.PDECore;
26
import org.eclipse.pde.internal.core.target.Messages;
25
import org.eclipse.pde.internal.core.target.Messages;
26
import org.eclipse.pde.internal.core.target.P2TargetUtils;
27
import org.eclipse.pde.internal.ui.*;
27
import org.eclipse.pde.internal.ui.*;
28
import org.eclipse.swt.SWT;
28
import org.eclipse.swt.SWT;
29
import org.eclipse.swt.events.SelectionAdapter;
29
import org.eclipse.swt.events.SelectionAdapter;
Lines 67-72 Link Here
67
				styledString.append("(", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
67
				styledString.append("(", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
68
				styledString.append(iuPackage.getVersion().toString(), StyledString.QUALIFIER_STYLER);
68
				styledString.append(iuPackage.getVersion().toString(), StyledString.QUALIFIER_STYLER);
69
				styledString.append(")", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
69
				styledString.append(")", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
70
				IInstallableUnit iu = iuPackage.getIU();
71
				styledString.append(" from ", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
72
				styledString.append(iu.getId(), StyledString.QUALIFIER_STYLER);
73
				styledString.append(' ');
74
				styledString.append("(", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
75
				styledString.append(iu.getVersion().toString(), StyledString.QUALIFIER_STYLER);
76
				styledString.append(")", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
70
			} else if (element instanceof IInstallableUnit) {
77
			} else if (element instanceof IInstallableUnit) {
71
				IInstallableUnit iu = (IInstallableUnit) element;
78
				IInstallableUnit iu = (IInstallableUnit) element;
72
				String name = iu.getProperty(IInstallableUnit.PROP_NAME, null);
79
				String name = iu.getProperty(IInstallableUnit.PROP_NAME, null);
Lines 190-199 Link Here
190
	 */
197
	 */
191
	protected void fillContentProvider(AbstractContentProvider contentProvider, ItemsFilter itemsFilter, IProgressMonitor progressMonitor) throws CoreException {
198
	protected void fillContentProvider(AbstractContentProvider contentProvider, ItemsFilter itemsFilter, IProgressMonitor progressMonitor) throws CoreException {
192
		// TODO clean up this code a bit...
199
		// TODO clean up this code a bit...
193
		IProvisioningAgent agent = (IProvisioningAgent) PDECore.getDefault().acquireService(IProvisioningAgent.SERVICE_NAME);
200
		IMetadataRepositoryManager manager = P2TargetUtils.getRepoManager();
194
		if (agent == null)
201
		if (manager == null)
195
			throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_7));
202
			throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_2));
196
		IMetadataRepositoryManager manager = (IMetadataRepositoryManager) agent.getService(IMetadataRepositoryManager.SERVICE_NAME);
197
203
198
		//URI[] knownRepositories = metadataManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL);
204
		//URI[] knownRepositories = metadataManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL);
199
		IQuery pipedQuery;
205
		IQuery pipedQuery;
(-)src/org/eclipse/pde/internal/ui/search/dialogs/TargetRepositorySearchHandler.java (-3 / +2 lines)
Lines 78-87 Link Here
78
		ITargetPlatformService service = (ITargetPlatformService) PDECore.getDefault().acquireService(ITargetPlatformService.class.getName());
78
		ITargetPlatformService service = (ITargetPlatformService) PDECore.getDefault().acquireService(ITargetPlatformService.class.getName());
79
		ITargetHandle currentTarget = service.getWorkspaceTargetHandle();
79
		ITargetHandle currentTarget = service.getWorkspaceTargetHandle();
80
		ITargetDefinition definition = currentTarget.getTargetDefinition();
80
		ITargetDefinition definition = currentTarget.getTargetDefinition();
81
		IUBundleContainer container = (IUBundleContainer) service.newIUContainer(units, repositories);
82
		// Force the target into slicer mode as all requirements may not be available
81
		// Force the target into slicer mode as all requirements may not be available
83
		container.setIncludeAllRequired(false, definition);
82
		int flags = IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS | IUBundleContainer.INCLUDE_SOURCE;
84
		container.setIncludeAllEnvironments(true, definition);
83
		IUBundleContainer container = (IUBundleContainer) service.newIUContainer(units, repositories, flags);
85
		IBundleContainer[] oldContainers = definition.getBundleContainers();
84
		IBundleContainer[] oldContainers = definition.getBundleContainers();
86
		if (oldContainers == null) {
85
		if (oldContainers == null) {
87
			definition.setBundleContainers(new IBundleContainer[] {container});
86
			definition.setBundleContainers(new IBundleContainer[] {container});
(-)src/org/eclipse/pde/internal/ui/shared/target/AddBundleContainerSelectionPage.java (-10 / +1 lines)
Lines 14-25 Link Here
14
import java.util.ArrayList;
14
import java.util.ArrayList;
15
import java.util.List;
15
import java.util.List;
16
import org.eclipse.core.runtime.*;
16
import org.eclipse.core.runtime.*;
17
import org.eclipse.equinox.p2.engine.IProfile;
18
import org.eclipse.jface.dialogs.*;
17
import org.eclipse.jface.dialogs.*;
19
import org.eclipse.jface.viewers.*;
18
import org.eclipse.jface.viewers.*;
20
import org.eclipse.jface.wizard.*;
19
import org.eclipse.jface.wizard.*;
21
import org.eclipse.pde.internal.core.PDECore;
20
import org.eclipse.pde.internal.core.PDECore;
22
import org.eclipse.pde.internal.core.target.P2TargetUtils;
23
import org.eclipse.pde.internal.core.target.provisional.*;
21
import org.eclipse.pde.internal.core.target.provisional.*;
24
import org.eclipse.pde.internal.ui.*;
22
import org.eclipse.pde.internal.ui.*;
25
import org.eclipse.pde.internal.ui.wizards.WizardElement;
23
import org.eclipse.pde.internal.ui.wizards.WizardElement;
Lines 291-304 Link Here
291
							settings = PDEPlugin.getDefault().getDialogSettings().addNewSection(SETTINGS_SECTION);
289
							settings = PDEPlugin.getDefault().getDialogSettings().addNewSection(SETTINGS_SECTION);
292
						}
290
						}
293
						setDialogSettings(settings);
291
						setDialogSettings(settings);
294
						// TODO Use proper API to get the profile
292
						addPage(new EditIUContainerPage(fTarget));
295
						IProfile profile = null;
296
						try {
297
							profile = P2TargetUtils.getProfile(fTarget);
298
						} catch (CoreException e) {
299
							PDEPlugin.log(e);
300
						}
301
						addPage(new EditIUContainerPage(fTarget, profile));
302
					}
293
					}
303
294
304
					public boolean performFinish() {
295
					public boolean performFinish() {
(-)src/org/eclipse/pde/internal/ui/shared/target/EditBundleContainerWizard.java (-6 / +1 lines)
Lines 10-16 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.pde.internal.ui.shared.target;
11
package org.eclipse.pde.internal.ui.shared.target;
12
12
13
import org.eclipse.core.runtime.CoreException;
14
import org.eclipse.jface.dialogs.IDialogSettings;
13
import org.eclipse.jface.dialogs.IDialogSettings;
15
import org.eclipse.jface.wizard.Wizard;
14
import org.eclipse.jface.wizard.Wizard;
16
import org.eclipse.pde.internal.core.target.*;
15
import org.eclipse.pde.internal.core.target.*;
Lines 50-60 Link Here
50
		} else if (fContainer instanceof FeatureBundleContainer) {
49
		} else if (fContainer instanceof FeatureBundleContainer) {
51
			fPage = new EditFeatureContainerPage(fContainer);
50
			fPage = new EditFeatureContainerPage(fContainer);
52
		} else if (fContainer instanceof IUBundleContainer) {
51
		} else if (fContainer instanceof IUBundleContainer) {
53
			try {
52
			fPage = new EditIUContainerPage((IUBundleContainer) fContainer, fTarget);
54
				fPage = new EditIUContainerPage((IUBundleContainer) fContainer, fTarget, P2TargetUtils.getProfile(fTarget));
55
			} catch (CoreException e) {
56
				PDEPlugin.log(e);
57
			}
58
		}
53
		}
59
		if (fPage != null) {
54
		if (fPage != null) {
60
			addPage(fPage);
55
			addPage(fPage);
(-)src/org/eclipse/pde/internal/ui/shared/target/EditIUContainerPage.java (-38 / +36 lines)
Lines 18-24 Link Here
18
import org.eclipse.equinox.internal.p2.ui.actions.PropertyDialogAction;
18
import org.eclipse.equinox.internal.p2.ui.actions.PropertyDialogAction;
19
import org.eclipse.equinox.internal.p2.ui.dialogs.*;
19
import org.eclipse.equinox.internal.p2.ui.dialogs.*;
20
import org.eclipse.equinox.internal.p2.ui.query.IUViewQueryContext;
20
import org.eclipse.equinox.internal.p2.ui.query.IUViewQueryContext;
21
import org.eclipse.equinox.p2.engine.IProfile;
22
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
21
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
23
import org.eclipse.equinox.p2.ui.Policy;
22
import org.eclipse.equinox.p2.ui.Policy;
24
import org.eclipse.equinox.p2.ui.ProvisioningUI;
23
import org.eclipse.equinox.p2.ui.ProvisioningUI;
Lines 30-35 Link Here
30
import org.eclipse.osgi.util.NLS;
29
import org.eclipse.osgi.util.NLS;
31
import org.eclipse.pde.internal.core.PDECore;
30
import org.eclipse.pde.internal.core.PDECore;
32
import org.eclipse.pde.internal.core.target.IUBundleContainer;
31
import org.eclipse.pde.internal.core.target.IUBundleContainer;
32
import org.eclipse.pde.internal.core.target.P2TargetUtils;
33
import org.eclipse.pde.internal.core.target.provisional.*;
33
import org.eclipse.pde.internal.core.target.provisional.*;
34
import org.eclipse.pde.internal.ui.*;
34
import org.eclipse.pde.internal.ui.*;
35
import org.eclipse.swt.SWT;
35
import org.eclipse.swt.SWT;
Lines 68-78 Link Here
68
	private IUBundleContainer fEditContainer;
68
	private IUBundleContainer fEditContainer;
69
69
70
	/**
70
	/**
71
	 * Profile from the target
72
	 */
73
	private IProfile fProfile;
74
75
	/**
76
	 * Used to provide special attributes/filtering to the available iu group 
71
	 * Used to provide special attributes/filtering to the available iu group 
77
	 */
72
	 */
78
	private IUViewQueryContext fQueryContext;
73
	private IUViewQueryContext fQueryContext;
Lines 97-115 Link Here
97
92
98
	/**
93
	/**
99
	 * Constructor for creating a new container
94
	 * Constructor for creating a new container
100
	 * @param profile profile from the parent target, used to setup the p2 UI
95
	 * @param definition the target definintion we are editing
101
	 */
96
	 */
102
	protected EditIUContainerPage(ITargetDefinition definition, IProfile profile) {
97
	protected EditIUContainerPage(ITargetDefinition definition) {
103
		super("AddP2Container"); //$NON-NLS-1$
98
		super("AddP2Container"); //$NON-NLS-1$
104
		setTitle(Messages.EditIUContainerPage_5);
99
		setTitle(Messages.EditIUContainerPage_5);
105
		setMessage(Messages.EditIUContainerPage_6);
100
		setMessage(Messages.EditIUContainerPage_6);
106
		fTarget = definition;
101
		fTarget = definition;
107
		fProfile = profile;
108
		ProvisioningUI selfProvisioningUI = ProvisioningUI.getDefaultUI();
102
		ProvisioningUI selfProvisioningUI = ProvisioningUI.getDefaultUI();
109
		// TODO we use the service session from the self profile.  In the future we may want
103
		// TODO we use the service session from the self profile.  In the future we may want
110
		// to set up our own services for the profile (separate repo managers, etc).
104
		// to set up our own services for the profile (separate repo managers, etc).
111
		// We use our own new policy so we don't bash the SDK's settings.
105
		// We use our own new policy so we don't bash the SDK's settings.
112
		profileUI = new ProvisioningUI(selfProvisioningUI.getSession(), profile.getProfileId(), new Policy());
106
		profileUI = new ProvisioningUI(selfProvisioningUI.getSession(), P2TargetUtils.getProfileId(definition), new Policy());
113
	}
107
	}
114
108
115
	/**
109
	/**
Lines 117-124 Link Here
117
	 * @param container the container to edit
111
	 * @param container the container to edit
118
	 * @param profile profile from the parent target, used to setup the p2 UI
112
	 * @param profile profile from the parent target, used to setup the p2 UI
119
	 */
113
	 */
120
	protected EditIUContainerPage(IUBundleContainer container, ITargetDefinition definition, IProfile profile) {
114
	protected EditIUContainerPage(IUBundleContainer container, ITargetDefinition definition) {
121
		this(definition, profile);
115
		this(definition);
122
		setTitle(Messages.EditIUContainerPage_7);
116
		setTitle(Messages.EditIUContainerPage_7);
123
		setMessage(Messages.EditIUContainerPage_6);
117
		setMessage(Messages.EditIUContainerPage_6);
124
		fEditContainer = container;
118
		fEditContainer = container;
Lines 132-141 Link Here
132
		if (service == null) {
126
		if (service == null) {
133
			PDEPlugin.log(new Status(IStatus.ERROR, PDEPlugin.getPluginId(), Messages.EditIUContainerPage_9));
127
			PDEPlugin.log(new Status(IStatus.ERROR, PDEPlugin.getPluginId(), Messages.EditIUContainerPage_9));
134
		}
128
		}
135
		IUBundleContainer container = (IUBundleContainer) service.newIUContainer(fAvailableIUGroup.getCheckedLeafIUs(), fRepoLocation != null ? new URI[] {fRepoLocation} : null);
129
		int flags = fIncludeRequiredButton.getSelection() ? IUBundleContainer.INCLUDE_REQUIRED : 0;
136
		container.setIncludeAllRequired(fIncludeRequiredButton.getSelection(), fTarget);
130
		flags |= fAllPlatformsButton.getSelection() ? IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS : 0;
137
		container.setIncludeAllEnvironments(fAllPlatformsButton.getSelection(), fTarget);
131
		flags |= fIncludeSourceButton.getSelection() ? IUBundleContainer.INCLUDE_SOURCE : 0;
138
		container.setIncludeSource(fIncludeSourceButton.getSelection());
132
		IUBundleContainer container = (IUBundleContainer) service.newIUContainer(fAvailableIUGroup.getCheckedLeafIUs(), fRepoLocation != null ? new URI[] {fRepoLocation} : null, flags);
139
		return container;
133
		return container;
140
	}
134
	}
141
135
Lines 299-330 Link Here
299
		});
293
		});
300
		((GridData) fAllPlatformsButton.getLayoutData()).horizontalIndent = 10;
294
		((GridData) fAllPlatformsButton.getLayoutData()).horizontalIndent = 10;
301
		fIncludeSourceButton = SWTFactory.createCheckButton(slicerGroup, Messages.EditIUContainerPage_16, null, true, 1);
295
		fIncludeSourceButton = SWTFactory.createCheckButton(slicerGroup, Messages.EditIUContainerPage_16, null, true, 1);
296
		fIncludeSourceButton.addSelectionListener(new SelectionAdapter() {
297
			public void widgetSelected(SelectionEvent e) {
298
				warnIfGlobalSettingChanged();
299
			}
300
		});
302
	}
301
	}
303
302
304
	private void warnIfGlobalSettingChanged() {
303
	private void warnIfGlobalSettingChanged() {
305
		boolean warn = false;
304
		boolean noChange = true;
306
		if (fTarget != null) {
305
		IUBundleContainer iuContainer = null;
307
			IBundleContainer[] containers = fTarget.getBundleContainers();
306
		IBundleContainer[] containers = fTarget.getBundleContainers();
308
			if (containers != null) {
307
		if (containers != null) {
309
				for (int i = 0; i < containers.length; i++) {
308
			// Look for a IUBundleContainer to compare against.
310
					if (containers[i] instanceof IUBundleContainer && containers[i] != fEditContainer) {
309
			for (int i = 0; i < containers.length; i++) {
311
						IUBundleContainer container = (IUBundleContainer) containers[i];
310
				if (containers[i] instanceof IUBundleContainer && containers[i] != fEditContainer) {
312
						if (container.getIncludeAllRequired() != fIncludeRequiredButton.getSelection()) {
311
					iuContainer = (IUBundleContainer) containers[i];
313
							warn = true;
312
					break;
314
							break;
315
						}
316
						if (!fIncludeRequiredButton.getSelection() && container.getIncludeAllEnvironments() != fAllPlatformsButton.getSelection()) {
317
							warn = true;
318
							break;
319
						}
320
					}
321
				}
313
				}
322
			}
314
			}
315
			// If there is another IU container then compare against it.  No need to check them all
316
			// as they will all be set the same within one target.
317
			if (iuContainer != null) {
318
				noChange &= fIncludeRequiredButton.getSelection() == iuContainer.getIncludeAllRequired();
319
				noChange &= fAllPlatformsButton.getSelection() == iuContainer.getIncludeAllEnvironments();
320
				noChange &= fIncludeSourceButton.getSelection() == iuContainer.getIncludeSource();
321
			}
323
		}
322
		}
324
		if (warn) {
323
		if (noChange) {
325
			setMessage(Messages.EditIUContainerPage_4, IStatus.WARNING);
326
		} else {
327
			setMessage(Messages.EditIUContainerPage_6);
324
			setMessage(Messages.EditIUContainerPage_6);
325
		} else {
326
			setMessage(Messages.EditIUContainerPage_4, IStatus.WARNING);
328
		}
327
		}
329
	}
328
	}
330
329
Lines 333-339 Link Here
333
	 */
332
	 */
334
	private void createQueryContext() {
333
	private void createQueryContext() {
335
		fQueryContext = ProvUI.getQueryContext(ProvisioningUI.getDefaultUI().getPolicy());
334
		fQueryContext = ProvUI.getQueryContext(ProvisioningUI.getDefaultUI().getPolicy());
336
		fQueryContext.setInstalledProfileId(fProfile.getProfileId());
335
		fQueryContext.setInstalledProfileId(P2TargetUtils.getProfileId(fTarget));
337
		fQueryContext.showAlreadyInstalled();
336
		fQueryContext.showAlreadyInstalled();
338
	}
337
	}
339
338
Lines 498-504 Link Here
498
				// Only able to check items if we don't have categories
497
				// Only able to check items if we don't have categories
499
				fQueryContext.setViewType(IUViewQueryContext.AVAILABLE_VIEW_FLAT);
498
				fQueryContext.setViewType(IUViewQueryContext.AVAILABLE_VIEW_FLAT);
500
				fAvailableIUGroup.updateAvailableViewState();
499
				fAvailableIUGroup.updateAvailableViewState();
501
				fAvailableIUGroup.setChecked(fEditContainer.getInstallableUnits(fProfile));
500
				fAvailableIUGroup.setChecked(fEditContainer.getInstallableUnits());
502
				// Make sure view is back in proper state
501
				// Make sure view is back in proper state
503
				updateViewContext();
502
				updateViewContext();
504
				IInstallableUnit[] units = fAvailableIUGroup.getCheckedLeafIUs();
503
				IInstallableUnit[] units = fAvailableIUGroup.getCheckedLeafIUs();
Lines 519-523 Link Here
519
			}
518
			}
520
		}
519
		}
521
	}
520
	}
522
523
}
521
}
(-)src/org/eclipse/pde/internal/ui/shared/target/TargetContentsGroup.java (-2 / +2 lines)
Lines 1028-1037 Link Here
1028
		if (parent == null) {
1028
		if (parent == null) {
1029
			result = fAllBundles.toArray();
1029
			result = fAllBundles.toArray();
1030
		} else if (fFeaureModeButton.getSelection() && parent == OTHER_CATEGORY) {
1030
		} else if (fFeaureModeButton.getSelection() && parent == OTHER_CATEGORY) {
1031
			return ((TargetDefinition) fTargetDefinition).getOtherBundles();
1031
			result = ((TargetDefinition) fTargetDefinition).getOtherBundles();
1032
		} else if (fGrouping == GROUP_BY_CONTAINER && parent instanceof IBundleContainer) {
1032
		} else if (fGrouping == GROUP_BY_CONTAINER && parent instanceof IBundleContainer) {
1033
			IBundleContainer container = (IBundleContainer) parent;
1033
			IBundleContainer container = (IBundleContainer) parent;
1034
			return container.getBundles();
1034
			result = container.getBundles();
1035
		} else if (fGrouping == GROUP_BY_FILE_LOC && parent instanceof IPath) {
1035
		} else if (fGrouping == GROUP_BY_FILE_LOC && parent instanceof IPath) {
1036
			List bundles = (List) getFileBundleMapping().get(parent);
1036
			List bundles = (List) getFileBundleMapping().get(parent);
1037
			if (bundles != null && bundles.size() > 0) {
1037
			if (bundles != null && bundles.size() > 0) {
(-)src/org/eclipse/pde/internal/ui/shared/target/TargetLocationsGroup.java (-7 / +7 lines)
Lines 10-23 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.pde.internal.ui.shared.target;
11
package org.eclipse.pde.internal.ui.shared.target;
12
12
13
import org.eclipse.pde.internal.core.target.UpdateTargetJob;
14
15
import java.util.*;
13
import java.util.*;
16
import java.util.List;
14
import java.util.List;
17
import org.eclipse.core.runtime.*;
15
import org.eclipse.core.runtime.*;
18
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
16
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
19
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
17
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
20
import org.eclipse.equinox.p2.engine.IProfile;
21
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
18
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
22
import org.eclipse.jface.viewers.*;
19
import org.eclipse.jface.viewers.*;
23
import org.eclipse.jface.window.Window;
20
import org.eclipse.jface.window.Window;
Lines 440-446 Link Here
440
		boolean updateAllowed = false;
437
		boolean updateAllowed = false;
441
		Iterator iter = selection.iterator();
438
		Iterator iter = selection.iterator();
442
		while (iter.hasNext()) {
439
		while (iter.hasNext()) {
443
			if (removeAllowed && updateAllowed){
440
			if (removeAllowed && updateAllowed) {
444
				break;
441
				break;
445
			}
442
			}
446
			Object current = iter.next();
443
			Object current = iter.next();
Lines 495-504 Link Here
495
						}
492
						}
496
					} else if (parentElement instanceof IUBundleContainer) {
493
					} else if (parentElement instanceof IUBundleContainer) {
497
						// Show the IUs as children
494
						// Show the IUs as children
498
						// TODO See if we can get the profile using API
499
						try {
495
						try {
500
							IProfile profile = P2TargetUtils.getProfile(fTarget);
496
							// if this is a bundle container then we must be sure that all bundle containers are
501
							IInstallableUnit[] units = ((IUBundleContainer) parentElement).getInstallableUnits(profile);
497
							// happy since they all share the same profile.
498
							if (!P2TargetUtils.isResolved(fTarget)) {
499
								return new Object[0];
500
							}
501
							IInstallableUnit[] units = ((IUBundleContainer) parentElement).getInstallableUnits();
502
							// Wrap the units so that they remember their parent container
502
							// Wrap the units so that they remember their parent container
503
							List wrappedUnits = new ArrayList(units.length);
503
							List wrappedUnits = new ArrayList(units.length);
504
							for (int i = 0; i < units.length; i++) {
504
							for (int i = 0; i < units.length; i++) {
(-)src/org/eclipse/pde/internal/ui/wizards/exports/ExportTargetJob.java (-7 / +4 lines)
Lines 15-27 Link Here
15
import org.eclipse.core.filesystem.*;
15
import org.eclipse.core.filesystem.*;
16
import org.eclipse.core.runtime.*;
16
import org.eclipse.core.runtime.*;
17
import org.eclipse.core.runtime.jobs.Job;
17
import org.eclipse.core.runtime.jobs.Job;
18
import org.eclipse.equinox.p2.engine.IProfile;
19
import org.eclipse.equinox.p2.internal.repository.tools.Repo2Runnable;
18
import org.eclipse.equinox.p2.internal.repository.tools.Repo2Runnable;
20
import org.eclipse.equinox.p2.internal.repository.tools.RepositoryDescriptor;
19
import org.eclipse.equinox.p2.internal.repository.tools.RepositoryDescriptor;
21
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
20
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
22
import org.eclipse.equinox.p2.metadata.IProvidedCapability;
21
import org.eclipse.equinox.p2.metadata.IProvidedCapability;
23
import org.eclipse.equinox.p2.query.IQueryResult;
22
import org.eclipse.equinox.p2.query.IQueryResult;
24
import org.eclipse.equinox.p2.query.QueryUtil;
25
import org.eclipse.pde.internal.core.feature.ExternalFeatureModel;
23
import org.eclipse.pde.internal.core.feature.ExternalFeatureModel;
26
import org.eclipse.pde.internal.core.ifeature.IFeatureModel;
24
import org.eclipse.pde.internal.core.ifeature.IFeatureModel;
27
import org.eclipse.pde.internal.core.target.IUBundleContainer;
25
import org.eclipse.pde.internal.core.target.IUBundleContainer;
Lines 219-231 Link Here
219
	}
217
	}
220
218
221
	private void exportProfile(ITargetDefinition target, URI destination, IProgressMonitor monitor) throws CoreException {
219
	private void exportProfile(ITargetDefinition target, URI destination, IProgressMonitor monitor) throws CoreException {
222
		IProfile profile = P2TargetUtils.getProfile(target);
223
		Repo2Runnable exporter = new Repo2Runnable();
220
		Repo2Runnable exporter = new Repo2Runnable();
224
		exporter.addDestination(createRepoDescriptor(destination, profile.getProfileId(), RepositoryDescriptor.KIND_METADATA));
221
		exporter.addDestination(createRepoDescriptor(destination, P2TargetUtils.getProfileId(target), RepositoryDescriptor.KIND_METADATA));
225
		exporter.addDestination(createRepoDescriptor(destination, profile.getProfileId(), RepositoryDescriptor.KIND_ARTIFACT));
222
		exporter.addDestination(createRepoDescriptor(destination, P2TargetUtils.getProfileId(target), RepositoryDescriptor.KIND_ARTIFACT));
226
		exporter.addSource(createRepoDescriptor(P2TargetUtils.getBundlePool(profile).getLocation(), null, RepositoryDescriptor.KIND_ARTIFACT));
223
		exporter.addSource(createRepoDescriptor(P2TargetUtils.getBundlePool().getLocation(), null, RepositoryDescriptor.KIND_ARTIFACT));
227
224
228
		IQueryResult ius = profile.query(QueryUtil.createIUAnyQuery(), null);
225
		IQueryResult ius = P2TargetUtils.getIUs(target, monitor);
229
		ArrayList toExport = new ArrayList();
226
		ArrayList toExport = new ArrayList();
230
		for (Iterator i = ius.iterator(); i.hasNext();) {
227
		for (Iterator i = ius.iterator(); i.hasNext();) {
231
			IInstallableUnit iu = (IInstallableUnit) i.next();
228
			IInstallableUnit iu = (IInstallableUnit) i.next();
(-)src/org/eclipse/pde/ui/tests/target/IUBundleContainerTests.java (-35 / +14 lines)
Lines 10-19 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.pde.ui.tests.target;
11
package org.eclipse.pde.ui.tests.target;
12
12
13
import org.eclipse.pde.internal.core.target.P2TargetUtils;
14
15
import java.util.Iterator;
16
17
import java.io.*;
13
import java.io.*;
18
import java.net.URI;
14
import java.net.URI;
19
import java.net.URL;
15
import java.net.URL;
Lines 23-30 Link Here
23
import org.eclipse.core.filesystem.URIUtil;
19
import org.eclipse.core.filesystem.URIUtil;
24
import org.eclipse.core.runtime.*;
20
import org.eclipse.core.runtime.*;
25
import org.eclipse.equinox.internal.p2.core.helpers.URLUtil;
21
import org.eclipse.equinox.internal.p2.core.helpers.URLUtil;
26
import org.eclipse.equinox.p2.core.IProvisioningAgent;
27
import org.eclipse.equinox.p2.engine.*;
28
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
22
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
29
import org.eclipse.equinox.p2.query.IQueryResult;
23
import org.eclipse.equinox.p2.query.IQueryResult;
30
import org.eclipse.equinox.p2.query.QueryUtil;
24
import org.eclipse.equinox.p2.query.QueryUtil;
Lines 89-104 Link Here
89
	}
83
	}
90
	
84
	
91
	public void testResolveUsingProfile() throws Exception {
85
	public void testResolveUsingProfile() throws Exception {
92
		String[] bundleIDs = new String[]{"feature.b.feature.group"};
86
		String[] features1 = new String[]{"feature.b.feature.group"};
87
		String[] features2 = new String[]{"feature.a.feature.group"};
93
		String[] expectedBundles = new String[]{"bundle.a1", "bundle.a2", "bundle.a3", "bundle.b1", "bundle.b2", "bundle.b3"};
88
		String[] expectedBundles = new String[]{"bundle.a1", "bundle.a2", "bundle.a3", "bundle.b1", "bundle.b2", "bundle.b3"};
94
		String[] expectedBundles2 = new String[]{"bundle.b1", "bundle.b2", "bundle.b3"};
89
		String[] expectedBundles2 = new String[]{"bundle.a1", "bundle.a2", "bundle.a3"};
95
90
96
		try { 
91
		try { 
97
92
			// create a target that references just a high level root
98
			IUBundleContainer container = createContainer(bundleIDs);
93
			IUBundleContainer container = createContainer(features1);
99
			ITargetDefinition target = getTargetService().newTarget();
94
			ITargetDefinition target = getTargetService().newTarget();
100
			target.setBundleContainers(new IBundleContainer[]{container});
95
			target.setBundleContainers(new IBundleContainer[]{container});
101
102
			List infos = getAllBundleInfos(target);
96
			List infos = getAllBundleInfos(target);
103
			Set names = collectAllSymbolicNames(infos);
97
			Set names = collectAllSymbolicNames(infos);
104
			assertEquals(expectedBundles.length, infos.size());
98
			assertEquals(expectedBundles.length, infos.size());
Lines 106-129 Link Here
106
				assertTrue("Missing: " + expectedBundles[i], names.contains(expectedBundles[i]));
100
				assertTrue("Missing: " + expectedBundles[i], names.contains(expectedBundles[i]));
107
			}
101
			}
108
102
109
			IProfile profile = P2TargetUtils.getProfile(target);
103
			// Now modify the target to have just a lower level root.  The extra higher level stuff should get removed.
110
104
			container = createContainer(features2);
111
			IProvisioningAgent agent = P2TargetUtils.getAgent();
105
			target.setBundleContainers(new IBundleContainer[]{container});
112
			IEngine engine = P2TargetUtils.getEngine();
113
			IProvisioningPlan plan = engine.createPlan(profile, new ProvisioningContext(agent));
114
			IQueryResult units = profile.query(QueryUtil.ALL_UNITS, null);
115
			for (Iterator iterator = units.iterator(); iterator.hasNext();) {
116
				IInstallableUnit unit = (IInstallableUnit) iterator.next();
117
				if (unit.getId().startsWith("bundle.a")){
118
					plan.removeInstallableUnit(unit);
119
				}
120
			}
121
			IPhaseSet phases = PhaseSetFactory.createDefaultPhaseSetExcluding(new String[] {PhaseSetFactory.PHASE_CHECK_TRUST, PhaseSetFactory.PHASE_CONFIGURE, PhaseSetFactory.PHASE_UNCONFIGURE});
122
			IStatus result = engine.perform(plan, phases, null);
123
124
			assertTrue("Problem while provisioning: " + result.getMessage(), result.isOK());
125
			
126
			target.resolve(null);  // Force the target to reresolve (hopefully using the modified profile)
127
			infos = getAllBundleInfos(target);
106
			infos = getAllBundleInfos(target);
128
			names = collectAllSymbolicNames(infos);
107
			names = collectAllSymbolicNames(infos);
129
			assertEquals(expectedBundles2.length, infos.size());
108
			assertEquals(expectedBundles2.length, infos.size());
Lines 211-218 Link Here
211
	 */
190
	 */
212
	public void testContentEqualNull() throws Exception {		
191
	public void testContentEqualNull() throws Exception {		
213
		ITargetPlatformService service = getTargetService();
192
		ITargetPlatformService service = getTargetService();
214
		IUBundleContainer c3 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null);
193
		IUBundleContainer c3 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null, 0);
215
		IUBundleContainer c4 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null);
194
		IUBundleContainer c4 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null, 0);
216
		assertTrue("Contents should be equivalent", c3.isContentEqual(c4));
195
		assertTrue("Contents should be equivalent", c3.isContentEqual(c4));
217
	}
196
	}
218
	
197
	
Lines 223-230 Link Here
223
	 */
202
	 */
224
	public void testContentNotEqualNull() throws Exception {		
203
	public void testContentNotEqualNull() throws Exception {		
225
		ITargetPlatformService service = getTargetService();
204
		ITargetPlatformService service = getTargetService();
226
		IUBundleContainer c3 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null);
205
		IUBundleContainer c3 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null, 1);
227
		IUBundleContainer c4 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.b1", "bundle.b2"}, new String[]{"1.0.0", "1.0.0"}, null);
206
		IUBundleContainer c4 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.b1", "bundle.b2"}, new String[]{"1.0.0", "1.0.0"}, null, 0);
228
		assertFalse("Contents should not be equivalent", c3.isContentEqual(c4));
207
		assertFalse("Contents should not be equivalent", c3.isContentEqual(c4));
229
	}	
208
	}	
230
	
209
	
Lines 356-362 Link Here
356
	 * @throws Exception
335
	 * @throws Exception
357
	 */
336
	 */
358
	protected IUBundleContainer createContainer(IInstallableUnit[] units, URI[] repositories) throws Exception {
337
	protected IUBundleContainer createContainer(IInstallableUnit[] units, URI[] repositories) throws Exception {
359
		return (IUBundleContainer) getTargetService().newIUContainer(units, repositories);
338
		return (IUBundleContainer) getTargetService().newIUContainer(units, repositories, IUBundleContainer.INCLUDE_REQUIRED);
360
	}
339
	}
361
	
340
	
362
	/**
341
	/**
Lines 473-479 Link Here
473
		
452
		
474
		infos = getBundleInfos(c2);
453
		infos = getBundleInfos(c2);
475
		names = collectAllSymbolicNames(infos);
454
		names = collectAllSymbolicNames(infos);
476
		bundleIds = new String[]{"bundle.b1", "bundle.b2", "bundle.b3"};
455
		bundleIds = new String[]{"bundle.a1", "bundle.a2", "bundle.a3", "bundle.b1", "bundle.b2", "bundle.b3"};
477
		assertEquals(bundleIds.length, infos.size());
456
		assertEquals(bundleIds.length, infos.size());
478
		
457
		
479
		for (int i = 0; i < bundleIds.length; i++) {
458
		for (int i = 0; i < bundleIds.length; i++) {
(-)src/org/eclipse/pde/ui/tests/target/TargetDefinitionPersistenceTests.java (-6 / +2 lines)
Lines 236-247 Link Here
236
		IBundleContainer restrictedProfileContainer = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), null);
236
		IBundleContainer restrictedProfileContainer = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), null);
237
	
237
	
238
		// Site bundle containers with different settings
238
		// Site bundle containers with different settings
239
		IUBundleContainer siteContainer = (IUBundleContainer)getTargetService().newIUContainer(new IInstallableUnit[]{}, new URI[]{new URI("TESTURI"), new URI("TESTURI2")});
239
		IUBundleContainer siteContainer = (IUBundleContainer)getTargetService().newIUContainer(new IInstallableUnit[]{}, new URI[]{new URI("TESTURI"), new URI("TESTURI2")}, IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS);
240
		siteContainer.setIncludeAllRequired(false, null);
240
		IUBundleContainer siteContainer2 = (IUBundleContainer)getTargetService().newIUContainer(new String[]{"unit1","unit2"},new String[]{"1.0", "2.0"}, new URI[]{new URI("TESTURI"), new URI("TESTURI2")}, IUBundleContainer.INCLUDE_REQUIRED);
241
		siteContainer.setIncludeAllEnvironments(true, null);
242
		IUBundleContainer siteContainer2 = (IUBundleContainer)getTargetService().newIUContainer(new String[]{"unit1","unit2"},new String[]{"1.0", "2.0"}, new URI[]{new URI("TESTURI"), new URI("TESTURI2")});
243
		siteContainer2.setIncludeAllRequired(true, null);
244
		siteContainer2.setIncludeAllEnvironments(false, null);
245
		
241
		
246
		NameVersionDescriptor[] restrictions = new NameVersionDescriptor[]{
242
		NameVersionDescriptor[] restrictions = new NameVersionDescriptor[]{
247
				new NameVersionDescriptor("org.eclipse.jdt.launching", null),
243
				new NameVersionDescriptor("org.eclipse.jdt.launching", null),
(-)src/org/eclipse/pde/ui/tests/target/TargetDefinitionResolutionTests.java (-22 / +24 lines)
Lines 594-640 Link Here
594
	 */
594
	 */
595
	public void testSiteContainerIncludeSettings() throws Exception{
595
	public void testSiteContainerIncludeSettings() throws Exception{
596
		ITargetDefinition target = getNewTarget();
596
		ITargetDefinition target = getNewTarget();
597
		IUBundleContainer containerA = (IUBundleContainer)getTargetService().newIUContainer(new IInstallableUnit[0], null);
597
		IUBundleContainer containerA = (IUBundleContainer)getTargetService().newIUContainer(new IInstallableUnit[0], null, IUBundleContainer.INCLUDE_REQUIRED);
598
		IUBundleContainer containerB = (IUBundleContainer)getTargetService().newIUContainer(new String[]{"unit1", "unit2"}, new String[]{"1.0","2.0"}, null);
598
		IUBundleContainer containerB = (IUBundleContainer)getTargetService().newIUContainer(new String[]{"unit1", "unit2"}, new String[]{"1.0","2.0"}, null, IUBundleContainer.INCLUDE_REQUIRED);
599
		target.setBundleContainers(new IBundleContainer[]{containerA, containerB});
599
		target.setBundleContainers(new IBundleContainer[]{containerA, containerB});
600
		
600
		
601
		// Check default settings
601
		// Check default settings
602
		assertTrue(containerA.getIncludeAllRequired());
602
		assertTrue(containerA.getIncludeAllRequired());
603
		assertFalse(containerA.getIncludeAllEnvironments());
603
		assertFalse(containerA.getIncludeAllEnvironments());
604
		assertFalse(containerA.getIncludeSource());
604
		assertTrue(containerB.getIncludeAllRequired());
605
		assertTrue(containerB.getIncludeAllRequired());
605
		assertFalse(containerB.getIncludeAllEnvironments());
606
		assertFalse(containerB.getIncludeAllEnvironments());
607
		assertFalse(containerB.getIncludeSource());
606
		
608
		
607
		// Check basic changes
609
		// Check basic changes
608
		containerA.setIncludeAllRequired(false, null);
610
		int flags = IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS | IUBundleContainer.INCLUDE_SOURCE;
609
		containerA.setIncludeAllEnvironments(true, null);
611
		containerA = (IUBundleContainer)getTargetService().newIUContainer(new IInstallableUnit[0], null, flags);
612
		containerB = (IUBundleContainer)getTargetService().newIUContainer(new String[]{"unit1", "unit2"}, new String[]{"1.0","2.0"}, null, flags);
613
		target.setBundleContainers(new IBundleContainer[]{containerA, containerB});
610
		assertFalse(containerA.getIncludeAllRequired());
614
		assertFalse(containerA.getIncludeAllRequired());
611
		assertTrue(containerA.getIncludeAllEnvironments());
615
		assertTrue(containerA.getIncludeAllEnvironments());
612
		containerA.setIncludeAllEnvironments(false, null);
616
		assertTrue(containerA.getIncludeSource());
613
		containerA.setIncludeAllRequired(true, null);
614
		assertTrue(containerA.getIncludeAllRequired());
615
		assertFalse(containerA.getIncludeAllEnvironments());
616
		
617
		
617
		// Check that all containers are updated in the target if target is passed as argument
618
		// Check that all containers are updated in the target if target is passed as argument
618
		containerA.setIncludeAllRequired(false, target);
619
		flags = IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS | IUBundleContainer.INCLUDE_SOURCE;
619
		assertFalse(containerA.getIncludeAllRequired());
620
		containerA = (IUBundleContainer)getTargetService().newIUContainer(new IInstallableUnit[0], null, flags);
620
		assertFalse(containerA.getIncludeAllEnvironments());
621
		flags = IUBundleContainer.INCLUDE_REQUIRED;
621
		assertFalse(containerB.getIncludeAllRequired());
622
		containerB = (IUBundleContainer)getTargetService().newIUContainer(new String[]{"unit1", "unit2"}, new String[]{"1.0","2.0"}, null, flags);
622
		assertFalse(containerB.getIncludeAllEnvironments());
623
623
		containerB.setIncludeAllRequired(true, target);
624
		target.setBundleContainers(new IBundleContainer[]{containerA, containerB});
624
		assertTrue(containerA.getIncludeAllRequired());
625
		assertTrue(containerA.getIncludeAllRequired());
625
		assertFalse(containerA.getIncludeAllEnvironments());
626
		assertFalse(containerA.getIncludeAllEnvironments());
627
		assertFalse(containerA.getIncludeSource());
626
		assertTrue(containerB.getIncludeAllRequired());
628
		assertTrue(containerB.getIncludeAllRequired());
627
		assertFalse(containerB.getIncludeAllEnvironments());
629
		assertFalse(containerB.getIncludeAllEnvironments());
628
		containerA.setIncludeAllEnvironments(true, target);
630
		assertFalse(containerB.getIncludeSource());
629
		assertTrue(containerA.getIncludeAllRequired());
631
632
		// now switch the order of A and B
633
		target.setBundleContainers(new IBundleContainer[]{containerB, containerA});
634
		assertFalse(containerA.getIncludeAllRequired());
630
		assertTrue(containerA.getIncludeAllEnvironments());
635
		assertTrue(containerA.getIncludeAllEnvironments());
631
		assertTrue(containerB.getIncludeAllRequired());
636
		assertTrue(containerA.getIncludeSource());
637
		assertFalse(containerB.getIncludeAllRequired());
632
		assertTrue(containerB.getIncludeAllEnvironments());
638
		assertTrue(containerB.getIncludeAllEnvironments());
633
		containerB.setIncludeAllEnvironments(false, target);
639
		assertTrue(containerB.getIncludeSource());
634
		assertTrue(containerA.getIncludeAllRequired());
635
		assertFalse(containerA.getIncludeAllEnvironments());
636
		assertTrue(containerB.getIncludeAllRequired());
637
		assertFalse(containerB.getIncludeAllEnvironments());
638
	}
640
	}
639
	
641
	
640
	public void testNameVersionDescriptor() {
642
	public void testNameVersionDescriptor() {

Return to bug 331068