Controlling Login Information

ConnectedUser.java
001/* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com */ 002 003package com.db4odoc.semaphores; 004 005import java.util.*; 006import com.db4o.*; 007import com.db4o.config.*; 008import com.db4o.ext.*; 009import com.db4o.query.*; 010 011/** 012 * This class demonstrates how semaphores can be used to rule out race 013 * conditions when providing exact and up-to-date information about 014 * all connected clients on a server. The class also can be used to 015 * make sure that only one login is possible with a give user name and 016 * ipAddress combination. 017 */ 018public class ConnectedUser { 019 020 static final String SEMAPHORE_CONNECTED = "ConnectedUser_"; 021 022 static final String SEMAPHORE_LOCK_ACCESS = "ConnectedUser_Lock_"; 023 024 static final int TIMEOUT = 10000; // concurrent access timeout 025 026 // 10 seconds 027 028 String userName; 029 030 String ipAddress; 031 032 public ConnectedUser(String userName, String ipAddress) { 033 this.userName = userName; 034 this.ipAddress = ipAddress; 035 } 036 037 // make sure to call this on the server before opening the 038 // database 039 // to improve querying speed 040 public static void configure() { 041 ObjectClass objectClass = Db4o.configure().objectClass( 042 ConnectedUser.class); 043 objectClass.objectField("userName").indexed(true); 044 objectClass.objectField("ipAddress").indexed(true); 045 } 046 047 // call this on the client to ensure to have a ConnectedUser 048 // record 049 // in the database file and the semaphore set 050 public static void login(ObjectContainer client, String userName, 051 String ipAddress) { 052 if (!client.ext() 053 .setSemaphore(SEMAPHORE_LOCK_ACCESS, TIMEOUT)) { 054 throw new RuntimeException( 055 "Timeout trying to get access to ConnectedUser lock"); 056 } 057 Query q = client.query(); 058 q.constrain(ConnectedUser.class); 059 q.descend("userName").constrain(userName); 060 q.descend("ipAddress").constrain(ipAddress); 061 if (q.execute().size() == 0) { 062 client.set(new ConnectedUser(userName, ipAddress)); 063 client.commit(); 064 } 065 String connectedSemaphoreName = SEMAPHORE_CONNECTED 066 + userName + ipAddress; 067 boolean unique = client.ext().setSemaphore( 068 connectedSemaphoreName, 0); 069 client.ext().releaseSemaphore(SEMAPHORE_LOCK_ACCESS); 070 if (!unique) { 071 throw new RuntimeException( 072 "Two clients with same userName and ipAddress"); 073 } 074 } 075 076 // here is your list of all connected users, callable on the 077 // server 078 public static List connectedUsers(ObjectServer server) { 079 ExtObjectContainer serverObjectContainer = server.ext() 080 .objectContainer().ext(); 081 if (serverObjectContainer.setSemaphore(SEMAPHORE_LOCK_ACCESS, 082 TIMEOUT)) { 083 throw new RuntimeException( 084 "Timeout trying to get access to ConnectedUser lock"); 085 } 086 List list = new ArrayList(); 087 Query q = serverObjectContainer.query(); 088 q.constrain(ConnectedUser.class); 089 ObjectSet objectSet = q.execute(); 090 while (objectSet.hasNext()) { 091 ConnectedUser connectedUser = (ConnectedUser) objectSet 092 .next(); 093 String connectedSemaphoreName = SEMAPHORE_CONNECTED 094 + connectedUser.userName 095 + connectedUser.ipAddress; 096 if (serverObjectContainer.setSemaphore( 097 connectedSemaphoreName, TIMEOUT)) { 098 serverObjectContainer.delete(connectedUser); 099 } else { 100 list.add(connectedUser); 101 } 102 } 103 serverObjectContainer.commit(); 104 serverObjectContainer.releaseSemaphore(SEMAPHORE_LOCK_ACCESS); 105 return list; 106 } 107}