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  private 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 status of the interactive mode.
157   *
158   * @return {@code true} if interactive mode is activated.
159   */
160  boolean isInteractiveMode()
161  {
162    return isInteractiveMode;
163  }
164
165  /**
166   * Sets the interactive mode.
167   *
168   * @param isInteractiveMode
169   *          {@code true} if the interactive mode is activated.
170   * @return This upgrade context.
171   */
172  public UpgradeContext setInteractiveMode(boolean isInteractiveMode)
173  {
174    this.isInteractiveMode = isInteractiveMode;
175    return this;
176  }
177
178  /**
179   * Returns the status of the force upgrade mode.
180   *
181   * @return {@code true} if the force upgrade mode is activated.
182   */
183  boolean isForceUpgradeMode()
184  {
185    return isForceUpgradeMode;
186  }
187
188  /**
189   * Sets the force upgrade mode.
190   *
191   * @param isForceUpgradeMode
192   *          {@code true} if the force upgrade mode is activated.
193   * @return This upgrade context.
194   */
195  public UpgradeContext setForceUpgradeMode(boolean isForceUpgradeMode)
196  {
197    this.isForceUpgradeMode = isForceUpgradeMode;
198    return this;
199  }
200
201  /**
202   * Sends notification message to the application via the call-back handler.
203   *
204   * @param message
205   *          The message to be reported.
206   * @throws ClientException
207   *           If an error occurred while reporting the message.
208   */
209  void notify(final LocalizableMessage message) throws ClientException
210  {
211    try
212    {
213      handler.handle(new Callback[] { new TextOutputCallback(
214          TextOutputCallback.INFORMATION, message.toString()) });
215    }
216    catch (final Exception e)
217    {
218      throw new ClientException(ReturnCode.ERROR_UNEXPECTED,
219          ERR_UPGRADE_DISPLAY_NOTIFICATION_ERROR.get(e.getMessage()));
220    }
221  }
222
223  /**
224   * Sends notification message to the application via the call-back handler
225   * containing specific sub type message.
226   *
227   * @param message
228   *          The message to be reported.
229   * @param msgType
230   *          The sub type message. The message to be reported.
231   * @throws ClientException
232   *           If an error occurred while reporting the message.
233   */
234  void notify(final LocalizableMessage message, final int msgType) throws ClientException
235  {
236    try
237    {
238      handler.handle(new Callback[] { new FormattedNotificationCallback(
239          message, msgType) });
240    }
241    catch (final Exception e)
242    {
243      throw new ClientException(ReturnCode.ERROR_UNEXPECTED,
244          ERR_UPGRADE_DISPLAY_NOTIFICATION_ERROR.get(e.getMessage()));
245    }
246  }
247
248  /**
249   * Displays a progress callback.
250   *
251   * @param callback
252   *          The callback to display.
253   * @throws ClientException
254   *           If an error occurred while reporting the message.
255   */
256  void notifyProgress(final ProgressNotificationCallback callback)
257      throws ClientException
258  {
259    try
260    {
261      handler.handle(new Callback[] { callback });
262    }
263    catch (final Exception e)
264    {
265      throw new ClientException(ReturnCode.ERROR_UNEXPECTED,
266          ERR_UPGRADE_DISPLAY_NOTIFICATION_ERROR.get(e.getMessage()));
267    }
268  }
269
270  /**
271   * Asks a confirmation to the user. Answer is yes or no.
272   *
273   * @param message
274   *          The message to be reported.
275   * @param defaultOption
276   *          The default selected option for this callback.
277   * @throws ClientException
278   *           If an error occurred while reporting the message.
279   * @return an integer corresponding to the user's answer.
280   */
281  int confirmYN(final LocalizableMessage message, final int defaultOption)
282      throws ClientException
283  {
284    final ConfirmationCallback confirmYNCallback = new ConfirmationCallback(
285        message.toString(), ConfirmationCallback.WARNING,
286        ConfirmationCallback.YES_NO_OPTION, defaultOption);
287    try
288    {
289      handler.handle(new Callback[] { confirmYNCallback });
290    }
291    catch (final Exception e)
292    {
293      throw new ClientException(ReturnCode.ERROR_UNEXPECTED,
294          ERR_UPGRADE_DISPLAY_CONFIRM_ERROR.get(e.getMessage()));
295    }
296    return confirmYNCallback.getSelectedIndex();
297  }
298
299  @Override
300  public String toString()
301  {
302    return "Upgrade from " + fromVersion + " to " + toVersion;
303  }
304}