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