X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=security%2Fplugins%2Forg.argeo.security.ui%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fsecurity%2Fui%2Fdialogs%2FAbstractLoginDialog.java;h=5c83066ee007ea01a1a8182bb96f10e081a189fb;hb=6bb0606505be3e99021c5ff9771c719eb1e1f2e7;hp=d3d1be38b5154b785f6ea3b36ac68a43697e1f2e;hpb=a7a5f4db586128a9bb2c171ee819eb3eb19f80aa;p=lgpl%2Fargeo-commons.git diff --git a/security/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/dialogs/AbstractLoginDialog.java b/security/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/dialogs/AbstractLoginDialog.java index d3d1be38b..5c83066ee 100644 --- a/security/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/dialogs/AbstractLoginDialog.java +++ b/security/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/dialogs/AbstractLoginDialog.java @@ -7,10 +7,13 @@ import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.security.ui.SecurityUiPlugin; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.jface.dialogs.TrayDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.operation.ModalContext; import org.eclipse.swt.events.SelectionEvent; @@ -19,9 +22,13 @@ import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; -public abstract class AbstractLoginDialog extends TitleAreaDialog implements +/** Base for login dialogs */ +public abstract class AbstractLoginDialog extends TrayDialog implements CallbackHandler { + private final static Log log = LogFactory.getLog(AbstractLoginDialog.class); + + private Thread modalContextThread = null; boolean processCallbacks = false; boolean isCancelled = false; Callback[] callbackArray; @@ -48,6 +55,22 @@ public abstract class AbstractLoginDialog extends TitleAreaDialog implements * .callback.Callback[]) */ public void handle(final Callback[] callbacks) throws IOException { + // clean previous usage + if (processCallbacks) { + // this handler was already used + processCallbacks = false; + } + + if (modalContextThread != null) { + try { + modalContextThread.join(1000); + } catch (InterruptedException e) { + // silent + } + modalContextThread = null; + } + + // initialize this.callbackArray = callbacks; final Display display = Display.getDefault(); display.syncExec(new Runnable() { @@ -56,6 +79,7 @@ public abstract class AbstractLoginDialog extends TitleAreaDialog implements isCancelled = false; setBlockOnOpen(false); open(); + final Button okButton = getButton(IDialogConstants.OK_ID); okButton.setText("Login"); okButton.addSelectionListener(new SelectionListener() { @@ -87,15 +111,24 @@ public abstract class AbstractLoginDialog extends TitleAreaDialog implements ModalContext.run(new IRunnableWithProgress() { public void run(final IProgressMonitor monitor) { + modalContextThread = Thread.currentThread(); // Wait here until OK or cancel is pressed, then let it rip. // The event // listener // is responsible for closing the dialog (in the // loginSucceeded // event). - while (!processCallbacks) { + while (!processCallbacks && (modalContextThread != null) + && (modalContextThread == Thread.currentThread()) + && SecurityUiPlugin.getDefault() != null) { + // Note: SecurityUiPlugin.getDefault() != null is false + // when the OSGi runtime is shut down try { Thread.sleep(100); + // if (display.isDisposed()) { + // log.warn("Display is disposed, killing login dialog thread"); + // throw new ThreadDeath(); + // } } catch (final Exception e) { // do nothing } @@ -113,15 +146,31 @@ public abstract class AbstractLoginDialog extends TitleAreaDialog implements ((NameCallback) callback).setName(null); } }, true, new NullProgressMonitor(), Display.getDefault()); - } catch (final Exception e) { - final IOException ioe = new IOException(); + } catch (ThreadDeath e) { + isCancelled = true; + log.debug("Thread " + Thread.currentThread().getId() + " died"); + throw e; + } catch (Exception e) { + isCancelled = true; + IOException ioe = new IOException( + "Unexpected issue in login dialog, see root cause for more details"); ioe.initCause(e); throw ioe; + } finally { + // so that the modal thread dies + processCallbacks = true; + // try { + // // wait for the modal context thread to gracefully exit + // modalContextThread.join(); + // } catch (InterruptedException ie) { + // // silent + // } + modalContextThread = null; } } protected void configureShell(Shell shell) { super.configureShell(shell); - shell.setText("Login"); + shell.setText("Authentication"); } }