diff options
17 files changed, 343 insertions, 144 deletions
diff --git a/bundles/org.eclipse.equinox.p2.director.app/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.director.app/META-INF/MANIFEST.MF index 140fafc36..65c8e1515 100644 --- a/bundles/org.eclipse.equinox.p2.director.app/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.p2.director.app/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.equinox.p2.director.app;singleton:=true -Bundle-Version: 1.1.100.qualifier +Bundle-Version: 1.1.200.qualifier Bundle-Activator: org.eclipse.equinox.internal.p2.director.app.Activator Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/bundles/org.eclipse.equinox.p2.director.app/pom.xml b/bundles/org.eclipse.equinox.p2.director.app/pom.xml index bc1a5ff76..cf0655b36 100644 --- a/bundles/org.eclipse.equinox.p2.director.app/pom.xml +++ b/bundles/org.eclipse.equinox.p2.director.app/pom.xml @@ -9,6 +9,6 @@ </parent> <groupId>org.eclipse.equinox</groupId> <artifactId>org.eclipse.equinox.p2.director.app</artifactId> - <version>1.1.100-SNAPSHOT</version> + <version>1.1.200-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DefaultLog.java b/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DefaultLog.java index 651d56bc5..fcffbff1b 100644 --- a/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DefaultLog.java +++ b/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DefaultLog.java @@ -19,7 +19,7 @@ public class DefaultLog implements ILog, Closeable { public void log(IStatus status) { LogHelper.log(status); - if (!status.isOK()) { + if (status.getSeverity() == IStatus.ERROR) { failed = true; } } @@ -54,6 +54,6 @@ public class DefaultLog implements ILog, Closeable { return; } - printErr("Failures loggaed in file: " + fwLog.getFile()); //$NON-NLS-1$ + printErr("There were errors. See log file: " + fwLog.getFile()); //$NON-NLS-1$ } } diff --git a/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DirectorApplication.java b/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DirectorApplication.java index a341ae3b7..259f7e833 100644 --- a/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DirectorApplication.java +++ b/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DirectorApplication.java @@ -17,15 +17,45 @@ *******************************************************************************/ package org.eclipse.equinox.internal.p2.director.app; -import java.io.*; +import static org.eclipse.core.runtime.IStatus.ERROR; +import static org.eclipse.core.runtime.IStatus.INFO; +import static org.eclipse.core.runtime.IStatus.OK; +import static org.eclipse.core.runtime.IStatus.WARNING; +import static org.eclipse.equinox.internal.p2.director.app.Activator.ID; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; import java.net.URI; import java.net.URISyntaxException; import java.security.cert.Certificate; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.EventObject; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; import java.util.stream.Collectors; import java.util.stream.IntStream; -import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.URIUtil; import org.eclipse.equinox.app.IApplication; import org.eclipse.equinox.app.IApplicationContext; import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper; @@ -37,21 +67,37 @@ import org.eclipse.equinox.internal.provisional.p2.core.eventbus.ProvisioningLis import org.eclipse.equinox.internal.provisional.p2.director.IDirector; import org.eclipse.equinox.internal.provisional.p2.director.PlanExecutionHelper; import org.eclipse.equinox.internal.provisional.p2.repository.RepositoryEvent; -import org.eclipse.equinox.p2.core.*; -import org.eclipse.equinox.p2.engine.*; +import org.eclipse.equinox.p2.core.IProvisioningAgent; +import org.eclipse.equinox.p2.core.IProvisioningAgentProvider; +import org.eclipse.equinox.p2.core.ProvisionException; +import org.eclipse.equinox.p2.core.UIServices; +import org.eclipse.equinox.p2.engine.IEngine; +import org.eclipse.equinox.p2.engine.IProfile; +import org.eclipse.equinox.p2.engine.IProfileRegistry; +import org.eclipse.equinox.p2.engine.IProvisioningPlan; +import org.eclipse.equinox.p2.engine.PhaseSetFactory; +import org.eclipse.equinox.p2.engine.ProvisioningContext; import org.eclipse.equinox.p2.engine.query.UserVisibleRootQuery; -import org.eclipse.equinox.p2.metadata.*; +import org.eclipse.equinox.p2.metadata.IInstallableUnit; +import org.eclipse.equinox.p2.metadata.IVersionedId; import org.eclipse.equinox.p2.metadata.Version; import org.eclipse.equinox.p2.metadata.VersionRange; +import org.eclipse.equinox.p2.metadata.VersionedId; 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.query.Collector; +import org.eclipse.equinox.p2.query.IQuery; +import org.eclipse.equinox.p2.query.IQueryResult; +import org.eclipse.equinox.p2.query.IQueryable; +import org.eclipse.equinox.p2.query.QueryUtil; import org.eclipse.equinox.p2.repository.IRepository; import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager; import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager; import org.eclipse.osgi.service.environment.EnvironmentInfo; import org.eclipse.osgi.util.NLS; -import org.osgi.framework.*; +import org.osgi.framework.BundleContext; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; public class DirectorApplication implements IApplication, ProvisioningListener { public static class AvoidTrustPromptService extends UIServices { @@ -298,14 +344,14 @@ public class DirectorApplication implements IApplication, ProvisioningListener { private Properties loadProperties(File file) { if (!file.exists()) { // log a warning and return - log.log(new Status(IStatus.WARNING, Activator.ID, NLS.bind(Messages.File_does_not_exist, file.getAbsolutePath()))); + log.log(new Status(WARNING, ID, NLS.bind(Messages.File_does_not_exist, file.getAbsolutePath()))); return null; } Properties properties = new Properties(); try (InputStream input = new BufferedInputStream(new FileInputStream(file))) { properties.load(input); } catch (IOException e) { - log.log(new Status(IStatus.ERROR, Activator.ID, NLS.bind(Messages.Problem_loading_file, file.getAbsolutePath()), e)); + log.log(new Status(ERROR, ID, NLS.bind(Messages.Problem_loading_file, file.getAbsolutePath()), e)); return null; } return properties; @@ -345,10 +391,10 @@ public class DirectorApplication implements IApplication, ProvisioningListener { // skip over the keyword id = line.substring(0, index); } catch (NumberFormatException e) { - log.log(new Status(IStatus.WARNING, Activator.ID, NLS.bind(Messages.Bad_format, line, iuProfileProperties), e)); + log.log(new Status(WARNING, ID, NLS.bind(Messages.Bad_format, line, iuProfileProperties), e)); continue; } catch (IndexOutOfBoundsException e) { - log.log(new Status(IStatus.WARNING, Activator.ID, NLS.bind(Messages.Bad_format, line, iuProfileProperties), e)); + log.log(new Status(WARNING, ID, NLS.bind(Messages.Bad_format, line, iuProfileProperties), e)); continue; } @@ -370,7 +416,7 @@ public class DirectorApplication implements IApplication, ProvisioningListener { if (key == null || value == null) { String message = NLS.bind(Messages.Unmatched_iu_profile_property_key_value, key + '/' + value); - log.log(new Status(IStatus.WARNING, Activator.ID, message)); + log.log(new Status(WARNING, ID, message)); continue; } @@ -382,7 +428,7 @@ public class DirectorApplication implements IApplication, ProvisioningListener { IQueryResult<IInstallableUnit> qr = getInstallableUnits(null, query, null); if (qr.isEmpty()) { String msg = NLS.bind(Messages.Cannot_set_iu_profile_property_iu_does_not_exist, id + '/' + version); - log.log(new Status(IStatus.WARNING, Activator.ID, msg)); + log.log(new Status(WARNING, ID, msg)); continue; } IInstallableUnit iu = qr.iterator().next(); @@ -429,7 +475,7 @@ public class DirectorApplication implements IApplication, ProvisioningListener { Iterator<IInstallableUnit> itor = roots.iterator(); if (!itor.hasNext()) - throw new CoreException(new Status(IStatus.ERROR, org.eclipse.equinox.internal.p2.director.app.Activator.ID, NLS.bind(Messages.Missing_IU, rootQuery))); + throw new CoreException(new Status(ERROR, ID, NLS.bind(Messages.Missing_IU, rootQuery))); do { allRoots.add(itor.next()); } while (itor.hasNext()); @@ -725,26 +771,35 @@ public class DirectorApplication implements IApplication, ProvisioningListener { boolean wasRoaming = Boolean.parseBoolean(profile.getProperty(IProfile.PROP_ROAMING)); try { updateRoamingProperties(profile); + ProvisioningContext context = new ProvisioningContext(targetAgent); - context.setMetadataRepositories(metadataRepositoryLocations.toArray(new URI[metadataRepositoryLocations.size()])); - context.setArtifactRepositories(artifactRepositoryLocations.toArray(new URI[artifactRepositoryLocations.size()])); + context.setMetadataRepositories(metadataRepositoryLocations.stream().toArray(URI[]::new)); + context.setArtifactRepositories(artifactRepositoryLocations.stream().toArray(URI[]::new)); context.setProperty(ProvisioningContext.FOLLOW_REPOSITORY_REFERENCES, String.valueOf(followReferences)); context.setProperty(FOLLOW_ARTIFACT_REPOSITORY_REFERENCES, String.valueOf(followReferences)); + ProfileChangeRequest request = buildProvisioningRequest(profile, installs, uninstalls); printRequest(request); + planAndExecute(profile, context, request); } finally { // if we were originally were set to be roaming and we changed it, change it back before we return - if (wasRoaming && !Boolean.parseBoolean(profile.getProperty(IProfile.PROP_ROAMING))) + if (wasRoaming && !Boolean.parseBoolean(profile.getProperty(IProfile.PROP_ROAMING))) { setRoaming(profile); + } } } private void planAndExecute(IProfile profile, ProvisioningContext context, ProfileChangeRequest request) throws CoreException { IProvisioningPlan result = planner.getProvisioningPlan(request, context, new NullProgressMonitor()); + IStatus operationStatus = result.getStatus(); - if (!operationStatus.isOK()) + if (!operationStatus.isOK()) { throw new CoreException(operationStatus); + } + + log.log(operationStatus); + executePlan(context, result); } @@ -760,16 +815,17 @@ public class DirectorApplication implements IApplication, ProvisioningListener { operationStatus = PlanExecutionHelper.executePlan(result, engine, PhaseSetFactory.createPhaseSetIncluding(new String[] {PhaseSetFactory.PHASE_COLLECT, PhaseSetFactory.PHASE_CHECK_TRUST}), context, new NullProgressMonitor()); switch (operationStatus.getSeverity()) { - case IStatus.OK : + case OK : break; - case IStatus.INFO : - case IStatus.WARNING : + case INFO : + case WARNING : log.log(operationStatus); break; - //. All other status codes correspond to IStatus.isOk() == false + // All other status codes correspond to IStatus.isOk() == false default : - if (noArtifactRepositorySpecified && hasNoRepositoryFound(operationStatus)) + if (noArtifactRepositorySpecified && hasNoRepositoryFound(operationStatus)) { throw new ProvisionException(Messages.Application_NoRepositories); + } throw new CoreException(operationStatus); } @@ -1062,10 +1118,12 @@ public class DirectorApplication implements IApplication, ProvisioningListener { } return IApplication.EXIT_OK; } catch (CoreException e) { + IStatus error = e.getStatus(); + log.printOut(Messages.Operation_failed); - printError(e.getStatus(), 0); + printError(error, 0); - log.log(e.getStatus()); + log.log(error); //set empty exit data to suppress error dialog from launcher setSystemProperty("eclipse.exitdata", ""); //$NON-NLS-1$ //$NON-NLS-2$ @@ -1101,7 +1159,7 @@ public class DirectorApplication implements IApplication, ProvisioningListener { } if (targetProfile == null) - throw new CoreException(new Status(IStatus.ERROR, Activator.ID, Messages.Missing_profile)); + throw new CoreException(new Status(ERROR, ID, Messages.Missing_profile)); IProvisioningPlan plan = planner.getDiffPlan(profile, targetProfile, new NullProgressMonitor()); ProvisioningContext context = new ProvisioningContext(targetAgent); @@ -1241,7 +1299,7 @@ public class DirectorApplication implements IApplication, ProvisioningListener { IProvisioningPlan result = planner.getProvisioningPlan(request, context, new NullProgressMonitor()); IStatus status = PlanExecutionHelper.executePlan(result, engine, context, new NullProgressMonitor()); if (!status.isOK()) - throw new CoreException(new MultiStatus(Activator.ID, IStatus.ERROR, new IStatus[] {status}, NLS.bind(Messages.Cant_change_roaming, profile.getProfileId()), null)); + throw new CoreException(new MultiStatus(ID, ERROR, new IStatus[] {status}, NLS.bind(Messages.Cant_change_roaming, profile.getProfileId()), null)); } @Override diff --git a/bundles/org.eclipse.equinox.p2.director/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.director/META-INF/MANIFEST.MF index 343dfeb04..61808e78e 100644 --- a/bundles/org.eclipse.equinox.p2.director/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.p2.director/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.equinox.p2.director;singleton:=true -Bundle-Version: 2.4.0.qualifier +Bundle-Version: 2.4.100.qualifier Bundle-ClassPath: . Bundle-Activator: org.eclipse.equinox.internal.p2.director.DirectorActivator Bundle-Vendor: %providerName diff --git a/bundles/org.eclipse.equinox.p2.director/pom.xml b/bundles/org.eclipse.equinox.p2.director/pom.xml index 2133c3f72..14535ebdd 100644 --- a/bundles/org.eclipse.equinox.p2.director/pom.xml +++ b/bundles/org.eclipse.equinox.p2.director/pom.xml @@ -9,6 +9,6 @@ </parent> <groupId>org.eclipse.equinox</groupId> <artifactId>org.eclipse.equinox.p2.director</artifactId> - <version>2.4.0-SNAPSHOT</version> + <version>2.4.100-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Explanation.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Explanation.java index 3e6a0de98..0d2c46a41 100644 --- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Explanation.java +++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Explanation.java @@ -11,8 +11,12 @@ package org.eclipse.equinox.internal.p2.director; import java.util.Arrays; -import org.eclipse.core.runtime.*; -import org.eclipse.equinox.p2.metadata.*; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.equinox.p2.metadata.IInstallableUnit; +import org.eclipse.equinox.p2.metadata.IInstallableUnitPatch; +import org.eclipse.equinox.p2.metadata.IRequirement; import org.eclipse.osgi.util.NLS; public abstract class Explanation implements Comparable<Explanation> { @@ -331,7 +335,7 @@ public abstract class Explanation implements Comparable<Explanation> { return new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, toString()); } - protected String getUserReadableName(IInstallableUnit iu) { + protected static String getUserReadableName(IInstallableUnit iu) { if (iu == null) return ""; //$NON-NLS-1$ String result = getLocalized(iu); @@ -340,7 +344,7 @@ public abstract class Explanation implements Comparable<Explanation> { return result + ' ' + iu.getVersion() + " (" + iu.toString() + ')'; //$NON-NLS-1$ } - private String getLocalized(IInstallableUnit iu) { + private static String getLocalized(IInstallableUnit iu) { String value = iu.getProperty(IInstallableUnit.PROP_NAME); if (value == null || value.length() <= 1 || value.charAt(0) != '%') return value; diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Messages.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Messages.java index 2f2ba8170..b73372881 100644 --- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Messages.java +++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Messages.java @@ -29,6 +29,9 @@ public class Messages extends NLS { public static String Director_Task_Updating; public static String Director_Task_Resolving_Dependencies; public static String Director_Unsatisfied_Dependencies; + public static String Director_Satisfied_Dependencies; + public static String Director_Satisfied_Change; + public static String Director_Unsatisfied_Change; public static String Director_error_applying_configuration; public static String Director_For_Target; public static String Director_For_Target_Unselect_Required; diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/SimplePlanner.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/SimplePlanner.java index 7b1238e9b..edba6ad29 100644 --- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/SimplePlanner.java +++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/SimplePlanner.java @@ -12,13 +12,39 @@ ******************************************************************************/ package org.eclipse.equinox.internal.p2.director; +import static org.eclipse.core.runtime.IStatus.CANCEL; +import static org.eclipse.core.runtime.IStatus.ERROR; +import static org.eclipse.core.runtime.IStatus.INFO; +import static org.eclipse.core.runtime.IStatus.OK; +import static org.eclipse.equinox.internal.p2.director.DirectorActivator.PI_DIRECTOR; +import static org.eclipse.equinox.internal.provisional.p2.director.RequestStatus.ADDED; +import static org.eclipse.equinox.internal.provisional.p2.director.RequestStatus.REMOVED; + import java.lang.reflect.Method; import java.net.URI; -import java.util.*; -import org.eclipse.core.runtime.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.stream.Stream; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; import org.eclipse.equinox.internal.p2.core.helpers.LogHelper; import org.eclipse.equinox.internal.p2.core.helpers.Tracing; import org.eclipse.equinox.internal.p2.director.Explanation.MissingIU; +import org.eclipse.equinox.internal.p2.director.Explanation.Singleton; import org.eclipse.equinox.internal.p2.metadata.IRequiredCapability; import org.eclipse.equinox.internal.p2.metadata.query.UpdateQuery; import org.eclipse.equinox.internal.p2.rollback.FormerState; @@ -26,12 +52,28 @@ import org.eclipse.equinox.internal.provisional.p2.director.PlannerStatus; import org.eclipse.equinox.internal.provisional.p2.director.RequestStatus; import org.eclipse.equinox.p2.core.IAgentLocation; import org.eclipse.equinox.p2.core.IProvisioningAgent; -import org.eclipse.equinox.p2.engine.*; +import org.eclipse.equinox.p2.engine.IEngine; +import org.eclipse.equinox.p2.engine.IProfile; +import org.eclipse.equinox.p2.engine.IProfileRegistry; +import org.eclipse.equinox.p2.engine.IProvisioningPlan; +import org.eclipse.equinox.p2.engine.ProvisioningContext; import org.eclipse.equinox.p2.engine.query.IUProfilePropertyQuery; -import org.eclipse.equinox.p2.metadata.*; +import org.eclipse.equinox.p2.metadata.IInstallableUnit; +import org.eclipse.equinox.p2.metadata.IProvidedCapability; +import org.eclipse.equinox.p2.metadata.IRequirement; +import org.eclipse.equinox.p2.metadata.MetadataFactory; import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription; -import org.eclipse.equinox.p2.planner.*; -import org.eclipse.equinox.p2.query.*; +import org.eclipse.equinox.p2.metadata.Version; +import org.eclipse.equinox.p2.metadata.VersionRange; +import org.eclipse.equinox.p2.planner.IPlanner; +import org.eclipse.equinox.p2.planner.IProfileChangeRequest; +import org.eclipse.equinox.p2.planner.ProfileInclusionRules; +import org.eclipse.equinox.p2.query.CollectionResult; +import org.eclipse.equinox.p2.query.CompoundQueryable; +import org.eclipse.equinox.p2.query.IQuery; +import org.eclipse.equinox.p2.query.IQueryResult; +import org.eclipse.equinox.p2.query.IQueryable; +import org.eclipse.equinox.p2.query.QueryUtil; import org.eclipse.osgi.util.NLS; public class SimplePlanner implements IPlanner { @@ -69,11 +111,12 @@ public class SimplePlanner implements IPlanner { } } - Map<IInstallableUnit, RequestStatus>[] changes = computeActualChangeRequest(toState, changeRequest); + Map<IInstallableUnit, RequestStatus>[] changes = buildDetailedSuccess(toState, changeRequest); Map<IInstallableUnit, RequestStatus> requestChanges = (changes == null) ? null : changes[0]; Map<IInstallableUnit, RequestStatus> requestSideEffects = (changes == null) ? null : changes[1]; + IStatus status = convertChangesToStatus(requestChanges, requestSideEffects); QueryableArray plannedState = new QueryableArray(toState.toArray(new IInstallableUnit[toState.size()])); - PlannerStatus plannerStatus = new PlannerStatus(Status.OK_STATUS, null, requestChanges, requestSideEffects, plannedState); + PlannerStatus plannerStatus = new PlannerStatus(status, null, requestChanges, requestSideEffects, plannedState); plan.setStatus(plannerStatus); plan.setInstallerPlan(installerPlan); return plan; @@ -82,36 +125,33 @@ public class SimplePlanner implements IPlanner { private Map<IInstallableUnit, RequestStatus>[] buildDetailedErrors(ProfileChangeRequest changeRequest) { Collection<IInstallableUnit> requestedAdditions = changeRequest.getAdditions(); Collection<IInstallableUnit> requestedRemovals = changeRequest.getRemovals(); - Map<IInstallableUnit, RequestStatus> requestStatus = new HashMap<>(requestedAdditions.size() + requestedAdditions.size()); + Map<IInstallableUnit, RequestStatus> requestStatus = new HashMap<>(requestedAdditions.size() + requestedRemovals.size()); for (IInstallableUnit added : requestedAdditions) { - requestStatus.put(added, new RequestStatus(added, RequestStatus.ADDED, IStatus.ERROR, null)); + requestStatus.put(added, new RequestStatus(added, ADDED, ERROR, null)); } for (IInstallableUnit removed : requestedRemovals) { - requestStatus.put(removed, new RequestStatus(removed, RequestStatus.REMOVED, IStatus.ERROR, null)); + requestStatus.put(removed, new RequestStatus(removed, REMOVED, ERROR, null)); } @SuppressWarnings("unchecked") Map<IInstallableUnit, RequestStatus>[] maps = new Map[] {requestStatus, null}; return maps; } - private Map<IInstallableUnit, RequestStatus>[] computeActualChangeRequest(Collection<IInstallableUnit> toState, ProfileChangeRequest changeRequest) { + private Map<IInstallableUnit, RequestStatus>[] buildDetailedSuccess(Collection<IInstallableUnit> toState, ProfileChangeRequest changeRequest) { Collection<IInstallableUnit> requestedAdditions = changeRequest.getAdditions(); Collection<IInstallableUnit> requestedRemovals = new ArrayList<>(changeRequest.getRemovals()); requestedRemovals.removeAll(requestedAdditions); Map<IInstallableUnit, RequestStatus> requestStatus = new HashMap<>(requestedAdditions.size() + requestedRemovals.size()); + for (IInstallableUnit added : requestedAdditions) { - if (toState.contains(added)) - requestStatus.put(added, new RequestStatus(added, RequestStatus.ADDED, IStatus.OK, null)); - else - requestStatus.put(added, new RequestStatus(added, RequestStatus.ADDED, IStatus.ERROR, null)); + int status = toState.contains(added) ? OK : ERROR; + requestStatus.put(added, new RequestStatus(added, ADDED, status, null)); } for (IInstallableUnit removed : requestedRemovals) { - if (!toState.contains(removed)) - requestStatus.put(removed, new RequestStatus(removed, RequestStatus.REMOVED, IStatus.OK, null)); - else - requestStatus.put(removed, new RequestStatus(removed, RequestStatus.REMOVED, IStatus.ERROR, null)); + int status = !toState.contains(removed) ? OK : ERROR; + requestStatus.put(removed, new RequestStatus(removed, REMOVED, status, null)); } //Compute the side effect changes (e.g. things installed optionally going away) @@ -120,7 +160,7 @@ public class SimplePlanner implements IPlanner { while (includedIUs.hasNext()) { IInstallableUnit removal = includedIUs.next(); if (!toState.contains(removal) && !requestStatus.containsKey(removal)) { - sideEffectStatus.put(removal, new RequestStatus(removal, RequestStatus.REMOVED, IStatus.INFO, null)); + sideEffectStatus.put(removal, new RequestStatus(removal, REMOVED, INFO, null)); } } @SuppressWarnings("unchecked") @@ -129,50 +169,111 @@ public class SimplePlanner implements IPlanner { } /** - * Converts a set containing a list of resolver explanations into a human-readable status object. + * Converts a list of {@link Projector#getExplanation() resolver explanations} to a human-readable status object + * + * @param explanations List of resolver explanations ordered by logical causality. + * I.e. read from start to end should forms logical chain of statements as to why resolution failed. + * @return the {@link IStatus} */ - private IStatus convertExplanationToStatus(Set<Explanation> explanations) { - if (explanations == null) - return new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, Messages.Director_Unsatisfied_Dependencies); - - // hack to create a useful message when a user installs something intended for a target platform into the IDE - ArrayList<IStatus> forTargets = new ArrayList<>(0); + private static IStatus convertExplanationToStatus(Set<Explanation> explanations) { + // Hack to create a useful message when a user installs something intended only for the PDE target platform into a general purpose profile. + List<IStatus> forTargets = new ArrayList<>(0); for (Explanation next : explanations) { - if (next instanceof Explanation.MissingIU) { - Explanation.MissingIU missingIU = (MissingIU) next; - if (missingIU.req instanceof IRequiredCapability && missingIU.req.getMatches().getParameters().length == 3 && "A.PDE.Target.Platform".equals(((IRequiredCapability) missingIU.req).getNamespace())) //$NON-NLS-1$ - forTargets.add(new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, missingIU.getUserReadableName(missingIU.iu))); + if (next instanceof MissingIU) { + MissingIU missingIU = (MissingIU) next; + if (missingIU.req instanceof IRequiredCapability && + missingIU.req.getMatches().getParameters().length == 3 && + "A.PDE.Target.Platform".equals(((IRequiredCapability) missingIU.req).getNamespace())) {//$NON-NLS-1$ + // This IU requires the PDE target platform IU and it is missing. + // I.e. this IU is intended only for the PDE target platform. + forTargets.add(new Status(ERROR, PI_DIRECTOR, Explanation.getUserReadableName(missingIU.iu))); + } } } - if (forTargets.size() > 0) { - // add a blurb about disabling 'include required software'. The following line could be removed if bug 309863 is fixed - forTargets.add(new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, Messages.Director_For_Target_Unselect_Required)); - // return a multi status with all the IUs that require A.PDE.Target.Platform - return new MultiStatus(DirectorActivator.PI_DIRECTOR, 1, forTargets.toArray(new IStatus[forTargets.size()]), Messages.Director_For_Target, null); + if (!forTargets.isEmpty()) { + // The following line could be removed if Bug 309863 is fixed + forTargets.add(new Status(ERROR, PI_DIRECTOR, Messages.Director_For_Target_Unselect_Required)); + // Return a multi status with all the IUs that require A.PDE.Target.Platform + return new MultiStatus(PI_DIRECTOR, 1, forTargets.stream().toArray(IStatus[]::new), Messages.Director_For_Target, null); } - MultiStatus root = new MultiStatus(DirectorActivator.PI_DIRECTOR, 1, Messages.Director_Unsatisfied_Dependencies, null); - //try to find a more specific root message if possible - String specificMessage = null; - int errorCode = 0; + + // Use the most specific message for the root of the MultiStatus + // Missing IU takes precedence over singleton conflicts + String message = Messages.Director_Unsatisfied_Dependencies; + int errorCode = 1; for (Explanation next : explanations) { - root.add(next.toStatus()); - if (specificMessage == null && next instanceof Explanation.MissingIU) { - specificMessage = Messages.Explanation_rootMissing; + if (next instanceof MissingIU) { + message = Messages.Explanation_rootMissing; errorCode = 10053; - } else if (specificMessage == null && next instanceof Explanation.Singleton) { - specificMessage = Messages.Explanation_rootSingleton; + break; + } + + if (next instanceof Singleton) { + message = Messages.Explanation_rootSingleton; errorCode = 10054; + break; } } - //use a more specific root message if available - if (specificMessage != null) { - MultiStatus newRoot = new MultiStatus(DirectorActivator.PI_DIRECTOR, errorCode, specificMessage, null); - newRoot.merge(root); - root = newRoot; - } + + // The children follow the order of logical causality as produced by the Projector + MultiStatus root = new MultiStatus(PI_DIRECTOR, errorCode, message, null); + explanations.stream().map(Explanation::toStatus).forEach(root::add); + return root; + } + + /** + * TODO Find a way to emit INFO status. The issue is that all {@link IStatus#isOK()} calls will fail. + * + * @param requestChanges + * @param requestSideEffects + * @return the {@link IStatus} + */ + private static IStatus convertChangesToStatus(Map<IInstallableUnit, RequestStatus> requestChanges, Map<IInstallableUnit, RequestStatus> requestSideEffects) { + MultiStatus root = new MultiStatus(PI_DIRECTOR, OK, Messages.Director_Satisfied_Dependencies, null); + + Stream.concat(requestChanges.values().stream(), requestSideEffects.values().stream()) + .map(SimplePlanner::buildChangeStatus) + .forEach(root::add); + return root; } + private static IStatus buildChangeStatus(RequestStatus rs) { + final String change; + switch (rs.getInitialRequestType()) { + case ADDED : + change = "Add"; //$NON-NLS-1$ + break; + case REMOVED : + change = "Remove"; //$NON-NLS-1$ + break; + default : + change = "UNKNOWN change type " + rs.getInitialRequestType(); //$NON-NLS-1$ + break; + } + + final IStatus status; + if (!rs.isOK()) { + String message = NLS.bind(Messages.Director_Unsatisfied_Change, change, Explanation.getUserReadableName(rs.getIu())); + + if (rs.getExplanations().isEmpty()) { + status = new Status(OK, PI_DIRECTOR, message, rs.getException()); + } else { + status = new MultiStatus( + PI_DIRECTOR, + OK, + rs.getExplanations().stream().map(Explanation::toStatus).toArray(IStatus[]::new), + message, + rs.getException()); + } + } else { + String message = NLS.bind(Messages.Director_Satisfied_Change, change, Explanation.getUserReadableName(rs.getIu())); + status = new Status(OK, PI_DIRECTOR, message, rs.getException()); + } + + return status; + } + private void planPropertyOperations(IProvisioningPlan plan, ProfileChangeRequest profileChangeRequest, Collection<IInstallableUnit> toState) { // First deal with profile properties to remove. @@ -306,8 +407,16 @@ public class SimplePlanner implements IPlanner { return satisfyMetaRequirements(p.getProperties()); } - // Return the set of IUs representing the complete future state of the profile to satisfy the request or return a - // ProvisioningPlan when the request can not be satisfied + /** + * Performs a provisioning request resolution + * + * @param profileChangeRequest The requested change. + * @param context The context for the resolution pass + * @param monitor + * + * @return Return a {@link Projector} that captures the complete future state of the profile that satisfies the request. + * If the request can't be satisfied return an {@link IProvisioningPlan} where the error is captured in {@link IProvisioningPlan#getStatus()} + */ private Object getSolutionFor(ProfileChangeRequest profileChangeRequest, ProvisioningContext context, IProgressMonitor monitor) { SubMonitor sub = SubMonitor.convert(monitor, ExpandWork); sub.setTaskName(Messages.Director_Task_Resolving_Dependencies); @@ -322,12 +431,12 @@ public class SimplePlanner implements IPlanner { extraIUs.addAll(profileChangeRequest.getRemovals()); if (context == null || context.getProperty(INCLUDE_PROFILE_IUS) == null || context.getProperty(INCLUDE_PROFILE_IUS).equalsIgnoreCase(Boolean.TRUE.toString())) { Iterator<IInstallableUnit> itor = profile.available(QueryUtil.createIUAnyQuery(), null).iterator(); - while (itor.hasNext()) + while (itor.hasNext()) { extraIUs.add(itor.next()); + } } - IInstallableUnit[] availableIUs = gatherAvailableInstallableUnits(extraIUs.toArray(new IInstallableUnit[extraIUs.size()]), context, sub.newChild(ExpandWork / 4)); - + IInstallableUnit[] availableIUs = gatherAvailableInstallableUnits(extraIUs.stream().toArray(IInstallableUnit[]::new), context, sub.newChild(ExpandWork / 4)); Slicer slicer = new Slicer(new QueryableArray(availableIUs), newSelectionContext, satisfyMetaRequirements(profileChangeRequest.getProfileProperties())); IQueryable<IInstallableUnit> slice = slicer.slice(new IInstallableUnit[] {(IInstallableUnit) updatedPlan[0]}, sub.newChild(ExpandWork / 4)); if (slice == null) { @@ -335,45 +444,59 @@ public class SimplePlanner implements IPlanner { plan.setStatus(slicer.getStatus()); return plan; } + @SuppressWarnings("unchecked") - final IQueryable<IInstallableUnit>[] queryables = new IQueryable[] {slice, new QueryableArray(profileChangeRequest.getAdditions().toArray(new IInstallableUnit[profileChangeRequest.getAdditions().size()]))}; + IQueryable<IInstallableUnit>[] queryables = new IQueryable[] {slice, new QueryableArray(profileChangeRequest.getAdditions().stream().toArray(IInstallableUnit[]::new))}; slice = new CompoundQueryable<>(queryables); + Projector projector = new Projector(slice, newSelectionContext, slicer.getNonGreedyIUs(), satisfyMetaRequirements(profileChangeRequest.getProfileProperties())); - projector.setUserDefined(profileChangeRequest.getPropertiesToAdd().containsKey("_internal_user_defined_")); + projector.setUserDefined(profileChangeRequest.getPropertiesToAdd().containsKey("_internal_user_defined_")); //$NON-NLS-1$ projector.encode((IInstallableUnit) updatedPlan[0], (IInstallableUnit[]) updatedPlan[1], profile, profileChangeRequest.getAdditions(), sub.newChild(ExpandWork / 4)); + IStatus s = projector.invokeSolver(sub.newChild(ExpandWork / 4)); - if (s.getSeverity() == IStatus.CANCEL) { - IProvisioningPlan plan = engine.createPlan(profile, context); - plan.setStatus(s); - return plan; - } - if (s.getSeverity() == IStatus.ERROR) { - sub.setTaskName(Messages.Planner_NoSolution); - if (s.getCode() != UNSATISFIABLE || (context != null && !(context.getProperty(EXPLANATION) == null || Boolean.TRUE.toString().equalsIgnoreCase(context.getProperty(EXPLANATION))))) { + switch (s.getSeverity()) { + case CANCEL : { IProvisioningPlan plan = engine.createPlan(profile, context); plan.setStatus(s); return plan; } - //Extract the explanation - Set<Explanation> explanation = projector.getExplanation(sub.newChild(ExpandWork / 4)); - IStatus explanationStatus = convertExplanationToStatus(explanation); + // Convert the projector explanation chain into an IStatus + case ERROR : { + sub.setTaskName(Messages.Planner_NoSolution); + if (s.getCode() != UNSATISFIABLE || (context != null && !(context.getProperty(EXPLANATION) == null || Boolean.parseBoolean(context.getProperty(EXPLANATION))))) { + IProvisioningPlan plan = engine.createPlan(profile, context); + plan.setStatus(s); + return plan; + } - Map<IInstallableUnit, RequestStatus>[] changes = buildDetailedErrors(profileChangeRequest); - Map<IInstallableUnit, RequestStatus> requestChanges = (changes == null) ? null : changes[0]; - Map<IInstallableUnit, RequestStatus> requestSideEffects = (changes == null) ? null : changes[1]; - PlannerStatus plannerStatus = new PlannerStatus(explanationStatus, new RequestStatus(null, RequestStatus.REMOVED, IStatus.ERROR, explanation), requestChanges, requestSideEffects, null); + //Extract the explanation + Set<Explanation> explanation = projector.getExplanation(sub.newChild(ExpandWork / 4)); + IStatus explanationStatus = convertExplanationToStatus(explanation); - IProvisioningPlan plan = engine.createPlan(profile, context); - plan.setStatus(plannerStatus); - return plan; - } - //The resolution succeeded. We can forget about the warnings since there is a solution. - if (Tracing.DEBUG && s.getSeverity() != IStatus.OK) - LogHelper.log(s); - s = Status.OK_STATUS; + Map<IInstallableUnit, RequestStatus>[] changes = buildDetailedErrors(profileChangeRequest); + Map<IInstallableUnit, RequestStatus> requestChanges = (changes == null) ? null : changes[0]; + Map<IInstallableUnit, RequestStatus> requestSideEffects = (changes == null) ? null : changes[1]; + PlannerStatus plannerStatus = new PlannerStatus(explanationStatus, new RequestStatus(null, REMOVED, ERROR, explanation), requestChanges, requestSideEffects, null); + + IProvisioningPlan plan = engine.createPlan(profile, context); + plan.setStatus(plannerStatus); + return plan; + } - return projector; + //The resolution succeeded. We can forget about the warnings since there is a solution. + case OK : { + return projector; + } + + // Log the unexpected status type, but continue + default : { + if (Tracing.DEBUG) { + LogHelper.log(s); + } + return projector; + } + } } finally { sub.done(); } @@ -388,8 +511,9 @@ public class SimplePlanner implements IPlanner { //Get the solution for the initial request Object resolutionResult = getSolutionFor(pcr, context, sub.newChild(ExpandWork / 2)); // a return value of a plan indicates failure when resolving so return. - if (resolutionResult instanceof IProvisioningPlan) + if (resolutionResult instanceof IProvisioningPlan) { return (IProvisioningPlan) resolutionResult; + } Collection<IInstallableUnit> newState = ((Projector) resolutionResult).extractSolution(); Collection<IInstallableUnit> fullState = new ArrayList<>(); @@ -471,7 +595,7 @@ public class SimplePlanner implements IPlanner { sub.setTaskName(Messages.Director_Task_installer_plan); if (profileRegistry == null) { IProvisioningPlan plan = engine.createPlan(initialRequest.getProfile(), initialContext); - plan.setStatus(new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, Messages.Planner_no_profile_registry)); + plan.setStatus(new Status(ERROR, PI_DIRECTOR, Messages.Planner_no_profile_registry)); return plan; } @@ -490,7 +614,7 @@ public class SimplePlanner implements IPlanner { if (profile.getProfileId().equals(installerProfile.getProfileId())) { if (profile.getTimestamp() != installerProfile.getTimestamp()) { IProvisioningPlan plan = engine.createPlan(initialRequest.getProfile(), initialContext); - plan.setStatus(new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, NLS.bind(Messages.Planner_profile_out_of_sync, profile.getProfileId()))); + plan.setStatus(new Status(ERROR, PI_DIRECTOR, NLS.bind(Messages.Planner_profile_out_of_sync, profile.getProfileId()))); return plan; } return createInstallerPlanForCohostedCase(profile, initialRequest, initialPlan, unattachedState, expectedState, initialContext, sub); @@ -543,8 +667,8 @@ public class SimplePlanner implements IPlanner { if (previousActionsIU != null) agentRequest.remove(previousActionsIU); Object externalInstallerPlan = getSolutionFor(agentRequest, initialContext, sub.newChild(10)); - if (externalInstallerPlan instanceof IProvisioningPlan && ((IProvisioningPlan) externalInstallerPlan).getStatus().getSeverity() == IStatus.ERROR) { - MultiStatus externalInstallerStatus = new MultiStatus(DirectorActivator.PI_DIRECTOR, 0, Messages.Planner_can_not_install_preq, null); + if (externalInstallerPlan instanceof IProvisioningPlan && ((IProvisioningPlan) externalInstallerPlan).getStatus().getSeverity() == ERROR) { + MultiStatus externalInstallerStatus = new MultiStatus(PI_DIRECTOR, 0, Messages.Planner_can_not_install_preq, null); externalInstallerStatus.add(((IProvisioningPlan) externalInstallerPlan).getStatus()); IProvisioningPlan plan = engine.createPlan(initialRequest.getProfile(), initialContext); plan.setStatus(externalInstallerStatus); @@ -594,8 +718,8 @@ public class SimplePlanner implements IPlanner { ArrayList<IInstallableUnit> extraIUs = new ArrayList<>(unattachedState); agentCtx.setExtraInstallableUnits(extraIUs); Object agentSolution = getSolutionFor(agentRequest, agentCtx, monitor.newChild(3)); - if (agentSolution instanceof IProvisioningPlan && ((IProvisioningPlan) agentSolution).getStatus().getSeverity() == IStatus.ERROR) { - MultiStatus agentStatus = new MultiStatus(DirectorActivator.PI_DIRECTOR, 0, Messages.Planner_actions_and_software_incompatible, null); + if (agentSolution instanceof IProvisioningPlan && ((IProvisioningPlan) agentSolution).getStatus().getSeverity() == ERROR) { + MultiStatus agentStatus = new MultiStatus(PI_DIRECTOR, 0, Messages.Planner_actions_and_software_incompatible, null); agentStatus.add(((IProvisioningPlan) agentSolution).getStatus()); IProvisioningPlan plan = engine.createPlan(initialRequest.getProfile(), initialContext); plan.setStatus(agentStatus); @@ -614,7 +738,7 @@ public class SimplePlanner implements IPlanner { //...This computes the attachment of what is currently in the profile Object initialSolution = getSolutionFor(new ProfileChangeRequest(new EverythingOptionalProfile(initialRequest.getProfile())), noRepoContext, new NullProgressMonitor()); if (initialSolution instanceof IProvisioningPlan) { - LogHelper.log(new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, "The resolution of the previous state contained in profile " + initialRequest.getProfile().getProfileId() + " version " + initialRequest.getProfile().getTimestamp() + " failed.")); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + LogHelper.log(new Status(ERROR, PI_DIRECTOR, "The resolution of the previous state contained in profile " + initialRequest.getProfile().getProfileId() + " version " + initialRequest.getProfile().getTimestamp() + " failed.")); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ return (IProvisioningPlan) initialSolution; } Iterator<IInstallableUnit> profileState = initialRequest.getProfile().query(QueryUtil.createIUAnyQuery(), null).iterator(); @@ -638,7 +762,7 @@ public class SimplePlanner implements IPlanner { //Compute the attachment of the previous state Object initialSolution = getSolutionFor(new ProfileChangeRequest(new EverythingOptionalProfile(request.getProfile())), noRepoContext, new NullProgressMonitor()); if (initialSolution instanceof IProvisioningPlan) { - LogHelper.log(new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, "The resolution of the previous state contained in profile " + request.getProfile().getProfileId() + " version " + request.getProfile().getTimestamp() + " failed.")); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + LogHelper.log(new Status(ERROR, PI_DIRECTOR, "The resolution of the previous state contained in profile " + request.getProfile().getProfileId() + " version " + request.getProfile().getTimestamp() + " failed.")); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ return (IProvisioningPlan) initialSolution; } Iterator<IInstallableUnit> profileState = request.getProfile().query(QueryUtil.createIUAnyQuery(), null).iterator(); diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/messages.properties b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/messages.properties index 046e279ea..2b129db92 100644 --- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/messages.properties +++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/messages.properties @@ -13,11 +13,13 @@ Director_Task_installer_plan=Computing prerequisite plan Director_Task_Installing=Installing into {0} Director_Task_Updating=Updating Director_Task_Resolving_Dependencies=Calculating requirements and dependencies. -Director_Unsatisfied_Dependencies=\ -Cannot complete the install because some dependencies are not satisfiable +Director_Unsatisfied_Dependencies=Cannot complete the install because some dependencies are not satisfiable +Director_Satisfied_Dependencies=Overall install request is satisfiable +Director_Satisfied_Change={0} request for {1} is satisfiable +Director_Unsatisfied_Change={0} request for {1} is NOT satisfiable Director_error_applying_configuration=Unexpected failure applying configuration after for the installer plan execution. -Director_For_Target = The following software cannot be installed because it is intended for use only in Plug-in Development Environment (PDE) target platforms. Please deselect these items and retry the operation. -Director_For_Target_Unselect_Required = If provisioning a target platform then try disabling the option 'Include required software' +Director_For_Target=The following software cannot be installed because it is intended for use only in Plug-in Development Environment (PDE) target platforms. Please deselect these items and retry the operation. +Director_For_Target_Unselect_Required=If provisioning a target platform then try disabling the option 'Include required software' Explanation_alreadyInstalled=Software currently installed: {0} Explanation_from=From: {0} diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/provisional/p2/director/RequestStatus.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/provisional/p2/director/RequestStatus.java index 2bc3d681c..12129f6f1 100644 --- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/provisional/p2/director/RequestStatus.java +++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/provisional/p2/director/RequestStatus.java @@ -10,11 +10,16 @@ ******************************************************************************/ package org.eclipse.equinox.internal.provisional.p2.director; -import java.util.*; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; import org.eclipse.core.runtime.Status; -import org.eclipse.equinox.internal.p2.director.*; +import org.eclipse.equinox.internal.p2.director.DirectorActivator; +import org.eclipse.equinox.internal.p2.director.Explanation; import org.eclipse.equinox.internal.p2.director.Explanation.IUInstalled; import org.eclipse.equinox.internal.p2.director.Explanation.IUToInstall; +import org.eclipse.equinox.internal.p2.director.Messages; import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.osgi.util.NLS; @@ -33,10 +38,11 @@ public class RequestStatus extends Status { super(severity, DirectorActivator.PI_DIRECTOR, NLS.bind(Messages.RequestStatus_message, iu)); this.iu = iu; this.initialRequestType = initialRequesType; - this.explanation = explanation; conflictingRootIUs = new HashSet<>(); conflictingInstalledIUs = new HashSet<>(); if (explanation != null) { + this.explanation = explanation; + Iterator<Explanation> iterator = explanation.iterator(); Explanation o = null; while (iterator.hasNext() && ((o = iterator.next()) instanceof Explanation.IUToInstall)) { @@ -49,6 +55,8 @@ public class RequestStatus extends Status { } } detailedExplanation = o; + } else { + this.explanation = Collections.emptySet(); } } diff --git a/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF index 70231344b..ca9360bbf 100644 --- a/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.equinox.p2.tests;singleton:=true -Bundle-Version: 1.7.200.qualifier +Bundle-Version: 1.7.300.qualifier Bundle-ClassPath: . Bundle-Activator: org.eclipse.equinox.p2.tests.TestActivator Bundle-Vendor: %providerName diff --git a/bundles/org.eclipse.equinox.p2.tests/pom.xml b/bundles/org.eclipse.equinox.p2.tests/pom.xml index c62828f44..a8d6ceaa8 100644 --- a/bundles/org.eclipse.equinox.p2.tests/pom.xml +++ b/bundles/org.eclipse.equinox.p2.tests/pom.xml @@ -16,7 +16,7 @@ <groupId>org.eclipse.equinox</groupId> <artifactId>org.eclipse.equinox.p2.tests</artifactId> - <version>1.7.200-SNAPSHOT</version> + <version>1.7.300-SNAPSHOT</version> <packaging>eclipse-test-plugin</packaging> <properties> diff --git a/features/org.eclipse.equinox.p2.core.feature/feature.xml b/features/org.eclipse.equinox.p2.core.feature/feature.xml index bdd8807d4..e22b24b34 100644 --- a/features/org.eclipse.equinox.p2.core.feature/feature.xml +++ b/features/org.eclipse.equinox.p2.core.feature/feature.xml @@ -2,7 +2,7 @@ <feature id="org.eclipse.equinox.p2.core.feature" label="%featureName" - version="1.5.0.qualifier" + version="1.5.100.qualifier" provider-name="%providerName" license-feature="org.eclipse.license" license-feature-version="0.0.0"> @@ -184,7 +184,7 @@ fragment="true" unpack="false"/> - <plugin + <plugin id="org.eclipse.equinox.security.linux.x86_64" os="linux" arch="x86_64" diff --git a/features/org.eclipse.equinox.p2.core.feature/pom.xml b/features/org.eclipse.equinox.p2.core.feature/pom.xml index 04aef4e3f..a5bd36f60 100644 --- a/features/org.eclipse.equinox.p2.core.feature/pom.xml +++ b/features/org.eclipse.equinox.p2.core.feature/pom.xml @@ -20,7 +20,7 @@ </parent> <groupId>org.eclipse.equinox</groupId> <artifactId>org.eclipse.equinox.p2.core.feature</artifactId> - <version>1.5.0-SNAPSHOT</version> + <version>1.5.100-SNAPSHOT</version> <packaging>eclipse-feature</packaging> diff --git a/features/org.eclipse.equinox.p2.rcp.feature/feature.xml b/features/org.eclipse.equinox.p2.rcp.feature/feature.xml index b1c1993bb..910d5ea7c 100644 --- a/features/org.eclipse.equinox.p2.rcp.feature/feature.xml +++ b/features/org.eclipse.equinox.p2.rcp.feature/feature.xml @@ -2,7 +2,7 @@ <feature id="org.eclipse.equinox.p2.rcp.feature" label="%featureName" - version="1.4.0.qualifier" + version="1.4.100.qualifier" provider-name="%providerName" license-feature="org.eclipse.license" license-feature-version="0.0.0"> diff --git a/features/org.eclipse.equinox.p2.rcp.feature/pom.xml b/features/org.eclipse.equinox.p2.rcp.feature/pom.xml index caff73d8e..d88afae50 100644 --- a/features/org.eclipse.equinox.p2.rcp.feature/pom.xml +++ b/features/org.eclipse.equinox.p2.rcp.feature/pom.xml @@ -20,7 +20,7 @@ <groupId>org.eclipse.equinox</groupId> <artifactId>org.eclipse.equinox.p2.rcp.feature</artifactId> - <version>1.4.0-SNAPSHOT</version> + <version>1.4.100-SNAPSHOT</version> <packaging>eclipse-feature</packaging> <build> |