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 }