001/* 002 * GWTEventService 003 * Copyright (c) 2011 and beyond, strawbill UG (haftungsbeschr?nkt) 004 * 005 * This is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU Lesser General Public License as 007 * published by the Free Software Foundation; either version 3 of 008 * the License, or (at your option) any later version. 009 * Other licensing for GWTEventService may also be possible on request. 010 * Please view the license.txt of the project for more information. 011 * 012 * This software 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 software; if not, write to the Free 019 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 020 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 021 */ 022package de.novanic.eventservice.service.registry.user; 023 024import de.novanic.eventservice.client.event.domain.Domain; 025 026import java.util.Set; 027import java.util.HashSet; 028import java.util.Map; 029import java.util.concurrent.ConcurrentMap; 030import java.util.concurrent.ConcurrentHashMap; 031 032/** 033 * DomainUserMapping manages the allocation of users ({@link de.novanic.eventservice.service.registry.user.UserInfo}) to domains 034 * ({@link de.novanic.eventservice.client.event.domain.Domain}) and provides several methods for access and modifications. 035 * 036 * @author sstrohschein 037 * <br>Date: 09.09.2009 038 * <br>Time: 15:04:36 039 */ 040public class DomainUserMapping 041{ 042 private final ConcurrentMap<Domain, ConcurrentMap<UserInfo, UserInfo>> myDomainUserInfoMap; 043 044 /** 045 * Creates a new, empty DomainUserMapping. 046 */ 047 public DomainUserMapping() { 048 myDomainUserInfoMap = new ConcurrentHashMap<Domain, ConcurrentMap<UserInfo, UserInfo>>(); 049 } 050 051 /** 052 * Adds a new user to a domain and creates a new domain entry when the domain is new to the DomainUserMapping. 053 * @param aDomain domain to add the user to 054 * @param aUserInfo user 055 */ 056 public void addUser(Domain aDomain, UserInfo aUserInfo) { 057 ConcurrentMap<UserInfo, UserInfo> theUsers = myDomainUserInfoMap.get(aDomain); 058 if(theUsers == null) { 059 ConcurrentMap<UserInfo, UserInfo> theNewUsers = new ConcurrentHashMap<UserInfo, UserInfo>(); 060 theUsers = myDomainUserInfoMap.putIfAbsent(aDomain, theNewUsers); 061 if(theUsers == null) { 062 theUsers = theNewUsers; 063 } 064 } 065 theUsers.putIfAbsent(aUserInfo, aUserInfo); 066 } 067 068 /** 069 * Removes a user from all domains and removes the domains when no other users are added to the domain. 070 * @param aUserInfo user 071 */ 072 public void removeUser(UserInfo aUserInfo) { 073 for(Map.Entry<Domain, ConcurrentMap<UserInfo, UserInfo>> theDomainUsersEntry: myDomainUserInfoMap.entrySet()) { 074 Domain theDomain = theDomainUsersEntry.getKey(); 075 ConcurrentMap<UserInfo, UserInfo> theDomainUsers = theDomainUsersEntry.getValue(); 076 removeUser(theDomain, theDomainUsers, aUserInfo); 077 } 078 } 079 080 /** 081 * Removes a user from a specified domain and removes the domain when no other users are added to the domain. 082 * @param aDomain domain 083 * @param aUserInfo user 084 * @return true when the user is removed from the domain, otherwise false 085 */ 086 public boolean removeUser(Domain aDomain, UserInfo aUserInfo) { 087 boolean isUserRemoved = false; 088 089 if(aDomain != null && aUserInfo != null) { 090 ConcurrentMap<UserInfo, UserInfo> theDomainUsers = myDomainUserInfoMap.get(aDomain); 091 if(theDomainUsers != null) { 092 isUserRemoved = removeUser(aDomain, theDomainUsers, aUserInfo); 093 } 094 } 095 return isUserRemoved; 096 } 097 098 /** 099 * Removes a user from a specified domain and removes the domain when no other users are added to the domain. 100 * @param aDomain domain 101 * @param aDomainUsers users of the domain 102 * @param aUser user 103 * @return true when the user is removed from the domain, otherwise false 104 */ 105 private boolean removeUser(Domain aDomain, ConcurrentMap<UserInfo, UserInfo> aDomainUsers, UserInfo aUser) { 106 boolean isUserRemoved = (aDomainUsers.remove(aUser) != null); 107 if(isUserRemoved) { 108 if(aDomainUsers.isEmpty()) { 109 //Atomic operation to remove only when the collection is empty. Otherwise another thread could add a user between the check of is empty and remove. 110 //isEmpty is checked before for more performance for the most cases. 111 myDomainUserInfoMap.remove(aDomain, aDomainUsers); 112 } 113 } 114 return isUserRemoved; 115 } 116 117 /** 118 * Returns all domains which have added users 119 * @return all domains which have added users 120 */ 121 public Set<Domain> getDomains() { 122 return myDomainUserInfoMap.keySet(); 123 } 124 125 /** 126 * Returns all domains to a user. 127 * @param aUserInfo user 128 * @return all domains where the user is added 129 */ 130 public Set<Domain> getDomains(UserInfo aUserInfo) { 131 if(aUserInfo != null) { 132 Set<Domain> theDomains = new HashSet<Domain>(myDomainUserInfoMap.size()); 133 134 for(Map.Entry<Domain, ConcurrentMap<UserInfo, UserInfo>> theDomainUserEntry : myDomainUserInfoMap.entrySet()) { 135 ConcurrentMap<UserInfo, UserInfo> theDomainUsers = theDomainUserEntry.getValue(); 136 if(theDomainUsers.containsKey(aUserInfo)) { 137 theDomains.add(theDomainUserEntry.getKey()); 138 } 139 } 140 return theDomains; 141 } 142 return new HashSet<Domain>(0); 143 } 144 145 /** 146 * Returns all users of a domain. 147 * @param aDomain domain 148 * @return all users of the domain 149 */ 150 public Set<UserInfo> getUsers(Domain aDomain) { 151 if(aDomain != null) { 152 final ConcurrentMap<UserInfo, UserInfo> theUserInfoCollection = myDomainUserInfoMap.get(aDomain); 153 if(theUserInfoCollection != null) { 154 return new HashSet<UserInfo>(theUserInfoCollection.keySet()); 155 } 156 return new HashSet<UserInfo>(0); 157 } 158 return null; 159 } 160 161 /** 162 * Checks if a user is added to a domain. 163 * @param aUserInfo user 164 * @return true when the user is added to a domain, otherwise false 165 */ 166 public boolean isUserContained(UserInfo aUserInfo) { 167 for(ConcurrentMap<UserInfo, UserInfo> theDomainUsers: myDomainUserInfoMap.values()) { 168 if(theDomainUsers.containsKey(aUserInfo)) { 169 return true; 170 } 171 } 172 return false; 173 } 174 175 /** 176 * Checks if a user is added to the domain. 177 * @param aDomain domain 178 * @param aUserInfo user 179 * @return true when the user is added to the domain, otherwise false 180 */ 181 public boolean isUserContained(Domain aDomain, UserInfo aUserInfo) { 182 ConcurrentMap<UserInfo, UserInfo> theDomainUsers = myDomainUserInfoMap.get(aDomain); 183 return theDomainUsers != null && theDomainUsers.containsKey(aUserInfo); 184 } 185}