001 /* 002 * $Id: LoginService.java,v 1.9 2005/11/30 05:21:56 rbair Exp $ 003 * 004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle, 005 * Santa Clara, California 95054, U.S.A. All rights reserved. 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 020 */ 021 package org.jdesktop.swingx.auth; 022 023 import java.awt.EventQueue; 024 import java.util.Iterator; 025 import java.util.Vector; 026 import java.util.logging.Logger; 027 028 import javax.swing.SwingUtilities; 029 import org.jdesktop.swingx.util.SwingWorker; 030 031 /** 032 * <b>LoginService</b> is the abstract base class for all classes implementing 033 * a login mechanism. It allows you to customize the threading behaviour 034 * used to perform the login. Subclasses need to override the <b>authenticate</b> 035 * method. 036 * Subclasses may implement the getUserRoles() method to return a meaningful value 037 * this method will be called once upon a successful login to determine the user roles. 038 * It is not defined as abstract to simplify the task of implementing a login service 039 * for those who do not require this functionality. 040 * 041 * @author Bino George 042 * @author Shai Almog 043 */ 044 public abstract class LoginService { 045 private Logger LOG = Logger.getLogger(LoginService.class.getName()); 046 private Vector<LoginListener> listenerList = new Vector<LoginListener>(); 047 private SwingWorker loginWorker; 048 049 /* 050 * Controls the authentication behaviour to be either 051 * synchronous or asynchronous 052 */ 053 private boolean synchronous; 054 private String server; 055 056 public LoginService() { 057 } 058 059 public LoginService(String server) { 060 setServer(server); 061 } 062 063 /** 064 * This method is intended to be implemented by clients 065 * wishing to authenticate a user with a given password. 066 * Clients should implement the authentication in a 067 * manner that the authentication can be cancelled at 068 * any time. 069 * 070 * @param name username 071 * @param password password 072 * @param server server (optional) 073 * 074 * @return <code>true</code> on authentication success 075 * @throws Exception 076 */ 077 public abstract boolean authenticate(String name, char[] password, String server) throws Exception; 078 079 /** 080 * Called immediately after a successful authentication. This method should return an array 081 * of user roles or null if role based permissions are not used. 082 * 083 * @return per default <code>null</code> 084 */ 085 public String[] getUserRoles() { 086 return null; 087 } 088 089 /** 090 * Notifies the LoginService that an already running 091 * authentication request should be cancelled. This 092 * method is intended to be used by clients who want 093 * to provide user with control over cancelling a long 094 * running authentication request. 095 */ 096 public void cancelAuthentication() { 097 if (loginWorker != null) { 098 loginWorker.cancel(true); 099 } 100 } 101 102 /** 103 * This method starts the authentication process and is either 104 * synchronous or asynchronous based on the synchronous property 105 * 106 * @param user user 107 * @param password password 108 * @param server server 109 * @throws Exception 110 */ 111 public void startAuthentication(final String user, final char[] password, final String server) throws Exception { 112 if (getSynchronous()) { 113 try { 114 if (authenticate(user,password,server)) { 115 fireLoginSucceeded(new LoginEvent(this)); 116 } else { 117 fireLoginFailed(new LoginEvent(this)); 118 } 119 } catch (Throwable e) { 120 fireLoginFailed(new LoginEvent(this, e)); 121 } 122 } else { 123 loginWorker = new SwingWorker() { 124 protected Object doInBackground() throws Exception { 125 try { 126 final boolean result = authenticate(user,password,server); 127 if (isCancelled()) { 128 EventQueue.invokeLater(new Runnable() { 129 public void run() { 130 fireLoginCanceled(new LoginEvent(this)); 131 } 132 }); 133 return false; 134 } 135 EventQueue.invokeLater(new Runnable() { 136 public void run() { 137 if (result) { 138 fireLoginSucceeded(new LoginEvent(LoginService.this)); 139 } else { 140 fireLoginFailed(new LoginEvent(LoginService.this)); 141 } 142 } 143 }); 144 return result; 145 } catch (final Throwable failed) { 146 if (!isCancelled()) { 147 SwingUtilities.invokeLater(new Runnable() { 148 public void run() { 149 fireLoginFailed(new LoginEvent(LoginService.this, failed)); 150 } 151 }); 152 } else { 153 EventQueue.invokeLater(new Runnable() { 154 public void run() { 155 fireLoginCanceled(new LoginEvent(this)); 156 } 157 }); 158 } 159 return false; 160 } 161 } 162 }; 163 loginWorker.execute(); 164 fireLoginStarted(new LoginEvent(this)); 165 } 166 } 167 168 /** 169 * Get the synchronous property 170 * @return the synchronous property 171 */ 172 public boolean getSynchronous() { 173 return synchronous; 174 } 175 /** 176 * Sets the synchronous property 177 * 178 * @param synchronous synchronous property 179 */ 180 public void setSynchronous(boolean synchronous) { 181 this.synchronous = synchronous; 182 } 183 184 /** 185 * Adds a <strong>LoginListener</strong> to the list of listeners 186 * 187 * @param listener listener 188 */ 189 190 public void addLoginListener(LoginListener listener) { 191 listenerList.add(listener); 192 } 193 194 /** 195 * Removes a <strong>LoginListener</strong> from the list of listeners 196 * 197 * @param listener listener 198 */ 199 public void removeLoginListener(LoginListener listener) { 200 listenerList.remove(listener); 201 } 202 203 204 void fireLoginStarted(final LoginEvent source) { 205 Iterator iter = listenerList.iterator(); 206 while (iter.hasNext()) { 207 LoginListener listener = (LoginListener) iter.next(); 208 listener.loginStarted(source); 209 } 210 } 211 212 void fireLoginSucceeded(final LoginEvent source) { 213 Iterator iter = listenerList.iterator(); 214 while (iter.hasNext()) { 215 LoginListener listener = (LoginListener) iter.next(); 216 listener.loginSucceeded(source); 217 } 218 } 219 220 void fireLoginFailed(final LoginEvent source) { 221 Iterator iter = listenerList.iterator(); 222 while (iter.hasNext()) { 223 LoginListener listener = (LoginListener) iter.next(); 224 listener.loginFailed(source); 225 } 226 } 227 228 void fireLoginCanceled(final LoginEvent source) { 229 Iterator iter = listenerList.iterator(); 230 while (iter.hasNext()) { 231 LoginListener listener = (LoginListener) iter.next(); 232 listener.loginCanceled(source); 233 } 234 } 235 236 237 /** 238 * @return Returns the server. 239 */ 240 public String getServer() { 241 return server; 242 } 243 /** 244 * @param server The server to set. 245 */ 246 public void setServer(String server) { 247 this.server = server; 248 } 249 }