1/*
2 * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package javax.security.auth.callback;
27
28/**
29 * <p> Underlying security services instantiate and pass a
30 * {@code ChoiceCallback} to the {@code handle}
31 * method of a {@code CallbackHandler} to display a list of choices
32 * and to retrieve the selected choice(s).
33 *
34 * @since 1.4
35 * @see javax.security.auth.callback.CallbackHandler
36 */
37public class ChoiceCallback implements Callback, java.io.Serializable {
38
39    private static final long serialVersionUID = -3975664071579892167L;
40
41    /**
42     * @serial
43     * @since 1.4
44     */
45    private String prompt;
46    /**
47     * @serial the list of choices
48     * @since 1.4
49     */
50    private String[] choices;
51    /**
52     * @serial the choice to be used as the default choice
53     * @since 1.4
54     */
55    private int defaultChoice;
56    /**
57     * @serial whether multiple selections are allowed from the list of
58     * choices
59     * @since 1.4
60     */
61    private boolean multipleSelectionsAllowed;
62    /**
63     * @serial the selected choices, represented as indexes into the
64     *          {@code choices} list.
65     * @since 1.4
66     */
67    private int[] selections;
68
69    /**
70     * Construct a {@code ChoiceCallback} with a prompt,
71     * a list of choices, a default choice, and a boolean specifying
72     * whether or not multiple selections from the list of choices are allowed.
73     *
74     *
75     * @param prompt the prompt used to describe the list of choices.
76     *
77     * @param choices the list of choices.
78     *
79     * @param defaultChoice the choice to be used as the default choice
80     *                  when the list of choices are displayed.  This value
81     *                  is represented as an index into the
82     *                  {@code choices} array.
83     *
84     * @param multipleSelectionsAllowed boolean specifying whether or
85     *                  not multiple selections can be made from the
86     *                  list of choices.
87     *
88     * @exception IllegalArgumentException if {@code prompt} is null,
89     *                  if {@code prompt} has a length of 0,
90     *                  if {@code choices} is null,
91     *                  if {@code choices} has a length of 0,
92     *                  if any element from {@code choices} is null,
93     *                  if any element from {@code choices}
94     *                  has a length of 0 or if {@code defaultChoice}
95     *                  does not fall within the array boundaries of
96     *                  {@code choices}.
97     */
98    public ChoiceCallback(String prompt, String[] choices,
99                int defaultChoice, boolean multipleSelectionsAllowed) {
100
101        if (prompt == null || prompt.length() == 0 ||
102            choices == null || choices.length == 0 ||
103            defaultChoice < 0 || defaultChoice >= choices.length)
104            throw new IllegalArgumentException();
105
106        for (int i = 0; i < choices.length; i++) {
107            if (choices[i] == null || choices[i].length() == 0)
108                throw new IllegalArgumentException();
109        }
110
111        this.prompt = prompt;
112        this.choices = choices;
113        this.defaultChoice = defaultChoice;
114        this.multipleSelectionsAllowed = multipleSelectionsAllowed;
115    }
116
117    /**
118     * Get the prompt.
119     *
120     * @return the prompt.
121     */
122    public String getPrompt() {
123        return prompt;
124    }
125
126    /**
127     * Get the list of choices.
128     *
129     * @return the list of choices.
130     */
131    public String[] getChoices() {
132        return choices;
133    }
134
135    /**
136     * Get the defaultChoice.
137     *
138     * @return the defaultChoice, represented as an index into
139     *          the {@code choices} list.
140     */
141    public int getDefaultChoice() {
142        return defaultChoice;
143    }
144
145    /**
146     * Get the boolean determining whether multiple selections from
147     * the {@code choices} list are allowed.
148     *
149     * @return whether multiple selections are allowed.
150     */
151    public boolean allowMultipleSelections() {
152        return multipleSelectionsAllowed;
153    }
154
155    /**
156     * Set the selected choice.
157     *
158     * @param selection the selection represented as an index into the
159     *          {@code choices} list.
160     *
161     * @see #getSelectedIndexes
162     */
163    public void setSelectedIndex(int selection) {
164        this.selections = new int[1];
165        this.selections[0] = selection;
166    }
167
168    /**
169     * Set the selected choices.
170     *
171     * @param selections the selections represented as indexes into the
172     *          {@code choices} list.
173     *
174     * @exception UnsupportedOperationException if multiple selections are
175     *          not allowed, as determined by
176     *          {@code allowMultipleSelections}.
177     *
178     * @see #getSelectedIndexes
179     */
180    public void setSelectedIndexes(int[] selections) {
181        if (!multipleSelectionsAllowed)
182            throw new UnsupportedOperationException();
183        this.selections = selections;
184    }
185
186    /**
187     * Get the selected choices.
188     *
189     * @return the selected choices, represented as indexes into the
190     *          {@code choices} list.
191     *
192     * @see #setSelectedIndexes
193     */
194    public int[] getSelectedIndexes() {
195        return selections;
196    }
197}
198