After more investigation, it appeared that the problem was in the leaveRoom() method in LocalMUCRoom.java (line 680).
http://www.igniterealtime.org/fisheye/browse/svn-org/openfire/trunk/src/java/org /jivesoftware/openfire/muc/spi/LocalMUCRoom.java?r=10084
The unavailable presence from a user was broadcasted even if this user had a role which was not a role we want to broadcast the presence.
This is what we did to fix the pb:
public void leaveRoom(MUCRole leaveRole) {
if (leaveRole.isLocal()) {
// Ask other cluster nodes to remove occupant from room
OccupantLeftEvent event = new OccupantLeftEvent(this, leaveRole);
CacheFactory.doClusterTask(event);
}
try {
{color:#ff0000}String oldRole = leaveRole.getRole().name();
Presence presence = leaveRole.getPresence().createCopy();
presence.setType(Presence.Type.unavailable);
presence.setStatus(null);
// Change (or add) presence information about roles and affiliations
Element childElement = presence.getChildElement(“x”, “http://jabber.org/protocol/muc#user”);
if (childElement == null) {
childElement = presence.addChildElement(“x”, “http://jabber.org/protocol/muc#user”);
}
Element item = childElement.element(“item”);
if (item == null) {
item = childElement.addElement(“item”);
}
item.addAttribute(“role”, “none”);
// Inform the leaving user that he/she has left the room
leaveRole.send(presence);
// if presence have to be broadcasted for every role
if (!hasToCheckRoleToBroadcastPresence()) {
// Inform the rest of the room occupants that the user has left the room
broadcastPresence(presence);
}
// else if the user had a role which is in the roles we want to broadcast presence
else if (getRolesToBroadcastPresence().contains(oldRole)) {
// Inform the rest of the room occupants that the user has left the room
broadcastPresence(presence);
}
}
catch (Exception e) {
Log.error(e);
}
// Remove occupant from room and destroy room if empty and not persistent
OccupantLeftEvent event = new OccupantLeftEvent(this, leaveRole);
event.setOriginator(true);
event.run();
}