📄 mucpersistencemanager.java
字号:
/**
* $RCSfile$
* $Revision: 1623 $
* $Date: 2005-07-12 18:40:57 -0300 (Tue, 12 Jul 2005) $
*
* Copyright (C) 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.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.openfire.PacketRouter;
import org.jivesoftware.openfire.muc.MUCRole;
import org.jivesoftware.openfire.muc.MUCRoom;
import org.jivesoftware.openfire.muc.MultiUserChatServer;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
/**
* A manager responsible for ensuring room persistence. There are different ways to make a room
* persistent. The first attempt will be to save the room in a relation database. If for some reason
* the room can't be saved in the database an alternative repository will be used to save the room
* such as XML files.<p>
*
* After the problem with the database has been solved, the information saved in the XML files will
* be moved to the database.
*
* @author Gaston Dombiak
*/
public class MUCPersistenceManager {
private static final String GET_RESERVED_NAME =
"SELECT nickname FROM mucMember WHERE roomID=? AND jid=?";
private static final String LOAD_ROOM =
"SELECT roomID, creationDate, modificationDate, naturalName, description, lockedDate, " +
"emptyDate, canChangeSubject, maxUsers, publicRoom, moderated, membersOnly, canInvite, " +
"roomPassword, canDiscoverJID, logEnabled, subject, rolesToBroadcast, useReservedNick, " +
"canChangeNick, canRegister FROM mucRoom WHERE name=?";
private static final String LOAD_AFFILIATIONS =
"SELECT jid, affiliation FROM mucAffiliation WHERE roomID=?";
private static final String LOAD_MEMBERS =
"SELECT jid, nickname FROM mucMember WHERE roomID=?";
private static final String LOAD_HISTORY =
"SELECT sender, nickname, logTime, subject, body FROM mucConversationLog " +
"WHERE logTime>? AND roomID=? AND (nickname IS NOT NULL OR subject IS NOT NULL) ORDER BY logTime";
private static final String LOAD_ALL_ROOMS =
"SELECT roomID, creationDate, modificationDate, name, naturalName, description, " +
"lockedDate, emptyDate, canChangeSubject, maxUsers, publicRoom, moderated, membersOnly, " +
"canInvite, roomPassword, canDiscoverJID, logEnabled, subject, rolesToBroadcast, " +
"useReservedNick, canChangeNick, canRegister " +
"FROM mucRoom WHERE emptyDate IS NULL or emptyDate > ?";
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 LOAD_ALL_HISTORY =
"SELECT roomID, sender, nickname, logTime, subject, body FROM mucConversationLog " +
"WHERE logTime>? AND (nickname IS NOT NULL OR subject IS NOT NULL) ORDER BY logTime";
private static final String UPDATE_ROOM =
"UPDATE mucRoom SET modificationDate=?, naturalName=?, description=?, " +
"canChangeSubject=?, maxUsers=?, publicRoom=?, moderated=?, membersOnly=?, " +
"canInvite=?, roomPassword=?, canDiscoverJID=?, logEnabled=?, rolesToBroadcast=?, " +
"useReservedNick=?, canChangeNick=?, canRegister=? WHERE roomID=?";
private static final String ADD_ROOM =
"INSERT INTO mucRoom (roomID, creationDate, modificationDate, name, naturalName, " +
"description, lockedDate, emptyDate, canChangeSubject, maxUsers, publicRoom, moderated, " +
"membersOnly, canInvite, roomPassword, canDiscoverJID, logEnabled, subject, " +
"rolesToBroadcast, useReservedNick, canChangeNick, canRegister) VALUES (?,?,?,?,?,?,?,?," +
"?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
private static final String UPDATE_SUBJECT =
"UPDATE mucRoom SET subject=? WHERE roomID=?";
private static final String UPDATE_LOCK =
"UPDATE mucRoom SET lockedDate=? WHERE roomID=?";
private static final String UPDATE_EMPTYDATE =
"UPDATE mucRoom SET emptyDate=? WHERE roomID=?";
private static final String DELETE_ROOM =
"DELETE FROM mucRoom WHERE roomID=?";
private static final String DELETE_AFFILIATIONS =
"DELETE FROM mucAffiliation WHERE roomID=?";
private static final String DELETE_MEMBERS =
"DELETE FROM mucMember WHERE roomID=?";
private static final String ADD_MEMBER =
"INSERT INTO mucMember (roomID,jid,nickname) VALUES (?,?,?)";
private static final String UPDATE_MEMBER =
"UPDATE mucMember SET nickname=? WHERE roomID=? AND jid=?";
private static final String DELETE_MEMBER =
"DELETE FROM mucMember WHERE roomID=? AND jid=?";
private static final String ADD_AFFILIATION =
"INSERT INTO mucAffiliation (roomID,jid,affiliation) VALUES (?,?,?)";
private static final String UPDATE_AFFILIATION =
"UPDATE mucAffiliation SET affiliation=? WHERE roomID=? AND jid=?";
private static final String DELETE_AFFILIATION =
"DELETE FROM mucAffiliation WHERE roomID=? AND jid=?";
private static final String ADD_CONVERSATION_LOG =
"INSERT INTO mucConversationLog (roomID,sender,nickname,logTime,subject,body) " +
"VALUES (?,?,?,?,?,?)";
/**
* Returns the reserved room nickname for the bare JID in a given room or null if none.
*
* @param room the room where the user would like to obtain his reserved nickname.
* @param bareJID The bare jid of the user of which you'd like to obtain his reserved nickname.
* @return the reserved room nickname for the bare JID or null if none.
*/
public static String getReservedNickname(MUCRoom room, String bareJID) {
Connection con = null;
PreparedStatement pstmt = null;
String answer = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(GET_RESERVED_NAME);
pstmt.setLong(1, room.getID());
pstmt.setString(2, bareJID);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
answer = rs.getString(1);
}
rs.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;
}
/**
* Loads the room configuration from the database if the room was persistent.
*
* @param room the room to load from the database if persistent
*/
public static void loadFromDB(LocalMUCRoom room) {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_ROOM);
pstmt.setString(1, room.getName());
ResultSet rs = pstmt.executeQuery();
if (!rs.next()) {
throw new IllegalArgumentException("Room " + room.getName() + " was not found in the database.");
}
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(4));
room.setDescription(rs.getString(5));
room.setLockedDate(new Date(Long.parseLong(rs.getString(6).trim())));
if (rs.getString(7) != null) {
room.setEmptyDate(new Date(Long.parseLong(rs.getString(7).trim())));
}
else {
room.setEmptyDate(null);
}
room.setCanOccupantsChangeSubject(rs.getInt(8) == 1 ? true : false);
room.setMaxUsers(rs.getInt(9));
room.setPublicRoom(rs.getInt(10) == 1 ? true : false);
room.setModerated(rs.getInt(11) == 1 ? true : false);
room.setMembersOnly(rs.getInt(12) == 1 ? true : false);
room.setCanOccupantsInvite(rs.getInt(13) == 1 ? true : false);
room.setPassword(rs.getString(14));
room.setCanAnyoneDiscoverJID(rs.getInt(15) == 1 ? true : false);
room.setLogEnabled(rs.getInt(16) == 1 ? true : false);
room.setSubject(rs.getString(17));
List<String> rolesToBroadcast = new ArrayList<String>();
String roles = Integer.toBinaryString(rs.getInt(18));
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);
room.setLoginRestrictedToNickname(rs.getInt(19) == 1 ? true : false);
room.setChangeNickname(rs.getInt(20) == 1 ? true : false);
room.setRegistrationEnabled(rs.getInt(21) == 1 ? true : false);
room.setPersistent(true);
rs.close();
pstmt.close();
pstmt = con.prepareStatement(LOAD_HISTORY);
// Recreate the history until two days ago
long from = System.currentTimeMillis() - (86400000 * 2);
pstmt.setString(1, StringUtils.dateToMillis(new Date(from)));
pstmt.setLong(2, room.getID());
rs = pstmt.executeQuery();
while (rs.next()) {
String senderJID = rs.getString(1);
String nickname = rs.getString(2);
Date sentDate = new Date(Long.parseLong(rs.getString(3).trim()));
String subject = rs.getString(4);
String body = rs.getString(5);
// Recreate the history only for the rooms that have the conversation logging
// enabled
if (room.isLogEnabled()) {
room.getRoomHistory().addOldMessage(senderJID, nickname, sentDate, subject,
body);
}
}
rs.close();
pstmt.close();
// If the room does not include the last subject in the history then recreate one if
// possible
if (!room.getRoomHistory().hasChangedSubject() && room.getSubject() != null &&
room.getSubject().length() > 0) {
room.getRoomHistory().addOldMessage(room.getRole().getRoleAddress().toString(),
null, room.getModificationDate(), room.getSubject(), null);
}
pstmt = con.prepareStatement(LOAD_AFFILIATIONS);
pstmt.setLong(1, room.getID());
rs = pstmt.executeQuery();
while (rs.next()) {
String jid = rs.getString(1);
MUCRole.Affiliation affiliation = MUCRole.Affiliation.valueOf(rs.getInt(2));
try {
switch (affiliation) {
case owner:
room.addOwner(jid, room.getRole());
break;
case admin:
room.addAdmin(jid, room.getRole());
break;
case 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_MEMBERS);
pstmt.setLong(1, room.getID());
rs = pstmt.executeQuery();
while (rs.next()) {
try {
room.addMember(rs.getString(1), rs.getString(2), room.getRole());
}
catch (Exception e) {
Log.error(e);
}
}
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);
if (room.getEmptyDate() == null) {
// The service process was killed somehow while the room was being used. Since
// the room won't have occupants at this time we need to set the best date when
// the last occupant left the room that we can
room.setEmptyDate(new Date());
}
}
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); }
}
}
/**
* Save the room configuration to the DB.
*
* @param room The room to save its configuration.
*/
public static void saveToDB(LocalMUCRoom room) {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
if (room.wasSavedToDB()) {
pstmt = con.prepareStatement(UPDATE_ROOM);
pstmt.setString(1, StringUtils.dateToMillis(room.getModificationDate()));
pstmt.setString(2, room.getNaturalLanguageName());
pstmt.setString(3, room.getDescription());
pstmt.setInt(4, (room.canOccupantsChangeSubject() ? 1 : 0));
pstmt.setInt(5, room.getMaxUsers());
pstmt.setInt(6, (room.isPublicRoom() ? 1 : 0));
pstmt.setInt(7, (room.isModerated() ? 1 : 0));
pstmt.setInt(8, (room.isMembersOnly() ? 1 : 0));
pstmt.setInt(9, (room.canOccupantsInvite() ? 1 : 0));
pstmt.setString(10, room.getPassword());
pstmt.setInt(11, (room.canAnyoneDiscoverJID() ? 1 : 0));
pstmt.setInt(12, (room.isLogEnabled() ? 1 : 0));
pstmt.setInt(13, marshallRolesToBroadcast(room));
pstmt.setInt(14, (room.isLoginRestrictedToNickname() ? 1 : 0));
pstmt.setInt(15, (room.canChangeNickname() ? 1 : 0));
pstmt.setInt(16, (room.isRegistrationEnabled() ? 1 : 0));
pstmt.setLong(17, room.getID());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -