mucroomimpl.java
来自「基于Jabber协议的即时消息服务器」· Java 代码 · 共 1,693 行 · 第 1/5 页
JAVA
1,693 行
/**
* $RCSfile$
* $Revision: 3158 $
* $Date: 2005-12-04 22:55:49 -0300 (Sun, 04 Dec 2005) $
*
* Copyright (C) 2004 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.
*/
package org.jivesoftware.wildfire.muc.spi;
import org.dom4j.Element;
import org.jivesoftware.database.SequenceManager;
import org.jivesoftware.util.JiveConstants;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.NotFoundException;
import org.jivesoftware.wildfire.PacketRouter;
import org.jivesoftware.wildfire.auth.UnauthorizedException;
import org.jivesoftware.wildfire.muc.*;
import org.jivesoftware.wildfire.user.UserAlreadyExistsException;
import org.jivesoftware.wildfire.user.UserNotFoundException;
import org.xmpp.packet.*;
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;
/**
* Simple in-memory implementation of a chatroom. A MUCRoomImpl could represent a persistent room
* which means that its configuration will be maintained in synch with its representation in the
* database.
*
* @author Gaston Dombiak
*/
public class MUCRoomImpl implements MUCRoom {
/**
* The server hosting the room.
*/
private MultiUserChatServer 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;
/**
* 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = false;
/**
* Enables the logging of the conversation. The conversation in the room will be saved to the
* database.
*/
private boolean logEnabled = false;
/**
* Enables the logging of the conversation. The conversation in the room will be saved to the
* database.
*/
private boolean loginRestrictedToNickname = false;
/**
* Enables the logging of the conversation. The conversation in the room will be saved to the
* database.
*/
private boolean canChangeNickname = true;
/**
* Enables the logging of the conversation. The conversation in the room will be saved to the
* database.
*/
private boolean 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;
/**
* 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.
*/
MUCRoomImpl(MultiUserChatServer chatserver, String roomname, PacketRouter packetRouter) {
this.server = 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()));
role = new RoomRole(this);
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;
}
public long getID() {
if (isPersistent() || isLogEnabled()) {
if (roomID == -1) {
roomID = SequenceManager.nextID(JiveConstants.MUC_ROOM);
}
}
return roomID;
}
public void setID(long roomID) {
this.roomID = roomID;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public Date getModificationDate() {
return modificationDate;
}
public void setModificationDate(Date modificationDate) {
this.modificationDate = modificationDate;
}
public void setEmptyDate(Date emptyDate) {
// Do nothing if old value is same as new value
if (this.emptyDate == emptyDate) {
return;
}
this.emptyDate = emptyDate;
MUCPersistenceManager.updateRoomEmptyDate(this);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?