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 * Copyright 2008-2009 Sun Microsystems, Inc.
015 * Portions Copyright 2014-2016 ForgeRock AS.
016 */
017package org.opends.quicksetup;
018
019import static com.forgerock.opendj.cli.Utils.*;
020
021import org.forgerock.i18n.LocalizableMessage;
022import org.forgerock.i18n.slf4j.LocalizedLogger;
023import org.opends.quicksetup.event.ProgressUpdateEvent;
024import org.opends.quicksetup.event.ProgressUpdateListener;
025import org.opends.quicksetup.util.PlainTextProgressMessageFormatter;
026import org.opends.quicksetup.util.ProgressMessageFormatter;
027import org.opends.quicksetup.util.Utils;
028
029import com.forgerock.opendj.cli.ClientException;
030
031/** Class used by Launcher to start a CLI application. */
032public class QuickSetupCli {
033
034  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
035
036  /** Arguments passed in the command line. */
037  private final Launcher launcher;
038  private final CliApplication cliApp;
039  private UserData userData;
040
041  /**
042   * Creates a QuickSetupCli instance.
043   * @param cliApp the application to be run
044   * @param launcher that launched the app
045   */
046  public QuickSetupCli(CliApplication cliApp, Launcher launcher) {
047    this.cliApp = cliApp;
048    this.launcher = launcher;
049  }
050
051  /**
052   * Gets the user data this application will use when running.
053   * @return UserData to use when running
054   */
055  public UserData getUserData() {
056    return this.userData;
057  }
058
059  /**
060   * Parses the user data and prompts the user for data if required.  If the
061   * user provides all the required data it launches the application.
062   *
063   * @return the return code (SUCCESSFUL, CANCELLED, USER_DATA_ERROR,
064   * ERROR_ACCESSING_FILE_SYSTEM, ERROR_STOPPING_SERVER or BUG.
065   */
066  ReturnCode run()
067  {
068    ReturnCode returnValue;
069    // Parse the arguments
070    try
071    {
072      ProgressMessageFormatter formatter =
073        new PlainTextProgressMessageFormatter();
074      cliApp.setProgressMessageFormatter(formatter);
075      userData = cliApp.createUserData(launcher);
076      if (userData != null)
077      {
078        cliApp.setUserData(userData);
079        if (!userData.isQuiet()) {
080          cliApp.addProgressUpdateListener(
081                  new ProgressUpdateListener() {
082                    @Override
083                    public void progressUpdate(ProgressUpdateEvent ev) {
084                      LocalizableMessage newLogs = ev.getNewLogs();
085                      if (newLogs != null) {
086                        System.out.print(
087                                wrapText(newLogs, Utils.getCommandLineMaxLineWidth()));
088                      }
089                    }
090                  });
091        }
092        Thread appThread = new Thread(cliApp, "CLI Application");
093        logger.info(LocalizableMessage.raw("Launching application"));
094        appThread.start();
095        while (!Thread.State.TERMINATED.equals(appThread.getState())) {
096          try {
097            Thread.sleep(100);
098          } catch (Exception ex) {
099            // do nothing;
100          }
101        }
102        returnValue = cliApp.getReturnCode();
103        logger.info(LocalizableMessage.raw("Application returnValue: "+returnValue));
104        if (returnValue == null) {
105          ApplicationException ue = cliApp.getRunError();
106          if (ue != null)
107          {
108            logger.info(LocalizableMessage.raw("Application run error: "+ue, ue));
109            returnValue = ue.getType();
110          }
111          else
112          {
113            returnValue = ReturnCode.SUCCESSFUL;
114          }
115        }
116      }
117      else
118      {
119        // User cancelled operation.
120        returnValue = ReturnCode.CANCELED;
121      }
122    }
123    catch (UserDataException uude)
124    {
125      logger.error(LocalizableMessage.raw("UserDataException: "+uude, uude));
126      System.err.println();
127      System.err.println(wrapText(uude.getLocalizedMessage(),
128              Utils.getCommandLineMaxLineWidth()));
129      System.err.println();
130      if (uude.getCause() instanceof ClientException)
131      {
132        returnValue = ReturnCode.USER_INPUT_ERROR;
133      }
134      else
135      {
136        returnValue = ReturnCode.USER_DATA_ERROR;
137      }
138    }
139    catch (ApplicationException ae)
140    {
141      logger.error(LocalizableMessage.raw("ApplicationException: "+ae, ae));
142      System.err.println();
143      System.err.println(ae.getLocalizedMessage());
144      System.err.println();
145      returnValue = ae.getType();
146    }
147    catch (Throwable t)
148    {
149      logger.error(LocalizableMessage.raw("Unexpected error: "+t, t));
150      returnValue = ReturnCode.UNKNOWN;
151    }
152    logger.info(LocalizableMessage.raw("returnValue: "+returnValue.getReturnCode()));
153    return returnValue;
154  }
155
156}