Controlling Login Information

ConnectedUser.java
01/* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com */ 02 03package com.db4odoc.f1.semaphores; 04 05 06import java.util.*; 07import com.db4o.*; 08import com.db4o.config.*; 09import com.db4o.ext.*; 10import com.db4o.query.*; 11 12/** 13 * This class demonstrates how semaphores can be used 14 * to rule out race conditions when providing exact and 15 * up-to-date information about all connected clients 16 * on a server. The class also can be used to make sure 17 * that only one login is possible with a give user name 18 * and ipAddress combination. 19 */ 20public class ConnectedUser { 21 22 static final String SEMAPHORE_CONNECTED = "ConnectedUser_"; 23 static final String SEMAPHORE_LOCK_ACCESS = "ConnectedUser_Lock_"; 24 25 static final int TIMEOUT = 10000; // concurrent access timeout 10 seconds 26 27 String userName; 28 String ipAddress; 29 30 public ConnectedUser(String userName, String ipAddress){ 31 this.userName = userName; 32 this.ipAddress = ipAddress; 33 } 34 35 // make sure to call this on the server before opening the database 36 // to improve querying speed 37 public static void configure(){ 38 ObjectClass objectClass = Db4o.configure().objectClass(ConnectedUser.class); 39 objectClass.objectField("userName").indexed(true); 40 objectClass.objectField("ipAddress").indexed(true); 41 } 42 43 // call this on the client to ensure to have a ConnectedUser record 44 // in the database file and the semaphore set 45 public static void login(ObjectContainer client, String userName, String ipAddress){ 46 if(! client.ext().setSemaphore(SEMAPHORE_LOCK_ACCESS, TIMEOUT)){ 47 throw new RuntimeException("Timeout trying to get access to ConnectedUser lock"); 48 } 49 Query q = client.query(); 50 q.constrain(ConnectedUser.class); 51 q.descend("userName").constrain(userName); 52 q.descend("ipAddress").constrain(ipAddress); 53 if(q.execute().size() == 0){ 54 client.set(new ConnectedUser(userName, ipAddress)); 55 client.commit(); 56 } 57 String connectedSemaphoreName = SEMAPHORE_CONNECTED + userName + ipAddress; 58 boolean unique = client.ext().setSemaphore(connectedSemaphoreName, 0); 59 client.ext().releaseSemaphore(SEMAPHORE_LOCK_ACCESS); 60 if(! unique){ 61 throw new RuntimeException("Two clients with same userName and ipAddress"); 62 } 63 } 64 65 // here is your list of all connected users, callable on the server 66 public static List connectedUsers(ObjectServer server){ 67 ExtObjectContainer serverObjectContainer = server.ext().objectContainer().ext(); 68 if(serverObjectContainer.setSemaphore(SEMAPHORE_LOCK_ACCESS, TIMEOUT)){ 69 throw new RuntimeException("Timeout trying to get access to ConnectedUser lock"); 70 } 71 List list = new ArrayList(); 72 Query q = serverObjectContainer.query(); 73 q.constrain(ConnectedUser.class); 74 ObjectSet objectSet = q.execute(); 75 while(objectSet.hasNext()){ 76 ConnectedUser connectedUser = (ConnectedUser)objectSet.next(); 77 String connectedSemaphoreName = 78 SEMAPHORE_CONNECTED + 79 connectedUser.userName + 80 connectedUser.ipAddress; 81 if(serverObjectContainer.setSemaphore(connectedSemaphoreName, TIMEOUT)){ 82 serverObjectContainer.delete(connectedUser); 83 }else{ 84 list.add(connectedUser); 85 } 86 } 87 serverObjectContainer.commit(); 88 serverObjectContainer.releaseSemaphore(SEMAPHORE_LOCK_ACCESS); 89 return list; 90 } 91}