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-2010 Sun Microsystems, Inc. 015 * Portions Copyright 2012-2015 ForgeRock AS. 016 */ 017 018package org.opends.quicksetup; 019 020import org.forgerock.i18n.LocalizableMessage; 021import org.forgerock.i18n.LocalizableMessageBuilder; 022 023import static org.opends.messages.AdminToolMessages.*; 024import static com.forgerock.opendj.cli.Utils.wrapText; 025 026import org.opends.quicksetup.util.Utils; 027import com.forgerock.opendj.cli.ClientException; 028import com.forgerock.opendj.cli.ConsoleApplication; 029import com.forgerock.opendj.cli.Menu; 030import com.forgerock.opendj.cli.MenuBuilder; 031import com.forgerock.opendj.cli.MenuResult; 032 033import java.util.List; 034 035import org.forgerock.i18n.slf4j.LocalizedLogger; 036 037/** 038 * Supports user interactions for a command line driven application. 039 */ 040public class CliUserInteraction extends ConsoleApplication 041 implements UserInteraction { 042 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 043 044 private final boolean isInteractive; 045 private final boolean isForceOnError; 046 047 /** 048 * Creates an instance that will use standard streams for interaction and with 049 * the provided CLI arguments. 050 * @param ud The CLI arguments. 051 */ 052 public CliUserInteraction(UserData ud) { 053 isInteractive = ud == null || ud.isInteractive(); 054 isForceOnError = ud != null && ud.isForceOnError(); 055 } 056 057 /** {@inheritDoc} */ 058 public Object confirm(LocalizableMessage summary, LocalizableMessage details, 059 LocalizableMessage title, MessageType type, LocalizableMessage[] options, 060 LocalizableMessage def) { 061 return confirm(summary, details, null, title, type, options, def, null); 062 } 063 064 /** {@inheritDoc} */ 065 public Object confirm(LocalizableMessage summary, LocalizableMessage details, LocalizableMessage fineDetails, 066 LocalizableMessage title, MessageType type, LocalizableMessage[] options, 067 LocalizableMessage def, LocalizableMessage viewDetailsOption) { 068 MenuBuilder<Integer> builder = new MenuBuilder<>(this); 069 070 LocalizableMessageBuilder b = new LocalizableMessageBuilder(); 071 b.append(summary); 072 b.append(Constants.LINE_SEPARATOR); 073 b.append(details); 074 builder.setPrompt(b.toMessage()); 075 076 int defInt = -1; 077 for (int i=0; i<options.length; i++) 078 { 079 builder.addNumberedOption(options[i], MenuResult.success(i+1)); 080 if (options[i].equals(def)) 081 { 082 defInt = i+1; 083 } 084 } 085 086 if (fineDetails != null) { 087 LocalizableMessage detailsPrompt = viewDetailsOption; 088 if (detailsPrompt == null) 089 { 090 detailsPrompt = INFO_CLI_VIEW_DETAILS.get(); 091 } 092 builder.addNumberedOption(detailsPrompt, 093 MenuResult.success(options.length + 1)); 094 } 095 096 builder.setDefault(LocalizableMessage.raw(String.valueOf(defInt)), 097 MenuResult.success(defInt)); 098 099 Menu<Integer> menu = builder.toMenu(); 100 101 Object returnValue = null; 102 boolean menuDisplayed = false; 103 while (returnValue == null) { 104 int respInt; 105 try 106 { 107 if (menuDisplayed) 108 { 109 println(); 110 builder.setPrompt(null); 111 menu = builder.toMenu(); 112 } 113 MenuResult<Integer> m = menu.run(); 114 menuDisplayed = true; 115 116 if (m.isSuccess()) 117 { 118 respInt = m.getValue(); 119 } 120 else 121 { 122 // Should never happen. 123 throw new RuntimeException(); 124 } 125 } 126 catch (ClientException ce) 127 { 128 respInt = defInt; 129 logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce)); 130 } 131 if (fineDetails != null && respInt == options.length + 1) { 132 println(); 133 println(String.valueOf(fineDetails)); 134 } else { 135 returnValue = options[respInt - 1]; 136 } 137 } 138 return returnValue; 139 } 140 141 /** {@inheritDoc} */ 142 public String createUnorderedList(List<?> list) { 143 StringBuilder sb = new StringBuilder(); 144 if (list != null) { 145 for (Object o : list) { 146 sb.append(/*bullet=*/"* "); 147 sb.append(o); 148 sb.append(Constants.LINE_SEPARATOR); 149 } 150 } 151 return sb.toString(); 152 } 153 154 private void println(String text) { 155 text = Utils.convertHtmlBreakToLineSeparator(text); 156 text = Utils.stripHtml(text); 157 text = wrapText(text, Utils.getCommandLineMaxLineWidth()); 158 getErrorStream().println(text); 159 } 160 161 /** {@inheritDoc} */ 162 public boolean isAdvancedMode() { 163 return false; 164 } 165 166 /** {@inheritDoc} */ 167 public boolean isInteractive() { 168 return isInteractive; 169 } 170 171 /** {@inheritDoc} */ 172 @Override 173 public boolean isMenuDrivenMode() { 174 return true; 175 } 176 177 /** {@inheritDoc} */ 178 public boolean isQuiet() { 179 return false; 180 } 181 182 /** {@inheritDoc} */ 183 public boolean isScriptFriendly() { 184 return false; 185 } 186 187 /** {@inheritDoc} */ 188 public boolean isVerbose() { 189 return true; 190 } 191 192 /** {@inheritDoc} */ 193 public boolean isCLI() 194 { 195 return true; 196 } 197 198 /** {@inheritDoc} */ 199 public boolean isForceOnError() { 200 return isForceOnError; 201 } 202}