1 package org
.argeo
.security
.ui
.dialogs
;
3 import java
.io
.IOException
;
5 import javax
.security
.auth
.callback
.Callback
;
6 import javax
.security
.auth
.callback
.CallbackHandler
;
7 import javax
.security
.auth
.callback
.NameCallback
;
8 import javax
.security
.auth
.callback
.PasswordCallback
;
10 import org
.apache
.commons
.logging
.Log
;
11 import org
.apache
.commons
.logging
.LogFactory
;
12 import org
.argeo
.security
.ui
.SecurityUiPlugin
;
13 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
14 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
15 import org
.eclipse
.jface
.dialogs
.IDialogConstants
;
16 import org
.eclipse
.jface
.dialogs
.TrayDialog
;
17 import org
.eclipse
.jface
.operation
.IRunnableWithProgress
;
18 import org
.eclipse
.jface
.operation
.ModalContext
;
19 import org
.eclipse
.swt
.events
.SelectionEvent
;
20 import org
.eclipse
.swt
.events
.SelectionListener
;
21 import org
.eclipse
.swt
.widgets
.Button
;
22 import org
.eclipse
.swt
.widgets
.Display
;
23 import org
.eclipse
.swt
.widgets
.Shell
;
25 /** Base for login dialogs */
26 public abstract class AbstractLoginDialog
extends TrayDialog
implements
29 private final static Log log
= LogFactory
.getLog(AbstractLoginDialog
.class);
31 private Thread modalContextThread
= null;
32 boolean processCallbacks
= false;
33 boolean isCancelled
= false;
34 Callback
[] callbackArray
;
36 protected final Callback
[] getCallbacks() {
37 return this.callbackArray
;
40 public abstract void internalHandle();
42 public boolean isCancelled() {
46 protected AbstractLoginDialog(Shell parentShell
) {
54 * javax.security.auth.callback.CallbackHandler#handle(javax.security.auth
55 * .callback.Callback[])
57 public void handle(final Callback
[] callbacks
) throws IOException
{
58 // clean previous usage
59 if (processCallbacks
) {
60 // this handler was already used
61 processCallbacks
= false;
64 if (modalContextThread
!= null) {
66 modalContextThread
.join(1000);
67 } catch (InterruptedException e
) {
70 modalContextThread
= null;
74 this.callbackArray
= callbacks
;
75 final Display display
= Display
.getDefault();
76 display
.syncExec(new Runnable() {
80 setBlockOnOpen(false);
82 final Button okButton
= getButton(IDialogConstants
.OK_ID
);
83 okButton
.setText("Login");
84 okButton
.addSelectionListener(new SelectionListener() {
86 public void widgetSelected(final SelectionEvent event
) {
87 processCallbacks
= true;
90 public void widgetDefaultSelected(final SelectionEvent event
) {
94 final Button cancel
= getButton(IDialogConstants
.CANCEL_ID
);
95 cancel
.addSelectionListener(new SelectionListener() {
97 public void widgetSelected(final SelectionEvent event
) {
99 processCallbacks
= true;
102 public void widgetDefaultSelected(final SelectionEvent event
) {
109 ModalContext
.setAllowReadAndDispatch(true); // Works for now.
110 ModalContext
.run(new IRunnableWithProgress() {
112 public void run(final IProgressMonitor monitor
) {
113 modalContextThread
= Thread
.currentThread();
114 // Wait here until OK or cancel is pressed, then let it rip.
117 // is responsible for closing the dialog (in the
120 while (!processCallbacks
&& (modalContextThread
!= null)
121 && (modalContextThread
== Thread
.currentThread())
122 && SecurityUiPlugin
.getDefault() != null) {
123 // Note: SecurityUiPlugin.getDefault() != null is false
124 // when the OSGi runtime is shut down
127 // if (display.isDisposed()) {
128 // log.warn("Display is disposed, killing login dialog thread");
129 // throw new ThreadDeath();
131 } catch (final Exception e
) {
135 processCallbacks
= false;
136 // Call the adapter to handle the callbacks
140 // clear callbacks are when cancelling
141 for (Callback callback
: callbacks
)
142 if (callback
instanceof PasswordCallback
)
143 ((PasswordCallback
) callback
).setPassword(null);
144 else if (callback
instanceof NameCallback
)
145 ((NameCallback
) callback
).setName(null);
147 }, true, new NullProgressMonitor(), Display
.getDefault());
148 } catch (ThreadDeath e
) {
150 log
.debug("Thread " + Thread
.currentThread().getId() + " died");
152 } catch (Exception e
) {
154 IOException ioe
= new IOException(
155 "Unexpected issue in login dialog, see root cause for more details");
159 // so that the modal thread dies
160 processCallbacks
= true;
162 // // wait for the modal context thread to gracefully exit
163 // modalContextThread.join();
164 // } catch (InterruptedException ie) {
167 modalContextThread
= null;
171 protected void configureShell(Shell shell
) {
172 super.configureShell(shell
);
173 shell
.setText("Login");