|
1 /* |
|
2 * CDDL HEADER START |
|
3 * |
|
4 * The contents of this file are subject to the terms of the |
|
5 * Common Development and Distribution License (the "License"). |
|
6 * You may not use this file except in compliance with the License. |
|
7 * |
|
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 * or http://www.opensolaris.org/os/licensing. |
|
10 * See the License for the specific language governing permissions |
|
11 * and limitations under the License. |
|
12 * |
|
13 * When distributing Covered Code, include this CDDL HEADER in each |
|
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 * If applicable, add the following below this CDDL HEADER, with the |
|
16 * fields enclosed by brackets "[]" replaced with your own identifying |
|
17 * information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 * |
|
19 * CDDL HEADER END |
|
20 */ |
|
21 |
|
22 /* |
|
23 * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. |
|
24 */ |
|
25 |
|
26 package com.oracle.solaris.vp.client.swing; |
|
27 |
|
28 import java.awt.*; |
|
29 import java.util.*; |
|
30 import java.util.List; |
|
31 import javax.swing.*; |
|
32 import javax.swing.event.*; |
|
33 import javax.swing.text.JTextComponent; |
|
34 import com.oracle.solaris.vp.panel.common.*; |
|
35 import com.oracle.solaris.vp.panel.common.action.*; |
|
36 import com.oracle.solaris.vp.util.misc.DialogMessage; |
|
37 import com.oracle.solaris.vp.util.misc.finder.Finder; |
|
38 import com.oracle.solaris.vp.util.swing.*; |
|
39 import com.oracle.solaris.vp.util.swing.layout.*; |
|
40 |
|
41 @SuppressWarnings({"serial"}) |
|
42 public class LoginPane extends DialogPane { |
|
43 // |
|
44 // Inner classes |
|
45 // |
|
46 |
|
47 private static interface LoginField<T> { |
|
48 T getValue(); |
|
49 |
|
50 void requestEditFocus(); |
|
51 |
|
52 void setEditable(boolean editable); |
|
53 |
|
54 void setValue(T text); |
|
55 |
|
56 void setVisible(boolean visible); |
|
57 } |
|
58 |
|
59 private static abstract class DualLoginField<T, C extends Component> |
|
60 extends JPanel implements LoginField<T> { |
|
61 |
|
62 // |
|
63 // Instance data |
|
64 // |
|
65 |
|
66 private JLabel label; |
|
67 private C field; |
|
68 |
|
69 // |
|
70 // Constructors |
|
71 // |
|
72 |
|
73 public DualLoginField() { |
|
74 super(new BorderLayout()); |
|
75 setOpaque(false); |
|
76 |
|
77 label = new JLabel(); |
|
78 add(label, BorderLayout.WEST); |
|
79 |
|
80 field = createField(); |
|
81 add(field, BorderLayout.NORTH); |
|
82 } |
|
83 |
|
84 // |
|
85 // LoginField methods |
|
86 // |
|
87 |
|
88 @Override |
|
89 public void requestEditFocus() { |
|
90 field.requestFocusInWindow(); |
|
91 } |
|
92 |
|
93 @Override |
|
94 public void setEditable(boolean editable) { |
|
95 label.setVisible(!editable); |
|
96 field.setVisible(editable); |
|
97 } |
|
98 |
|
99 // |
|
100 // DualLoginField methods |
|
101 // |
|
102 |
|
103 public abstract C createField(); |
|
104 |
|
105 public JLabel getLabel() { |
|
106 return label; |
|
107 } |
|
108 |
|
109 public C getField() { |
|
110 return field; |
|
111 } |
|
112 |
|
113 public String toDisplayableText(T value) { |
|
114 return value == null ? null : value.toString(); |
|
115 } |
|
116 |
|
117 protected void updateLabel() { |
|
118 getLabel().setText(toDisplayableText(getValue())); |
|
119 } |
|
120 } |
|
121 |
|
122 private static class LoginTextField |
|
123 extends DualLoginField<String, JTextField> { |
|
124 |
|
125 // |
|
126 // LoginField methods |
|
127 // |
|
128 |
|
129 @Override |
|
130 public String getValue() { |
|
131 String value = getField().getText(); |
|
132 if (value.isEmpty()) { |
|
133 value = null; |
|
134 } |
|
135 return value; |
|
136 } |
|
137 |
|
138 @Override |
|
139 public void requestEditFocus() { |
|
140 getField().selectAll(); |
|
141 super.requestEditFocus(); |
|
142 } |
|
143 |
|
144 @Override |
|
145 public void setValue(String text) { |
|
146 getField().setText(text); |
|
147 } |
|
148 |
|
149 // |
|
150 // DualLoginField methods |
|
151 // |
|
152 |
|
153 @Override |
|
154 public JTextField createField() { |
|
155 JTextField field = new JTextField(GUIUtil.getTextFieldWidth()); |
|
156 |
|
157 field.getDocument().addDocumentListener( |
|
158 new DocumentAdapter() { |
|
159 @Override |
|
160 public void docUpdate(DocumentEvent e) { |
|
161 updateLabel(); |
|
162 } |
|
163 }); |
|
164 |
|
165 return field; |
|
166 } |
|
167 } |
|
168 |
|
169 private static class LoginComboBox |
|
170 extends DualLoginField<String, JComboBox> { |
|
171 |
|
172 // |
|
173 // Instance data |
|
174 // |
|
175 |
|
176 private String nullText; |
|
177 |
|
178 // |
|
179 // Constructors |
|
180 // |
|
181 |
|
182 public LoginComboBox(String nullText) { |
|
183 this.nullText = nullText; |
|
184 updateLabel(); |
|
185 } |
|
186 |
|
187 // |
|
188 // LoginField methods |
|
189 // |
|
190 |
|
191 @Override |
|
192 public String getValue() { |
|
193 return (String)getField().getSelectedItem(); |
|
194 } |
|
195 |
|
196 @Override |
|
197 public void setValue(String text) { |
|
198 getField().getModel().setSelectedItem(text); |
|
199 } |
|
200 |
|
201 // |
|
202 // DualLoginField methods |
|
203 // |
|
204 |
|
205 @Override |
|
206 public JComboBox createField() { |
|
207 JComboBox field = new JComboBox(); |
|
208 if (!(field.getModel() instanceof DefaultComboBoxModel)) { |
|
209 field.setModel(new DefaultComboBoxModel()); |
|
210 } |
|
211 |
|
212 final ListCellRenderer renderer = field.getRenderer(); |
|
213 |
|
214 // Handle null values in the model |
|
215 field.setRenderer( |
|
216 new ListCellRenderer() { |
|
217 @Override |
|
218 public Component getListCellRendererComponent(JList list, |
|
219 Object value, int index, boolean isSelected, |
|
220 boolean cellHasFocus) { |
|
221 |
|
222 return renderer.getListCellRendererComponent(list, |
|
223 toDisplayableText((String)value), index, isSelected, |
|
224 cellHasFocus); |
|
225 } |
|
226 }); |
|
227 |
|
228 field.getModel().addListDataListener( |
|
229 new ListDataListener() { |
|
230 @Override |
|
231 public void contentsChanged(ListDataEvent e) { |
|
232 updateLabel(); |
|
233 } |
|
234 |
|
235 @Override |
|
236 public void intervalAdded(ListDataEvent e) { |
|
237 updateLabel(); |
|
238 } |
|
239 |
|
240 @Override |
|
241 public void intervalRemoved(ListDataEvent e) { |
|
242 updateLabel(); |
|
243 } |
|
244 }); |
|
245 |
|
246 return field; |
|
247 } |
|
248 |
|
249 @Override |
|
250 public String toDisplayableText(String value) { |
|
251 return value == null ? nullText : value; |
|
252 } |
|
253 } |
|
254 |
|
255 private static class LoginCheckBox extends JCheckBox |
|
256 implements LoginField<Boolean> { |
|
257 |
|
258 // |
|
259 // Instance data |
|
260 // |
|
261 |
|
262 private UneditableToggleButtonModel model; |
|
263 |
|
264 // |
|
265 // Constructors |
|
266 // |
|
267 |
|
268 public LoginCheckBox() { |
|
269 model = new UneditableToggleButtonModel(); |
|
270 setModel(model); |
|
271 } |
|
272 |
|
273 // |
|
274 // LoginField methods |
|
275 // |
|
276 |
|
277 @Override |
|
278 public Boolean getValue() { |
|
279 return isSelected(); |
|
280 } |
|
281 |
|
282 @Override |
|
283 public void requestEditFocus() { |
|
284 requestFocusInWindow(); |
|
285 } |
|
286 |
|
287 @Override |
|
288 public void setEditable(boolean editable) { |
|
289 model.setEditable(editable); |
|
290 } |
|
291 |
|
292 @Override |
|
293 public void setValue(Boolean checked) { |
|
294 model.setSelectedForced(checked != null && checked); |
|
295 } |
|
296 } |
|
297 |
|
298 // |
|
299 // Static data |
|
300 // |
|
301 |
|
302 private static final Color COLOR_LABEL_ERROR = Color.red.darker(); |
|
303 |
|
304 private static final String LABEL_HOST = |
|
305 Finder.getString("login.label.host"); |
|
306 |
|
307 private static final String LABEL_USER = |
|
308 Finder.getString("login.label.user"); |
|
309 |
|
310 private static final String LABEL_ROLE = |
|
311 Finder.getString("login.label.role"); |
|
312 |
|
313 private static final String LABEL_ZONEPROMPT = |
|
314 Finder.getString("login.label.zoneprompt"); |
|
315 |
|
316 private static final String LABEL_ZONE = |
|
317 Finder.getString("login.label.zone"); |
|
318 |
|
319 private static final String LABEL_ZONEUSER = |
|
320 Finder.getString("login.label.zoneuser"); |
|
321 |
|
322 private static final String LABEL_ZONEROLE = |
|
323 Finder.getString("login.label.zonerole"); |
|
324 |
|
325 // |
|
326 // Instance data |
|
327 // |
|
328 |
|
329 private JPanel fieldPanel; |
|
330 private int nCoreFields; |
|
331 |
|
332 private JLabel hostLabel; |
|
333 private LoginTextField hostField; |
|
334 |
|
335 private JLabel userLabel; |
|
336 private LoginTextField userField; |
|
337 |
|
338 private JLabel roleLabel; |
|
339 private LoginComboBox roleField; |
|
340 |
|
341 private LoginCheckBox zonePromptField; |
|
342 |
|
343 private JLabel zoneLabel; |
|
344 private LoginComboBox zoneField; |
|
345 |
|
346 private JLabel zoneUserLabel; |
|
347 private LoginTextField zoneUserField; |
|
348 |
|
349 private JLabel zoneRoleLabel; |
|
350 private LoginComboBox zoneRoleField; |
|
351 |
|
352 // |
|
353 // Constructors |
|
354 // |
|
355 |
|
356 public LoginPane() { |
|
357 createFieldPanel(); |
|
358 |
|
359 zonePromptField = new LoginCheckBox(); |
|
360 |
|
361 int gap = GUIUtil.getHalfGap(); |
|
362 JPanel panel = new JPanel(new BorderLayout(gap, gap)); |
|
363 panel.setOpaque(false); |
|
364 panel.add(fieldPanel, BorderLayout.CENTER); |
|
365 panel.add(zonePromptField, BorderLayout.SOUTH); |
|
366 |
|
367 setContent(panel, false, false); |
|
368 |
|
369 SettingsButtonBar buttonBar = getButtonBar(); |
|
370 |
|
371 JButton cancel = buttonBar.getCancelButton(); |
|
372 cancel.addActionListener(setClickedButtonActionListener); |
|
373 |
|
374 // Move to left side of dialog |
|
375 buttonBar.remove(cancel); |
|
376 buttonBar.add(cancel, 0); |
|
377 |
|
378 JButton close = buttonBar.getCloseButton(); |
|
379 close.addActionListener(setClickedButtonActionListener); |
|
380 |
|
381 JButton back = buttonBar.getBackButton(); |
|
382 back.addActionListener(setClickedButtonActionListener); |
|
383 |
|
384 JButton forward = buttonBar.getForwardButton(); |
|
385 forward.addActionListener(setClickedButtonActionListener); |
|
386 forward.setText(Finder.getString("login.button.forward")); |
|
387 } |
|
388 |
|
389 // |
|
390 // LoginPane methods |
|
391 // |
|
392 |
|
393 public void promptForAck(LoginRequest request) |
|
394 throws ActionAbortedException { |
|
395 |
|
396 assert !EventQueue.isDispatchThread(); |
|
397 |
|
398 final LoginProperty<String> host = request.getHost(); |
|
399 final LoginProperty<String> user = request.getUser(); |
|
400 final LoginProperty<String> role = request.getRole(); |
|
401 final LoginProperty<String> zone = request.getZone(); |
|
402 final LoginProperty<String> zoneUser = request.getZoneUser(); |
|
403 final LoginProperty<String> zoneRole = request.getZoneRole(); |
|
404 final List<DialogMessage> messages = request.getMessages(); |
|
405 |
|
406 addMessage(request, "login.message.ack"); |
|
407 |
|
408 GUIUtil.invokeAndWait( |
|
409 new Runnable() { |
|
410 @Override |
|
411 public void run() { |
|
412 getMessagePanel().setMessages(messages); |
|
413 |
|
414 clear(); |
|
415 setHostInUI(host, false); |
|
416 setUserInUI(user, false); |
|
417 |
|
418 if (role.getValue() != null) { |
|
419 setRoleInUI(role, false); |
|
420 } |
|
421 |
|
422 if (zone.getValue() != null) { |
|
423 setZoneInUI(zone, false); |
|
424 if (zoneUser.getValue() != null) { |
|
425 setZoneUserInUI(zoneUser, false); |
|
426 if (zoneRole.getValue() != null) { |
|
427 setZoneRoleInUI(zoneRole, false); |
|
428 } |
|
429 } |
|
430 } |
|
431 |
|
432 getButtonBar().getBackButton().setEnabled(false); |
|
433 } |
|
434 }); |
|
435 |
|
436 try { |
|
437 awaitForward(); |
|
438 } catch (ActionRegressedException impossible) { |
|
439 } |
|
440 } |
|
441 |
|
442 public void promptForAuth(LoginRequest request, |
|
443 final List<LoginProperty> properties, final boolean isZone, |
|
444 final boolean isUserAuth, boolean isFirst) |
|
445 throws ActionAbortedException, ActionRegressedException { |
|
446 |
|
447 assert !EventQueue.isDispatchThread(); |
|
448 |
|
449 final LoginProperty<String> host = request.getHost(); |
|
450 final LoginProperty<String> user = request.getUser(); |
|
451 final LoginProperty<Boolean> zonePrompt = request.getZonePrompt(); |
|
452 final LoginProperty<String> role = request.getRole(); |
|
453 final LoginProperty<String> zone = request.getZone(); |
|
454 final LoginProperty<String> zoneUser = request.getZoneUser(); |
|
455 final LoginProperty<String> zoneRole = request.getZoneRole(); |
|
456 final List<DialogMessage> messages = request.getMessages(); |
|
457 |
|
458 if (isFirst) { |
|
459 String message = "login.message.auth."; |
|
460 if (isZone) { |
|
461 message += "zone."; |
|
462 } |
|
463 message += isUserAuth ? "user" : "role"; |
|
464 addMessage(request, message); |
|
465 } |
|
466 |
|
467 final Map<LoginProperty, JTextComponent> map = |
|
468 new HashMap<LoginProperty, JTextComponent>(); |
|
469 |
|
470 GUIUtil.invokeAndWait( |
|
471 new Runnable() { |
|
472 @Override |
|
473 public void run() { |
|
474 getMessagePanel().setMessages(messages); |
|
475 |
|
476 clear(); |
|
477 setHostInUI(host, false); |
|
478 |
|
479 if (isZone) { |
|
480 setZoneInUI(zone, false); |
|
481 setZoneUserInUI(zoneUser, false); |
|
482 if (!isUserAuth) { |
|
483 setZoneRoleInUI(zoneRole, false); |
|
484 } |
|
485 } else { |
|
486 setUserInUI(user, false); |
|
487 if (!isUserAuth) { |
|
488 setRoleInUI(role, false); |
|
489 } |
|
490 } |
|
491 |
|
492 boolean editable = host.isEditable() || user.isEditable() || |
|
493 zonePrompt.isEditable(); |
|
494 if (isZone) { |
|
495 editable |= role.isEditable() || zone.isEditable() || |
|
496 zoneUser.isEditable() || (!isUserAuth && |
|
497 zoneRole.isEditable()); |
|
498 } else { |
|
499 editable |= !isUserAuth && role.isEditable(); |
|
500 } |
|
501 |
|
502 getButtonBar().getBackButton().setEnabled(editable); |
|
503 |
|
504 int cols = GUIUtil.getTextFieldWidth(); |
|
505 |
|
506 if (properties != null) { |
|
507 for (LoginProperty property : properties) { |
|
508 JLabel label = new JLabel(property.getName()); |
|
509 JTextComponent field = null; |
|
510 Object value = property.getValue(); |
|
511 String text; |
|
512 if (property instanceof PasswordLoginProperty) { |
|
513 field = new JPasswordField(cols); |
|
514 text = new String((char[])value); |
|
515 } else { |
|
516 field = new JTextField(cols); |
|
517 text = (String)value; |
|
518 } |
|
519 |
|
520 field.setText(text); |
|
521 fieldPanel.add(label); |
|
522 fieldPanel.add(field); |
|
523 map.put(property, field); |
|
524 } |
|
525 } |
|
526 } |
|
527 }); |
|
528 |
|
529 final boolean[] success = {false}; |
|
530 try { |
|
531 awaitForward(); |
|
532 success[0] = true; |
|
533 } finally { |
|
534 GUIUtil.invokeAndWait( |
|
535 new Runnable() { |
|
536 @Override |
|
537 public void run() { |
|
538 for (Map.Entry<LoginProperty, JTextComponent> entry : |
|
539 map.entrySet()) { |
|
540 |
|
541 JTextComponent field = entry.getValue(); |
|
542 |
|
543 if (success[0]) { |
|
544 if (field instanceof JPasswordField) { |
|
545 @SuppressWarnings({"unchecked"}) |
|
546 LoginProperty<char[]> prop = |
|
547 (LoginProperty<char[]>)entry.getKey(); |
|
548 prop.setValue( |
|
549 ((JPasswordField)field).getPassword()); |
|
550 } else { |
|
551 @SuppressWarnings({"unchecked"}) |
|
552 LoginProperty<String> prop = |
|
553 (LoginProperty<String>)entry.getKey(); |
|
554 prop.setValue(field.getText()); |
|
555 } |
|
556 } |
|
557 |
|
558 // Remove any sensitive information |
|
559 field.setText(null); |
|
560 } |
|
561 } |
|
562 }); |
|
563 } |
|
564 } |
|
565 |
|
566 public void promptForFailedRequest(LoginRequest request) { |
|
567 assert !EventQueue.isDispatchThread(); |
|
568 |
|
569 final LoginProperty<String> host = request.getHost(); |
|
570 final LoginProperty<String> user = request.getUser(); |
|
571 final LoginProperty<String> role = request.getRole(); |
|
572 final LoginProperty<String> zone = request.getZone(); |
|
573 final LoginProperty<String> zoneUser = request.getZoneUser(); |
|
574 final LoginProperty<String> zoneRole = request.getZoneRole(); |
|
575 final List<DialogMessage> messages = request.getMessages(); |
|
576 |
|
577 if (messages.isEmpty()) { |
|
578 addMessage(request, "login.message.fail"); |
|
579 } |
|
580 |
|
581 GUIUtil.invokeAndWait( |
|
582 new Runnable() { |
|
583 @Override |
|
584 public void run() { |
|
585 getMessagePanel().setMessages(messages); |
|
586 |
|
587 clear(); |
|
588 if (host.getValue() != null) { |
|
589 setHostInUI(host, false); |
|
590 if (user.getValue() != null) { |
|
591 setUserInUI(user, false); |
|
592 if (role.getValue() != null) { |
|
593 setRoleInUI(role, false); |
|
594 } |
|
595 if (zone.getValue() != null) { |
|
596 setZoneInUI(zone, false); |
|
597 if (zoneUser.getValue() != null) { |
|
598 setZoneUserInUI(zoneUser, false); |
|
599 if (zoneRole.getValue() != null) { |
|
600 setZoneRoleInUI(zoneRole, false); |
|
601 } |
|
602 } |
|
603 } |
|
604 } |
|
605 } |
|
606 } |
|
607 }); |
|
608 |
|
609 awaitClose(); |
|
610 } |
|
611 |
|
612 public void promptForHostAndUser(LoginRequest request) |
|
613 throws ActionAbortedException { |
|
614 |
|
615 assert !EventQueue.isDispatchThread(); |
|
616 |
|
617 final LoginProperty<String> host = request.getHost(); |
|
618 final LoginProperty<String> user = request.getUser(); |
|
619 final LoginProperty<Boolean> zonePrompt = request.getZonePrompt(); |
|
620 final List<DialogMessage> messages = request.getMessages(); |
|
621 |
|
622 String resource = "login.message.hostuser"; |
|
623 if (host.isEditable()) { |
|
624 resource += ".host"; |
|
625 } |
|
626 if (user.isEditable()) { |
|
627 resource += ".user"; |
|
628 } |
|
629 addMessage(request, resource); |
|
630 |
|
631 GUIUtil.invokeAndWait( |
|
632 new Runnable() { |
|
633 @Override |
|
634 public void run() { |
|
635 getMessagePanel().setMessages(messages); |
|
636 |
|
637 clear(); |
|
638 setHostInUI(host, true); |
|
639 setUserInUI(user, true); |
|
640 |
|
641 Boolean zonePromptValue = zonePrompt.getValue(); |
|
642 if ((zonePromptValue != null && zonePromptValue) || |
|
643 zonePrompt.isEditable()) { |
|
644 setZonePromptInUI(zonePrompt, true); |
|
645 } |
|
646 |
|
647 getButtonBar().getBackButton().setEnabled(false); |
|
648 } |
|
649 }); |
|
650 |
|
651 try { |
|
652 awaitForward(); |
|
653 } catch (ActionRegressedException impossible) { |
|
654 } |
|
655 |
|
656 setInProperty(host, hostField); |
|
657 setInProperty(user, userField); |
|
658 setInProperty(zonePrompt, zonePromptField); |
|
659 } |
|
660 |
|
661 public void promptForRole(LoginRequest request, |
|
662 final List<String> roles, final boolean isZone) |
|
663 throws ActionAbortedException, ActionRegressedException { |
|
664 |
|
665 assert !EventQueue.isDispatchThread(); |
|
666 |
|
667 final LoginProperty<String> host = request.getHost(); |
|
668 final LoginProperty<String> user = request.getUser(); |
|
669 final LoginProperty<Boolean> zonePrompt = request.getZonePrompt(); |
|
670 final LoginProperty<String> role = request.getRole(); |
|
671 final LoginProperty<String> zone = request.getZone(); |
|
672 final LoginProperty<String> zoneUser = request.getZoneUser(); |
|
673 final LoginProperty<String> zoneRole = request.getZoneRole(); |
|
674 final List<DialogMessage> messages = request.getMessages(); |
|
675 |
|
676 addMessage(request, isZone ? "login.message.zonerole" : |
|
677 "login.message.role"); |
|
678 |
|
679 GUIUtil.invokeAndWait( |
|
680 new Runnable() { |
|
681 @Override |
|
682 public void run() { |
|
683 getMessagePanel().setMessages(messages); |
|
684 |
|
685 LoginComboBox field = isZone ? zoneRoleField : roleField; |
|
686 DefaultComboBoxModel model = |
|
687 (DefaultComboBoxModel)field.getField().getModel(); |
|
688 |
|
689 model.removeAllElements(); |
|
690 model.addElement(null); |
|
691 for (String r : roles) { |
|
692 model.addElement(r); |
|
693 } |
|
694 |
|
695 clear(); |
|
696 setHostInUI(host, false); |
|
697 |
|
698 if (isZone) { |
|
699 setZoneInUI(zone, false); |
|
700 setZoneUserInUI(zoneUser, false); |
|
701 setZoneRoleInUI(zoneRole, true); |
|
702 } else { |
|
703 setUserInUI(user, false); |
|
704 setRoleInUI(role, true); |
|
705 } |
|
706 |
|
707 getButtonBar().getBackButton().setEnabled( |
|
708 host.isEditable() || user.isEditable() || |
|
709 zonePrompt.isEditable() || |
|
710 (isZone && zone.isEditable() || zoneUser.isEditable())); |
|
711 } |
|
712 }); |
|
713 |
|
714 awaitForward(); |
|
715 if (isZone) { |
|
716 setInProperty(zoneRole, zoneRoleField); |
|
717 } else { |
|
718 setInProperty(role, roleField); |
|
719 } |
|
720 } |
|
721 |
|
722 public void promptForZoneAndUser(LoginRequest request, |
|
723 final List<String> zones) throws ActionAbortedException, |
|
724 ActionRegressedException { |
|
725 |
|
726 assert !EventQueue.isDispatchThread(); |
|
727 |
|
728 final LoginProperty<String> host = request.getHost(); |
|
729 final LoginProperty<String> user = request.getUser(); |
|
730 final LoginProperty<Boolean> zonePrompt = request.getZonePrompt(); |
|
731 final LoginProperty<String> role = request.getRole(); |
|
732 final LoginProperty<String> zone = request.getZone(); |
|
733 final LoginProperty<String> zoneUser = request.getZoneUser(); |
|
734 final List<DialogMessage> messages = request.getMessages(); |
|
735 |
|
736 String resource = "login.message.zoneuser"; |
|
737 if (zone.isEditable()) { |
|
738 resource += ".zone"; |
|
739 } |
|
740 if (zoneUser.isEditable()) { |
|
741 resource += ".user"; |
|
742 } |
|
743 addMessage(request, resource); |
|
744 |
|
745 if (zoneUser.getValue() == null) { |
|
746 // Prepopulate with sensible default if unset |
|
747 zoneUser.setValue(user.getValue()); |
|
748 } |
|
749 |
|
750 GUIUtil.invokeAndWait( |
|
751 new Runnable() { |
|
752 @Override |
|
753 public void run() { |
|
754 getMessagePanel().setMessages(messages); |
|
755 |
|
756 DefaultComboBoxModel model = |
|
757 (DefaultComboBoxModel)zoneField.getField().getModel(); |
|
758 |
|
759 model.removeAllElements(); |
|
760 model.addElement(null); |
|
761 for (String z : zones) { |
|
762 model.addElement(z); |
|
763 } |
|
764 |
|
765 clear(); |
|
766 setHostInUI(host, false); |
|
767 setZoneInUI(zone, true); |
|
768 setZoneUserInUI(zoneUser, true); |
|
769 |
|
770 getButtonBar().getBackButton().setEnabled( |
|
771 host.isEditable() || user.isEditable() || |
|
772 zonePrompt.isEditable() || role.isEditable()); |
|
773 } |
|
774 }); |
|
775 |
|
776 awaitForward(); |
|
777 setInProperty(zone, zoneField); |
|
778 setInProperty(zoneUser, zoneUserField); |
|
779 } |
|
780 |
|
781 // |
|
782 // Private methods |
|
783 // |
|
784 |
|
785 private void addMessage(LoginRequest request, String resource) { |
|
786 DialogMessage message = new DialogMessage(Finder.getString( |
|
787 resource, request.getHost().getValue(), |
|
788 request.getUser().getValue(), request.getRole().getValue(), |
|
789 request.getZone().getValue(), request.getZoneUser().getValue(), |
|
790 request.getZoneRole().getValue())); |
|
791 request.getMessages().add(message); |
|
792 } |
|
793 |
|
794 private void awaitClose() { |
|
795 SettingsButtonBar bar = getButtonBar(); |
|
796 AbstractButton closeButton = bar.getCloseButton(); |
|
797 |
|
798 for (AbstractButton button : bar.getButtons()) { |
|
799 button.setVisible(button == closeButton); |
|
800 } |
|
801 |
|
802 while (awaitClickedButton() != closeButton); |
|
803 } |
|
804 |
|
805 private void awaitForward() throws ActionAbortedException, |
|
806 ActionRegressedException { |
|
807 |
|
808 SettingsButtonBar bar = getButtonBar(); |
|
809 AbstractButton backButton = bar.getBackButton(); |
|
810 AbstractButton forwardButton = bar.getForwardButton(); |
|
811 AbstractButton cancelButton = bar.getCancelButton(); |
|
812 |
|
813 for (AbstractButton button : bar.getButtons()) { |
|
814 button.setVisible(button == backButton || |
|
815 button == forwardButton || button == cancelButton); |
|
816 } |
|
817 |
|
818 JButton clicked = null; |
|
819 while (clicked != forwardButton) { |
|
820 clicked = awaitClickedButton(); |
|
821 |
|
822 if (clicked == backButton) { |
|
823 throw new ActionRegressedException(); |
|
824 } |
|
825 |
|
826 if (clicked == cancelButton) { |
|
827 throw new ActionAbortedException(); |
|
828 } |
|
829 } |
|
830 } |
|
831 |
|
832 private void createFieldPanel() { |
|
833 hostField = new LoginTextField(); |
|
834 hostLabel = new JLabel(); |
|
835 hostLabel.setLabelFor(hostField); |
|
836 |
|
837 userField = new LoginTextField(); |
|
838 userLabel = new JLabel(); |
|
839 userLabel.setLabelFor(userField); |
|
840 |
|
841 roleField = new LoginComboBox( |
|
842 Finder.getString("login.field.role.none")); |
|
843 roleLabel = new JLabel(); |
|
844 roleLabel.setLabelFor(roleField); |
|
845 |
|
846 zoneField = new LoginComboBox( |
|
847 Finder.getString("login.field.zone.select")); |
|
848 zoneLabel = new JLabel(); |
|
849 zoneLabel.setLabelFor(zoneField); |
|
850 |
|
851 zoneUserField = new LoginTextField(); |
|
852 zoneUserLabel = new JLabel(); |
|
853 zoneUserLabel.setLabelFor(zoneUserField); |
|
854 |
|
855 zoneRoleField = new LoginComboBox( |
|
856 Finder.getString("login.field.zonerole.none")); |
|
857 zoneRoleLabel = new JLabel(); |
|
858 zoneRoleLabel.setLabelFor(zoneRoleField); |
|
859 |
|
860 int gap = GUIUtil.getHalfGap(); |
|
861 |
|
862 HasAnchors a = new SimpleHasAnchors( |
|
863 HorizontalAnchor.LEFT, VerticalAnchor.CENTER); |
|
864 |
|
865 TableLayout layout = new TableLayout(1, 2, gap, gap); |
|
866 layout.setHorizontalAnchor(HorizontalAnchor.LEFT); |
|
867 layout.setDefaultConstraint(a); |
|
868 |
|
869 fieldPanel = new JPanel(layout); |
|
870 fieldPanel.setOpaque(false); |
|
871 |
|
872 fieldPanel.add(hostLabel); |
|
873 fieldPanel.add(hostField); |
|
874 |
|
875 fieldPanel.add(userLabel); |
|
876 fieldPanel.add(userField); |
|
877 |
|
878 fieldPanel.add(roleLabel); |
|
879 fieldPanel.add(roleField); |
|
880 |
|
881 fieldPanel.add(zoneLabel); |
|
882 fieldPanel.add(zoneField); |
|
883 |
|
884 fieldPanel.add(zoneUserLabel); |
|
885 fieldPanel.add(zoneUserField); |
|
886 |
|
887 fieldPanel.add(zoneRoleLabel); |
|
888 fieldPanel.add(zoneRoleField); |
|
889 |
|
890 nCoreFields = fieldPanel.getComponentCount(); |
|
891 } |
|
892 |
|
893 private void clear() { |
|
894 assert EventQueue.isDispatchThread(); |
|
895 |
|
896 hostLabel.setVisible(false); |
|
897 hostField.setVisible(false); |
|
898 |
|
899 roleLabel.setVisible(false); |
|
900 roleField.setVisible(false); |
|
901 |
|
902 userLabel.setVisible(false); |
|
903 userField.setVisible(false); |
|
904 |
|
905 zoneLabel.setVisible(false); |
|
906 zoneField.setVisible(false); |
|
907 |
|
908 zonePromptField.setVisible(false); |
|
909 |
|
910 zoneUserLabel.setVisible(false); |
|
911 zoneUserField.setVisible(false); |
|
912 |
|
913 zoneRoleLabel.setVisible(false); |
|
914 zoneRoleField.setVisible(false); |
|
915 |
|
916 // Remove all but the "core" fields (host, user, role, etc.) |
|
917 while (fieldPanel.getComponentCount() > nCoreFields) { |
|
918 fieldPanel.remove(nCoreFields); |
|
919 } |
|
920 } |
|
921 |
|
922 private void setHostInUI(LoginProperty<String> property, boolean allowEdit) |
|
923 { |
|
924 setInUI(property, hostLabel, hostField, LABEL_HOST, allowEdit); |
|
925 } |
|
926 |
|
927 private <T> void setInProperty(LoginProperty<T> property, |
|
928 LoginField<T> field) { |
|
929 |
|
930 if (property.isEditable()) { |
|
931 property.setValue(field.getValue()); |
|
932 } |
|
933 property.setErrored(false); |
|
934 } |
|
935 |
|
936 private <T> void setInUI(LoginProperty<T> property, Component label, |
|
937 final LoginField<T> field, String defaultLabel, boolean allowEdit) { |
|
938 |
|
939 assert EventQueue.isDispatchThread(); |
|
940 |
|
941 String labelText = property.getName(); |
|
942 if (labelText == null) { |
|
943 labelText = defaultLabel; |
|
944 } |
|
945 if (label instanceof JLabel) { |
|
946 ((JLabel)label).setText(labelText); |
|
947 } else if (label instanceof JCheckBox) { |
|
948 ((JCheckBox)label).setText(labelText); |
|
949 } |
|
950 |
|
951 boolean editable = allowEdit && property.isEditable(); |
|
952 Color foreground = null; |
|
953 int style = Font.PLAIN; |
|
954 if (property.isErrored()) { |
|
955 foreground = COLOR_LABEL_ERROR; |
|
956 style = Font.BOLD; |
|
957 if (editable) { |
|
958 EventQueue.invokeLater( |
|
959 new Runnable() { |
|
960 @Override |
|
961 public void run() { |
|
962 field.requestEditFocus(); |
|
963 } |
|
964 }); |
|
965 } |
|
966 } |
|
967 label.setForeground(foreground); |
|
968 label.setFont(label.getFont().deriveFont(style)); |
|
969 label.setVisible(true); |
|
970 |
|
971 field.setValue(property.getValue()); |
|
972 field.setEditable(editable); |
|
973 field.setVisible(true); |
|
974 } |
|
975 |
|
976 private void setRoleInUI(LoginProperty<String> property, boolean allowEdit) |
|
977 { |
|
978 setInUI(property, roleLabel, roleField, LABEL_ROLE, allowEdit); |
|
979 } |
|
980 |
|
981 private void setUserInUI(LoginProperty<String> property, boolean allowEdit) |
|
982 { |
|
983 setInUI(property, userLabel, userField, LABEL_USER, allowEdit); |
|
984 } |
|
985 |
|
986 private void setZoneInUI(LoginProperty<String> property, boolean allowEdit) |
|
987 { |
|
988 setInUI(property, zoneLabel, zoneField, LABEL_ZONE, allowEdit); |
|
989 } |
|
990 |
|
991 private void setZonePromptInUI(LoginProperty<Boolean> property, |
|
992 boolean allowEdit) { |
|
993 setInUI(property, zonePromptField, zonePromptField, LABEL_ZONEPROMPT, |
|
994 allowEdit); |
|
995 } |
|
996 |
|
997 private void setZoneRoleInUI(LoginProperty<String> property, |
|
998 boolean allowEdit) { |
|
999 |
|
1000 setInUI(property, zoneRoleLabel, zoneRoleField, LABEL_ZONEROLE, |
|
1001 allowEdit); |
|
1002 } |
|
1003 |
|
1004 private void setZoneUserInUI(LoginProperty<String> property, |
|
1005 boolean allowEdit) { |
|
1006 setInUI(property, zoneUserLabel, zoneUserField, LABEL_ZONEUSER, |
|
1007 allowEdit); |
|
1008 } |
|
1009 } |