X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=security%2Fplugins%2Forg.argeo.security.ui%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fsecurity%2Fui%2Fdialogs%2FAbstractLoginDialog.java;h=7c7e0c6b6cb4a0547ef37ed84ea2471ea1e61bb0;hb=3a3d316af102ba410d1d9e6de349d0c8f7ac044f;hp=9316a85d24700ad085d320829acf8a5fd5fbc96c;hpb=5266ec50ddbf3247a5033d98a1dbceec6673a5b8;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 9316a85d2..7c7e0c6b6 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 @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.argeo.security.ui.dialogs; import java.io.IOException; @@ -7,6 +22,9 @@ 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; @@ -19,9 +37,13 @@ import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; +/** 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 +70,22 @@ public abstract class AbstractLoginDialog extends TrayDialog 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 +94,7 @@ public abstract class AbstractLoginDialog extends TrayDialog implements isCancelled = false; setBlockOnOpen(false); open(); + final Button okButton = getButton(IDialogConstants.OK_ID); okButton.setText("Login"); okButton.addSelectionListener(new SelectionListener() { @@ -87,15 +126,24 @@ public abstract class AbstractLoginDialog extends TrayDialog 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 +161,31 @@ public abstract class AbstractLoginDialog extends TrayDialog 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"); } }