use of org.xmpp.packet.Presence in project Openfire by igniterealtime.
the class LocalMUCRoom method destroyRoom.
public void destroyRoom(DestroyRoomRequest destroyRequest) {
JID alternateJID = destroyRequest.getAlternateJID();
String reason = destroyRequest.getReason();
Collection<MUCRole> removedRoles = new ArrayList<>();
lock.writeLock().lock();
try {
boolean hasRemoteOccupants = false;
// Remove each occupant
for (MUCRole leaveRole : occupantsByFullJID.values()) {
if (leaveRole != null) {
// list of removed occupants to process later outside of the lock.
if (leaveRole.isLocal()) {
removedRoles.add(leaveRole);
} else {
hasRemoteOccupants = true;
}
removeOccupantRole(leaveRole, destroyRequest.isOriginator());
}
}
endTime = System.currentTimeMillis();
// Set that the room has been destroyed
isDestroyed = true;
if (destroyRequest.isOriginator()) {
if (hasRemoteOccupants) {
// Ask other cluster nodes to remove occupants since room is being destroyed
CacheFactory.doClusterTask(new DestroyRoomRequest(this, alternateJID, reason));
}
// Removes the room from the list of rooms hosted in the service
mucService.removeChatRoom(name);
}
} finally {
lock.writeLock().unlock();
}
// Send an unavailable presence to each removed occupant
for (MUCRole removedRole : removedRoles) {
try {
// Send a presence stanza of type "unavailable" to the occupant
Presence presence = createPresence(Presence.Type.unavailable);
presence.setFrom(removedRole.getRoleAddress());
// A fragment containing the x-extension for room destruction.
Element fragment = presence.addChildElement("x", "http://jabber.org/protocol/muc#user");
Element item = fragment.addElement("item");
item.addAttribute("affiliation", "none");
item.addAttribute("role", "none");
if (alternateJID != null) {
fragment.addElement("destroy").addAttribute("jid", alternateJID.toString());
}
if (reason != null && reason.length() > 0) {
Element destroy = fragment.element("destroy");
if (destroy == null) {
destroy = fragment.addElement("destroy");
}
destroy.addElement("reason").setText(reason);
}
removedRole.send(presence);
} catch (Exception e) {
Log.error(e.getMessage(), e);
}
}
if (destroyRequest.isOriginator()) {
// Remove the room from the DB if the room was persistent
MUCPersistenceManager.deleteFromDB(this);
// Fire event that the room has been destroyed
MUCEventDispatcher.roomDestroyed(getRole().getRoleAddress());
}
}
use of org.xmpp.packet.Presence in project Openfire by igniterealtime.
the class ComponentStanzaHandler method processPresence.
@Override
protected void processPresence(Presence packet) throws UnauthorizedException {
if (session.getStatus() != Session.STATUS_AUTHENTICATED) {
// Session is not authenticated so return error
Presence reply = new Presence();
reply.setID(packet.getID());
reply.setTo(packet.getFrom());
reply.setFrom(packet.getTo());
reply.setError(PacketError.Condition.not_authorized);
session.process(reply);
return;
}
super.processPresence(packet);
}
use of org.xmpp.packet.Presence in project Openfire by igniterealtime.
the class LocalMUCRoom method broadcast.
public void broadcast(BroadcastPresenceRequest presenceRequest) {
String jid = null;
Presence presence = presenceRequest.getPresence();
JID to = presence.getTo();
Element frag = presence.getChildElement("x", "http://jabber.org/protocol/muc#user");
// is not a moderator
if (!canAnyoneDiscoverJID()) {
jid = frag.element("item").attributeValue("jid");
}
for (MUCRole occupant : occupantsByFullJID.values()) {
if (!occupant.isLocal()) {
continue;
}
// is not a moderator
if (!canAnyoneDiscoverJID()) {
if (MUCRole.Role.moderator == occupant.getRole()) {
frag.element("item").addAttribute("jid", jid);
} else {
frag.element("item").addAttribute("jid", null);
}
}
// Some status codes should only be included in the "self-presence", which is only sent to the user, but not to other occupants.
if (occupant.getPresence().getFrom().equals(to)) {
Presence selfPresence = presence.createCopy();
Element fragSelfPresence = selfPresence.getChildElement("x", "http://jabber.org/protocol/muc#user");
fragSelfPresence.addElement("status").addAttribute("code", "110");
// http://xmpp.org/registrar/mucstatus.html
if (presenceRequest.isJoinPresence()) {
boolean isRoomNew = isLocked() && creationDate.getTime() == lockedTime;
if (canAnyoneDiscoverJID()) {
// // XEP-0045: Example 26.
// If the user is entering a room that is non-anonymous (i.e., which informs all occupants of each occupant's full JID as shown above), the service MUST warn the user by including a status code of "100" in the initial presence that the room sends to the new occupant
fragSelfPresence.addElement("status").addAttribute("code", "100");
}
if (isRoomNew) {
fragSelfPresence.addElement("status").addAttribute("code", "201");
}
}
occupant.send(selfPresence);
} else {
occupant.send(presence);
}
}
}
use of org.xmpp.packet.Presence in project Openfire by igniterealtime.
the class LocalMUCRoom method applyAffiliationChange.
/**
* Evaluate the given JID to determine what the appropriate affiliation should be
* after a change has been made. Each affected user will be granted the highest
* affiliation they now possess, either explicitly or implicitly via membership
* in one or more groups. If the JID is a user, the effective affiliation is
* applied to each presence corresponding to that user. If the given JID is a group,
* each user in the group is evaluated to determine what their new affiliations will
* be. The returned presence updates will be broadcast to the occupants of the room.
*
* @param senderRole Typically the room itself, or an owner/admin
* @param affiliationJID The JID for the user or group that has been changed
* @param reason An optional reason to explain why a user was kicked from the room
* @return List of presence updates to be delivered to the room's occupants
*/
private List<Presence> applyAffiliationChange(MUCRole senderRole, final JID affiliationJID, String reason) {
// Update the presence(s) for the new affiliation and inform all occupants
List<JID> affectedOccupants = new ArrayList<>();
// first, determine which actual (user) JIDs are affected by the affiliation change
if (GroupJID.isGroup(affiliationJID)) {
try {
Group group = GroupManager.getInstance().getGroup(affiliationJID);
// if so, calculate a new affiliation (if any) for the occupant(s)
for (JID groupMember : group.getAll()) {
if (occupantsByBareJID.containsKey(groupMember)) {
affectedOccupants.add(groupMember);
}
}
} catch (GroupNotFoundException gnfe) {
Log.error("Error updating group presences for " + affiliationJID, gnfe);
}
} else {
if (occupantsByBareJID.containsKey(affiliationJID)) {
affectedOccupants.add(affiliationJID);
}
}
// now update each of the affected occupants with a new role/affiliation
MUCRole.Role newRole;
MUCRole.Affiliation newAffiliation;
List<Presence> updatedPresences = new ArrayList<>();
// new role/affiliation may be granted via group membership
for (JID occupantJID : affectedOccupants) {
Log.info("Applying affiliation change for " + occupantJID);
boolean kickMember = false, isOutcast = false;
if (owners.includes(occupantJID)) {
newRole = MUCRole.Role.moderator;
newAffiliation = MUCRole.Affiliation.owner;
} else if (admins.includes(occupantJID)) {
newRole = MUCRole.Role.moderator;
newAffiliation = MUCRole.Affiliation.admin;
} else // outcast trumps member when an affiliation is changed
if (outcasts.includes(occupantJID)) {
newAffiliation = MUCRole.Affiliation.outcast;
newRole = MUCRole.Role.none;
kickMember = true;
isOutcast = true;
} else if (members.includesKey(occupantJID)) {
newRole = MUCRole.Role.participant;
newAffiliation = MUCRole.Affiliation.member;
} else if (isMembersOnly()) {
newRole = MUCRole.Role.none;
newAffiliation = MUCRole.Affiliation.none;
kickMember = true;
} else {
newRole = isModerated() ? MUCRole.Role.visitor : MUCRole.Role.participant;
newAffiliation = MUCRole.Affiliation.none;
}
Log.info("New affiliation: " + newAffiliation);
try {
List<Presence> thisOccupant = changeOccupantAffiliation(senderRole, occupantJID, newAffiliation, newRole);
if (kickMember) {
// a status code of 301 indicates the user was removed as an outcast
for (Presence presence : thisOccupant) {
presence.setType(Presence.Type.unavailable);
presence.setStatus(null);
Element x = presence.getChildElement("x", "http://jabber.org/protocol/muc#user");
if (reason != null && reason.trim().length() > 0) {
x.element("item").addElement("reason").setText(reason);
}
x.addElement("status").addAttribute("code", isOutcast ? "301" : "321");
kickPresence(presence, senderRole.getUserAddress(), senderRole.getNickname());
}
}
updatedPresences.addAll(thisOccupant);
} catch (NotAllowedException e) {
Log.error("Error updating presences for " + occupantJID, e);
}
}
return updatedPresences;
}
use of org.xmpp.packet.Presence in project Openfire by igniterealtime.
the class LocalMUCRoom method sendInitialPresences.
/**
* Sends presence of existing occupants to new occupant.
*
* @param joinRole the role of the new occupant in the room.
*/
private void sendInitialPresences(LocalMUCRole joinRole) {
for (MUCRole occupant : occupantsByFullJID.values()) {
if (occupant == joinRole) {
continue;
}
Presence occupantPresence = occupant.getPresence();
// Skip to the next occupant if we cannot send presence of this occupant
if (hasToCheckRoleToBroadcastPresence()) {
Element frag = occupantPresence.getChildElement("x", "http://jabber.org/protocol/muc#user");
// Check if we can broadcast the presence for this role
if (!canBroadcastPresence(frag.element("item").attributeValue("role"))) {
continue;
}
}
// is not a moderator
if (!canAnyoneDiscoverJID() && MUCRole.Role.moderator != joinRole.getRole()) {
occupantPresence = occupantPresence.createCopy();
Element frag = occupantPresence.getChildElement("x", "http://jabber.org/protocol/muc#user");
frag.element("item").addAttribute("jid", null);
}
joinRole.send(occupantPresence);
}
}
Aggregations