📄 localmucroom.java
字号:
/**
* $RCSfile$
* $Revision: 3158 $
* $Date: 2005-12-04 22:55:49 -0300 (Sun, 04 Dec 2005) $
*
* Copyright (C) 2004-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.muc.spi;
import org.dom4j.Element;
import org.jivesoftware.database.SequenceManager;
import org.jivesoftware.openfire.PacketRouter;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.cluster.NodeID;
import org.jivesoftware.openfire.muc.*;
import org.jivesoftware.openfire.muc.cluster.*;
import org.jivesoftware.openfire.user.UserAlreadyExistsException;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.*;
import org.jivesoftware.util.cache.CacheFactory;
import org.jivesoftware.util.cache.ExternalizableUtil;
import org.xmpp.packet.*;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Implementation of a chatroom that is being hosted by this JVM. A LocalMUCRoom could represent
* a persistent room which means that its configuration will be maintained in synch with its
* representation in the database.<p>
*
* When running in a cluster each cluster node will have its own copy of local rooms. Persistent
* rooms will be loaded by each cluster node when starting up. Not persistent rooms will be copied
* from the senior cluster member. All room occupants will be copied from the senior cluster member
* too.
*
* @author Gaston Dombiak
*/
public class LocalMUCRoom implements MUCRoom {
/**
* The server hosting the room.
*/
private MultiUserChatServerImpl server;
/**
* The occupants of the room accessible by the occupants nickname.
*/
private Map<String,MUCRole> occupants = new ConcurrentHashMap<String, MUCRole>();
/**
* The occupants of the room accessible by the occupants bare JID.
*/
private Map<String, List<MUCRole>> occupantsByBareJID = new ConcurrentHashMap<String, List<MUCRole>>();
/**
* The occupants of the room accessible by the occupants full JID.
*/
private Map<JID, MUCRole> occupantsByFullJID = new ConcurrentHashMap<JID, MUCRole>();
/**
* The name of the room.
*/
private String name;
/**
* A lock to protect the room occupants.
*/
ReadWriteLock lock = new ReentrantReadWriteLock();
/**
* The role of the room itself.
*/
private MUCRole role = new RoomRole(this);
/**
* The router used to send packets for the room.
*/
private PacketRouter router;
/**
* The start time of the chat.
*/
long startTime;
/**
* The end time of the chat.
*/
long endTime;
/**
* After a room has been destroyed it may remain in memory but it won't be possible to use it.
* When a room is destroyed it is immediately removed from the MultiUserChatServer but it's
* possible that while the room was being destroyed it was being used by another thread so we
* need to protect the room under these rare circumstances.
*/
boolean isDestroyed = false;
/**
* ChatRoomHistory object.
*/
private MUCRoomHistory roomHistory;
/**
* Time when the room was locked. A value of zero means that the room is unlocked.
*/
private long lockedTime;
/**
* List of chatroom's owner. The list contains only bare jid.
*/
List<String> owners = new CopyOnWriteArrayList<String>();
/**
* List of chatroom's admin. The list contains only bare jid.
*/
List<String> admins = new CopyOnWriteArrayList<String>();
/**
* List of chatroom's members. The list contains only bare jid.
*/
private Map<String, String> members = new ConcurrentHashMap<String,String>();
/**
* List of chatroom's outcast. The list contains only bare jid of not allowed users.
*/
private List<String> outcasts = new CopyOnWriteArrayList<String>();
/**
* The natural language name of the room.
*/
private String naturalLanguageName;
/**
* Description of the room. The owner can change the description using the room configuration
* form.
*/
private String description;
/**
* Indicates if occupants are allowed to change the subject of the room.
*/
private boolean canOccupantsChangeSubject = JiveGlobals.getBooleanProperty("muc.room.canOccupantsChangeSubject", false);
/**
* Maximum number of occupants that could be present in the room. If the limit's been reached
* and a user tries to join, a not-allowed error will be returned.
*/
private int maxUsers = JiveGlobals.getIntProperty("muc.room.maxUsers", 30);
/**
* List of roles of which presence will be broadcasted to the rest of the occupants. This
* feature is useful for implementing "invisible" occupants.
*/
private List<String> rolesToBroadcastPresence = new ArrayList<String>();
/**
* A public room means that the room is searchable and visible. This means that the room can be
* located using disco requests.
*/
private boolean publicRoom = JiveGlobals.getBooleanProperty("muc.room.publicRoom", true);
/**
* Persistent rooms are saved to the database to make sure that rooms configurations can be
* restored in case the server goes down.
*/
private boolean persistent = JiveGlobals.getBooleanProperty("muc.room.persistent", false);
/**
* Moderated rooms enable only participants to speak. Users that join the room and aren't
* participants can't speak (they are just visitors).
*/
private boolean moderated = JiveGlobals.getBooleanProperty("muc.room.moderated", false);
/**
* A room is considered members-only if an invitation is required in order to enter the room.
* Any user that is not a member of the room won't be able to join the room unless the user
* decides to register with the room (thus becoming a member).
*/
private boolean membersOnly = JiveGlobals.getBooleanProperty("muc.room.membersOnly", false);
/**
* Some rooms may restrict the occupants that are able to send invitations. Sending an
* invitation in a members-only room adds the invitee to the members list.
*/
private boolean canOccupantsInvite = JiveGlobals.getBooleanProperty("muc.room.canOccupantsInvite", false);
/**
* The password that every occupant should provide in order to enter the room.
*/
private String password = null;
/**
* Every presence packet can include the JID of every occupant unless the owner deactives this
* configuration.
*/
private boolean canAnyoneDiscoverJID = JiveGlobals.getBooleanProperty("muc.room.canAnyoneDiscoverJID", true);
/**
* Enables the logging of the conversation. The conversation in the room will be saved to the
* database.
*/
private boolean logEnabled = JiveGlobals.getBooleanProperty("muc.room.logEnabled", false);
/**
* Enables the logging of the conversation. The conversation in the room will be saved to the
* database.
*/
private boolean loginRestrictedToNickname = JiveGlobals.getBooleanProperty("muc.room.loginRestrictedToNickname", false);
/**
* Enables the logging of the conversation. The conversation in the room will be saved to the
* database.
*/
private boolean canChangeNickname = JiveGlobals.getBooleanProperty("muc.room.canChangeNickname", true);
/**
* Enables the logging of the conversation. The conversation in the room will be saved to the
* database.
*/
private boolean registrationEnabled = JiveGlobals.getBooleanProperty("muc.room.registrationEnabled", true);
/**
* Internal component that handles IQ packets sent by the room owners.
*/
private IQOwnerHandler iqOwnerHandler;
/**
* Internal component that handles IQ packets sent by moderators, admins and owners.
*/
private IQAdminHandler iqAdminHandler;
/**
* The last known subject of the room. This information is used to respond disco requests. The
* MUCRoomHistory class holds the history of the room together with the last message that set
* the room's subject.
*/
private String subject = "";
/**
* The ID of the room. If the room is temporary and does not log its conversation then the value
* will always be -1. Otherwise a value will be obtained from the database.
*/
private long roomID = -1;
/**
* The date when the room was created.
*/
private Date creationDate;
/**
* The last date when the room's configuration was modified.
*/
private Date modificationDate;
/**
* The date when the last occupant left the room. A null value means that there are occupants
* in the room at the moment.
*/
private Date emptyDate;
/**
* Indicates if the room is present in the database.
*/
private boolean savedToDB = false;
/**
* Do not use this constructor. It was added to implement the Externalizable
* interface required to work inside of a cluster.
*/
public LocalMUCRoom() {
}
/**
* Create a new chat room.
*
* @param chatserver the server hosting the room.
* @param roomname the name of the room.
* @param packetRouter the router for sending packets from the room.
*/
LocalMUCRoom(MultiUserChatServer chatserver, String roomname, PacketRouter packetRouter) {
this.server = (MultiUserChatServerImpl) chatserver;
this.name = roomname;
this.naturalLanguageName = roomname;
this.description = roomname;
this.router = packetRouter;
this.startTime = System.currentTimeMillis();
this.creationDate = new Date(startTime);
this.modificationDate = new Date(startTime);
this.emptyDate = new Date(startTime);
// TODO Allow to set the history strategy from the configuration form?
roomHistory = new MUCRoomHistory(this, new HistoryStrategy(server.getHistoryStrategy()));
this.iqOwnerHandler = new IQOwnerHandler(this, packetRouter);
this.iqAdminHandler = new IQAdminHandler(this, packetRouter);
// No one can join the room except the room's owner
this.lockedTime = startTime;
// Set the default roles for which presence is broadcast
rolesToBroadcastPresence.add("moderator");
rolesToBroadcastPresence.add("participant");
rolesToBroadcastPresence.add("visitor");
}
public String getName() {
return name;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -