Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 184185 Details for
Bug 331068
[target] Update the use of profiles
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Patch with my updates
clipboard.txt (text/plain), 161.40 KB, created by
Curtis Windatt
on 2010-11-30 16:08:05 EST
(
hide
)
Description:
Patch with my updates
Filename:
MIME Type:
Creator:
Curtis Windatt
Created:
2010-11-30 16:08:05 EST
Size:
161.40 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.pde.core >Index: src/org/eclipse/pde/internal/core/target/AbstractBundleContainer.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/AbstractBundleContainer.java,v >retrieving revision 1.9 >diff -u -r1.9 AbstractBundleContainer.java >--- src/org/eclipse/pde/internal/core/target/AbstractBundleContainer.java 30 Aug 2010 21:30:07 -0000 1.9 >+++ src/org/eclipse/pde/internal/core/target/AbstractBundleContainer.java 30 Nov 2010 21:03:55 -0000 >@@ -41,12 +41,12 @@ > /** > * Resolved bundles or <code>null</code> if unresolved > */ >- private IResolvedBundle[] fBundles; >+ protected IResolvedBundle[] fBundles; > > /** > * List of features contained in this bundle container or <code>null</code> if unresolved > */ >- private IFeatureModel[] fFeatures; >+ protected IFeatureModel[] fFeatures; > > /** > * Status generated when this container was resolved, possibly <code>null</code> >@@ -551,4 +551,14 @@ > } > return fVMArgs; > } >+ >+ /** >+ * Associate this bundle container with the given target. This allows for the container and >+ * the target to share configuration information etc. >+ * >+ * @param target the target to which this container is being added. >+ */ >+ protected void associateWithTarget(ITargetDefinition target) { >+ // Do nothing by default >+ } > } >Index: src/org/eclipse/pde/internal/core/target/IUBundleContainer.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/IUBundleContainer.java,v >retrieving revision 1.33 >diff -u -r1.33 IUBundleContainer.java >--- src/org/eclipse/pde/internal/core/target/IUBundleContainer.java 17 Nov 2010 20:00:09 -0000 1.33 >+++ src/org/eclipse/pde/internal/core/target/IUBundleContainer.java 30 Nov 2010 21:03:55 -0000 >@@ -8,31 +8,19 @@ > * Contributors: > * IBM Corporation - initial API and implementation > * Sonatype, Inc. - ongoing development >+ * EclipseSource, Inc. - ongoing development > *******************************************************************************/ > package org.eclipse.pde.internal.core.target; > > import java.io.File; > import java.net.URI; >-import java.net.URISyntaxException; > import java.util.*; > import org.eclipse.core.runtime.*; >-import org.eclipse.core.runtime.preferences.IPreferencesService; > import org.eclipse.equinox.internal.p2.director.PermissiveSlicer; >-import org.eclipse.equinox.internal.p2.engine.ProfileMetadataRepository; >-import org.eclipse.equinox.p2.core.IAgentLocation; >-import org.eclipse.equinox.p2.core.ProvisionException; >-import org.eclipse.equinox.p2.engine.*; >-import org.eclipse.equinox.p2.engine.query.IUProfilePropertyQuery; >+import org.eclipse.equinox.p2.engine.IProfile; > import org.eclipse.equinox.p2.metadata.*; >-import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription; >-import org.eclipse.equinox.p2.planner.IPlanner; >-import org.eclipse.equinox.p2.planner.IProfileChangeRequest; > import org.eclipse.equinox.p2.query.*; >-import org.eclipse.equinox.p2.repository.*; >-import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager; > import org.eclipse.equinox.p2.repository.artifact.IFileArtifactRepository; >-import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository; >-import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager; > import org.eclipse.equinox.p2.touchpoint.eclipse.query.OSGiBundleQuery; > import org.eclipse.osgi.util.NLS; > import org.eclipse.pde.internal.core.PDECore; >@@ -57,64 +45,56 @@ > private static final String FEATURE_ID_SUFFIX = ".feature.group"; //$NON-NLS-1$ > > /** >- * IU identifiers. >+ * Whether this container must have all required IUs of the selected IUs available and included >+ * in the target to resolve successfully. If this option is true, the planner will be used to resolve >+ * otherwise the slicer is used. The planner can describe any missing requirements as errors. > */ >- private String[] fIds; >+ public static final int INCLUDE_REQUIRED = 1 << 0; > > /** >- * IU versions >+ * Whether this container should download and include environment (platform) specific units for all >+ * available platforms (vs only the current target definition's environment settings). Only supported >+ * by the slicer so {@link fIncludeAllRequired} must be turned off for this setting to be used. > */ >- private Version[] fVersions; >+ public static final int INCLUDE_ALL_ENVIRONMENTS = 1 << 1; > > /** >- * Cached IU's referenced by this bundle container, or <code>null</code> if not >- * resolved. >+ * Whether this container should download and include source bundles for the selected units if the associated >+ * source is available in the repository. > */ >- private IInstallableUnit[] fUnits; >+ public static final int INCLUDE_SOURCE = 1 << 2; > > /** >- * Cached id/version pairs listing the features that were downloaded to the bundle pool during resolution. <code>null</code> if not resolved. >+ * IU identifiers. > */ >- private NameVersionDescriptor[] fFeatures; >+ private String[] fIds; > > /** >- * Repositories to consider, or <code>null</code> if default. >+ * IU versions > */ >- private URI[] fRepos; >+ private Version[] fVersions; > > /** >- * Whether this container must have all required IUs of the selected IUs available and included >- * in the target to resolve successfully. If this option is true, the planner will be used to resolve >- * otherwise the slicer is used. The planner can describe any missing requirements as errors. >- * <p> >- * <code>true</code> by default >- * </p> >+ * Cached IU's referenced by this bundle container, or <code>null</code> if not >+ * resolved. > */ >- private boolean fIncludeAllRequired = true; >+ private IInstallableUnit[] fUnits; > > /** >- * Whether this container should download and include environment (platform) specific units for all >- * available platforms (vs only the current target definition's environment settings). Only supported >- * by the slicer so {@link fIncludeAllRequired} must be turned off for this setting to be used. >- * <p> >- * <code>false</code> by default >- * </p> >+ * Repositories to consider, or <code>null</code> if default. > */ >- private boolean fIncludeMultipleEnvironments = false; >+ private URI[] fRepos; > > /** >- * Whether this container should download and include source bundles for the selected units if the associated >- * source is available in the repository. >- * <p> >- * <code>false</code>by default >+ * A set of bitmask flags that indicate how this container gets elements from its >+ * associated p2 repository. > */ >- private boolean fIncludeSource = false; >+ private int fFlags; > > /** >- * Constant ID for a root installable unit that is installed into the profile if {@link #fIncludeSource} is set >- * to <code>true</code>. The source units found in the repository will be set as required IUs on the root unit. >+ * The p2 synchronizer to use in managing this container. > */ >- private static final String SOURCE_IU_ID = "org.eclipse.pde.core.target.source.bundles"; //$NON-NLS-1$ >+ private P2TargetUtils fSynchronizer; > > private static final boolean DEBUG_PROFILE; > >@@ -127,11 +107,12 @@ > * > * @param ids IU identifiers > * @param versions IU versions >- * @param repositories metadata repositories used to search for IU's or <code>null</code> if >- * default set >+ * @param repositories metadata repositories used to search for IU's or <code>null</code> for default set >+ * @param resolutionFlags bitmask of flags to control IU resolution, possible flags are {@link IUBundleContainer#INCLUDE_ALL_ENVIRONMENTS}, {@link IUBundleContainer#INCLUDE_REQUIRED}, {@link IUBundleContainer#INCLUDE_SOURCE} > */ >- IUBundleContainer(String[] ids, String[] versions, URI[] repositories) { >+ IUBundleContainer(String[] ids, String[] versions, URI[] repositories, int resolutionFlags) { > fIds = ids; >+ fFlags = resolutionFlags; > fVersions = new Version[versions.length]; > for (int i = 0; i < versions.length; i++) { > fVersions[i] = Version.create(versions[i]); >@@ -148,12 +129,12 @@ > * Constructs a installable unit bundle container for the specified units. > * > * @param units IU's >- * @param repositories metadata repositories used to search for IU's or <code>null</code> if >- * default set >+ * @param repositories metadata repositories used to search for IU's or <code>null</code> for default set >+ * @param resolutionFlags bitmask of flags to control IU resolution, possible flags are {@link IUBundleContainer#INCLUDE_ALL_ENVIRONMENTS}, {@link IUBundleContainer#INCLUDE_REQUIRED}, {@link IUBundleContainer#INCLUDE_SOURCE} > */ >- IUBundleContainer(IInstallableUnit[] units, URI[] repositories) { >- fUnits = units; >+ IUBundleContainer(IInstallableUnit[] units, URI[] repositories, int resolutionFlags) { > fIds = new String[units.length]; >+ fFlags = resolutionFlags; > fVersions = new Version[units.length]; > for (int i = 0; i < units.length; i++) { > fIds[i] = units[i].getId(); >@@ -184,609 +165,131 @@ > * @see org.eclipse.pde.internal.core.target.AbstractBundleContainer#resolveFeatures(org.eclipse.pde.internal.core.target.provisional.ITargetDefinition, org.eclipse.core.runtime.IProgressMonitor) > */ > protected IFeatureModel[] resolveFeatures(ITargetDefinition definition, IProgressMonitor monitor) throws CoreException { >- if (fFeatures == null || fFeatures.length == 0 || !(definition instanceof TargetDefinition)) { >+ fSynchronizer.synchronize(monitor); >+ return fFeatures; >+ } >+ >+ /** >+ * Update this container's cache of feature objects based on the given profile. >+ * NOTE: this method expects the synchronizer to be synchronized and is called >+ * as a result of a synchronization operation. >+ */ >+ IFeatureModel[] cacheFeatures() throws CoreException { >+ Set features = new HashSet(); >+ for (int i = 0; i < fUnits.length; i++) { >+ IInstallableUnit unit = fUnits[i]; >+ String id = unit.getId(); >+ // if theIU was explicitly added and the naming convention says it is a feature, then add it. >+ // This is less than optimal but there is no clear way of identifying an IU as a feature. >+ if (isRoot(id, unit.getVersion()) && id.endsWith(FEATURE_ID_SUFFIX)) { >+ id = id.substring(0, id.length() - FEATURE_ID_SUFFIX.length()); >+ String version = unit.getVersion().toString(); >+ features.add(new NameVersionDescriptor(id, version, NameVersionDescriptor.TYPE_FEATURE)); >+ } >+ } >+ if (features.isEmpty()) { > return new IFeatureModel[0]; > } > >- // Note: By creating a map of the container features, we are limiting the user to only one version of a feature in this container >+ // Now get feature models for all known features >+ TargetDefinition definition = (TargetDefinition) fSynchronizer.getTargetDefinition(); >+ IFeatureModel[] allFeatures = definition.getFeatureModels(getLocation(false), new NullProgressMonitor()); > >- // Get all the features in the bundle pool >- IFeatureModel[] allFeatures = ((TargetDefinition) definition).getFeatureModels(getLocation(false), monitor); >- >- // Create a map of the container features for quick lookups >- HashMap containerFeatures = new HashMap(); >- for (int i = 0; i < fFeatures.length; i++) { >- containerFeatures.put(fFeatures[i].getId(), fFeatures[i]); >- } >- >- List includedFeatures = new ArrayList(); >+ // Build a final set of the models for the features in the profile. >+ List result = new ArrayList(); > for (int i = 0; i < allFeatures.length; i++) { >- NameVersionDescriptor candidate = (NameVersionDescriptor) containerFeatures.get(allFeatures[i].getFeature().getId()); >- if (candidate != null) { >- if (candidate.getVersion().equals(allFeatures[i].getFeature().getVersion())) { >- includedFeatures.add(allFeatures[i]); >- } >+ NameVersionDescriptor candidate = new NameVersionDescriptor(allFeatures[i].getFeature().getId(), allFeatures[i].getFeature().getVersion(), NameVersionDescriptor.TYPE_FEATURE); >+ if (features.contains(candidate)) { >+ result.add(allFeatures[i]); > } > } >- return (IFeatureModel[]) includedFeatures.toArray(new IFeatureModel[includedFeatures.size()]); >+ fFeatures = (IFeatureModel[]) result.toArray(new IFeatureModel[result.size()]); >+ return fFeatures; >+ } >+ >+ private boolean isRoot(String id, Version version) { >+ for (int i = 0; i < fIds.length; i++) { >+ String fid = fIds[i]; >+ if (fid.equals(id) && fVersions[i].equals(version)) >+ return true; >+ } >+ return false; > } > > /* (non-Javadoc) > * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#resolveBundles(org.eclipse.pde.internal.core.target.provisional.ITargetDefinition, org.eclipse.core.runtime.IProgressMonitor) > */ > protected IResolvedBundle[] resolveBundles(ITargetDefinition definition, IProgressMonitor monitor) throws CoreException { >- // Resolving may change the included features, clear the cached values >- fFeatures = null; >- >- SubMonitor subMon = SubMonitor.convert(monitor, 100); >- >- // Attempt to restore from the profile first, as it is local and faster >- IResolvedBundle[] result = resolveWithProfile(definition, subMon.newChild(25)); >- if (result != null) { >- subMon.done(); >- return result; >- } >- >- // Unable to load from profile, resolve normally >- try { >- if (fIncludeAllRequired) { >- result = resolveWithPlanner(definition, subMon.newChild(75)); >- } else { >- result = resolveWithSlicer(definition, subMon.newChild(75)); >- } >- // If there is a problem generating the profile, delete it so it doesn't get used by #resolveWithProfile() >- if (result == null || result.length == 0 || subMon.isCanceled()) { >- AbstractTargetHandle handle = ((AbstractTargetHandle) definition.getHandle()); >- P2TargetUtils.deleteProfile(handle); >- } >- return result; >- } catch (CoreException e) { >- AbstractTargetHandle handle = ((AbstractTargetHandle) definition.getHandle()); >- P2TargetUtils.deleteProfile(handle); >- throw e; >- } >- >+ fSynchronizer.synchronize(monitor); >+ return fBundles; > } > > /** >- * Used to resolve the contents of this container if the container has been resolved and saved to a profile file. If the >- * profile contains the correct bundles, there is no need to do a full resolve. If this method has a problem (missing >- * file, unable to compute all dependent bundles), this method will return <code>null</code> and the caller should >- * use {@link #resolveWithPlanner(ITargetDefinition, IProgressMonitor)} or {@link #resolveWithSlicer(ITargetDefinition, IProgressMonitor)} >- * to do a full resolve. >- * >- * @param definition definition being resolved >- * @param monitor for reporting progress >- * @return set of bundles included in this container or <code>null</code> if the profile is out of date >- * @throws CoreException if an unexpected problem occurs trying to read from the profile >- */ >- private IResolvedBundle[] resolveWithProfile(ITargetDefinition definition, IProgressMonitor monitor) throws CoreException { >- if (DEBUG_PROFILE) { >- System.out.println("Target resolution using profile (" + definition.getName() + ")"); //$NON-NLS-1$//$NON-NLS-2$ >- } >- >- IProfile profile = P2TargetUtils.getProfile(definition); >- if (profile == null) { >- if (DEBUG_PROFILE) { >- System.out.println("No profile found"); //$NON-NLS-1$ >- } >- return null; >- } >- >- SubMonitor subMonitor = SubMonitor.convert(monitor, Messages.IUBundleContainer_LoadingFromProfileJob, 20); >- >- // Always create our own units because the slicer will return existing units even though the profile is empty >- if (DEBUG_PROFILE) { >- System.out.print("Required Units: "); //$NON-NLS-1$ >- for (int i = 0; i < fIds.length; i++) { >- System.out.print(fIds[i] + ", "); //$NON-NLS-1$ >- } >- System.out.println(); >- } >- >- fUnits = new IInstallableUnit[fIds.length]; >+ * Update this container's cache of top level IUs based on the given profile. >+ * NOTE: this method expects the synchronizer to be synchronized and is called >+ * as a result of a synchronization operation. >+ */ >+ IInstallableUnit[] cacheIUs() throws CoreException { >+ IProfile profile = fSynchronizer.getProfile(); >+ ArrayList result = new ArrayList(); > for (int i = 0; i < fIds.length; i++) { > IQuery query = QueryUtil.createIUQuery(fIds[i], fVersions[i]); > IQueryResult queryResult = profile.query(query, null); >- if (queryResult.isEmpty()) { >- if (DEBUG_PROFILE) { >- System.out.println("Required unit not found in profile: " + fIds[i]); //$NON-NLS-1$ >- } >- fUnits = null; >- return null; >- } >- fUnits[i] = (IInstallableUnit) queryResult.iterator().next(); >- } >- // check that the include source flag matches what the profile represents >- if (fIncludeSource != (getCurrentSourceIU(profile) != null)) >- return null; >- >- // OK. Everything looks good. Now gather the features and bundles and be done. >- ResolvedBundle[] resolvedBundles = updateAfterResolve(profile, definition); >- >- subMonitor.worked(10); >- subMonitor.done(); >- if (DEBUG_PROFILE) { >- if (resolvedBundles == null || resolvedBundles.length == 0) >- System.out.println("No bundles loaded from profile"); //$NON-NLS-1$ >- else >- System.out.println("Loading from profile successful. " + resolvedBundles.length + " bundles found"); //$NON-NLS-1$ //$NON-NLS-2$ >- System.out.println(); >- } >- return resolvedBundles; >- } >- >- /** >- * Used to resolve the contents of this container if the user is including all required software. The p2 planner is used >- * to determine the complete set of IUs required to run the selected software. If all requirements are met, the bundles >- * are downloaded from the repository into the bundle pool and added to the target definition. >- * >- * @param definition definition being resolved >- * @param monitor for reporting progress >- * @return set of bundles included in this container >- * @throws CoreException if there is a problem with the requirements or there is a problem downloading >- */ >- private IResolvedBundle[] resolveWithPlanner(ITargetDefinition definition, IProgressMonitor monitor) throws CoreException { >- SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 10); >- subMonitor.beginTask(Messages.IUBundleContainer_0, 200); >- >- // retrieve profile >- IProfile profile = P2TargetUtils.getProfile(definition); >- profile.getTimestamp(); >- subMonitor.worked(10); >- >- if (subMonitor.isCanceled()) { >- return new IResolvedBundle[0]; >- } >- >- // resolve IUs >- IInstallableUnit[] units = getInstallableUnits(profile); >- >- if (subMonitor.isCanceled()) { >- return new IResolvedBundle[0]; >- } >- >- // create the provisioning plan >- IPlanner planner = P2TargetUtils.getPlanner(); >- IProfileChangeRequest request = planner.createChangeRequest(profile); >- // first remove everything that was explicitly installed. Then add it back. This has the net effect of >- // removing everything that is no longer needed. >- computeRemovals(profile, request, units); >- request.addAll(Arrays.asList(units)); >- for (int i = 0; i < units.length; i++) { >- IInstallableUnit unit = units[i]; >- request.setInstallableUnitProfileProperty(unit, P2TargetUtils.PROP_INSTALLED_IU, Boolean.toString(true)); >- } >- >- ProvisioningContext context = new ProvisioningContext(P2TargetUtils.getAgent()); >- context.setMetadataRepositories(resolveRepositories()); >- context.setArtifactRepositories(resolveArtifactRepositories()); >- >- if (subMonitor.isCanceled()) { >- return new IResolvedBundle[0]; >- } >- >- IProvisioningPlan plan = planner.getProvisioningPlan(request, context, new SubProgressMonitor(subMonitor, 20)); >- IStatus status = plan.getStatus(); >- if (!status.isOK()) { >- throw new CoreException(status); >- } >- IProvisioningPlan installerPlan = plan.getInstallerPlan(); >- if (installerPlan != null) { >- // this plan requires an update to the installer first, log the fact and attempt >- // to continue, we don't want to update the running SDK while provisioning a target >- PDECore.log(new Status(IStatus.INFO, PDECore.PLUGIN_ID, Messages.IUBundleContainer_6)); >- } >- subMonitor.worked(10); >- >- if (subMonitor.isCanceled()) { >- return new IResolvedBundle[0]; >- } >- >- // execute the provisioning plan >- IPhaseSet phases = PhaseSetFactory.createDefaultPhaseSetExcluding(new String[] {PhaseSetFactory.PHASE_CHECK_TRUST, PhaseSetFactory.PHASE_CONFIGURE, PhaseSetFactory.PHASE_UNCONFIGURE}); >- IEngine engine = P2TargetUtils.getEngine(); >- plan.setProfileProperty(P2TargetUtils.PROP_PROVISION_MODE, TargetDefinitionPersistenceHelper.MODE_PLANNER); >- plan.setProfileProperty(P2TargetUtils.PROP_ALL_ENVIRONMENTS, Boolean.toString(false)); >- IStatus result = engine.perform(plan, phases, new SubProgressMonitor(subMonitor, 140)); >- >- if (subMonitor.isCanceled()) { >- return new IResolvedBundle[0]; >- } >- if (!result.isOK()) { >- throw new CoreException(result); >- } >- >- // Now that we have a plan with all the binary and explicit bundles, do a second pass and add >- // in all the source. >- try { >- planInSourceBundles(profile, context, subMonitor); >- } catch (CoreException e) { >- // XXX Review required: is adding in the source critical or optional? >- // We failed adding in the source so remove the intermediate profile and rethrow >- P2TargetUtils.getProfileRegistry().removeProfile(profile.getProfileId(), profile.getTimestamp()); >- throw e; >- } >- >- ResolvedBundle[] resolvedBundles = updateAfterResolve(profile, definition); >- subMonitor.worked(10); >- subMonitor.done(); >- return resolvedBundles; >- } >- >- /** >- * Update the given change request to remove anything that was explicitly installed >- * including the internal source IU. >- */ >- private void computeRemovals(IProfile profile, IProfileChangeRequest request, IInstallableUnit[] units) { >- // if include source is off then ensure that the source IU is removed. >- if (!fIncludeSource) { >- IInstallableUnit sourceIU = getCurrentSourceIU(profile); >- if (sourceIU != null) >- request.remove(sourceIU); >- } >- // remove everything that is marked as roots. The plan will have the new roots added in anyway. >- IQuery query = new IUProfilePropertyQuery(P2TargetUtils.PROP_INSTALLED_IU, Boolean.toString(true)); >- IQueryResult installedIUs = profile.query(query, null); >- request.removeAll(installedIUs.toSet()); >- } >- >- // run a second pass of the planner to add in the source bundles for everything that's >- // in the current profile. >- private void planInSourceBundles(IProfile profile, ProvisioningContext context, IProgressMonitor monitor) throws CoreException { >- if (!fIncludeSource) >- return; >- >- SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 10); >- subMonitor.beginTask(Messages.IUBundleContainer_ProvisioningSourceBundles, 200); >- >- // create an IU that optionally and greedily requires the related source bundles. >- // Completely replace any source IU that may already be in place >- IInstallableUnit currentSourceIU = getCurrentSourceIU(profile); >- >- // determine the new version number. start at 1 >- Version sourceVersion = Version.createOSGi(1, 0, 0); >- if (currentSourceIU != null) { >- Integer major = (Integer) currentSourceIU.getVersion().getSegment(0); >- sourceVersion = Version.createOSGi(major.intValue() + 1, 0, 0); >- } >- IInstallableUnit sourceIU = createSourceIU(profile, sourceVersion); >- >- // call the planner again to add in the new source IU and all available source bundles >- IPlanner planner = P2TargetUtils.getPlanner(); >- IProfileChangeRequest request = planner.createChangeRequest(profile); >- if (currentSourceIU != null) >- request.remove(currentSourceIU); >- request.add(sourceIU); >- IProvisioningPlan plan = planner.getProvisioningPlan(request, context, new SubProgressMonitor(subMonitor, 20)); >- IStatus status = plan.getStatus(); >- if (!status.isOK()) { >- throw new CoreException(status); >- } >- if (subMonitor.isCanceled()) { >- return; >- } >- >- long oldTimestamp = profile.getTimestamp(); >- >- // execute the provisioning plan >- IPhaseSet phases = PhaseSetFactory.createDefaultPhaseSetExcluding(new String[] {PhaseSetFactory.PHASE_CHECK_TRUST, PhaseSetFactory.PHASE_CONFIGURE, PhaseSetFactory.PHASE_UNCONFIGURE, PhaseSetFactory.PHASE_UNINSTALL}); >- IEngine engine = P2TargetUtils.getEngine(); >- plan.setProfileProperty(P2TargetUtils.PROP_PROVISION_MODE, TargetDefinitionPersistenceHelper.MODE_PLANNER); >- plan.setProfileProperty(P2TargetUtils.PROP_ALL_ENVIRONMENTS, Boolean.toString(false)); >- IStatus result = engine.perform(plan, phases, new SubProgressMonitor(subMonitor, 140)); >- >- if (subMonitor.isCanceled()) { >- return; >- } >- if (!result.isOK()) { >- throw new CoreException(result); >- } >- >- // remove the old (intermediate) profile version now we have a new one with source. >- P2TargetUtils.getProfileRegistry().removeProfile(profile.getProfileId(), oldTimestamp); >- subMonitor.worked(10); >- subMonitor.done(); >- } >- >- // Create and return an IU that has optional and greedy requirements on all source bundles >- // related to bundle IUs in the given queryable. >- /** >- * Creates and returns an IU that has optional and greedy requirements on all source bundles >- * related to bundle IUs in the given queryable. >- * @param queryable location to search for source bundle IUs >- * @param iuVersion version to set on the returned installable unit >- * @return a new installable unit with requirements on the available source IUs >- */ >- private IInstallableUnit createSourceIU(IQueryable queryable, Version iuVersion) { >- // compute the set of source bundles we could possibly need for the bundles in the profile >- IRequirement bundleRequirement = MetadataFactory.createRequirement("org.eclipse.equinox.p2.eclipse.type", "bundle", null, null, false, false, false); //$NON-NLS-1$ //$NON-NLS-2$ >- IQueryResult profileIUs = queryable.query(QueryUtil.createIUAnyQuery(), null); >- ArrayList requirements = new ArrayList(); >- for (Iterator i = profileIUs.iterator(); i.hasNext();) { >- IInstallableUnit profileIU = (IInstallableUnit) i.next(); >- if (profileIU.satisfies(bundleRequirement)) { >- String id = profileIU.getId() + ".source"; //$NON-NLS-1$ >- Version version = profileIU.getVersion(); >- VersionRange range = new VersionRange(version, true, version, true); >- IRequirement sourceRequirement = MetadataFactory.createRequirement("osgi.bundle", id, range, null, true, false, true); //$NON-NLS-1$ >- requirements.add(sourceRequirement); >- } >+ if (queryResult.isEmpty()) >+ throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.IUBundleContainer_1, fIds[i]))); >+ result.add(queryResult.iterator().next()); > } >- >- InstallableUnitDescription sourceDescription = new MetadataFactory.InstallableUnitDescription(); >- sourceDescription.setSingleton(true); >- sourceDescription.setId(SOURCE_IU_ID); >- sourceDescription.setVersion(iuVersion); >- sourceDescription.addRequirements(requirements); >- IProvidedCapability capability = MetadataFactory.createProvidedCapability(IInstallableUnit.NAMESPACE_IU_ID, SOURCE_IU_ID, iuVersion); >- sourceDescription.setCapabilities(new IProvidedCapability[] {capability}); >- return MetadataFactory.createInstallableUnit(sourceDescription); >- } >- >- /** >- * Lookup and return the source IU in the given queryable or <code>null</code> if not found. >- * @param queryable location to look for source IUs >- * @return the source IU or <code>null</code> >- */ >- private IInstallableUnit getCurrentSourceIU(IQueryable queryable) { >- IQuery query = QueryUtil.createIUQuery(SOURCE_IU_ID); >- IQueryResult list = queryable.query(query, null); >- IInstallableUnit currentSourceIU = null; >- if (!list.isEmpty()) >- currentSourceIU = (IInstallableUnit) list.iterator().next(); >- return currentSourceIU; >+ fUnits = (IInstallableUnit[]) result.toArray(new IInstallableUnit[result.size()]); >+ return fUnits; > } > > /** >- * Used to resolve the contents of this container when the user has chosen to manage the dependencies in the target >- * themselves. The selected IUs and any required software that can be found will be retrieved from the repositories >- * and added to the target. Any missing required software will be ignored. >- * >- * @param definition definition being resolved >- * @param monitor for reporting progress >- * @return set of resolved bundles included in this container >- * @throws CoreException if there is a problem interacting with the repositories >- */ >- private IResolvedBundle[] resolveWithSlicer(ITargetDefinition definition, IProgressMonitor monitor) throws CoreException { >- SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 10); >- subMonitor.beginTask(Messages.IUBundleContainer_0, 180); >- >- // retrieve profile >- IProfile profile = P2TargetUtils.getProfile(definition); >- subMonitor.worked(10); >- >- if (subMonitor.isCanceled()) { >- return new IResolvedBundle[0]; >- } >- >- // resolve IUs >- IInstallableUnit[] units = getInstallableUnits(profile); >- >- if (subMonitor.isCanceled()) { >- return new IResolvedBundle[0]; >- } >- >- URI[] repositories = resolveRepositories(); >- int repoCount = repositories.length; >- if (repoCount == 0) { >- return new IResolvedBundle[0]; >- } >- >- IProgressMonitor loadMonitor = new SubProgressMonitor(subMonitor, 10); >- loadMonitor.beginTask(null, repoCount * 10); >- List metadataRepos = new ArrayList(repoCount); >- MultiStatus repoStatus = new MultiStatus(PDECore.PLUGIN_ID, 0, Messages.IUBundleContainer_ProblemsLoadingRepositories, null); >- IMetadataRepositoryManager manager = P2TargetUtils.getRepoManager(); >- for (int i = 0; i < repoCount; ++i) { >- try { >- IMetadataRepository repo = manager.loadRepository(repositories[i], new SubProgressMonitor(loadMonitor, 10)); >- metadataRepos.add(repo); >- } catch (ProvisionException e) { >- repoStatus.add(e.getStatus()); >- } >- } >- loadMonitor.done(); >- >- IQueryable allMetadata; >- if (metadataRepos.size() == 0) { >- throw new CoreException(repoStatus); >- } else if (metadataRepos.size() == 1) { >- allMetadata = (IQueryable) metadataRepos.get(0); >- } else { >- allMetadata = QueryUtil.compoundQueryable(metadataRepos); >- } >- >- // do an initial slice to add everything the user requested >- IQueryResult queryResult = slice(units, allMetadata, definition, subMonitor); >- if (subMonitor.isCanceled() || queryResult == null || queryResult.isEmpty()) { >- return new IResolvedBundle[0]; >- } >- >- // If we are including source then create a source IU to bring in the relevant source >- // bundles and run the slicer again. >- if (fIncludeSource) { >- // Build an IU that represents all the source bundles and slice again to add them in if available >- IInstallableUnit sourceIU = createSourceIU(queryResult, Version.createOSGi(1, 0, 0)); >- IInstallableUnit[] units2 = new IInstallableUnit[units.length + 1]; >- System.arraycopy(units, 0, units2, 0, units.length); >- units2[units.length] = sourceIU; >- >- queryResult = slice(units2, allMetadata, definition, subMonitor); >- if (subMonitor.isCanceled() || queryResult == null || queryResult.isEmpty()) { >- return new IResolvedBundle[0]; >- } >- } >- >- IEngine engine = P2TargetUtils.getEngine(); >- ProvisioningContext context = new ProvisioningContext(P2TargetUtils.getAgent()); >- context.setMetadataRepositories(repositories); >- context.setArtifactRepositories(resolveArtifactRepositories()); >- IProvisioningPlan plan = engine.createPlan(profile, context); >- >- Set newSet = queryResult.toSet(); >- Iterator itor = newSet.iterator(); >- while (itor.hasNext()) { >- plan.addInstallableUnit((IInstallableUnit) itor.next()); >- } >- for (int i = 0; i < units.length; i++) { >- IInstallableUnit unit = units[i]; >- plan.setInstallableUnitProfileProperty(unit, P2TargetUtils.PROP_INSTALLED_IU, Boolean.toString(true)); >- } >- >- // remove all units that are in the current profile but not in the new slice >- Set toRemove = profile.query(QueryUtil.ALL_UNITS, null).toSet(); >- toRemove.removeAll(newSet); >- for (Iterator i = toRemove.iterator(); i.hasNext();) { >- plan.removeInstallableUnit((IInstallableUnit) i.next()); >- } >- >- plan.setProfileProperty(P2TargetUtils.PROP_PROVISION_MODE, TargetDefinitionPersistenceHelper.MODE_SLICER); >- plan.setProfileProperty(P2TargetUtils.PROP_ALL_ENVIRONMENTS, Boolean.toString(getIncludeAllEnvironments())); >- >- // execute the provisioning plan >- IPhaseSet phases = PhaseSetFactory.createDefaultPhaseSetExcluding(new String[] {PhaseSetFactory.PHASE_CHECK_TRUST, PhaseSetFactory.PHASE_CONFIGURE, PhaseSetFactory.PHASE_UNCONFIGURE}); >- IStatus result = engine.perform(plan, phases, new SubProgressMonitor(subMonitor, 140)); >- >- if (subMonitor.isCanceled()) { >- return new IResolvedBundle[0]; >- } >- if (!result.isOK()) { >- throw new CoreException(result); >- } >- >- ResolvedBundle[] resolvedBundles = updateAfterResolve(profile, definition); >- >- subMonitor.worked(10); >- subMonitor.done(); >- return resolvedBundles; >- } >- >- private ResolvedBundle[] updateAfterResolve(IProfile profile, ITargetDefinition definition) throws CoreException { >- // Cache the feature list >- queryForFeatures(profile); >+ * Update this container's cache of bundle objects based on the given profile. >+ * NOTE: this method expects the synchronizer to be synchronized and is called >+ * as a result of a synchronization operation. >+ */ >+ IResolvedBundle[] cacheBundles() throws CoreException { >+ // slice the profile to find the bundles attributed to this container. >+ // Look only for strict dependencies if we are using the slicer. >+ // We can always consider all platforms since the profile wouldn't contain it if it was not interesting >+ boolean onlyStrict = !fSynchronizer.getIncludeAllRequired(); >+ IProfile metadata = fSynchronizer.getProfile(); >+ PermissiveSlicer slicer = new PermissiveSlicer(metadata, new HashMap(), true, false, true, onlyStrict, false); >+ IQueryable slice = slicer.slice(fUnits, new NullProgressMonitor()); > > // query for bundles >- IFileArtifactRepository repository = null; >+ IFileArtifactRepository artifacts = null; > try { >- repository = P2TargetUtils.getBundlePool(profile); >+ artifacts = P2TargetUtils.getBundlePool(); > } catch (CoreException e) { > if (DEBUG_PROFILE) { > System.out.println("Bundle pool repository could not be loaded"); //$NON-NLS-1$ > } >- return null; >+ return fBundles = null; > } > >- Map bundles = generateResolvedBundles(profile, repository, true); >- if (bundles == null || bundles.isEmpty()) { >+ Map bundles = generateResolvedBundles(slice, metadata, artifacts); >+ if (bundles.isEmpty()) { > if (DEBUG_PROFILE) { > System.out.println("Profile does not contain any bundles or artifacts were missing"); //$NON-NLS-1$ > } >- return null; >- } >- >- removeDuplicateBundles(definition, bundles); >- if (bundles.isEmpty()) { >- return null; >+ return fBundles = null; > } > >- return (ResolvedBundle[]) bundles.values().toArray(new ResolvedBundle[bundles.size()]); >- } >- >- private IQueryResult slice(IInstallableUnit[] units, IQueryable allMetadata, ITargetDefinition definition, SubProgressMonitor subMonitor) throws CoreException { >- // slice IUs and all prerequisites >- PermissiveSlicer slicer = null; >- if (getIncludeAllEnvironments()) { >- slicer = new PermissiveSlicer(allMetadata, new HashMap(), true, false, true, true, false); >- } else { >- Map props = new HashMap(); >- props.put("osgi.os", definition.getOS() != null ? definition.getOS() : Platform.getOS()); //$NON-NLS-1$ >- props.put("osgi.ws", definition.getWS() != null ? definition.getWS() : Platform.getWS()); //$NON-NLS-1$ >- props.put("osgi.arch", definition.getArch() != null ? definition.getArch() : Platform.getOSArch()); //$NON-NLS-1$ >- props.put("osgi.nl", definition.getNL() != null ? definition.getNL() : Platform.getNL()); //$NON-NLS-1$ >- props.put(IProfile.PROP_INSTALL_FEATURES, Boolean.TRUE.toString()); >- slicer = new PermissiveSlicer(allMetadata, props, true, false, false, true, false); >- } >- IQueryable slice = slicer.slice(units, new SubProgressMonitor(subMonitor, 10)); >- if (!slicer.getStatus().isOK()) { >- throw new CoreException(slicer.getStatus()); >- } >- IQueryResult queryResult = null; >- if (slice != null) >- queryResult = slice.query(QueryUtil.createIUAnyQuery(), new SubProgressMonitor(subMonitor, 10)); >- return queryResult; >- } >- >- /** >- * Queries the given given queryable and finds all feature group IUs. The feature id/versions of the features >- * are cached in {@link #fFeatures}. >- * >- * @param queryable profile/slicer/etc. to query for features >- */ >- private void queryForFeatures(IQueryable queryable) { >- // Query for features, cache the result for calls to resolveFeatures() >- // Get any IU with the group property, this will return any feature groups >- IQuery featureQuery = QueryUtil.createMatchQuery("properties[$0] == $1", new Object[] {MetadataFactory.InstallableUnitDescription.PROP_TYPE_GROUP, Boolean.TRUE.toString()}); //$NON-NLS-1$ >- IQueryResult featureResult = queryable.query(featureQuery, null); >- List features = new ArrayList(); >- for (Iterator iterator = featureResult.iterator(); iterator.hasNext();) { >- IInstallableUnit unit = (IInstallableUnit) iterator.next(); >- String id = unit.getId(); >- if (id.endsWith(FEATURE_ID_SUFFIX)) { >- id = id.substring(0, id.length() - FEATURE_ID_SUFFIX.length()); >- } >- String version = unit.getVersion().toString(); >- features.add(new NameVersionDescriptor(id, version, NameVersionDescriptor.TYPE_FEATURE)); >- } >- fFeatures = (NameVersionDescriptor[]) features.toArray(new NameVersionDescriptor[features.size()]); >+ fBundles = (ResolvedBundle[]) bundles.values().toArray(new ResolvedBundle[bundles.size()]); >+ return fBundles; > } > >- /** >- * Returns the IU's this container references. Checks in the profile first to avoid >- * going out to repositories. >- * >- * @param profile profile to check first >- * @return IU's >- * @exception CoreException if unable to retrieve IU's >+ /* >+ * Respond to the notification that the synchronizer associated with this container has changed >+ * This is a callback method used by the synchronizer. >+ * It should NOT be called any other time. > */ >- public synchronized IInstallableUnit[] getInstallableUnits(IProfile profile) throws CoreException { >- if (fUnits == null) { >- fUnits = new IInstallableUnit[fIds.length]; >- for (int i = 0; i < fIds.length; i++) { >- IQuery query = QueryUtil.createIUQuery(fIds[i], fVersions[i]); >- IQueryResult queryResult = profile.query(query, null); >- if (queryResult.isEmpty()) { >- // try repositories >- URI[] repositories = resolveRepositories(); >- for (int j = 0; j < repositories.length; j++) { >- try { >- IMetadataRepository repository = P2TargetUtils.getRepository(repositories[j]); >- queryResult = repository.query(query, null); >- if (!queryResult.isEmpty()) { >- break; >- } >- } catch (ProvisionException e) { >- // Ignore and move on to the next site >- } >- } >- } >- if (queryResult.isEmpty()) { >- // not found >- fUnits = null; >- throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.IUBundleContainer_1, fIds[i]))); >- } >- fUnits[i] = (IInstallableUnit) queryResult.iterator().next(); >- } >- } >- return fUnits; >- } >- >- private IMetadataRepository[] getRepos() throws CoreException { >- URI[] repos = resolveRepositories(); >- IMetadataRepository[] result = new IMetadataRepository[repos.length]; >- for (int i = 0; i < repos.length; i++) >- result[i] = P2TargetUtils.getRepository(repos[i]); >- return result; >+ void synchronizerChanged() throws CoreException { >+ // cache the IUs first as they are used to slice the profile for the other caches. >+ cacheIUs(); >+ cacheBundles(); >+ cacheFeatures(); > } > > /** >@@ -794,11 +297,11 @@ > * > * @param toUpdate the set of IU ids in this container to consider updating. If null > * then update everything >- * @return a bitmasked int indicating how/if this container changed. See {@link UpdateTargetJob#DIRTY} and {@link UpdateTargetJob#UPDATED}. >+ * @return a bitmasked int indicating how/if this container changed. See DIRTY and UPDATED. > * @exception CoreException if unable to retrieve IU's > */ > public synchronized int update(Set toUpdate) throws CoreException { >- IQueryable source = new CompoundQueryable(getRepos()); >+ IQueryable source = fSynchronizer.getQueryableMetadata(fRepos, null); > int dirty = 0; > int updated = 0; > for (int i = 0; i < fIds.length; i++) { >@@ -811,7 +314,6 @@ > if (!it.hasNext()) > throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.IUBundleContainer_1, fIds[i]))); > IInstallableUnit iu = (IInstallableUnit) it.next(); >- fUnits[i] = iu; > // if the version is different from the spec (up or down), record the change. > if (!iu.getVersion().equals(fVersions[i])) { > updated = UpdateTargetJob.UPDATED; >@@ -826,87 +328,64 @@ > } > > /** >- * Checks all other bundle containers in the given target and removes any bundles provided by them from >- * the map. This prevents targets containing more than one IUBundleContainer from having duplicate bundles. >- * >- * @param definition target definition to look for other containers in >- * @param bundles collection of bundles arranged by mapping BundleInfo to IResolvedBundle >- */ >- private void removeDuplicateBundles(ITargetDefinition definition, Map bundles) { >- // remove all bundles from previous IU containers (so we don't get duplicates from multi-locations >- IBundleContainer[] containers = definition.getBundleContainers(); >- for (int i = 0; i < containers.length; i++) { >- IBundleContainer container = containers[i]; >- if (container == this) { >- break; >- } >- if (container instanceof IUBundleContainer) { >- IUBundleContainer bc = (IUBundleContainer) container; >- IResolvedBundle[] included = bc.getBundles(); >- if (included != null) { >- for (int j = 0; j < included.length; j++) { >- bundles.remove(included[j].getBundleInfo()); >- } >- } >- } >- } >- } >- >- /** > * Collects all available installable units from the given source that represent OSGI > * bundles. A IResolvedBundle is created for each and a map containing all results > * mapping BundleInfo to IResolvedBundle is returned. > * <p> >- * If there is an artifact missing for a unit it will either be ignored (not added to the returned map), >- * or <code>null</code> will be returned depending on the ignoreMissingFiles parameter. >+ * If there is an artifact missing for a unit it will be ignored (not added to the returned map). >+ * If this container is setup to automatically include source, an corresponding source bundles >+ * found in the given profile will also be added as resolved bundles. > * </p> >- * @param source A queryable profile or slice that the bundle units will be obtained from >- * @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 >- * @return map of BundleInfo to IResolvedBundle or <code>null</code> if a missing file is found and not ignored >+ * @param source the bundle units to be converted >+ * @param metadata the metadata backing the conversion >+ * @param artifacts the underlying artifact repo against which the bundles are validated >+ * @return map of BundleInfo to IResolvedBundle > * @throws CoreException > */ >- private Map generateResolvedBundles(IQueryable source, IFileArtifactRepository repo, boolean ignoreMissingFiles) throws CoreException { >+ private Map generateResolvedBundles(IQueryable source, IQueryable metadata, IFileArtifactRepository artifacts) throws CoreException { > OSGiBundleQuery query = new OSGiBundleQuery(); > IQueryResult queryResult = source.query(query, null); > Map bundles = new LinkedHashMap(); >- for (Iterator iterator = queryResult.iterator(); iterator.hasNext();) { >- IInstallableUnit unit = (IInstallableUnit) iterator.next(); >- Collection artifacts = unit.getArtifacts(); >- for (Iterator iterator2 = artifacts.iterator(); iterator2.hasNext();) { >- File file = repo.getArtifactFile((IArtifactKey) iterator2.next()); >- if (file == null) { >- // Missing file >- if (!ignoreMissingFiles) { >- if (DEBUG_PROFILE) { >- System.out.println("Backing file missing for: " + unit.getId()); //$NON-NLS-1$ >- } >- return null; >- } >- } else { >- IResolvedBundle bundle = generateBundle(file); >- if (bundle != null) { >- bundles.put(bundle.getBundleInfo(), bundle); >- } >+ for (Iterator i = queryResult.iterator(); i.hasNext();) { >+ IInstallableUnit unit = (IInstallableUnit) i.next(); >+ generateBundle(unit, artifacts, bundles); >+ if (getIncludeSource()) { >+ // bit of a hack using the bundle naming convention for finding source bundles >+ // but this matches what we do when adding source to the profile so... >+ IQuery sourceQuery = QueryUtil.createIUQuery(unit.getId() + ".source", unit.getVersion()); //$NON-NLS-1$ >+ IQueryResult result = metadata.query(sourceQuery, null); >+ if (!result.isEmpty()) { >+ generateBundle((IInstallableUnit) result.iterator().next(), artifacts, bundles); > } > } > } > return bundles; > } > >+ private void generateBundle(IInstallableUnit unit, IFileArtifactRepository repo, Map bundles) throws CoreException { >+ Collection artifacts = unit.getArtifacts(); >+ for (Iterator iterator2 = artifacts.iterator(); iterator2.hasNext();) { >+ File file = repo.getArtifactFile((IArtifactKey) iterator2.next()); >+ if (file != null) { >+ IResolvedBundle bundle = generateBundle(file); >+ if (bundle != null) { >+ bundles.put(bundle.getBundleInfo(), bundle); >+ } >+ } >+ } >+ } >+ > /* (non-Javadoc) > * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#isContentEqual(org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer) > */ > public boolean isContentEqual(AbstractBundleContainer container) { > if (container instanceof IUBundleContainer) { > IUBundleContainer iuContainer = (IUBundleContainer) container; >- if (iuContainer.getIncludeAllRequired() == getIncludeAllRequired()) { >- // include all targets only matters if include all required is turned off >- if (getIncludeAllRequired() || iuContainer.getIncludeAllEnvironments() == getIncludeAllEnvironments()) { >- return isEqualOrNull(fIds, iuContainer.fIds) && isEqualOrNull(fVersions, iuContainer.fVersions) && isEqualOrNull(fRepos, iuContainer.fRepos); >- } >- } >- if (fIncludeSource != iuContainer.getIncludeSource()) >- return false; >+ boolean result = true; >+ result &= iuContainer.getIncludeAllRequired() == getIncludeAllRequired(); >+ result &= iuContainer.getIncludeAllEnvironments() == getIncludeAllEnvironments(); >+ result &= iuContainer.getIncludeSource() == getIncludeSource(); >+ return result && isEqualOrNull(fIds, iuContainer.fIds) && isEqualOrNull(fVersions, iuContainer.fVersions) && isEqualOrNull(fRepos, iuContainer.fRepos); > } > return false; > } >@@ -947,141 +426,24 @@ > } > > /** >- * Returns the repositories to consider when resolving IU's (will return default set of >- * repositories if current repository settings are <code>null</code>). >- * >- * @return URI's of repositories to use when resolving bundles >- * @exception CoreException >- */ >- private URI[] resolveRepositories() throws CoreException { >- if (fRepos == null) { >- IMetadataRepositoryManager manager = P2TargetUtils.getRepoManager(); >- return manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL); >- } >- return fRepos; >- } >- >- /** >- * Returns the artifact repositories to consider when getting artifacts. Returns a default set of >- * repositories if current repository settings are <code>null</code>). >+ * Removes an installable unit from this container. The container will no longer be resolved. > * >- * @return URI's of repositories to use when getting artifacts >- * @exception CoreException >- */ >- private URI[] resolveArtifactRepositories() throws CoreException { >- URI[] repositories = fRepos; >- if (fRepos == null) { >- IArtifactRepositoryManager manager = P2TargetUtils.getArtifactRepositoryManager(); >- repositories = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL); >- } >- if (!useAdditionalLocalArtifacts()) >- return repositories; >- Set additionalRepos = new HashSet(Arrays.asList(repositories)); >- findProfileRepos(additionalRepos); >- findWorkspaceRepos(additionalRepos); >- return (URI[]) additionalRepos.toArray(new URI[additionalRepos.size()]); >- } >- >- /** >- * @return whether to use local artifact repositories when provisioning the target >- */ >- private boolean useAdditionalLocalArtifacts() { >- // TODO consider using a preference here or another strategy if users are able to spec >- // what local repos are to be considered. >- return true; >- } >- >- /** >- * Add the artifact repos from the PDE target bundle pools from all known repos. For example, the list >- * of "recent workspaces" maintained by the IDE is a good source. >- * >- * @param additionalRepos the set to which additional repos are added. >- */ >- private void findWorkspaceRepos(Set additionalRepos) { >- IPreferencesService prefs = P2TargetUtils.getPreferences(); >- if (prefs == null) >- return; >- String recent = prefs.getString("org.eclipse.ui.ide", "RECENT_WORKSPACES", null, null); //$NON-NLS-1$ //$NON-NLS-2$ >- if (recent == null) >- return; >- String[] recents = recent.split("\n"); //$NON-NLS-1$ >- for (int i = 0; i < recents.length; i++) { >- String bundlePool = recents[i] + "/.metadata/.plugins/org.eclipse.pde.core/.bundle_pool"; //$NON-NLS-1$ >- if (new File(bundlePool).exists()) { >- URI uri; >- try { >- uri = new URI("file", bundlePool, null); //$NON-NLS-1$ >- additionalRepos.add(uri); >- } catch (URISyntaxException e) { >- // should never happen >- } >- } >- } >- } >- >- /** >- * Look through the current p2 profile (_SELF_) and add the artifact repos that make up its >- * bundle pool, dropins location, ... This helps in the cases that you are targeting stuff that >- * makes up your current IDE. >- * >- * @param additionalRepos the set to which additional repos are added. >+ * @param unit unit to remove from the list of root IUs > */ >- private void findProfileRepos(Set additionalRepos) { >- try { >- // NOTE: be sure to use the global p2 agent here as we are looking for SELF. >- IProfileRegistry profileRegistry = (IProfileRegistry) P2TargetUtils.getGlobalAgent().getService(IProfileRegistry.SERVICE_NAME); >- if (profileRegistry == null) >- return; >- IProfile self = profileRegistry.getProfile(IProfileRegistry.SELF); >- if (self == null) >- return; >- >- IAgentLocation location = (IAgentLocation) P2TargetUtils.getGlobalAgent().getService(IAgentLocation.SERVICE_NAME); >- URI dataArea = location.getDataArea("org.eclipse.equinox.p2.engine"); //$NON-NLS-1$ >- dataArea = URIUtil.append(dataArea, "profileRegistry/" + self.getProfileId() + ".profile"); //$NON-NLS-1$//$NON-NLS-2$ >- ProfileMetadataRepository profileRepo = new ProfileMetadataRepository(P2TargetUtils.getGlobalAgent(), dataArea, null); >- Collection repos = profileRepo.getReferences(); >- for (Iterator i = repos.iterator(); i.hasNext();) { >- Object element = i.next(); >- if (element instanceof IRepositoryReference) { >- IRepositoryReference reference = (IRepositoryReference) element; >- if (reference.getType() == IRepository.TYPE_ARTIFACT && reference.getLocation() != null) >- additionalRepos.add(reference.getLocation()); >- } >+ public synchronized void removeInstallableUnit(IInstallableUnit unit) { >+ List newIds = new ArrayList(fIds.length); >+ List newVersions = new ArrayList(fIds.length); >+ for (int i = 0; i < fIds.length; i++) { >+ if (fIds[i].equals(unit.getId()) && fVersions[i].equals(unit.getVersion())) { >+ newIds.add(fIds[i]); >+ newVersions.add(fVersions[i]); > } >- } catch (CoreException e) { >- // if there is a problem, move on. Could log something here >- return; > } >- } >+ fIds = (String[]) newIds.toArray(new String[newIds.size()]); >+ fVersions = (Version[]) newVersions.toArray(new Version[newVersions.size()]); > >- /** >- * Sets whether all required units must be available to resolve this container. When <code>true</code> >- * the resolve operation will use the planner to determine the complete set of IUs required to >- * make the selected IUs runnable. If any dependencies are missing, the resolve operation will return an >- * error explaining what problems exist. When <code>false</code> the resolve operation will use the slicer >- * to determine what units to include. Any required units that are not available in the repositories will >- * be ignored. >- * <p> >- * Since there is only one profile per target and the planner and slicer resolve methods are incompatible >- * it is highly recommended that the parent target be passed to this method so all other IUBundleContainers >- * in the target can be updated with the new setting. >- * </p> >- * @param include whether all required units must be available to resolve this container >- * @param definition parent target, used to update other IUBundleContainers with this setting, can be <code>null</code> >- */ >- public void setIncludeAllRequired(boolean include, ITargetDefinition definition) { >- fIncludeAllRequired = include; >- if (definition != null) { >- IBundleContainer[] containers = definition.getBundleContainers(); >- if (containers != null) { >- for (int i = 0; i < containers.length; i++) { >- if (containers[i] instanceof IUBundleContainer && containers[i] != this) { >- ((IUBundleContainer) containers[i]).setIncludeAllRequired(include, null); >- } >- } >- } >- } >+ // Need to mark the container as unresolved >+ clearResolutionStatus(); > } > > /** >@@ -1095,35 +457,10 @@ > * @return whether all required units must be available to resolve this container > */ > public boolean getIncludeAllRequired() { >- return fIncludeAllRequired; >- } >- >- /** >- * Sets whether all environment (platform) specific installable units should >- * be included in this container when it is resolved. This feature is not supported >- * by the planner so will only have an effect if the include all required setting >- * is turned off ({@link #getIncludeAllRequired()}). >- * <p> >- * There is only one profile per target and this setting can only be set for the >- * entire target definition. It is highly recommended that the parent target be passed >- * to this method so all other IUBundleContainers in the target can be updated with the >- * new setting. >- * </p> >- * @param include whether environment specific units should be included >- * @param definition parent target, used to update other IUBundleContainers with this setting, can be <code>null</code> >- */ >- public void setIncludeAllEnvironments(boolean include, ITargetDefinition definition) { >- fIncludeMultipleEnvironments = include; >- if (definition != null) { >- IBundleContainer[] containers = definition.getBundleContainers(); >- if (containers != null) { >- for (int i = 0; i < containers.length; i++) { >- if (containers[i] instanceof IUBundleContainer && containers[i] != this) { >- ((IUBundleContainer) containers[i]).setIncludeAllEnvironments(include, null); >- } >- } >- } >- } >+ // if this container has not been associated with a container, return its own value >+ if (fSynchronizer == null) >+ return (fFlags & INCLUDE_REQUIRED) == INCLUDE_REQUIRED; >+ return fSynchronizer.getIncludeAllRequired(); > } > > /** >@@ -1135,17 +472,10 @@ > * @return whether environment specific units should be included > */ > public boolean getIncludeAllEnvironments() { >- return fIncludeMultipleEnvironments; >- } >- >- /** >- * Set whether or not the source bundles corresponding to any binary bundles should >- * be automatically included in the target. >- * >- * @param value whether or not to include source >- */ >- public void setIncludeSource(boolean value) { >- fIncludeSource = value; >+ // if this container has not been associated with a container, return its own value >+ if (fSynchronizer == null) >+ return (fFlags & INCLUDE_ALL_ENVIRONMENTS) == INCLUDE_ALL_ENVIRONMENTS; >+ return fSynchronizer.getIncludeAllEnvironments(); > } > > /** >@@ -1155,30 +485,22 @@ > * @return whether or not source is included automatically > */ > public boolean getIncludeSource() { >- return fIncludeSource; >+ // if this container has not been associated with a container, return its own value >+ if (fSynchronizer == null) >+ return (fFlags & INCLUDE_SOURCE) == INCLUDE_SOURCE; >+ return fSynchronizer.getIncludeSource(); > } > > /** >- * Removes an installable unit from this container. The container will no longer be resolved. >- * >- * @param unit unit to remove from the list of root IUs >+ * Returns the installable units defined by this container >+ * >+ * @return the discovered IUs >+ * @exception CoreException if unable to retrieve IU's > */ >- public void removeInstallableUnit(IInstallableUnit unit) { >- List newUnits = new ArrayList(fUnits.length); >- for (int i = 0; i < fUnits.length; i++) { >- if (!fUnits[i].equals(unit)) { >- newUnits.add(fUnits[i]); >- } >- } >- fUnits = (IInstallableUnit[]) newUnits.toArray(new IInstallableUnit[newUnits.size()]); >- fIds = new String[fUnits.length]; >- fVersions = new Version[fUnits.length]; >- for (int i = 0; i < fUnits.length; i++) { >- fIds[i] = fUnits[i].getId(); >- fVersions[i] = fUnits[i].getVersion(); >- } >- // Need to mark the container as unresolved >- clearResolutionStatus(); >+ public IInstallableUnit[] getInstallableUnits() throws CoreException { >+ if (fUnits == null) >+ return new IInstallableUnit[0]; >+ return fUnits; > } > > /** >@@ -1199,4 +521,36 @@ > return fVersions; > } > >+ /** >+ * Return the synchronizer for this container. If there isn't one and a target definition is >+ * supplied, then get/create the one used by the target and the other containers. >+ */ >+ P2TargetUtils getSynchronizer(ITargetDefinition definition) { >+ if (fSynchronizer != null) { >+ return fSynchronizer; >+ } >+ if (definition == null) >+ return null; >+ return fSynchronizer = P2TargetUtils.getSynchronizer(definition); >+ } >+ >+ /** >+ * Callback method used by the synchronizer to associate containers with >+ * synchronizers. >+ */ >+ void setSynchronizer(P2TargetUtils value) { >+ fSynchronizer = value; >+ } >+ >+ /** >+ * Associate this container with the given target. The include settings for this container >+ * override the settings for all other IU containers in the target. Last one wins. >+ */ >+ protected void associateWithTarget(ITargetDefinition target) { >+ super.associateWithTarget(target); >+ fSynchronizer = getSynchronizer(target); >+ fSynchronizer.setIncludeAllRequired((fFlags & INCLUDE_REQUIRED) == INCLUDE_REQUIRED); >+ fSynchronizer.setIncludeAllEnvironments((fFlags & INCLUDE_ALL_ENVIRONMENTS) == INCLUDE_ALL_ENVIRONMENTS); >+ fSynchronizer.setIncludeSource((fFlags & INCLUDE_SOURCE) == INCLUDE_SOURCE); >+ } > } >Index: src/org/eclipse/pde/internal/core/target/Messages.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/Messages.java,v >retrieving revision 1.10 >diff -u -r1.10 Messages.java >--- src/org/eclipse/pde/internal/core/target/Messages.java 5 Nov 2010 15:56:16 -0000 1.10 >+++ src/org/eclipse/pde/internal/core/target/Messages.java 30 Nov 2010 21:03:55 -0000 >@@ -34,6 +34,7 @@ > public static String IUBundleContainer_0; > public static String IUBundleContainer_1; > public static String IUBundleContainer_10; >+ public static String IUBundleContainer_11; > public static String IUBundleContainer_2; > public static String IUBundleContainer_3; > public static String IUBundleContainer_4; >Index: src/org/eclipse/pde/internal/core/target/Messages.properties >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/Messages.properties,v >retrieving revision 1.10 >diff -u -r1.10 Messages.properties >--- src/org/eclipse/pde/internal/core/target/Messages.properties 5 Nov 2010 15:56:16 -0000 1.10 >+++ src/org/eclipse/pde/internal/core/target/Messages.properties 30 Nov 2010 21:03:55 -0000 >@@ -25,14 +25,15 @@ > FeatureBundleContainer_5=Plug-ins directory does not exist for feature {0} > IUBundleContainer_0=Provisioning target > IUBundleContainer_1=Unable to locate installable unit {0} >-IUBundleContainer_10=Provisioning Agent service not found >+IUBundleContainer_10=Provisioning Agent Location service not found >+IUBundleContainer_11=Global Provisioning Agent service not found > IUBundleContainer_2=Metadata repository service not found > IUBundleContainer_3=Artifact respository service not found > IUBundleContainer_4=Provisioning engine not found > IUBundleContainer_5=Provisioning planner not found > IUBundleContainer_6=Target provisioning skipped install plan > IUBundleContainer_7=Provisioning agent not found >-IUBundleContainer_8=Profile registry service not found >+IUBundleContainer_8=Profile Registry service not found > IUBundleContainer_9=Garbage Collector service not found > IUBundleContainer_LoadingFromProfileJob=Loading target information from profile > IUBundleContainer_NoBundlePool=No location for downloaded bundles could be found. >Index: src/org/eclipse/pde/internal/core/target/P2TargetUtils.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/P2TargetUtils.java,v >retrieving revision 1.1 >diff -u -r1.1 P2TargetUtils.java >--- src/org/eclipse/pde/internal/core/target/P2TargetUtils.java 5 Nov 2010 15:56:16 -0000 1.1 >+++ src/org/eclipse/pde/internal/core/target/P2TargetUtils.java 30 Nov 2010 21:03:55 -0000 >@@ -12,27 +12,36 @@ > > import java.io.File; > import java.net.URI; >+import java.net.URISyntaxException; > import java.util.*; > import org.eclipse.core.runtime.*; > import org.eclipse.core.runtime.preferences.IPreferencesService; >+import org.eclipse.equinox.internal.p2.director.PermissiveSlicer; >+import org.eclipse.equinox.internal.p2.engine.*; >+import org.eclipse.equinox.internal.p2.engine.phases.*; > import org.eclipse.equinox.internal.p2.garbagecollector.GarbageCollector; > import org.eclipse.equinox.p2.core.*; > import org.eclipse.equinox.p2.engine.*; > import org.eclipse.equinox.p2.engine.query.IUProfilePropertyQuery; >-import org.eclipse.equinox.p2.metadata.IInstallableUnit; >+import org.eclipse.equinox.p2.engine.spi.ProvisioningAction; >+import org.eclipse.equinox.p2.metadata.*; >+import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription; > import org.eclipse.equinox.p2.metadata.Version; > import org.eclipse.equinox.p2.planner.IPlanner; >-import org.eclipse.equinox.p2.query.IQueryResult; >-import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager; >-import org.eclipse.equinox.p2.repository.artifact.IFileArtifactRepository; >-import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository; >+import org.eclipse.equinox.p2.planner.IProfileChangeRequest; >+import org.eclipse.equinox.p2.query.*; >+import org.eclipse.equinox.p2.repository.*; >+import org.eclipse.equinox.p2.repository.artifact.*; > import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager; >+import org.eclipse.osgi.util.NLS; > import org.eclipse.pde.internal.core.PDECore; > import org.eclipse.pde.internal.core.target.provisional.*; > import org.osgi.framework.*; > > public class P2TargetUtils { > >+ private static final String SOURCE_IU_ID = "org.eclipse.pde.core.target.source.bundles"; //$NON-NLS-1$ >+ > /** > * URI to the local directory where the p2 agent keeps its information. > */ >@@ -81,6 +90,58 @@ > static final String PROP_ALL_ENVIRONMENTS = PDECore.PLUGIN_ID + ".all_environments"; //$NON-NLS-1$ > > /** >+ * Profile property that keeps track of the target sequence number >+ */ >+ static final String PROP_SEQUENCE_NUMBER = PDECore.PLUGIN_ID + ".sequence"; //$NON-NLS-1$ >+ >+ /** >+ * Profile property that tracks whether or not source to be auto-included >+ */ >+ static final String PROP_AUTO_INCLUDE_SOURCE = PDECore.PLUGIN_ID + ".autoIncludeSource"; //$NON-NLS-1$ >+ >+ /** >+ * The profile to be synchronized >+ */ >+ private IProfile fProfile; >+ >+ /** >+ * The target to be synchronized. >+ */ >+ private ITargetDefinition fTarget; >+ >+ /** >+ * Whether this container must have all required IUs of the selected IUs available and included >+ * in the target to resolve successfully. If this option is true, the planner will be used to resolve >+ * otherwise the slicer is used. The planner can describe any missing requirements as errors. >+ * <p> >+ * <code>true</code> by default >+ * </p> >+ */ >+ private boolean fIncludeAllRequired = true; >+ >+ /** >+ * Whether this container should download and include environment (platform) specific units for all >+ * available platforms (vs only the current target definition's environment settings). Only supported >+ * by the slicer so {@link fIncludeAllRequired} must be turned off for this setting to be used. >+ * <p> >+ * <code>false</code> by default >+ * </p> >+ */ >+ private boolean fIncludeMultipleEnvironments = false; >+ >+ /** >+ * Whether this container should download and include source bundles for the selected units if the associated >+ * source is available in the repository. >+ * <p> >+ * <code>false</code>by default >+ */ >+ private boolean fIncludeSource = false; >+ >+ public P2TargetUtils(ITargetDefinition target) { >+ fTarget = target; >+ } >+ >+ /** > * Deletes any profiles associated with target definitions that no longer exist > * and returns a list of profile identifiers that were deleted. > */ >@@ -93,8 +154,8 @@ > for (int i = 0; i < profiles.length; i++) { > IProfile profile = profiles[i]; > String id = profile.getProfileId(); >- if (id.startsWith(P2TargetUtils.PROFILE_ID_PREFIX)) { >- String memento = id.substring(P2TargetUtils.PROFILE_ID_PREFIX.length()); >+ if (id.startsWith(PROFILE_ID_PREFIX)) { >+ String memento = id.substring(PROFILE_ID_PREFIX.length()); > ITargetHandle handle = tps.getTarget(memento); > if (!handle.exists()) { > deleteProfile(handle); >@@ -154,7 +215,7 @@ > try { > IProfile[] profiles = getProfileRegistry().getProfiles(); > for (int i = 0; i < profiles.length; i++) { >- if (profiles[i].getProfileId().startsWith(P2TargetUtils.PROFILE_ID_PREFIX)) { >+ if (profiles[i].getProfileId().startsWith(PROFILE_ID_PREFIX)) { > getGarbageCollector().runGC(profiles[i]); > } > } >@@ -169,7 +230,7 @@ > * > * @return environment properties > */ >- private static String generateEnvironmentProperties(ITargetDefinition target) { >+ private String generateEnvironmentProperties(ITargetDefinition target) { > // TODO: are there constants for these keys? > StringBuffer env = new StringBuffer(); > String ws = target.getWS(); >@@ -200,7 +261,7 @@ > * > * @return NL profile property > */ >- private static String generateNLProperty(ITargetDefinition target) { >+ private String generateNLProperty(ITargetDefinition target) { > String nl = target.getNL(); > if (nl == null) { > nl = Platform.getNL(); >@@ -246,7 +307,7 @@ > public static IProvisioningAgent getGlobalAgent() throws CoreException { > IProvisioningAgent agent = (IProvisioningAgent) PDECore.getDefault().acquireService(IProvisioningAgent.SERVICE_NAME); > if (agent == null) >- throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_10)); >+ throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_11)); > return agent; > } > >@@ -278,22 +339,23 @@ > } > > /** >- * Returns the local bundle pool (repository) where bundles are stored for the >- * given profile. >+ * Returns the local bundle pool (repository) where bundles are stored > * >- * @param profile profile bundles are stored > * @return local file artifact repository > * @throws CoreException > */ >- public static IFileArtifactRepository getBundlePool(IProfile profile) throws CoreException { >- String path = profile.getProperty(IProfile.PROP_CACHE); >- if (path == null) { >- // We should always be setting the bundle pool, so if the bundle pool location is missing there isn't much we can do >- throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_NoBundlePool)); >- } >- URI uri = new File(path).toURI(); >+ public static IFileArtifactRepository getBundlePool() throws CoreException { >+ URI uri = BUNDLE_POOL.toFile().toURI(); > IArtifactRepositoryManager manager = getArtifactRepositoryManager(); >- return (IFileArtifactRepository) manager.loadRepository(uri, null); >+ try { >+ if (manager.contains(uri)) >+ return (IFileArtifactRepository) manager.loadRepository(uri, null); >+ } catch (CoreException e) { >+ // could not load or there wasn't one, fall through to create >+ } >+ String repoName = "PDE Target Bundle Pool"; //$NON-NLS-1$ >+ IArtifactRepository result = manager.createRepository(uri, repoName, IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, null); >+ return (IFileArtifactRepository) result; > } > > /** >@@ -331,7 +393,7 @@ > * @throws CoreException if none > */ > public static IPlanner getPlanner() throws CoreException { >- IPlanner planner = (IPlanner) P2TargetUtils.getAgent().getService(IPlanner.class.getName()); >+ IPlanner planner = (IPlanner) getAgent().getService(IPlanner.class.getName()); > if (planner == null) { > throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_5)); > } >@@ -348,107 +410,328 @@ > } > > /** >- * Returns the profile for the this target handle, creating one if required. >+ * Returns whether the contents of the profile matches the expected contents of the target definition > * >- * @return profile >+ * @return whether or not the profile and target definitions match > * @throws CoreException in unable to retrieve profile > */ >- public static IProfile getProfile(ITargetDefinition target) throws CoreException { >- IProfileRegistry registry = getProfileRegistry(); >- if (registry == null) { >- throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.AbstractTargetHandle_0)); >+ private boolean checkProfile() throws CoreException { >+ // make sure we have a profile to validate >+ if (fProfile == null) { >+ return false; >+ } >+ >+ // check that the target and profiles are in sync. If they are then life is good. >+ // If they are not equal, there is still a chance that everything is ok. >+ String profileNumber = fProfile.getProperty(PROP_SEQUENCE_NUMBER); >+ if (Integer.toString(fTarget.currentSequenceNumber()).equals(profileNumber)) { >+ return true; >+ } >+ >+ // check if all environments setting is the same >+ boolean all = false; >+ String value = fProfile.getProperty(PROP_ALL_ENVIRONMENTS); >+ if (value != null) { >+ all = Boolean.valueOf(value).booleanValue(); >+ if (!Boolean.toString(getIncludeAllEnvironments()).equals(value)) { >+ return false; >+ } > } >- AbstractTargetHandle handle = ((AbstractTargetHandle) target.getHandle()); >- String id = P2TargetUtils.getProfileId(handle); >- IProfile profile = registry.getProfile(id); >- if (profile != null) { >- boolean recreate = false; >- // check if all environments setting is the same >- boolean all = false; >- String value = profile.getProperty(P2TargetUtils.PROP_ALL_ENVIRONMENTS); >- if (value != null) { >- all = Boolean.valueOf(value).booleanValue(); >- if (!Boolean.toString(isAllEnvironments(target)).equals(value)) { >- recreate = true; >- } >- } >- // ensure environment & NL settings are still the same (else we need a new profile) >- String property = null; >- if (!recreate && !all) { >- property = generateEnvironmentProperties(target); >- value = profile.getProperty(IProfile.PROP_ENVIRONMENTS); >- if (!property.equals(value)) { >- recreate = true; >- } >- } >- // check provisioning mode: slice versus plan >- String mode = getProvisionMode(target); >- if (mode != null) { >- value = profile.getProperty(P2TargetUtils.PROP_PROVISION_MODE); >- if (!mode.equals(value)) { >- recreate = true; >+ >+ // ensure environment & NL settings are still the same (else we need a new profile) >+ String property = null; >+ if (!all) { >+ property = generateEnvironmentProperties(fTarget); >+ value = fProfile.getProperty(IProfile.PROP_ENVIRONMENTS); >+ if (!property.equals(value)) { >+ return false; >+ } >+ } >+ property = generateNLProperty(fTarget); >+ value = fProfile.getProperty(IProfile.PROP_NL); >+ if (!property.equals(value)) { >+ return false; >+ } >+ >+ // check provisioning mode: slice versus plan >+ if (!getProvisionMode(fTarget).equals(fProfile.getProperty(PROP_PROVISION_MODE))) { >+ return false; >+ } >+ >+ // check that the include source flag matches what the profile represents >+ if (getIncludeSource() != Boolean.valueOf(fProfile.getProperty(PROP_AUTO_INCLUDE_SOURCE)).booleanValue()) { >+ return false; >+ } >+ >+ // check top level IU's. If any have been removed from the containers that are >+ // still in the profile, we need to recreate (rather than uninstall) >+ IUProfilePropertyQuery propertyQuery = new IUProfilePropertyQuery(PROP_INSTALLED_IU, Boolean.toString(true)); >+ IQueryResult queryResult = fProfile.query(propertyQuery, null); >+ Iterator iterator = queryResult.iterator(); >+ Set installedIUs = new HashSet(); >+ while (iterator.hasNext()) { >+ IInstallableUnit unit = (IInstallableUnit) iterator.next(); >+ installedIUs.add(new NameVersionDescriptor(unit.getId(), unit.getVersion().toString())); >+ } >+ IBundleContainer[] containers = fTarget.getBundleContainers(); >+ if (containers == null) { >+ return installedIUs.isEmpty(); >+ } >+ for (int i = 0; i < containers.length; i++) { >+ if (containers[i] instanceof IUBundleContainer) { >+ IUBundleContainer bc = (IUBundleContainer) containers[i]; >+ String[] ids = bc.getIds(); >+ Version[] versions = bc.getVersions(); >+ for (int j = 0; j < versions.length; j++) { >+ // if there is something in a container but not in the profile, recreate >+ if (!installedIUs.remove(new NameVersionDescriptor(ids[j], versions[j].toString()))) { >+ return false; >+ } > } > } >+ } >+ if (!installedIUs.isEmpty()) { >+ return false; >+ } > >- if (!recreate) { >- property = generateNLProperty(target); >- value = profile.getProperty(IProfile.PROP_NL); >- if (!property.equals(value)) { >- recreate = true; >- } >- } >- if (!recreate) { >- // check top level IU's. If any have been removed from the containers that are >- // still in the profile, we need to recreate (rather than uninstall) >- IUProfilePropertyQuery propertyQuery = new IUProfilePropertyQuery(P2TargetUtils.PROP_INSTALLED_IU, Boolean.toString(true)); >- IQueryResult queryResult = profile.query(propertyQuery, null); >- Iterator iterator = queryResult.iterator(); >- if (iterator.hasNext()) { >- Set installedIUs = new HashSet(); >- while (iterator.hasNext()) { >- IInstallableUnit unit = (IInstallableUnit) iterator.next(); >- installedIUs.add(new NameVersionDescriptor(unit.getId(), unit.getVersion().toString())); >- } >- IBundleContainer[] containers = target.getBundleContainers(); >- if (containers != null) { >- for (int i = 0; i < containers.length; i++) { >- if (containers[i] instanceof IUBundleContainer) { >- IUBundleContainer bc = (IUBundleContainer) containers[i]; >- String[] ids = bc.getIds(); >- Version[] versions = bc.getVersions(); >- for (int j = 0; j < versions.length; j++) { >- installedIUs.remove(new NameVersionDescriptor(ids[j], versions[j].toString())); >- } >- } >- } >- } >- if (!installedIUs.isEmpty()) { >- recreate = true; >- } >+ // Phew! seems like the profile checks out. >+ return true; >+ } >+ >+ /** >+ * Sets whether all required units must be available to resolve this container. When <code>true</code> >+ * the resolve operation will use the planner to determine the complete set of IUs required to >+ * make the selected IUs runnable. If any dependencies are missing, the resolve operation will return an >+ * error explaining what problems exist. When <code>false</code> the resolve operation will use the slicer >+ * to determine what units to include. Any required units that are not available in the repositories will >+ * be ignored. >+ * <p> >+ * Since there is only one profile per target and the planner and slicer resolve methods are incompatible. >+ * </p> >+ * @param value whether all required units must be available to resolve this container >+ */ >+ public void setIncludeAllRequired(boolean value) { >+ fIncludeAllRequired = value; >+ } >+ >+ /** >+ * Returns whether all required units must be available to resolve this container. When <code>true</code> >+ * the resolve operation will use the planner to determine the complete set of IUs required to >+ * make the selected IUs runnable. If any dependencies are missing, the resolve operation will return an >+ * error explaining what problems exist. When <code>false</code> the resolve operation will use the slicer >+ * to determine what units to include. Any required units that are not available in the repositories will >+ * be ignored. >+ * >+ * @return whether all required units must be available to resolve this container >+ */ >+ public boolean getIncludeAllRequired() { >+ return fIncludeAllRequired; >+ } >+ >+ /** >+ * Sets whether all environment (platform) specific installable units should >+ * be included in this container when it is resolved. This feature is not supported >+ * by the planner so will only have an effect if the include all required setting >+ * is turned off ({@link #getIncludeAllRequired()}). >+ * <p> >+ * There is only one profile per target and this setting can only be set for the >+ * entire target definition. >+ * </p> >+ * @param value whether environment specific units should be included >+ */ >+ public void setIncludeAllEnvironments(boolean value) { >+ fIncludeMultipleEnvironments = value; >+ } >+ >+ /** >+ * Returns whether all environment (platform) specific installable units should >+ * be included in this container when it is resolved. This feature is not supported >+ * by the planner so will only have an effect if the include all required setting >+ * is turned off ({@link #getIncludeAllRequired()}). >+ * >+ * @return whether environment specific units should be included >+ */ >+ public boolean getIncludeAllEnvironments() { >+ return fIncludeMultipleEnvironments; >+ } >+ >+ /** >+ * Set whether or not the source bundles corresponding to any binary bundles should >+ * be automatically included in the target. >+ * >+ * @param value whether or not to include source >+ */ >+ public void setIncludeSource(boolean value) { >+ fIncludeSource = value; >+ } >+ >+ /** >+ * Returns whether or not source bundles corresponding to selected binary bundles >+ * are automatically included in the target. >+ * >+ * @return whether or not source is included automatically >+ */ >+ public boolean getIncludeSource() { >+ return fIncludeSource; >+ } >+ >+ /** >+ * Return whether or not the given target has a matching profile that is in sync >+ * @param target the target to check >+ * @return whether or not the target has been resolved at the p2 level >+ */ >+ public static boolean isResolved(ITargetDefinition target) { >+ P2TargetUtils synchronizer = getSynchronizer(target); >+ if (synchronizer == null) >+ return false; >+ try { >+ return synchronizer.checkProfile(); >+ } catch (CoreException e) { >+ return false; >+ } >+ } >+ >+ /** >+ * Get the synchronizer to use for the given target. If there is already one on a >+ * container in the target, use that one. Otherwise, create a new one. Either way, >+ * ensure that all other IU containers in the target are using the same synchronizer. >+ * <p> >+ * The synchronizer is an instance of {@link P2TargetUtils} that has access to the >+ * profile and other p2 bits for the target. >+ * </p> >+ * >+ * @param target the target for which we are getting the synchronizer >+ * @return the discovered or created synchronizer >+ */ >+ static synchronized P2TargetUtils getSynchronizer(ITargetDefinition target) { >+ IBundleContainer[] containers = target.getBundleContainers(); >+ P2TargetUtils result = null; >+ // if there are no containers then just create/return the synchronizer >+ if (containers == null) { >+ return new P2TargetUtils(target); >+ } >+ >+ // Otherwise, look for a pre-existing synchronizer >+ for (int i = 0; i < containers.length; i++) { >+ if (containers[i] instanceof IUBundleContainer) { >+ result = ((IUBundleContainer) containers[i]).getSynchronizer(null); >+ if (result != null) { >+ break; > } > } >- if (recreate) { >- P2TargetUtils.deleteProfile(handle); >- profile = null; >- } >- } >- if (profile == null) { >- // create profile >- Map properties = new HashMap(); >- properties.put(IProfile.PROP_INSTALL_FOLDER, P2TargetUtils.INSTALL_FOLDERS.append(Long.toString(LocalTargetHandle.nextTimeStamp())).toOSString()); >- properties.put(IProfile.PROP_CACHE, P2TargetUtils.BUNDLE_POOL.toOSString()); >- properties.put(IProfile.PROP_INSTALL_FEATURES, Boolean.TRUE.toString()); >- // set up environment & NL properly so OS specific fragments are down loaded/installed >- properties.put(IProfile.PROP_ENVIRONMENTS, generateEnvironmentProperties(target)); >- properties.put(IProfile.PROP_NL, generateNLProperty(target)); >- String mode = getProvisionMode(target); >- if (mode != null) { >- properties.put(P2TargetUtils.PROP_PROVISION_MODE, mode); >- properties.put(P2TargetUtils.PROP_ALL_ENVIRONMENTS, Boolean.toString(isAllEnvironments(target))); >+ } >+ >+ // still no luck? create a new one >+ if (result == null) { >+ result = new P2TargetUtils(target); >+ } >+ >+ // finally set all the other IU containers to use the same synchronizer >+ for (int i = 0; i < containers.length; i++) { >+ if (containers[i] instanceof IUBundleContainer) { >+ ((IUBundleContainer) containers[i]).setSynchronizer(result); >+ } >+ } >+ return result; >+ } >+ >+ /** >+ * Return the set of IUs in all IU containers associated with this synchronizer. >+ * This is a helper method so we don't have to expose the profile itself. >+ * >+ * @param target the target definition to query >+ * @param monitor the progress monitor to use >+ * @return the set of associated IUs >+ * @throws CoreException if there is a problem discovering the IUs >+ */ >+ public static IQueryResult getIUs(ITargetDefinition target, IProgressMonitor monitor) throws CoreException { >+ P2TargetUtils synchronizer = getSynchronizer(target); >+ if (synchronizer == null) >+ return null; >+ synchronizer.synchronize(monitor); >+ return synchronizer.getProfile().query(QueryUtil.createIUAnyQuery(), null); >+ } >+ >+ /** >+ * Synchronize the profile and the target definition managed by this synchronizer. On return the profile will >+ * be resolved and correctly match the given target. The IUBundleContainers associated with >+ * the target will be notified of any changes in the underlying p2 profile and given an >+ * opportunity to update themselves accordingly. >+ * >+ * NOTE: this is a potentially *very* heavyweight operation. >+ * >+ * NOTE: this method is synchronized as it is effectively a "test and set" caching method. Two >+ * threads getting the profile at the same time should not execute concurrently or the profiles >+ * will get out of sync. >+ * >+ * @throws CoreException if there was a problem synchronizing >+ */ >+ public synchronized void synchronize(IProgressMonitor monitor) throws CoreException { >+ // Happiness if we have a profile and it checks out or if we can load one and it checks out. >+ if (fProfile == null) { >+ fProfile = getProfileRegistry().getProfile(getProfileId(fTarget)); >+ if (fProfile != null && checkProfile()) { >+ // if we just loaded the profile for the first time, refresh the container caches >+ notify(monitor); >+ return; >+ } >+ } else if (checkProfile()) { >+ return; >+ } >+ >+ long timestamp = -1; >+ // If we could not find a profile, create one. >+ if (fProfile == null) >+ createProfile(); >+ else >+ timestamp = fProfile.getTimestamp(); >+ >+ // Now resolve the profile and refresh the relate IU containers >+ if (getIncludeAllRequired()) >+ resolveWithPlanner(monitor); >+ else >+ resolveWithSlicer(monitor); >+ >+ // If we are updating a profile then delete the old snapshot on success. >+ if (timestamp != -1) >+ getProfileRegistry().removeProfile(getProfileId(fTarget), timestamp); >+ notify(monitor); >+ } >+ >+ private void createProfile() throws CoreException, ProvisionException { >+ // create a new profile >+ IProfileRegistry registry = getProfileRegistry(); >+ if (registry == null) { >+ throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.AbstractTargetHandle_0)); >+ } >+ Map properties = new HashMap(); >+ properties.put(IProfile.PROP_INSTALL_FOLDER, INSTALL_FOLDERS.append(Long.toString(LocalTargetHandle.nextTimeStamp())).toOSString()); >+ properties.put(IProfile.PROP_CACHE, BUNDLE_POOL.toOSString()); >+ properties.put(IProfile.PROP_INSTALL_FEATURES, Boolean.TRUE.toString()); >+ properties.put(IProfile.PROP_ENVIRONMENTS, generateEnvironmentProperties(fTarget)); >+ properties.put(IProfile.PROP_NL, generateNLProperty(fTarget)); >+ properties.put(PROP_SEQUENCE_NUMBER, Integer.toString(fTarget.currentSequenceNumber())); >+ properties.put(PROP_PROVISION_MODE, getProvisionMode(fTarget)); >+ properties.put(PROP_ALL_ENVIRONMENTS, Boolean.toString(getIncludeAllEnvironments())); >+ properties.put(PROP_AUTO_INCLUDE_SOURCE, Boolean.toString(getIncludeSource())); >+ fProfile = registry.addProfile(getProfileId(fTarget), properties); >+ } >+ >+ /** >+ * Signal the relevant bundle containers that the given profile has changed. >+ */ >+ private void notify(IProgressMonitor monitor) throws CoreException { >+ // flush the target caches first since some of them are used in rebuilding >+ // the container caches (e.g., featureModels) >+ ((TargetDefinition) fTarget).flushCaches(P2TargetUtils.BUNDLE_POOL.toOSString()); >+ // Now proactively recompute all the related container caches. >+ IBundleContainer[] containers = fTarget.getBundleContainers(); >+ for (int i = 0; i < containers.length; i++) { >+ IBundleContainer container = containers[i]; >+ if (container instanceof IUBundleContainer) { >+ ((IUBundleContainer) container).synchronizerChanged(); > } >- profile = registry.addProfile(id, properties); > } >- return profile; > } > > /** >@@ -466,6 +749,22 @@ > } > > /** >+ * Returns the profile identifier for this target handle. There is one profile >+ * per target definition. >+ * >+ * @return definition the target to lookup >+ * @throws CoreException in unable to generate identifier >+ */ >+ public static String getProfileId(ITargetDefinition definition) { >+ try { >+ return getProfileId(definition.getHandle()); >+ } catch (CoreException e) { >+ // gotta make sure that this never happens. all we're doing here is computing a string. >+ return null; >+ } >+ } >+ >+ /** > * Returns the profile registry or <code>null</code> > * > * @return profile registry or <code>null</code> >@@ -485,20 +784,8 @@ > * > * @return provisioning mode or <code>null</code> > */ >- private static String getProvisionMode(ITargetDefinition target) { >- IBundleContainer[] containers = target.getBundleContainers(); >- if (containers != null) { >- for (int i = 0; i < containers.length; i++) { >- if (containers[i] instanceof IUBundleContainer) { >- IUBundleContainer iu = (IUBundleContainer) containers[i]; >- if (iu.getIncludeAllRequired()) { >- return TargetDefinitionPersistenceHelper.MODE_PLANNER; >- } >- return TargetDefinitionPersistenceHelper.MODE_SLICER; >- } >- } >- } >- return null; >+ private String getProvisionMode(ITargetDefinition target) { >+ return getIncludeAllRequired() ? TargetDefinitionPersistenceHelper.MODE_PLANNER : TargetDefinitionPersistenceHelper.MODE_SLICER; > } > > /** >@@ -516,37 +803,591 @@ > } > > /** >- * Returns the metadata repository with the given URI. >+ * Return a queryable on the metadata defined in the given repo locations > * >- * @param uri location >- * @return repository >- * @throws CoreException >+ * @param repos the repos to lookup >+ * @param monitor the progress monitor >+ * @return the set of metadata repositories found >+ * @throws CoreException if there is a problem getting the repositories > */ >- public static IMetadataRepository getRepository(URI uri) throws CoreException { >+ static IQueryable getQueryableMetadata(URI[] repos, IProgressMonitor monitor) throws CoreException { > IMetadataRepositoryManager manager = getRepoManager(); >- IMetadataRepository repo = manager.loadRepository(uri, null); >- return repo; >+ if (repos == null) { >+ repos = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL); >+ } >+ >+ IProgressMonitor loadMonitor = new SubProgressMonitor(monitor, 10); >+ int repoCount = repos.length; >+ loadMonitor.beginTask(null, repoCount * 10); >+ List result = new ArrayList(repoCount); >+ MultiStatus repoStatus = new MultiStatus(PDECore.PLUGIN_ID, 0, Messages.IUBundleContainer_ProblemsLoadingRepositories, null); >+ for (int i = 0; i < repoCount; ++i) { >+ try { >+ result.add(manager.loadRepository(repos[i], new SubProgressMonitor(loadMonitor, 10))); >+ } catch (ProvisionException e) { >+ repoStatus.add(e.getStatus()); >+ } >+ } >+ loadMonitor.done(); >+ >+ if (result.size() != repos.length) { >+ throw new CoreException(repoStatus); >+ } >+ if (result.size() == 1) { >+ return (IQueryable) result.get(0); >+ } >+ return QueryUtil.compoundQueryable(result); > } > > /** >- * Returns whether software site containers are configured to provision for all environments >- * versus a single environment. >+ * Used to resolve the contents of this container if the user is including all required software. The p2 planner is used >+ * to determine the complete set of IUs required to run the selected software. If all requirements are met, the bundles >+ * are downloaded from the repository into the bundle pool and added to the target definition. > * >- * @return whether all environments will be provisioned >+ * @param monitor for reporting progress >+ * @throws CoreException if there is a problem with the requirements or there is a problem downloading > */ >- private static boolean isAllEnvironments(ITargetDefinition target) { >+ private void resolveWithPlanner(IProgressMonitor monitor) throws CoreException { >+ SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 10); >+ subMonitor.beginTask(Messages.IUBundleContainer_0, 200); >+ >+ // Get the root IUs for every relevant container in the target definition >+ IInstallableUnit[] units = getRootIUs(fTarget); >+ if (subMonitor.isCanceled()) { >+ return; >+ } >+ >+ // create the provisioning plan >+ IPlanner planner = getPlanner(); >+ IProfileChangeRequest request = planner.createChangeRequest(fProfile); >+ // first remove everything that was explicitly installed. Then add it back. This has the net effect of >+ // removing everything that is no longer needed. >+ computeRemovals(fProfile, request, getIncludeSource()); >+ request.addAll(Arrays.asList(units)); >+ for (int i = 0; i < units.length; i++) { >+ IInstallableUnit unit = units[i]; >+ request.setInstallableUnitProfileProperty(unit, PROP_INSTALLED_IU, Boolean.toString(true)); >+ } >+ >+ ProvisioningContext context = new ProvisioningContext(getAgent()); >+ context.setMetadataRepositories(getMetadataRepositories(fTarget)); >+ context.setArtifactRepositories(getArtifactRepositories(fTarget)); >+ >+ if (subMonitor.isCanceled()) { >+ return; >+ } >+ >+ IProvisioningPlan plan = planner.getProvisioningPlan(request, context, new SubProgressMonitor(subMonitor, 20)); >+ IStatus status = plan.getStatus(); >+ if (!status.isOK()) { >+ throw new CoreException(status); >+ } >+ setPlanProperties(plan, fTarget, TargetDefinitionPersistenceHelper.MODE_PLANNER); >+ IProvisioningPlan installerPlan = plan.getInstallerPlan(); >+ if (installerPlan != null) { >+ // this plan requires an update to the installer first, log the fact and attempt >+ // to continue, we don't want to update the running SDK while provisioning a target >+ PDECore.log(new Status(IStatus.INFO, PDECore.PLUGIN_ID, Messages.IUBundleContainer_6)); >+ } >+ subMonitor.worked(10); >+ if (subMonitor.isCanceled()) { >+ return; >+ } >+ >+ // execute the provisioning plan >+ IPhaseSet phases = createPhaseSet(); >+ IEngine engine = getEngine(); >+ IStatus result = engine.perform(plan, phases, new SubProgressMonitor(subMonitor, 140)); >+ if (subMonitor.isCanceled()) { >+ return; >+ } >+ if (!result.isOK()) { >+ throw new CoreException(result); >+ } >+ >+ // Now that we have a plan with all the binary and explicit bundles, do a second pass and add >+ // in all the source. >+ try { >+ planInSourceBundles(fProfile, context, subMonitor); >+ } catch (CoreException e) { >+ // XXX Review required: is adding in the source critical or optional? >+ // We failed adding in the source so remove the intermediate profile and rethrow >+ getProfileRegistry().removeProfile(fProfile.getProfileId(), fProfile.getTimestamp()); >+ throw e; >+ } >+ subMonitor.worked(10); >+ subMonitor.done(); >+ } >+ >+ private void setPlanProperties(IProvisioningPlan plan, ITargetDefinition definition, String mode) { >+ plan.setProfileProperty(PROP_PROVISION_MODE, mode); >+ plan.setProfileProperty(PROP_ALL_ENVIRONMENTS, Boolean.toString(getIncludeSource())); >+ plan.setProfileProperty(PROP_AUTO_INCLUDE_SOURCE, Boolean.toString(getIncludeSource())); >+ plan.setProfileProperty(PROP_SEQUENCE_NUMBER, Integer.toString(definition.currentSequenceNumber())); >+ } >+ >+ private IPhaseSet createPhaseSet() { >+ ArrayList phases = new ArrayList(4); >+ phases.add(new Collect(100)); >+ phases.add(new Property(1)); >+ phases.add(new Uninstall(50, true)); >+ phases.add(new Install(50)); >+ phases.add(new CollectNativesPhase(100)); >+ return new PhaseSet((Phase[]) phases.toArray(new Phase[phases.size()])); >+ } >+ >+ /** >+ * Update the given change request to remove anything that was explicitly installed >+ * including the internal source IU. >+ */ >+ private void computeRemovals(IProfile profile, IProfileChangeRequest request, boolean includeSource) { >+ // if include source is off then ensure that the source IU is removed. >+ if (!includeSource) { >+ IInstallableUnit sourceIU = getCurrentSourceIU(profile); >+ if (sourceIU != null) >+ request.remove(sourceIU); >+ } >+ // remove everything that is marked as roots. The plan will have the new roots added in anyway. >+ IQuery query = new IUProfilePropertyQuery(PROP_INSTALLED_IU, Boolean.toString(true)); >+ IQueryResult installedIUs = profile.query(query, null); >+ request.removeAll(installedIUs.toSet()); >+ } >+ >+ // run a second pass of the planner to add in the source bundles for everything that's >+ // in the current profile. >+ private void planInSourceBundles(IProfile fProfile, ProvisioningContext context, IProgressMonitor monitor) throws CoreException { >+ SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 10); >+ subMonitor.beginTask("Provisioning source bundles", 200); >+ >+ // create an IU that optionally and greedily requires the related source bundles. >+ // Completely replace any source IU that may already be in place >+ IInstallableUnit currentSourceIU = getCurrentSourceIU(fProfile); >+ >+ // determine the new version number. start at 1 >+ Version sourceVersion = Version.createOSGi(1, 0, 0); >+ if (currentSourceIU != null) { >+ Integer major = (Integer) currentSourceIU.getVersion().getSegment(0); >+ sourceVersion = Version.createOSGi(major.intValue() + 1, 0, 0); >+ } >+ IInstallableUnit sourceIU = createSourceIU(fProfile, sourceVersion); >+ >+ // call the planner again to add in the new source IU and all available source bundles >+ IPlanner planner = getPlanner(); >+ IProfileChangeRequest request = planner.createChangeRequest(fProfile); >+ if (currentSourceIU != null) >+ request.remove(currentSourceIU); >+ request.add(sourceIU); >+ IProvisioningPlan plan = planner.getProvisioningPlan(request, context, new SubProgressMonitor(subMonitor, 20)); >+ IStatus status = plan.getStatus(); >+ if (!status.isOK()) { >+ throw new CoreException(status); >+ } >+ if (subMonitor.isCanceled()) { >+ return; >+ } >+ >+ // execute the provisioning plan >+ long oldTimestamp = fProfile.getTimestamp(); >+ IPhaseSet phases = PhaseSetFactory.createDefaultPhaseSetExcluding(new String[] {PhaseSetFactory.PHASE_CHECK_TRUST, PhaseSetFactory.PHASE_CONFIGURE, PhaseSetFactory.PHASE_UNCONFIGURE, PhaseSetFactory.PHASE_UNINSTALL}); >+ IEngine engine = getEngine(); >+ plan.setProfileProperty(PROP_PROVISION_MODE, TargetDefinitionPersistenceHelper.MODE_PLANNER); >+ plan.setProfileProperty(PROP_ALL_ENVIRONMENTS, Boolean.toString(false)); >+ IStatus result = engine.perform(plan, phases, new SubProgressMonitor(subMonitor, 140)); >+ >+ if (subMonitor.isCanceled()) { >+ return; >+ } >+ if (!result.isOK()) { >+ throw new CoreException(result); >+ } >+ >+ // remove the old (intermediate) profile version now we have a new one with source. >+ getProfileRegistry().removeProfile(fProfile.getProfileId(), oldTimestamp); >+ subMonitor.worked(10); >+ subMonitor.done(); >+ } >+ >+ // Create and return an IU that has optional and greedy requirements on all source bundles >+ // related to bundle IUs in the given queryable. >+ private IInstallableUnit createSourceIU(IQueryable queryable, Version iuVersion) { >+ // compute the set of source bundles we could possibly need for the bundles in the profile >+ IRequirement bundleRequirement = MetadataFactory.createRequirement("org.eclipse.equinox.p2.eclipse.type", "bundle", null, null, false, false, false); //$NON-NLS-1$ //$NON-NLS-2$ >+ IQueryResult profileIUs = queryable.query(QueryUtil.createIUAnyQuery(), null); >+ ArrayList requirements = new ArrayList(); >+ for (Iterator i = profileIUs.iterator(); i.hasNext();) { >+ IInstallableUnit profileIU = (IInstallableUnit) i.next(); >+ if (profileIU.satisfies(bundleRequirement)) { >+ String id = profileIU.getId() + ".source"; //$NON-NLS-1$ >+ Version version = profileIU.getVersion(); >+ VersionRange range = new VersionRange(version, true, version, true); >+ IRequirement sourceRequirement = MetadataFactory.createRequirement("osgi.bundle", id, range, null, true, false, true); //$NON-NLS-1$ >+ requirements.add(sourceRequirement); >+ } >+ } >+ >+ InstallableUnitDescription sourceDescription = new MetadataFactory.InstallableUnitDescription(); >+ sourceDescription.setSingleton(true); >+ sourceDescription.setId(SOURCE_IU_ID); >+ sourceDescription.setVersion(iuVersion); >+ sourceDescription.addRequirements(requirements); >+ IProvidedCapability capability = MetadataFactory.createProvidedCapability(IInstallableUnit.NAMESPACE_IU_ID, SOURCE_IU_ID, iuVersion); >+ sourceDescription.setCapabilities(new IProvidedCapability[] {capability}); >+ return MetadataFactory.createInstallableUnit(sourceDescription); >+ } >+ >+ // Lookup and return (if any) the source IU in the given queryable. >+ private IInstallableUnit getCurrentSourceIU(IQueryable queryable) { >+ IQuery query = QueryUtil.createIUQuery(SOURCE_IU_ID); >+ IQueryResult list = queryable.query(query, null); >+ IInstallableUnit currentSourceIU = null; >+ if (!list.isEmpty()) >+ currentSourceIU = (IInstallableUnit) list.iterator().next(); >+ return currentSourceIU; >+ } >+ >+ /** >+ * Used to resolve the contents of this container when the user has chosen to manage the dependencies in the target >+ * themselves. The selected IUs and any required software that can be found will be retrieved from the repositories >+ * and added to the target. Any missing required software will be ignored. >+ * >+ * @param monitor for reporting progress >+ * @throws CoreException if there is a problem interacting with the repositories >+ */ >+ private void resolveWithSlicer(IProgressMonitor monitor) throws CoreException { >+ SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 10); >+ subMonitor.beginTask(Messages.IUBundleContainer_0, 180); >+ >+ // resolve IUs >+ IInstallableUnit[] units = getRootIUs(fTarget); >+ if (subMonitor.isCanceled()) { >+ return; >+ } >+ >+ URI[] repositories = getMetadataRepositories(fTarget); >+ int repoCount = repositories.length; >+ if (repoCount == 0) { >+ return; >+ } >+ IQueryable allMetadata = getQueryableMetadata(repositories, subMonitor); >+ >+ // do an initial slice to add everything the user requested >+ IQueryResult queryResult = slice(units, allMetadata, fTarget, subMonitor); >+ if (subMonitor.isCanceled() || queryResult == null || queryResult.isEmpty()) { >+ return; >+ } >+ >+ // If we are including source then create a source IU to bring in the relevant source >+ // bundles and run the slicer again. >+ if (getIncludeSource()) { >+ // Build an IU that represents all the source bundles and slice again to add them in if available >+ IInstallableUnit sourceIU = createSourceIU(queryResult, Version.createOSGi(1, 0, 0)); >+ IInstallableUnit[] units2 = new IInstallableUnit[units.length + 1]; >+ System.arraycopy(units, 0, units2, 0, units.length); >+ units2[units.length] = sourceIU; >+ >+ queryResult = slice(units2, allMetadata, fTarget, subMonitor); >+ if (subMonitor.isCanceled() || queryResult == null || queryResult.isEmpty()) { >+ return; >+ } >+ } >+ >+ IEngine engine = getEngine(); >+ ProvisioningContext context = new ProvisioningContext(getAgent()); >+ context.setMetadataRepositories(repositories); >+ context.setArtifactRepositories(getArtifactRepositories(fTarget)); >+ IProvisioningPlan plan = engine.createPlan(fProfile, context); >+ setPlanProperties(plan, fTarget, TargetDefinitionPersistenceHelper.MODE_SLICER); >+ >+ Set newSet = queryResult.toSet(); >+ Iterator itor = newSet.iterator(); >+ while (itor.hasNext()) { >+ plan.addInstallableUnit((IInstallableUnit) itor.next()); >+ } >+ for (int i = 0; i < units.length; i++) { >+ IInstallableUnit unit = units[i]; >+ plan.setInstallableUnitProfileProperty(unit, PROP_INSTALLED_IU, Boolean.toString(true)); >+ } >+ >+ // remove all units that are in the current profile but not in the new slice >+ Set toRemove = fProfile.query(QueryUtil.ALL_UNITS, null).toSet(); >+ toRemove.removeAll(newSet); >+ for (Iterator i = toRemove.iterator(); i.hasNext();) { >+ plan.removeInstallableUnit((IInstallableUnit) i.next()); >+ } >+ >+ // execute the provisioning plan >+ IPhaseSet phases = createPhaseSet(); >+ IStatus result = engine.perform(plan, phases, new SubProgressMonitor(subMonitor, 140)); >+ if (!result.isOK()) { >+ throw new CoreException(result); >+ } >+ >+ subMonitor.worked(10); >+ subMonitor.done(); >+ } >+ >+ private IQueryResult slice(IInstallableUnit[] units, IQueryable allMetadata, ITargetDefinition definition, SubProgressMonitor subMonitor) throws CoreException { >+ // slice IUs and all prerequisites >+ PermissiveSlicer slicer = null; >+ if (getIncludeAllEnvironments()) { >+ slicer = new PermissiveSlicer(allMetadata, new HashMap(), true, false, true, true, false); >+ } else { >+ Map props = new HashMap(); >+ props.put("osgi.os", definition.getOS() != null ? definition.getOS() : Platform.getOS()); //$NON-NLS-1$ >+ props.put("osgi.ws", definition.getWS() != null ? definition.getWS() : Platform.getWS()); //$NON-NLS-1$ >+ props.put("osgi.arch", definition.getArch() != null ? definition.getArch() : Platform.getOSArch()); //$NON-NLS-1$ >+ props.put("osgi.nl", definition.getNL() != null ? definition.getNL() : Platform.getNL()); //$NON-NLS-1$ >+ props.put(IProfile.PROP_INSTALL_FEATURES, Boolean.TRUE.toString()); >+ slicer = new PermissiveSlicer(allMetadata, props, true, false, false, true, false); >+ } >+ IQueryable slice = slicer.slice(units, new SubProgressMonitor(subMonitor, 10)); >+ if (!slicer.getStatus().isOK()) { >+ throw new CoreException(slicer.getStatus()); >+ } >+ IQueryResult queryResult = null; >+ if (slice != null) >+ queryResult = slice.query(QueryUtil.createIUAnyQuery(), new SubProgressMonitor(subMonitor, 10)); >+ return queryResult; >+ } >+ >+ /** >+ * Returns the artifact repositories to consider when getting artifacts. Returns a default set of >+ * repositories if current repository settings are <code>null</code>). >+ * >+ * @return URI's of repositories to use when getting artifacts >+ * @exception CoreException >+ */ >+ private URI[] getArtifactRepositories(ITargetDefinition target) throws CoreException { >+ Set result = new HashSet(); > IBundleContainer[] containers = target.getBundleContainers(); >- if (containers != null) { >- for (int i = 0; i < containers.length; i++) { >- if (containers[i] instanceof IUBundleContainer) { >- IUBundleContainer iu = (IUBundleContainer) containers[i]; >- if (iu.getIncludeAllEnvironments()) { >- return true; >- } >+ IArtifactRepositoryManager manager = getArtifactRepositoryManager(); >+ for (int i = 0; i < containers.length; i++) { >+ IBundleContainer container = containers[i]; >+ if (container instanceof IUBundleContainer) { >+ URI[] repos = ((IUBundleContainer) container).getRepositories(); >+ if (repos == null) { >+ repos = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL); >+ } >+ result.addAll(Arrays.asList(repos)); >+ } >+ } >+ if (useAdditionalLocalArtifacts()) { >+ // get all the artifact repos we know in the manager currently >+ result.addAll(Arrays.asList(manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL))); >+ >+ // Add in the IDE profile bundle pool and all known workspaces >+ findProfileRepos(result); >+ findWorkspaceRepos(result); >+ } >+ return (URI[]) result.toArray(new URI[result.size()]); >+ } >+ >+ /** >+ * return whether or not to use local artifact repositories when provisioning the target >+ */ >+ private boolean useAdditionalLocalArtifacts() { >+ // XXX consider using a preference here or another strategy if users are able to spec >+ // what local repos are to be considered. >+ return true; >+ } >+ >+ /** >+ * Add the artifact repos from the PDE target bundle pools from all known repos. For example, the list >+ * of "recent workspaces" maintained by the IDE is a good source. >+ * >+ * @param additionalRepos the set to which additional repos are added. >+ */ >+ private void findWorkspaceRepos(Set additionalRepos) { >+ IPreferencesService prefs = getPreferences(); >+ if (prefs == null) >+ return; >+ String recent = prefs.getString("org.eclipse.ui.ide", "RECENT_WORKSPACES", null, null); //$NON-NLS-1$ //$NON-NLS-2$ >+ if (recent == null) >+ return; >+ String[] recents = recent.split("\n"); //$NON-NLS-1$ >+ for (int i = 0; i < recents.length; i++) { >+ String bundlePool = recents[i] + "/.metadata/.plugins/org.eclipse.pde.core/.bundle_pool"; //$NON-NLS-1$ >+ if (new File(bundlePool).exists()) { >+ URI uri; >+ try { >+ uri = new URI("file", bundlePool, null); //$NON-NLS-1$ >+ additionalRepos.add(uri); >+ } catch (URISyntaxException e) { >+ // should never happen >+ } >+ } >+ } >+ } >+ >+ /** >+ * Look through the current p2 profile (_SELF_) and add the artifact repos that make up its >+ * bundle pool, dropins location, ... This helps in the cases that you are targeting stuff that >+ * makes up your current IDE. >+ * >+ * @param additionalRepos the set to which additional repos are added. >+ */ >+ private void findProfileRepos(Set additionalRepos) { >+ try { >+ // NOTE: be sure to use the global p2 agent here as we are looking for SELF. >+ IProfileRegistry profileRegistry = (IProfileRegistry) getGlobalAgent().getService(IProfileRegistry.SERVICE_NAME); >+ if (profileRegistry == null) >+ return; >+ IProfile self = profileRegistry.getProfile(IProfileRegistry.SELF); >+ if (self == null) >+ return; >+ >+ IAgentLocation location = (IAgentLocation) getGlobalAgent().getService(IAgentLocation.SERVICE_NAME); >+ URI dataArea = location.getDataArea("org.eclipse.equinox.p2.engine"); //$NON-NLS-1$ >+ dataArea = URIUtil.append(dataArea, "profileRegistry/" + self.getProfileId() + ".profile"); //$NON-NLS-1$//$NON-NLS-2$ >+ ProfileMetadataRepository profileRepo = new ProfileMetadataRepository(getGlobalAgent(), dataArea, null); >+ Collection repos = profileRepo.getReferences(); >+ for (Iterator i = repos.iterator(); i.hasNext();) { >+ Object element = i.next(); >+ if (element instanceof IRepositoryReference) { >+ IRepositoryReference reference = (IRepositoryReference) element; >+ if (reference.getType() == IRepository.TYPE_ARTIFACT && reference.getLocation() != null) >+ additionalRepos.add(reference.getLocation()); >+ } >+ } >+ } catch (CoreException e) { >+ // if there is a problem, move on. Could log something here >+ return; >+ } >+ } >+ >+ /** >+ * Returns the IU's for the given target related to the given containers >+ * >+ * @param containers the bundle containers to filter with >+ * @return the discovered IUs >+ * @exception CoreException if unable to retrieve IU's >+ */ >+ private IInstallableUnit[] getRootIUs(ITargetDefinition definition) throws CoreException { >+ HashSet result = new HashSet(); >+ IBundleContainer[] containers = definition.getBundleContainers(); >+ for (int i = 0; i < containers.length; i++) { >+ IBundleContainer container = containers[i]; >+ if (container instanceof IUBundleContainer) { >+ IUBundleContainer iuContainer = (IUBundleContainer) container; >+ IQueryable repos = getQueryableMetadata(iuContainer.getRepositories(), new NullProgressMonitor()); >+ String[] ids = iuContainer.getIds(); >+ Version[] versions = iuContainer.getVersions(); >+ for (int j = 0; j < ids.length; j++) { >+ IQuery query = QueryUtil.createIUQuery(ids[j], versions[j]); >+ IQueryResult queryResult = repos.query(query, null); >+ if (queryResult.isEmpty()) >+ throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.IUBundleContainer_1, ids[j]))); >+ result.add(queryResult.iterator().next()); > } > } > } >- return false; >+ return (IInstallableUnit[]) result.toArray(new IInstallableUnit[result.size()]); >+ } >+ >+ /** >+ * Returns the repositories to consider when resolving IU's (will return default set of >+ * repositories if current repository settings are <code>null</code>). >+ * >+ * @return URI's of repositories to use when resolving bundles >+ * @exception CoreException >+ */ >+ private URI[] getMetadataRepositories(ITargetDefinition target) throws CoreException { >+ Set result = new HashSet(); >+ IBundleContainer[] containers = target.getBundleContainers(); >+ IMetadataRepositoryManager manager = getRepoManager(); >+ for (int i = 0; i < containers.length; i++) { >+ IBundleContainer container = containers[i]; >+ if (container instanceof IUBundleContainer) { >+ URI[] repos = ((IUBundleContainer) container).getRepositories(); >+ if (repos == null) { >+ repos = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL); >+ } >+ result.addAll(Arrays.asList(repos)); >+ } >+ } >+ return (URI[]) result.toArray(new URI[result.size()]); >+ } >+ >+ private static final String NATIVE_ARTIFACTS = "nativeArtifacts"; //$NON-NLS-1$ >+ private static final String NATIVE_TYPE = "org.eclipse.equinox.p2.native"; //$NON-NLS-1$ >+ private static final String PARM_OPERAND = "operand"; //$NON-NLS-1$ >+ >+ protected static class CollectNativesAction extends ProvisioningAction { >+ public IStatus execute(Map parameters) { >+ InstallableUnitOperand operand = (InstallableUnitOperand) parameters.get(PARM_OPERAND); >+ IInstallableUnit installableUnit = operand.second(); >+ if (installableUnit == null) >+ return Status.OK_STATUS; >+ >+ IArtifactRepositoryManager manager; >+ try { >+ Collection toDownload = installableUnit.getArtifacts(); >+ if (toDownload == null) >+ return Status.OK_STATUS; >+ >+ List artifactRequests = (List) parameters.get(NATIVE_ARTIFACTS); >+ IArtifactRepository destinationArtifactRepository = getBundlePool(); >+ manager = getArtifactRepositoryManager(); >+ for (Iterator i = toDownload.iterator(); i.hasNext();) { >+ IArtifactKey keyToDownload = (IArtifactKey) i.next(); >+ IArtifactRequest request = manager.createMirrorRequest(keyToDownload, destinationArtifactRepository, null, null); >+ artifactRequests.add(request); >+ } >+ } catch (CoreException e) { >+ return e.getStatus(); >+ } >+ return Status.OK_STATUS; >+ } >+ >+ public IStatus undo(Map parameters) { >+ // nothing to do for now >+ return Status.OK_STATUS; >+ } >+ } >+ >+ protected static class CollectNativesPhase extends InstallableUnitPhase { >+ public CollectNativesPhase(int weight) { >+ super(NATIVE_ARTIFACTS, weight); >+ } >+ >+ protected List getActions(InstallableUnitOperand operand) { >+ IInstallableUnit unit = operand.second(); >+ if (unit != null && unit.getTouchpointType().getId().equals(NATIVE_TYPE)) { >+ return Collections.singletonList(new CollectNativesAction()); >+ } >+ return null; >+ } >+ >+ protected IStatus initializePhase(IProgressMonitor monitor, IProfile profile, Map parameters) { >+ parameters.put(NATIVE_ARTIFACTS, new ArrayList()); >+ parameters.put(PARM_PROFILE, profile); >+ return null; >+ } >+ >+ protected IStatus completePhase(IProgressMonitor monitor, IProfile profile, Map parameters) { >+ List artifactRequests = (List) parameters.get(NATIVE_ARTIFACTS); >+ ProvisioningContext context = (ProvisioningContext) parameters.get(PARM_CONTEXT); >+ IProvisioningAgent agent = (IProvisioningAgent) parameters.get(PARM_AGENT); >+ DownloadManager dm = new DownloadManager(context, agent); >+ for (Iterator i = artifactRequests.iterator(); i.hasNext();) { >+ dm.add((IArtifactRequest) i.next()); >+ } >+ return dm.start(monitor); >+ } >+ } >+ >+ /** >+ * @return the profile associated with this synchronizer >+ */ >+ IProfile getProfile() { >+ return fProfile; >+ } >+ >+ /** >+ * @return the target definition associated with this synchronizer >+ */ >+ ITargetDefinition getTargetDefinition() { >+ return fTarget; > } > > } >Index: src/org/eclipse/pde/internal/core/target/TargetDefinition.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/TargetDefinition.java,v >retrieving revision 1.18 >diff -u -r1.18 TargetDefinition.java >--- src/org/eclipse/pde/internal/core/target/TargetDefinition.java 5 Nov 2010 15:56:16 -0000 1.18 >+++ src/org/eclipse/pde/internal/core/target/TargetDefinition.java 30 Nov 2010 21:03:55 -0000 >@@ -75,6 +75,8 @@ > private IFeatureModel[] fFeatureModels; > private IResolvedBundle[] fOtherBundles; > >+ private int fSequenceNumber = -1; >+ > /** > * Constructs a target definition based on the given handle. > */ >@@ -142,6 +144,7 @@ > * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setArch(java.lang.String) > */ > public void setArch(String arch) { >+ incrementSequenceNumber(); > fArch = arch; > } > >@@ -149,6 +152,7 @@ > * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setNL(java.lang.String) > */ > public void setNL(String nl) { >+ incrementSequenceNumber(); > fNL = nl; > } > >@@ -163,6 +167,7 @@ > * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setOS(java.lang.String) > */ > public void setOS(String os) { >+ incrementSequenceNumber(); > fOS = os; > } > >@@ -190,6 +195,7 @@ > * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setWS(java.lang.String) > */ > public void setWS(String ws) { >+ incrementSequenceNumber(); > fWS = ws; > } > >@@ -197,6 +203,7 @@ > * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setBundleContainers(org.eclipse.pde.internal.core.target.provisional.IBundleContainer[]) > */ > public void setBundleContainers(IBundleContainer[] containers) { >+ incrementSequenceNumber(); > // Clear the feature model cache as it is based on the bundle container locations > fFeatureModels = null; > fOtherBundles = null; >@@ -210,6 +217,30 @@ > if (containers == null) { > fIncluded = null; > fOptional = null; >+ } else { >+ for (int i = 0; i < containers.length; i++) { >+ ((AbstractBundleContainer) containers[i]).associateWithTarget(this); >+ } >+ } >+ } >+ >+ /** >+ * Clears the any models that are cached for the given container location. >+ * >+ * @param location location to clear cache for or <code>null</code> to clear all cached models >+ */ >+ public void flushCaches(String location) { >+ // Clear the feature model cache as it is based on the bundle container locations >+ fFeatureModels = null; >+ fOtherBundles = null; >+ if (location == null) { >+ fFeaturesInLocation.clear(); >+ } else { >+ fFeaturesInLocation.remove(location); >+ } >+ if (fContainers == null) { >+ fIncluded = null; >+ fOptional = null; > } > } > >@@ -623,6 +654,7 @@ > fProgramArgs = null; > fVMArgs = null; > fWS = null; >+ fSequenceNumber = 0; > TargetDefinitionPersistenceHelper.initFromXML(this, stream); > } catch (ParserConfigurationException e) { > abort(Messages.TargetDefinition_0, e); >@@ -994,11 +1026,42 @@ > return result; > } > >+ /** >+ * @return the current UI style one of {@link #MODE_FEATURE} or {@link #MODE_PLUGIN} >+ */ > public int getUIMode() { > return fUIMode; > } > >+ /** >+ * @param mode new UI style to use, one of {@link #MODE_FEATURE} or {@link #MODE_PLUGIN} >+ */ > public void setUIMode(int mode) { > fUIMode = mode; > } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#currentSequenceNumber() >+ */ >+ public int currentSequenceNumber() { >+ return fSequenceNumber; >+ } >+ >+ /** >+ * Increases the current sequence number. >+ * @see TargetDefinition#currentSequenceNumber() >+ * @return the current sequence number after it has been increased >+ */ >+ public int incrementSequenceNumber() { >+ return ++fSequenceNumber; >+ } >+ >+ /** >+ * Convenience method to set the sequence number to a specific >+ * value. Used when loading a target from a persisted file. >+ * @param value value to set the sequence number to >+ */ >+ void setSequenceNumber(int value) { >+ fSequenceNumber = value; >+ } > } >Index: src/org/eclipse/pde/internal/core/target/TargetDefinitionPersistenceHelper.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/TargetDefinitionPersistenceHelper.java,v >retrieving revision 1.9 >diff -u -r1.9 TargetDefinitionPersistenceHelper.java >--- src/org/eclipse/pde/internal/core/target/TargetDefinitionPersistenceHelper.java 5 Nov 2010 15:56:16 -0000 1.9 >+++ src/org/eclipse/pde/internal/core/target/TargetDefinitionPersistenceHelper.java 30 Nov 2010 21:03:55 -0000 >@@ -72,6 +72,7 @@ > static final String ATTR_OPTIONAL = "optional"; //$NON-NLS-1$ > static final String ATTR_VERSION = "version"; //$NON-NLS-1$ > static final String ATTR_CONFIGURATION = "configuration"; //$NON-NLS-1$ >+ static final String ATTR_SEQUENCE_NUMBER = "sequenceNumber"; //$NON-NLS-1$ > static final String CONTENT = "content"; //$NON-NLS-1$ > static final String ATTR_USE_ALL = "useAllPlugins"; //$NON-NLS-1$ > static final String PLUGINS = "plugins"; //$NON-NLS-1$ >@@ -107,6 +108,8 @@ > rootElement.setAttribute(ATTR_INCLUDE_MODE, FEATURE); > } > >+ rootElement.setAttribute(ATTR_SEQUENCE_NUMBER, Integer.toString(definition.currentSequenceNumber())); >+ > IBundleContainer[] containers = definition.getBundleContainers(); > if (containers != null && containers.length > 0) { > Element containersElement = doc.createElement(LOCATIONS); >Index: src/org/eclipse/pde/internal/core/target/TargetPersistence35Helper.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/TargetPersistence35Helper.java,v >retrieving revision 1.2 >diff -u -r1.2 TargetPersistence35Helper.java >--- src/org/eclipse/pde/internal/core/target/TargetPersistence35Helper.java 1 Mar 2010 21:41:05 -0000 1.2 >+++ src/org/eclipse/pde/internal/core/target/TargetPersistence35Helper.java 30 Nov 2010 21:03:55 -0000 >@@ -224,18 +224,14 @@ > String[] iuIDs = (String[]) ids.toArray(new String[ids.size()]); > String[] iuVer = (String[]) versions.toArray(new String[versions.size()]); > URI[] uris = (URI[]) repos.toArray(new URI[repos.size()]); >- container = new IUBundleContainer(iuIDs, iuVer, uris); >+ int flags = IUBundleContainer.INCLUDE_REQUIRED; > if (includeMode != null && includeMode.trim().length() > 0) { >- if (includeMode.equals(TargetDefinitionPersistenceHelper.MODE_PLANNER)) { >- ((IUBundleContainer) container).setIncludeAllRequired(true, null); >- } else if (includeMode.equals(TargetDefinitionPersistenceHelper.MODE_SLICER)) { >- ((IUBundleContainer) container).setIncludeAllRequired(false, null); >+ if (includeMode.equals(TargetDefinitionPersistenceHelper.MODE_SLICER)) { >+ flags = 0; > } > } >- if (includeAllPlatforms != null && includeAllPlatforms.trim().length() > 0) { >- ((IUBundleContainer) container).setIncludeAllEnvironments(Boolean.valueOf(includeAllPlatforms).booleanValue(), null); >- } >- >+ flags |= Boolean.valueOf(includeAllPlatforms).booleanValue() ? IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS : 0; >+ container = new IUBundleContainer(iuIDs, iuVer, uris, flags); > } > > NodeList list = location.getChildNodes(); >Index: src/org/eclipse/pde/internal/core/target/TargetPersistence36Helper.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/TargetPersistence36Helper.java,v >retrieving revision 1.2 >diff -u -r1.2 TargetPersistence36Helper.java >--- src/org/eclipse/pde/internal/core/target/TargetPersistence36Helper.java 5 Nov 2010 15:56:16 -0000 1.2 >+++ src/org/eclipse/pde/internal/core/target/TargetPersistence36Helper.java 30 Nov 2010 21:03:55 -0000 >@@ -148,6 +148,14 @@ > } > } > } >+ >+ // Set the sequence number at the very end >+ String sequenceNumber = root.getAttribute(TargetDefinitionPersistenceHelper.ATTR_SEQUENCE_NUMBER); >+ try { >+ ((TargetDefinition) definition).setSequenceNumber(Integer.parseInt(sequenceNumber)); >+ } catch (NumberFormatException e) { >+ ((TargetDefinition) definition).setSequenceNumber(0); >+ } > } > > /** >@@ -215,19 +223,16 @@ > String[] iuIDs = (String[]) ids.toArray(new String[ids.size()]); > String[] iuVer = (String[]) versions.toArray(new String[versions.size()]); > URI[] uris = (URI[]) repos.toArray(new URI[repos.size()]); >- container = new IUBundleContainer(iuIDs, iuVer, uris); >+ >+ int flags = IUBundleContainer.INCLUDE_REQUIRED; > if (includeMode != null && includeMode.trim().length() > 0) { >- if (includeMode.equals(TargetDefinitionPersistenceHelper.MODE_PLANNER)) { >- ((IUBundleContainer) container).setIncludeAllRequired(true, null); >- } else if (includeMode.equals(TargetDefinitionPersistenceHelper.MODE_SLICER)) { >- ((IUBundleContainer) container).setIncludeAllRequired(false, null); >+ if (includeMode.equals(TargetDefinitionPersistenceHelper.MODE_SLICER)) { >+ flags = 0; > } > } >- if (includeAllPlatforms != null && includeAllPlatforms.trim().length() > 0) { >- ((IUBundleContainer) container).setIncludeAllEnvironments(Boolean.valueOf(includeAllPlatforms).booleanValue(), null); >- } >- ((IUBundleContainer) container).setIncludeSource(Boolean.valueOf(includeSource).booleanValue()); >- >+ flags |= Boolean.valueOf(includeAllPlatforms).booleanValue() ? IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS : 0; >+ flags |= Boolean.valueOf(includeSource).booleanValue() ? IUBundleContainer.INCLUDE_SOURCE : 0; >+ container = new IUBundleContainer(iuIDs, iuVer, uris, flags); > } > return container; > } >Index: src/org/eclipse/pde/internal/core/target/TargetPlatformService.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/TargetPlatformService.java,v >retrieving revision 1.12 >diff -u -r1.12 TargetPlatformService.java >--- src/org/eclipse/pde/internal/core/target/TargetPlatformService.java 5 Nov 2010 15:56:16 -0000 1.12 >+++ src/org/eclipse/pde/internal/core/target/TargetPlatformService.java 30 Nov 2010 21:03:55 -0000 >@@ -591,16 +591,16 @@ > } > > /* (non-Javadoc) >- * @see org.eclipse.pde.internal.core.target.provisional.ITargetPlatformService#newIUContainer(org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit[], java.net.URI[]) >+ * @see org.eclipse.pde.internal.core.target.provisional.ITargetPlatformService#newIUContainer(org.eclipse.equinox.p2.metadata.IInstallableUnit[], java.net.URI[], int) > */ >- public IBundleContainer newIUContainer(IInstallableUnit[] units, URI[] repositories) { >- return new IUBundleContainer(units, repositories); >+ public IBundleContainer newIUContainer(IInstallableUnit[] units, URI[] repositories, int resolutionFlags) { >+ return new IUBundleContainer(units, repositories, resolutionFlags); > } > > /* (non-Javadoc) >- * @see org.eclipse.pde.internal.core.target.provisional.ITargetPlatformService#newIUContainer(java.lang.String[], java.lang.String[], java.net.URI[]) >+ * @see org.eclipse.pde.internal.core.target.provisional.ITargetPlatformService#newIUContainer(java.lang.String[], java.lang.String[], java.net.URI[], int) > */ >- public IBundleContainer newIUContainer(String[] unitIds, String[] versions, URI[] repositories) { >- return new IUBundleContainer(unitIds, versions, repositories); >+ public IBundleContainer newIUContainer(String[] unitIds, String[] versions, URI[] repositories, int resolutionFlags) { >+ return new IUBundleContainer(unitIds, versions, repositories, resolutionFlags); > } > } >Index: src/org/eclipse/pde/internal/core/target/provisional/ITargetDefinition.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/provisional/ITargetDefinition.java,v >retrieving revision 1.10 >diff -u -r1.10 ITargetDefinition.java >--- src/org/eclipse/pde/internal/core/target/provisional/ITargetDefinition.java 8 Apr 2010 20:57:50 -0000 1.10 >+++ src/org/eclipse/pde/internal/core/target/provisional/ITargetDefinition.java 30 Nov 2010 21:03:55 -0000 >@@ -320,4 +320,13 @@ > * @return implicit dependencies or <code>null</code> > */ > public NameVersionDescriptor[] getImplicitDependencies(); >+ >+ /** >+ * Returns the current sequence number of this target. Sequence numbers change >+ * whenever something in the target that affects the set of features and bundles that >+ * would be resolved. >+ * >+ * @return the current sequence number >+ */ >+ public int currentSequenceNumber(); > } >Index: src/org/eclipse/pde/internal/core/target/provisional/ITargetPlatformService.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/provisional/ITargetPlatformService.java,v >retrieving revision 1.13 >diff -u -r1.13 ITargetPlatformService.java >--- src/org/eclipse/pde/internal/core/target/provisional/ITargetPlatformService.java 28 May 2010 19:40:04 -0000 1.13 >+++ src/org/eclipse/pde/internal/core/target/provisional/ITargetPlatformService.java 30 Nov 2010 21:03:55 -0000 >@@ -10,11 +10,11 @@ > *******************************************************************************/ > package org.eclipse.pde.internal.core.target.provisional; > >-import org.eclipse.equinox.p2.metadata.IInstallableUnit; >- > import java.net.URI; > import org.eclipse.core.resources.IFile; > import org.eclipse.core.runtime.*; >+import org.eclipse.equinox.p2.metadata.IInstallableUnit; >+import org.eclipse.pde.internal.core.target.IUBundleContainer; > > /** > * A service to manage target platform definitions available to the workspace. >@@ -139,9 +139,10 @@ > * @param units installable units > * @param repositories URI's describing repository locations or <code>null</code> to use > * default repositories >+ * @param resolutionFlags bitmask of flags to control IU resolution, possible flags are {@link IUBundleContainer#INCLUDE_ALL_ENVIRONMENTS}, {@link IUBundleContainer#INCLUDE_REQUIRED}, {@link IUBundleContainer#INCLUDE_SOURCE} > * @return bundle container > */ >- public IBundleContainer newIUContainer(IInstallableUnit[] units, URI[] repositories); >+ public IBundleContainer newIUContainer(IInstallableUnit[] units, URI[] repositories, int resolutionFlags); > > /** > * Creates and returns a bundle container that contains all bundles contained in >@@ -152,9 +153,10 @@ > * @param versions version identifiers > * @param repositories URI's describing repository locations or <code>null</code> to use > * default repositories >+ * @param resolutionFlags bitmask of flags to control IU resolution, possible flags are {@link IUBundleContainer#INCLUDE_ALL_ENVIRONMENTS}, {@link IUBundleContainer#INCLUDE_REQUIRED}, {@link IUBundleContainer#INCLUDE_SOURCE} > * @return bundle container > */ >- public IBundleContainer newIUContainer(String[] unitIds, String[] versions, URI[] repositories); >+ public IBundleContainer newIUContainer(String[] unitIds, String[] versions, URI[] repositories, int resolutionFlags); > > /** > * Creates and returns a bundle container that contains all bundles referenced by >#P org.eclipse.pde.ui >Index: META-INF/MANIFEST.MF >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF,v >retrieving revision 1.88 >diff -u -r1.88 MANIFEST.MF >--- META-INF/MANIFEST.MF 23 Nov 2010 18:56:29 -0000 1.88 >+++ META-INF/MANIFEST.MF 30 Nov 2010 21:03:58 -0000 >@@ -108,7 +108,7 @@ > org.eclipse.pde.launching;bundle-version="[3.6.0,4.0.0)";visibility:=reexport, > org.eclipse.ui.console;bundle-version="[3.5.0,4.0.0)", > org.eclipse.equinox.simpleconfigurator;bundle-version="[1.0.200,2.0.0)", >- org.eclipse.equinox.p2.repository.tools >+ org.eclipse.equinox.p2.repository.tools;bundle-version="[2.0.100,3.0.0)" > Eclipse-LazyStart: true > Import-Package: com.ibm.icu.text, > org.eclipse.jdt.debug.core >Index: src/org/eclipse/pde/internal/ui/search/dialogs/FilteredIUSelectionDialog.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/search/dialogs/FilteredIUSelectionDialog.java,v >retrieving revision 1.3 >diff -u -r1.3 FilteredIUSelectionDialog.java >--- src/org/eclipse/pde/internal/ui/search/dialogs/FilteredIUSelectionDialog.java 2 Mar 2010 20:57:09 -0000 1.3 >+++ src/org/eclipse/pde/internal/ui/search/dialogs/FilteredIUSelectionDialog.java 30 Nov 2010 21:03:58 -0000 >@@ -13,7 +13,6 @@ > import java.util.Comparator; > import java.util.Iterator; > import org.eclipse.core.runtime.*; >-import org.eclipse.equinox.p2.core.IProvisioningAgent; > import org.eclipse.equinox.p2.metadata.IInstallableUnit; > import org.eclipse.equinox.p2.metadata.IProvidedCapability; > import org.eclipse.equinox.p2.query.IQuery; >@@ -24,6 +23,7 @@ > import org.eclipse.jface.viewers.*; > import org.eclipse.pde.internal.core.PDECore; > import org.eclipse.pde.internal.core.target.Messages; >+import org.eclipse.pde.internal.core.target.P2TargetUtils; > import org.eclipse.pde.internal.ui.*; > import org.eclipse.swt.SWT; > import org.eclipse.swt.events.SelectionAdapter; >@@ -67,6 +67,13 @@ > styledString.append("(", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$ > styledString.append(iuPackage.getVersion().toString(), StyledString.QUALIFIER_STYLER); > styledString.append(")", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$ >+ IInstallableUnit iu = iuPackage.getIU(); >+ styledString.append(" from ", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$ >+ styledString.append(iu.getId(), StyledString.QUALIFIER_STYLER); >+ styledString.append(' '); >+ styledString.append("(", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$ >+ styledString.append(iu.getVersion().toString(), StyledString.QUALIFIER_STYLER); >+ styledString.append(")", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$ > } else if (element instanceof IInstallableUnit) { > IInstallableUnit iu = (IInstallableUnit) element; > String name = iu.getProperty(IInstallableUnit.PROP_NAME, null); >@@ -190,10 +197,9 @@ > */ > protected void fillContentProvider(AbstractContentProvider contentProvider, ItemsFilter itemsFilter, IProgressMonitor progressMonitor) throws CoreException { > // TODO clean up this code a bit... >- IProvisioningAgent agent = (IProvisioningAgent) PDECore.getDefault().acquireService(IProvisioningAgent.SERVICE_NAME); >- if (agent == null) >- throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_7)); >- IMetadataRepositoryManager manager = (IMetadataRepositoryManager) agent.getService(IMetadataRepositoryManager.SERVICE_NAME); >+ IMetadataRepositoryManager manager = P2TargetUtils.getRepoManager(); >+ if (manager == null) >+ throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_2)); > > //URI[] knownRepositories = metadataManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL); > IQuery pipedQuery; >Index: src/org/eclipse/pde/internal/ui/search/dialogs/TargetRepositorySearchHandler.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/search/dialogs/TargetRepositorySearchHandler.java,v >retrieving revision 1.7 >diff -u -r1.7 TargetRepositorySearchHandler.java >--- src/org/eclipse/pde/internal/ui/search/dialogs/TargetRepositorySearchHandler.java 9 Aug 2010 21:18:08 -0000 1.7 >+++ src/org/eclipse/pde/internal/ui/search/dialogs/TargetRepositorySearchHandler.java 30 Nov 2010 21:03:58 -0000 >@@ -78,10 +78,9 @@ > ITargetPlatformService service = (ITargetPlatformService) PDECore.getDefault().acquireService(ITargetPlatformService.class.getName()); > ITargetHandle currentTarget = service.getWorkspaceTargetHandle(); > ITargetDefinition definition = currentTarget.getTargetDefinition(); >- IUBundleContainer container = (IUBundleContainer) service.newIUContainer(units, repositories); > // Force the target into slicer mode as all requirements may not be available >- container.setIncludeAllRequired(false, definition); >- container.setIncludeAllEnvironments(true, definition); >+ int flags = IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS | IUBundleContainer.INCLUDE_SOURCE; >+ IUBundleContainer container = (IUBundleContainer) service.newIUContainer(units, repositories, flags); > IBundleContainer[] oldContainers = definition.getBundleContainers(); > if (oldContainers == null) { > definition.setBundleContainers(new IBundleContainer[] {container}); >Index: src/org/eclipse/pde/internal/ui/shared/target/AddBundleContainerSelectionPage.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/shared/target/AddBundleContainerSelectionPage.java,v >retrieving revision 1.21 >diff -u -r1.21 AddBundleContainerSelectionPage.java >--- src/org/eclipse/pde/internal/ui/shared/target/AddBundleContainerSelectionPage.java 5 Nov 2010 15:56:16 -0000 1.21 >+++ src/org/eclipse/pde/internal/ui/shared/target/AddBundleContainerSelectionPage.java 30 Nov 2010 21:03:58 -0000 >@@ -14,12 +14,10 @@ > import java.util.ArrayList; > import java.util.List; > import org.eclipse.core.runtime.*; >-import org.eclipse.equinox.p2.engine.IProfile; > import org.eclipse.jface.dialogs.*; > import org.eclipse.jface.viewers.*; > import org.eclipse.jface.wizard.*; > import org.eclipse.pde.internal.core.PDECore; >-import org.eclipse.pde.internal.core.target.P2TargetUtils; > import org.eclipse.pde.internal.core.target.provisional.*; > import org.eclipse.pde.internal.ui.*; > import org.eclipse.pde.internal.ui.wizards.WizardElement; >@@ -291,14 +289,7 @@ > settings = PDEPlugin.getDefault().getDialogSettings().addNewSection(SETTINGS_SECTION); > } > setDialogSettings(settings); >- // TODO Use proper API to get the profile >- IProfile profile = null; >- try { >- profile = P2TargetUtils.getProfile(fTarget); >- } catch (CoreException e) { >- PDEPlugin.log(e); >- } >- addPage(new EditIUContainerPage(fTarget, profile)); >+ addPage(new EditIUContainerPage(fTarget)); > } > > public boolean performFinish() { >Index: src/org/eclipse/pde/internal/ui/shared/target/EditBundleContainerWizard.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/shared/target/EditBundleContainerWizard.java,v >retrieving revision 1.6 >diff -u -r1.6 EditBundleContainerWizard.java >--- src/org/eclipse/pde/internal/ui/shared/target/EditBundleContainerWizard.java 5 Nov 2010 15:56:16 -0000 1.6 >+++ src/org/eclipse/pde/internal/ui/shared/target/EditBundleContainerWizard.java 30 Nov 2010 21:03:58 -0000 >@@ -10,7 +10,6 @@ > *******************************************************************************/ > package org.eclipse.pde.internal.ui.shared.target; > >-import org.eclipse.core.runtime.CoreException; > import org.eclipse.jface.dialogs.IDialogSettings; > import org.eclipse.jface.wizard.Wizard; > import org.eclipse.pde.internal.core.target.*; >@@ -50,11 +49,7 @@ > } else if (fContainer instanceof FeatureBundleContainer) { > fPage = new EditFeatureContainerPage(fContainer); > } else if (fContainer instanceof IUBundleContainer) { >- try { >- fPage = new EditIUContainerPage((IUBundleContainer) fContainer, fTarget, P2TargetUtils.getProfile(fTarget)); >- } catch (CoreException e) { >- PDEPlugin.log(e); >- } >+ fPage = new EditIUContainerPage((IUBundleContainer) fContainer, fTarget); > } > if (fPage != null) { > addPage(fPage); >Index: src/org/eclipse/pde/internal/ui/shared/target/EditIUContainerPage.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/shared/target/EditIUContainerPage.java,v >retrieving revision 1.18 >diff -u -r1.18 EditIUContainerPage.java >--- src/org/eclipse/pde/internal/ui/shared/target/EditIUContainerPage.java 5 Nov 2010 15:56:16 -0000 1.18 >+++ src/org/eclipse/pde/internal/ui/shared/target/EditIUContainerPage.java 30 Nov 2010 21:03:58 -0000 >@@ -18,7 +18,6 @@ > import org.eclipse.equinox.internal.p2.ui.actions.PropertyDialogAction; > import org.eclipse.equinox.internal.p2.ui.dialogs.*; > import org.eclipse.equinox.internal.p2.ui.query.IUViewQueryContext; >-import org.eclipse.equinox.p2.engine.IProfile; > import org.eclipse.equinox.p2.metadata.IInstallableUnit; > import org.eclipse.equinox.p2.ui.Policy; > import org.eclipse.equinox.p2.ui.ProvisioningUI; >@@ -30,6 +29,7 @@ > import org.eclipse.osgi.util.NLS; > import org.eclipse.pde.internal.core.PDECore; > import org.eclipse.pde.internal.core.target.IUBundleContainer; >+import org.eclipse.pde.internal.core.target.P2TargetUtils; > import org.eclipse.pde.internal.core.target.provisional.*; > import org.eclipse.pde.internal.ui.*; > import org.eclipse.swt.SWT; >@@ -68,11 +68,6 @@ > private IUBundleContainer fEditContainer; > > /** >- * Profile from the target >- */ >- private IProfile fProfile; >- >- /** > * Used to provide special attributes/filtering to the available iu group > */ > private IUViewQueryContext fQueryContext; >@@ -97,19 +92,18 @@ > > /** > * Constructor for creating a new container >- * @param profile profile from the parent target, used to setup the p2 UI >+ * @param definition the target definintion we are editing > */ >- protected EditIUContainerPage(ITargetDefinition definition, IProfile profile) { >+ protected EditIUContainerPage(ITargetDefinition definition) { > super("AddP2Container"); //$NON-NLS-1$ > setTitle(Messages.EditIUContainerPage_5); > setMessage(Messages.EditIUContainerPage_6); > fTarget = definition; >- fProfile = profile; > ProvisioningUI selfProvisioningUI = ProvisioningUI.getDefaultUI(); > // TODO we use the service session from the self profile. In the future we may want > // to set up our own services for the profile (separate repo managers, etc). > // We use our own new policy so we don't bash the SDK's settings. >- profileUI = new ProvisioningUI(selfProvisioningUI.getSession(), profile.getProfileId(), new Policy()); >+ profileUI = new ProvisioningUI(selfProvisioningUI.getSession(), P2TargetUtils.getProfileId(definition), new Policy()); > } > > /** >@@ -117,8 +111,8 @@ > * @param container the container to edit > * @param profile profile from the parent target, used to setup the p2 UI > */ >- protected EditIUContainerPage(IUBundleContainer container, ITargetDefinition definition, IProfile profile) { >- this(definition, profile); >+ protected EditIUContainerPage(IUBundleContainer container, ITargetDefinition definition) { >+ this(definition); > setTitle(Messages.EditIUContainerPage_7); > setMessage(Messages.EditIUContainerPage_6); > fEditContainer = container; >@@ -132,10 +126,10 @@ > if (service == null) { > PDEPlugin.log(new Status(IStatus.ERROR, PDEPlugin.getPluginId(), Messages.EditIUContainerPage_9)); > } >- IUBundleContainer container = (IUBundleContainer) service.newIUContainer(fAvailableIUGroup.getCheckedLeafIUs(), fRepoLocation != null ? new URI[] {fRepoLocation} : null); >- container.setIncludeAllRequired(fIncludeRequiredButton.getSelection(), fTarget); >- container.setIncludeAllEnvironments(fAllPlatformsButton.getSelection(), fTarget); >- container.setIncludeSource(fIncludeSourceButton.getSelection()); >+ int flags = fIncludeRequiredButton.getSelection() ? IUBundleContainer.INCLUDE_REQUIRED : 0; >+ flags |= fAllPlatformsButton.getSelection() ? IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS : 0; >+ flags |= fIncludeSourceButton.getSelection() ? IUBundleContainer.INCLUDE_SOURCE : 0; >+ IUBundleContainer container = (IUBundleContainer) service.newIUContainer(fAvailableIUGroup.getCheckedLeafIUs(), fRepoLocation != null ? new URI[] {fRepoLocation} : null, flags); > return container; > } > >@@ -299,32 +293,37 @@ > }); > ((GridData) fAllPlatformsButton.getLayoutData()).horizontalIndent = 10; > fIncludeSourceButton = SWTFactory.createCheckButton(slicerGroup, Messages.EditIUContainerPage_16, null, true, 1); >+ fIncludeSourceButton.addSelectionListener(new SelectionAdapter() { >+ public void widgetSelected(SelectionEvent e) { >+ warnIfGlobalSettingChanged(); >+ } >+ }); > } > > private void warnIfGlobalSettingChanged() { >- boolean warn = false; >- if (fTarget != null) { >- IBundleContainer[] containers = fTarget.getBundleContainers(); >- if (containers != null) { >- for (int i = 0; i < containers.length; i++) { >- if (containers[i] instanceof IUBundleContainer && containers[i] != fEditContainer) { >- IUBundleContainer container = (IUBundleContainer) containers[i]; >- if (container.getIncludeAllRequired() != fIncludeRequiredButton.getSelection()) { >- warn = true; >- break; >- } >- if (!fIncludeRequiredButton.getSelection() && container.getIncludeAllEnvironments() != fAllPlatformsButton.getSelection()) { >- warn = true; >- break; >- } >- } >+ boolean noChange = true; >+ IUBundleContainer iuContainer = null; >+ IBundleContainer[] containers = fTarget.getBundleContainers(); >+ if (containers != null) { >+ // Look for a IUBundleContainer to compare against. >+ for (int i = 0; i < containers.length; i++) { >+ if (containers[i] instanceof IUBundleContainer && containers[i] != fEditContainer) { >+ iuContainer = (IUBundleContainer) containers[i]; >+ break; > } > } >+ // If there is another IU container then compare against it. No need to check them all >+ // as they will all be set the same within one target. >+ if (iuContainer != null) { >+ noChange &= fIncludeRequiredButton.getSelection() == iuContainer.getIncludeAllRequired(); >+ noChange &= fAllPlatformsButton.getSelection() == iuContainer.getIncludeAllEnvironments(); >+ noChange &= fIncludeSourceButton.getSelection() == iuContainer.getIncludeSource(); >+ } > } >- if (warn) { >- setMessage(Messages.EditIUContainerPage_4, IStatus.WARNING); >- } else { >+ if (noChange) { > setMessage(Messages.EditIUContainerPage_6); >+ } else { >+ setMessage(Messages.EditIUContainerPage_4, IStatus.WARNING); > } > } > >@@ -333,7 +332,7 @@ > */ > private void createQueryContext() { > fQueryContext = ProvUI.getQueryContext(ProvisioningUI.getDefaultUI().getPolicy()); >- fQueryContext.setInstalledProfileId(fProfile.getProfileId()); >+ fQueryContext.setInstalledProfileId(P2TargetUtils.getProfileId(fTarget)); > fQueryContext.showAlreadyInstalled(); > } > >@@ -498,7 +497,7 @@ > // Only able to check items if we don't have categories > fQueryContext.setViewType(IUViewQueryContext.AVAILABLE_VIEW_FLAT); > fAvailableIUGroup.updateAvailableViewState(); >- fAvailableIUGroup.setChecked(fEditContainer.getInstallableUnits(fProfile)); >+ fAvailableIUGroup.setChecked(fEditContainer.getInstallableUnits()); > // Make sure view is back in proper state > updateViewContext(); > IInstallableUnit[] units = fAvailableIUGroup.getCheckedLeafIUs(); >@@ -519,5 +518,4 @@ > } > } > } >- > } >Index: src/org/eclipse/pde/internal/ui/shared/target/TargetContentsGroup.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/shared/target/TargetContentsGroup.java,v >retrieving revision 1.22 >diff -u -r1.22 TargetContentsGroup.java >--- src/org/eclipse/pde/internal/ui/shared/target/TargetContentsGroup.java 1 Oct 2010 19:23:59 -0000 1.22 >+++ src/org/eclipse/pde/internal/ui/shared/target/TargetContentsGroup.java 30 Nov 2010 21:03:58 -0000 >@@ -1028,10 +1028,10 @@ > if (parent == null) { > result = fAllBundles.toArray(); > } else if (fFeaureModeButton.getSelection() && parent == OTHER_CATEGORY) { >- return ((TargetDefinition) fTargetDefinition).getOtherBundles(); >+ result = ((TargetDefinition) fTargetDefinition).getOtherBundles(); > } else if (fGrouping == GROUP_BY_CONTAINER && parent instanceof IBundleContainer) { > IBundleContainer container = (IBundleContainer) parent; >- return container.getBundles(); >+ result = container.getBundles(); > } else if (fGrouping == GROUP_BY_FILE_LOC && parent instanceof IPath) { > List bundles = (List) getFileBundleMapping().get(parent); > if (bundles != null && bundles.size() > 0) { >Index: src/org/eclipse/pde/internal/ui/shared/target/TargetLocationsGroup.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/shared/target/TargetLocationsGroup.java,v >retrieving revision 1.17 >diff -u -r1.17 TargetLocationsGroup.java >--- src/org/eclipse/pde/internal/ui/shared/target/TargetLocationsGroup.java 5 Nov 2010 15:56:16 -0000 1.17 >+++ src/org/eclipse/pde/internal/ui/shared/target/TargetLocationsGroup.java 30 Nov 2010 21:03:58 -0000 >@@ -10,14 +10,11 @@ > *******************************************************************************/ > package org.eclipse.pde.internal.ui.shared.target; > >-import org.eclipse.pde.internal.core.target.UpdateTargetJob; >- > import java.util.*; > import java.util.List; > import org.eclipse.core.runtime.*; > import org.eclipse.core.runtime.jobs.IJobChangeEvent; > import org.eclipse.core.runtime.jobs.JobChangeAdapter; >-import org.eclipse.equinox.p2.engine.IProfile; > import org.eclipse.equinox.p2.metadata.IInstallableUnit; > import org.eclipse.jface.viewers.*; > import org.eclipse.jface.window.Window; >@@ -440,7 +437,7 @@ > boolean updateAllowed = false; > Iterator iter = selection.iterator(); > while (iter.hasNext()) { >- if (removeAllowed && updateAllowed){ >+ if (removeAllowed && updateAllowed) { > break; > } > Object current = iter.next(); >@@ -495,10 +492,13 @@ > } > } else if (parentElement instanceof IUBundleContainer) { > // Show the IUs as children >- // TODO See if we can get the profile using API > try { >- IProfile profile = P2TargetUtils.getProfile(fTarget); >- IInstallableUnit[] units = ((IUBundleContainer) parentElement).getInstallableUnits(profile); >+ // if this is a bundle container then we must be sure that all bundle containers are >+ // happy since they all share the same profile. >+ if (!P2TargetUtils.isResolved(fTarget)) { >+ return new Object[0]; >+ } >+ IInstallableUnit[] units = ((IUBundleContainer) parentElement).getInstallableUnits(); > // Wrap the units so that they remember their parent container > List wrappedUnits = new ArrayList(units.length); > for (int i = 0; i < units.length; i++) { >Index: src/org/eclipse/pde/internal/ui/wizards/exports/ExportTargetJob.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/wizards/exports/ExportTargetJob.java,v >retrieving revision 1.1 >diff -u -r1.1 ExportTargetJob.java >--- src/org/eclipse/pde/internal/ui/wizards/exports/ExportTargetJob.java 23 Nov 2010 18:56:29 -0000 1.1 >+++ src/org/eclipse/pde/internal/ui/wizards/exports/ExportTargetJob.java 30 Nov 2010 21:03:58 -0000 >@@ -15,13 +15,11 @@ > import org.eclipse.core.filesystem.*; > import org.eclipse.core.runtime.*; > import org.eclipse.core.runtime.jobs.Job; >-import org.eclipse.equinox.p2.engine.IProfile; > import org.eclipse.equinox.p2.internal.repository.tools.Repo2Runnable; > import org.eclipse.equinox.p2.internal.repository.tools.RepositoryDescriptor; > import org.eclipse.equinox.p2.metadata.IInstallableUnit; > import org.eclipse.equinox.p2.metadata.IProvidedCapability; > import org.eclipse.equinox.p2.query.IQueryResult; >-import org.eclipse.equinox.p2.query.QueryUtil; > import org.eclipse.pde.internal.core.feature.ExternalFeatureModel; > import org.eclipse.pde.internal.core.ifeature.IFeatureModel; > import org.eclipse.pde.internal.core.target.IUBundleContainer; >@@ -219,13 +217,12 @@ > } > > private void exportProfile(ITargetDefinition target, URI destination, IProgressMonitor monitor) throws CoreException { >- IProfile profile = P2TargetUtils.getProfile(target); > Repo2Runnable exporter = new Repo2Runnable(); >- exporter.addDestination(createRepoDescriptor(destination, profile.getProfileId(), RepositoryDescriptor.KIND_METADATA)); >- exporter.addDestination(createRepoDescriptor(destination, profile.getProfileId(), RepositoryDescriptor.KIND_ARTIFACT)); >- exporter.addSource(createRepoDescriptor(P2TargetUtils.getBundlePool(profile).getLocation(), null, RepositoryDescriptor.KIND_ARTIFACT)); >+ exporter.addDestination(createRepoDescriptor(destination, P2TargetUtils.getProfileId(target), RepositoryDescriptor.KIND_METADATA)); >+ exporter.addDestination(createRepoDescriptor(destination, P2TargetUtils.getProfileId(target), RepositoryDescriptor.KIND_ARTIFACT)); >+ exporter.addSource(createRepoDescriptor(P2TargetUtils.getBundlePool().getLocation(), null, RepositoryDescriptor.KIND_ARTIFACT)); > >- IQueryResult ius = profile.query(QueryUtil.createIUAnyQuery(), null); >+ IQueryResult ius = P2TargetUtils.getIUs(target, monitor); > ArrayList toExport = new ArrayList(); > for (Iterator i = ius.iterator(); i.hasNext();) { > IInstallableUnit iu = (IInstallableUnit) i.next(); >#P org.eclipse.pde.ui.tests >Index: src/org/eclipse/pde/ui/tests/target/IUBundleContainerTests.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/target/IUBundleContainerTests.java,v >retrieving revision 1.15 >diff -u -r1.15 IUBundleContainerTests.java >--- src/org/eclipse/pde/ui/tests/target/IUBundleContainerTests.java 5 Nov 2010 19:53:46 -0000 1.15 >+++ src/org/eclipse/pde/ui/tests/target/IUBundleContainerTests.java 30 Nov 2010 21:03:59 -0000 >@@ -10,10 +10,6 @@ > *******************************************************************************/ > package org.eclipse.pde.ui.tests.target; > >-import org.eclipse.pde.internal.core.target.P2TargetUtils; >- >-import java.util.Iterator; >- > import java.io.*; > import java.net.URI; > import java.net.URL; >@@ -23,8 +19,6 @@ > import org.eclipse.core.filesystem.URIUtil; > import org.eclipse.core.runtime.*; > import org.eclipse.equinox.internal.p2.core.helpers.URLUtil; >-import org.eclipse.equinox.p2.core.IProvisioningAgent; >-import org.eclipse.equinox.p2.engine.*; > import org.eclipse.equinox.p2.metadata.IInstallableUnit; > import org.eclipse.equinox.p2.query.IQueryResult; > import org.eclipse.equinox.p2.query.QueryUtil; >@@ -89,16 +83,16 @@ > } > > public void testResolveUsingProfile() throws Exception { >- String[] bundleIDs = new String[]{"feature.b.feature.group"}; >+ String[] features1 = new String[]{"feature.b.feature.group"}; >+ String[] features2 = new String[]{"feature.a.feature.group"}; > String[] expectedBundles = new String[]{"bundle.a1", "bundle.a2", "bundle.a3", "bundle.b1", "bundle.b2", "bundle.b3"}; >- String[] expectedBundles2 = new String[]{"bundle.b1", "bundle.b2", "bundle.b3"}; >+ String[] expectedBundles2 = new String[]{"bundle.a1", "bundle.a2", "bundle.a3"}; > > try { >- >- IUBundleContainer container = createContainer(bundleIDs); >+ // create a target that references just a high level root >+ IUBundleContainer container = createContainer(features1); > ITargetDefinition target = getTargetService().newTarget(); > target.setBundleContainers(new IBundleContainer[]{container}); >- > List infos = getAllBundleInfos(target); > Set names = collectAllSymbolicNames(infos); > assertEquals(expectedBundles.length, infos.size()); >@@ -106,24 +100,9 @@ > assertTrue("Missing: " + expectedBundles[i], names.contains(expectedBundles[i])); > } > >- IProfile profile = P2TargetUtils.getProfile(target); >- >- IProvisioningAgent agent = P2TargetUtils.getAgent(); >- IEngine engine = P2TargetUtils.getEngine(); >- IProvisioningPlan plan = engine.createPlan(profile, new ProvisioningContext(agent)); >- IQueryResult units = profile.query(QueryUtil.ALL_UNITS, null); >- for (Iterator iterator = units.iterator(); iterator.hasNext();) { >- IInstallableUnit unit = (IInstallableUnit) iterator.next(); >- if (unit.getId().startsWith("bundle.a")){ >- plan.removeInstallableUnit(unit); >- } >- } >- IPhaseSet phases = PhaseSetFactory.createDefaultPhaseSetExcluding(new String[] {PhaseSetFactory.PHASE_CHECK_TRUST, PhaseSetFactory.PHASE_CONFIGURE, PhaseSetFactory.PHASE_UNCONFIGURE}); >- IStatus result = engine.perform(plan, phases, null); >- >- assertTrue("Problem while provisioning: " + result.getMessage(), result.isOK()); >- >- target.resolve(null); // Force the target to reresolve (hopefully using the modified profile) >+ // Now modify the target to have just a lower level root. The extra higher level stuff should get removed. >+ container = createContainer(features2); >+ target.setBundleContainers(new IBundleContainer[]{container}); > infos = getAllBundleInfos(target); > names = collectAllSymbolicNames(infos); > assertEquals(expectedBundles2.length, infos.size()); >@@ -211,8 +190,8 @@ > */ > public void testContentEqualNull() throws Exception { > ITargetPlatformService service = getTargetService(); >- IUBundleContainer c3 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null); >- IUBundleContainer c4 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null); >+ IUBundleContainer c3 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null, 0); >+ IUBundleContainer c4 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null, 0); > assertTrue("Contents should be equivalent", c3.isContentEqual(c4)); > } > >@@ -223,8 +202,8 @@ > */ > public void testContentNotEqualNull() throws Exception { > ITargetPlatformService service = getTargetService(); >- IUBundleContainer c3 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null); >- IUBundleContainer c4 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.b1", "bundle.b2"}, new String[]{"1.0.0", "1.0.0"}, null); >+ IUBundleContainer c3 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null, 1); >+ IUBundleContainer c4 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.b1", "bundle.b2"}, new String[]{"1.0.0", "1.0.0"}, null, 0); > assertFalse("Contents should not be equivalent", c3.isContentEqual(c4)); > } > >@@ -356,7 +335,7 @@ > * @throws Exception > */ > protected IUBundleContainer createContainer(IInstallableUnit[] units, URI[] repositories) throws Exception { >- return (IUBundleContainer) getTargetService().newIUContainer(units, repositories); >+ return (IUBundleContainer) getTargetService().newIUContainer(units, repositories, IUBundleContainer.INCLUDE_REQUIRED); > } > > /** >@@ -473,7 +452,7 @@ > > infos = getBundleInfos(c2); > names = collectAllSymbolicNames(infos); >- bundleIds = new String[]{"bundle.b1", "bundle.b2", "bundle.b3"}; >+ bundleIds = new String[]{"bundle.a1", "bundle.a2", "bundle.a3", "bundle.b1", "bundle.b2", "bundle.b3"}; > assertEquals(bundleIds.length, infos.size()); > > for (int i = 0; i < bundleIds.length; i++) { >Index: src/org/eclipse/pde/ui/tests/target/TargetDefinitionPersistenceTests.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/target/TargetDefinitionPersistenceTests.java,v >retrieving revision 1.13 >diff -u -r1.13 TargetDefinitionPersistenceTests.java >--- src/org/eclipse/pde/ui/tests/target/TargetDefinitionPersistenceTests.java 25 Feb 2010 19:44:40 -0000 1.13 >+++ src/org/eclipse/pde/ui/tests/target/TargetDefinitionPersistenceTests.java 30 Nov 2010 21:03:59 -0000 >@@ -236,12 +236,8 @@ > IBundleContainer restrictedProfileContainer = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), null); > > // Site bundle containers with different settings >- IUBundleContainer siteContainer = (IUBundleContainer)getTargetService().newIUContainer(new IInstallableUnit[]{}, new URI[]{new URI("TESTURI"), new URI("TESTURI2")}); >- siteContainer.setIncludeAllRequired(false, null); >- siteContainer.setIncludeAllEnvironments(true, null); >- IUBundleContainer siteContainer2 = (IUBundleContainer)getTargetService().newIUContainer(new String[]{"unit1","unit2"},new String[]{"1.0", "2.0"}, new URI[]{new URI("TESTURI"), new URI("TESTURI2")}); >- siteContainer2.setIncludeAllRequired(true, null); >- siteContainer2.setIncludeAllEnvironments(false, null); >+ IUBundleContainer siteContainer = (IUBundleContainer)getTargetService().newIUContainer(new IInstallableUnit[]{}, new URI[]{new URI("TESTURI"), new URI("TESTURI2")}, IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS); >+ 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); > > NameVersionDescriptor[] restrictions = new NameVersionDescriptor[]{ > new NameVersionDescriptor("org.eclipse.jdt.launching", null), >Index: src/org/eclipse/pde/ui/tests/target/TargetDefinitionResolutionTests.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/target/TargetDefinitionResolutionTests.java,v >retrieving revision 1.16 >diff -u -r1.16 TargetDefinitionResolutionTests.java >--- src/org/eclipse/pde/ui/tests/target/TargetDefinitionResolutionTests.java 9 Nov 2010 15:40:15 -0000 1.16 >+++ src/org/eclipse/pde/ui/tests/target/TargetDefinitionResolutionTests.java 30 Nov 2010 21:03:59 -0000 >@@ -594,47 +594,49 @@ > */ > public void testSiteContainerIncludeSettings() throws Exception{ > ITargetDefinition target = getNewTarget(); >- IUBundleContainer containerA = (IUBundleContainer)getTargetService().newIUContainer(new IInstallableUnit[0], null); >- IUBundleContainer containerB = (IUBundleContainer)getTargetService().newIUContainer(new String[]{"unit1", "unit2"}, new String[]{"1.0","2.0"}, null); >+ IUBundleContainer containerA = (IUBundleContainer)getTargetService().newIUContainer(new IInstallableUnit[0], null, IUBundleContainer.INCLUDE_REQUIRED); >+ IUBundleContainer containerB = (IUBundleContainer)getTargetService().newIUContainer(new String[]{"unit1", "unit2"}, new String[]{"1.0","2.0"}, null, IUBundleContainer.INCLUDE_REQUIRED); > target.setBundleContainers(new IBundleContainer[]{containerA, containerB}); > > // Check default settings > assertTrue(containerA.getIncludeAllRequired()); > assertFalse(containerA.getIncludeAllEnvironments()); >+ assertFalse(containerA.getIncludeSource()); > assertTrue(containerB.getIncludeAllRequired()); > assertFalse(containerB.getIncludeAllEnvironments()); >+ assertFalse(containerB.getIncludeSource()); > > // Check basic changes >- containerA.setIncludeAllRequired(false, null); >- containerA.setIncludeAllEnvironments(true, null); >+ int flags = IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS | IUBundleContainer.INCLUDE_SOURCE; >+ containerA = (IUBundleContainer)getTargetService().newIUContainer(new IInstallableUnit[0], null, flags); >+ containerB = (IUBundleContainer)getTargetService().newIUContainer(new String[]{"unit1", "unit2"}, new String[]{"1.0","2.0"}, null, flags); >+ target.setBundleContainers(new IBundleContainer[]{containerA, containerB}); > assertFalse(containerA.getIncludeAllRequired()); > assertTrue(containerA.getIncludeAllEnvironments()); >- containerA.setIncludeAllEnvironments(false, null); >- containerA.setIncludeAllRequired(true, null); >- assertTrue(containerA.getIncludeAllRequired()); >- assertFalse(containerA.getIncludeAllEnvironments()); >+ assertTrue(containerA.getIncludeSource()); > > // Check that all containers are updated in the target if target is passed as argument >- containerA.setIncludeAllRequired(false, target); >- assertFalse(containerA.getIncludeAllRequired()); >- assertFalse(containerA.getIncludeAllEnvironments()); >- assertFalse(containerB.getIncludeAllRequired()); >- assertFalse(containerB.getIncludeAllEnvironments()); >- containerB.setIncludeAllRequired(true, target); >+ flags = IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS | IUBundleContainer.INCLUDE_SOURCE; >+ containerA = (IUBundleContainer)getTargetService().newIUContainer(new IInstallableUnit[0], null, flags); >+ flags = IUBundleContainer.INCLUDE_REQUIRED; >+ containerB = (IUBundleContainer)getTargetService().newIUContainer(new String[]{"unit1", "unit2"}, new String[]{"1.0","2.0"}, null, flags); >+ >+ target.setBundleContainers(new IBundleContainer[]{containerA, containerB}); > assertTrue(containerA.getIncludeAllRequired()); > assertFalse(containerA.getIncludeAllEnvironments()); >+ assertFalse(containerA.getIncludeSource()); > assertTrue(containerB.getIncludeAllRequired()); > assertFalse(containerB.getIncludeAllEnvironments()); >- containerA.setIncludeAllEnvironments(true, target); >- assertTrue(containerA.getIncludeAllRequired()); >+ assertFalse(containerB.getIncludeSource()); >+ >+ // now switch the order of A and B >+ target.setBundleContainers(new IBundleContainer[]{containerB, containerA}); >+ assertFalse(containerA.getIncludeAllRequired()); > assertTrue(containerA.getIncludeAllEnvironments()); >- assertTrue(containerB.getIncludeAllRequired()); >+ assertTrue(containerA.getIncludeSource()); >+ assertFalse(containerB.getIncludeAllRequired()); > assertTrue(containerB.getIncludeAllEnvironments()); >- containerB.setIncludeAllEnvironments(false, target); >- assertTrue(containerA.getIncludeAllRequired()); >- assertFalse(containerA.getIncludeAllEnvironments()); >- assertTrue(containerB.getIncludeAllRequired()); >- assertFalse(containerB.getIncludeAllEnvironments()); >+ assertTrue(containerB.getIncludeSource()); > } > > public void testNameVersionDescriptor() {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 331068
:
183810
|
184066
|
184185
|
184195
|
184217
|
184319
|
184374