### 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 2 Dec 2010 02:34:53 -0000
@@ -41,12 +41,12 @@
/**
* Resolved bundles or null
if unresolved
*/
- private IResolvedBundle[] fBundles;
+ protected IResolvedBundle[] fBundles;
/**
* List of features contained in this bundle container or null
if unresolved
*/
- private IFeatureModel[] fFeatures;
+ protected IFeatureModel[] fFeatures;
/**
* Status generated when this container was resolved, possibly null
@@ -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 2 Dec 2010 02:34:53 -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 null
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. null
if not resolved.
+ * IU identifiers.
*/
- private NameVersionDescriptor[] fFeatures;
+ private String[] fIds;
/**
- * Repositories to consider, or null
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.
- *
- * true
by default
- *
null
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.
- *
- * false
by default
- *
null
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.
- *
- * false
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 true
. 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 null
if
- * default set
+ * @param repositories metadata repositories used to search for IU's or null
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 null
if
- * default set
+ * @param repositories metadata repositories used to search for IU's or null
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
-
- // 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]);
- }
+ // Now get feature models for all known features
+ TargetDefinition definition = (TargetDefinition) fSynchronizer.getTargetDefinition();
+ IFeatureModel[] allFeatures = definition.getFeatureModels(getLocation(false), new NullProgressMonitor());
- 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 null
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 null
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 null
if not found.
- * @param queryable location to look for source IUs
- * @return the source IU or null
- */
- 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;
+ return fBundles = null;
}
- removeDuplicateBundles(definition, bundles);
- if (bundles.isEmpty()) {
- return 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,24 +297,25 @@
*
* @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());
+ public synchronized int update(Set toUpdate, IProgressMonitor monitor) throws CoreException {
+ SubMonitor progress = SubMonitor.convert(monitor, 100);
+ IQueryable source = P2TargetUtils.getQueryableMetadata(fRepos, progress.newChild(30));
int dirty = 0;
int updated = 0;
+ SubMonitor loopProgress = progress.newChild(70).setWorkRemaining(fIds.length);
for (int i = 0; i < fIds.length; i++) {
if (!toUpdate.isEmpty() && !toUpdate.contains(fIds[i]))
continue;
IQuery query = QueryUtil.createLatestQuery(QueryUtil.createIUQuery(fIds[i]));
- IQueryResult queryResult = source.query(query, null);
+ IQueryResult queryResult = source.query(query, loopProgress.newChild(1));
Iterator it = queryResult.iterator();
// bail if the feature is no longer available.
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;
@@ -822,34 +326,16 @@
}
}
}
+ if (updated == UpdateTargetJob.UPDATED) {
+ // Things have changed so mark the container as unresolved
+ clearResolutionStatus();
+ }
return dirty | updated;
}
- /**
- * 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());
- }
- }
- }
- }
+ protected void clearResolutionStatus() {
+ super.clearResolutionStatus();
+ fSynchronizer.markDirty();
}
/**
@@ -857,56 +343,60 @@
* bundles. A IResolvedBundle is created for each and a map containing all results
* mapping BundleInfo to IResolvedBundle is returned.
*
- * If there is an artifact missing for a unit it will either be ignored (not added to the returned map),
- * or null
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.
*
true
ius that have missing artifacts will be ignored and not added to the map, if false
, null
will be returned
- * @return map of BundleInfo to IResolvedBundle or null
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 +437,24 @@
}
/**
- * Returns the repositories to consider when resolving IU's (will return default set of
- * repositories if current repository settings are null
).
- *
- * @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 null
).
+ * 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 true
- * 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 false
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.
- * - * 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. - *
- * @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 benull
- */
- 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 +468,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()}).
- * - * 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. - *
- * @param include whether environment specific units should be included - * @param definition parent target, used to update other IUBundleContainers with this setting, can benull
- */
- 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 +483,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 +496,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 +532,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 2 Dec 2010 02:34:53 -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 2 Dec 2010 02:34:53 -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 2 Dec 2010 02:34:53 -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,63 @@
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.
+ *
+ * true
by default
+ *
+ * false
by default
+ *
+ * false
by default
+ */
+ private boolean fIncludeSource = false;
+
+ /**
+ * Whether or not this synchronizer is dirty by means other than target tweaks etc.
+ */
+ private boolean fDirty = 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 +159,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 +220,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 +235,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 +266,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 +312,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 +344,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 +398,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 +415,333 @@
}
/**
- * 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;
+ }
+
+ if (fDirty)
+ 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 true
+ * 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 false
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.
+ *
+ * Since there is only one profile per target and the planner and slicer resolve methods are incompatible. + *
+ * @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. Whentrue
+ * 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 false
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()}).
+ * + * There is only one profile per target and this setting can only be set for the + * entire target definition. + *
+ * @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. + *+ * The synchronizer is an instance of {@link P2TargetUtils} that has access to the + * profile and other p2 bits for the target. + *
+ * + * @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 { + SubMonitor progress = SubMonitor.convert(monitor, 100); + + // 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(progress.newChild(25)); + return; + } + } else if (checkProfile()) { + return; + } + + // Either no profile was found or it was stale. Delete the current profile and recreate. + // This keeps the internal agent data clean and does not cost us much. + deleteProfile(fTarget.getHandle()); + createProfile(); + + if (progress.isCanceled()) + return; + progress.setWorkRemaining(75); + + // Now resolve the profile and refresh the relate IU containers + if (getIncludeAllRequired()) + resolveWithPlanner(progress.newChild(60)); + else + resolveWithSlicer(progress.newChild(60)); + + // If we are updating a profile then delete the old snapshot on success. + notify(progress.newChild(15)); + fDirty = false; + } + + 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 +759,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 ornull
*
* @return profile registry or null
@@ -485,20 +794,8 @@
*
* @return provisioning mode or null
*/
- 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 +813,590 @@
}
/**
- * 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);
+ }
+
+ /**
+ * 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 monitor for reporting progress
+ * @throws CoreException if there is a problem with the requirements or there is a problem downloading
+ */
+ private void resolveWithPlanner(IProgressMonitor monitor) throws CoreException {
+ SubMonitor subMonitor = SubMonitor.convert(monitor, 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, subMonitor.newChild(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, subMonitor.newChild(100));
+ 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.newChild(60));
+ } 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;
+ }
+ }
+
+ 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 {
+ SubMonitor subMonitor = SubMonitor.convert(monitor, "Provisioning source bundles", 100);
+
+ // 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, subMonitor.newChild(25));
+ 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, subMonitor.newChild(75));
+
+ 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);
+ }
+
+ // 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 {
+ SubMonitor subMonitor = SubMonitor.convert(monitor, Messages.IUBundleContainer_0, 100);
+
+ // 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.newChild(10));
+
+ // do an initial slice to add everything the user requested
+ IQueryResult queryResult = slice(units, allMetadata, fTarget, subMonitor.newChild(10));
+ 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.newChild(10));
+ 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());
+ }
+
+ if (subMonitor.isCanceled()) {
+ return;
+ }
+ subMonitor.worked(10);
+
+ // execute the provisioning plan
+ IPhaseSet phases = createPhaseSet();
+ IStatus result = engine.perform(plan, phases, subMonitor.newChild(60));
+ if (!result.isOK()) {
+ throw new CoreException(result);
+ }
+ }
+
+ private IQueryResult slice(IInstallableUnit[] units, IQueryable allMetadata, ITargetDefinition definition, IProgressMonitor monitor) throws CoreException {
+ SubMonitor subMonitor = SubMonitor.convert(monitor, 100);
+ // 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, subMonitor.newChild(50));
+ if (!slicer.getStatus().isOK()) {
+ throw new CoreException(slicer.getStatus());
+ }
+ IQueryResult queryResult = null;
+ if (slice != null)
+ queryResult = slice.query(QueryUtil.createIUAnyQuery(), subMonitor.newChild(50));
+ return queryResult;
+ }
+
+ /**
+ * Returns the artifact repositories to consider when getting artifacts. Returns a default set of
+ * repositories if current repository settings are null
).
+ *
+ * @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();
+ 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()]);
}
/**
- * Returns whether software site containers are configured to provision for all environments
- * versus a single environment.
+ * 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.
*
- * @return whether all environments will be provisioned
+ * @param additionalRepos the set to which additional repos are added.
*/
- private static boolean isAllEnvironments(ITargetDefinition target) {
+ 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 (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 null
).
+ *
+ * @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();
- 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;
- }
+ 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 false;
}
+ /**
+ * @return the profile associated with this synchronizer
+ */
+ IProfile getProfile() {
+ return fProfile;
+ }
+
+ /**
+ * @return the target definition associated with this synchronizer
+ */
+ ITargetDefinition getTargetDefinition() {
+ return fTarget;
+ }
+
+ void markDirty() {
+ fDirty = true;
+ }
}
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 2 Dec 2010 02:34:54 -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 null
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 2 Dec 2010 02:34:54 -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 2 Dec 2010 02:34:54 -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 2 Dec 2010 02:34:54 -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 2 Dec 2010 02:34:54 -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/UpdateTargetJob.java
===================================================================
RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/UpdateTargetJob.java,v
retrieving revision 1.1
diff -u -r1.1 UpdateTargetJob.java
--- src/org/eclipse/pde/internal/core/target/UpdateTargetJob.java 5 Nov 2010 15:56:16 -0000 1.1
+++ src/org/eclipse/pde/internal/core/target/UpdateTargetJob.java 2 Dec 2010 02:34:54 -0000
@@ -73,17 +73,16 @@
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
*/
protected IStatus run(IProgressMonitor monitor) {
- int totalWork = toUpdate.size();
+ SubMonitor progress = SubMonitor.convert(monitor, Messages.UpdateTargetJob_UpdatingTarget, toUpdate.size());
result = 0;
try {
- monitor.beginTask(Messages.UpdateTargetJob_UpdatingTarget, totalWork);
for (Iterator i = toUpdate.entrySet().iterator(); i.hasNext();) {
try {
Map.Entry entry = (Map.Entry) i.next();
IBundleContainer container = (IBundleContainer) entry.getKey();
monitor.subTask(NLS.bind(Messages.UpdateTargetJob_UpdatingContainer, ((AbstractBundleContainer) container).getLocation(false)));
if (container instanceof IUBundleContainer)
- result |= ((IUBundleContainer) container).update((Set) entry.getValue());
+ result |= ((IUBundleContainer) container).update((Set) entry.getValue(), progress.newChild(1));
} catch (CoreException e1) {
return e1.getStatus();
} finally {
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 2 Dec 2010 02:34:54 -0000
@@ -320,4 +320,13 @@
* @return implicit dependencies or null
*/
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 2 Dec 2010 02:34:54 -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 null
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 null
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 2 Dec 2010 02:34:55 -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 2 Dec 2010 02:34:55 -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 2 Dec 2010 02:34:55 -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 2 Dec 2010 02:34:56 -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 2 Dec 2010 02:34:56 -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 2 Dec 2010 02:34:56 -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 2 Dec 2010 02:34:56 -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 2 Dec 2010 02:34:56 -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;
@@ -423,8 +420,6 @@
// do nothing if we could not see the current target.
}
updateButtons();
- // XXX still need to figure how to mark the target as dirty so it gets persisted.
- // right now it seems to always be dirty
}
});
}
@@ -440,7 +435,7 @@
boolean updateAllowed = false;
Iterator iter = selection.iterator();
while (iter.hasNext()) {
- if (removeAllowed && updateAllowed){
+ if (removeAllowed && updateAllowed) {
break;
}
Object current = iter.next();
@@ -495,10 +490,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 2 Dec 2010 02:34:56 -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 2 Dec 2010 02:34:57 -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 2 Dec 2010 02:34:57 -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 2 Dec 2010 02:34:57 -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() {