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