| /******************************************************************************* |
| * Copyright (c) 2009, 2018 Daniel Le Berre and others. All rights reserved. This |
| * program and the accompanying materials are made available under the terms of |
| * the Eclipse Public License v1.0 which accompanies this distribution, and is |
| * available at http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Daniel Le Berre - initial API and implementation |
| * IBM - ongoing development |
| ******************************************************************************/ |
| 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.osgi.util.NLS; |
| |
| public abstract class Explanation implements Comparable<Explanation> { |
| |
| public static class PatchedHardRequirement extends Explanation { |
| public final IInstallableUnit iu; |
| public final IInstallableUnitPatch patch; |
| public final IRequirement req; |
| |
| public PatchedHardRequirement(IInstallableUnit iu, IInstallableUnitPatch patch) { |
| this.iu = iu; |
| this.req = null; |
| this.patch = patch; |
| } |
| |
| public PatchedHardRequirement(IInstallableUnit iu, IRequirement req, IInstallableUnitPatch patch) { |
| this.iu = iu; |
| this.req = req; |
| this.patch = patch; |
| } |
| |
| @Override |
| public int orderValue() { |
| return 6; |
| } |
| |
| @Override |
| public IStatus toStatus() { |
| MultiStatus result = new MultiStatus(DirectorActivator.PI_DIRECTOR, 1, Messages.Explanation_unsatisfied, null); |
| final String fromString = patch.toString() + ' ' + getUserReadableName(iu); |
| result.add(new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, NLS.bind(Messages.Explanation_fromPatch, fromString))); |
| result.add(new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, NLS.bind(Messages.Explanation_to, req))); |
| return result; |
| } |
| |
| @Override |
| public String toString() { |
| return NLS.bind(Messages.Explanation_patchedHardDependency, new Object[] {patch, iu, req}); |
| } |
| |
| @Override |
| public int shortAnswer() { |
| return Explanation.VIOLATED_PATCHED_HARD_REQUIREMENT; |
| } |
| |
| } |
| |
| public static class HardRequirement extends Explanation { |
| public final IInstallableUnit iu; |
| public final IRequirement req; |
| |
| public HardRequirement(IInstallableUnit iu, IRequirement req) { |
| this.iu = iu; |
| this.req = req; |
| } |
| |
| @Override |
| public int orderValue() { |
| return 5; |
| } |
| |
| @Override |
| public IStatus toStatus() { |
| MultiStatus result = new MultiStatus(DirectorActivator.PI_DIRECTOR, 1, Messages.Explanation_unsatisfied, null); |
| result.add(new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, NLS.bind(Messages.Explanation_from, getUserReadableName(iu)))); |
| result.add(new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, NLS.bind(Messages.Explanation_to, req))); |
| return result; |
| } |
| |
| @Override |
| public String toString() { |
| return NLS.bind(Messages.Explanation_hardDependency, iu, req); |
| } |
| |
| @Override |
| public int shortAnswer() { |
| return VIOLATED_HARD_REQUIREMENT; |
| } |
| } |
| |
| public static class IUInstalled extends Explanation { |
| public final IInstallableUnit iu; |
| |
| public IUInstalled(IInstallableUnit iu) { |
| this.iu = iu; |
| } |
| |
| @Override |
| public int orderValue() { |
| return 2; |
| } |
| |
| @Override |
| public String toString() { |
| return NLS.bind(Messages.Explanation_alreadyInstalled, iu); |
| } |
| |
| @Override |
| public IStatus toStatus() { |
| return new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, NLS.bind(Messages.Explanation_alreadyInstalled, getUserReadableName(iu))); |
| } |
| |
| @Override |
| public int shortAnswer() { |
| return IU_INSTALLED; |
| } |
| } |
| |
| public static class IUToInstall extends Explanation { |
| public final IInstallableUnit iu; |
| |
| public IUToInstall(IInstallableUnit iu) { |
| this.iu = iu; |
| } |
| |
| @Override |
| public int orderValue() { |
| return 1; |
| } |
| |
| @Override |
| public String toString() { |
| return NLS.bind(Messages.Explanation_toInstall, iu); |
| } |
| |
| @Override |
| public IStatus toStatus() { |
| return new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, NLS.bind(Messages.Explanation_toInstall, getUserReadableName(iu))); |
| } |
| |
| @Override |
| public int shortAnswer() { |
| return IU_TO_INSTALL; |
| } |
| } |
| |
| public static class NotInstallableRoot extends Explanation { |
| public final IRequirement req; |
| |
| public NotInstallableRoot(IRequirement req) { |
| this.req = req; |
| } |
| |
| @Override |
| public String toString() { |
| return NLS.bind(Messages.Explanation_missingRootFilter, req); |
| } |
| |
| @Override |
| public IStatus toStatus() { |
| return new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, NLS.bind(Messages.Explanation_missingRootFilter, req)); |
| } |
| |
| @Override |
| protected int orderValue() { |
| return 2; |
| } |
| |
| @Override |
| public int shortAnswer() { |
| return NON_INSTALLABLE_ROOT; |
| } |
| } |
| |
| public static class MissingIU extends Explanation { |
| public final IInstallableUnit iu; |
| public final IRequirement req; |
| public boolean isEntryPoint; |
| |
| public MissingIU(IInstallableUnit iu, IRequirement req, boolean isEntryPoint) { |
| this.iu = iu; |
| this.req = req; |
| this.isEntryPoint = isEntryPoint; |
| } |
| |
| @Override |
| public int orderValue() { |
| return 3; |
| } |
| |
| @Override |
| public int shortAnswer() { |
| return MISSING_REQUIREMENT; |
| } |
| |
| @Override |
| public String toString() { |
| if (isEntryPoint) { |
| return NLS.bind(Messages.Explanation_missingRootRequired, req); |
| } |
| if (req.getFilter() == null) { |
| return NLS.bind(Messages.Explanation_missingRequired, iu, req); |
| } |
| return NLS.bind(Messages.Explanation_missingRequiredFilter, new Object[] {req.getFilter(), iu, req}); |
| } |
| |
| @Override |
| public IStatus toStatus() { |
| if (isEntryPoint) { |
| return new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, NLS.bind(Messages.Explanation_missingRootRequired, req)); |
| } |
| if (req.getFilter() == null) { |
| return new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, NLS.bind(Messages.Explanation_missingRequired, getUserReadableName(iu), req)); |
| } |
| return new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, NLS.bind(Messages.Explanation_missingRequiredFilter, new Object[] {req.getFilter(), getUserReadableName(iu), req})); |
| } |
| } |
| |
| public static class MissingGreedyIU extends Explanation { |
| public final IInstallableUnit iu; |
| |
| public MissingGreedyIU(IInstallableUnit iu) { |
| this.iu = iu; |
| } |
| |
| @Override |
| public int orderValue() { |
| return 3; |
| } |
| |
| @Override |
| public int shortAnswer() { |
| return MISSING_REQUIREMENT; |
| } |
| |
| @Override |
| public String toString() { |
| return NLS.bind(Messages.Explanation_missingNonGreedyRequired, iu); |
| } |
| |
| @Override |
| public IStatus toStatus() { |
| return new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, NLS.bind(Messages.Explanation_missingNonGreedyRequired, getUserReadableName(iu))); |
| } |
| } |
| |
| public static class Singleton extends Explanation { |
| public final IInstallableUnit[] ius; |
| |
| public Singleton(IInstallableUnit[] ius) { |
| this.ius = ius; |
| } |
| |
| @Override |
| public int orderValue() { |
| return 4; |
| } |
| |
| @Override |
| public int shortAnswer() { |
| return VIOLATED_SINGLETON_CONSTRAINT; |
| } |
| |
| @Override |
| public IStatus toStatus() { |
| MultiStatus result = new MultiStatus(DirectorActivator.PI_DIRECTOR, 1, NLS.bind(Messages.Explanation_singleton, ""), null); //$NON-NLS-1$ |
| for (IInstallableUnit iu : ius) |
| result.add(new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, getUserReadableName(iu))); |
| return result; |
| } |
| |
| @Override |
| public String toString() { |
| return NLS.bind(Messages.Explanation_singleton, Arrays.asList(ius)); |
| } |
| |
| } |
| |
| public static final Explanation OPTIONAL_REQUIREMENT = new Explanation() { |
| |
| @Override |
| public int orderValue() { |
| return 6; |
| } |
| |
| @Override |
| public String toString() { |
| return Messages.Explanation_optionalDependency; |
| } |
| |
| @Override |
| public int shortAnswer() { |
| return OTHER_REASON; |
| } |
| }; |
| |
| public static final int MISSING_REQUIREMENT = 1; |
| public static final int VIOLATED_SINGLETON_CONSTRAINT = 2; |
| public static final int IU_INSTALLED = 3; |
| public static final int IU_TO_INSTALL = 4; |
| public static final int VIOLATED_HARD_REQUIREMENT = 5; |
| public static final int VIOLATED_PATCHED_HARD_REQUIREMENT = 6; |
| public static final int NON_INSTALLABLE_ROOT = 7; |
| public static final int OTHER_REASON = 100; |
| |
| protected Explanation() { |
| super(); |
| } |
| |
| @Override |
| public int compareTo(Explanation exp) { |
| if (this.orderValue() == exp.orderValue()) { |
| return this.toString().compareTo(exp.toString()); |
| } |
| return this.orderValue() - exp.orderValue(); |
| } |
| |
| protected abstract int orderValue(); |
| |
| abstract public int shortAnswer(); |
| |
| /** |
| * Returns a representation of this explanation as a status object. |
| */ |
| public IStatus toStatus() { |
| return new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, toString()); |
| } |
| |
| protected static String getUserReadableName(IInstallableUnit iu) { |
| if (iu == null) |
| return ""; //$NON-NLS-1$ |
| String result = getLocalized(iu); |
| if (result == null) |
| return iu.toString(); |
| return result + ' ' + iu.getVersion() + " (" + iu.toString() + ')'; //$NON-NLS-1$ |
| } |
| |
| private static String getLocalized(IInstallableUnit iu) { |
| String value = iu.getProperty(IInstallableUnit.PROP_NAME); |
| if (value == null || value.length() <= 1 || value.charAt(0) != '%') |
| return value; |
| final String actualKey = value.substring(1); // Strip off the % |
| return iu.getProperty("df_LT." + actualKey); //$NON-NLS-1$ |
| } |
| } |