| | |
| | | |
| | | package org.opends.quicksetup.upgrader; |
| | | |
| | | import org.opends.quicksetup.i18n.ResourceProvider; |
| | | import org.opends.quicksetup.BuildInformation; |
| | | import org.opends.quicksetup.UserInteraction; |
| | | import org.opends.quicksetup.ApplicationException; |
| | | import org.opends.quicksetup.Constants; |
| | | import org.opends.server.util.VersionCompatibilityIssue; |
| | | import static org.opends.server.util.VersionCompatibilityIssue.*; |
| | | |
| | | import java.util.Set; |
| | | import java.util.List; |
| | | import java.util.logging.Logger; |
| | | import java.util.logging.Level; |
| | | |
| | | /** |
| | | * This class can answer questions important upgrade/reversion questions |
| | | * like 'can I upgrade from verion X to version Y?' and 'if not then why?'. |
| | | * {@link org.opends.quicksetup.upgrader.VersionOracle} specific |
| | | * to upgrade tools. |
| | | */ |
| | | public class UpgradeOracle { |
| | | public class UpgradeOracle extends VersionOracle { |
| | | |
| | | private BuildInformation currentBuildInfo; |
| | | private BuildInformation newBuildInfo; |
| | | static private final Logger LOG = |
| | | Logger.getLogger(UpgradeOracle.class.getName()); |
| | | |
| | | /** |
| | | * Creates a new instance that can analyze a hypothetical upgrade/reversion |
| | | * operation from one version to another. |
| | | * @param ui UserInteraction for relaying information to the user |
| | | * @param current BuildInformation representing the current version |
| | | * @param neu BuildInformation representing the proposed next version |
| | | */ |
| | | public UpgradeOracle(BuildInformation current, BuildInformation neu) { |
| | | this.currentBuildInfo = current; |
| | | this.newBuildInfo = neu; |
| | | public UpgradeOracle(UserInteraction ui, |
| | | BuildInformation current, |
| | | BuildInformation neu) { |
| | | super(ui, current, neu); |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether or not this operation would be considered an |
| | | * upgrade (as opposed to a reversion). |
| | | * @return boolean where true indicates that this would be an upgrade; |
| | | * false indicates that this would be a reversion. |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isUpgrade() { |
| | | return currentBuildInfo.compareTo(newBuildInfo) < 0; |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether or not this operation would be considered an |
| | | * reversion (as opposed to an upgrade). |
| | | * @return boolean where true indicates that this would be a reversion; |
| | | * false indicates that this would be an upgrade. |
| | | */ |
| | | public boolean isReversion() { |
| | | return currentBuildInfo.compareTo(newBuildInfo) > 0; |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether or not this hypothetical operation should be allowed |
| | | * to happen. |
| | | * @return boolean where true indicates that we are confident that such |
| | | * an operation will succeed |
| | | */ |
| | | public boolean isSupported() { |
| | | return !isReversion(); |
| | | } |
| | | |
| | | /** |
| | | * Creates a string summarizing a hypothetical upgrade/reversion |
| | | * from <code>currentVersion</code> to <code>newVersion</code> giving |
| | | * reasons why such an attempt would not be successful. |
| | | * @return String representing a localized message giving a summary of |
| | | * this hypothetical operation. |
| | | */ |
| | | public String getLocalizedSummaryMessage() { |
| | | String msg; |
| | | String[] args = { currentBuildInfo.toString(), |
| | | currentBuildInfo.toString() }; |
| | | ResourceProvider rp = ResourceProvider.getInstance(); |
| | | if (isSupported()) { |
| | | if (isUpgrade()) { |
| | | msg = rp.getMsg("upgrade-hypothetical-upgrade-success", args); |
| | | } else if (isReversion()) { |
| | | msg = rp.getMsg("upgrade-hypothetical-reversion-success", args); |
| | | public void notifyUser() throws ApplicationException { |
| | | String[] args = { currentBuildInfo.toString(), newBuildInfo.toString() }; |
| | | String cont = getMsg("oracle-action-prompt-continue"); |
| | | String cancel = getMsg("oracle-action-prompt-cancel"); |
| | | if (hasIssues()) { |
| | | List<Directive> issues = getIssues(); |
| | | if (!isSupported()) { |
| | | if (issues != null) { |
| | | for (VersionOracle.Directive directive : issues) { |
| | | LOG.log(Level.INFO, "Unsupported upgrade details: " + |
| | | directive.getMessage()); |
| | | } |
| | | } |
| | | throw new ApplicationException(ApplicationException.Type.APPLICATION, |
| | | getMsg("upgrade-oracle-unsupported", args), null); |
| | | } else { |
| | | msg = rp.getMsg("upgrade-hypothetical-versions-the-same", args); |
| | | if (ui != null) { |
| | | for (VersionOracle.Directive directive : issues) { |
| | | String title; |
| | | String summary; |
| | | String details; |
| | | String defaultAction; |
| | | UserInteraction.MessageType msgType; |
| | | switch (directive.getType()) { |
| | | case ACTION: |
| | | title = getMsg("general-action-required"); |
| | | summary = getMsg("upgrade-oracle-action", args); |
| | | details = directive.getMessage() + |
| | | Constants.HTML_LINE_BREAK + |
| | | Constants.HTML_LINE_BREAK + |
| | | getMsg("oracle-action-prompt"); |
| | | msgType = UserInteraction.MessageType.WARNING; |
| | | defaultAction = cancel; |
| | | break; |
| | | case INFO: |
| | | title = getMsg("general-info"); |
| | | summary = getMsg("upgrade-oracle-info"); |
| | | details = directive.getMessage() + |
| | | Constants.HTML_LINE_BREAK + |
| | | Constants.HTML_LINE_BREAK + |
| | | getMsg("oracle-info-prompt"); |
| | | msgType = UserInteraction.MessageType.INFORMATION; |
| | | defaultAction = cont; |
| | | break; |
| | | case WARNING: |
| | | title = getMsg("general-warning"); |
| | | summary = getMsg("upgrade-oracle-warning"); |
| | | details = directive.getMessage() + |
| | | Constants.HTML_LINE_BREAK + |
| | | Constants.HTML_LINE_BREAK + |
| | | getMsg("oracle-info-prompt"); |
| | | msgType = UserInteraction.MessageType.WARNING; |
| | | defaultAction = cont; |
| | | break; |
| | | default: |
| | | LOG.log(Level.INFO, "Unexpected issue type " + |
| | | directive.getType()); |
| | | title = ""; |
| | | summary = ""; |
| | | details = directive.getMessage(); |
| | | msgType = UserInteraction.MessageType.WARNING; |
| | | defaultAction = cont; |
| | | } |
| | | if (cancel.equals(ui.confirm( |
| | | summary, |
| | | details, |
| | | title, |
| | | msgType, |
| | | new String[]{cont, cancel}, |
| | | defaultAction))) { |
| | | throw new ApplicationException( |
| | | ApplicationException.Type.CANCEL, |
| | | getMsg("upgrade-canceled"), null); |
| | | } |
| | | } |
| | | } else { |
| | | throw new ApplicationException(ApplicationException.Type.APPLICATION, |
| | | getMsg("oracle-no-silent"), null); |
| | | } |
| | | } |
| | | } else { |
| | | if (isUpgrade()) { |
| | | msg = rp.getMsg("upgrade-hypothetical-upgrade-failure", args); |
| | | } else if (isReversion()) { |
| | | msg = rp.getMsg("upgrade-hypothetical-reversion-failure", args); |
| | | } else { |
| | | msg = rp.getMsg("upgrade-hypothetical-versions-the-same", args); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | protected String getLocalizedDetailMessage( |
| | | VersionCompatibilityIssue.Cause cause) |
| | | { |
| | | String msg = cause.getLocalizedUpgradeMessage(); |
| | | |
| | | // See if we need to supply a generic message |
| | | Set<VersionCompatibilityIssue.Effect> effects = cause.getEffects(); |
| | | |
| | | // If the import/export effect is present, append the detailed |
| | | // instructions. |
| | | if (effects.contains(Effect.UPGRADE_DATA_EXPORT_AND_REIMPORT_REQUIRED)) { |
| | | if (msg == null) msg = ""; |
| | | msg = msg + Constants.HTML_LINE_BREAK + |
| | | ui.createUnorderedList(getExportImportInstructions()); |
| | | } |
| | | return msg; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | protected boolean isActionRequired(VersionCompatibilityIssue.Cause cause) { |
| | | boolean isAction = false; |
| | | if (cause != null) { |
| | | Set<VersionCompatibilityIssue.Effect> effects = cause.getEffects(); |
| | | isAction = |
| | | effects.contains( |
| | | Effect.UPGRADE_DATA_EXPORT_AND_REIMPORT_REQUIRED) || |
| | | (effects.contains( |
| | | Effect.UPGRADE_MANUAL_ACTION_REQUIRED) && |
| | | cause.getLocalizedUpgradeMessage() != null); |
| | | } |
| | | return isAction; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | protected boolean isWarning(VersionCompatibilityIssue.Cause cause) { |
| | | boolean isWarning = false; |
| | | if (cause != null && !isActionRequired(cause)) { |
| | | Set<VersionCompatibilityIssue.Effect> effects = cause.getEffects(); |
| | | isWarning = effects.contains(Effect.UPGRADE_SHOW_WARNING_MESSAGE) && |
| | | cause.getLocalizedUpgradeMessage() != null; |
| | | } |
| | | return isWarning; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | protected boolean isUnsupported(VersionCompatibilityIssue.Cause cause) { |
| | | boolean isUnsupported = false; |
| | | if (cause != null) { |
| | | Set<VersionCompatibilityIssue.Effect> effects = cause.getEffects(); |
| | | for (VersionCompatibilityIssue.Effect effect : effects) { |
| | | switch (effect) { |
| | | case UPGRADE_NOT_POSSIBLE: |
| | | isUnsupported = true; break; |
| | | default: |
| | | // assume not an tion; |
| | | } |
| | | } |
| | | } |
| | | return isUnsupported; |
| | | } |
| | | |
| | | } |