View Javadoc

1   /**
2    * LICENCIA LGPL:
3    * 
4    * Esta librería es Software Libre; Usted puede redistribuirla y/o modificarla
5    * bajo los términos de la GNU Lesser General Public License (LGPL) tal y como 
6    * ha sido publicada por la Free Software Foundation; o bien la versión 2.1 de 
7    * la Licencia, o (a su elección) cualquier versión posterior.
8    * 
9    * Esta librería se distribuye con la esperanza de que sea útil, pero SIN 
10   * NINGUNA GARANTÍA; tampoco las implícitas garantías de MERCANTILIDAD o 
11   * ADECUACIÓN A UN PROPÓSITO PARTICULAR. Consulte la GNU Lesser General Public 
12   * License (LGPL) para más detalles
13   * 
14   * Usted debe recibir una copia de la GNU Lesser General Public License (LGPL) 
15   * junto con esta librería; si no es así, escriba a la Free Software Foundation 
16   * Inc. 51 Franklin Street, 5º Piso, Boston, MA 02110-1301, USA o consulte
17   * <http://www.gnu.org/licenses/>.
18   *
19   * Copyright 2011 Agencia de Tecnología y Certificación Electrónica
20   */
21  package es.accv.arangi.base.device.util;
22  
23  import java.awt.Component;
24  import java.util.ArrayList;
25  import java.util.Iterator;
26  import java.util.List;
27  
28  import javax.security.auth.callback.Callback;
29  import javax.security.auth.callback.CallbackHandler;
30  import javax.security.auth.callback.ConfirmationCallback;
31  import javax.security.auth.callback.PasswordCallback;
32  import javax.security.auth.callback.UnsupportedCallbackException;
33  import javax.swing.Box;
34  import javax.swing.JLabel;
35  import javax.swing.JOptionPane;
36  import javax.swing.JPasswordField;
37  
38  public class CustomDialogCallbackHandler  implements CallbackHandler {
39  
40  	/* -- Fields -- */
41  
42      /* The parent window, or null if using the default parent */
43      private Component parentComponent;
44      private String customText = null;
45      private String customTitle = null;
46      private static final int JPasswordFieldLen = 8 ;
47  
48      /* -- Methods -- */
49  
50      /**
51       * Creates a callback dialog with the default parent window.
52       */
53      public CustomDialogCallbackHandler() { }
54      
55      /**
56       * Creates a callback dialog with the default parent window and a custom text dialog.
57       */
58      public CustomDialogCallbackHandler(String customText, String customTitle) { 
59      	this.customText = customText;
60      	this.customTitle = customTitle;
61      }
62  
63      /**
64       * Creates a callback dialog and specify the parent window.
65       *
66       * @param parentComponent the parent window -- specify <code>null</code>
67       * for the default parent
68       */
69      public CustomDialogCallbackHandler(Component parentComponent) {
70          this.parentComponent = parentComponent;
71      }
72  
73      /**
74       * Creates a callback dialog and specify the parent window and a custom text.
75       *
76       * @param parentComponent the parent window -- specify <code>null</code>
77       * for the default parent
78       */
79      public CustomDialogCallbackHandler(Component parentComponent, String customText, String customTitle) {
80          this.parentComponent = parentComponent;
81          this.customText = customText;
82          this.customTitle = customTitle;
83      }
84      
85      /*
86       * An interface for recording actions to carry out if the user
87       * clicks OK for the dialog.
88       */
89      private static interface Action {
90           void perform();
91      }
92  
93      /**
94       * Handles the specified set of callbacks.
95       *
96       * @param callbacks the callbacks to handle
97       * @throws UnsupportedCallbackException if the callback is not an
98       * instance  of NameCallback or PasswordCallback
99       */
100 
101     public void handle(Callback[] callbacks)
102         throws UnsupportedCallbackException
103     {
104         /* Collect messages to display in the dialog */
105         final List<Object> messages = new ArrayList<Object>(3);
106 
107         /* Collection actions to perform if the user clicks OK */
108         final List<Action> okActions = new ArrayList<Action>(2);
109 
110         ConfirmationInfo confirmation = new ConfirmationInfo();
111 
112         for (int i = 0; i < callbacks.length; i++) {
113             if (callbacks[i] instanceof PasswordCallback) {
114                 final PasswordCallback pc = (PasswordCallback) callbacks[i];
115 
116                 JLabel prompt = new JLabel();
117                 if (customText != null) {
118                 	prompt.setText(customText);
119 				} else {
120 					prompt.setText(pc.getPrompt());					
121 				}
122 
123                 final JPasswordField password =
124                                         new JPasswordField(JPasswordFieldLen);
125                 if (!pc.isEchoOn()) {
126                     password.setEchoChar('*');
127                 }
128 
129                 Box passwordPanel = Box.createHorizontalBox();
130                 passwordPanel.add(prompt);
131                 passwordPanel.add(password);
132                 messages.add(passwordPanel);
133 
134                 okActions.add(new Action() {
135                     public void perform() {
136                         pc.setPassword(password.getPassword());
137                     }
138                 });
139 
140             } else {
141                 throw new UnsupportedCallbackException(
142                     callbacks[i], "Unrecognized Callback");
143             }
144         }
145 
146         String title = customTitle != null ? customTitle : "Confirmation";
147         /* Display the dialog */
148         int result = JOptionPane.showOptionDialog(
149             parentComponent,
150             messages.toArray(),
151             title,                     /* title */
152             confirmation.optionType,
153             confirmation.messageType,
154             null,                               /* icon */
155             confirmation.options,               /* options */
156             confirmation.initialValue);         /* initialValue */
157 
158         /* Perform the OK actions */
159         if (result == JOptionPane.OK_OPTION
160             || result == JOptionPane.YES_OPTION)
161         {
162             Iterator<Action> iterator = okActions.iterator();
163             while (iterator.hasNext()) {
164                 iterator.next().perform();
165             }
166         }
167         confirmation.handleResult(result);
168     }
169 
170     /*
171      * Provides assistance with translating between JAAS and Swing
172      * confirmation dialogs.
173      */
174     private static class ConfirmationInfo {
175 
176         private int[] translations;
177 
178         int optionType = JOptionPane.OK_CANCEL_OPTION;
179         Object[] options = null;
180         Object initialValue = null;
181 
182         int messageType = JOptionPane.QUESTION_MESSAGE;
183 
184         private ConfirmationCallback callback;
185 
186         /* Set the confirmation callback handler */
187         void setCallback(ConfirmationCallback callback)
188             throws UnsupportedCallbackException
189         {
190             this.callback = callback;
191 
192             int confirmationOptionType = callback.getOptionType();
193             switch (confirmationOptionType) {
194             case ConfirmationCallback.YES_NO_OPTION:
195                 optionType = JOptionPane.YES_NO_OPTION;
196                 translations = new int[] {
197                     JOptionPane.YES_OPTION, ConfirmationCallback.YES,
198                     JOptionPane.NO_OPTION, ConfirmationCallback.NO,
199                     JOptionPane.CLOSED_OPTION, ConfirmationCallback.NO
200                 };
201                 break;
202             case ConfirmationCallback.YES_NO_CANCEL_OPTION:
203                 optionType = JOptionPane.YES_NO_CANCEL_OPTION;
204                 translations = new int[] {
205                     JOptionPane.YES_OPTION, ConfirmationCallback.YES,
206                     JOptionPane.NO_OPTION, ConfirmationCallback.NO,
207                     JOptionPane.CANCEL_OPTION, ConfirmationCallback.CANCEL,
208                     JOptionPane.CLOSED_OPTION, ConfirmationCallback.CANCEL
209                 };
210                 break;
211             case ConfirmationCallback.OK_CANCEL_OPTION:
212                 optionType = JOptionPane.OK_CANCEL_OPTION;
213                 translations = new int[] {
214                     JOptionPane.OK_OPTION, ConfirmationCallback.OK,
215                     JOptionPane.CANCEL_OPTION, ConfirmationCallback.CANCEL,
216                     JOptionPane.CLOSED_OPTION, ConfirmationCallback.CANCEL
217                 };
218                 break;
219             case ConfirmationCallback.UNSPECIFIED_OPTION:
220                 options = callback.getOptions();
221                 /*
222                  * There's no way to know if the default option means
223                  * to cancel the login, but there isn't a better way
224                  * to guess this.
225                  */
226                 translations = new int[] {
227                     JOptionPane.CLOSED_OPTION, callback.getDefaultOption()
228                 };
229                 break;
230             default:
231                 throw new UnsupportedCallbackException(
232                     callback,
233                     "Unrecognized option type: " + confirmationOptionType);
234             }
235 
236             int confirmationMessageType = callback.getMessageType();
237             switch (confirmationMessageType) {
238             case ConfirmationCallback.WARNING:
239                 messageType = JOptionPane.WARNING_MESSAGE;
240                 break;
241             case ConfirmationCallback.ERROR:
242                 messageType = JOptionPane.ERROR_MESSAGE;
243                 break;
244             case ConfirmationCallback.INFORMATION:
245                 messageType = JOptionPane.INFORMATION_MESSAGE;
246                 break;
247             default:
248                 throw new UnsupportedCallbackException(
249                     callback,
250                     "Unrecognized message type: " + confirmationMessageType);
251             }
252         }
253 
254 
255         /* Process the result returned by the Swing dialog */
256         void handleResult(int result) {
257             if (callback == null) {
258                 return;
259             }
260 
261             for (int i = 0; i < translations.length; i += 2) {
262                 if (translations[i] == result) {
263                     result = translations[i + 1];
264                     break;
265                 }
266             }
267             callback.setSelectedIndex(result);
268         }
269     }
270 
271 }