Commit 0dfb2b24 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gaston

Persistent rooms will always remain in memory. RoomSurrogates are no longer necessary.


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@459 b35dd754-fafc-0310-a699-88a17e54d16e
parent 4b45689b
...@@ -493,6 +493,17 @@ public class IQOwnerHandler { ...@@ -493,6 +493,17 @@ public class IQOwnerHandler {
presences.addAll(room.addMember(jid, null, senderRole)); presences.addAll(room.addMember(jid, null, senderRole));
} }
// Destroy the room if the room is no longer persistent and there are no occupants in
// the room
if (!room.isPersistent() && room.getOccupantsCount() == 0) {
try {
room.destroyRoom(null, null);
}
catch (UnauthorizedException e) {
// Do nothing.
}
}
} }
finally { finally {
room.lock.writeLock().unlock(); room.lock.writeLock().unlock();
......
...@@ -15,9 +15,7 @@ import java.sql.Connection; ...@@ -15,9 +15,7 @@ import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Date;
import org.jivesoftware.database.DbConnectionManager; import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.messenger.muc.MUCRole; import org.jivesoftware.messenger.muc.MUCRole;
...@@ -40,11 +38,6 @@ import org.jivesoftware.util.StringUtils; ...@@ -40,11 +38,6 @@ import org.jivesoftware.util.StringUtils;
*/ */
public class MUCPersistenceManager { public class MUCPersistenceManager {
private static final String LOAD_ROOM_SURROGATES =
"SELECT roomID, creationDate, modificationDate, name, naturalName, description, " +
"canChangeSubject, maxUsers, moderated, invitationRequired, canInvite, " +
"password, canDiscoverJID, logEnabled, subject, rolesToBroadcast " +
"FROM mucRoom WHERE inMemory=0 and publicRoom=1";
private static final String GET_RESERVED_NAME = private static final String GET_RESERVED_NAME =
"SELECT nickname FROM mucMember WHERE roomID=? AND jid=?"; "SELECT nickname FROM mucMember WHERE roomID=? AND jid=?";
private static final String LOAD_ROOM = private static final String LOAD_ROOM =
...@@ -56,6 +49,15 @@ public class MUCPersistenceManager { ...@@ -56,6 +49,15 @@ public class MUCPersistenceManager {
"SELECT jid,affiliation FROM mucAffiliation WHERE roomID=?"; "SELECT jid,affiliation FROM mucAffiliation WHERE roomID=?";
private static final String LOAD_MEMBERS = private static final String LOAD_MEMBERS =
"SELECT jid, nickname FROM mucMember WHERE roomID=?"; "SELECT jid, nickname FROM mucMember WHERE roomID=?";
private static final String LOAD_ALL_ROOMS =
"SELECT roomID, creationDate, modificationDate, name, naturalName, description, " +
"canChangeSubject, maxUsers, publicRoom, moderated, invitationRequired, canInvite, " +
"password, canDiscoverJID, logEnabled, subject, rolesToBroadcast " +
"FROM mucRoom";
private static final String LOAD_ALL_AFFILIATIONS =
"SELECT roomID,jid,affiliation FROM mucAffiliation";
private static final String LOAD_ALL_MEMBERS =
"SELECT roomID,jid, nickname FROM mucMember";
private static final String UPDATE_ROOM = private static final String UPDATE_ROOM =
"UPDATE mucRoom SET modificationDate=?, naturalName=?, description=?, " + "UPDATE mucRoom SET modificationDate=?, naturalName=?, description=?, " +
"canChangeSubject=?, maxUsers=?, publicRoom=?, moderated=?, invitationRequired=?, " + "canChangeSubject=?, maxUsers=?, publicRoom=?, moderated=?, invitationRequired=?, " +
...@@ -68,10 +70,6 @@ public class MUCPersistenceManager { ...@@ -68,10 +70,6 @@ public class MUCPersistenceManager {
"lastActiveDate, inMemory) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; "lastActiveDate, inMemory) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
private static final String UPDATE_SUBJECT = private static final String UPDATE_SUBJECT =
"UPDATE mucRoom SET subject=? WHERE roomID=?"; "UPDATE mucRoom SET subject=? WHERE roomID=?";
private static final String UPDATE_IN_MEMORY =
"UPDATE mucRoom SET lastActiveDate=?, inMemory=? WHERE roomID=?";
private static final String RESET_IN_MEMORY =
"UPDATE mucRoom SET lastActiveDate=?, inMemory=0 WHERE inMemory=1";
private static final String DELETE_ROOM = private static final String DELETE_ROOM =
"DELETE FROM mucRoom WHERE roomID=?"; "DELETE FROM mucRoom WHERE roomID=?";
private static final String DELETE_AFFILIATIONS = private static final String DELETE_AFFILIATIONS =
...@@ -95,61 +93,6 @@ public class MUCPersistenceManager { ...@@ -95,61 +93,6 @@ public class MUCPersistenceManager {
"INSERT INTO mucConversationLog (roomID,sender,nickname,time,subject,body) " + "INSERT INTO mucConversationLog (roomID,sender,nickname,time,subject,body) " +
"VALUES (?,?,?,?,?,?)"; "VALUES (?,?,?,?,?,?)";
public static List<MUCPersistentRoomSurrogate> getRoomSurrogates(MultiUserChatServer chatserver,
PacketRouter packetRouter) {
Connection con = null;
PreparedStatement pstmt = null;
List<MUCPersistentRoomSurrogate> answer = new ArrayList<MUCPersistentRoomSurrogate>();
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_ROOM_SURROGATES);
ResultSet rs = pstmt.executeQuery();
MUCPersistentRoomSurrogate room = null;
while (rs.next()) {
room = new MUCPersistentRoomSurrogate(chatserver, rs.getString(4), packetRouter);
room.setID(rs.getLong(1));
room.setCreationDate(new Date(Long.parseLong(rs.getString(2).trim()))); // creation date
room.setModificationDate(new Date(Long.parseLong(rs.getString(3).trim()))); // modification date
room.setNaturalLanguageName(rs.getString(5));
room.setDescription(rs.getString(6));
room.setCanOccupantsChangeSubject(rs.getInt(7) == 1 ? true : false);
room.setMaxUsers(rs.getInt(8));
room.setModerated(rs.getInt(9) == 1 ? true : false);
room.setInvitationRequiredToEnter(rs.getInt(10) == 1 ? true : false);
room.setCanOccupantsInvite(rs.getInt(11) == 1 ? true : false);
room.setPassword(rs.getString(12));
room.setCanAnyoneDiscoverJID(rs.getInt(13) == 1 ? true : false);
room.setLogEnabled(rs.getInt(14) == 1 ? true : false);
room.setSubject(rs.getString(15));
List rolesToBroadcast = new ArrayList();
String roles = Integer.toBinaryString(rs.getInt(16));
if (roles.charAt(0) == '1') {
rolesToBroadcast.add("moderator");
}
if (roles.length() > 1 && roles.charAt(1) == '1') {
rolesToBroadcast.add("participant");
}
if (roles.length() > 2 && roles.charAt(2) == '1') {
rolesToBroadcast.add("visitor");
}
room.setRolesToBroadcastPresence(rolesToBroadcast);
answer.add(room);
}
rs.close();
pstmt.close();
}
catch (SQLException sqle) {
Log.error(sqle);
}
finally {
try { if (pstmt != null) pstmt.close(); }
catch (Exception e) { Log.error(e); }
try { if (con != null) con.close(); }
catch (Exception e) { Log.error(e); }
}
return answer;
}
/** /**
* Returns the reserved room nickname for the bare JID in a given room or null if none. * Returns the reserved room nickname for the bare JID in a given room or null if none.
* *
...@@ -273,6 +216,10 @@ public class MUCPersistenceManager { ...@@ -273,6 +216,10 @@ public class MUCPersistenceManager {
} }
} }
rs.close(); rs.close();
// Set now that the room's configuration is updated in the database. Note: We need to
// set this now since otherwise the room's affiliations will be saved to the database
// "again" while adding them to the room!
room.setSavedToDB(true);
} }
catch (SQLException sqle) { catch (SQLException sqle) {
Log.error(sqle); Log.error(sqle);
...@@ -392,50 +339,97 @@ public class MUCPersistenceManager { ...@@ -392,50 +339,97 @@ public class MUCPersistenceManager {
} }
/** /**
* Updates the in-memmory status of the room in the database. * Loads all the rooms from the database. This query will be executed only when
* the service is started up.
* *
* @param room the room to update its in-memory status. * @return a collection with all the persistent rooms.
* @param inMemory boolean that indicates whether the room is available in memory or not.
*/ */
public static void updateRoomInMemory(MUCRoom room, boolean inMemory) { public static Collection<MUCRoom> loadRoomsFromDB(MultiUserChatServer chatserver,
if (!room.isPersistent() || !room.wasSavedToDB()) { PacketRouter packetRouter) {
return;
}
Connection con = null; Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
Map<Long,MUCRoom> rooms = new HashMap<Long,MUCRoom>();
try { try {
con = DbConnectionManager.getConnection(); con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(UPDATE_IN_MEMORY); pstmt = con.prepareStatement(LOAD_ALL_ROOMS);
pstmt.setString(1, StringUtils.dateToMillis(new Date())); ResultSet rs = pstmt.executeQuery();
pstmt.setBoolean(2, inMemory); MUCRoom room = null;
pstmt.setLong(3, room.getID()); while (rs.next()) {
pstmt.executeUpdate(); room = new MUCRoomImpl(chatserver, rs.getString(4), packetRouter);
room.setID(rs.getLong(1));
room.setCreationDate(new Date(Long.parseLong(rs.getString(2).trim()))); // creation date
room.setModificationDate(new Date(Long.parseLong(rs.getString(3).trim()))); // modification date
room.setNaturalLanguageName(rs.getString(5));
room.setDescription(rs.getString(6));
room.setCanOccupantsChangeSubject(rs.getInt(7) == 1 ? true : false);
room.setMaxUsers(rs.getInt(8));
room.setPublicRoom(rs.getInt(9) == 1 ? true : false);
room.setModerated(rs.getInt(10) == 1 ? true : false);
room.setInvitationRequiredToEnter(rs.getInt(11) == 1 ? true : false);
room.setCanOccupantsInvite(rs.getInt(12) == 1 ? true : false);
room.setPassword(rs.getString(13));
room.setCanAnyoneDiscoverJID(rs.getInt(14) == 1 ? true : false);
room.setLogEnabled(rs.getInt(15) == 1 ? true : false);
room.setSubject(rs.getString(16));
List rolesToBroadcast = new ArrayList();
String roles = Integer.toBinaryString(rs.getInt(17));
if (roles.charAt(0) == '1') {
rolesToBroadcast.add("moderator");
} }
catch (SQLException sqle) { if (roles.length() > 1 && roles.charAt(1) == '1') {
Log.error(sqle); rolesToBroadcast.add("participant");
} }
finally { if (roles.length() > 2 && roles.charAt(2) == '1') {
try { if (pstmt != null) pstmt.close(); } rolesToBroadcast.add("visitor");
catch (Exception e) { Log.error(e); }
try { if (con != null) con.close(); }
catch (Exception e) { Log.error(e); }
} }
room.setRolesToBroadcastPresence(rolesToBroadcast);
room.setPersistent(true);
rooms.put(room.getID(), room);
} }
rs.close();
pstmt.close();
/** pstmt = con.prepareStatement(LOAD_ALL_AFFILIATIONS);
* Updates the in-memmory status of ALL the rooms in the database to false. This is necessary rs = pstmt.executeQuery();
* in case the Multi-User Chat service went down unexpectedly. This query will be executed when while (rs.next()) {
* the service is starting up (again). String jid = rs.getString(2);
*/ int affiliation = rs.getInt(3);
public static void resetRoomInMemory() { room = rooms.get(rs.getLong(1));
Connection con = null;
PreparedStatement pstmt = null;
try { try {
con = DbConnectionManager.getConnection(); switch (affiliation) {
pstmt = con.prepareStatement(RESET_IN_MEMORY); case MUCRole.OWNER:
pstmt.setString(1, StringUtils.dateToMillis(new Date())); room.addOwner(jid, room.getRole());
pstmt.executeUpdate(); break;
case MUCRole.ADMINISTRATOR:
room.addAdmin(jid, room.getRole());
break;
case MUCRole.OUTCAST:
room.addOutcast(jid, null, room.getRole());
break;
default:
Log.error("Unkown affiliation value " + affiliation + " for user "
+ jid + " in persistent room " + room.getID());
}
}
catch (Exception e) {
Log.error(e);
}
}
rs.close();
pstmt.close();
pstmt = con.prepareStatement(LOAD_ALL_MEMBERS);
rs = pstmt.executeQuery();
while (rs.next()) {
room = rooms.get(rs.getLong(1));
try {
room.addMember(rs.getString(2), rs.getString(3), room.getRole());
}
catch (Exception e) {
Log.error(e);
}
}
rs.close();
} }
catch (SQLException sqle) { catch (SQLException sqle) {
Log.error(sqle); Log.error(sqle);
...@@ -446,6 +440,14 @@ public class MUCPersistenceManager { ...@@ -446,6 +440,14 @@ public class MUCPersistenceManager {
try { if (con != null) con.close(); } try { if (con != null) con.close(); }
catch (Exception e) { Log.error(e); } catch (Exception e) { Log.error(e); }
} }
// Set now that the room's configuration is updated in the database. Note: We need to
// set this now since otherwise the room's affiliations will be saved to the database
// "again" while adding them to the room!
for (MUCRoom room : rooms.values()) {
room.setSavedToDB(true);
}
return rooms.values();
} }
/** /**
......
...@@ -172,8 +172,8 @@ public class MUCRoomImpl implements MUCRoom { ...@@ -172,8 +172,8 @@ public class MUCRoomImpl implements MUCRoom {
private boolean publicRoom = true; private boolean publicRoom = true;
/** /**
* Persistent rooms are saved to the database so that when the last occupant leaves the room, * Persistent rooms are saved to the database to make sure that rooms configurations can be
* the room is removed from memory but it's configuration is saved in the database. * restored in case the server goes down.
*/ */
private boolean persistent = false; private boolean persistent = false;
...@@ -279,17 +279,6 @@ public class MUCRoomImpl implements MUCRoom { ...@@ -279,17 +279,6 @@ public class MUCRoomImpl implements MUCRoom {
rolesToBroadcastPresence.add("moderator"); rolesToBroadcastPresence.add("moderator");
rolesToBroadcastPresence.add("participant"); rolesToBroadcastPresence.add("participant");
rolesToBroadcastPresence.add("visitor"); rolesToBroadcastPresence.add("visitor");
// If the room is persistent load the configuration values from the DB
try {
MUCPersistenceManager.loadFromDB(this);
if (this.isPersistent()) {
this.savedToDB = true;
this.roomLocked = false;
}
}
catch (IllegalArgumentException e) {
// Do nothing. The room does not exist.
}
} }
public String getName() { public String getName() {
...@@ -578,7 +567,9 @@ public class MUCRoomImpl implements MUCRoom { ...@@ -578,7 +567,9 @@ public class MUCRoomImpl implements MUCRoom {
// "unavailable" from the room to the owner including a <destroy/> element and reason // "unavailable" from the room to the owner including a <destroy/> element and reason
// (if provided) as defined under the "Destroying a Room" use case. // (if provided) as defined under the "Destroying a Room" use case.
if (occupants.isEmpty()) { // Remove the room from the server only if there are no more occupants and the room is
// not persistent
if (occupants.isEmpty() && !isPersistent()) {
endTime = System.currentTimeMillis(); endTime = System.currentTimeMillis();
server.removeChatRoom(name); server.removeChatRoom(name);
...@@ -1631,6 +1622,11 @@ public class MUCRoomImpl implements MUCRoom { ...@@ -1631,6 +1622,11 @@ public class MUCRoomImpl implements MUCRoom {
public void setSavedToDB(boolean saved) { public void setSavedToDB(boolean saved) {
this.savedToDB = saved; this.savedToDB = saved;
if (saved) {
// Unlock the room now. This is necessary only when a persistent room has been
// retrieved from the database.
this.roomLocked = false;
}
} }
public void setPersistent(boolean persistent) { public void setPersistent(boolean persistent) {
......
...@@ -91,13 +91,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -91,13 +91,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
*/ */
private Map<String,MUCRoom> rooms = new ConcurrentHashMap<String,MUCRoom>(); private Map<String,MUCRoom> rooms = new ConcurrentHashMap<String,MUCRoom>();
/**
* Cache for the persistent room surrogates. There will be a persistent room surrogate for each
* persistent room that has not been loaded into memory. Whenever a persistent room is loaded or
* unloaded from memory the cache is updated.
*/
private Cache persistentRoomSurrogateCache;
/** /**
* chat users managed by this manager, table: key user jid (XMPPAddress); value ChatUser * chat users managed by this manager, table: key user jid (XMPPAddress); value ChatUser
*/ */
...@@ -164,13 +157,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -164,13 +157,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
historyStrategy = new HistoryStrategy(null); historyStrategy = new HistoryStrategy(null);
} }
private void initializeCaches() {
// create cache - no size limit and expires after one hour of being idle
persistentRoomSurrogateCache = new Cache("Room Surrogates", -1, JiveConstants.HOUR);
// warm-up cache now to avoid a delay responding the first disco request
populateRoomSurrogateCache();
}
/** /**
* Probes the presence of any user who's last packet was sent more than 5 minute ago. * Probes the presence of any user who's last packet was sent more than 5 minute ago.
*/ */
...@@ -269,8 +255,14 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -269,8 +255,14 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
room = rooms.get(roomName.toLowerCase()); room = rooms.get(roomName.toLowerCase());
if (room == null) { if (room == null) {
room = new MUCRoomImpl(this, roomName, router); room = new MUCRoomImpl(this, roomName, router);
// Check whether the room was just created or loaded from the database // If the room is persistent load the configuration values from the DB
if (!room.isPersistent()) { try {
// Try to load the room's configuration from the database (if the room is
// persistent but was added to the DB after the server was started up)
MUCPersistenceManager.loadFromDB(room);
}
catch (IllegalArgumentException e) {
// The room does not exist so check for creation permissions
// Room creation is always allowed for sysadmin // Room creation is always allowed for sysadmin
if (isRoomCreationRestricted() && if (isRoomCreationRestricted() &&
!sysadmins.contains(userjid.toBareStringPrep())) { !sysadmins.contains(userjid.toBareStringPrep())) {
...@@ -283,13 +275,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -283,13 +275,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
} }
room.addFirstOwner(userjid.toBareStringPrep()); room.addFirstOwner(userjid.toBareStringPrep());
} }
else {
// The room was loaded from the database and is now available in memory.
// Update in the database that the room is now available in memory
MUCPersistenceManager.updateRoomInMemory(room, true);
// Remove the surrogate of the room (if any) from the surrogates cache
persistentRoomSurrogateCache.remove(room.getName());
}
rooms.put(roomName.toLowerCase(), room); rooms.put(roomName.toLowerCase(), room);
} }
} }
...@@ -297,39 +282,11 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -297,39 +282,11 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
} }
public MUCRoom getChatRoom(String roomName) { public MUCRoom getChatRoom(String roomName) {
MUCRoom answer = rooms.get(roomName.toLowerCase()); return rooms.get(roomName.toLowerCase());
// If the room is not in memory check if there exists a surrogate of the room. There
// will be a surrogate if and only if exists an room in the database for the requested
// room name
if (answer == null) {
synchronized (persistentRoomSurrogateCache) {
if (persistentRoomSurrogateCache.size() == 0) {
populateRoomSurrogateCache();
}
}
answer = (MUCRoom) persistentRoomSurrogateCache.get(roomName);
}
return answer;
} }
public List<MUCRoom> getChatRooms() { public List<MUCRoom> getChatRooms() {
List<MUCRoom> answer = new ArrayList<MUCRoom>(rooms.size() * 2); return new ArrayList<MUCRoom>(rooms.values());
synchronized (rooms) {
answer.addAll(rooms.values());
synchronized (persistentRoomSurrogateCache) {
if (persistentRoomSurrogateCache.size() == 0) {
populateRoomSurrogateCache();
}
}
answer.addAll(persistentRoomSurrogateCache.values());
}
return answer;
}
private void populateRoomSurrogateCache() {
for (MUCRoom room : MUCPersistenceManager.getRoomSurrogates(this, router)) {
persistentRoomSurrogateCache.put(room.getName(), room);
}
} }
public boolean hasChatRoom(String roomName) { public boolean hasChatRoom(String roomName) {
...@@ -341,18 +298,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -341,18 +298,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
if (room != null) { if (room != null) {
final long chatLength = room.getChatLength(); final long chatLength = room.getChatLength();
totalChatTime += chatLength; totalChatTime += chatLength;
// Update the database to indicate that the room is no longer in memory (only if the
// room is persistent
MUCPersistenceManager.updateRoomInMemory(room, false);
// Clear the surrogates cache if the room thas is being removed from memory is
// persistent
if (room.isPersistent()) {
persistentRoomSurrogateCache.clear();
}
else {
// Just force to expire old entries since the cache doesn't have a clean-up thread
persistentRoomSurrogateCache.size();
}
} }
} }
...@@ -577,10 +522,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -577,10 +522,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
// Log the room conversations every 5 minutes after a 5 minutes server startup delay // Log the room conversations every 5 minutes after a 5 minutes server startup delay
// (default values) // (default values)
timer.schedule(new LogConversationTask(), LOG_TIMEOUT, LOG_TIMEOUT); timer.schedule(new LogConversationTask(), LOG_TIMEOUT, LOG_TIMEOUT);
// Update the DB to indicate that no room is in-memory. This may be necessary when the
// server went down unexpectedly
MUCPersistenceManager.resetRoomInMemory();
initializeCaches();
} }
public void start() { public void start() {
...@@ -591,6 +532,10 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -591,6 +532,10 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
params.clear(); params.clear();
params.add(chatServiceName); params.add(chatServiceName);
Log.info(LocaleUtils.getLocalizedString("startup.starting.muc", params)); Log.info(LocaleUtils.getLocalizedString("startup.starting.muc", params));
// Load all the persistent rooms to memory
for (MUCRoom room : MUCPersistenceManager.loadRoomsFromDB(this, router)) {
rooms.put(room.getName().toLowerCase(), room);
}
} }
public void stop() { public void stop() {
...@@ -823,24 +768,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -823,24 +768,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
answer.add(item); answer.add(item);
} }
} }
// Load the room surrogates for persistent rooms that aren't in memory (if the cache
// is still empty)
synchronized(persistentRoomSurrogateCache) {
if (persistentRoomSurrogateCache.size() == 0) {
populateRoomSurrogateCache();
}
}
// Add items for each room surrogate (persistent room that is not in memory at
// the moment)
MUCRoom room;
for (Iterator it=persistentRoomSurrogateCache.values().iterator(); it.hasNext();) {
room = (MUCRoom)it.next();
item = DocumentHelper.createElement("item");
item.addAttribute("jid", room.getRole().getRoleAddress().toStringPrep());
item.addAttribute("name", room.getNaturalLanguageName());
answer.add(item);
}
} }
else if (name != null && node == null) { else if (name != null && node == null) {
// Answer the room occupants as items if that info is publicly available // Answer the room occupants as items if that info is publicly available
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment