001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Portions Copyright 2013-2016 ForgeRock AS.
015 */
016package org.opends.server.tools.upgrade;
017
018import static org.opends.messages.ToolMessages.*;
019
020import javax.security.auth.callback.Callback;
021import javax.security.auth.callback.CallbackHandler;
022import javax.security.auth.callback.ConfirmationCallback;
023import javax.security.auth.callback.TextOutputCallback;
024
025import org.forgerock.i18n.LocalizableMessage;
026import org.opends.server.types.InitializationException;
027import org.opends.server.util.BuildVersion;
028
029import com.forgerock.opendj.cli.ClientException;
030import com.forgerock.opendj.cli.ReturnCode;
031
032/**
033 * Context information which is passed to upgrade tasks. This might include
034 * server configuration, etc.
035 */
036public final class UpgradeContext
037{
038  /** The version we upgrade from. */
039  private final BuildVersion fromVersion;
040  /** The version we want to upgrade to. */
041  private final BuildVersion toVersion;
042
043  /** The call-back handler for interacting with the upgrade application. */
044  private final CallbackHandler handler;
045
046  /** If ignore errors is enabled. */
047  private boolean isIgnoreErrorsMode;
048  /** If accept license is enabled. */
049  private boolean isAcceptLicenseMode;
050  /** If interactive mode is enabled. */
051  private boolean isInteractiveMode;
052  /** If force upgrade is enabled. */
053  private boolean isForceUpgradeMode;
054
055  /**
056   * Creates a new upgrade context for upgrading from the instance version (as
057   * obtained from config/buildinfo) to the binary version.
058   *
059   * @param handler
060   *          The call-back handler for interacting with the upgrade
061   *          application.
062   * @throws InitializationException
063   *           If an error occurred while reading or parsing the version.
064   */
065  public UpgradeContext(CallbackHandler handler) throws InitializationException
066  {
067    this(BuildVersion.instanceVersion(), BuildVersion.binaryVersion(), handler);
068  }
069
070  /**
071   * Constructor for the upgrade context.
072   *
073   * @param fromVersion
074   *          The version number from we upgrade from.
075   * @param toVersion
076   *          The version number we want to upgrade to.
077   * @param handler
078   *          The call-back handler for interacting with the upgrade
079   *          application.
080   */
081  public UpgradeContext(final BuildVersion fromVersion,
082      final BuildVersion toVersion, CallbackHandler handler)
083  {
084    this.fromVersion = fromVersion;
085    this.toVersion = toVersion;
086    this.handler = handler;
087  }
088
089  /**
090   * Returns the old version.
091   *
092   * @return The old version.
093   */
094  BuildVersion getFromVersion()
095  {
096    return fromVersion;
097  }
098
099  /**
100   * Returns the new version.
101   *
102   * @return The new version.
103   */
104  BuildVersion getToVersion()
105  {
106    return toVersion;
107  }
108
109  /**
110   * Returns the ignore error mode.
111   *
112   * @return {code true} if ignore error mode is activated.
113   */
114  boolean isIgnoreErrorsMode()
115  {
116    return isIgnoreErrorsMode;
117  }
118
119  /**
120   * Sets the ignore errors mode.
121   *
122   * @param isIgnoreErrorsMode
123   *          {@code true} if ignore error mode is activated.
124   * @return This upgrade context.
125   */
126  public UpgradeContext setIgnoreErrorsMode(boolean isIgnoreErrorsMode)
127  {
128    this.isIgnoreErrorsMode = isIgnoreErrorsMode;
129    return this;
130  }
131
132  /**
133   * Returns the accept license mode.
134   *
135   * @return {@code true} if accept license mode is activated.
136   */
137  boolean isAcceptLicenseMode()
138  {
139    return isAcceptLicenseMode;
140  }
141
142  /**
143   * Sets the accept license mode.
144   *
145   * @param isAcceptLicenseMode
146   *          {@code true} if the accept license mode is activated.
147   * @return This upgrade context.
148   */
149  public UpgradeContext setAcceptLicenseMode(boolean isAcceptLicenseMode)
150  {
151    this.isAcceptLicenseMode = isAcceptLicenseMode;
152    return this;
153  }
154
155  /**
156   * Returns the callback handler.
157   *
158   * @return The actual callback handler.
159   */
160  CallbackHandler getHandler()
161  {
162    return handler;
163  }
164
165  /**
166   * Returns the status of the interactive mode.
167   *
168   * @return {@code true} if interactive mode is activated.
169   */
170  boolean isInteractiveMode()
171  {
172    return isInteractiveMode;
173  }
174
175  /**
176   * Sets the interactive mode.
177   *
178   * @param isInteractiveMode
179   *          {@code true} if the interactive mode is activated.
180   * @return This upgrade context.
181   */
182  public UpgradeContext setInteractiveMode(boolean isInteractiveMode)
183  {
184    this.isInteractiveMode = isInteractiveMode;
185    return this;
186  }
187
188  /**
189   * Returns the status of the force upgrade mode.
190   *
191   * @return {@code true} if the force upgrade mode is activated.
192   */
193  boolean isForceUpgradeMode()
194  {
195    return isForceUpgradeMode;
196  }
197
198  /**
199   * Sets the force upgrade mode.
200   *
201   * @param isForceUpgradeMode
202   *          {@code true} if the force upgrade mode is activated.
203   * @return This upgrade context.
204   */
205  public UpgradeContext setForceUpgradeMode(boolean isForceUpgradeMode)
206  {
207    this.isForceUpgradeMode = isForceUpgradeMode;
208    return this;
209  }
210
211  /**
212   * Sends notification message to the application via the call-back handler.
213   *
214   * @param message
215   *          The message to be reported.
216   * @throws ClientException
217   *           If an error occurred while reporting the message.
218   */
219  void notify(final LocalizableMessage message) throws ClientException
220  {
221    try
222    {
223      handler.handle(new Callback[] { new TextOutputCallback(
224          TextOutputCallback.INFORMATION, message.toString()) });
225    }
226    catch (final Exception e)
227    {
228      throw new ClientException(ReturnCode.ERROR_UNEXPECTED,
229          ERR_UPGRADE_DISPLAY_NOTIFICATION_ERROR.get(e.getMessage()));
230    }
231  }
232
233  /**
234   * Sends notification message to the application via the call-back handler
235   * containing specific sub type message.
236   *
237   * @param message
238   *          The message to be reported.
239   * @param msgType
240   *          The sub type message. The message to be reported.
241   * @throws ClientException
242   *           If an error occurred while reporting the message.
243   */
244  void notify(final LocalizableMessage message, final int msgType) throws ClientException
245  {
246    try
247    {
248      handler.handle(new Callback[] { new FormattedNotificationCallback(
249          message, msgType) });
250    }
251    catch (final Exception e)
252    {
253      throw new ClientException(ReturnCode.ERROR_UNEXPECTED,
254          ERR_UPGRADE_DISPLAY_NOTIFICATION_ERROR.get(e.getMessage()));
255    }
256  }
257
258  /**
259   * Displays a progress callback.
260   *
261   * @param callback
262   *          The callback to display.
263   * @throws ClientException
264   *           If an error occurred while reporting the message.
265   */
266  void notifyProgress(final ProgressNotificationCallback callback)
267      throws ClientException
268  {
269    try
270    {
271      handler.handle(new Callback[] { callback });
272    }
273    catch (final Exception e)
274    {
275      throw new ClientException(ReturnCode.ERROR_UNEXPECTED,
276          ERR_UPGRADE_DISPLAY_NOTIFICATION_ERROR.get(e.getMessage()));
277    }
278  }
279
280  /**
281   * Asks a confirmation to the user. Answer is yes or no.
282   *
283   * @param message
284   *          The message to be reported.
285   * @param defaultOption
286   *          The default selected option for this callback.
287   * @throws ClientException
288   *           If an error occurred while reporting the message.
289   * @return an integer corresponding to the user's answer.
290   */
291  int confirmYN(final LocalizableMessage message, final int defaultOption)
292      throws ClientException
293  {
294    final ConfirmationCallback confirmYNCallback = new ConfirmationCallback(
295        message.toString(), ConfirmationCallback.WARNING,
296        ConfirmationCallback.YES_NO_OPTION, defaultOption);
297    try
298    {
299      handler.handle(new Callback[] { confirmYNCallback });
300    }
301    catch (final Exception e)
302    {
303      throw new ClientException(ReturnCode.ERROR_UNEXPECTED,
304          ERR_UPGRADE_DISPLAY_CONFIRM_ERROR.get(e.getMessage()));
305    }
306    return confirmYNCallback.getSelectedIndex();
307  }
308
309  @Override
310  public String toString()
311  {
312    return "Upgrade from " + fromVersion + " to " + toVersion;
313  }
314}