Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTodor Boev2018-05-10 12:19:01 +0000
committerAlexander Kurtakov2018-06-05 15:31:41 +0000
commitcd6e132b43c635f72b6f0f132ddd3f13d8fe1090 (patch)
tree4aeb7ee5a52a10354c5c375e569bb02a5efe5240
parent0c85a21c906722b458e3841d7ca29d7e613ea5b0 (diff)
downloadrt.equinox.p2-cd6e132b43c635f72b6f0f132ddd3f13d8fe1090.tar.gz
rt.equinox.p2-cd6e132b43c635f72b6f0f132ddd3f13d8fe1090.tar.xz
rt.equinox.p2-cd6e132b43c635f72b6f0f132ddd3f13d8fe1090.zip
Bug 534536 - The planner always reports detailed statusI20180606-1020
- SimplePlanner builds a MultiStatus for successful operations just like it does for failed ones - The DirectorApplication logs the status of successful planner invocations Change-Id: I0886dcf377172f99cf2d26df0f2b3dedfe9a7280 Signed-off-by: Todor Boev <rinsvind@gmail.com>
-rw-r--r--bundles/org.eclipse.equinox.p2.director.app/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.director.app/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DefaultLog.java4
-rw-r--r--bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DirectorApplication.java114
-rw-r--r--bundles/org.eclipse.equinox.p2.director/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.director/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Explanation.java12
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Messages.java3
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/SimplePlanner.java308
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/messages.properties10
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/provisional/p2/director/RequestStatus.java14
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/pom.xml2
-rw-r--r--features/org.eclipse.equinox.p2.core.feature/feature.xml4
-rw-r--r--features/org.eclipse.equinox.p2.core.feature/pom.xml2
-rw-r--r--features/org.eclipse.equinox.p2.rcp.feature/feature.xml2
-rw-r--r--features/org.eclipse.equinox.p2.rcp.feature/pom.xml2
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>

Back to the top