📄 rostermanager.java
字号:
/**
* $RCSfile: RosterManager.java,v $
* $Revision: 3138 $
* $Date: 2005-12-01 02:13:26 -0300 (Thu, 01 Dec 2005) $
*
* Copyright (C) 2008 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution, or a commercial license
* agreement with Jive.
*/
package org.jivesoftware.openfire.roster;
import org.jivesoftware.openfire.RoutingTable;
import org.jivesoftware.openfire.SharedGroupException;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.container.BasicModule;
import org.jivesoftware.openfire.event.GroupEventDispatcher;
import org.jivesoftware.openfire.event.GroupEventListener;
import org.jivesoftware.openfire.event.UserEventDispatcher;
import org.jivesoftware.openfire.event.UserEventListener;
import org.jivesoftware.openfire.group.Group;
import org.jivesoftware.openfire.group.GroupManager;
import org.jivesoftware.openfire.group.GroupNotFoundException;
import org.jivesoftware.openfire.user.User;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.cache.Cache;
import org.jivesoftware.util.cache.CacheFactory;
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence;
import java.util.*;
/**
* A simple service that allows components to retrieve a roster based solely on the ID
* of the owner. Users have convenience methods for obtaining a roster associated with
* the owner. However there are many components that need to retrieve the roster
* based solely on the generic ID owner key. This interface defines a service that can
* do that. This allows classes that generically manage resource for resource owners
* (such as presence updates) to generically offer their services without knowing or
* caring if the roster owner is a user, chatbot, etc.
*
* @author Iain Shigeoka
*/
public class RosterManager extends BasicModule implements GroupEventListener, UserEventListener {
private Cache<String, Roster> rosterCache = null;
private XMPPServer server;
private RoutingTable routingTable;
/**
* Returns true if the roster service is enabled. When disabled it is not possible to
* retrieve users rosters or broadcast presence packets to roster contacts.
*
* @return true if the roster service is enabled.
*/
public static boolean isRosterServiceEnabled() {
return JiveGlobals.getBooleanProperty("xmpp.client.roster.active", true);
}
public RosterManager() {
super("Roster Manager");
rosterCache = CacheFactory.createCache("Roster");
}
/**
* Returns the roster for the given username.
*
* @param username the username to search for.
* @return the roster associated with the ID.
* @throws org.jivesoftware.openfire.user.UserNotFoundException if the ID does not correspond
* to a known entity on the server.
*/
public Roster getRoster(String username) throws UserNotFoundException {
Roster roster = rosterCache.get(username);
if (roster == null) {
// Synchronize using a unique key so that other threads loading the User
// and not the Roster cannot produce a deadlock
synchronized ((username + " ro").intern()) {
roster = rosterCache.get(username);
if (roster == null) {
// Not in cache so load a new one:
roster = new Roster(username);
rosterCache.put(username, roster);
}
}
}
return roster;
}
/**
* Removes the entire roster of a given user. This is necessary when a user
* account is being deleted from the server.
*
* @param user the user.
*/
public void deleteRoster(JID user) {
if (!server.isLocal(user)) {
// Ignore request if user is not a local user
return;
}
try {
String username = user.getNode();
// Get the roster of the deleted user
Roster roster = getRoster(username);
// Remove each roster item from the user's roster
for (RosterItem item : roster.getRosterItems()) {
try {
roster.deleteRosterItem(item.getJid(), false);
}
catch (SharedGroupException e) {
// Do nothing. We shouldn't have this exception since we disabled the checkings
}
}
// Remove the cached roster from memory
rosterCache.remove(username);
// Get the rosters that have a reference to the deleted user
RosterItemProvider rosteItemProvider = RosterItemProvider.getInstance();
Iterator<String> usernames = rosteItemProvider.getUsernames(user.toBareJID());
while (usernames.hasNext()) {
username = usernames.next();
try {
// Get the roster that has a reference to the deleted user
roster = getRoster(username);
// Remove the deleted user reference from this roster
roster.deleteRosterItem(user, false);
}
catch (SharedGroupException e) {
// Do nothing. We shouldn't have this exception since we disabled the checkings
}
catch (UserNotFoundException e) {
// Do nothing.
}
}
}
catch (UnsupportedOperationException e) {
// Do nothing
}
catch (UserNotFoundException e) {
// Do nothing.
}
}
/**
* Returns a collection with all the groups that the user may include in his roster. The
* following criteria will be used to select the groups: 1) Groups that are configured so that
* everybody can include in his roster, 2) Groups that are configured so that its users may
* include the group in their rosters and the user is a group user of the group and 3) User
* belongs to a Group that may see a Group that whose members may include the Group in their
* rosters.
*
* @param username the username of the user to return his shared groups.
* @return a collection with all the groups that the user may include in his roster.
*/
public Collection<Group> getSharedGroups(String username) {
Collection<Group> answer = new HashSet<Group>();
Collection<Group> groups = GroupManager.getInstance().getSharedGroups();
for (Group group : groups) {
String showInRoster = group.getProperties().get("sharedRoster.showInRoster");
if ("onlyGroup".equals(showInRoster)) {
if (group.isUser(username)) {
// The user belongs to the group so add the group to the answer
answer.add(group);
}
else {
// Check if the user belongs to a group that may see this group
Collection<Group> groupList = parseGroups(group.getProperties().get("sharedRoster.groupList"));
for (Group groupInList : groupList) {
if (groupInList.isUser(username)) {
answer.add(group);
}
}
}
}
else if ("everybody".equals(showInRoster)) {
// Anyone can see this group so add the group to the answer
answer.add(group);
}
}
return answer;
}
/**
* Returns the list of shared groups whose visibility is public.
*
* @return the list of shared groups whose visibility is public.
*/
public Collection<Group> getPublicSharedGroups() {
Collection<Group> answer = new HashSet<Group>();
Collection<Group> groups = GroupManager.getInstance().getSharedGroups();
for (Group group : groups) {
String showInRoster = group.getProperties().get("sharedRoster.showInRoster");
if ("everybody".equals(showInRoster)) {
// Anyone can see this group so add the group to the answer
answer.add(group);
}
}
return answer;
}
/**
* Returns a collection of Groups obtained by parsing a comma delimited String with the name
* of groups.
*
* @param groupNames a comma delimited string with group names.
* @return a collection of Groups obtained by parsing a comma delimited String with the name
* of groups.
*/
private Collection<Group> parseGroups(String groupNames) {
Collection<Group> answer = new HashSet<Group>();
for (String groupName : parseGroupNames(groupNames)) {
try {
answer.add(GroupManager.getInstance().getGroup(groupName));
}
catch (GroupNotFoundException e) {
// Do nothing. Silently ignore the invalid reference to the group
}
}
return answer;
}
/**
* Returns a collection of Groups obtained by parsing a comma delimited String with the name
* of groups.
*
* @param groupNames a comma delimited string with group names.
* @return a collection of Groups obtained by parsing a comma delimited String with the name
* of groups.
*/
private static Collection<String> parseGroupNames(String groupNames) {
Collection<String> answer = new HashSet<String>();
if (groupNames != null) {
StringTokenizer tokenizer = new StringTokenizer(groupNames, ",");
while (tokenizer.hasMoreTokens()) {
answer.add(tokenizer.nextToken());
}
}
return answer;
}
public void groupCreated(Group group, Map params) {
//Do nothing
}
public void groupDeleting(Group group, Map params) {
// Get group members
Collection<JID> users = new HashSet<JID>(group.getMembers());
users.addAll(group.getAdmins());
// Get users whose roster will be updated
Collection<JID> affectedUsers = getAffectedUsers(group);
// Iterate on group members and update rosters of affected users
for (JID deletedUser : users) {
groupUserDeleted(group, affectedUsers, deletedUser);
}
}
public void groupModified(Group group, Map params) {
// Do nothing if no group property has been modified
if ("propertyDeleted".equals(params.get("type"))) {
return;
}
String keyChanged = (String) params.get("propertyKey");
String originalValue = (String) params.get("originalValue");
if ("sharedRoster.showInRoster".equals(keyChanged)) {
String currentValue = group.getProperties().get("sharedRoster.showInRoster");
// Nothing has changed so do nothing.
if (currentValue.equals(originalValue)) {
return;
}
// Get the users of the group
Collection<JID> users = new HashSet<JID>(group.getMembers());
users.addAll(group.getAdmins());
// Get the users whose roster will be affected
Collection<JID> affectedUsers = getAffectedUsers(group, originalValue,
group.getProperties().get("sharedRoster.groupList"));
// Remove the group members from the affected rosters
for (JID deletedUser : users) {
groupUserDeleted(group, affectedUsers, deletedUser);
}
// Simulate that the group users has been added to the group. This will cause to push
// roster items to the "affected" users for the group users
for (JID user : users) {
groupUserAdded(group, user);
}
}
else if ("sharedRoster.groupList".equals(keyChanged)) {
String currentValue = group.getProperties().get("sharedRoster.groupList");
// Nothing has changed so do nothing.
if (currentValue.equals(originalValue)) {
return;
}
// Get the users of the group
Collection<JID> users = new HashSet<JID>(group.getMembers());
users.addAll(group.getAdmins());
// Get the users whose roster will be affected
Collection<JID> affectedUsers = getAffectedUsers(group,
group.getProperties().get("sharedRoster.showInRoster"), originalValue);
// Remove the group members from the affected rosters
for (JID deletedUser : users) {
groupUserDeleted(group, affectedUsers, deletedUser);
}
// Simulate that the group users has been added to the group. This will cause to push
// roster items to the "affected" users for the group users
for (JID user : users) {
groupUserAdded(group, user);
}
}
else if ("sharedRoster.displayName".equals(keyChanged)) {
String currentValue = group.getProperties().get("sharedRoster.displayName");
// Nothing has changed so do nothing.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -