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 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.util.cli; 028 029 030 031 import java.util.ArrayList; 032 import java.util.Collection; 033 import java.util.Collections; 034 035 036 037 /** 038 * The result of running a {@link Menu}. The result indicates to the 039 * application how it should proceed: 040 * <ul> 041 * <li>{@link #again()} - the menu should be displayed again. A good 042 * example of this is when a user chooses to view some help. Normally, 043 * after the help is displayed, the user is allowed to select another 044 * option 045 * <li>{@link #cancel()} - the user chose to cancel any task 046 * currently in progress and go back to the previous main menu if 047 * applicable 048 * <li>{@link #success()} - the user chose to apply any task 049 * currently in progress and go back to the previous menu if 050 * applicable. Any result values applicable to the chosen option can 051 * be retrieved using {@link #getValue()} or {@link #getValues()} 052 * <li>{@link #quit()} - the user chose to quit the application and 053 * cancel all outstanding tasks. 054 * </ul> 055 * 056 * @param <T> 057 * The type of result value(s) contained in success results. 058 * Use <code>Void</code> if success results should not 059 * contain values. 060 */ 061 public final class MenuResult<T> { 062 063 /** 064 * The type of result returned from the menu. 065 */ 066 private static enum Type { 067 /** 068 * The user selected an option which did not return a result, so 069 * the menu should be displayed again. 070 */ 071 AGAIN, 072 073 /** 074 * The user did not select an option and instead chose to cancel 075 * the current task. 076 */ 077 CANCEL, 078 079 /** 080 * The user did not select an option and instead chose to quit the 081 * entire application. 082 */ 083 QUIT, 084 085 /** 086 * The user selected an option which succeeded and returned one or 087 * more result values. 088 */ 089 SUCCESS 090 } 091 092 093 094 /** 095 * Creates a new menu result indicating that the menu should be 096 * displayed again. A good example of this is when a user chooses to 097 * view some help. Normally, after the help is displayed, the user 098 * is allowed to select another option. 099 * 100 * @param <T> 101 * The type of result value(s) contained in success 102 * results. Use <code>Void</code> if success results 103 * should not contain values. 104 * @return Returns a new menu result indicating that the menu should 105 * be displayed again. 106 */ 107 public static <T> MenuResult<T> again() { 108 return new MenuResult<T>(Type.AGAIN, Collections.<T> emptyList()); 109 } 110 111 112 113 /** 114 * Creates a new menu result indicating that the user chose to 115 * cancel any task currently in progress and go back to the previous 116 * main menu if applicable. 117 * 118 * @param <T> 119 * The type of result value(s) contained in success 120 * results. Use <code>Void</code> if success results 121 * should not contain values. 122 * @return Returns a new menu result indicating that the user chose 123 * to cancel any task currently in progress and go back to 124 * the previous main menu if applicable. 125 */ 126 public static <T> MenuResult<T> cancel() { 127 return new MenuResult<T>(Type.CANCEL, Collections.<T> emptyList()); 128 } 129 130 131 132 /** 133 * Creates a new menu result indicating that the user chose to quit 134 * the application and cancel all outstanding tasks. 135 * 136 * @param <T> 137 * The type of result value(s) contained in success 138 * results. Use <code>Void</code> if success results 139 * should not contain values. 140 * @return Returns a new menu result indicating that the user chose 141 * to quit the application and cancel all outstanding tasks. 142 */ 143 public static <T> MenuResult<T> quit() { 144 return new MenuResult<T>(Type.QUIT, Collections.<T> emptyList()); 145 } 146 147 148 149 /** 150 * Creates a new menu result indicating that the user chose to apply 151 * any task currently in progress and go back to the previous menu 152 * if applicable. The menu result will not contain any result 153 * values. 154 * 155 * @param <T> 156 * The type of result value(s) contained in success 157 * results. Use <code>Void</code> if success results 158 * should not contain values. 159 * @return Returns a new menu result indicating that the user chose 160 * to apply any task currently in progress and go back to 161 * the previous menu if applicable.The menu result will not 162 * contain any result values. 163 */ 164 public static <T> MenuResult<T> success() { 165 return success(Collections.<T> emptySet()); 166 } 167 168 169 170 /** 171 * Creates a new menu result indicating that the user chose to apply 172 * any task currently in progress and go back to the previous menu 173 * if applicable. The menu result will contain the provided values, 174 * which can be retrieved using {@link #getValue()} or 175 * {@link #getValues()}. 176 * 177 * @param <T> 178 * The type of the result values. 179 * @param values 180 * The result values. 181 * @return Returns a new menu result indicating that the user chose 182 * to apply any task currently in progress and go back to 183 * the previous menu if applicable. The menu result will 184 * contain the provided values, which can be retrieved using 185 * {@link #getValue()} or {@link #getValues()}. 186 */ 187 public static <T> MenuResult<T> success(Collection<T> values) { 188 return new MenuResult<T>(Type.SUCCESS, new ArrayList<T>(values)); 189 } 190 191 192 193 /** 194 * Creates a new menu result indicating that the user chose to apply 195 * any task currently in progress and go back to the previous menu 196 * if applicable. The menu result will contain the provided value, 197 * which can be retrieved using {@link #getValue()} or 198 * {@link #getValues()}. 199 * 200 * @param <T> 201 * The type of the result value. 202 * @param value 203 * The result value. 204 * @return Returns a new menu result indicating that the user chose 205 * to apply any task currently in progress and go back to 206 * the previous menu if applicable. The menu result will 207 * contain the provided value, which can be retrieved using 208 * {@link #getValue()} or {@link #getValues()}. 209 */ 210 public static <T> MenuResult<T> success(T value) { 211 return success(Collections.singleton(value)); 212 } 213 214 // The type of result returned from the menu. 215 private final Type type; 216 217 // The menu result value(s). 218 private final Collection<T> values; 219 220 221 222 // Private constructor. 223 private MenuResult(Type type, Collection<T> values) { 224 this.type = type; 225 this.values = values; 226 } 227 228 229 230 /** 231 * Gets the menu result value if this is a menu result indicating 232 * success. 233 * 234 * @return Returns the menu result value, or <code>null</code> if 235 * there was no result value or if this is not a success 236 * menu result. 237 * @see #isSuccess() 238 */ 239 public T getValue() { 240 if (values.isEmpty()) { 241 return null; 242 } else { 243 return values.iterator().next(); 244 } 245 } 246 247 248 249 /** 250 * Gets the menu result values if this is a menu result indicating 251 * success. 252 * 253 * @return Returns the menu result values, which may be empty if 254 * there were no result values or if this is not a success 255 * menu result. 256 * @see #isSuccess() 257 */ 258 public Collection<T> getValues() { 259 return new ArrayList<T>(values); 260 } 261 262 263 264 /** 265 * Determines if this menu result indicates that the menu should be 266 * displayed again. A good example of this is when a user chooses to 267 * view some help. Normally, after the help is displayed, the user 268 * is allowed to select another option. 269 * 270 * @return Returns <code>true</code> if this menu result indicates 271 * that the menu should be displayed again. 272 */ 273 public boolean isAgain() { 274 return type == Type.AGAIN; 275 } 276 277 278 279 /** 280 * Determines if this menu result indicates that the user chose to 281 * cancel any task currently in progress and go back to the previous 282 * main menu if applicable. 283 * 284 * @return Returns <code>true</code> if this menu result indicates 285 * that the user chose to cancel any task currently in 286 * progress and go back to the previous main menu if 287 * applicable. 288 */ 289 public boolean isCancel() { 290 return type == Type.CANCEL; 291 } 292 293 294 295 /** 296 * Determines if this menu result indicates that the user chose to 297 * quit the application and cancel all outstanding tasks. 298 * 299 * @return Returns <code>true</code> if this menu result indicates 300 * that the user chose to quit the application and cancel 301 * all outstanding tasks. 302 */ 303 public boolean isQuit() { 304 return type == Type.QUIT; 305 } 306 307 308 309 /** 310 * Determines if this menu result indicates that the user chose to 311 * apply any task currently in progress and go back to the previous 312 * menu if applicable. Any result values can be retrieved using the 313 * {@link #getValue()} or {@link #getValues()} methods. 314 * 315 * @return Returns <code>true</code> if this menu result indicates 316 * that the user chose to apply any task currently in 317 * progress and go back to the previous menu if applicable. 318 * @see #getValue() 319 * @see #getValues() 320 */ 321 public boolean isSuccess() { 322 return type == Type.SUCCESS; 323 } 324 }