Commit efcc5ed0 authored by Daniel Henninger's avatar Daniel Henninger Committed by dhenninger

[JM-1284] Added support for multiple MUC services. Reviewer: Gabriel

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@10071 b35dd754-fafc-0310-a699-88a17e54d16e
parent bba3e672
......@@ -178,7 +178,23 @@ CREATE INDEX jiveSecAuditLog_uname_idx ON jiveSecurityAuditLog (username);
-- MUC tables
CREATE TABLE mucService (
serviceID INTEGER NOT NULL,
subdomain VARCHAR(255) NOT NULL,
description VARCHAR(255),
CONSTRAINT mucService_pk PRIMARY KEY (subdomain)
);
CREATE INDEX mucService_serviceid_idx ON mucService(serviceID);
CREATE TABLE mucServiceProp (
serviceID INTEGER NOT NULL,
name VARCHAR(100) NOT NULL,
propValue VARCHAR(2000) NOT NULL,
CONSTRAINT mucServiceProp_pk PRIMARY KEY (serviceID, name)
);
CREATE TABLE mucRoom (
serviceID INTEGER NOT NULL,
roomID INTEGER NOT NULL,
creationDate CHAR(15) NOT NULL,
modificationDate CHAR(15) NOT NULL,
......@@ -201,9 +217,10 @@ CREATE TABLE mucRoom (
useReservedNick INTEGER NOT NULL,
canChangeNick INTEGER NOT NULL,
canRegister INTEGER NOT NULL,
CONSTRAINT mucRoom_pk PRIMARY KEY (name)
CONSTRAINT mucRoom_pk PRIMARY KEY (serviceID, name)
);
CREATE INDEX mucRm_roomid_idx ON mucRoom (roomID);
CREATE INDEX mucRm_serviceid_idx ON mucRoom (serviceID);
CREATE TABLE mucRoomProp (
......@@ -365,9 +382,13 @@ CREATE TABLE pubsubDefaultConf (
INSERT INTO jiveID (idType, id) VALUES (18, 1);
INSERT INTO jiveID (idType, id) VALUES (19, 1);
INSERT INTO jiveID (idType, id) VALUES (23, 1);
INSERT INTO jiveID (idType, id) VALUES (26, 1);
INSERT INTO jiveVersion (name, version) VALUES ('openfire', 16);
INSERT INTO jiveVersion (name, version) VALUES ('openfire', 17);
-- Entry for admin user
INSERT INTO jiveUser (username, plainPassword, name, email, creationDate, modificationDate)
VALUES ('admin', 'admin', 'Administrator', 'admin@example.com', '0', '0');
\ No newline at end of file
VALUES ('admin', 'admin', 'Administrator', 'admin@example.com', '0', '0');
-- Entry for default conference service
INSERT INTO mucService (serviceID, subdomain) VALUES (1, "conference");
\ No newline at end of file
......@@ -174,7 +174,23 @@ CREATE INDEX jiveSecAuditLog_uname_idx ON jiveSecurityAuditLog (username);
// MUC Tables
CREATE TABLE mucService (
serviceID BIGINT NOT NULL,
subdomain VARCHAR(255) NOT NULL,
description VARCHAR(255),
CONSTRAINT mucService_pk PRIMARY KEY (subdomain)
);
CREATE INDEX mucService_serviceid_idx ON mucService(serviceID);
CREATE TABLE mucServiceProp (
serviceID BIGINT NOT NULL,
name VARCHAR(100) NOT NULL,
propValue VARCHAR(4000) NOT NULL,
CONSTRAINT mucServiceProp_pk PRIMARY KEY (serviceID, name)
);
CREATE TABLE mucRoom (
serviceID BIGINT NOT NULL,
roomID BIGINT NOT NULL,
creationDate CHAR(15) NOT NULL,
modificationDate CHAR(15) NOT NULL,
......@@ -197,10 +213,10 @@ CREATE TABLE mucRoom (
useReservedNick INTEGER NOT NULL,
canChangeNick INTEGER NOT NULL,
canRegister INTEGER NOT NULL,
CONSTRAINT mucRoom_pk PRIMARY KEY (name)
CONSTRAINT mucRoom_pk PRIMARY KEY (serviceID, name)
);
CREATE INDEX mucRoom_roomid_idx ON mucRoom(roomID);
CREATE INDEX mucRoom_serviceid_idx ON mucRoom(serviceID);
CREATE TABLE mucRoomProp (
roomID BIGINT NOT NULL,
......@@ -352,9 +368,13 @@ CREATE TABLE pubsubDefaultConf (
INSERT INTO jiveID (idType, id) VALUES (18, 1);
INSERT INTO jiveID (idType, id) VALUES (19, 1);
INSERT INTO jiveID (idType, id) VALUES (23, 1);
INSERT INTO jiveID (idType, id) VALUES (26, 1);
INSERT INTO jiveVersion (name, version) VALUES ('openfire', 16);
INSERT INTO jiveVersion (name, version) VALUES ('openfire', 17);
// Entry for admin user
INSERT INTO jiveUser (username, plainPassword, name, email, creationDate, modificationDate)
VALUES ('admin', 'admin', 'Administrator', 'admin@example.com', '0', '0');
\ No newline at end of file
VALUES ('admin', 'admin', 'Administrator', 'admin@example.com', '0', '0');
// Entry for default conference service
INSERT INTO mucService (serviceID, subdomain) VALUES (1, "conference");
......@@ -163,7 +163,23 @@ CREATE TABLE jiveSecurityAuditLog (
# MUC Tables
CREATE TABLE mucService (
serviceID BIGINT NOT NULL,
subdomain VARCHAR(255) NOT NULL,
description VARCHAR(255),
PRIMARY KEY (subdomain),
INDEX mucService_serviceid_idx (serviceID)
);
CREATE TABLE mucServiceProp (
serviceID BIGINT NOT NULL,
name VARCHAR(100) NOT NULL,
propValue TEXT NOT NULL,
PRIMARY KEY (serviceID, name)
);
CREATE TABLE mucRoom (
serviceID BIGINT NOT NULL,
roomID BIGINT NOT NULL,
creationDate CHAR(15) NOT NULL,
modificationDate CHAR(15) NOT NULL,
......@@ -186,8 +202,9 @@ CREATE TABLE mucRoom (
useReservedNick TINYINT NOT NULL,
canChangeNick TINYINT NOT NULL,
canRegister TINYINT NOT NULL,
PRIMARY KEY (name),
INDEX mucRoom_roomid_idx (roomID)
PRIMARY KEY (serviceID,name),
INDEX mucRoom_roomid_idx (roomID),
INDEX mucRoom_serviceid_idx (serviceID)
);
CREATE TABLE mucRoomProp (
......@@ -340,9 +357,13 @@ CREATE TABLE pubsubDefaultConf (
INSERT INTO jiveID (idType, id) VALUES (18, 1);
INSERT INTO jiveID (idType, id) VALUES (19, 1);
INSERT INTO jiveID (idType, id) VALUES (23, 1);
INSERT INTO jiveID (idType, id) VALUES (26, 1);
INSERT INTO jiveVersion (name, version) VALUES ('openfire', 16);
INSERT INTO jiveVersion (name, version) VALUES ('openfire', 17);
# Entry for admin user
INSERT INTO jiveUser (username, plainPassword, name, email, creationDate, modificationDate)
VALUES ('admin', 'admin', 'Administrator', 'admin@example.com', '0', '0');
\ No newline at end of file
VALUES ('admin', 'admin', 'Administrator', 'admin@example.com', '0', '0');
# Entry for default conference service
INSERT INTO mucService (serviceID, subdomain) VALUES (1, "conference");
......@@ -171,7 +171,23 @@ CREATE INDEX jiveSecAuditLog_uname_idx ON jiveSecurityAuditLog (username);
-- MUC Tables
CREATE TABLE mucService (
serviceID INT NOT NULL,
subdomain VARCHAR2(255) NOT NULL,
description VARCHAR2(255),
CONSTRAINT mucService_pk PRIMARY KEY (subdomain)
);
CREATE INDEX mucService_serviceid_idx ON mucService(serviceID);
CREATE TABLE mucServiceProp (
serviceID INT NOT NULL,
name VARCHAR2(100) NOT NULL,
propValue VARCHAR2(1024) NOT NULL,
CONSTRAINT mucServiceProp_pk PRIMARY KEY (serviceID, name)
);
CREATE TABLE mucRoom(
serviceID INT NOT NULL,
roomID INT NOT NULL,
creationDate CHAR(15) NOT NULL,
modificationDate CHAR(15) NOT NULL,
......@@ -194,9 +210,10 @@ CREATE TABLE mucRoom(
useReservedNick INTEGER NOT NULL,
canChangeNick INTEGER NOT NULL,
canRegister INTEGER NOT NULL,
CONSTRAINT mucRoom_pk PRIMARY KEY (name)
CONSTRAINT mucRoom_pk PRIMARY KEY (serviceID, name)
);
CREATE INDEX mucRoom_roomid_idx ON mucRoom (roomID);
CREATE INDEX mucRoom_serviceid_idx ON mucRoom (serviceID);
CREATE TABLE mucRoomProp (
roomID INT NOT NULL,
......@@ -348,11 +365,15 @@ CREATE TABLE pubsubDefaultConf (
INSERT INTO jiveID (idType, id) VALUES (18, 1);
INSERT INTO jiveID (idType, id) VALUES (19, 1);
INSERT INTO jiveID (idType, id) VALUES (23, 1);
INSERT INTO jiveID (idType, id) VALUES (26, 1);
INSERT INTO jiveVersion (name, version) VALUES ('openfire', 16);
INSERT INTO jiveVersion (name, version) VALUES ('openfire', 17);
-- Entry for admin user
INSERT INTO jiveUser (username, plainPassword, name, email, creationDate, modificationDate)
VALUES ('admin', 'admin', 'Administrator', 'admin@example.com', '0', '0');
-- Entry for default conference service
INSERT INTO mucService (serviceID, subdomain) VALUES (1, "conference");
commit;
\ No newline at end of file
......@@ -179,7 +179,23 @@ CREATE INDEX jiveSecAuditLog_uname_idx ON jiveSecurityAuditLog (username);
-- MUC Tables
CREATE TABLE mucService (
serviceID INTEGER NOT NULL,
subdomain VARCHAR(255) NOT NULL,
description VARCHAR(255),
CONSTRAINT mucService_pk PRIMARY KEY (subdomain)
);
CREATE INDEX mucService_serviceid_idx ON mucService(serviceID);
CREATE TABLE mucServiceProp (
serviceID INTEGER NOT NULL,
name VARCHAR(100) NOT NULL,
propValue TEXT NOT NULL,
CONSTRAINT mucServiceProp_pk PRIMARY KEY (serviceID, name)
);
CREATE TABLE mucRoom (
serviceID INTEGER NOT NULL,
roomID INTEGER NOT NULL,
creationDate CHAR(15) NOT NULL,
modificationDate CHAR(15) NOT NULL,
......@@ -202,10 +218,10 @@ CREATE TABLE mucRoom (
useReservedNick INTEGER NOT NULL,
canChangeNick INTEGER NOT NULL,
canRegister INTEGER NOT NULL,
CONSTRAINT mucRoom__pk PRIMARY KEY (name)
CONSTRAINT mucRoom__pk PRIMARY KEY (serviceID, name)
);
CREATE INDEX mucRoom_roomID_idx ON mucRoom(roomID);
CREATE INDEX mucRoom_serviceID_idx ON mucRoom(serviceID);
CREATE TABLE mucRoomProp (
roomID INTEGER NOT NULL,
......@@ -357,9 +373,13 @@ CREATE TABLE pubsubDefaultConf (
INSERT INTO jiveID (idType, id) VALUES (18, 1);
INSERT INTO jiveID (idType, id) VALUES (19, 1);
INSERT INTO jiveID (idType, id) VALUES (23, 1);
INSERT INTO jiveID (idType, id) VALUES (26, 1);
INSERT INTO jiveVersion (name, version) VALUES ('openfire', 16);
INSERT INTO jiveVersion (name, version) VALUES ('openfire', 17);
-- Entry for admin user
INSERT INTO jiveUser (username, plainPassword, name, email, creationDate, modificationDate)
VALUES ('admin', 'admin', 'Administrator', 'admin@example.com', '0', '0');
-- Entry for default conference service
INSERT INTO mucService (serviceID, subdomain) VALUES (1, "conference");
......@@ -177,7 +177,23 @@ CREATE INDEX jiveSecAuditLog_uname_idx ON jiveSecurityAuditLog (username);
/* MUC Tables */
CREATE TABLE mucService (
serviceID INT NOT NULL,
subdomain NVARCHAR(255) NOT NULL,
description NVARCHAR(255),
CONSTRAINT mucService_pk PRIMARY KEY (subdomain)
);
CREATE INDEX mucService_serviceid_idx ON mucService(serviceID);
CREATE TABLE mucServiceProp (
serviceID INT NOT NULL,
name NVARCHAR(100) NOT NULL,
propValue NVARCHAR(2000) NOT NULL,
CONSTRAINT mucServiceProp_pk PRIMARY KEY (serviceID, name)
);
CREATE TABLE mucRoom (
serviceID INT NOT NULL,
roomID INT NOT NULL,
creationDate CHAR(15) NOT NULL,
modificationDate CHAR(15) NOT NULL,
......@@ -200,10 +216,10 @@ CREATE TABLE mucRoom (
useReservedNick INT NOT NULL,
canChangeNick INT NOT NULL,
canRegister INT NOT NULL,
CONSTRAINT mucRoom__pk PRIMARY KEY (name)
CONSTRAINT mucRoom__pk PRIMARY KEY (serviceID, name)
);
CREATE INDEX mucRoom_roomID_idx on mucRoom(roomID);
CREATE INDEX mucRoom_serviceID_idx on mucRoom(serviceID);
CREATE TABLE mucRoomProp (
roomID INT NOT NULL,
......@@ -355,9 +371,13 @@ CREATE TABLE pubsubDefaultConf (
INSERT INTO jiveID (idType, id) VALUES (18, 1);
INSERT INTO jiveID (idType, id) VALUES (19, 1);
INSERT INTO jiveID (idType, id) VALUES (23, 1);
INSERT INTO jiveID (idType, id) VALUES (26, 1);
INSERT INTO jiveVersion (name, version) VALUES ('openfire', 16);
INSERT INTO jiveVersion (name, version) VALUES ('openfire', 17);
/* Entry for admin user */
INSERT INTO jiveUser (username, plainPassword, name, email, creationDate, modificationDate)
VALUES ('admin', 'admin', 'Administrator', 'admin@example.com', '0', '0');
\ No newline at end of file
VALUES ('admin', 'admin', 'Administrator', 'admin@example.com', '0', '0');
/* Entry for default conference service */
INSERT INTO mucService (serviceID, subdomain) VALUES (1, "conference");
\ No newline at end of file
......@@ -176,7 +176,23 @@ CREATE INDEX jiveSecAuditLog_uname_idx ON jiveSecurityAuditLog (username);
/* MUC Tables */
CREATE TABLE mucService (
serviceID INT NOT NULL,
subdomain NVARCHAR(255) NOT NULL,
description NVARCHAR(255),
CONSTRAINT mucService_pk PRIMARY KEY (subdomain)
);
CREATE INDEX mucService_serviceid_idx ON mucService(serviceID);
CREATE TABLE mucServiceProp (
serviceID INT NOT NULL,
name NVARCHAR(100) NOT NULL,
propValue TEXT NOT NULL,
CONSTRAINT mucServiceProp_pk PRIMARY KEY (serviceID, name)
);
CREATE TABLE mucRoom (
serviceID INT NOT NULL,
roomID INT NOT NULL,
creationDate CHAR(15) NOT NULL,
modificationDate CHAR(15) NOT NULL,
......@@ -199,10 +215,10 @@ CREATE TABLE mucRoom (
useReservedNick INT NOT NULL,
canChangeNick INT NOT NULL,
canRegister INT NOT NULL,
CONSTRAINT mucRoom__pk PRIMARY KEY (name)
CONSTRAINT mucRoom__pk PRIMARY KEY (serviceID, name)
);
CREATE INDEX mucRoom_roomID_idx on mucRoom(roomID);
CREATE INDEX mucRoom_serviceID_idx on mucRoom(sericeID);
CREATE TABLE mucRoomProp (
roomID INT NOT NULL,
......@@ -354,9 +370,13 @@ CREATE TABLE pubsubDefaultConf (
INSERT INTO jiveID (idType, id) VALUES (18, 1);
INSERT INTO jiveID (idType, id) VALUES (19, 1);
INSERT INTO jiveID (idType, id) VALUES (23, 1);
INSERT INTO jiveID (idType, id) VALUES (26, 1);
INSERT INTO jiveVersion (name, version) VALUES ('openfire', 16);
INSERT INTO jiveVersion (name, version) VALUES ('openfire', 17);
/* Entry for admin user */
INSERT INTO jiveUser (username, plainPassword, name, email, creationDate, modificationDate)
VALUES ('admin', 'admin', 'Administrator', 'admin@example.com', '0', '0');
\ No newline at end of file
VALUES ('admin', 'admin', 'Administrator', 'admin@example.com', '0', '0');
/* Entry for default conference service */
INSERT INTO mucService (serviceID, subdomain) VALUES (1, "conference");
\ No newline at end of file
-- change mucRoom's primary key to be referenced around serviceID
ALTER TABLE mucRoom DROP CONSTRAINT mucRoom_pk;
ALTER TABLE mucRoom ADD CONSTRAINT mucRoom_pk PRIMARY KEY (serviceID, name);
-- create table mucService
CREATE TABLE mucService (
serviceID INTEGER NOT NULL,
subdomain VARCHAR(255) NOT NULL,
description VARCHAR(255),
CONSTRAINT mucService_pk PRIMARY KEY (subdomain)
);
CREATE INDEX mucService_serviceid_idx ON mucService(serviceID);
-- create table mucServiceProp
CREATE TABLE mucServiceProp (
serviceID INTEGER NOT NULL,
name VARCHAR(100) NOT NULL,
propValue VARCHAR(2000) NOT NULL,
CONSTRAINT mucServiceProp_pk PRIMARY KEY (serviceID, name)
);
-- add new indexed column to mucRoom
ALTER TABLE mucRoom ADD COLUMN serviceID INTEGER NOT NULL;
CREATE INDEX mucRm_serviceid_idx ON mucRoom (serviceID);
-- add default entry for conference service and associated jiveID value
INSERT INTO mucService (serviceID, subdomain) VALUES (1, "conference");
INSERT INTO jiveID (idType, id) VALUES (26, 1);
-- update all entries in mucRoom to be set to the default conference service
UPDATE mucRoom set serviceID = 1;
-- update conference name/desc if there's a custom one set
UPDATE mucService SET mucService.subdomain = ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "xmpp.muc.service" )
WHERE EXISTS ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "xmpp.muc.service" );
DELETE FROM jiveProperty WHERE name = "xmpp.muc.service";
UPDATE mucService SET mucService.description = ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "muc.service-name" )
WHERE EXISTS ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "muc.service-name" );
DELETE FROM jiveProperty WHERE name = "muc.service-name";
-- transfer all system properties to muc specific properties
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canOccupantsChangeSubject",propValue FROM jiveProperty WHERE name = "muc.room.canOccupantsChangeSubject";
DELETE FROM jiveProperty WHERE name = "muc.room.canOccupantsChangeSubject";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.maxUsers",propValue FROM jiveProperty WHERE name = "muc.room.maxUsers";
DELETE FROM jiveProperty WHERE name = "muc.room.maxUsers";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.publicRoom",propValue FROM jiveProperty WHERE name = "muc.room.publicRoom";
DELETE FROM jiveProperty WHERE name = "muc.room.publicRoom";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.persistent",propValue FROM jiveProperty WHERE name = "muc.room.persistent";
DELETE FROM jiveProperty WHERE name = "muc.room.persistent";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.moderated",propValue FROM jiveProperty WHERE name = "muc.room.moderated";
DELETE FROM jiveProperty WHERE name = "muc.room.moderated";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.membersOnly",propValue FROM jiveProperty WHERE name = "muc.room.membersOnly";
DELETE FROM jiveProperty WHERE name = "muc.room.membersOnly";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canOccupantsInvite",propValue FROM jiveProperty WHERE name = "muc.room.canOccupantsInvite";
DELETE FROM jiveProperty WHERE name = "muc.room.canOccupantsInvite";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canAnyoneDiscoverJID",propValue FROM jiveProperty WHERE name = "muc.room.canAnyoneDiscoverJID";
DELETE FROM jiveProperty WHERE name = "muc.room.canAnyoneDiscoverJID";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.logEnabled",propValue FROM jiveProperty WHERE name = "muc.room.logEnabled";
DELETE FROM jiveProperty WHERE name = "muc.room.logEnabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.loginRestrictedToNickname",propValue FROM jiveProperty WHERE name = "muc.room.loginRestrictedToNickname";
DELETE FROM jiveProperty WHERE name = "muc.room.loginRestrictedToNickname";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canChangeNickname",propValue FROM jiveProperty WHERE name = "muc.room.canChangeNickname";
DELETE FROM jiveProperty WHERE name = "muc.room.canChangeNickname";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.registrationEnabled",propValue FROM jiveProperty WHERE name = "muc.room.registrationEnabled";
DELETE FROM jiveProperty WHERE name = "muc.room.registrationEnabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.user.timeout",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.timeout";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.timeout";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.user.idle",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.idle";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.idle";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.log.timeout",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.timeout";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.timeout";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.log.batchsize",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.batchsize";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.batchsize";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"sysadmin.jid",propValue FROM jiveProperty WHERE name = "xmpp.muc.sysadmin.jid";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.sysadmin.jid";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"discover.locked",propValue FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"create.anyone",propValue FROM jiveProperty WHERE name = "xmpp.muc.create.anyone";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.create.anyone";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"create.jid",propValue FROM jiveProperty WHERE name = "xmpp.muc.create.jid";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.create.jid";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"enabled",propValue FROM jiveProperty WHERE name = "xmpp.muc.enabled";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.enabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"unload.empty_days",propValue FROM jiveProperty WHERE name = "xmpp.muc.unload.empty_days";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.unload.empty_days";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"discover.locked",propValue FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"history.maxNumber",propValue FROM jiveProperty WHERE name = "xmpp.muc.history.maxNumber";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.history.maxNumber";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"history.type",propValue FROM jiveProperty WHERE name = "xmpp.muc.history.type";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.history.type";
UPDATE jiveVersion set version=17 where name = 'openfire';
// change mucRoom's primary key to be referenced around serviceID
ALTER TABLE mucRoom DROP CONSTRAINT mucRoom_pk;
ALTER TABLE mucRoom ADD CONSTRAINT mucRoom_pk PRIMARY KEY (serviceID, name);
// create table mucService
CREATE TABLE mucService (
serviceID BIGINT NOT NULL,
subdomain VARCHAR(255) NOT NULL,
description VARCHAR(255),
CONSTRAINT mucService_pk PRIMARY KEY (subdomain)
);
CREATE INDEX mucService_serviceid_idx ON mucService(serviceID);
// create table mucServiceProp
CREATE TABLE mucServiceProp (
serviceID BIGINT NOT NULL,
name VARCHAR(100) NOT NULL,
propValue VARCHAR(4000) NOT NULL,
CONSTRAINT mucServiceProp_pk PRIMARY KEY (serviceID, name)
);
// add new indexed column to mucRoom
ALTER TABLE mucRoom ADD COLUMN serviceID BIGINT NOT NULL BEFORE roomID;
CREATE INDEX mucRoom_serviceid_idx ON mucRoom(serviceID);
// add default entry for conference service and associated jiveID value
INSERT INTO mucService (serviceID, subdomain) VALUES (1, "conference");
INSERT INTO jiveID (idType, id) VALUES (26, 1);
// update all entries in mucRoom to be set to the default conference service
UPDATE mucRoom set serviceID = 1;
// update conference name/desc if there's a custom one set
UPDATE mucService SET mucService.subdomain = ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "xmpp.muc.service" )
WHERE EXISTS ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "xmpp.muc.service" );
DELETE FROM jiveProperty WHERE name = "xmpp.muc.service";
UPDATE mucService SET mucService.description = ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "muc.service-name" )
WHERE EXISTS ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "muc.service-name" );
DELETE FROM jiveProperty WHERE name = "muc.service-name";
// transfer all system properties to muc specific properties
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canOccupantsChangeSubject",propValue FROM jiveProperty WHERE name = "muc.room.canOccupantsChangeSubject";
DELETE FROM jiveProperty WHERE name = "muc.room.canOccupantsChangeSubject";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.maxUsers",propValue FROM jiveProperty WHERE name = "muc.room.maxUsers";
DELETE FROM jiveProperty WHERE name = "muc.room.maxUsers";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.publicRoom",propValue FROM jiveProperty WHERE name = "muc.room.publicRoom";
DELETE FROM jiveProperty WHERE name = "muc.room.publicRoom";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.persistent",propValue FROM jiveProperty WHERE name = "muc.room.persistent";
DELETE FROM jiveProperty WHERE name = "muc.room.persistent";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.moderated",propValue FROM jiveProperty WHERE name = "muc.room.moderated";
DELETE FROM jiveProperty WHERE name = "muc.room.moderated";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.membersOnly",propValue FROM jiveProperty WHERE name = "muc.room.membersOnly";
DELETE FROM jiveProperty WHERE name = "muc.room.membersOnly";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canOccupantsInvite",propValue FROM jiveProperty WHERE name = "muc.room.canOccupantsInvite";
DELETE FROM jiveProperty WHERE name = "muc.room.canOccupantsInvite";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canAnyoneDiscoverJID",propValue FROM jiveProperty WHERE name = "muc.room.canAnyoneDiscoverJID";
DELETE FROM jiveProperty WHERE name = "muc.room.canAnyoneDiscoverJID";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.logEnabled",propValue FROM jiveProperty WHERE name = "muc.room.logEnabled";
DELETE FROM jiveProperty WHERE name = "muc.room.logEnabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.loginRestrictedToNickname",propValue FROM jiveProperty WHERE name = "muc.room.loginRestrictedToNickname";
DELETE FROM jiveProperty WHERE name = "muc.room.loginRestrictedToNickname";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canChangeNickname",propValue FROM jiveProperty WHERE name = "muc.room.canChangeNickname";
DELETE FROM jiveProperty WHERE name = "muc.room.canChangeNickname";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.registrationEnabled",propValue FROM jiveProperty WHERE name = "muc.room.registrationEnabled";
DELETE FROM jiveProperty WHERE name = "muc.room.registrationEnabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.user.timeout",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.timeout";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.timeout";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.user.idle",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.idle";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.idle";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.log.timeout",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.timeout";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.timeout";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.log.batchsize",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.batchsize";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.batchsize";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"sysadmin.jid",propValue FROM jiveProperty WHERE name = "xmpp.muc.sysadmin.jid";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.sysadmin.jid";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"discover.locked",propValue FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"create.anyone",propValue FROM jiveProperty WHERE name = "xmpp.muc.create.anyone";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.create.anyone";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"create.jid",propValue FROM jiveProperty WHERE name = "xmpp.muc.create.jid";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.create.jid";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"enabled",propValue FROM jiveProperty WHERE name = "xmpp.muc.enabled";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.enabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"unload.empty_days",propValue FROM jiveProperty WHERE name = "xmpp.muc.unload.empty_days";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.unload.empty_days";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"discover.locked",propValue FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"history.maxNumber",propValue FROM jiveProperty WHERE name = "xmpp.muc.history.maxNumber";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.history.maxNumber";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"history.type",propValue FROM jiveProperty WHERE name = "xmpp.muc.history.type";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.history.type";
UPDATE jiveVersion set version=17 where name = 'openfire';
# change mucRoom's primary key to be referenced around serviceID
ALTER TABLE mucRoom DROP PRIMARY KEY;
ALTER TABLE mucRoom ADD PRIMARY KEY (serviceID,name);
# create table mucService
CREATE TABLE mucService (
serviceID BIGINT NOT NULL,
subdomain VARCHAR(255) NOT NULL,
description VARCHAR(255),
PRIMARY KEY (subdomain),
INDEX mucService_serviceid_idx (serviceID)
);
# create table mucServiceProp
CREATE TABLE mucServiceProp (
serviceID BIGINT NOT NULL,
name VARCHAR(100) NOT NULL,
propValue TEXT NOT NULL,
PRIMARY KEY (serviceID, name)
);
# add new indexed column to mucRoom
ALTER TABLE mucRoom ADD COLUMN serviceID BIGINT NOT NULL FIRST;
ALTER TABLE mucRoom ADD INDEX mucRoom_serviceid_idx (serviceID);
# add default entry for conference service and associated jiveID value
INSERT INTO mucService (serviceID, subdomain) VALUES (1, "conference");
INSERT INTO jiveID (idType, id) VALUES (26, 1);
# update all entries in mucRoom to be set to the default conference service
UPDATE mucRoom set serviceID = 1;
# update conference name/desc if there's a custom one set
UPDATE mucService SET mucService.subdomain = ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "xmpp.muc.service" )
WHERE EXISTS ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "xmpp.muc.service" );
DELETE FROM jiveProperty WHERE name = "xmpp.muc.service";
UPDATE mucService SET mucService.description = ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "muc.service-name" )
WHERE EXISTS ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "muc.service-name" );
DELETE FROM jiveProperty WHERE name = "muc.service-name";
# transfer all system properties to muc specific properties
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canOccupantsChangeSubject",propValue FROM jiveProperty WHERE name = "muc.room.canOccupantsChangeSubject";
DELETE FROM jiveProperty WHERE name = "muc.room.canOccupantsChangeSubject";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.maxUsers",propValue FROM jiveProperty WHERE name = "muc.room.maxUsers";
DELETE FROM jiveProperty WHERE name = "muc.room.maxUsers";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.publicRoom",propValue FROM jiveProperty WHERE name = "muc.room.publicRoom";
DELETE FROM jiveProperty WHERE name = "muc.room.publicRoom";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.persistent",propValue FROM jiveProperty WHERE name = "muc.room.persistent";
DELETE FROM jiveProperty WHERE name = "muc.room.persistent";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.moderated",propValue FROM jiveProperty WHERE name = "muc.room.moderated";
DELETE FROM jiveProperty WHERE name = "muc.room.moderated";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.membersOnly",propValue FROM jiveProperty WHERE name = "muc.room.membersOnly";
DELETE FROM jiveProperty WHERE name = "muc.room.membersOnly";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canOccupantsInvite",propValue FROM jiveProperty WHERE name = "muc.room.canOccupantsInvite";
DELETE FROM jiveProperty WHERE name = "muc.room.canOccupantsInvite";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canAnyoneDiscoverJID",propValue FROM jiveProperty WHERE name = "muc.room.canAnyoneDiscoverJID";
DELETE FROM jiveProperty WHERE name = "muc.room.canAnyoneDiscoverJID";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.logEnabled",propValue FROM jiveProperty WHERE name = "muc.room.logEnabled";
DELETE FROM jiveProperty WHERE name = "muc.room.logEnabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.loginRestrictedToNickname",propValue FROM jiveProperty WHERE name = "muc.room.loginRestrictedToNickname";
DELETE FROM jiveProperty WHERE name = "muc.room.loginRestrictedToNickname";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canChangeNickname",propValue FROM jiveProperty WHERE name = "muc.room.canChangeNickname";
DELETE FROM jiveProperty WHERE name = "muc.room.canChangeNickname";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.registrationEnabled",propValue FROM jiveProperty WHERE name = "muc.room.registrationEnabled";
DELETE FROM jiveProperty WHERE name = "muc.room.registrationEnabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.user.timeout",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.timeout";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.timeout";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.user.idle",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.idle";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.idle";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.log.timeout",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.timeout";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.timeout";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.log.batchsize",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.batchsize";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.batchsize";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"sysadmin.jid",propValue FROM jiveProperty WHERE name = "xmpp.muc.sysadmin.jid";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.sysadmin.jid";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"discover.locked",propValue FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"create.anyone",propValue FROM jiveProperty WHERE name = "xmpp.muc.create.anyone";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.create.anyone";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"create.jid",propValue FROM jiveProperty WHERE name = "xmpp.muc.create.jid";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.create.jid";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"enabled",propValue FROM jiveProperty WHERE name = "xmpp.muc.enabled";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.enabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"unload.empty_days",propValue FROM jiveProperty WHERE name = "xmpp.muc.unload.empty_days";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.unload.empty_days";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"discover.locked",propValue FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"history.maxNumber",propValue FROM jiveProperty WHERE name = "xmpp.muc.history.maxNumber";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.history.maxNumber";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"history.type",propValue FROM jiveProperty WHERE name = "xmpp.muc.history.type";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.history.type";
UPDATE jiveVersion set version=17 where name = 'openfire';
-- change mucRoom's primary key to be referenced around serviceID
ALTER TABLE mucRoom DROP CONSTRAINT mucRoom_pk;
ALTER TABLE mucRoom ADD CONSTRAINT mucRoom_pk PRIMARY KEY (serviceID, name);
-- create table mucService
CREATE TABLE mucService (
serviceID INT NOT NULL,
subdomain VARCHAR2(255) NOT NULL,
description VARCHAR2(255),
CONSTRAINT mucService_pk PRIMARY KEY (subdomain)
);
CREATE INDEX mucService_serviceid_idx ON mucService(serviceID);
-- create table mucServiceProp
CREATE TABLE mucServiceProp (
serviceID INT NOT NULL,
name VARCHAR2(100) NOT NULL,
propValue VARCHAR2(1024) NOT NULL,
CONSTRAINT mucServiceProp_pk PRIMARY KEY (serviceID, name)
);
-- add new indexed column to mucRoom
ALTER TABLE mucRoom ADD COLUMN serviceID INT NOT NULL;
CREATE INDEX mucRm_serviceid_idx ON mucRoom (serviceID);
-- add default entry for conference service and associated jiveID value
INSERT INTO mucService (serviceID, subdomain) VALUES (1, "conference");
INSERT INTO jiveID (idType, id) VALUES (26, 1);
-- update all entries in mucRoom to be set to the default conference service
UPDATE mucRoom set serviceID = 1;
-- update conference name/desc if there's a custom one set
UPDATE mucService SET mucService.subdomain = ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "xmpp.muc.service" )
WHERE EXISTS ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "xmpp.muc.service" );
DELETE FROM jiveProperty WHERE name = "xmpp.muc.service";
UPDATE mucService SET mucService.description = ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "muc.service-name" )
WHERE EXISTS ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "muc.service-name" );
DELETE FROM jiveProperty WHERE name = "muc.service-name";
-- transfer all system properties to muc specific properties
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canOccupantsChangeSubject",propValue FROM jiveProperty WHERE name = "muc.room.canOccupantsChangeSubject";
DELETE FROM jiveProperty WHERE name = "muc.room.canOccupantsChangeSubject";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.maxUsers",propValue FROM jiveProperty WHERE name = "muc.room.maxUsers";
DELETE FROM jiveProperty WHERE name = "muc.room.maxUsers";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.publicRoom",propValue FROM jiveProperty WHERE name = "muc.room.publicRoom";
DELETE FROM jiveProperty WHERE name = "muc.room.publicRoom";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.persistent",propValue FROM jiveProperty WHERE name = "muc.room.persistent";
DELETE FROM jiveProperty WHERE name = "muc.room.persistent";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.moderated",propValue FROM jiveProperty WHERE name = "muc.room.moderated";
DELETE FROM jiveProperty WHERE name = "muc.room.moderated";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.membersOnly",propValue FROM jiveProperty WHERE name = "muc.room.membersOnly";
DELETE FROM jiveProperty WHERE name = "muc.room.membersOnly";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canOccupantsInvite",propValue FROM jiveProperty WHERE name = "muc.room.canOccupantsInvite";
DELETE FROM jiveProperty WHERE name = "muc.room.canOccupantsInvite";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canAnyoneDiscoverJID",propValue FROM jiveProperty WHERE name = "muc.room.canAnyoneDiscoverJID";
DELETE FROM jiveProperty WHERE name = "muc.room.canAnyoneDiscoverJID";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.logEnabled",propValue FROM jiveProperty WHERE name = "muc.room.logEnabled";
DELETE FROM jiveProperty WHERE name = "muc.room.logEnabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.loginRestrictedToNickname",propValue FROM jiveProperty WHERE name = "muc.room.loginRestrictedToNickname";
DELETE FROM jiveProperty WHERE name = "muc.room.loginRestrictedToNickname";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canChangeNickname",propValue FROM jiveProperty WHERE name = "muc.room.canChangeNickname";
DELETE FROM jiveProperty WHERE name = "muc.room.canChangeNickname";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.registrationEnabled",propValue FROM jiveProperty WHERE name = "muc.room.registrationEnabled";
DELETE FROM jiveProperty WHERE name = "muc.room.registrationEnabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.user.timeout",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.timeout";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.timeout";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.user.idle",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.idle";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.idle";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.log.timeout",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.timeout";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.timeout";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.log.batchsize",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.batchsize";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.batchsize";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"sysadmin.jid",propValue FROM jiveProperty WHERE name = "xmpp.muc.sysadmin.jid";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.sysadmin.jid";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"discover.locked",propValue FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"create.anyone",propValue FROM jiveProperty WHERE name = "xmpp.muc.create.anyone";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.create.anyone";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"create.jid",propValue FROM jiveProperty WHERE name = "xmpp.muc.create.jid";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.create.jid";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"enabled",propValue FROM jiveProperty WHERE name = "xmpp.muc.enabled";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.enabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"unload.empty_days",propValue FROM jiveProperty WHERE name = "xmpp.muc.unload.empty_days";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.unload.empty_days";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"discover.locked",propValue FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"history.maxNumber",propValue FROM jiveProperty WHERE name = "xmpp.muc.history.maxNumber";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.history.maxNumber";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"history.type",propValue FROM jiveProperty WHERE name = "xmpp.muc.history.type";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.history.type";
UPDATE jiveVersion set version=17 where name = 'openfire';
commit;
\ No newline at end of file
-- change mucRoom's primary key to be referenced around serviceID
ALTER TABLE mucRoom DROP CONSTRAINT mucRoom_pk;
ALTER TABLE mucRoom ADD CONSTRAINT mucRoom_pk PRIMARY KEY (serviceID, name);
-- create table mucService
CREATE TABLE mucService (
serviceID INTEGER NOT NULL,
subdomain VARCHAR(255) NOT NULL,
description VARCHAR(255),
CONSTRAINT mucService_pk PRIMARY KEY (subdomain)
);
CREATE INDEX mucService_serviceid_idx ON mucService(serviceID);
-- create table mucServiceProp
CREATE TABLE mucServiceProp (
serviceID INTEGER NOT NULL,
name VARCHAR(100) NOT NULL,
propValue TEXT NOT NULL,
CONSTRAINT mucServiceProp_pk PRIMARY KEY (serviceID, name)
);
-- add new indexed column to mucRoom
ALTER TABLE mucRoom ADD COLUMN serviceID INTEGER NOT NULL;
CREATE INDEX mucRm_serviceid_idx ON mucRoom (serviceID);
-- add default entry for conference service and associated jiveID value
INSERT INTO mucService (serviceID, subdomain) VALUES (1, "conference");
INSERT INTO jiveID (idType, id) VALUES (26, 1);
-- update all entries in mucRoom to be set to the default conference service
UPDATE mucRoom set serviceID = 1;
-- update conference name/desc if there's a custom one set
UPDATE mucService SET mucService.subdomain = ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "xmpp.muc.service" )
WHERE EXISTS ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "xmpp.muc.service" );
DELETE FROM jiveProperty WHERE name = "xmpp.muc.service";
UPDATE mucService SET mucService.description = ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "muc.service-name" )
WHERE EXISTS ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "muc.service-name" );
DELETE FROM jiveProperty WHERE name = "muc.service-name";
-- transfer all system properties to muc specific properties
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canOccupantsChangeSubject",propValue FROM jiveProperty WHERE name = "muc.room.canOccupantsChangeSubject";
DELETE FROM jiveProperty WHERE name = "muc.room.canOccupantsChangeSubject";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.maxUsers",propValue FROM jiveProperty WHERE name = "muc.room.maxUsers";
DELETE FROM jiveProperty WHERE name = "muc.room.maxUsers";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.publicRoom",propValue FROM jiveProperty WHERE name = "muc.room.publicRoom";
DELETE FROM jiveProperty WHERE name = "muc.room.publicRoom";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.persistent",propValue FROM jiveProperty WHERE name = "muc.room.persistent";
DELETE FROM jiveProperty WHERE name = "muc.room.persistent";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.moderated",propValue FROM jiveProperty WHERE name = "muc.room.moderated";
DELETE FROM jiveProperty WHERE name = "muc.room.moderated";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.membersOnly",propValue FROM jiveProperty WHERE name = "muc.room.membersOnly";
DELETE FROM jiveProperty WHERE name = "muc.room.membersOnly";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canOccupantsInvite",propValue FROM jiveProperty WHERE name = "muc.room.canOccupantsInvite";
DELETE FROM jiveProperty WHERE name = "muc.room.canOccupantsInvite";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canAnyoneDiscoverJID",propValue FROM jiveProperty WHERE name = "muc.room.canAnyoneDiscoverJID";
DELETE FROM jiveProperty WHERE name = "muc.room.canAnyoneDiscoverJID";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.logEnabled",propValue FROM jiveProperty WHERE name = "muc.room.logEnabled";
DELETE FROM jiveProperty WHERE name = "muc.room.logEnabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.loginRestrictedToNickname",propValue FROM jiveProperty WHERE name = "muc.room.loginRestrictedToNickname";
DELETE FROM jiveProperty WHERE name = "muc.room.loginRestrictedToNickname";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canChangeNickname",propValue FROM jiveProperty WHERE name = "muc.room.canChangeNickname";
DELETE FROM jiveProperty WHERE name = "muc.room.canChangeNickname";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.registrationEnabled",propValue FROM jiveProperty WHERE name = "muc.room.registrationEnabled";
DELETE FROM jiveProperty WHERE name = "muc.room.registrationEnabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.user.timeout",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.timeout";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.timeout";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.user.idle",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.idle";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.idle";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.log.timeout",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.timeout";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.timeout";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.log.batchsize",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.batchsize";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.batchsize";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"sysadmin.jid",propValue FROM jiveProperty WHERE name = "xmpp.muc.sysadmin.jid";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.sysadmin.jid";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"discover.locked",propValue FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"create.anyone",propValue FROM jiveProperty WHERE name = "xmpp.muc.create.anyone";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.create.anyone";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"create.jid",propValue FROM jiveProperty WHERE name = "xmpp.muc.create.jid";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.create.jid";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"enabled",propValue FROM jiveProperty WHERE name = "xmpp.muc.enabled";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.enabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"unload.empty_days",propValue FROM jiveProperty WHERE name = "xmpp.muc.unload.empty_days";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.unload.empty_days";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"discover.locked",propValue FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"history.maxNumber",propValue FROM jiveProperty WHERE name = "xmpp.muc.history.maxNumber";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.history.maxNumber";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"history.type",propValue FROM jiveProperty WHERE name = "xmpp.muc.history.type";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.history.type";
UPDATE jiveVersion set version=17 where name = 'openfire';
/* change mucRoom's primary key to be referenced around serviceID */
ALTER TABLE mucRoom DROP CONSTRAINT mucRoom_pk;
ALTER TABLE mucRoom ADD CONSTRAINT mucRoom_pk PRIMARY KEY (serviceID, name);
/* create table mucService */
CREATE TABLE mucService (
serviceID INT NOT NULL,
subdomain NVARCHAR(255) NOT NULL,
description NVARCHAR(255),
CONSTRAINT mucService_pk PRIMARY KEY (subdomain)
);
CREATE INDEX mucService_serviceid_idx ON mucService(serviceID);
/* create table mucServiceProp */
CREATE TABLE mucServiceProp (
serviceID INT NOT NULL,
name NVARCHAR(100) NOT NULL,
propValue NVARCHAR(2000) NOT NULL,
CONSTRAINT mucServiceProp_pk PRIMARY KEY (serviceID, name)
);
/* add new indexed column to mucRoom */
ALTER TABLE mucRoom ADD COLUMN serviceID INT NOT NULL;
CREATE INDEX mucRoom_serviceid_idx ON mucRoom(serviceID);
/* add default entry for conference service and associated jiveID value */
INSERT INTO mucService (serviceID, subdomain) VALUES (1, "conference");
INSERT INTO jiveID (idType, id) VALUES (26, 1);
/* update all entries in mucRoom to be set to the default conference service */
UPDATE mucRoom set serviceID = 1;
/* update conference name/desc if there's a custom one set */
UPDATE mucService SET mucService.subdomain = ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "xmpp.muc.service" )
WHERE EXISTS ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "xmpp.muc.service" );
DELETE FROM jiveProperty WHERE name = "xmpp.muc.service";
UPDATE mucService SET mucService.description = ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "muc.service-name" )
WHERE EXISTS ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "muc.service-name" );
DELETE FROM jiveProperty WHERE name = "muc.service-name";
/* transfer all system properties to muc specific properties */
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canOccupantsChangeSubject",propValue FROM jiveProperty WHERE name = "muc.room.canOccupantsChangeSubject";
DELETE FROM jiveProperty WHERE name = "muc.room.canOccupantsChangeSubject";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.maxUsers",propValue FROM jiveProperty WHERE name = "muc.room.maxUsers";
DELETE FROM jiveProperty WHERE name = "muc.room.maxUsers";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.publicRoom",propValue FROM jiveProperty WHERE name = "muc.room.publicRoom";
DELETE FROM jiveProperty WHERE name = "muc.room.publicRoom";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.persistent",propValue FROM jiveProperty WHERE name = "muc.room.persistent";
DELETE FROM jiveProperty WHERE name = "muc.room.persistent";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.moderated",propValue FROM jiveProperty WHERE name = "muc.room.moderated";
DELETE FROM jiveProperty WHERE name = "muc.room.moderated";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.membersOnly",propValue FROM jiveProperty WHERE name = "muc.room.membersOnly";
DELETE FROM jiveProperty WHERE name = "muc.room.membersOnly";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canOccupantsInvite",propValue FROM jiveProperty WHERE name = "muc.room.canOccupantsInvite";
DELETE FROM jiveProperty WHERE name = "muc.room.canOccupantsInvite";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canAnyoneDiscoverJID",propValue FROM jiveProperty WHERE name = "muc.room.canAnyoneDiscoverJID";
DELETE FROM jiveProperty WHERE name = "muc.room.canAnyoneDiscoverJID";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.logEnabled",propValue FROM jiveProperty WHERE name = "muc.room.logEnabled";
DELETE FROM jiveProperty WHERE name = "muc.room.logEnabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.loginRestrictedToNickname",propValue FROM jiveProperty WHERE name = "muc.room.loginRestrictedToNickname";
DELETE FROM jiveProperty WHERE name = "muc.room.loginRestrictedToNickname";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canChangeNickname",propValue FROM jiveProperty WHERE name = "muc.room.canChangeNickname";
DELETE FROM jiveProperty WHERE name = "muc.room.canChangeNickname";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.registrationEnabled",propValue FROM jiveProperty WHERE name = "muc.room.registrationEnabled";
DELETE FROM jiveProperty WHERE name = "muc.room.registrationEnabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.user.timeout",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.timeout";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.timeout";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.user.idle",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.idle";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.idle";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.log.timeout",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.timeout";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.timeout";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.log.batchsize",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.batchsize";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.batchsize";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"sysadmin.jid",propValue FROM jiveProperty WHERE name = "xmpp.muc.sysadmin.jid";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.sysadmin.jid";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"discover.locked",propValue FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"create.anyone",propValue FROM jiveProperty WHERE name = "xmpp.muc.create.anyone";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.create.anyone";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"create.jid",propValue FROM jiveProperty WHERE name = "xmpp.muc.create.jid";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.create.jid";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"enabled",propValue FROM jiveProperty WHERE name = "xmpp.muc.enabled";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.enabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"unload.empty_days",propValue FROM jiveProperty WHERE name = "xmpp.muc.unload.empty_days";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.unload.empty_days";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"discover.locked",propValue FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"history.maxNumber",propValue FROM jiveProperty WHERE name = "xmpp.muc.history.maxNumber";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.history.maxNumber";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"history.type",propValue FROM jiveProperty WHERE name = "xmpp.muc.history.type";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.history.type";
UPDATE jiveVersion set version=17 where name = 'openfire';
/* change mucRoom's primary key to be referenced around serviceID */
ALTER TABLE mucRoom DROP CONSTRAINT mucRoom_pk;
ALTER TABLE mucRoom ADD CONSTRAINT mucRoom_pk PRIMARY KEY (serviceID, name);
/* create table mucService */
CREATE TABLE mucService (
serviceID INT NOT NULL,
subdomain NVARCHAR(255) NOT NULL,
description NVARCHAR(255),
CONSTRAINT mucService_pk PRIMARY KEY (subdomain)
);
CREATE INDEX mucService_serviceid_idx ON mucService(serviceID);
/* create table mucServiceProp */
CREATE TABLE mucServiceProp (
serviceID INT NOT NULL,
name NVARCHAR(100) NOT NULL,
propValue TEXT NOT NULL,
CONSTRAINT mucServiceProp_pk PRIMARY KEY (serviceID, name)
);
/* add new indexed column to mucRoom */
ALTER TABLE mucRoom ADD COLUMN serviceID INT NOT NULL;
CREATE INDEX mucRoom_serviceid_idx ON mucRoom(serviceID);
/* add default entry for conference service and associated jiveID value */
INSERT INTO mucService (serviceID, subdomain) VALUES (1, "conference");
INSERT INTO jiveID (idType, id) VALUES (26, 1);
/* update all entries in mucRoom to be set to the default conference service */
UPDATE mucRoom set serviceID = 1;
/* update conference name/desc if there's a custom one set */
UPDATE mucService SET mucService.subdomain = ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "xmpp.muc.service" )
WHERE EXISTS ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "xmpp.muc.service" );
DELETE FROM jiveProperty WHERE name = "xmpp.muc.service";
UPDATE mucService SET mucService.description = ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "muc.service-name" )
WHERE EXISTS ( SELECT jiveProperty.propValue FROM jiveProperty WHERE jiveProperty.name = "muc.service-name" );
DELETE FROM jiveProperty WHERE name = "muc.service-name";
/* transfer all system properties to muc specific properties */
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canOccupantsChangeSubject",propValue FROM jiveProperty WHERE name = "muc.room.canOccupantsChangeSubject";
DELETE FROM jiveProperty WHERE name = "muc.room.canOccupantsChangeSubject";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.maxUsers",propValue FROM jiveProperty WHERE name = "muc.room.maxUsers";
DELETE FROM jiveProperty WHERE name = "muc.room.maxUsers";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.publicRoom",propValue FROM jiveProperty WHERE name = "muc.room.publicRoom";
DELETE FROM jiveProperty WHERE name = "muc.room.publicRoom";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.persistent",propValue FROM jiveProperty WHERE name = "muc.room.persistent";
DELETE FROM jiveProperty WHERE name = "muc.room.persistent";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.moderated",propValue FROM jiveProperty WHERE name = "muc.room.moderated";
DELETE FROM jiveProperty WHERE name = "muc.room.moderated";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.membersOnly",propValue FROM jiveProperty WHERE name = "muc.room.membersOnly";
DELETE FROM jiveProperty WHERE name = "muc.room.membersOnly";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canOccupantsInvite",propValue FROM jiveProperty WHERE name = "muc.room.canOccupantsInvite";
DELETE FROM jiveProperty WHERE name = "muc.room.canOccupantsInvite";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canAnyoneDiscoverJID",propValue FROM jiveProperty WHERE name = "muc.room.canAnyoneDiscoverJID";
DELETE FROM jiveProperty WHERE name = "muc.room.canAnyoneDiscoverJID";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.logEnabled",propValue FROM jiveProperty WHERE name = "muc.room.logEnabled";
DELETE FROM jiveProperty WHERE name = "muc.room.logEnabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.loginRestrictedToNickname",propValue FROM jiveProperty WHERE name = "muc.room.loginRestrictedToNickname";
DELETE FROM jiveProperty WHERE name = "muc.room.loginRestrictedToNickname";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.canChangeNickname",propValue FROM jiveProperty WHERE name = "muc.room.canChangeNickname";
DELETE FROM jiveProperty WHERE name = "muc.room.canChangeNickname";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"room.registrationEnabled",propValue FROM jiveProperty WHERE name = "muc.room.registrationEnabled";
DELETE FROM jiveProperty WHERE name = "muc.room.registrationEnabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.user.timeout",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.timeout";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.timeout";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.user.idle",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.idle";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.user.idle";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.log.timeout",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.timeout";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.timeout";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"tasks.log.batchsize",propValue FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.batchsize";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.tasks.log.batchsize";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"sysadmin.jid",propValue FROM jiveProperty WHERE name = "xmpp.muc.sysadmin.jid";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.sysadmin.jid";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"discover.locked",propValue FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"create.anyone",propValue FROM jiveProperty WHERE name = "xmpp.muc.create.anyone";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.create.anyone";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"create.jid",propValue FROM jiveProperty WHERE name = "xmpp.muc.create.jid";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.create.jid";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"enabled",propValue FROM jiveProperty WHERE name = "xmpp.muc.enabled";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.enabled";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"unload.empty_days",propValue FROM jiveProperty WHERE name = "xmpp.muc.unload.empty_days";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.unload.empty_days";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"discover.locked",propValue FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.discover.locked";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"history.maxNumber",propValue FROM jiveProperty WHERE name = "xmpp.muc.history.maxNumber";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.history.maxNumber";
INSERT INTO mucServiceProp(serviceID,name,propValue) SELECT 1,"history.type",propValue FROM jiveProperty WHERE name = "xmpp.muc.history.type";
DELETE FROM jiveProperty WHERE name = "xmpp.muc.history.type";
UPDATE jiveVersion set version=17 where name = 'openfire';
......@@ -2309,3 +2309,40 @@ sidebar.security-audit-viewer=Security Audit Viewer
sidebar.security-audit-viewer.descr=Click to view the security audit logs
setup.ldap.server.alias_dereference=Deference Aliases
setup.ldap.server.alias_dereference_help=Automatically deference LDAP aliases when found
sidebar.muc-service-summary=Service Summary
sidebar.muc-service-summary.descr=Click to see a list of group chat services
sidebar.muc-service-create=Create New Service
sidebar.muc-service-create.descr=Click to add a new group chat service
sidebar.sidebar-muc-service-options=Service Options
sidebar.muc-service-delete=Delete Service
sidebar.muc-service-delete.descr=Click to delete the service
global.edit=Edit
groupchat.service.properties.label_service_description=Group chat service description (optional):
groupchat.service.settings_affect=Changes you make here will affect the group chat service:
muc.room.summary.service=Service
muc.service.summary.title=Group Chat Service
muc.service.summary.info=Below is an overview of the Group Chat Services in the system. From here you can \
edit their configurations, and create new services, and delete services you don't need anymore.
muc.service.summary.deleted=Service destroyed successfully.
muc.service.summary.total_room=Total Service
muc.service.summary.sorted_id=Sorted by Subdomain
muc.service.summary.subdomain=Subdomain
muc.service.summary.description=Description
muc.service.summary.numrooms=# Rooms
muc.service.summary.numusers=# Users
muc.service.summary.edit=Edit
muc.service.summary.destroy=Destroy
muc.service.summary.no_services=No group chat services configured.
muc.service.summary.total_services=Total Services
muc.service.summary.sorted=Sorted by Subdomain
muc.service.summary.services_per_page=Services per page
muc.service.summary.no_services_warning=There are no group chat services configured for this server. \
You will need to create a new service if you wish to provide MUC/group chat services.
muc.service.delete.title=Delete MUC Service
muc.service.delete.info=Are you sure you want to destroy the MUC service
muc.service.delete.detail=from the system? You may specify a reason for the service destruction. \
This information will be sent to occupants of rooms on the service.
muc.service.delete.destructon_title=Destruction Details
muc.service.delete.service_name=Subdomain:
muc.service.delete.reason=Reason:
muc.service.delete.destroy_service=Destroy Service
......@@ -2295,3 +2295,40 @@ sidebar.security-audit-viewer=Security Audit Viewer
sidebar.security-audit-viewer.descr=Click to view the security audit logs
setup.ldap.server.alias_dereference=Deference Aliases
setup.ldap.server.alias_dereference_help=Automatically deference LDAP aliases when found
sidebar.muc-service-summary=Service Summary
sidebar.muc-service-summary.descr=Click to see a list of group chat services
sidebar.muc-service-create=Create New Service
sidebar.muc-service-create.descr=Click to add a new group chat service
sidebar.sidebar-muc-service-options=Service Options
sidebar.muc-service-delete=Delete Service
sidebar.muc-service-delete.descr=Click to delete the service
global.edit=Edit
groupchat.service.properties.label_service_description=Group chat service description (optional):
groupchat.service.settings_affect=Changes you make here will affect the group chat service:
muc.room.summary.service=Service
muc.service.summary.title=Group Chat Service
muc.service.summary.info=Below is an overview of the Group Chat Services in the system. From here you can \
edit their configurations, and create new services, and delete services you don't need anymore.
muc.service.summary.deleted=Service destroyed successfully.
muc.service.summary.total_room=Total Service
muc.service.summary.sorted_id=Sorted by Subdomain
muc.service.summary.subdomain=Subdomain
muc.service.summary.description=Description
muc.service.summary.numrooms=# Rooms
muc.service.summary.numusers=# Users
muc.service.summary.edit=Edit
muc.service.summary.destroy=Destroy
muc.service.summary.no_services=No group chat services configured.
muc.service.summary.total_services=Total Services
muc.service.summary.sorted=Sorted by Subdomain
muc.service.summary.services_per_page=Services per page
muc.service.summary.no_services_warning=There are no group chat services configured for this server. \
You will need to create a new service if you wish to provide MUC/group chat services.
muc.service.delete.title=Delete MUC Service
muc.service.delete.info=Are you sure you want to destroy the MUC service
muc.service.delete.detail=from the system? You may specify a reason for the service destruction. \
This information will be sent to occupants of rooms on the service.
muc.service.delete.destructon_title=Destruction Details
muc.service.delete.service_name=Subdomain:
muc.service.delete.reason=Reason:
muc.service.delete.destroy_service=Destroy Service
......@@ -358,6 +358,44 @@
## 3.6.0
## Added key: 'setup.ldap.server.alias_dereference'
## Added key: 'setup.ldap.server.alias_dereference_help'
## Added key: 'muc.service.summary.title'
## Added key: 'muc.service.summary.info'
## Added key: 'muc.service.summary.deleted'
## Added key: 'muc.service.summary.total_room'
## Added key: 'muc.service.summary.sorted_id'
## Added key: 'muc.service.summary.subdomain'
## Added key: 'muc.service.summary.description'
## Added key: 'muc.service.summary.numrooms'
## Added key: 'muc.service.summary.numusers'
## Added key: 'muc.service.summary.edit'
## Added key: 'muc.service.summary.destroy'
## Added key: 'muc.service.summary.no_services'
## Added key: 'muc.service.summary.total_services'
## Added key: 'muc.service.summary.sorted'
## Added key: 'muc.service.summary.services_per_page'
## Added key: 'muc.service.delete.title'
## Added key: 'muc.service.delete.info'
## Added key: 'muc.service.delete.detail'
## Added key: 'muc.service.delete.destructon_title'
## Added key: 'muc.service.delete.service_name'
## Added key: 'muc.service.delete.reason'
## Added key: 'muc.service.delete.destroy_service'
## Added key: 'groupchat.service.properties.label_service_description'
## Updated key: 'setup.ldap.user.vcard.test.description'
## Added key: 'sidebar.muc-service-summary'
## Added key: 'sidebar.muc-service-summary.descr'
## Added key: 'sidebar.muc-room-create'
## Added key: 'sidebar.muc-room-create.descr'
## Added key: 'global.edit'
## Updated key: 'groupchat.service.properties.introduction'
## Added key: 'muc.room.summary.service'
## Added key: 'muc.service.summary.no_services_warning'
## Added key: 'sidebar.muc-service-delete'
## Added key: 'sidebar.muc-service-delete.descr'
## Added key: 'sidebar.sidebar-muc-service-options'
## Added key: 'groupchat.service.settings_affect'
## Updated key: 'groupchat.service.properties.saved_successfully'
## Removed key: 'groupchat.service.properties.saved_successfully2'
# Openfire
......@@ -471,16 +509,23 @@ tab.tab-session.descr=Click to manage connected sessions
tab.tab-groupchat=Group Chat
tab.tab-groupchat.descr=Click to manage group chat settings
sidebar.sidebar-groupchat-settings=Group Chat Settings
sidebar.muc-server-props=Service Properties
sidebar.muc-server-props.descr=
sidebar.muc-history=History Settings
sidebar.muc-history.descr=
sidebar.muc-sysadmin=Administrators
sidebar.muc-sysadmin.descr=
sidebar.muc-perms=Room Creation Permissions
sidebar.muc-perms.descr=
sidebar.muc-tasks=Other Settings
sidebar.muc-tasks.descr=
sidebar.muc-service-summary=Service Summary
sidebar.muc-service-summary.descr=Click to see a list of group chat services
sidebar.sidebar-muc-service-options=Service Options
sidebar.muc-server-props=Service Properties
sidebar.muc-server-props.descr=
sidebar.muc-history=History Settings
sidebar.muc-history.descr=
sidebar.muc-sysadmin=Administrators
sidebar.muc-sysadmin.descr=
sidebar.muc-perms=Room Creation Permissions
sidebar.muc-perms.descr=
sidebar.muc-tasks=Other Settings
sidebar.muc-tasks.descr=
sidebar.muc-service-delete=Delete Service
sidebar.muc-service-delete.descr=Click to delete the service
sidebar.muc-service-create=Create New Service
sidebar.muc-service-create.descr=Click to add a new group chat service
sidebar.sidebar-groupchat-administration=Room Administration
sidebar.muc-room-summary=Room Summary
sidebar.muc-room-summary.descr=Click to see a list of rooms in the service
......@@ -661,6 +706,7 @@ global.save_properties=Save Properties
global.edit_properties=Edit Properties
global.stop=Stop
global.restore_defaults=Restore Defaults
global.edit=Edit
global.add=Add
global.logout=Logout
global.main=Main
......@@ -690,14 +736,14 @@ global.click_test=Click to test...
# Group Chat Service Properties Page
groupchat.service.properties.title=Group Chat Service Properties
groupchat.service.properties.introduction=Use the form below to edit group chat service settings. \
Note, any changes will require a server restart.
groupchat.service.properties.saved_successfully=Service properties edited successfully. You must
groupchat.service.properties.saved_successfully2=the server in order for the changes to take effect (see
groupchat.service.properties.introduction=Use the form below to edit group chat service settings.
groupchat.service.properties.saved_successfully=Service properties edited successfully.
groupchat.service.properties.legend=Service Name
groupchat.service.properties.label_service_name=Group chat service name:
groupchat.service.properties.error_service_name=Please enter a valid name.
groupchat.service.properties.label_service_description=Group chat service description (optional):
groupchat.service.properties.save=Save Properties
groupchat.service.settings_affect=Changes you make here will affect the group chat service:
# Group Chat History Settings Page
......@@ -1076,6 +1122,39 @@ muc.room.summary.destroy=Destroy
muc.room.summary.no_room_in_group=No rooms in the Group Chat service.
muc.room.summary.alt_persistent=Room is persistent
muc.room.summary.alt_temporary=Room is temporary
muc.room.summary.service=Service
# MUC service summary Page
muc.service.summary.title=Group Chat Service
muc.service.summary.info=Below is an overview of the Group Chat Services in the system. From here you can \
edit their configurations, and create new services, and delete services you don't need anymore.
muc.service.summary.deleted=Service destroyed successfully.
muc.service.summary.total_room=Total Service
muc.service.summary.sorted_id=Sorted by Subdomain
muc.service.summary.subdomain=Subdomain
muc.service.summary.description=Description
muc.service.summary.numrooms=# Rooms
muc.service.summary.numusers=# Users
muc.service.summary.edit=Edit
muc.service.summary.destroy=Destroy
muc.service.summary.no_services=No group chat services configured.
muc.service.summary.total_services=Total Services
muc.service.summary.sorted=Sorted by Subdomain
muc.service.summary.services_per_page=Services per page
muc.service.summary.no_services_warning=There are no group chat services configured for this server. \
You will need to create a new service if you wish to provide MUC/group chat services.
# MUC delete service page
muc.service.delete.title=Delete MUC Service
muc.service.delete.info=Are you sure you want to destroy the MUC service
muc.service.delete.detail=from the system? You may specify a reason for the service destruction. \
This information will be sent to occupants of rooms on the service.
muc.service.delete.destructon_title=Destruction Details
muc.service.delete.service_name=Subdomain:
muc.service.delete.reason=Reason:
muc.service.delete.destroy_service=Destroy Service
# Muc tasks Page
......@@ -1782,7 +1861,7 @@ setup.ldap.test.error-loading-sample=An error occured while loading sample from
setup.ldap.test.internal-server-error=Test page is not able to find required information in HTTP session.
setup.ldap.user.vcard.test.description=A random profile is selected for you to review. Bold fields with no value mean \
that an error may have been found. To view another profile click 'Next ramdom profile'. When you are finished close \
that an error may have been found. To view another profile click 'Next random profile'. When you are finished close \
this window.
setup.ldap.user.vcard.test.random=Next random profile
setup.ldap.user.test.users-not-found=No users were found using the specified configuration. Try changing the base DN, \
......
......@@ -2346,3 +2346,40 @@ sidebar.security-audit-viewer=Security Audit Viewer
sidebar.security-audit-viewer.descr=Click to view the security audit logs
setup.ldap.server.alias_dereference=Deference Aliases
setup.ldap.server.alias_dereference_help=Automatically deference LDAP aliases when found
sidebar.muc-service-summary=Service Summary
sidebar.muc-service-summary.descr=Click to see a list of group chat services
sidebar.muc-service-create=Create New Service
sidebar.muc-service-create.descr=Click to add a new group chat service
sidebar.sidebar-muc-service-options=Service Options
sidebar.muc-service-delete=Delete Service
sidebar.muc-service-delete.descr=Click to delete the service
global.edit=Edit
groupchat.service.properties.label_service_description=Group chat service description (optional):
groupchat.service.settings_affect=Changes you make here will affect the group chat service:
muc.room.summary.service=Service
muc.service.summary.title=Group Chat Service
muc.service.summary.info=Below is an overview of the Group Chat Services in the system. From here you can \
edit their configurations, and create new services, and delete services you don't need anymore.
muc.service.summary.deleted=Service destroyed successfully.
muc.service.summary.total_room=Total Service
muc.service.summary.sorted_id=Sorted by Subdomain
muc.service.summary.subdomain=Subdomain
muc.service.summary.description=Description
muc.service.summary.numrooms=# Rooms
muc.service.summary.numusers=# Users
muc.service.summary.edit=Edit
muc.service.summary.destroy=Destroy
muc.service.summary.no_services=No group chat services configured.
muc.service.summary.total_services=Total Services
muc.service.summary.sorted=Sorted by Subdomain
muc.service.summary.services_per_page=Services per page
muc.service.summary.no_services_warning=There are no group chat services configured for this server. \
You will need to create a new service if you wish to provide MUC/group chat services.
muc.service.delete.title=Delete MUC Service
muc.service.delete.info=Are you sure you want to destroy the MUC service
muc.service.delete.detail=from the system? You may specify a reason for the service destruction. \
This information will be sent to occupants of rooms on the service.
muc.service.delete.destructon_title=Destruction Details
muc.service.delete.service_name=Subdomain:
muc.service.delete.reason=Reason:
muc.service.delete.destroy_service=Destroy Service
......@@ -1915,3 +1915,40 @@ sidebar.security-audit-viewer=Security Audit Viewer
sidebar.security-audit-viewer.descr=Click to view the security audit logs
setup.ldap.server.alias_dereference=Deference Aliases
setup.ldap.server.alias_dereference_help=Automatically deference LDAP aliases when found
sidebar.muc-service-summary=Service Summary
sidebar.muc-service-summary.descr=Click to see a list of group chat services
sidebar.muc-service-create=Create New Service
sidebar.muc-service-create.descr=Click to add a new group chat service
sidebar.sidebar-muc-service-options=Service Options
sidebar.muc-service-delete=Delete Service
sidebar.muc-service-delete.descr=Click to delete the service
global.edit=Edit
groupchat.service.properties.label_service_description=Group chat service description (optional):
groupchat.service.settings_affect=Changes you make here will affect the group chat service:
muc.room.summary.service=Service
muc.service.summary.title=Group Chat Service
muc.service.summary.info=Below is an overview of the Group Chat Services in the system. From here you can \
edit their configurations, and create new services, and delete services you don't need anymore.
muc.service.summary.deleted=Service destroyed successfully.
muc.service.summary.total_room=Total Service
muc.service.summary.sorted_id=Sorted by Subdomain
muc.service.summary.subdomain=Subdomain
muc.service.summary.description=Description
muc.service.summary.numrooms=# Rooms
muc.service.summary.numusers=# Users
muc.service.summary.edit=Edit
muc.service.summary.destroy=Destroy
muc.service.summary.no_services=No group chat services configured.
muc.service.summary.total_services=Total Services
muc.service.summary.sorted=Sorted by Subdomain
muc.service.summary.services_per_page=Services per page
muc.service.summary.no_services_warning=There are no group chat services configured for this server. \
You will need to create a new service if you wish to provide MUC/group chat services.
muc.service.delete.title=Delete MUC Service
muc.service.delete.info=Are you sure you want to destroy the MUC service
muc.service.delete.detail=from the system? You may specify a reason for the service destruction. \
This information will be sent to occupants of rooms on the service.
muc.service.delete.destructon_title=Destruction Details
muc.service.delete.service_name=Subdomain:
muc.service.delete.reason=Reason:
muc.service.delete.destroy_service=Destroy Service
......@@ -2442,3 +2442,40 @@ sidebar.security-audit-viewer=Security Audit Viewer
sidebar.security-audit-viewer.descr=Click to view the security audit logs
setup.ldap.server.alias_dereference=Deference Aliases
setup.ldap.server.alias_dereference_help=Automatically deference LDAP aliases when found
sidebar.muc-service-summary=Service Summary
sidebar.muc-service-summary.descr=Click to see a list of group chat services
sidebar.muc-service-create=Create New Service
sidebar.muc-service-create.descr=Click to add a new group chat service
sidebar.sidebar-muc-service-options=Service Options
sidebar.muc-service-delete=Delete Service
sidebar.muc-service-delete.descr=Click to delete the service
global.edit=Edit
groupchat.service.properties.label_service_description=Group chat service description (optional):
groupchat.service.settings_affect=Changes you make here will affect the group chat service:
muc.room.summary.service=Service
muc.service.summary.title=Group Chat Service
muc.service.summary.info=Below is an overview of the Group Chat Services in the system. From here you can \
edit their configurations, and create new services, and delete services you don't need anymore.
muc.service.summary.deleted=Service destroyed successfully.
muc.service.summary.total_room=Total Service
muc.service.summary.sorted_id=Sorted by Subdomain
muc.service.summary.subdomain=Subdomain
muc.service.summary.description=Description
muc.service.summary.numrooms=# Rooms
muc.service.summary.numusers=# Users
muc.service.summary.edit=Edit
muc.service.summary.destroy=Destroy
muc.service.summary.no_services=No group chat services configured.
muc.service.summary.total_services=Total Services
muc.service.summary.sorted=Sorted by Subdomain
muc.service.summary.services_per_page=Services per page
muc.service.summary.no_services_warning=There are no group chat services configured for this server. \
You will need to create a new service if you wish to provide MUC/group chat services.
muc.service.delete.title=Delete MUC Service
muc.service.delete.info=Are you sure you want to destroy the MUC service
muc.service.delete.detail=from the system? You may specify a reason for the service destruction. \
This information will be sent to occupants of rooms on the service.
muc.service.delete.destructon_title=Destruction Details
muc.service.delete.service_name=Subdomain:
muc.service.delete.reason=Reason:
muc.service.delete.destroy_service=Destroy Service
......@@ -2306,3 +2306,40 @@ sidebar.security-audit-viewer=Security Audit Viewer
sidebar.security-audit-viewer.descr=Click to view the security audit logs
setup.ldap.server.alias_dereference=Deference Aliases
setup.ldap.server.alias_dereference_help=Automatically deference LDAP aliases when found
sidebar.muc-service-summary=Service Summary
sidebar.muc-service-summary.descr=Click to see a list of group chat services
sidebar.muc-service-create=Create New Service
sidebar.muc-service-create.descr=Click to add a new group chat service
sidebar.sidebar-muc-service-options=Service Options
sidebar.muc-service-delete=Delete Service
sidebar.muc-service-delete.descr=Click to delete the service
global.edit=Edit
groupchat.service.properties.label_service_description=Group chat service description (optional):
groupchat.service.settings_affect=Changes you make here will affect the group chat service:
muc.room.summary.service=Service
muc.service.summary.title=Group Chat Service
muc.service.summary.info=Below is an overview of the Group Chat Services in the system. From here you can \
edit their configurations, and create new services, and delete services you don't need anymore.
muc.service.summary.deleted=Service destroyed successfully.
muc.service.summary.total_room=Total Service
muc.service.summary.sorted_id=Sorted by Subdomain
muc.service.summary.subdomain=Subdomain
muc.service.summary.description=Description
muc.service.summary.numrooms=# Rooms
muc.service.summary.numusers=# Users
muc.service.summary.edit=Edit
muc.service.summary.destroy=Destroy
muc.service.summary.no_services=No group chat services configured.
muc.service.summary.total_services=Total Services
muc.service.summary.sorted=Sorted by Subdomain
muc.service.summary.services_per_page=Services per page
muc.service.summary.no_services_warning=There are no group chat services configured for this server. \
You will need to create a new service if you wish to provide MUC/group chat services.
muc.service.delete.title=Delete MUC Service
muc.service.delete.info=Are you sure you want to destroy the MUC service
muc.service.delete.detail=from the system? You may specify a reason for the service destruction. \
This information will be sent to occupants of rooms on the service.
muc.service.delete.destructon_title=Destruction Details
muc.service.delete.service_name=Subdomain:
muc.service.delete.reason=Reason:
muc.service.delete.destroy_service=Destroy Service
......@@ -2275,3 +2275,40 @@ sidebar.security-audit-viewer=Security Audit Viewer
sidebar.security-audit-viewer.descr=Click to view the security audit logs
setup.ldap.server.alias_dereference=Deference Aliases
setup.ldap.server.alias_dereference_help=Automatically deference LDAP aliases when found
sidebar.muc-service-summary=Service Summary
sidebar.muc-service-summary.descr=Click to see a list of group chat services
sidebar.muc-service-create=Create New Service
sidebar.muc-service-create.descr=Click to add a new group chat service
sidebar.sidebar-muc-service-options=Service Options
sidebar.muc-service-delete=Delete Service
sidebar.muc-service-delete.descr=Click to delete the service
global.edit=Edit
groupchat.service.properties.label_service_description=Group chat service description (optional):
groupchat.service.settings_affect=Changes you make here will affect the group chat service:
muc.room.summary.service=Service
muc.service.summary.title=Group Chat Service
muc.service.summary.info=Below is an overview of the Group Chat Services in the system. From here you can \
edit their configurations, and create new services, and delete services you don't need anymore.
muc.service.summary.deleted=Service destroyed successfully.
muc.service.summary.total_room=Total Service
muc.service.summary.sorted_id=Sorted by Subdomain
muc.service.summary.subdomain=Subdomain
muc.service.summary.description=Description
muc.service.summary.numrooms=# Rooms
muc.service.summary.numusers=# Users
muc.service.summary.edit=Edit
muc.service.summary.destroy=Destroy
muc.service.summary.no_services=No group chat services configured.
muc.service.summary.total_services=Total Services
muc.service.summary.sorted=Sorted by Subdomain
muc.service.summary.services_per_page=Services per page
muc.service.summary.no_services_warning=There are no group chat services configured for this server. \
You will need to create a new service if you wish to provide MUC/group chat services.
muc.service.delete.title=Delete MUC Service
muc.service.delete.info=Are you sure you want to destroy the MUC service
muc.service.delete.detail=from the system? You may specify a reason for the service destruction. \
This information will be sent to occupants of rooms on the service.
muc.service.delete.destructon_title=Destruction Details
muc.service.delete.service_name=Subdomain:
muc.service.delete.reason=Reason:
muc.service.delete.destroy_service=Destroy Service
......@@ -2309,3 +2309,40 @@ sidebar.security-audit-viewer=Security Audit Viewer
sidebar.security-audit-viewer.descr=Click to view the security audit logs
setup.ldap.server.alias_dereference=Deference Aliases
setup.ldap.server.alias_dereference_help=Automatically deference LDAP aliases when found
sidebar.muc-service-summary=Service Summary
sidebar.muc-service-summary.descr=Click to see a list of group chat services
sidebar.muc-service-create=Create New Service
sidebar.muc-service-create.descr=Click to add a new group chat service
sidebar.sidebar-muc-service-options=Service Options
sidebar.muc-service-delete=Delete Service
sidebar.muc-service-delete.descr=Click to delete the service
global.edit=Edit
groupchat.service.properties.label_service_description=Group chat service description (optional):
groupchat.service.settings_affect=Changes you make here will affect the group chat service:
muc.room.summary.service=Service
muc.service.summary.title=Group Chat Service
muc.service.summary.info=Below is an overview of the Group Chat Services in the system. From here you can \
edit their configurations, and create new services, and delete services you don't need anymore.
muc.service.summary.deleted=Service destroyed successfully.
muc.service.summary.total_room=Total Service
muc.service.summary.sorted_id=Sorted by Subdomain
muc.service.summary.subdomain=Subdomain
muc.service.summary.description=Description
muc.service.summary.numrooms=# Rooms
muc.service.summary.numusers=# Users
muc.service.summary.edit=Edit
muc.service.summary.destroy=Destroy
muc.service.summary.no_services=No group chat services configured.
muc.service.summary.total_services=Total Services
muc.service.summary.sorted=Sorted by Subdomain
muc.service.summary.services_per_page=Services per page
muc.service.summary.no_services_warning=There are no group chat services configured for this server. \
You will need to create a new service if you wish to provide MUC/group chat services.
muc.service.delete.title=Delete MUC Service
muc.service.delete.info=Are you sure you want to destroy the MUC service
muc.service.delete.detail=from the system? You may specify a reason for the service destruction. \
This information will be sent to occupants of rooms on the service.
muc.service.delete.destructon_title=Destruction Details
muc.service.delete.service_name=Subdomain:
muc.service.delete.reason=Reason:
muc.service.delete.destroy_service=Destroy Service
......@@ -2086,3 +2086,40 @@ sidebar.security-audit-viewer=Security Audit Viewer
sidebar.security-audit-viewer.descr=Click to view the security audit logs
setup.ldap.server.alias_dereference=Deference Aliases
setup.ldap.server.alias_dereference_help=Automatically deference LDAP aliases when found
sidebar.muc-service-summary=Service Summary
sidebar.muc-service-summary.descr=Click to see a list of group chat services
sidebar.muc-service-create=Create New Service
sidebar.muc-service-create.descr=Click to add a new group chat service
sidebar.sidebar-muc-service-options=Service Options
sidebar.muc-service-delete=Delete Service
sidebar.muc-service-delete.descr=Click to delete the service
global.edit=Edit
groupchat.service.properties.label_service_description=Group chat service description (optional):
groupchat.service.settings_affect=Changes you make here will affect the group chat service:
muc.room.summary.service=Service
muc.service.summary.title=Group Chat Service
muc.service.summary.info=Below is an overview of the Group Chat Services in the system. From here you can \
edit their configurations, and create new services, and delete services you don't need anymore.
muc.service.summary.deleted=Service destroyed successfully.
muc.service.summary.total_room=Total Service
muc.service.summary.sorted_id=Sorted by Subdomain
muc.service.summary.subdomain=Subdomain
muc.service.summary.description=Description
muc.service.summary.numrooms=# Rooms
muc.service.summary.numusers=# Users
muc.service.summary.edit=Edit
muc.service.summary.destroy=Destroy
muc.service.summary.no_services=No group chat services configured.
muc.service.summary.total_services=Total Services
muc.service.summary.sorted=Sorted by Subdomain
muc.service.summary.services_per_page=Services per page
muc.service.summary.no_services_warning=There are no group chat services configured for this server. \
You will need to create a new service if you wish to provide MUC/group chat services.
muc.service.delete.title=Delete MUC Service
muc.service.delete.info=Are you sure you want to destroy the MUC service
muc.service.delete.detail=from the system? You may specify a reason for the service destruction. \
This information will be sent to occupants of rooms on the service.
muc.service.delete.destructon_title=Destruction Details
muc.service.delete.service_name=Subdomain:
muc.service.delete.reason=Reason:
muc.service.delete.destroy_service=Destroy Service
......@@ -44,7 +44,7 @@ public class SchemaManager {
/**
* Current Openfire database schema version.
*/
private static final int DATABASE_VERSION = 16;
private static final int DATABASE_VERSION = 17;
/**
* Creates a new Schema manager.
......
......@@ -30,8 +30,7 @@ import org.jivesoftware.openfire.filetransfer.proxy.FileTransferProxy;
import org.jivesoftware.openfire.handler.*;
import org.jivesoftware.openfire.lockout.LockOutManager;
import org.jivesoftware.openfire.mediaproxy.MediaProxyService;
import org.jivesoftware.openfire.muc.MultiUserChatServer;
import org.jivesoftware.openfire.muc.spi.MultiUserChatServerImpl;
import org.jivesoftware.openfire.muc.MultiUserChatManager;
import org.jivesoftware.openfire.net.MulticastDNSService;
import org.jivesoftware.openfire.net.SSLConfig;
import org.jivesoftware.openfire.net.ServerTrafficCounter;
......@@ -527,7 +526,6 @@ public class XMPPServer {
loadModule(IQOfflineMessagesHandler.class.getName());
loadModule(IQPEPHandler.class.getName());
loadModule(IQPEPOwnerHandler.class.getName());
loadModule(MultiUserChatServerImpl.class.getName());
loadModule(MulticastDNSService.class.getName());
loadModule(IQSharedGroupHandler.class.getName());
loadModule(AdHocCommandHandler.class.getName());
......@@ -542,6 +540,7 @@ public class XMPPServer {
loadModule(UpdateManager.class.getName());
loadModule(FlashCrossDomainHandler.class.getName());
loadModule(InternalComponentManager.class.getName());
loadModule(MultiUserChatManager.class.getName());
loadModule(ClearspaceManager.class.getName());
// Load this module always last since we don't want to start listening for clients
// before the rest of the modules have been started
......@@ -1350,14 +1349,14 @@ public class XMPPServer {
}
/**
* Returns the <code>MultiUserChatServer</code> registered with this server. The
* <code>MultiUserChatServer</code> was registered with the server as a module while starting up
* Returns the <code>MultiUserChatManager</code> registered with this server. The
* <code>MultiUserChatManager</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>MultiUserChatServer</code> registered with this server.
* @return the <code>MultiUserChatManager</code> registered with this server.
*/
public MultiUserChatServer getMultiUserChatServer() {
return (MultiUserChatServer) modules.get(MultiUserChatServerImpl.class);
public MultiUserChatManager getMultiUserChatManager() {
return (MultiUserChatManager) modules.get(MultiUserChatManager.class);
}
/**
......
......@@ -11,9 +11,10 @@ package org.jivesoftware.openfire.commands.admin.muc;
import org.jivesoftware.openfire.commands.AdHocCommand;
import org.jivesoftware.openfire.commands.SessionData;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.muc.MultiUserChatServer;
import org.jivesoftware.openfire.muc.MultiUserChatService;
import org.jivesoftware.openfire.muc.NotAllowedException;
import org.jivesoftware.openfire.muc.MUCRoom;
import org.jivesoftware.util.NotFoundException;
import org.dom4j.Element;
import org.xmpp.packet.JID;
import org.xmpp.forms.DataForm;
......@@ -44,12 +45,6 @@ public class CreateMUCRoom extends AdHocCommand {
public void execute(SessionData sessionData, Element command) {
Element note = command.addElement("note");
MultiUserChatServer server = XMPPServer.getInstance().getMultiUserChatServer();
if (!server.isServiceEnabled()) {
note.addAttribute("type", "error");
note.setText("Multi user chat is disabled on server.");
return;
}
Collection<JID> admins = XMPPServer.getInstance().getAdmins();
if (admins.size() <= 0) {
note.addAttribute("type", "error");
......@@ -58,6 +53,29 @@ public class CreateMUCRoom extends AdHocCommand {
}
Map<String, List<String>> data = sessionData.getData();
// Let's find the requested MUC service to create the room in
String servicehostname = get(data, "servicename", 0);
if (servicehostname == null) {
note.addAttribute("type", "error");
note.setText("Service name must be specified.");
return;
}
// Remove the server's domain name from the passed hostname
String servicename = servicehostname.replace("."+XMPPServer.getInstance().getServerInfo().getXMPPDomain(), "");
MultiUserChatService mucService;
try {
mucService = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(servicename);
if (!mucService.isServiceEnabled()) {
note.addAttribute("type", "error");
note.setText("Multi user chat is disabled for specified service.");
return;
}
}
catch (NotFoundException e) {
note.addAttribute("type", "error");
note.setText("Invalid service name specified.");
return;
}
// Let's create the jid and check that they are a local user
String roomname = get(data, "roomname", 0);
if (roomname == null) {
......@@ -68,7 +86,7 @@ public class CreateMUCRoom extends AdHocCommand {
JID admin = admins.iterator().next();
MUCRoom room;
try {
room = server.getChatRoom(roomname, admin);
room = mucService.getChatRoom(roomname, admin);
}
catch (NotAllowedException e) {
note.addAttribute("type", "error");
......@@ -104,6 +122,12 @@ public class CreateMUCRoom extends AdHocCommand {
field.setVariable("roomname");
field.setRequired(true);
field = form.addField();
field.setType(FormField.Type.text_single);
field.setLabel("The service (hostname) to create the room on");
field.setVariable("servicename");
field.setRequired(true);
field = form.addField();
field.setType(FormField.Type.text_private);
field.setLabel("The password for this account");
......
......@@ -147,7 +147,7 @@ public class HistoryRequest {
int accumulatedChars = 0;
int accumulatedStanzas = 0;
Element delayInformation;
LinkedList historyToSend = new LinkedList();
LinkedList<Message> historyToSend = new LinkedList<Message>();
ListIterator iterator = roomHistory.getReverseMessageHistory();
while (iterator.hasPrevious()) {
message = (Message)iterator.previous();
......@@ -173,7 +173,7 @@ public class HistoryRequest {
delayInformation = message.getChildElement("x", "jabber:x:delay");
try {
// Get the date when the historic message was sent
Date delayedDate = null;
Date delayedDate;
synchronized (delayedFormatter) {
delayedDate = delayedFormatter
.parse(delayInformation.attributeValue("stamp"));
......@@ -200,9 +200,8 @@ public class HistoryRequest {
historyToSend.addFirst(message);
}
// Send the smallest amount of traffic to the user
Iterator history = historyToSend.iterator();
while (history.hasNext()) {
joinRole.send((Message) history.next());
for (Object aHistoryToSend : historyToSend) {
joinRole.send((Message) aHistoryToSend);
}
}
}
......
......@@ -12,7 +12,7 @@
package org.jivesoftware.openfire.muc;
import org.jivesoftware.openfire.muc.cluster.UpdateHistoryStrategy;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.openfire.muc.spi.MUCPersistenceManager;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.cache.CacheFactory;
import org.xmpp.packet.Message;
......@@ -63,6 +63,10 @@ public class HistoryStrategy {
* (do not include trailing dot).
*/
private String contextPrefix = null;
/**
* The subdomain of the service the properties are set on.
*/
private String contextSubdomain = null;
/**
* Create a history strategy with the given parent strategy (for defaults) or null if no
......@@ -102,11 +106,11 @@ public class HistoryStrategy {
}
this.maxNumber = max;
if (contextPrefix != null){
JiveGlobals.setProperty(contextPrefix + ".maxNumber", Integer.toString(maxNumber));
MUCPersistenceManager.setProperty(contextSubdomain, contextPrefix + ".maxNumber", Integer.toString(maxNumber));
}
if (parent == null) {
// Update the history strategy of the MUC service
CacheFactory.doClusterTask(new UpdateHistoryStrategy(this));
CacheFactory.doClusterTask(new UpdateHistoryStrategy(contextSubdomain, this));
}
}
......@@ -124,11 +128,11 @@ public class HistoryStrategy {
type = newType;
}
if (contextPrefix != null){
JiveGlobals.setProperty(contextPrefix + ".type", type.toString());
MUCPersistenceManager.setProperty(contextSubdomain, contextPrefix + ".type", type.toString());
}
if (parent == null) {
// Update the history strategy of the MUC service
CacheFactory.doClusterTask(new UpdateHistoryStrategy(this));
CacheFactory.doClusterTask(new UpdateHistoryStrategy(contextSubdomain, this));
}
}
......@@ -235,7 +239,7 @@ public class HistoryStrategy {
*/
public enum Type {
defaulType, none, all, number
};
}
/**
* Obtain the strategy type from string name. See the Type enumeration name
......@@ -263,12 +267,13 @@ public class HistoryStrategy {
* Sets the prefix to use for retrieving and saving settings (and also
* triggers an immediate loading of properties).
*
* @param subdomain the subdomain of the muc service to pull properties for.
* @param prefix the prefix to use (without trailing dot) on property names.
*/
public void setContext(String prefix) {
public void setContext(String subdomain, String prefix) {
this.contextPrefix = prefix;
setTypeFromString(JiveGlobals.getProperty(prefix + ".type"));
String maxNumberString = JiveGlobals.getProperty(prefix + ".maxNumber");
setTypeFromString(MUCPersistenceManager.getProperty(subdomain, prefix + ".type"));
String maxNumberString = MUCPersistenceManager.getProperty(subdomain, prefix + ".maxNumber");
if (maxNumberString != null && maxNumberString.trim().length() > 0){
try {
this.maxNumber = Integer.parseInt(maxNumberString);
......
/**
* $Revision$
* $Date$
*
* Copyright (C) 2006 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.openfire.muc;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
import java.util.Collection;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* Dispatches MUC events. The following events are supported:
* <ul>
* <li><b>occupantJoined</b> --> Someone joined a room.</li>
* <li><b>occupantLeft</b> --> Someone left a room.</li>
* <li><b>nicknameChanged</b> --> A nickname was changed in a room.</li>
* <li><b>messageReceived</b> --> A message was received in a room.</li>
* <li><b>roomCreated</b> --> A room was created.</li>
* <li><b>roomDestryod</b> --> A room was destroyed.</li>
* </ul>
* Use {@link #addListener(MUCEventListener)} and {@link #removeListener(MUCEventListener)}
* to add or remove {@link MUCEventListener}.
*
* @author Daniel Henninger
*/
public class MUCEventDispatcher {
private static Collection<MUCEventListener> listeners =
new ConcurrentLinkedQueue<MUCEventListener>();
public static void addListener(MUCEventListener listener) {
listeners.add(listener);
}
public static void removeListener(MUCEventListener listener) {
listeners.remove(listener);
}
public static void occupantJoined(JID roomJID, JID user, String nickname) {
for (MUCEventListener listener : listeners) {
listener.occupantJoined(roomJID, user, nickname);
}
}
public static void occupantLeft(JID roomJID, JID user) {
for (MUCEventListener listener : listeners) {
listener.occupantLeft(roomJID, user);
}
}
public static void nicknameChanged(JID roomJID, JID user, String oldNickname, String newNickname) {
for (MUCEventListener listener : listeners) {
listener.nicknameChanged(roomJID, user, oldNickname, newNickname);
}
}
public static void messageReceived(JID roomJID, JID user, String nickname, Message message) {
for (MUCEventListener listener : listeners) {
listener.messageReceived(roomJID, user, nickname, message);
}
}
public static void roomCreated(JID roomJID) {
for (MUCEventListener listener : listeners) {
listener.roomCreated(roomJID);
}
}
public static void roomDestroyed(JID roomJID) {
for (MUCEventListener listener : listeners) {
listener.roomDestroyed(roomJID);
}
}
}
......@@ -15,7 +15,7 @@ import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
/**
* Interface to listen for MUC events. Use the {@link MultiUserChatServer#addListener(MUCEventListener)}
* Interface to listen for MUC events. Use the {@link MUCEventDispatcher#addListener(MUCEventListener)}
* method to register for events.
*
* @author Gaston Dombiak
......
......@@ -50,6 +50,13 @@ public interface MUCRoom extends Externalizable, Result {
*/
String getName();
/**
* Get the full JID of this room.
*
* @return the JID for this room.
*/
JID getJID();
/**
* Obtain a unique numerical id for this room. Useful for storing rooms in databases. If the
* room is persistent or is logging the conversation then the returned ID won't be -1.
......@@ -68,6 +75,20 @@ public interface MUCRoom extends Externalizable, Result {
*/
void setID(long roomID);
/**
* Get the multi user chat service the room is attached to.
*
* @return the MultiUserChatService instance that the room is attached to.
*/
MultiUserChatService getMUCService();
/**
* Sets the multi user chat service the room is attached to.
*
* @param service The MultiUserChatService that the room is attached to.
*/
void setMUCService(MultiUserChatService service);
/**
* Returns the date when the room was created.
*
......@@ -238,6 +259,7 @@ public interface MUCRoom extends Externalizable, Result {
/**
* Create a new presence in this room for the given role.
*
* @param type Type of presence to create.
* @return The new presence
* @throws UnauthorizedException If the user doesn't have permission to leave the room
*/
......
/**
* $Revision$
* $Date$
*
* 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.
*/
package org.jivesoftware.openfire.muc;
import org.jivesoftware.util.*;
import org.jivesoftware.util.cache.CacheFactory;
import org.jivesoftware.openfire.container.BasicModule;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.cluster.ClusterEventListener;
import org.jivesoftware.openfire.cluster.ClusterManager;
import org.jivesoftware.openfire.stats.Statistic;
import org.jivesoftware.openfire.stats.StatisticsManager;
import org.jivesoftware.openfire.muc.spi.MultiUserChatServiceImpl;
import org.jivesoftware.openfire.muc.spi.LocalMUCRoom;
import org.jivesoftware.openfire.muc.spi.MUCServicePropertyEventListener;
import org.jivesoftware.openfire.muc.cluster.*;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.database.SequenceManager;
import org.xmpp.packet.JID;
import org.xmpp.component.ComponentManagerFactory;
import org.xmpp.component.ComponentException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.sql.*;
/**
* Provides centralized management of all configured Multi User Chat (MUC) services.
*
* @author Daniel Henninger
*/
public class MultiUserChatManager extends BasicModule implements ClusterEventListener, MUCServicePropertyEventListener {
private static final String LOAD_SERVICES = "SELECT subdomain,description FROM mucService";
private static final String CREATE_SERVICE = "INSERT INTO mucService(serviceID,subdomain,description) VALUES(?,?,?)";
private static final String UPDATE_SERVICE = "UPDATE mucService SET subdomain=?,description=? WHERE serviceID=?";
private static final String DELETE_SERVICE = "DELETE FROM mucService WHERE serviceID=?";
private static final String LOAD_SERVICE_ID = "SELECT serviceID FROM mucService WHERE subdomain=?";
private static final String LOAD_SUBDOMAIN = "SELECT subdomain FROM mucService WHERE serviceID=?";
/**
* Statistics keys
*/
private static final String roomsStatKey = "muc_rooms";
private static final String occupantsStatKey = "muc_occupants";
private static final String usersStatKey = "muc_users";
private static final String incomingStatKey = "muc_incoming";
private static final String outgoingStatKey = "muc_outgoing";
private static final String trafficStatGroup = "muc_traffic";
private ConcurrentHashMap<String,MultiUserChatService> mucServices = new ConcurrentHashMap<String,MultiUserChatService>();
/**
* Creates a new MultiUserChatManager instance.
*/
public MultiUserChatManager() {
super("Multi user chat manager");
}
/**
* Called when manager starts up, to initialize things.
*/
public void start() {
super.start();
loadServices();
for (MultiUserChatService service : mucServices.values()) {
registerMultiUserChatService(service);
}
// Add statistics
addTotalRoomStats();
addTotalOccupantsStats();
addTotalConnectedUsers();
addNumberIncomingMessages();
addNumberOutgoingMessages();
ClusterManager.addListener(this);
}
/**
* Called when manager is stopped, to clean things up.
*/
public void stop() {
super.stop();
ClusterManager.removeListener(this);
// Remove the statistics.
StatisticsManager.getInstance().removeStatistic(roomsStatKey);
StatisticsManager.getInstance().removeStatistic(occupantsStatKey);
StatisticsManager.getInstance().removeStatistic(usersStatKey);
StatisticsManager.getInstance().removeStatistic(incomingStatKey);
StatisticsManager.getInstance().removeStatistic(outgoingStatKey);
for (MultiUserChatService service : mucServices.values()) {
unregisterMultiUserChatService(service.getServiceName());
}
}
/**
* Registers a new MultiUserChatService implementation to the manager.
* This is typically used if you have a custom MUC implementation that you
* want to register with the manager. In other words, it may not be database
* stored and may follow special rules, implementating MultiUserChatService.
* It is also used internally to register services from the database. Triggers
* the service to start up.
*
* @param service The MultiUserChatService to be registered.
*/
public void registerMultiUserChatService(MultiUserChatService service) {
Log.debug("MultiUserChatManager: Registering MUC service "+service.getServiceName());
mucServices.put(service.getServiceName(), service);
try {
ComponentManagerFactory.getComponentManager().addComponent(service.getServiceName(), service);
}
catch (ComponentException e) {
Log.error("MultiUserChatManager: Unable to add "+service.getServiceName()+" as component.", e);
}
}
/**
* Unregisters a MultiUserChatService from the manager. It can be used
* to explicitly unregister services, and is also used internally to unregister
* database stored services. Triggers the service to shut down.
*
* @param subdomain The subdomain of the service to be unregistered.
*/
public void unregisterMultiUserChatService(String subdomain) {
Log.debug("MultiUserChatManager: Unregistering MUC service "+subdomain);
MultiUserChatService service = mucServices.get(subdomain);
if (service != null) {
service.shutdown();
try {
ComponentManagerFactory.getComponentManager().removeComponent(subdomain);
}
catch (ComponentException e) {
Log.error("MultiUserChatManager: Unable to remove "+subdomain+" from component manager.", e);
}
mucServices.remove(subdomain);
}
}
/**
* Returns the number of registered MultiUserChatServices.
*
* @param includePrivate True if you want to include private/hidden services in the count.
* @return Number of registered services.
*/
public Integer getServicesCount(boolean includePrivate) {
Integer servicesCnt = mucServices.size();
if (!includePrivate) {
for (MultiUserChatService service : mucServices.values()) {
if (service.isServicePrivate()) {
servicesCnt--;
}
}
}
return servicesCnt;
}
/**
* Creates a new MUC service and registers it with the manager, and starts up the service.
*
* @param subdomain Subdomain of the MUC service.
* @param description Description of the MUC service (can be null for default description)
* @throws AlreadyExistsException if the service already exists.
*/
public void createMultiUserChatService(String subdomain, String description) throws AlreadyExistsException {
try {
getMultiUserChatServiceID(subdomain);
throw new AlreadyExistsException();
}
catch (NotFoundException e) {
// Good =)
}
insertService(subdomain, description);
MultiUserChatServiceImpl muc = new MultiUserChatServiceImpl(subdomain, description);
registerMultiUserChatService(muc);
}
/**
* Updates the configuration of a MUC service. This is more involved than it may seem. If the
* subdomain is changed, we need to shut down the old service and start up the new one, registering
* the new subdomain and cleaning up the old one. Properties are tied to the ID, which will not change.
*
* @param serviceID The ID of the service to be updated.
* @param subdomain New subdomain to assign to the service.
* @param description New description to assign to the service.
* @throws NotFoundException if service was not found.
*/
public void updateMultiUserChatService(Long serviceID, String subdomain, String description) throws NotFoundException {
MultiUserChatServiceImpl muc = (MultiUserChatServiceImpl) getMultiUserChatService(serviceID);
// A NotFoundException is thrown if the specified service was not found.
String oldsubdomain = muc.getServiceName();
if (!mucServices.containsKey(oldsubdomain)) {
// This should never occur, but just in case...
throw new NotFoundException();
}
if (oldsubdomain.equals(subdomain)) {
// Alright, all we're changing is the description. This is easy.
updateService(serviceID, subdomain, description);
// Update the existing service's description.
muc.setDescription(description);
}
else {
// Changing the subdomain, here's where it gets complex.
// Unregister existing muc service
unregisterMultiUserChatService(subdomain);
// Update the information stored about the MUC service
updateService(serviceID, subdomain, description);
// Create new MUC service with new settings
muc = new MultiUserChatServiceImpl(subdomain, description);
// Register to new service
registerMultiUserChatService(muc);
}
}
/**
* Updates the configuration of a MUC service. This is more involved than it may seem. If the
* subdomain is changed, we need to shut down the old service and start up the new one, registering
* the new subdomain and cleaning up the old one. Properties are tied to the ID, which will not change.
*
* @param cursubdomain The current subdomain assigned to the service.
* @param newsubdomain New subdomain to assign to the service.
* @param description New description to assign to the service.
* @throws NotFoundException if service was not found.
*/
public void updateMultiUserChatService(String cursubdomain, String newsubdomain, String description) throws NotFoundException {
Long serviceID = getMultiUserChatServiceID(cursubdomain);
updateMultiUserChatService(serviceID, newsubdomain, description);
}
/**
* Deletes a configured MultiUserChatService by subdomain, and shuts it down.
*
* @param subdomain The subdomain of the service to be deleted.
*/
public void removeMultiUserChatService(String subdomain) {
try {
Long serviceID = getMultiUserChatServiceID(subdomain);
removeMultiUserChatService(serviceID);
}
catch (NotFoundException e) {
Log.error("MultiUserChatManager: Unable to find service to remove for "+subdomain);
}
}
/**
* Deletes a configured MultiUserChatService by ID, and shuts it down.
*
* @param serviceID The ID opf the service to be deleted.
*/
public void removeMultiUserChatService(Long serviceID) {
try {
MultiUserChatServiceImpl muc = (MultiUserChatServiceImpl) getMultiUserChatService(serviceID);
unregisterMultiUserChatService(muc.getServiceName());
deleteService(serviceID);
}
catch (NotFoundException e) {
Log.error("MultiUserChatManager: Unable to find service to remove for service ID "+serviceID);
}
}
/**
* Retrieves a MultiUserChatService instance specified by it's service ID.
*
* @param serviceID ID of the conference service you wish to query.
* @return The MultiUserChatService instance associated with the id.
* @throws NotFoundException if no matching service was found.
*/
public MultiUserChatService getMultiUserChatService(Long serviceID) throws NotFoundException {
String subdomain = getMultiUserChatSubdomain(serviceID);
if (!mucServices.containsKey(subdomain)) {
throw new NotFoundException();
}
return mucServices.get(subdomain);
}
/**
* Retrieves a MultiUserChatService instance specified by it's subdomain of the
* server's primary domain. In other words, if the service is conference.example.org,
* and the server is example.org, you would specify conference here.
*
* @param subdomain Subdomain of the conference service you wish to query.
* @return The MultiUserChatService instance associated with the subdomain.
* @throws NotFoundException if no matching service was found.
*/
public MultiUserChatService getMultiUserChatService(String subdomain) throws NotFoundException {
if (!mucServices.containsKey(subdomain)) {
throw new NotFoundException();
}
return mucServices.get(subdomain);
}
/**
* Retrieves a MultiUserChatService instance specified by any JID that refers to it.
* In other words, it can be a hostname for the service, a room JID, or even the JID
* of a occupant of the room. Basically it takes the hostname part of the JID,
* strips off the server hostname from the end, leaving only the subdomain, and then calls
* the subdomain version of the call.
*
* @param jid JID that contains a reference to the conference service.
* @return The MultiUserChatService instance associated with the JID.
* @throws NotFoundException if no matching service was found.
*/
public MultiUserChatService getMultiUserChatService(JID jid) throws NotFoundException {
String subdomain = jid.getDomain().replace("."+ XMPPServer.getInstance().getServerInfo().getXMPPDomain(), "");
return getMultiUserChatService(subdomain);
}
/**
* Retrieves all of the MultiUserChatServices managed and configured for this server.
*
* @return A collection of MultiUserChatServices configured for this server.
*/
public Collection<MultiUserChatService> getMultiUserChatServices() {
return mucServices.values();
}
/**
* Retrieves the number of MultiUserChatServices that are configured for this server.
*
* @return The number of registered MultiUserChatServices.
*/
public Integer getMultiUserChatServicesCount() {
return mucServices.size();
}
/**
* Returns true if a MUC service is configured/exists for a given subdomain.
*
* @param subdomain Subdomain of service to check on.
* @return True or false if the subdomain is registered as a MUC service.
*/
public boolean isServiceRegistered(String subdomain) {
if (subdomain == null) return false;
return mucServices.containsKey(subdomain);
}
/**
* Retrieves ID of MUC service by subdomain.
*
* @param subdomain Subdomain of service to get ID of.
* @return ID number of MUC service.
* @throws NotFoundException if service was not found.
*/
public Long getMultiUserChatServiceID(String subdomain) throws NotFoundException {
Long id = loadServiceID(subdomain);
if (id == -1) {
throw new NotFoundException();
}
return id;
}
/**
* Retrieves the subdomain of a specified service ID.
*
* @param serviceID ID of service to get subdomain of.
* @return Subdomain of MUC service.
* @throws NotFoundException if service was not found.
*/
public String getMultiUserChatSubdomain(Long serviceID) throws NotFoundException {
String subdomain = loadServiceSubdomain(serviceID);
if (subdomain == null) {
throw new NotFoundException();
}
return subdomain;
}
/**
* Loads the list of configured services stored in the database.
*/
private void loadServices() {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_SERVICES);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
String subdomain = rs.getString(1);
String description = rs.getString(2);
MultiUserChatServiceImpl muc = new MultiUserChatServiceImpl(subdomain, description);
mucServices.put(subdomain, muc);
}
rs.close();
}
catch (Exception e) {
Log.error(e);
}
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); }
}
}
/**
* Gets a specific subdomain/service's ID number.
* @param subdomain Subdomain to retrieve ID for.
* @return ID number of service.
*/
private long loadServiceID(String subdomain) {
Connection con = null;
PreparedStatement pstmt = null;
Long id = (long)-1;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_SERVICE_ID);
pstmt.setString(1, subdomain);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
id = rs.getLong(1);
}
else {
throw new Exception("Unable to locate Service ID for subdomain "+subdomain);
}
rs.close();
}
catch (Exception e) {
// No problem, considering this as a "not found".
}
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 id;
}
/**
* Gets a specific subdomain by a service's ID number.
* @param serviceID ID to retrieve subdomain for.
* @return Subdomain of service.
*/
private String loadServiceSubdomain(Long serviceID) {
Connection con = null;
PreparedStatement pstmt = null;
String subdomain = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_SUBDOMAIN);
pstmt.setLong(1, serviceID);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
subdomain = rs.getString(1);
}
else {
throw new Exception("Unable to locate subdomain for service ID "+serviceID);
}
rs.close();
}
catch (Exception e) {
// No problem, considering this as a "not found".
}
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 subdomain;
}
/**
* Inserts a new MUC service into the database.
* @param subdomain Subdomain of new service.
* @param description Description of MUC service. Can be null for default description.
*/
private void insertService(String subdomain, String description) {
Connection con = null;
PreparedStatement pstmt = null;
Long serviceID = SequenceManager.nextID(JiveConstants.MUC_SERVICE);
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(CREATE_SERVICE);
pstmt.setLong(1, serviceID);
pstmt.setString(2, subdomain);
if (description != null) {
pstmt.setString(3, description);
}
else {
pstmt.setNull(3, Types.VARCHAR);
}
pstmt.executeUpdate();
}
catch (SQLException e) {
Log.error(e);
}
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); }
}
}
/**
* Updates an existing service's subdomain and description in the database.
* @param serviceID ID of the service to update.
* @param subdomain Subdomain to set service to.
* @param description Description of MUC service. Can be null for default description.
*/
private void updateService(Long serviceID, String subdomain, String description) {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(UPDATE_SERVICE);
pstmt.setString(1, subdomain);
if (description != null) {
pstmt.setString(2, description);
}
else {
pstmt.setNull(2, Types.VARCHAR);
}
pstmt.setLong(3, serviceID);
pstmt.executeUpdate();
}
catch (SQLException e) {
Log.error(e);
}
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); }
}
}
/**
* Deletes a service based on service ID.
* @param serviceID ID of the service to delete.
*/
private void deleteService(Long serviceID) {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(DELETE_SERVICE);
pstmt.setLong(1, serviceID);
pstmt.executeUpdate();
}
catch (SQLException e) {
Log.error(e);
}
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); }
}
}
/****************** Statistics code ************************/
private void addTotalRoomStats() {
// Register a statistic.
Statistic statistic = new Statistic() {
public String getName() {
return LocaleUtils.getLocalizedString("muc.stats.active_group_chats.name");
}
public Type getStatType() {
return Type.count;
}
public String getDescription() {
return LocaleUtils.getLocalizedString("muc.stats.active_group_chats.desc");
}
public String getUnits() {
return LocaleUtils.getLocalizedString("muc.stats.active_group_chats.units");
}
public double sample() {
double rooms = 0;
for (MultiUserChatService service : getMultiUserChatServices()) {
rooms += service.getNumberChatRooms();
}
return rooms;
}
public boolean isPartialSample() {
return false;
}
};
StatisticsManager.getInstance().addStatistic(roomsStatKey, statistic);
}
private void addTotalOccupantsStats() {
// Register a statistic.
Statistic statistic = new Statistic() {
public String getName() {
return LocaleUtils.getLocalizedString("muc.stats.occupants.name");
}
public Type getStatType() {
return Type.count;
}
public String getDescription() {
return LocaleUtils.getLocalizedString("muc.stats.occupants.description");
}
public String getUnits() {
return LocaleUtils.getLocalizedString("muc.stats.occupants.label");
}
public double sample() {
double occupants = 0;
for (MultiUserChatService service : getMultiUserChatServices()) {
occupants += service.getNumberRoomOccupants();
}
return occupants;
}
public boolean isPartialSample() {
return false;
}
};
StatisticsManager.getInstance().addStatistic(occupantsStatKey, statistic);
}
private void addTotalConnectedUsers() {
// Register a statistic.
Statistic statistic = new Statistic() {
public String getName() {
return LocaleUtils.getLocalizedString("muc.stats.users.name");
}
public Type getStatType() {
return Type.count;
}
public String getDescription() {
return LocaleUtils.getLocalizedString("muc.stats.users.description");
}
public String getUnits() {
return LocaleUtils.getLocalizedString("muc.stats.users.label");
}
public double sample() {
double users = 0;
for (MultiUserChatService service : getMultiUserChatServices()) {
users += service.getNumberConnectedUsers(false);
}
return users;
}
public boolean isPartialSample() {
return false;
}
};
StatisticsManager.getInstance().addStatistic(usersStatKey, statistic);
}
private void addNumberIncomingMessages() {
// Register a statistic.
Statistic statistic = new Statistic() {
public String getName() {
return LocaleUtils.getLocalizedString("muc.stats.incoming.name");
}
public Type getStatType() {
return Type.rate;
}
public String getDescription() {
return LocaleUtils.getLocalizedString("muc.stats.incoming.description");
}
public String getUnits() {
return LocaleUtils.getLocalizedString("muc.stats.incoming.label");
}
public double sample() {
double msgcnt = 0;
for (MultiUserChatService service : getMultiUserChatServices()) {
msgcnt += service.getIncomingMessageCount(true);
}
return msgcnt;
}
public boolean isPartialSample() {
// Get this value from the other cluster nodes
return true;
}
};
StatisticsManager.getInstance().addMultiStatistic(incomingStatKey, trafficStatGroup, statistic);
}
private void addNumberOutgoingMessages() {
// Register a statistic.
Statistic statistic = new Statistic() {
public String getName() {
return LocaleUtils.getLocalizedString("muc.stats.outgoing.name");
}
public Type getStatType() {
return Type.rate;
}
public String getDescription() {
return LocaleUtils.getLocalizedString("muc.stats.outgoing.description");
}
public String getUnits() {
return LocaleUtils.getLocalizedString("muc.stats.outgoing.label");
}
public double sample() {
double msgcnt = 0;
for (MultiUserChatService service : getMultiUserChatServices()) {
msgcnt += service.getOutgoingMessageCount(true);
}
return msgcnt;
}
public boolean isPartialSample() {
// Each cluster node knows the total across the cluster
return false;
}
};
StatisticsManager.getInstance().addMultiStatistic(outgoingStatKey, trafficStatGroup, statistic);
}
// Cluster management tasks
public void joinedCluster() {
if (!ClusterManager.isSeniorClusterMember()) {
// Get transient rooms and persistent rooms with occupants from senior
// cluster member and merge with local ones. If room configuration was
// changed in both places then latest configuration will be kept
@SuppressWarnings("unchecked")
List<ServiceInfo> result = (List<ServiceInfo>) CacheFactory.doSynchronousClusterTask(
new SeniorMemberServicesRequest(), ClusterManager.getSeniorClusterMember().toByteArray());
if (result != null) {
for (ServiceInfo serviceInfo : result) {
MultiUserChatService service;
try {
service = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(serviceInfo.getSubdomain());
}
catch (NotFoundException e) {
// This is a service we don't know about yet, create it locally and register it;
service = new MultiUserChatServiceImpl(serviceInfo.getSubdomain(), serviceInfo.getDescription());
XMPPServer.getInstance().getMultiUserChatManager().registerMultiUserChatService(service);
}
// TODO: How do we handle non-default service implemtations properly here?
MultiUserChatServiceImpl serviceImpl = (MultiUserChatServiceImpl)service;
for (RoomInfo roomInfo : serviceInfo.getRooms()) {
LocalMUCRoom remoteRoom = roomInfo.getRoom();
LocalMUCRoom localRoom = serviceImpl.getLocalChatRoom(remoteRoom.getName());
if (localRoom == null) {
// Create local room with remote information
localRoom = remoteRoom;
serviceImpl.chatRoomAdded(localRoom);
}
else {
// Update local room with remote information
localRoom.updateConfiguration(remoteRoom);
}
// Add remote occupants to local room
// TODO Handle conflict of nicknames
for (OccupantAddedEvent event : roomInfo.getOccupants()) {
event.setSendPresence(true);
event.run();
}
}
}
}
}
}
public void joinedCluster(byte[] nodeID) {
@SuppressWarnings("unchecked")
List<RoomInfo> result =
(List<RoomInfo>) CacheFactory.doSynchronousClusterTask(new GetNewMemberRoomsRequest(), nodeID);
if (result != null) {
for (RoomInfo roomInfo : result) {
LocalMUCRoom remoteRoom = roomInfo.getRoom();
// TODO: How do we handle non-default service implemtations properly here?
MultiUserChatServiceImpl service = (MultiUserChatServiceImpl)remoteRoom.getMUCService();
LocalMUCRoom localRoom = service.getLocalChatRoom(remoteRoom.getName());
if (localRoom == null) {
// Create local room with remote information
localRoom = remoteRoom;
service.chatRoomAdded(localRoom);
}
// Add remote occupants to local room
for (OccupantAddedEvent event : roomInfo.getOccupants()) {
event.setSendPresence(true);
event.run();
}
}
}
}
public void leftCluster() {
// Do nothing. An unavailable presence will be created for occupants hosted in other cluster nodes.
}
public void leftCluster(byte[] nodeID) {
// Do nothing. An unavailable presence will be created for occupants hosted in the leaving cluster node.
}
public void markedAsSeniorClusterMember() {
// Do nothing
}
public void propertySet(String service, String property, Map<String, Object> params) {
// Let everyone know we've had an update.
CacheFactory.doSynchronousClusterTask(new ServiceUpdatedEvent(service), false);
}
public void propertyDeleted(String service, String property, Map<String, Object> params) {
// Let everyone know we've had an update.
CacheFactory.doSynchronousClusterTask(new ServiceUpdatedEvent(service), false);
}
}
......@@ -14,6 +14,9 @@ package org.jivesoftware.openfire.muc;
import org.xmpp.component.Component;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
import org.jivesoftware.openfire.muc.spi.LocalMUCRoom;
import org.jivesoftware.database.JiveID;
import org.jivesoftware.util.JiveConstants;
import java.util.Collection;
import java.util.List;
......@@ -25,7 +28,8 @@ import java.util.List;
*
* @author Gaston Dombiak
*/
public interface MultiUserChatServer extends Component {
@JiveID(JiveConstants.MUC_SERVICE)
public interface MultiUserChatService extends Component {
/**
* Returns the fully-qualifed domain name of this chat service.
......@@ -43,14 +47,6 @@ public interface MultiUserChatServer extends Component {
*/
String getServiceName();
/**
* Set the name of this chat service. The new name won't go into effect until the server is
* restarted.
*
* @param name The chat service name (host name).
*/
void setServiceName(String name);
/**
* Returns the collection of JIDs that are system administrators of the MUC service. A sysadmin has
* the same permissions as a room owner.
......@@ -227,6 +223,22 @@ public interface MultiUserChatServer extends Component {
*/
boolean hasChatRoom(String roomName);
/**
* Notification message indicating that the specified chat room was
* removed from some other cluster member.
*
* @param room the removed room in another cluster node.
*/
public void chatRoomRemoved(LocalMUCRoom room);
/**
* Notification message indicating that a chat room has been created
* in another cluster member.
*
* @param room the created room in another cluster node.
*/
public void chatRoomAdded(LocalMUCRoom room);
/**
* Removes the room associated with the given name.
*
......@@ -252,6 +264,45 @@ public interface MultiUserChatServer extends Component {
*/
public long getTotalChatTime();
/**
* Retuns the number of existing rooms in the server (i.e. persistent or not,
* in memory or not).
*
* @return the number of existing rooms in the server.
*/
public int getNumberChatRooms();
/**
* Retuns the total number of occupants in all rooms in the server.
*
* @param onlyLocal true if only users connected to this JVM will be considered. Otherwise count cluster wise.
* @return the number of existing rooms in the server.
*/
public int getNumberConnectedUsers(boolean onlyLocal);
/**
* Retuns the total number of users that have joined in all rooms in the server.
*
* @return the number of existing rooms in the server.
*/
public int getNumberRoomOccupants();
/**
* Returns the total number of incoming messages since last reset.
*
* @param resetAfter True if you want the counter to be reset after results returned.
* @return the number of incoming messages through the service.
*/
public long getIncomingMessageCount(boolean resetAfter);
/**
* Returns the total number of outgoing messages since last reset.
*
* @param resetAfter True if you want the counter to be reset after results returned.
* @return the number of outgoing messages through the service.
*/
public long getOutgoingMessageCount(boolean resetAfter);
/**
* Logs that a given message was sent to a room as part of a conversation. Every message sent
* to the room that is allowed to be broadcasted and that was sent either from the room itself
......@@ -261,7 +312,7 @@ public interface MultiUserChatServer extends Component {
* the logged messages in memory until the logging process saves them to the database. It's
* possible to configure the logging process to run every X milliseconds and also the number
* of messages to log on each execution.
* @see org.jivesoftware.openfire.muc.spi.MultiUserChatServerImpl#initialize(org.jivesoftware.openfire.XMPPServer)
* @see org.jivesoftware.openfire.muc.spi.MultiUserChatServiceImpl#initialize(org.jivesoftware.openfire.XMPPServer)
*
* @param room the room that received the message.
* @param message the message to log as part of the conversation in the room.
......@@ -295,16 +346,14 @@ public interface MultiUserChatServer extends Component {
boolean isServiceEnabled();
/**
* Registers a listener to receive events.
* Returns true if the MUC service is a private, externally managed, service. This is typically
* set to true when the implementation is not the default one, and is not to be managed by
* the standard Openfire interface. If this is set to true, the service will not show up in
* the service list in the admin console.
*
* @param listener the listener.
*/
void addListener(MUCEventListener listener);
/**
* Unregisters a listener to receive events.
* TODO: Anything else? Should it show up in Disco browsing?
*
* @param listener the listener.
* @return true if the MUC service is private and externally managed.
*/
void removeListener(MUCEventListener listener);
boolean isServicePrivate();
}
\ No newline at end of file
......@@ -28,14 +28,14 @@ import java.io.ObjectOutput;
*
* @author Gaston Dombiak
*/
public class BroascastMessageRequest extends MUCRoomTask {
public class BroadcastMessageRequest extends MUCRoomTask {
private int occupants;
private Message message;
public BroascastMessageRequest() {
public BroadcastMessageRequest() {
}
public BroascastMessageRequest(LocalMUCRoom room, Message message, int occupants) {
public BroadcastMessageRequest(LocalMUCRoom room, Message message, int occupants) {
super(room);
this.message = message;
this.occupants = occupants;
......
......@@ -29,13 +29,13 @@ import java.io.ObjectOutput;
*
* @author Gaston Dombiak
*/
public class BroascastPresenceRequest extends MUCRoomTask {
public class BroadcastPresenceRequest extends MUCRoomTask {
private Presence presence;
public BroascastPresenceRequest() {
public BroadcastPresenceRequest() {
}
public BroascastPresenceRequest(LocalMUCRoom room, Presence message) {
public BroadcastPresenceRequest(LocalMUCRoom room, Presence message) {
super(room);
this.presence = message;
}
......
......@@ -14,7 +14,7 @@ package org.jivesoftware.openfire.muc.cluster;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.muc.MUCRole;
import org.jivesoftware.openfire.muc.MUCRoom;
import org.jivesoftware.openfire.muc.MultiUserChatServer;
import org.jivesoftware.openfire.muc.MultiUserChatService;
import org.jivesoftware.openfire.muc.spi.LocalMUCRoom;
import org.jivesoftware.util.cache.ClusterTask;
......@@ -43,18 +43,20 @@ public class GetNewMemberRoomsRequest implements ClusterTask {
public void run() {
rooms = new ArrayList<RoomInfo>();
// Get rooms that have local occupants and include them in the reply
MultiUserChatServer mucServer = XMPPServer.getInstance().getMultiUserChatServer();
for (MUCRoom room : mucServer.getChatRooms()) {
LocalMUCRoom localRoom = (LocalMUCRoom) room;
Collection<MUCRole> localOccupants = new ArrayList<MUCRole>();
for (MUCRole occupant : room.getOccupants()) {
if (occupant.isLocal()) {
localOccupants.add(occupant);
// Get all services that have local occupants and include them in the reply
for (MultiUserChatService mucService : XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatServices()) {
// Get rooms that have local occupants and include them in the reply
for (MUCRoom room : mucService.getChatRooms()) {
LocalMUCRoom localRoom = (LocalMUCRoom) room;
Collection<MUCRole> localOccupants = new ArrayList<MUCRole>();
for (MUCRole occupant : room.getOccupants()) {
if (occupant.isLocal()) {
localOccupants.add(occupant);
}
}
if (!localOccupants.isEmpty()) {
rooms.add(new RoomInfo(localRoom, localOccupants));
}
}
if (!localOccupants.isEmpty()) {
rooms.add(new RoomInfo(localRoom, localOccupants));
}
}
}
......
......@@ -12,7 +12,7 @@
package org.jivesoftware.openfire.muc.cluster;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.muc.spi.MultiUserChatServerImpl;
import org.jivesoftware.openfire.muc.MultiUserChatService;
import org.jivesoftware.util.cache.ClusterTask;
import java.io.IOException;
......@@ -33,8 +33,10 @@ public class GetNumberConnectedUsers implements ClusterTask{
}
public void run() {
MultiUserChatServerImpl mucServer = (MultiUserChatServerImpl) XMPPServer.getInstance().getMultiUserChatServer();
count = mucServer.getNumberConnectedUsers(true);
count = 0;
for (MultiUserChatService mucService : XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatServices()) {
count += mucService.getNumberConnectedUsers(true);
}
}
public void writeExternal(ObjectOutput out) throws IOException {
......
......@@ -13,8 +13,10 @@ package org.jivesoftware.openfire.muc.cluster;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.muc.spi.LocalMUCRoom;
import org.jivesoftware.openfire.muc.MultiUserChatService;
import org.jivesoftware.util.cache.ClusterTask;
import org.jivesoftware.util.cache.ExternalizableUtil;
import org.jivesoftware.util.NotFoundException;
import java.io.IOException;
import java.io.ObjectInput;
......@@ -53,14 +55,22 @@ public abstract class MUCRoomTask implements ClusterTask {
public void writeExternal(ObjectOutput out) throws IOException {
ExternalizableUtil.getInstance().writeBoolean(out, originator);
ExternalizableUtil.getInstance().writeSafeUTF(out, room.getName());
ExternalizableUtil.getInstance().writeSafeUTF(out, room.getMUCService().getServiceName());
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
originator = ExternalizableUtil.getInstance().readBoolean(in);
String roomName = ExternalizableUtil.getInstance().readSafeUTF(in);
room = (LocalMUCRoom) XMPPServer.getInstance().getMultiUserChatServer().getChatRoom(roomName);
if (room == null) {
throw new IllegalArgumentException("Room not found: " + roomName);
String subdomain = ExternalizableUtil.getInstance().readSafeUTF(in);
try {
MultiUserChatService mucService = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(subdomain);
room = (LocalMUCRoom) mucService.getChatRoom(roomName);
if (room == null) {
throw new IllegalArgumentException("Room not found: " + roomName);
}
}
catch (NotFoundException e) {
throw new IllegalArgumentException("MUC service not found for subdomain: "+subdomain);
}
}
}
......@@ -11,9 +11,8 @@
package org.jivesoftware.openfire.muc.cluster;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.muc.spi.LocalMUCRoom;
import org.jivesoftware.openfire.muc.spi.MultiUserChatServerImpl;
import org.jivesoftware.openfire.muc.MultiUserChatService;
import org.jivesoftware.util.cache.ClusterTask;
import java.io.IOException;
......@@ -42,8 +41,8 @@ public class RoomAvailableEvent implements ClusterTask {
}
public void run() {
MultiUserChatServerImpl mucServer = (MultiUserChatServerImpl) XMPPServer.getInstance().getMultiUserChatServer();
mucServer.chatRoomAdded(room);
MultiUserChatService mucService = room.getMUCService();
mucService.chatRoomAdded(room);
}
public void writeExternal(ObjectOutput out) throws IOException {
......
......@@ -11,10 +11,9 @@
package org.jivesoftware.openfire.muc.cluster;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.muc.spi.MultiUserChatServerImpl;
import org.jivesoftware.openfire.muc.spi.LocalMUCRoom;
import org.jivesoftware.openfire.muc.MultiUserChatService;
import org.jivesoftware.util.cache.ClusterTask;
import org.jivesoftware.util.cache.ExternalizableUtil;
import java.io.IOException;
import java.io.ObjectInput;
......@@ -28,13 +27,13 @@ import java.io.ObjectOutput;
* @author Gaston Dombiak
*/
public class RoomRemovedEvent implements ClusterTask {
private String roomName;
private LocalMUCRoom room;
public RoomRemovedEvent() {
}
public RoomRemovedEvent(String roomName) {
this.roomName = roomName;
public RoomRemovedEvent(LocalMUCRoom room) {
this.room = room;
}
public Object getResult() {
......@@ -42,15 +41,16 @@ public class RoomRemovedEvent implements ClusterTask {
}
public void run() {
MultiUserChatServerImpl mucServer = (MultiUserChatServerImpl) XMPPServer.getInstance().getMultiUserChatServer();
mucServer.chatRoomRemoved(roomName);
MultiUserChatService mucService = room.getMUCService();
mucService.chatRoomRemoved(room);
}
public void writeExternal(ObjectOutput out) throws IOException {
ExternalizableUtil.getInstance().writeSafeUTF(out, roomName);
room.writeExternal(out);
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
roomName = ExternalizableUtil.getInstance().readSafeUTF(in);
room = new LocalMUCRoom();
room.readExternal(in);
}
}
/**
* $RCSfile$
* $Revision: $
* $Date: $
*
* Copyright (C) 2007 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.openfire.muc.cluster;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.muc.MUCRoom;
import org.jivesoftware.openfire.muc.MultiUserChatServer;
import org.jivesoftware.openfire.muc.spi.LocalMUCRoom;
import org.jivesoftware.util.cache.ClusterTask;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.ArrayList;
import java.util.List;
/**
* Task to be requested by a node that joins a cluster and be executed in the senior cluster member to get
* the rooms with occupants. The list of rooms with occupants is returned to the new cluster node so that
* the new cluster node can be updated and have the same information shared by the cluster.<p>
*
* Moreover, each existing cluster node will also need to learn the rooms with occupants that exist in
* the new cluster node and replicate them. This work is accomplished using {@link GetNewMemberRoomsRequest}.
*
* @author Gaston Dombiak
*/
public class SeniorMemberRoomsRequest implements ClusterTask {
private List<RoomInfo> rooms;
public SeniorMemberRoomsRequest() {
}
public Object getResult() {
return rooms;
}
public void run() {
rooms = new ArrayList<RoomInfo>();
// Get rooms that have occupants and include them in the reply
MultiUserChatServer mucServer = XMPPServer.getInstance().getMultiUserChatServer();
for (MUCRoom room : mucServer.getChatRooms()) {
LocalMUCRoom localRoom = (LocalMUCRoom) room;
if (!room.getOccupants().isEmpty()) {
rooms.add(new RoomInfo(localRoom, localRoom.getOccupants()));
}
}
}
public void writeExternal(ObjectOutput out) throws IOException {
// Do nothing
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
// Do nothing
}
}
/**
* $RCSfile$
* $Revision: $
* $Date: $
*
* Copyright (C) 2007 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.openfire.muc.cluster;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.muc.MultiUserChatService;
import org.jivesoftware.util.cache.ClusterTask;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.ArrayList;
import java.util.List;
/**
* Task to be requested by a node that joins a cluster and be executed in the senior cluster member to get
* the services with rooms with occupants. The list of services with rooms with occupants is returned to
* the new cluster node so that the new cluster node can be updated and have the same information shared
* by the cluster.<p>
*
* Moreover, each existing cluster node will also need to learn the services and rooms with occupants that
* exist in the new cluster node and replicate them. This work is accomplished using
* {@link GetNewMemberRoomsRequest} on each service.
*
* @author Daniel Henninger
*/
public class SeniorMemberServicesRequest implements ClusterTask {
private List<ServiceInfo> services;
public SeniorMemberServicesRequest() {
}
public Object getResult() {
return services;
}
public void run() {
services = new ArrayList<ServiceInfo>();
// Get all services and include them in the reply
for (MultiUserChatService mucService : XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatServices()) {
services.add(new ServiceInfo(mucService));
}
}
public void writeExternal(ObjectOutput out) throws IOException {
// Do nothing
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
// Do nothing
}
}
/**
* $RCSfile$
* $Revision: $
* $Date: $
*
* 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.
*/
package org.jivesoftware.openfire.muc.cluster;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.muc.MultiUserChatService;
import org.jivesoftware.openfire.muc.spi.MultiUserChatServiceImpl;
import org.jivesoftware.util.cache.ClusterTask;
import org.jivesoftware.util.cache.ExternalizableUtil;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
/**
* Task that will add a service to the cluster node. When a service is added
* in a cluster node the rest of the cluster nodes will need to add a copy.
* They do -not- need to create database entries for the new service as the originator
* will have already done that. This event assumes that it's the default representation
* of a MUC service, and therefore should not pass information about internal component
* generated MUC services.
*
* @author Daniel Henninger
*/
public class ServiceAddedEvent implements ClusterTask {
private String subdomain;
private String description;
public ServiceAddedEvent() {
}
public ServiceAddedEvent(String subdomain, String description) {
this.subdomain = subdomain;
this.description = description;
}
public Object getResult() {
return null;
}
public void run() {
// If it's registered already, no need to create it. Most likely this is because the service
// is provided by an internal component that registered at startup. This scenario, however,
// should really never occur.
if (!XMPPServer.getInstance().getMultiUserChatManager().isServiceRegistered(subdomain)) {
MultiUserChatService service = new MultiUserChatServiceImpl(subdomain, description);
XMPPServer.getInstance().getMultiUserChatManager().registerMultiUserChatService(service);
}
}
public void writeExternal(ObjectOutput out) throws IOException {
ExternalizableUtil.getInstance().writeSafeUTF(out, subdomain);
ExternalizableUtil.getInstance().writeSafeUTF(out, description);
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
subdomain = ExternalizableUtil.getInstance().readSafeUTF(in);
description = ExternalizableUtil.getInstance().readSafeUTF(in);
}
}
/**
* $RCSfile$
* $Revision: $
* $Date: $
*
* 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.
*/
package org.jivesoftware.openfire.muc.cluster;
import org.jivesoftware.util.cache.ExternalizableUtil;
import org.jivesoftware.openfire.muc.MultiUserChatService;
import org.jivesoftware.openfire.muc.MUCRoom;
import org.jivesoftware.openfire.muc.spi.LocalMUCRoom;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.ArrayList;
import java.util.List;
/**
* Representation of a service configuration. This information is requested by a cluster node when
* joining the cluster (requested to the senior member) and also from each cluster node to the new node
* joining the cluster. Each cluster node (existing and new one) has to merge its local services with the
* new ones. It does not include database stored configuration options, as they are handled via database
* reads.
*
* @author Daniel Henninger
*/
public class ServiceInfo implements Externalizable {
private String subdomain;
private String description;
private List<RoomInfo> rooms = new ArrayList<RoomInfo>();
/**
* Do not use this constructor. Needed for Externalizable interface.
*/
public ServiceInfo() {
}
public ServiceInfo(MultiUserChatService service) {
this.subdomain = service.getServiceName();
this.description = service.getDescription();
rooms = new ArrayList<RoomInfo>();
// Get rooms that have occupants and include them in the reply
for (MUCRoom room : service.getChatRooms()) {
LocalMUCRoom localRoom = (LocalMUCRoom) room;
if (!room.getOccupants().isEmpty()) {
rooms.add(new RoomInfo(localRoom, localRoom.getOccupants()));
}
}
}
public String getSubdomain() {
return subdomain;
}
public String getDescription() {
return description;
}
public List<RoomInfo> getRooms() {
return rooms;
}
public void writeExternal(ObjectOutput out) throws IOException {
ExternalizableUtil.getInstance().writeSafeUTF(out, subdomain);
ExternalizableUtil.getInstance().writeSafeUTF(out, description);
ExternalizableUtil.getInstance().writeExternalizableCollection(out, rooms);
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
subdomain = ExternalizableUtil.getInstance().readSafeUTF(in);
description = ExternalizableUtil.getInstance().readSafeUTF(in);
ExternalizableUtil.getInstance().readExternalizableCollection(in, rooms, getClass().getClassLoader());
}
}
/**
* $RCSfile$
* $Revision: $
* $Date: $
*
* 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.
*/
package org.jivesoftware.openfire.muc.cluster;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.util.cache.ClusterTask;
import org.jivesoftware.util.cache.ExternalizableUtil;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
/**
* Task that will remove a service from the cluster node. When a service is destroyed
* in a cluster node the rest of the cluster nodes will need to destroy their copy.
*
* @author Daniel Henninger
*/
public class ServiceRemovedEvent implements ClusterTask {
private String subdomain;
public ServiceRemovedEvent() {
}
public ServiceRemovedEvent(String subdomain) {
this.subdomain = subdomain;
}
public Object getResult() {
return null;
}
public void run() {
XMPPServer.getInstance().getMultiUserChatManager().unregisterMultiUserChatService(subdomain);
}
public void writeExternal(ObjectOutput out) throws IOException {
ExternalizableUtil.getInstance().writeSafeUTF(out, subdomain);
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
subdomain = ExternalizableUtil.getInstance().readSafeUTF(in);
}
}
/**
* $RCSfile$
* $Revision: $
* $Date: $
*
* 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.
*/
package org.jivesoftware.openfire.muc.cluster;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.muc.MultiUserChatService;
import org.jivesoftware.openfire.muc.spi.MultiUserChatServiceImpl;
import org.jivesoftware.openfire.muc.spi.MUCPersistenceManager;
import org.jivesoftware.util.cache.ClusterTask;
import org.jivesoftware.util.cache.ExternalizableUtil;
import org.jivesoftware.util.NotFoundException;
import org.jivesoftware.util.Log;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
/**
* Task that will update a service configuring in the cluster node. When a service is update
* in a cluster node the rest of the cluster nodes will need to reread their configuration
* from the database.
*
* @author Daniel Henninger
*/
public class ServiceUpdatedEvent implements ClusterTask {
private String subdomain;
public ServiceUpdatedEvent() {
}
public ServiceUpdatedEvent(String subdomain) {
this.subdomain = subdomain;
}
public Object getResult() {
return null;
}
public void run() {
try {
MultiUserChatService service = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(subdomain);
if (service instanceof MultiUserChatServiceImpl) {
MUCPersistenceManager.refreshProperties(subdomain);
((MultiUserChatServiceImpl)service).initializeSettings();
}
else {
// Ok. We don't handle non default implementations for this. Why are we seeing it?
}
}
catch (NotFoundException e) {
// Hrm. We got an update for something that we don't have.
Log.warn("ServiceUpdatedEvent: Received update for service we are not running: "+subdomain);
}
}
public void writeExternal(ObjectOutput out) throws IOException {
ExternalizableUtil.getInstance().writeSafeUTF(out, subdomain);
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
subdomain = ExternalizableUtil.getInstance().readSafeUTF(in);
}
}
......@@ -13,29 +13,32 @@ package org.jivesoftware.openfire.muc.cluster;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.muc.HistoryStrategy;
import org.jivesoftware.openfire.muc.spi.MultiUserChatServerImpl;
import org.jivesoftware.openfire.muc.spi.MultiUserChatServiceImpl;
import org.jivesoftware.util.cache.ClusterTask;
import org.jivesoftware.util.cache.ExternalizableUtil;
import org.jivesoftware.util.NotFoundException;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
/**
* Cluster task that will update the history strategy used by the MultiUserChatServer
* Cluster task that will update the history strategy used by a MultiUserChatService
* service. It is currently not possible to edit the history strategy of a given room
* but only of the service. Therefore, this task will only update the service's strategy.
*
* @author Gaston Dombiak
*/
public class UpdateHistoryStrategy implements ClusterTask {
private String serviceName;
private int type;
private int maxNumber;
public UpdateHistoryStrategy() {
}
public UpdateHistoryStrategy(HistoryStrategy historyStrategy) {
public UpdateHistoryStrategy(String serviceName, HistoryStrategy historyStrategy) {
this.serviceName = serviceName;
type = historyStrategy.getType().ordinal();
maxNumber = historyStrategy.getMaxNumber();
}
......@@ -45,18 +48,25 @@ public class UpdateHistoryStrategy implements ClusterTask {
}
public void run() {
MultiUserChatServerImpl mucServer = (MultiUserChatServerImpl) XMPPServer.getInstance().getMultiUserChatServer();
HistoryStrategy strategy = mucServer.getHistoryStrategy();
strategy.setType(HistoryStrategy.Type.values()[type]);
strategy.setMaxNumber(maxNumber);
try {
MultiUserChatServiceImpl mucServer = (MultiUserChatServiceImpl) XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(serviceName);
HistoryStrategy strategy = mucServer.getHistoryStrategy();
strategy.setType(HistoryStrategy.Type.values()[type]);
strategy.setMaxNumber(maxNumber);
}
catch (NotFoundException e) {
throw new IllegalArgumentException("MUC service not found for subdomain: "+serviceName);
}
}
public void writeExternal(ObjectOutput out) throws IOException {
ExternalizableUtil.getInstance().writeSafeUTF(out, serviceName);
ExternalizableUtil.getInstance().writeInt(out, type);
ExternalizableUtil.getInstance().writeInt(out, maxNumber);
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
serviceName = ExternalizableUtil.getInstance().readSafeUTF(in);
type = ExternalizableUtil.getInstance().readInt(in);
maxNumber = ExternalizableUtil.getInstance().readInt(in);
}
......
......@@ -24,7 +24,6 @@ import org.xmpp.packet.PacketError;
import org.xmpp.packet.Presence;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
......@@ -116,8 +115,8 @@ public class IQAdminHandler {
// Check if the client is requesting or changing the list of moderators/members/etc.
if (!hasJID && !hasNick) {
// The client is requesting the list of moderators/members/participants/outcasts
for (Iterator items = itemsList.iterator(); items.hasNext();) {
item = (Element)items.next();
for (Object anItem : itemsList) {
item = (Element) anItem;
affiliation = item.attributeValue("affiliation");
roleAttribute = item.attributeValue("role");
// Create the result that will hold an item for each
......@@ -137,8 +136,7 @@ public class IQAdminHandler {
metaData.addAttribute("jid", jid);
}
}
else if ("member".equals(affiliation)) {
} else if ("member".equals(affiliation)) {
// The client is requesting the list of members
// In a members-only room members can get the list of members
if (!room.isMembersOnly()
......@@ -160,8 +158,7 @@ public class IQAdminHandler {
// Do nothing
}
}
}
else if ("moderator".equals(roleAttribute)) {
} else if ("moderator".equals(roleAttribute)) {
// The client is requesting the list of moderators
if (MUCRole.Affiliation.admin != senderRole.getAffiliation()
&& MUCRole.Affiliation.owner != senderRole.getAffiliation()) {
......@@ -174,8 +171,7 @@ public class IQAdminHandler {
metaData.addAttribute("nick", role.getNickname());
metaData.addAttribute("affiliation", role.getAffiliation().toString());
}
}
else if ("participant".equals(roleAttribute)) {
} else if ("participant".equals(roleAttribute)) {
// The client is requesting the list of participants
if (MUCRole.Role.moderator != senderRole.getRole()) {
throw new ForbiddenException();
......@@ -187,8 +183,7 @@ public class IQAdminHandler {
metaData.addAttribute("nick", role.getNickname());
metaData.addAttribute("affiliation", role.getAffiliation().toString());
}
}
else {
} else {
reply.setError(PacketError.Condition.bad_request);
}
}
......@@ -205,9 +200,9 @@ public class IQAdminHandler {
List<Presence> presences = new ArrayList<Presence>(itemsList.size());
// Collect the new affiliations or roles for the specified jids
for (Iterator items = itemsList.iterator(); items.hasNext();) {
for (Object anItem : itemsList) {
try {
item = (Element)items.next();
item = (Element) anItem;
target = (hasAffiliation ? item.attributeValue("affiliation") : item
.attributeValue("role"));
// jid could be of the form "full JID" or "bare JID" depending if we are
......@@ -215,8 +210,7 @@ public class IQAdminHandler {
if (hasJID) {
jid = new JID(item.attributeValue("jid"));
nick = null;
}
else {
} else {
// Get the JID based on the requested nick
nick = item.attributeValue("nick");
jid = room.getOccupant(nick).getUserAddress();
......@@ -227,18 +221,15 @@ public class IQAdminHandler {
if ("moderator".equals(target)) {
// Add the user as a moderator of the room based on the full JID
presences.add(room.addModerator(jid, senderRole));
}
else if ("participant".equals(target)) {
} else if ("participant".equals(target)) {
// Add the user as a participant of the room based on the full JID
presences.add(room.addParticipant(jid,
item.elementTextTrim("reason"),
senderRole));
}
else if ("visitor".equals(target)) {
} else if ("visitor".equals(target)) {
// Add the user as a visitor of the room based on the full JID
presences.add(room.addVisitor(jid, senderRole));
}
else if ("member".equals(target)) {
} else if ("member".equals(target)) {
// Add the user as a member of the room based on the bare JID
boolean hadAffiliation = room.getAffiliation(jid.toBareJID()) != MUCRole.Affiliation.none;
presences.addAll(room.addMember(jid.toBareJID(), nick, senderRole));
......@@ -247,17 +238,14 @@ public class IQAdminHandler {
if (!hadAffiliation && room.isMembersOnly()) {
room.sendInvitation(jid, null, senderRole, null);
}
}
else if ("outcast".equals(target)) {
} else if ("outcast".equals(target)) {
// Add the user as an outcast of the room based on the bare JID
presences.addAll(room.addOutcast(jid.toBareJID(), item.elementTextTrim("reason"), senderRole));
}
else if ("none".equals(target)) {
} else if ("none".equals(target)) {
if (hasAffiliation) {
// Set that this jid has a NONE affiliation based on the bare JID
presences.addAll(room.addNone(jid.toBareJID(), senderRole));
}
else {
} else {
// Kick the user from the room
if (MUCRole.Role.moderator != senderRole.getRole()) {
throw new ForbiddenException();
......@@ -265,8 +253,7 @@ public class IQAdminHandler {
presences.add(room.kickOccupant(jid, senderRole.getUserAddress(),
item.elementTextTrim("reason")));
}
}
else {
} else {
reply.setError(PacketError.Condition.bad_request);
}
}
......
......@@ -21,7 +21,7 @@ import org.jivesoftware.openfire.forms.spi.XFormFieldImpl;
import org.jivesoftware.openfire.muc.ConflictException;
import org.jivesoftware.openfire.muc.ForbiddenException;
import org.jivesoftware.openfire.muc.MUCRoom;
import org.jivesoftware.openfire.muc.MultiUserChatServer;
import org.jivesoftware.openfire.muc.MultiUserChatService;
import org.jivesoftware.util.ElementUtil;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
......@@ -43,10 +43,10 @@ import java.util.List;
class IQMUCRegisterHandler {
private static Element probeResult;
private MultiUserChatServer mucServer;
private MultiUserChatService mucService;
public IQMUCRegisterHandler(MultiUserChatServer mucServer) {
this.mucServer = mucServer;
public IQMUCRegisterHandler(MultiUserChatService mucService) {
this.mucService = mucService;
initialize();
}
......@@ -109,7 +109,7 @@ class IQMUCRegisterHandler {
MUCRoom room = null;
String name = packet.getTo().getNode();
if (name != null) {
room = mucServer.getChatRoom(name);
room = mucService.getChatRoom(name);
}
if (room == null) {
// The room doesn't exist so answer a NOT_FOUND error
......
......@@ -17,10 +17,9 @@ import org.jivesoftware.openfire.forms.FormField;
import org.jivesoftware.openfire.forms.spi.XDataFormImpl;
import org.jivesoftware.openfire.forms.spi.XFormFieldImpl;
import org.jivesoftware.openfire.muc.MUCRoom;
import org.jivesoftware.openfire.muc.MultiUserChatServer;
import org.jivesoftware.openfire.muc.MultiUserChatService;
import org.jivesoftware.openfire.resultsetmanager.ResultSet;
import org.jivesoftware.openfire.resultsetmanager.ResultSetImpl;
import org.jivesoftware.util.JiveGlobals;
import org.xmpp.packet.IQ;
import org.xmpp.packet.PacketError;
import org.xmpp.packet.PacketError.Condition;
......@@ -39,17 +38,17 @@ public class IQMUCSearchHandler
/**
* The MUC-server to extend with jabber:iq:search functionality.
*/
private final MultiUserChatServer mucServer;
private final MultiUserChatService mucService;
/**
* Creates a new instance of the search provider.
*
* @param mucServer
* @param mucService
* The server for which to return search results.
*/
public IQMUCSearchHandler(MultiUserChatServer mucServer)
public IQMUCSearchHandler(MultiUserChatService mucService)
{
this.mucServer = mucServer;
this.mucService = mucService;
}
/**
......@@ -142,7 +141,8 @@ public class IQMUCSearchHandler
boolean includePasswordProtectedRooms = true;
final Set<String> names = new HashSet<String>();
final Iterator<FormField> formFields = df.getFields();
@SuppressWarnings("unchecked")
final Iterator<FormField> formFields = df.getFields();
while (formFields.hasNext())
{
......@@ -213,7 +213,7 @@ public class IQMUCSearchHandler
// search for chatrooms matching the request params.
final List<MUCRoom> mucs = new ArrayList<MUCRoom>();
for (MUCRoom room : mucServer.getChatRooms())
for (MUCRoom room : mucService.getChatRooms())
{
boolean find = false;
......@@ -307,7 +307,6 @@ public class IQMUCSearchHandler
mucrsm = new ArrayList<MUCRoom>(searchResults);
}
ArrayList<XFormFieldImpl> fields = null;
final Element res = DocumentHelper.createElement(QName.get("query",
"jabber:iq:search"));
......@@ -315,7 +314,7 @@ public class IQMUCSearchHandler
boolean atLeastoneResult = false;
for (MUCRoom room : mucrsm)
{
fields = new ArrayList<XFormFieldImpl>();
ArrayList<XFormFieldImpl> fields = new ArrayList<XFormFieldImpl>();
XFormFieldImpl innerfield = new XFormFieldImpl("name");
innerfield.setType(FormField.TYPE_TEXT_SINGLE);
innerfield.addValue(room.getNaturalLanguageName());
......@@ -397,6 +396,7 @@ public class IQMUCSearchHandler
*
* @param mucs
* The unordered list that will be sorted.
* @return The sorted list of MUC rooms.
*/
private static List<MUCRoom> sortByUserAmount(List<MUCRoom> mucs)
{
......@@ -413,7 +413,7 @@ public class IQMUCSearchHandler
/**
* Checks if the room may be included in search results. This is almost
* identical to {@link MultiUserChatServerImpl#canDiscoverRoom(MUCRoom room)},
* identical to {@link MultiUserChatServiceImpl#canDiscoverRoom(MUCRoom room)},
* but that method is private and cannot be re-used here.
*
* @param room
......@@ -424,7 +424,7 @@ public class IQMUCSearchHandler
private static boolean canBeIncludedInResult(MUCRoom room)
{
// Check if locked rooms may be discovered
final boolean discoverLocked = JiveGlobals.getBooleanProperty("xmpp.muc.discover.locked", true);
final boolean discoverLocked = MUCPersistenceManager.getBooleanProperty(room.getMUCService().getServiceName(), "discover.locked", true);
if (!discoverLocked && room.isLocked())
{
......
......@@ -138,15 +138,14 @@ public class IQOwnerHandler {
private void handleItemsElement(List itemsList, MUCRole senderRole, IQ reply)
throws ForbiddenException, ConflictException {
Element item;
String affiliation = null;
boolean hasJID = ((Element)itemsList.get(0)).attributeValue("jid") != null;
boolean hasNick = ((Element)itemsList.get(0)).attributeValue("nick") != null;
// Check if the client is requesting or changing the list of owners/admin
if (!hasJID && !hasNick) {
// The client is requesting the list of owners or admins
for (Iterator items = itemsList.iterator(); items.hasNext();) {
item = (Element)items.next();
affiliation = item.attributeValue("affiliation");
for (Object anItem : itemsList) {
item = (Element) anItem;
String affiliation = item.attributeValue("affiliation");
// Create the result that will hold an item for each owner or admin
Element result = reply.setChildElement("query", "http://jabber.org/protocol/muc#owner");
......@@ -169,8 +168,7 @@ public class IQOwnerHandler {
// Do nothing
}
}
}
else if ("admin".equals(affiliation)) {
} else if ("admin".equals(affiliation)) {
// The client is requesting the list of admins
Element adminMetaData;
MUCRole role;
......@@ -189,8 +187,7 @@ public class IQOwnerHandler {
// Do nothing
}
}
}
else {
} else {
reply.setError(PacketError.Condition.bad_request);
}
}
......@@ -198,17 +195,16 @@ public class IQOwnerHandler {
else {
// The client is modifying the list of owners or admins
Map<String,String> jids = new HashMap<String,String>();
String bareJID = null;
String nick;
// Collect the new affiliations for the specified jids
for (Iterator items = itemsList.iterator(); items.hasNext();) {
for (Object anItem : itemsList) {
try {
item = (Element)items.next();
affiliation = item.attributeValue("affiliation");
item = (Element) anItem;
String affiliation = item.attributeValue("affiliation");
String bareJID;
if (hasJID) {
bareJID = new JID(item.attributeValue("jid")).toBareJID();
}
else {
} else {
// Get the bare JID based on the requested nick
nick = item.attributeValue("nick");
bareJID = room.getOccupant(nick).getUserAddress().toBareJID();
......@@ -236,19 +232,15 @@ public class IQOwnerHandler {
room.lock.readLock().unlock();
room.lock.writeLock().lock();
try {
String targetAffiliation = null;
for (Iterator<String> it = jids.keySet().iterator(); it.hasNext();) {
bareJID = it.next();
targetAffiliation = jids.get(bareJID);
for (String bareJID : jids.keySet()) {
String targetAffiliation = jids.get(bareJID);
if ("owner".equals(targetAffiliation)) {
// Add the new user as an owner of the room
presences.addAll(room.addOwner(bareJID, senderRole));
}
else if ("admin".equals(targetAffiliation)) {
} else if ("admin".equals(targetAffiliation)) {
// Add the new user as an admin of the room
presences.addAll(room.addAdmin(bareJID, senderRole));
}
else if ("member".equals(targetAffiliation)) {
} else if ("member".equals(targetAffiliation)) {
// Add the new user as a member of the room
boolean hadAffiliation = room.getAffiliation(bareJID) != MUCRole.Affiliation.none;
presences.addAll(room.addMember(bareJID, null, senderRole));
......@@ -257,8 +249,7 @@ public class IQOwnerHandler {
if (!hadAffiliation && room.isMembersOnly()) {
room.sendInvitation(new JID(bareJID), null, senderRole, null);
}
}
else if ("none".equals(targetAffiliation)) {
} else if ("none".equals(targetAffiliation)) {
// Set that this jid has a NONE affiliation
presences.addAll(room.addNone(bareJID, senderRole));
}
......@@ -366,7 +357,7 @@ public class IQOwnerHandler {
}
// Keep a registry of the updated presences
List presences = new ArrayList(admins.size() + owners.size());
List<Presence> presences = new ArrayList<Presence>(admins.size() + owners.size());
room.lock.writeLock().lock();
try {
......@@ -386,7 +377,7 @@ public class IQOwnerHandler {
if (field != null) {
values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1");
room.setCanOccupantsChangeSubject(("1".equals(booleanValue) ? true : false));
room.setCanOccupantsChangeSubject(("1".equals(booleanValue)));
}
field = completedForm.getField("muc#roomconfig_maxusers");
......@@ -409,14 +400,14 @@ public class IQOwnerHandler {
if (field != null) {
values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1");
room.setPublicRoom(("1".equals(booleanValue) ? true : false));
room.setPublicRoom(("1".equals(booleanValue)));
}
field = completedForm.getField("muc#roomconfig_persistentroom");
if (field != null) {
values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1");
boolean isPersistent = ("1".equals(booleanValue) ? true : false);
boolean isPersistent = ("1".equals(booleanValue));
// Delete the room from the DB if it's no longer persistent
if (room.isPersistent() && !isPersistent) {
MUCPersistenceManager.deleteFromDB(room);
......@@ -428,22 +419,21 @@ public class IQOwnerHandler {
if (field != null) {
values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1");
room.setModerated(("1".equals(booleanValue) ? true : false));
room.setModerated(("1".equals(booleanValue)));
}
field = completedForm.getField("muc#roomconfig_membersonly");
if (field != null) {
values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1");
presences.addAll(room.setMembersOnly(("1".equals(booleanValue) ?
true : false)));
presences.addAll(room.setMembersOnly(("1".equals(booleanValue))));
}
field = completedForm.getField("muc#roomconfig_allowinvites");
if (field != null) {
values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1");
room.setCanOccupantsInvite(("1".equals(booleanValue) ? true : false));
room.setCanOccupantsInvite(("1".equals(booleanValue)));
}
field = completedForm.getField("muc#roomconfig_passwordprotectedroom");
......@@ -469,35 +459,35 @@ public class IQOwnerHandler {
if (field != null) {
values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1");
room.setCanAnyoneDiscoverJID(("anyone".equals(booleanValue) ? true : false));
room.setCanAnyoneDiscoverJID(("anyone".equals(booleanValue)));
}
field = completedForm.getField("muc#roomconfig_enablelogging");
if (field != null) {
values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1");
room.setLogEnabled(("1".equals(booleanValue) ? true : false));
room.setLogEnabled(("1".equals(booleanValue)));
}
field = completedForm.getField("x-muc#roomconfig_reservednick");
if (field != null) {
values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1");
room.setLoginRestrictedToNickname(("1".equals(booleanValue) ? true : false));
room.setLoginRestrictedToNickname(("1".equals(booleanValue)));
}
field = completedForm.getField("x-muc#roomconfig_canchangenick");
if (field != null) {
values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1");
room.setChangeNickname(("1".equals(booleanValue) ? true : false));
room.setChangeNickname(("1".equals(booleanValue)));
}
field = completedForm.getField("x-muc#roomconfig_registration");
if (field != null) {
values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1");
room.setRegistrationEnabled(("1".equals(booleanValue) ? true : false));
room.setRegistrationEnabled(("1".equals(booleanValue)));
}
// Update the modification date to reflect the last time when the room's configuration
......@@ -546,8 +536,8 @@ public class IQOwnerHandler {
}
// Send the updated presences to the room occupants
for (Iterator it = presences.iterator(); it.hasNext();) {
room.send((Presence)it.next());
for (Object presence : presences) {
room.send((Presence) presence);
}
}
......@@ -653,7 +643,7 @@ public class IQOwnerHandler {
configurationForm = new XDataFormImpl(DataForm.TYPE_FORM);
configurationForm.setTitle(LocaleUtils.getLocalizedString("muc.form.conf.title"));
List params = new ArrayList();
List<String> params = new ArrayList<String>();
params.add(room.getName());
configurationForm.addInstruction(LocaleUtils.getLocalizedString("muc.form.conf.instruction", params));
......
......@@ -19,7 +19,7 @@ import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.cluster.NodeID;
import org.jivesoftware.openfire.muc.MUCRole;
import org.jivesoftware.openfire.muc.MUCRoom;
import org.jivesoftware.openfire.muc.MultiUserChatServer;
import org.jivesoftware.openfire.muc.MultiUserChatService;
import org.jivesoftware.openfire.muc.NotAllowedException;
import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.openfire.session.Session;
......@@ -58,7 +58,7 @@ public class LocalMUCRole implements MUCRole {
/**
* The chatserver that hosts this role.
*/
private MultiUserChatServer server;
private MultiUserChatService server;
/**
* The role.
......@@ -109,7 +109,7 @@ public class LocalMUCRole implements MUCRole {
* @param presence the presence sent by the user to join the room.
* @param packetRouter the packet router for sending messages from this role.
*/
public LocalMUCRole(MultiUserChatServer chatserver, LocalMUCRoom chatroom, String nickname,
public LocalMUCRole(MultiUserChatService chatserver, LocalMUCRoom chatroom, String nickname,
MUCRole.Role role, MUCRole.Affiliation affiliation, LocalMUCUser chatuser, Presence presence,
PacketRouter packetRouter)
{
......
......@@ -50,9 +50,9 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
public class LocalMUCRoom implements MUCRoom {
/**
* The server hosting the room.
* The service hosting the room.
*/
private MultiUserChatServerImpl server;
private MultiUserChatService mucService;
/**
* The occupants of the room accessible by the occupants nickname.
......@@ -101,7 +101,7 @@ public class LocalMUCRoom implements MUCRoom {
/**
* 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
* When a room is destroyed it is immediately removed from the MultiUserChatService 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.
*/
......@@ -149,15 +149,15 @@ public class LocalMUCRoom implements MUCRoom {
private String description;
/**
* Indicates if occupants are allowed to change the subject of the room.
* Indicates if occupants are allowed to change the subject of the room.
*/
private boolean canOccupantsChangeSubject = JiveGlobals.getBooleanProperty("muc.room.canOccupantsChangeSubject", false);
private boolean canOccupantsChangeSubject;
/**
* 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);
private int maxUsers;
/**
* List of roles of which presence will be broadcasted to the rest of the occupants. This
......@@ -169,32 +169,32 @@ public class LocalMUCRoom implements MUCRoom {
* 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);
private boolean publicRoom;
/**
* 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);
private boolean persistent;
/**
* 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);
private boolean moderated;
/**
* 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);
private boolean membersOnly;
/**
* Some rooms may restrict the occupants that are able to send invitations. Sending an
* 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);
private boolean canOccupantsInvite;
/**
* The password that every occupant should provide in order to enter the room.
......@@ -203,33 +203,33 @@ public class LocalMUCRoom implements MUCRoom {
/**
* Every presence packet can include the JID of every occupant unless the owner deactives this
* configuration.
* configuration.
*/
private boolean canAnyoneDiscoverJID = JiveGlobals.getBooleanProperty("muc.room.canAnyoneDiscoverJID", true);
private boolean canAnyoneDiscoverJID;
/**
* 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);
private boolean logEnabled;
/**
* 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);
private boolean loginRestrictedToNickname;
/**
* 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);
private boolean canChangeNickname;
/**
* 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);
private boolean registrationEnabled;
/**
* Internal component that handles IQ packets sent by the room owners.
......@@ -247,7 +247,7 @@ public class LocalMUCRoom implements MUCRoom {
* 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.
......@@ -284,13 +284,13 @@ public class LocalMUCRoom implements MUCRoom {
/**
* Create a new chat room.
*
* @param chatserver the server hosting the room.
*
* @param chatservice the service 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;
LocalMUCRoom(MultiUserChatService chatservice, String roomname, PacketRouter packetRouter) {
this.mucService = chatservice;
this.name = roomname;
this.naturalLanguageName = roomname;
this.description = roomname;
......@@ -299,8 +299,20 @@ public class LocalMUCRoom implements MUCRoom {
this.creationDate = new Date(startTime);
this.modificationDate = new Date(startTime);
this.emptyDate = new Date(startTime);
this.canOccupantsChangeSubject = MUCPersistenceManager.getBooleanProperty(mucService.getServiceName(), "room.canOccupantsChangeSubject", false);
this.maxUsers = MUCPersistenceManager.getIntProperty(mucService.getServiceName(), "room.maxUsers", 30);
this.publicRoom = MUCPersistenceManager.getBooleanProperty(mucService.getServiceName(), "room.publicRoom", true);
this.persistent = MUCPersistenceManager.getBooleanProperty(mucService.getServiceName(), "room.persistent", false);
this.moderated = MUCPersistenceManager.getBooleanProperty(mucService.getServiceName(), "room.moderated", false);
this.membersOnly = MUCPersistenceManager.getBooleanProperty(mucService.getServiceName(), "room.membersOnly", false);
this.canOccupantsInvite = MUCPersistenceManager.getBooleanProperty(mucService.getServiceName(), "room.canOccupantsInvite", false);
this.canAnyoneDiscoverJID = MUCPersistenceManager.getBooleanProperty(mucService.getServiceName(), "room.canAnyoneDiscoverJID", true);
this.logEnabled = MUCPersistenceManager.getBooleanProperty(mucService.getServiceName(), "room.logEnabled", false);
this.loginRestrictedToNickname = MUCPersistenceManager.getBooleanProperty(mucService.getServiceName(), "room.loginRestrictedToNickname", false);
this.canChangeNickname = MUCPersistenceManager.getBooleanProperty(mucService.getServiceName(), "room.canChangeNickname", true);
this.registrationEnabled = MUCPersistenceManager.getBooleanProperty(mucService.getServiceName(), "room.registrationEnabled", true);
// TODO Allow to set the history strategy from the configuration form?
roomHistory = new MUCRoomHistory(this, new HistoryStrategy(server.getHistoryStrategy()));
roomHistory = new MUCRoomHistory(this, new HistoryStrategy(mucService.getHistoryStrategy()));
this.iqOwnerHandler = new IQOwnerHandler(this, packetRouter);
this.iqAdminHandler = new IQAdminHandler(this, packetRouter);
// No one can join the room except the room's owner
......@@ -315,6 +327,18 @@ public class LocalMUCRoom implements MUCRoom {
return name;
}
public JID getJID() {
return new JID(getName(), getMUCService().getServiceDomain(), null);
}
public MultiUserChatService getMUCService() {
return mucService;
}
public void setMUCService(MultiUserChatService service) {
this.mucService = service;
}
public long getID() {
if (isPersistent() || isLogEnabled()) {
if (roomID == -1) {
......@@ -476,8 +500,8 @@ public class LocalMUCRoom implements MUCRoom {
role = MUCRole.Role.moderator;
affiliation = MUCRole.Affiliation.owner;
}
else if (server.getSysadmins().contains(user.getAddress().toBareJID())) {
// The user is a system administrator of the MUC service. Treat him as an owner
else if (mucService.getSysadmins().contains(user.getAddress().toBareJID())) {
// The user is a system administrator of the MUC service. Treat him as an owner
// although he won't appear in the list of owners
role = MUCRole.Role.moderator;
affiliation = MUCRole.Affiliation.owner;
......@@ -507,7 +531,7 @@ public class LocalMUCRoom implements MUCRoom {
affiliation = MUCRole.Affiliation.none;
}
// Create a new role for this user in this room
joinRole = new LocalMUCRole(server, this, nickname, role, affiliation, user, presence, router);
joinRole = new LocalMUCRole(mucService, this, nickname, role, affiliation, user, presence, router);
// Add the new user as an occupant of this room
occupants.put(nickname.toLowerCase(), joinRole);
// Update the tables of occupants based on the bare and full JID
......@@ -582,7 +606,7 @@ public class LocalMUCRoom implements MUCRoom {
// Update the date when the last occupant left the room
setEmptyDate(null);
// Fire event that occupant joined the room
server.fireOccupantJoined(getRole().getRoleAddress(), user.getAddress(), joinRole.getNickname());
MUCEventDispatcher.occupantJoined(getRole().getRoleAddress(), user.getAddress(), joinRole.getNickname());
return joinRole;
}
......@@ -619,13 +643,13 @@ public class LocalMUCRoom implements MUCRoom {
}
public void occupantAdded(OccupantAddedEvent event) {
// Do not add new occupant with one with same nickname already exists
// Do not add new occupant with one with same nickname already exists
if (occupants.containsKey(event.getNickname().toLowerCase())) {
// TODO Handle conflict of nicknames
return;
}
// Create a proxy for the occupant that joined the room from another cluster node
RemoteMUCRole joinRole = new RemoteMUCRole(server, event);
RemoteMUCRole joinRole = new RemoteMUCRole(mucService, event);
// Add the new user as an occupant of this room
occupants.put(event.getNickname().toLowerCase(), joinRole);
// Update the tables of occupants based on the bare and full JID
......@@ -641,7 +665,7 @@ public class LocalMUCRoom implements MUCRoom {
setEmptyDate(null);
if (event.isOriginator()) {
// Fire event that occupant joined the room
server.fireOccupantJoined(getRole().getRoleAddress(), event.getUserAddress(), joinRole.getNickname());
MUCEventDispatcher.occupantJoined(getRole().getRoleAddress(), event.getUserAddress(), joinRole.getNickname());
}
// Check if we need to send presences of the new occupant to occupants hosted by this JVM
if (event.isSendPresence()) {
......@@ -706,14 +730,14 @@ public class LocalMUCRoom implements MUCRoom {
// "unavailable" from the room to the owner including a <destroy/> element and reason
// (if provided) as defined under the "Destroying a Room" use case.
// Remove the room from the server only if there are no more occupants and the room is
// Remove the room from the service only if there are no more occupants and the room is
// not persistent
if (occupants.isEmpty() && !isPersistent()) {
endTime = System.currentTimeMillis();
if (event.isOriginator()) {
server.removeChatRoom(name);
mucService.removeChatRoom(name);
// Fire event that the room has been destroyed
server.fireRoomDestroyed(getRole().getRoleAddress());
MUCEventDispatcher.roomDestroyed(getRole().getRoleAddress());
}
}
if (occupants.isEmpty()) {
......@@ -750,7 +774,7 @@ public class LocalMUCRoom implements MUCRoom {
occupantsByFullJID.remove(userAddress);
if (originator) {
// Fire event that occupant left the room
server.fireOccupantLeft(getRole().getRoleAddress(), userAddress);
MUCEventDispatcher.occupantLeft(getRole().getRoleAddress(), userAddress);
}
}
......@@ -786,8 +810,8 @@ public class LocalMUCRoom implements MUCRoom {
// 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 server
server.removeChatRoom(name);
// Removes the room from the list of rooms hosted in the service
mucService.removeChatRoom(name);
}
}
finally {
......@@ -826,7 +850,7 @@ public class LocalMUCRoom implements MUCRoom {
// Remove the room from the DB if the room was persistent
MUCPersistenceManager.deleteFromDB(this);
// Fire event that the room has been destroyed
server.fireRoomDestroyed(getRole().getRoleAddress());
MUCEventDispatcher.roomDestroyed(getRole().getRoleAddress());
}
}
......@@ -860,7 +884,7 @@ public class LocalMUCRoom implements MUCRoom {
message.setFrom(senderRole.getRoleAddress());
send(message);
// Fire event that message was receibed by the room
server.fireMessageReceived(getRole().getRoleAddress(), senderRole.getUserAddress(),
MUCEventDispatcher.messageReceived(getRole().getRoleAddress(), senderRole.getUserAddress(),
senderRole.getNickname(), message);
}
......@@ -920,16 +944,16 @@ public class LocalMUCRoom implements MUCRoom {
}
// Broadcast presence to occupants hosted by other cluster nodes
BroascastPresenceRequest request = new BroascastPresenceRequest(this, presence);
BroadcastPresenceRequest request = new BroadcastPresenceRequest(this, presence);
CacheFactory.doClusterTask(request);
// Broadcast presence to occupants connected to this JVM
request = new BroascastPresenceRequest(this, presence);
request = new BroadcastPresenceRequest(this, presence);
request.setOriginator(true);
request.run();
}
public void broadcast(BroascastPresenceRequest presenceRequest) {
public void broadcast(BroadcastPresenceRequest presenceRequest) {
String jid = null;
Presence presence = presenceRequest.getPresence();
Element frag = presence.getChildElement("x", "http://jabber.org/protocol/muc#user");
......@@ -958,16 +982,16 @@ public class LocalMUCRoom implements MUCRoom {
private void broadcast(Message message) {
// Broadcast message to occupants hosted by other cluster nodes
BroascastMessageRequest request = new BroascastMessageRequest(this, message, occupants.size());
BroadcastMessageRequest request = new BroadcastMessageRequest(this, message, occupants.size());
CacheFactory.doClusterTask(request);
// Broadcast message to occupants connected to this JVM
request = new BroascastMessageRequest(this, message, occupants.size());
request = new BroadcastMessageRequest(this, message, occupants.size());
request.setOriginator(true);
request.run();
}
public void broadcast(BroascastMessageRequest messageRequest) {
public void broadcast(BroadcastMessageRequest messageRequest) {
Message message = messageRequest.getMessage();
// Add message to the room history
roomHistory.addMessage(message);
......@@ -994,9 +1018,9 @@ public class LocalMUCRoom implements MUCRoom {
senderAddress = senderRole.getUserAddress();
}
// Log the conversation
server.logConversation(this, message, senderAddress);
mucService.logConversation(this, message, senderAddress);
}
server.messageBroadcastedTo(messageRequest.getOccupants());
mucService.messageBroadcastedTo(messageRequest.getOccupants());
}
/**
......@@ -1059,7 +1083,7 @@ public class LocalMUCRoom implements MUCRoom {
public JID getRoleAddress() {
if (crJID == null) {
crJID = new JID(room.getName(), server.getServiceDomain(), null, true);
crJID = new JID(room.getName(), mucService.getServiceDomain(), null, true);
}
return crJID;
}
......@@ -1084,7 +1108,7 @@ public class LocalMUCRoom implements MUCRoom {
* Updates all the presences of the given user with the new affiliation and role information. Do
* nothing if the given jid is not present in the room. If the user has joined the room from
* several client resources, all his/her occupants' presences will be updated.
*
*
* @param bareJID the bare jid of the user to update his/her role.
* @param newAffiliation the new affiliation for the JID.
* @param newRole the new role for the JID.
......@@ -1134,7 +1158,7 @@ public class LocalMUCRoom implements MUCRoom {
/**
* Updates the presence of the given user with the new role information. Do nothing if the given
* jid is not present in the room.
*
*
* @param jid the full jid of the user to update his/her role.
* @param newRole the new role for the JID.
* @return the updated presence of the user or null if none.
......@@ -1554,7 +1578,7 @@ public class LocalMUCRoom implements MUCRoom {
occupantRole.changeNickname(changeNickname.getNewNick());
if (changeNickname.isOriginator()) {
// Fire event that user changed his nickname
server.fireNicknameChanged(getRole().getRoleAddress(), occupantRole.getUserAddress(),
MUCEventDispatcher.nicknameChanged(getRole().getRoleAddress(), occupantRole.getUserAddress(),
changeNickname.getOldNick(), changeNickname.getNewNick());
}
// Associate the existing MUCRole with the new nickname
......@@ -1764,7 +1788,7 @@ public class LocalMUCRoom implements MUCRoom {
* Kicks the occupant from the room. This means that the occupant will receive an unavailable
* presence with the actor that initiated the kick (if any). The occupant will also be removed
* from the occupants lists.
*
*
* @param kickPresence the presence of the occupant to kick from the room.
* @param actorJID The JID of the actor that initiated the kick or <tt>null</tt> if the info
* was not provided.
......@@ -1926,11 +1950,11 @@ public class LocalMUCRoom implements MUCRoom {
public boolean wasSavedToDB() {
return isPersistent() && savedToDB;
}
public void setSavedToDB(boolean saved) {
this.savedToDB = saved;
}
public void setPersistent(boolean persistent) {
this.persistent = persistent;
}
......@@ -2135,6 +2159,7 @@ public class LocalMUCRoom implements MUCRoom {
ExternalizableUtil.getInstance().writeLong(out, emptyDate.getTime());
}
ExternalizableUtil.getInstance().writeBoolean(out, savedToDB);
ExternalizableUtil.getInstance().writeSafeUTF(out, mucService.getServiceName());
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
......@@ -2169,15 +2194,19 @@ public class LocalMUCRoom implements MUCRoom {
emptyDate = new Date(ExternalizableUtil.getInstance().readLong(in));
}
savedToDB = ExternalizableUtil.getInstance().readBoolean(in);
server = (MultiUserChatServerImpl) XMPPServer.getInstance().getMultiUserChatServer();
roomHistory = new MUCRoomHistory(this, new HistoryStrategy(server.getHistoryStrategy()));
String subdomain = ExternalizableUtil.getInstance().readSafeUTF(in);
try {
mucService = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(subdomain);
}
catch (NotFoundException e) {
throw new IllegalArgumentException("MUC service not found for subdomain: " + subdomain);
}
roomHistory = new MUCRoomHistory(this, new HistoryStrategy(mucService.getHistoryStrategy()));
PacketRouter packetRouter = XMPPServer.getInstance().getPacketRouter();
this.iqOwnerHandler = new IQOwnerHandler(this, packetRouter);
this.iqAdminHandler = new IQAdminHandler(this, packetRouter);
server = (MultiUserChatServerImpl) XMPPServer.getInstance().getMultiUserChatServer();
router = packetRouter;
}
......@@ -2210,6 +2239,7 @@ public class LocalMUCRoom implements MUCRoom {
modificationDate = otherRoom.modificationDate;
emptyDate = otherRoom.emptyDate;
savedToDB = otherRoom.savedToDB;
mucService = otherRoom.mucService;
}
/*
......
......@@ -40,7 +40,7 @@ import java.util.concurrent.ConcurrentHashMap;
public class LocalMUCUser implements MUCUser {
/** The chat server this user belongs to. */
private MultiUserChatServer server;
private MultiUserChatService server;
/** Real system XMPPAddress for the user. */
private JID realjid;
......@@ -59,14 +59,14 @@ public class LocalMUCUser implements MUCUser {
/**
* Create a new chat user.
*
* @param chatserver the server the user belongs to.
* @param chatservice the service the user belongs to.
* @param packetRouter the router for sending packets from this user.
* @param jid the real address of the user
*/
LocalMUCUser(MultiUserChatServerImpl chatserver, PacketRouter packetRouter, JID jid) {
LocalMUCUser(MultiUserChatService chatservice, PacketRouter packetRouter, JID jid) {
this.realjid = jid;
this.router = packetRouter;
this.server = chatserver;
this.server = chatservice;
}
/**
......@@ -274,6 +274,7 @@ public class LocalMUCUser implements MUCUser {
// Try to keep the list of extensions sent together with the
// message invitation. These extensions will be sent to the
// invitees.
@SuppressWarnings("unchecked")
List<Element> extensions = new ArrayList<Element>(packet
.getElement().elements());
extensions.remove(userInfo);
......
......@@ -13,17 +13,20 @@ package org.jivesoftware.openfire.muc.spi;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.openfire.PacketRouter;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.muc.MUCRole;
import org.jivesoftware.openfire.muc.MUCRoom;
import org.jivesoftware.openfire.muc.MultiUserChatServer;
import org.jivesoftware.openfire.muc.MultiUserChatService;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils;
import org.jivesoftware.util.NotFoundException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* A manager responsible for ensuring room persistence. There are different ways to make a room
......@@ -57,24 +60,29 @@ public class MUCPersistenceManager {
"lockedDate, emptyDate, canChangeSubject, maxUsers, publicRoom, moderated, membersOnly, " +
"canInvite, roomPassword, canDiscoverJID, logEnabled, subject, rolesToBroadcast, " +
"useReservedNick, canChangeNick, canRegister " +
"FROM mucRoom WHERE emptyDate IS NULL or emptyDate > ?";
"FROM mucRoom WHERE serviceID=? AND (emptyDate IS NULL or emptyDate > ?)";
private static final String LOAD_ALL_AFFILIATIONS =
"SELECT roomID,jid,affiliation FROM mucAffiliation";
"SELECT mucAffiliation.roomID,mucAffiliation.jid,mucAffiliation.affiliation " +
"FROM mucAffiliation,mucRoom WHERE mucAffiliation.roomID = mucRoom.roomID AND mucRoom.serviceID=?";
private static final String LOAD_ALL_MEMBERS =
"SELECT roomID,jid, nickname FROM mucMember";
"SELECT mucMember.roomID,mucMember.jid,mucMember.nickname FROM mucMember,mucRoom " +
"WHERE mucMember.roomID = mucRoom.roomID AND mucRoom.serviceID=?";
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";
"SELECT mucConversationLog.roomID, mucConversationLog.sender, mucConversationLog.nickname, " +
"mucConversationLog.logTime, mucConversationLog.subject, mucConversationLog.body FROM " +
"mucConversationLog, mucRoom WHERE mucConversationLog.roomID = mucRoom.roomID AND " +
"mucRoom.serviceID=? AND mucConversationLog.logTime>? AND (mucConversationLog.nickname IS NOT NULL " +
"OR mucConversationLog.subject IS NOT NULL) ORDER BY mucConversationLog.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, " +
"INSERT INTO mucRoom (serviceID, roomID, creationDate, modificationDate, name, naturalName, " +
"description, lockedDate, emptyDate, canChangeSubject, maxUsers, publicRoom, moderated, " +
"membersOnly, canInvite, roomPassword, canDiscoverJID, logEnabled, subject, " +
"rolesToBroadcast, useReservedNick, canChangeNick, canRegister) VALUES (?,?,?,?,?,?,?,?," +
"rolesToBroadcast, useReservedNick, canChangeNick, canRegister) VALUES (?,?,?,?,?,?,?,?,?," +
"?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
private static final String UPDATE_SUBJECT =
"UPDATE mucRoom SET subject=? WHERE roomID=?";
......@@ -100,11 +108,13 @@ public class MUCPersistenceManager {
"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 (?,?,?,?,?,?)";
/* Map of subdomains to their associated properties */
private static ConcurrentHashMap<String,MUCServiceProperties> propertyMaps = new ConcurrentHashMap<String,MUCServiceProperties>();
/**
* Returns the reserved room nickname for the bare JID in a given room or null if none.
*
......@@ -167,15 +177,15 @@ public class MUCPersistenceManager {
else {
room.setEmptyDate(null);
}
room.setCanOccupantsChangeSubject(rs.getInt(8) == 1 ? true : false);
room.setCanOccupantsChangeSubject(rs.getInt(8) == 1);
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.setPublicRoom(rs.getInt(10) == 1);
room.setModerated(rs.getInt(11) == 1);
room.setMembersOnly(rs.getInt(12) == 1);
room.setCanOccupantsInvite(rs.getInt(13) == 1);
room.setPassword(rs.getString(14));
room.setCanAnyoneDiscoverJID(rs.getInt(15) == 1 ? true : false);
room.setLogEnabled(rs.getInt(16) == 1 ? true : false);
room.setCanAnyoneDiscoverJID(rs.getInt(15) == 1);
room.setLogEnabled(rs.getInt(16) == 1);
room.setSubject(rs.getString(17));
List<String> rolesToBroadcast = new ArrayList<String>();
String roles = Integer.toBinaryString(rs.getInt(18));
......@@ -189,9 +199,9 @@ public class MUCPersistenceManager {
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.setLoginRestrictedToNickname(rs.getInt(19) == 1);
room.setChangeNickname(rs.getInt(20) == 1);
room.setRegistrationEnabled(rs.getInt(21) == 1);
room.setPersistent(true);
rs.close();
pstmt.close();
......@@ -322,37 +332,41 @@ public class MUCPersistenceManager {
}
else {
pstmt = con.prepareStatement(ADD_ROOM);
pstmt.setLong(1, room.getID());
pstmt.setString(2, StringUtils.dateToMillis(room.getCreationDate()));
pstmt.setString(3, StringUtils.dateToMillis(room.getModificationDate()));
pstmt.setString(4, room.getName());
pstmt.setString(5, room.getNaturalLanguageName());
pstmt.setString(6, room.getDescription());
pstmt.setString(7, StringUtils.dateToMillis(room.getLockedDate()));
pstmt.setLong(1, XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatServiceID(room.getMUCService().getServiceName()));
pstmt.setLong(2, room.getID());
pstmt.setString(3, StringUtils.dateToMillis(room.getCreationDate()));
pstmt.setString(4, StringUtils.dateToMillis(room.getModificationDate()));
pstmt.setString(5, room.getName());
pstmt.setString(6, room.getNaturalLanguageName());
pstmt.setString(7, room.getDescription());
pstmt.setString(8, StringUtils.dateToMillis(room.getLockedDate()));
Date emptyDate = room.getEmptyDate();
if (emptyDate == null) {
pstmt.setString(8, null);
pstmt.setString(9, null);
}
else {
pstmt.setString(8, StringUtils.dateToMillis(emptyDate));
}
pstmt.setInt(9, (room.canOccupantsChangeSubject() ? 1 : 0));
pstmt.setInt(10, room.getMaxUsers());
pstmt.setInt(11, (room.isPublicRoom() ? 1 : 0));
pstmt.setInt(12, (room.isModerated() ? 1 : 0));
pstmt.setInt(13, (room.isMembersOnly() ? 1 : 0));
pstmt.setInt(14, (room.canOccupantsInvite() ? 1 : 0));
pstmt.setString(15, room.getPassword());
pstmt.setInt(16, (room.canAnyoneDiscoverJID() ? 1 : 0));
pstmt.setInt(17, (room.isLogEnabled() ? 1 : 0));
pstmt.setString(18, room.getSubject());
pstmt.setInt(19, marshallRolesToBroadcast(room));
pstmt.setInt(20, (room.isLoginRestrictedToNickname() ? 1 : 0));
pstmt.setInt(21, (room.canChangeNickname() ? 1 : 0));
pstmt.setInt(22, (room.isRegistrationEnabled() ? 1 : 0));
pstmt.setString(9, StringUtils.dateToMillis(emptyDate));
}
pstmt.setInt(10, (room.canOccupantsChangeSubject() ? 1 : 0));
pstmt.setInt(11, room.getMaxUsers());
pstmt.setInt(12, (room.isPublicRoom() ? 1 : 0));
pstmt.setInt(13, (room.isModerated() ? 1 : 0));
pstmt.setInt(14, (room.isMembersOnly() ? 1 : 0));
pstmt.setInt(15, (room.canOccupantsInvite() ? 1 : 0));
pstmt.setString(16, room.getPassword());
pstmt.setInt(17, (room.canAnyoneDiscoverJID() ? 1 : 0));
pstmt.setInt(18, (room.isLogEnabled() ? 1 : 0));
pstmt.setString(19, room.getSubject());
pstmt.setInt(20, marshallRolesToBroadcast(room));
pstmt.setInt(21, (room.isLoginRestrictedToNickname() ? 1 : 0));
pstmt.setInt(22, (room.canChangeNickname() ? 1 : 0));
pstmt.setInt(23, (room.isRegistrationEnabled() ? 1 : 0));
pstmt.executeUpdate();
}
}
catch (NotFoundException e) {
Log.error(e);
}
catch (SQLException sqle) {
Log.error(sqle);
}
......@@ -415,19 +429,20 @@ public class MUCPersistenceManager {
* @param packetRouter the PacketRouter that loaded rooms will use to send packets.
* @return a collection with all the persistent rooms.
*/
public static Collection<LocalMUCRoom> loadRoomsFromDB(MultiUserChatServer chatserver,
public static Collection<LocalMUCRoom> loadRoomsFromDB(MultiUserChatService chatserver,
Date emptyDate, PacketRouter packetRouter) {
Connection con = null;
PreparedStatement pstmt = null;
Map<Long, LocalMUCRoom> rooms = new HashMap<Long, LocalMUCRoom>();
try {
Long serviceID = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatServiceID(chatserver.getServiceName());
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_ALL_ROOMS);
pstmt.setString(1, StringUtils.dateToMillis(emptyDate));
pstmt.setLong(1, serviceID);
pstmt.setString(2, StringUtils.dateToMillis(emptyDate));
ResultSet rs = pstmt.executeQuery();
LocalMUCRoom room = null;
while (rs.next()) {
room = new LocalMUCRoom(chatserver, rs.getString(4), packetRouter);
LocalMUCRoom room = new LocalMUCRoom(chatserver, rs.getString(4), packetRouter);
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
......@@ -440,15 +455,15 @@ public class MUCPersistenceManager {
else {
room.setEmptyDate(null);
}
room.setCanOccupantsChangeSubject(rs.getInt(9) == 1 ? true : false);
room.setCanOccupantsChangeSubject(rs.getInt(9) == 1);
room.setMaxUsers(rs.getInt(10));
room.setPublicRoom(rs.getInt(11) == 1 ? true : false);
room.setModerated(rs.getInt(12) == 1 ? true : false);
room.setMembersOnly(rs.getInt(13) == 1 ? true : false);
room.setCanOccupantsInvite(rs.getInt(14) == 1 ? true : false);
room.setPublicRoom(rs.getInt(11) == 1);
room.setModerated(rs.getInt(12) == 1);
room.setMembersOnly(rs.getInt(13) == 1);
room.setCanOccupantsInvite(rs.getInt(14) == 1);
room.setPassword(rs.getString(15));
room.setCanAnyoneDiscoverJID(rs.getInt(16) == 1 ? true : false);
room.setLogEnabled(rs.getInt(17) == 1 ? true : false);
room.setCanAnyoneDiscoverJID(rs.getInt(16) == 1);
room.setLogEnabled(rs.getInt(17) == 1);
room.setSubject(rs.getString(18));
List<String> rolesToBroadcast = new ArrayList<String>();
String roles = Integer.toBinaryString(rs.getInt(19));
......@@ -462,9 +477,9 @@ public class MUCPersistenceManager {
rolesToBroadcast.add("visitor");
}
room.setRolesToBroadcastPresence(rolesToBroadcast);
room.setLoginRestrictedToNickname(rs.getInt(20) == 1 ? true : false);
room.setChangeNickname(rs.getInt(21) == 1 ? true : false);
room.setRegistrationEnabled(rs.getInt(22) == 1 ? true : false);
room.setLoginRestrictedToNickname(rs.getInt(20) == 1);
room.setChangeNickname(rs.getInt(21) == 1);
room.setRegistrationEnabled(rs.getInt(22) == 1);
room.setPersistent(true);
rooms.put(room.getID(), room);
}
......@@ -474,11 +489,12 @@ public class MUCPersistenceManager {
pstmt = con.prepareStatement(LOAD_ALL_HISTORY);
// Recreate the history until two days ago
long from = System.currentTimeMillis() - (86400000 * 2);
pstmt.setString(1, StringUtils.dateToMillis(new Date(from)));
pstmt.setLong(1, serviceID);
pstmt.setString(2, StringUtils.dateToMillis(new Date(from)));
// Load the rooms conversations from the last two days
rs = pstmt.executeQuery();
while (rs.next()) {
room = (LocalMUCRoom) rooms.get(rs.getLong(1));
LocalMUCRoom room = rooms.get(rs.getLong(1));
// Skip to the next position if the room does not exist
if (room == null) {
continue;
......@@ -516,12 +532,13 @@ public class MUCPersistenceManager {
}
pstmt = con.prepareStatement(LOAD_ALL_AFFILIATIONS);
pstmt.setLong(1, serviceID);
rs = pstmt.executeQuery();
while (rs.next()) {
long roomID = rs.getLong(1);
String jid = rs.getString(2);
MUCRole.Affiliation affiliation = MUCRole.Affiliation.valueOf(rs.getInt(3));
room = (LocalMUCRoom) rooms.get(roomID);
LocalMUCRoom room = rooms.get(roomID);
// Skip to the next position if the room does not exist
if (room == null) {
continue;
......@@ -550,9 +567,10 @@ public class MUCPersistenceManager {
pstmt.close();
pstmt = con.prepareStatement(LOAD_ALL_MEMBERS);
pstmt.setLong(1, serviceID);
rs = pstmt.executeQuery();
while (rs.next()) {
room = (LocalMUCRoom) rooms.get(rs.getLong(1));
LocalMUCRoom room = rooms.get(rs.getLong(1));
// Skip to the next position if the room does not exist
if (room == null) {
continue;
......@@ -566,6 +584,9 @@ public class MUCPersistenceManager {
}
rs.close();
}
catch (NotFoundException e) {
Log.error(e);
}
catch (SQLException sqle) {
Log.error(sqle);
}
......@@ -959,4 +980,249 @@ public class MUCPersistenceManager {
buffer.append((room.canBroadcastPresence("visitor") ? "1" : "0"));
return Integer.parseInt(buffer.toString(), 2);
}
/**
* Returns a Jive property.
*
* @param subdomain the subdomain of the service to retrieve a property from
* @param name the name of the property to return.
* @return the property value specified by name.
*/
public static String getProperty(String subdomain, String name) {
MUCServiceProperties properties = propertyMaps.get(subdomain);
if (properties == null) {
properties = new MUCServiceProperties(subdomain);
propertyMaps.put(subdomain, properties);
}
return properties.get(name);
}
/**
* Returns a Jive property. If the specified property doesn't exist, the
* <tt>defaultValue</tt> will be returned.
*
* @param subdomain the subdomain of the service to retrieve a property from
* @param name the name of the property to return.
* @param defaultValue value returned if the property doesn't exist.
* @return the property value specified by name.
*/
public static String getProperty(String subdomain, String name, String defaultValue) {
MUCServiceProperties properties = propertyMaps.get(subdomain);
if (properties == null) {
properties = new MUCServiceProperties(subdomain);
propertyMaps.put(subdomain, properties);
}
String value = properties.get(name);
if (value != null) {
return value;
}
else {
return defaultValue;
}
}
/**
* Returns an integer value Jive property. If the specified property doesn't exist, the
* <tt>defaultValue</tt> will be returned.
*
* @param subdomain the subdomain of the service to retrieve a property from
* @param name the name of the property to return.
* @param defaultValue value returned if the property doesn't exist or was not
* a number.
* @return the property value specified by name or <tt>defaultValue</tt>.
*/
public static int getIntProperty(String subdomain, String name, int defaultValue) {
String value = getProperty(subdomain, name);
if (value != null) {
try {
return Integer.parseInt(value);
}
catch (NumberFormatException nfe) {
// Ignore.
}
}
return defaultValue;
}
/**
* Returns a long value Jive property. If the specified property doesn't exist, the
* <tt>defaultValue</tt> will be returned.
*
* @param subdomain the subdomain of the service to retrieve a property from
* @param name the name of the property to return.
* @param defaultValue value returned if the property doesn't exist or was not
* a number.
* @return the property value specified by name or <tt>defaultValue</tt>.
*/
public static long getLongProperty(String subdomain, String name, long defaultValue) {
String value = getProperty(subdomain, name);
if (value != null) {
try {
return Long.parseLong(value);
}
catch (NumberFormatException nfe) {
// Ignore.
}
}
return defaultValue;
}
/**
* Returns a boolean value Jive property.
*
* @param subdomain the subdomain of the service to retrieve a property from
* @param name the name of the property to return.
* @return true if the property value exists and is set to <tt>"true"</tt> (ignoring case).
* Otherwise <tt>false</tt> is returned.
*/
public static boolean getBooleanProperty(String subdomain, String name) {
return Boolean.valueOf(getProperty(subdomain, name));
}
/**
* Returns a boolean value Jive property. If the property doesn't exist, the <tt>defaultValue</tt>
* will be returned.
*
* If the specified property can't be found, or if the value is not a number, the
* <tt>defaultValue</tt> will be returned.
*
* @param subdomain the subdomain of the service to retrieve a property from
* @param name the name of the property to return.
* @param defaultValue value returned if the property doesn't exist.
* @return true if the property value exists and is set to <tt>"true"</tt> (ignoring case).
* Otherwise <tt>false</tt> is returned.
*/
public static boolean getBooleanProperty(String subdomain, String name, boolean defaultValue) {
String value = getProperty(subdomain, name);
if (value != null) {
return Boolean.valueOf(value);
}
else {
return defaultValue;
}
}
/**
* Return all immediate children property names of a parent Jive property as a list of strings,
* or an empty list if there are no children. For example, given
* the properties <tt>X.Y.A</tt>, <tt>X.Y.B</tt>, <tt>X.Y.C</tt> and <tt>X.Y.C.D</tt>, then
* the immediate child properties of <tt>X.Y</tt> are <tt>A</tt>, <tt>B</tt>, and
* <tt>C</tt> (<tt>C.D</tt> would not be returned using this method).<p>
*
* @param subdomain the subdomain of the service to retrieve a property from
* @param parent the root "node" of the properties to retrieve
* @return a List of all immediate children property names (Strings).
*/
public static List<String> getPropertyNames(String subdomain, String parent) {
MUCServiceProperties properties = propertyMaps.get(subdomain);
if (properties == null) {
properties = new MUCServiceProperties(subdomain);
propertyMaps.put(subdomain, properties);
}
return new ArrayList<String>(properties.getChildrenNames(parent));
}
/**
* Return all immediate children property values of a parent Jive property as a list of strings,
* or an empty list if there are no children. For example, given
* the properties <tt>X.Y.A</tt>, <tt>X.Y.B</tt>, <tt>X.Y.C</tt> and <tt>X.Y.C.D</tt>, then
* the immediate child properties of <tt>X.Y</tt> are <tt>X.Y.A</tt>, <tt>X.Y.B</tt>, and
* <tt>X.Y.C</tt> (the value of <tt>X.Y.C.D</tt> would not be returned using this method).<p>
*
* @param subdomain the subdomain of the service to retrieve a property from
* @param parent the name of the parent property to return the children for.
* @return all child property values for the given parent.
*/
public static List<String> getProperties(String subdomain, String parent) {
MUCServiceProperties properties = propertyMaps.get(subdomain);
if (properties == null) {
properties = new MUCServiceProperties(subdomain);
propertyMaps.put(subdomain, properties);
}
Collection<String> propertyNames = properties.getChildrenNames(parent);
List<String> values = new ArrayList<String>();
for (String propertyName : propertyNames) {
String value = getProperty(subdomain, propertyName);
if (value != null) {
values.add(value);
}
}
return values;
}
/**
* Returns all MUC service property names.
*
* @param subdomain the subdomain of the service to retrieve a property from
* @return a List of all property names (Strings).
*/
public static List<String> getPropertyNames(String subdomain) {
MUCServiceProperties properties = propertyMaps.get(subdomain);
if (properties == null) {
properties = new MUCServiceProperties(subdomain);
propertyMaps.put(subdomain, properties);
}
return new ArrayList<String>(properties.getPropertyNames());
}
/**
* Sets a Jive property. If the property doesn't already exists, a new
* one will be created.
*
* @param subdomain the subdomain of the service to set a property for
* @param name the name of the property being set.
* @param value the value of the property being set.
*/
public static void setProperty(String subdomain, String name, String value) {
MUCServiceProperties properties = propertyMaps.get(subdomain);
if (properties == null) {
properties = new MUCServiceProperties(subdomain);
}
properties.put(name, value);
propertyMaps.put(subdomain, properties);
}
/**
* Sets multiple Jive properties at once. If a property doesn't already exists, a new
* one will be created.
*
* @param subdomain the subdomain of the service to set properties for
* @param propertyMap a map of properties, keyed on property name.
*/
public static void setProperties(String subdomain, Map<String, String> propertyMap) {
MUCServiceProperties properties = propertyMaps.get(subdomain);
if (properties == null) {
properties = new MUCServiceProperties(subdomain);
}
properties.putAll(propertyMap);
propertyMaps.put(subdomain, properties);
}
/**
* Deletes a Jive property. If the property doesn't exist, the method
* does nothing. All children of the property will be deleted as well.
*
* @param subdomain the subdomain of the service to delete a property from
* @param name the name of the property to delete.
*/
public static void deleteProperty(String subdomain, String name) {
MUCServiceProperties properties = propertyMaps.get(subdomain);
if (properties == null) {
properties = new MUCServiceProperties(subdomain);
}
properties.remove(name);
propertyMaps.put(subdomain, properties);
}
/**
* Resets (reloads) the properties for a specified subdomain.
*
* @param subdomain the subdomain of the service to reload properties for.
*/
public static void refreshProperties(String subdomain) {
propertyMaps.replace(subdomain, new MUCServiceProperties(subdomain));
}
}
\ No newline at end of file
/**
* $RCSfile$
* $Revision: 9307 $
* $Date: 2007-10-12 18:35:17 -0400 (Fri, 12 Oct 2007) $
*
* Copyright (C) 2008 Jive Software. All rights reserved.
*
* This software is the proprietary information of Jive Software.
* Use is subject to license terms.
*/
package org.jivesoftware.openfire.muc.spi;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.NotFoundException;
import org.jivesoftware.openfire.XMPPServer;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.*;
/**
* Retrieves and stores MUC service properties. Properties are stored in the database.
*
* @author Daniel Henninger
*/
public class MUCServiceProperties implements Map<String, String> {
private static final String LOAD_PROPERTIES = "SELECT name, propValue FROM mucServiceProp WHERE serviceID=?";
private static final String INSERT_PROPERTY = "INSERT INTO mucServiceProp(name, propValue) VALUES(?,?,?)";
private static final String UPDATE_PROPERTY = "UPDATE mucServiceProp SET propValue=? WHERE serviceID=? AND name=?";
private static final String DELETE_PROPERTY = "DELETE FROM mucServiceProp WHERE serviceID=? AND name=?";
private String subdomain;
private Long serviceID;
private Map<String, String> properties;
public MUCServiceProperties(String subdomain) {
this.subdomain = subdomain;
if (properties == null) {
properties = new ConcurrentHashMap<String, String>();
}
else {
properties.clear();
}
try {
serviceID = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatServiceID(subdomain);
}
catch (NotFoundException e) {
Log.debug("MUCServiceProperties: Unable to find service ID for subdomain "+subdomain);
}
loadProperties();
}
public int size() {
return properties.size();
}
public void clear() {
throw new UnsupportedOperationException();
}
public boolean isEmpty() {
return properties.isEmpty();
}
public boolean containsKey(Object key) {
return properties.containsKey(key);
}
public boolean containsValue(Object value) {
return properties.containsValue(value);
}
public Collection<String> values() {
return Collections.unmodifiableCollection(properties.values());
}
public void putAll(Map<? extends String, ? extends String> t) {
for (Map.Entry<? extends String, ? extends String> entry : t.entrySet() ) {
put(entry.getKey(), entry.getValue());
}
}
public Set<Map.Entry<String, String>> entrySet() {
return Collections.unmodifiableSet(properties.entrySet());
}
public Set<String> keySet() {
return Collections.unmodifiableSet(properties.keySet());
}
public String get(Object key) {
return properties.get(key);
}
/**
* Return all children property names of a parent property as a Collection
* of String objects. For example, given the properties <tt>X.Y.A</tt>,
* <tt>X.Y.B</tt>, and <tt>X.Y.C</tt>, then the child properties of
* <tt>X.Y</tt> are <tt>X.Y.A</tt>, <tt>X.Y.B</tt>, and <tt>X.Y.C</tt>. The method
* is not recursive; ie, it does not return children of children.
*
* @param parentKey the name of the parent property.
* @return all child property names for the given parent.
*/
public Collection<String> getChildrenNames(String parentKey) {
Collection<String> results = new HashSet<String>();
for (String key : properties.keySet()) {
if (key.startsWith(parentKey + ".")) {
if (key.equals(parentKey)) {
continue;
}
int dotIndex = key.indexOf(".", parentKey.length()+1);
if (dotIndex < 1) {
if (!results.contains(key)) {
results.add(key);
}
}
else {
String name = parentKey + key.substring(parentKey.length(), dotIndex);
results.add(name);
}
}
}
return results;
}
/**
* Returns all property names as a Collection of String values.
*
* @return all property names.
*/
public Collection<String> getPropertyNames() {
return properties.keySet();
}
public String remove(Object key) {
String value;
synchronized (this) {
value = properties.remove(key);
// Also remove any children.
Collection<String> propNames = getPropertyNames();
for (String name : propNames) {
if (name.startsWith((String)key)) {
properties.remove(name);
}
}
deleteProperty((String)key);
}
// Generate event.
Map<String, Object> params = Collections.emptyMap();
MUCServicePropertyEventDispatcher.dispatchEvent(subdomain, (String)key, MUCServicePropertyEventDispatcher.EventType.property_deleted, params);
// TODO: Send cluster update.
return value;
}
void localRemove(String key) {
properties.remove(key);
// Also remove any children.
Collection<String> propNames = getPropertyNames();
for (String name : propNames) {
if (name.startsWith(key)) {
properties.remove(name);
}
}
// Generate event.
Map<String, Object> params = Collections.emptyMap();
MUCServicePropertyEventDispatcher.dispatchEvent(subdomain, key, MUCServicePropertyEventDispatcher.EventType.property_deleted, params);
}
public String put(String key, String value) {
if (key == null || value == null) {
throw new NullPointerException("Key or value cannot be null. Key=" +
key + ", value=" + value);
}
if (key.endsWith(".")) {
key = key.substring(0, key.length()-1);
}
key = key.trim();
String result;
synchronized (this) {
if (properties.containsKey(key)) {
if (!properties.get(key).equals(value)) {
updateProperty(key, value);
}
}
else {
insertProperty(key, value);
}
result = properties.put(key, value);
}
// Generate event.
Map<String, Object> params = new HashMap<String, Object>();
params.put("value", value);
MUCServicePropertyEventDispatcher.dispatchEvent(subdomain, key, MUCServicePropertyEventDispatcher.EventType.property_set, params);
// TODO: Send cluster update.
return result;
}
void localPut(String key, String value) {
properties.put(key, value);
// Generate event.
Map<String, Object> params = new HashMap<String, Object>();
params.put("value", value);
MUCServicePropertyEventDispatcher.dispatchEvent(subdomain, key, MUCServicePropertyEventDispatcher.EventType.property_set, params);
}
public String getProperty(String name, String defaultValue) {
String value = properties.get(name);
if (value != null) {
return value;
}
else {
return defaultValue;
}
}
public boolean getBooleanProperty(String name) {
return Boolean.valueOf(get(name));
}
public boolean getBooleanProperty(String name, boolean defaultValue) {
String value = get(name);
if (value != null) {
return Boolean.valueOf(value);
}
else {
return defaultValue;
}
}
private void insertProperty(String name, String value) {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(INSERT_PROPERTY);
pstmt.setLong(1, serviceID);
pstmt.setString(2, name);
pstmt.setString(3, value);
pstmt.executeUpdate();
}
catch (SQLException e) {
Log.error(e);
}
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); }
}
}
private void updateProperty(String name, String value) {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(UPDATE_PROPERTY);
pstmt.setString(1, value);
pstmt.setLong(2, serviceID);
pstmt.setString(3, name);
pstmt.executeUpdate();
}
catch (SQLException e) {
Log.error(e);
}
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); }
}
}
private void deleteProperty(String name) {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(DELETE_PROPERTY);
pstmt.setLong(1, serviceID);
pstmt.setString(2, name);
pstmt.executeUpdate();
}
catch (SQLException e) {
Log.error(e);
}
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); }
}
}
private void loadProperties() {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_PROPERTIES);
pstmt.setLong(1, serviceID);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
String name = rs.getString(1);
String value = rs.getString(2);
properties.put(name, value);
}
rs.close();
}
catch (Exception e) {
Log.error(e);
}
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); }
}
}
}
\ No newline at end of file
/**
* $RCSfile$
* $Revision: 8589 $
* $Date: 2007-06-21 16:08:03 -0400 (Thu, 21 Jun 2007) $
*
* 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.
*/
package org.jivesoftware.openfire.muc.spi;
import org.jivesoftware.util.Log;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* Dispatches property events. Each event has a {@link EventType type}
* and optional parameters, as follows:<p>
*
* <table border="1">
* <tr><th>Event Type</th><th>Extra Params</th></tr>
* <tr><td>{@link EventType#property_set property_set}</td><td>A param named <tt>value</tt> that
* has the value of the property set.</td></tr>
* <tr><td>{@link EventType#property_deleted property_deleted}</td><td><i>None</i></td></tr>
* </table>
*
* @author Daniel Henninger
*/
public class MUCServicePropertyEventDispatcher {
private static Set<MUCServicePropertyEventListener> listeners =
new CopyOnWriteArraySet<MUCServicePropertyEventListener>();
private MUCServicePropertyEventDispatcher() {
// Not instantiable.
}
/**
* Registers a listener to receive events.
*
* @param listener the listener.
*/
public static void addListener(MUCServicePropertyEventListener listener) {
if (listener == null) {
throw new NullPointerException();
}
listeners.add(listener);
}
/**
* Unregisters a listener to receive events.
*
* @param listener the listener.
*/
public static void removeListener(MUCServicePropertyEventListener listener) {
listeners.remove(listener);
}
/**
* Dispatches an event to all listeners.
*
* @param service the subdomain of the MUC service the property is set for.
* @param property the property.
* @param eventType the event type.
* @param params event parameters.
*/
public static void dispatchEvent(String service, String property, EventType eventType, Map<String, Object> params) {
for (MUCServicePropertyEventListener listener : listeners) {
try {
switch (eventType) {
case property_set: {
listener.propertySet(service, property, params);
break;
}
case property_deleted: {
listener.propertyDeleted(service, property, params);
break;
}
default:
break;
}
}
catch (Exception e) {
Log.error(e);
}
}
}
/**
* Represents valid event types.
*/
public enum EventType {
/**
* A property was set.
*/
property_set,
/**
* A property was deleted.
*/
property_deleted
}
}
\ No newline at end of file
/**
* $RCSfile$
* $Revision: 7175 $
* $Date: 2007-02-16 14:50:15 -0500 (Fri, 16 Feb 2007) $
*
* 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.
*/
package org.jivesoftware.openfire.muc.spi;
import java.util.Map;
/**
* Interface to listen for property events. Use the
* {@link org.jivesoftware.openfire.muc.spi.MUCServicePropertyEventDispatcher#addListener(MUCServicePropertyEventListener)}
* method to register for events.
*
* @author Daniel Henninger
*/
public interface MUCServicePropertyEventListener {
/**
* A property was set. The parameter map <tt>params</tt> will contain the
* the value of the property under the key <tt>value</tt>.
*
* @param service the subdomain of the service the property was set on.
* @param property the name of the property.
* @param params event parameters.
*/
public void propertySet(String service, String property, Map<String, Object> params);
/**
* A property was deleted.
*
* @param service the subdomain of the service the property was deleted from.
* @param property the name of the property deleted.
* @param params event parameters.
*/
public void propertyDeleted(String service, String property, Map<String, Object> params);
}
\ No newline at end of file
/**
* $RCSfile: MultiUserChatServerImpl.java,v $
* $Revision: 3036 $
* $Date: 2005-11-07 15:15:00 -0300 (Mon, 07 Nov 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.openfire.muc.spi;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.jivesoftware.openfire.*;
import org.jivesoftware.openfire.cluster.ClusterManager;
import org.jivesoftware.openfire.disco.*;
import org.jivesoftware.openfire.forms.DataForm;
import org.jivesoftware.openfire.forms.FormField;
import org.jivesoftware.openfire.forms.spi.XDataFormImpl;
import org.jivesoftware.openfire.forms.spi.XFormFieldImpl;
import org.jivesoftware.openfire.muc.*;
import org.jivesoftware.openfire.muc.cluster.*;
import org.jivesoftware.openfire.resultsetmanager.ResultSet;
import org.jivesoftware.util.*;
import org.jivesoftware.util.cache.CacheFactory;
import org.xmpp.component.ComponentManager;
import org.xmpp.component.Component;
import org.xmpp.packet.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
/**
* Implements the chat server as a cached memory resident chat server. The server is also
* responsible for responding Multi-User Chat disco requests as well as removing inactive users from
* the rooms after a period of time and to maintain a log of the conversation in the rooms that
* require to log their conversations. The conversations log is saved to the database using a
* separate process<p>
*
* Temporary rooms are held in memory as long as they have occupants. They will be destroyed after
* the last occupant left the room. On the other hand, persistent rooms are always present in memory
* even after the last occupant left the room. In order to keep memory clean of persistent rooms that
* have been forgotten or abandoned this class includes a clean up process. The clean up process
* will remove from memory rooms that haven't had occupants for a while. Moreover, forgotten or
* abandoned rooms won't be loaded into memory when the Multi-User Chat service starts up.
*
* @author Gaston Dombiak
*/
public class MultiUserChatServiceImpl implements Component, MultiUserChatService,
ServerItemsProvider, DiscoInfoProvider, DiscoItemsProvider {
private static final FastDateFormat dateFormatter = FastDateFormat
.getInstance(JiveConstants.XMPP_DELAY_DATETIME_FORMAT, TimeZone.getTimeZone("UTC"));
/**
* The time to elapse between clearing of idle chat users.
*/
private int user_timeout = 300000;
/**
* The number of milliseconds a user must be idle before he/she gets kicked from all the rooms.
*/
private int user_idle = -1;
/**
* Task that kicks idle users from the rooms.
*/
private UserTimeoutTask userTimeoutTask;
/**
* The time to elapse between logging the room conversations.
*/
private int log_timeout = 300000;
/**
* The number of messages to log on each run of the logging process.
*/
private int log_batch_size = 50;
/**
* Task that flushes room conversation logs to the database.
*/
private LogConversationTask logConversationTask;
/**
* the chat service's hostname (subdomain)
*/
private String chatServiceName = null;
/**
* the chat service's description
*/
private String chatDescription = null;
/**
* chatrooms managed by this manager, table: key room name (String); value ChatRoom
*/
private Map<String, LocalMUCRoom> rooms = new ConcurrentHashMap<String, LocalMUCRoom>();
/**
* Chat users managed by this manager. This includes only users connected to this JVM.
* That means that when running inside of a cluster each node will have its own manager
* that in turn will keep its own list of locally connected.
*
* table: key user jid (XMPPAddress); value ChatUser
*/
private Map<JID, LocalMUCUser> users = new ConcurrentHashMap<JID, LocalMUCUser>();
private HistoryStrategy historyStrategy;
private RoutingTable routingTable = null;
/**
* The packet router for the server.
*/
private PacketRouter router = null;
/**
* The handler of packets with namespace jabber:iq:register for the server.
*/
private IQMUCRegisterHandler registerHandler = null;
/**
* The handler of search requests ('jabber:iq:search' namespace).
*/
private IQMUCSearchHandler searchHandler = null;
/**
* The total time all agents took to chat *
*/
public long totalChatTime;
/**
* Timer to monitor chatroom participants. If they've been idle for too long, probe for
* presence.
*/
private Timer timer = new Timer("MUC cleanup");
/**
* Flag that indicates if the service should provide information about locked rooms when
* handling service discovery requests.
* Note: Setting this flag in false is not compliant with the spec. A user may try to join a
* locked room thinking that the room doesn't exist because the user didn't discover it before.
*/
private boolean allowToDiscoverLockedRooms = true;
/**
* Returns the permission policy for creating rooms. A true value means that not anyone can
* create a room, only the JIDs listed in <code>allowedToCreate</code> are allowed to create
* rooms.
*/
private boolean roomCreationRestricted = false;
/**
* Bare jids of users that are allowed to create MUC rooms. An empty list means that anyone can
* create a room.
*/
private List<String> allowedToCreate = new CopyOnWriteArrayList<String>();
/**
* Bare jids of users that are system administrators of the MUC service. A sysadmin has the same
* permissions as a room owner.
*/
private List<String> sysadmins = new CopyOnWriteArrayList<String>();
/**
* Queue that holds the messages to log for the rooms that need to log their conversations.
*/
private Queue<ConversationLogEntry> logQueue = new LinkedBlockingQueue<ConversationLogEntry>();
/**
* Max number of hours that a persistent room may be empty before the service removes the
* room from memory. Unloaded rooms will exist in the database and may be loaded by a user
* request. Default time limit is: 30 days.
*/
private long emptyLimit = 30 * 24;
/**
* Task that removes rooms from memory that have been without activity for a period of time. A
* room is considered without activity when no occupants are present in the room for a while.
*/
private CleanupTask cleanupTask;
/**
* The time to elapse between each rooms cleanup. Default frequency is 60 minutes.
*/
private static final long CLEANUP_FREQUENCY = 60 * 60 * 1000;
/**
* Total number of received messages in all rooms since the last reset. The counter
* is reset each time the Statistic makes a sampling.
*/
private AtomicInteger inMessages = new AtomicInteger(0);
/**
* Total number of broadcasted messages in all rooms since the last reset. The counter
* is reset each time the Statistic makes a sampling.
*/
private AtomicLong outMessages = new AtomicLong(0);
/**
* Flag that indicates if MUC service is enabled.
*/
private boolean serviceEnabled = true;
/**
* Create a new group chat server.
*
* @param subdomain Subdomain portion of the conference services (for example, conference for conference.example.org)
* @param description Short description of service for disco and such.
*/
public MultiUserChatServiceImpl(String subdomain, String description) {
this.chatServiceName = subdomain;
if (description != null && description.trim().length() > 0) {
this.chatDescription = description;
}
else {
this.chatDescription = LocaleUtils.getLocalizedString("muc.service-name");
}
historyStrategy = new HistoryStrategy(null);
initialize(XMPPServer.getInstance());
}
public String getDescription() {
return chatDescription;
}
public void setDescription(String desc) {
this.chatDescription = desc;
}
public void processPacket(Packet packet) {
if (!isServiceEnabled()) {
return;
}
// The MUC service will receive all the packets whose domain matches the domain of the MUC
// service. This means that, for instance, a disco request should be responded by the
// service itself instead of relying on the server to handle the request.
try {
// Check if the packet is a disco request or a packet with namespace iq:register
if (packet instanceof IQ) {
if (process((IQ)packet)) {
return;
}
}
// The packet is a normal packet that should possibly be sent to the room
JID receipient = packet.getTo();
String roomName = receipient != null ? receipient.getNode() : null;
getChatUser(packet.getFrom(), roomName).process(packet);
}
catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
/**
* Returns true if the IQ packet was processed. This method should only process disco packets
* as well as jabber:iq:register packets sent to the MUC service.
*
* @param iq the IQ packet to process.
* @return true if the IQ packet was processed.
*/
private boolean process(IQ iq) {
Element childElement = iq.getChildElement();
String namespace = null;
// Ignore IQs of type ERROR
if (IQ.Type.error == iq.getType()) {
return false;
}
if (iq.getTo().getResource() != null) {
// Ignore IQ packets sent to room occupants
return false;
}
if (childElement != null) {
namespace = childElement.getNamespaceURI();
}
if ("jabber:iq:register".equals(namespace)) {
IQ reply = registerHandler.handleIQ(iq);
router.route(reply);
}
else if ("jabber:iq:search".equals(namespace)) {
IQ reply = searchHandler.handleIQ(iq);
router.route(reply);
}
else if ("http://jabber.org/protocol/disco#info".equals(namespace)) {
// TODO MUC should have an IQDiscoInfoHandler of its own when MUC becomes
// a component
IQ reply = XMPPServer.getInstance().getIQDiscoInfoHandler().handleIQ(iq);
router.route(reply);
}
else if ("http://jabber.org/protocol/disco#items".equals(namespace)) {
// TODO MUC should have an IQDiscoItemsHandler of its own when MUC becomes
// a component
IQ reply = XMPPServer.getInstance().getIQDiscoItemsHandler().handleIQ(iq);
router.route(reply);
}
else {
return false;
}
return true;
}
public void initialize(JID jid, ComponentManager componentManager) {
}
public void shutdown() {
}
public String getServiceDomain() {
return chatServiceName + "." + XMPPServer.getInstance().getServerInfo().getXMPPDomain();
}
public JID getAddress() {
return new JID(null, getServiceDomain(), null, true);
}
/**
* Probes the presence of any user who's last packet was sent more than 5 minute ago.
*/
private class UserTimeoutTask extends TimerTask {
/**
* Remove any user that has been idle for longer than the user timeout time.
*/
public void run() {
checkForTimedOutUsers();
}
}
private void checkForTimedOutUsers() {
final long deadline = System.currentTimeMillis() - user_idle;
for (LocalMUCUser user : users.values()) {
try {
// If user is not present in any room then remove the user from
// the list of users
if (!user.isJoined()) {
removeUser(user.getAddress());
continue;
}
// Do nothing if this feature is disabled (i.e USER_IDLE equals -1)
if (user_idle == -1) {
return;
}
if (user.getLastPacketTime() < deadline) {
// Kick the user from all the rooms that he/she had previuosly joined
MUCRoom room;
Presence kickedPresence;
for (LocalMUCRole role : user.getRoles()) {
room = role.getChatRoom();
try {
kickedPresence =
room.kickOccupant(user.getAddress(), null, null);
// Send the updated presence to the room occupants
room.send(kickedPresence);
}
catch (NotAllowedException e) {
// Do nothing since we cannot kick owners or admins
}
}
}
}
catch (Throwable e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
}
/**
* Logs the conversation of the rooms that have this feature enabled.
*/
private class LogConversationTask extends TimerTask {
public void run() {
try {
logConversation();
}
catch (Throwable e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
}
private void logConversation() {
ConversationLogEntry entry;
boolean success;
for (int index = 0; index <= log_batch_size && !logQueue.isEmpty(); index++) {
entry = logQueue.poll();
if (entry != null) {
success = MUCPersistenceManager.saveConversationLogEntry(entry);
if (!success) {
logQueue.add(entry);
}
}
}
}
/**
* Logs all the remaining conversation log entries to the database. Use this method to force
* saving all the conversation log entries before the service becomes unavailable.
*/
private void logAllConversation() {
ConversationLogEntry entry;
while (!logQueue.isEmpty()) {
entry = logQueue.poll();
if (entry != null) {
MUCPersistenceManager.saveConversationLogEntry(entry);
}
}
}
/**
* Removes from memory rooms that have been without activity for a period of time. A room is
* considered without activity when no occupants are present in the room for a while.
*/
private class CleanupTask extends TimerTask {
public void run() {
if (ClusterManager.isClusteringStarted() && !ClusterManager.isSeniorClusterMember()) {
// Do nothing if we are in a cluster and this JVM is not the senior cluster member
return;
}
try {
cleanupRooms();
}
catch (Throwable e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
}
private void cleanupRooms() {
for (MUCRoom room : rooms.values()) {
if (room.getEmptyDate() != null && room.getEmptyDate().before(getCleanupDate())) {
removeChatRoom(room.getName());
}
}
}
public MUCRoom getChatRoom(String roomName, JID userjid) throws NotAllowedException {
LocalMUCRoom room;
boolean loaded = false;
boolean created = false;
synchronized (roomName.intern()) {
room = rooms.get(roomName);
if (room == null) {
room = new LocalMUCRoom(this, roomName, router);
// If the room is persistent load the configuration values from the DB
try {
// Try to load the room's configuration from the database (if the room is
// persistent but was added to the DB after the server was started up or the
// room may be an old room that was not present in memory)
MUCPersistenceManager.loadFromDB(room);
loaded = true;
}
catch (IllegalArgumentException e) {
// The room does not exist so check for creation permissions
// Room creation is always allowed for sysadmin
if (isRoomCreationRestricted() &&
!sysadmins.contains(userjid.toBareJID())) {
// The room creation is only allowed for certain JIDs
if (!allowedToCreate.contains(userjid.toBareJID())) {
// The user is not in the list of allowed JIDs to create a room so raise
// an exception
throw new NotAllowedException();
}
}
room.addFirstOwner(userjid.toBareJID());
created = true;
}
rooms.put(roomName, room);
}
}
if (created) {
// Fire event that a new room has been created
MUCEventDispatcher.roomCreated(room.getRole().getRoleAddress());
}
if (loaded || created) {
// Notify other cluster nodes that a new room is available
CacheFactory.doClusterTask(new RoomAvailableEvent(room));
for (MUCRole role : room.getOccupants()) {
if (role instanceof LocalMUCRole) {
CacheFactory.doClusterTask(new OccupantAddedEvent(room, role));
}
}
}
return room;
}
public MUCRoom getChatRoom(String roomName) {
boolean loaded = false;
LocalMUCRoom room = rooms.get(roomName);
if (room == null) {
// Check if the room exists in the databclase and was not present in memory
synchronized (roomName.intern()) {
room = rooms.get(roomName);
if (room == null) {
room = new LocalMUCRoom(this, roomName, router);
// If the room is persistent load the configuration values from the DB
try {
// Try to load the room's configuration from the database (if the room is
// persistent but was added to the DB after the server was started up or the
// room may be an old room that was not present in memory)
MUCPersistenceManager.loadFromDB(room);
loaded = true;
rooms.put(roomName, room);
}
catch (IllegalArgumentException e) {
// The room does not exist so do nothing
room = null;
}
}
}
}
if (loaded) {
// Notify other cluster nodes that a new room is available
CacheFactory.doClusterTask(new RoomAvailableEvent(room));
}
return room;
}
public LocalMUCRoom getLocalChatRoom(String roomName) {
return rooms.get(roomName);
}
public List<MUCRoom> getChatRooms() {
return new ArrayList<MUCRoom>(rooms.values());
}
public boolean hasChatRoom(String roomName) {
return getChatRoom(roomName) != null;
}
public void removeChatRoom(String roomName) {
removeChatRoom(roomName, true);
}
/**
* Notification message indicating that the specified chat room was
* removed from some other cluster member.
*
* @param room the removed room in another cluster node.
*/
public void chatRoomRemoved(LocalMUCRoom room) {
removeChatRoom(room.getName(), false);
}
/**
* Notification message indicating that a chat room has been created
* in another cluster member.
*
* @param room the created room in another cluster node.
*/
public void chatRoomAdded(LocalMUCRoom room) {
rooms.put(room.getName(), room);
}
private void removeChatRoom(String roomName, boolean notify) {
MUCRoom room = rooms.remove(roomName);
if (room != null) {
totalChatTime += room.getChatLength();
if (notify) {
// Notify other cluster nodes that a room has been removed
CacheFactory.doClusterTask(new RoomRemovedEvent((LocalMUCRoom)room));
}
}
}
public String getServiceName() {
return chatServiceName;
}
public String getName() {
return getServiceName();
}
public HistoryStrategy getHistoryStrategy() {
return historyStrategy;
}
/**
* Removes a user from all chat rooms.
*
* @param jabberID The user's normal jid, not the chat nickname jid.
*/
private void removeUser(JID jabberID) {
LocalMUCUser user = users.remove(jabberID);
if (user != null) {
for (LocalMUCRole role : user.getRoles()) {
try {
role.getChatRoom().leaveRoom(role);
}
catch (Exception e) {
Log.error(e);
}
}
}
}
/**
* Obtain a chat user by XMPPAddress. Only returns users that are connected to this JVM.
*
* @param userjid The XMPPAddress of the user.
* @param roomName name of the room to receive the packet.
* @return The chatuser corresponding to that XMPPAddress.
*/
private MUCUser getChatUser(JID userjid, String roomName) {
if (router == null) {
throw new IllegalStateException("Not initialized");
}
LocalMUCUser user;
synchronized (userjid.toString().intern()) {
user = users.get(userjid);
if (user == null) {
if (roomName != null) {
// Check if the JID belong to a user hosted in another cluster node
LocalMUCRoom localMUCRoom = rooms.get(roomName);
if (localMUCRoom != null) {
MUCRole occupant = localMUCRoom.getOccupantByFullJID(userjid);
if (occupant != null && !occupant.isLocal()) {
return new RemoteMUCUser(userjid, localMUCRoom);
}
}
}
user = new LocalMUCUser(this, router, userjid);
users.put(userjid, user);
}
}
return user;
}
public Collection<MUCRole> getMUCRoles(JID user) {
List<MUCRole> userRoles = new ArrayList<MUCRole>();
for (LocalMUCRoom room : rooms.values()) {
MUCRole role = room.getOccupantByFullJID(user);
if (role != null) {
userRoles.add(role);
}
}
return userRoles;
}
/**
* Returns the limit date after which rooms without activity will be removed from memory.
*
* @return the limit date after which rooms without activity will be removed from memory.
*/
private Date getCleanupDate() {
return new Date(System.currentTimeMillis() - (emptyLimit * 3600000));
}
public void setKickIdleUsersTimeout(int timeout) {
if (this.user_timeout == timeout) {
return;
}
// Cancel the existing task because the timeout has changed
if (userTimeoutTask != null) {
userTimeoutTask.cancel();
}
this.user_timeout = timeout;
// Create a new task and schedule it with the new timeout
userTimeoutTask = new UserTimeoutTask();
timer.schedule(userTimeoutTask, user_timeout, user_timeout);
// Set the new property value
MUCPersistenceManager.setProperty(chatServiceName, "tasks.user.timeout", Integer.toString(timeout));
}
public int getKickIdleUsersTimeout() {
return user_timeout;
}
public void setUserIdleTime(int idleTime) {
if (this.user_idle == idleTime) {
return;
}
this.user_idle = idleTime;
// Set the new property value
MUCPersistenceManager.setProperty(chatServiceName, "tasks.user.idle", Integer.toString(idleTime));
}
public int getUserIdleTime() {
return user_idle;
}
public void setLogConversationsTimeout(int timeout) {
if (this.log_timeout == timeout) {
return;
}
// Cancel the existing task because the timeout has changed
if (logConversationTask != null) {
logConversationTask.cancel();
}
this.log_timeout = timeout;
// Create a new task and schedule it with the new timeout
logConversationTask = new LogConversationTask();
timer.schedule(logConversationTask, log_timeout, log_timeout);
// Set the new property value
MUCPersistenceManager.setProperty(chatServiceName, "tasks.log.timeout", Integer.toString(timeout));
}
public int getLogConversationsTimeout() {
return log_timeout;
}
public void setLogConversationBatchSize(int size) {
if (this.log_batch_size == size) {
return;
}
this.log_batch_size = size;
// Set the new property value
MUCPersistenceManager.setProperty(chatServiceName, "tasks.log.batchsize", Integer.toString(size));
}
public int getLogConversationBatchSize() {
return log_batch_size;
}
public Collection<String> getUsersAllowedToCreate() {
return allowedToCreate;
}
public Collection<String> getSysadmins() {
return sysadmins;
}
public void addSysadmin(String userJID) {
sysadmins.add(userJID.trim().toLowerCase());
// CopyOnWriteArray does not allow sorting, so do sorting in temp list.
ArrayList<String> tempList = new ArrayList<String>(sysadmins);
Collections.sort(tempList);
sysadmins = new CopyOnWriteArrayList<String>(tempList);
// Update the config.
String[] jids = new String[sysadmins.size()];
jids = sysadmins.toArray(jids);
MUCPersistenceManager.setProperty(chatServiceName, "sysadmin.jid", fromArray(jids));
}
public void removeSysadmin(String userJID) {
sysadmins.remove(userJID.trim().toLowerCase());
// Update the config.
String[] jids = new String[sysadmins.size()];
jids = sysadmins.toArray(jids);
MUCPersistenceManager.setProperty(chatServiceName, "sysadmin.jid", fromArray(jids));
}
/**
* Returns the flag that indicates if the service should provide information about locked rooms
* when handling service discovery requests.
*
* @return true if the service should provide information about locked rooms.
*/
public boolean isAllowToDiscoverLockedRooms() {
return allowToDiscoverLockedRooms;
}
/**
* Sets the flag that indicates if the service should provide information about locked rooms
* when handling service discovery requests.
* Note: Setting this flag in false is not compliant with the spec. A user may try to join a
* locked room thinking that the room doesn't exist because the user didn't discover it before.
*
* @param allowToDiscoverLockedRooms if the service should provide information about locked
* rooms.
*/
public void setAllowToDiscoverLockedRooms(boolean allowToDiscoverLockedRooms) {
this.allowToDiscoverLockedRooms = allowToDiscoverLockedRooms;
MUCPersistenceManager.setProperty(chatServiceName, "discover.locked",
Boolean.toString(allowToDiscoverLockedRooms));
}
public boolean isRoomCreationRestricted() {
return roomCreationRestricted;
}
public void setRoomCreationRestricted(boolean roomCreationRestricted) {
this.roomCreationRestricted = roomCreationRestricted;
MUCPersistenceManager.setProperty(chatServiceName, "create.anyone", Boolean.toString(roomCreationRestricted));
}
public void addUserAllowedToCreate(String userJID) {
// Update the list of allowed JIDs to create MUC rooms. Since we are updating the instance
// variable there is no need to restart the service
allowedToCreate.add(userJID.trim().toLowerCase());
// CopyOnWriteArray does not allow sorting, so do sorting in temp list.
ArrayList<String> tempList = new ArrayList<String>(allowedToCreate);
Collections.sort(tempList);
allowedToCreate = new CopyOnWriteArrayList<String>(tempList);
// Update the config.
String[] jids = new String[allowedToCreate.size()];
jids = allowedToCreate.toArray(jids);
MUCPersistenceManager.setProperty(chatServiceName, "create.jid", fromArray(jids));
}
public void removeUserAllowedToCreate(String userJID) {
// Update the list of allowed JIDs to create MUC rooms. Since we are updating the instance
// variable there is no need to restart the service
allowedToCreate.remove(userJID.trim().toLowerCase());
// Update the config.
String[] jids = new String[allowedToCreate.size()];
jids = allowedToCreate.toArray(jids);
MUCPersistenceManager.setProperty(chatServiceName, "create.jid", fromArray(jids));
}
public void initialize(XMPPServer server) {
initializeSettings();
routingTable = server.getRoutingTable();
router = server.getPacketRouter();
// Configure the handler of iq:register packets
registerHandler = new IQMUCRegisterHandler(this);
// Configure the handler of jabber:iq:search packets
searchHandler = new IQMUCSearchHandler(this);
}
public void initializeSettings() {
serviceEnabled = MUCPersistenceManager.getBooleanProperty(chatServiceName, "enabled", true);
// Trigger the strategy to load itself from the context
historyStrategy.setContext(chatServiceName, "history");
// Load the list of JIDs that are sysadmins of the MUC service
String property = MUCPersistenceManager.getProperty(chatServiceName, "sysadmin.jid");
String[] jids;
sysadmins.clear();
if (property != null) {
jids = property.split(",");
for (String jid : jids) {
sysadmins.add(jid.trim().toLowerCase());
}
}
allowToDiscoverLockedRooms =
MUCPersistenceManager.getBooleanProperty(chatServiceName, "discover.locked", true);
roomCreationRestricted =
MUCPersistenceManager.getBooleanProperty(chatServiceName, "create.anyone", false);
// Load the list of JIDs that are allowed to create a MUC room
property = MUCPersistenceManager.getProperty(chatServiceName, "create.jid");
allowedToCreate.clear();
if (property != null) {
jids = property.split(",");
for (String jid : jids) {
allowedToCreate.add(jid.trim().toLowerCase());
}
}
String value = MUCPersistenceManager.getProperty(chatServiceName, "tasks.user.timeout");
user_timeout = 300000;
if (value != null) {
try {
user_timeout = Integer.parseInt(value);
}
catch (NumberFormatException e) {
Log.error("Wrong number format of property tasks.user.timeout for service "+chatServiceName, e);
}
}
value = MUCPersistenceManager.getProperty(chatServiceName, "tasks.user.idle");
user_idle = -1;
if (value != null) {
try {
user_idle = Integer.parseInt(value);
}
catch (NumberFormatException e) {
Log.error("Wrong number format of property tasks.user.idle for service "+chatServiceName, e);
}
}
value = MUCPersistenceManager.getProperty(chatServiceName, "tasks.log.timeout");
log_timeout = 300000;
if (value != null) {
try {
log_timeout = Integer.parseInt(value);
}
catch (NumberFormatException e) {
Log.error("Wrong number format of property tasks.log.timeout for service "+chatServiceName, e);
}
}
value = MUCPersistenceManager.getProperty(chatServiceName, "tasks.log.batchsize");
log_batch_size = 50;
if (value != null) {
try {
log_batch_size = Integer.parseInt(value);
}
catch (NumberFormatException e) {
Log.error("Wrong number format of property tasks.log.batchsize for service "+chatServiceName, e);
}
}
value = MUCPersistenceManager.getProperty(chatServiceName, "unload.empty_days");
emptyLimit = 30 * 24;
if (value != null) {
try {
emptyLimit = Integer.parseInt(value) * 24;
}
catch (NumberFormatException e) {
Log.error("Wrong number format of property unload.empty_days for service "+chatServiceName, e);
}
}
}
public void start() {
// Run through the users every 5 minutes after a 5 minutes server startup delay (default
// values)
userTimeoutTask = new UserTimeoutTask();
timer.schedule(userTimeoutTask, user_timeout, user_timeout);
// Log the room conversations every 5 minutes after a 5 minutes server startup delay
// (default values)
logConversationTask = new LogConversationTask();
timer.schedule(logConversationTask, log_timeout, log_timeout);
// Remove unused rooms from memory
cleanupTask = new CleanupTask();
timer.schedule(cleanupTask, CLEANUP_FREQUENCY, CLEANUP_FREQUENCY);
// Set us up to answer disco item requests
XMPPServer.getInstance().getIQDiscoItemsHandler().addServerItemsProvider(this);
XMPPServer.getInstance().getIQDiscoInfoHandler().setServerNodeInfoProvider(this.getServiceDomain(), this);
XMPPServer.getInstance().getServerItemsProviders().add(this);
ArrayList<String> params = new ArrayList<String>();
params.clear();
params.add(getServiceDomain());
Log.info(LocaleUtils.getLocalizedString("startup.starting.muc", params));
// Load all the persistent rooms to memory
for (LocalMUCRoom room : MUCPersistenceManager.loadRoomsFromDB(this, this.getCleanupDate(), router)) {
rooms.put(room.getName().toLowerCase(), room);
}
}
public void stop() {
XMPPServer.getInstance().getIQDiscoItemsHandler().removeServerItemsProvider(this);
XMPPServer.getInstance().getIQDiscoInfoHandler().removeServerNodeInfoProvider(this.getServiceDomain());
XMPPServer.getInstance().getServerItemsProviders().remove(this);
// Remove the route to this service
routingTable.removeComponentRoute(getAddress());
timer.cancel();
logAllConversation();
}
public void enableService(boolean enabled, boolean persistent) {
if (isServiceEnabled() == enabled) {
// Do nothing if the service status has not changed
return;
}
XMPPServer server = XMPPServer.getInstance();
if (!enabled) {
// Disable disco information
server.getIQDiscoItemsHandler().removeServerItemsProvider(this);
// Stop the service/module
stop();
}
if (persistent) {
MUCPersistenceManager.setProperty(chatServiceName, "enabled", Boolean.toString(enabled));
}
serviceEnabled = enabled;
if (enabled) {
// Start the service/module
start();
// Enable disco information
server.getIQDiscoItemsHandler().addServerItemsProvider(this);
}
}
public boolean isServiceEnabled() {
return serviceEnabled;
}
public long getTotalChatTime() {
return totalChatTime;
}
/**
* Retuns the number of existing rooms in the server (i.e. persistent or not,
* in memory or not).
*
* @return the number of existing rooms in the server.
*/
public int getNumberChatRooms() {
return rooms.size();
}
/**
* Retuns the total number of occupants in all rooms in the server.
*
* @param onlyLocal true if only users connected to this JVM will be considered. Otherwise count cluster wise.
* @return the number of existing rooms in the server.
*/
public int getNumberConnectedUsers(boolean onlyLocal) {
int total = 0;
for (LocalMUCUser user : users.values()) {
if (user.isJoined()) {
total = total + 1;
}
}
// Add users from remote cluster nodes
if (!onlyLocal) {
Collection<Object> results =
CacheFactory.doSynchronousClusterTask(new GetNumberConnectedUsers(), false);
for (Object result : results) {
if (result == null) {
continue;
}
total = total + (Integer) result;
}
}
return total;
}
/**
* Retuns the total number of users that have joined in all rooms in the server.
*
* @return the number of existing rooms in the server.
*/
public int getNumberRoomOccupants() {
int total = 0;
for (MUCRoom room : rooms.values()) {
total = total + room.getOccupantsCount();
}
return total;
}
/**
* Returns the total number of incoming messages since last reset.
*
* @param resetAfter True if you want the counter to be reset after results returned.
* @return the number of incoming messages through the service.
*/
public long getIncomingMessageCount(boolean resetAfter) {
if (resetAfter) {
return inMessages.getAndSet(0);
}
else {
return inMessages.get();
}
}
/**
* Returns the total number of outgoing messages since last reset.
*
* @param resetAfter True if you want the counter to be reset after results returned.
* @return the number of outgoing messages through the service.
*/
public long getOutgoingMessageCount(boolean resetAfter) {
if (resetAfter) {
return outMessages.getAndSet(0);
}
else {
return outMessages.get();
}
}
public void logConversation(MUCRoom room, Message message, JID sender) {
// Only log messages that have a subject or body. Otherwise ignore it.
if (message.getSubject() != null || message.getBody() != null) {
logQueue.add(new ConversationLogEntry(new Date(), room, message, sender));
}
}
public void messageBroadcastedTo(int numOccupants) {
// Increment counter of received messages that where broadcasted by one
inMessages.incrementAndGet();
// Increment counter of outgoing messages with the number of room occupants
// that received the message
outMessages.addAndGet(numOccupants);
}
public Iterator<DiscoServerItem> getItems() {
// Check if the service is disabled. Info is not available when
// disabled.
if (!isServiceEnabled())
{
return null;
}
final ArrayList<DiscoServerItem> items = new ArrayList<DiscoServerItem>();
final DiscoServerItem item = new DiscoServerItem(new JID(
getServiceDomain()), getDescription(), null, null, this, this);
items.add(item);
return items.iterator();
}
public Iterator<Element> getIdentities(String name, String node, JID senderJID) {
ArrayList<Element> identities = new ArrayList<Element>();
if (name == null && node == null) {
// Answer the identity of the MUC service
Element identity = DocumentHelper.createElement("identity");
identity.addAttribute("category", "conference");
identity.addAttribute("name", getDescription());
identity.addAttribute("type", "text");
identities.add(identity);
// TODO: Should internationalize Public Chatroom Search, and make it configurable.
Element searchId = DocumentHelper.createElement("identity");
searchId.addAttribute("category", "directory");
searchId.addAttribute("name", "Public Chatroom Search");
searchId.addAttribute("type", "chatroom");
identities.add(searchId);
}
else if (name != null && node == null) {
// Answer the identity of a given room
MUCRoom room = getChatRoom(name);
if (room != null && canDiscoverRoom(room)) {
Element identity = DocumentHelper.createElement("identity");
identity.addAttribute("category", "conference");
identity.addAttribute("name", room.getNaturalLanguageName());
identity.addAttribute("type", "text");
identities.add(identity);
}
}
else if (name != null && "x-roomuser-item".equals(node)) {
// Answer reserved nickname for the sender of the disco request in the requested room
MUCRoom room = getChatRoom(name);
if (room != null) {
String reservedNick = room.getReservedNickname(senderJID.toBareJID());
if (reservedNick != null) {
Element identity = DocumentHelper.createElement("identity");
identity.addAttribute("category", "conference");
identity.addAttribute("name", reservedNick);
identity.addAttribute("type", "text");
identities.add(identity);
}
}
}
return identities.iterator();
}
public Iterator<String> getFeatures(String name, String node, JID senderJID) {
ArrayList<String> features = new ArrayList<String>();
if (name == null && node == null) {
// Answer the features of the MUC service
features.add("http://jabber.org/protocol/muc");
features.add("http://jabber.org/protocol/disco#info");
features.add("http://jabber.org/protocol/disco#items");
features.add("jabber:iq:search");
features.add(ResultSet.NAMESPACE_RESULT_SET_MANAGEMENT);
}
else if (name != null && node == null) {
// Answer the features of a given room
MUCRoom room = getChatRoom(name);
if (room != null && canDiscoverRoom(room)) {
features.add("http://jabber.org/protocol/muc");
// Always add public since only public rooms can be discovered
features.add("muc_public");
if (room.isMembersOnly()) {
features.add("muc_membersonly");
}
else {
features.add("muc_open");
}
if (room.isModerated()) {
features.add("muc_moderated");
}
else {
features.add("muc_unmoderated");
}
if (room.canAnyoneDiscoverJID()) {
features.add("muc_nonanonymous");
}
else {
features.add("muc_semianonymous");
}
if (room.isPasswordProtected()) {
features.add("muc_passwordprotected");
}
else {
features.add("muc_unsecured");
}
if (room.isPersistent()) {
features.add("muc_persistent");
}
else {
features.add("muc_temporary");
}
}
}
return features.iterator();
}
public XDataFormImpl getExtendedInfo(String name, String node, JID senderJID) {
if (name != null && node == null) {
// Answer the extended info of a given room
MUCRoom room = getChatRoom(name);
if (room != null && canDiscoverRoom(room)) {
XDataFormImpl dataForm = new XDataFormImpl(DataForm.TYPE_RESULT);
XFormFieldImpl field = new XFormFieldImpl("FORM_TYPE");
field.setType(FormField.TYPE_HIDDEN);
field.addValue("http://jabber.org/protocol/muc#roominfo");
dataForm.addField(field);
field = new XFormFieldImpl("muc#roominfo_description");
field.setLabel(LocaleUtils.getLocalizedString("muc.extended.info.desc"));
field.addValue(room.getDescription());
dataForm.addField(field);
field = new XFormFieldImpl("muc#roominfo_subject");
field.setLabel(LocaleUtils.getLocalizedString("muc.extended.info.subject"));
field.addValue(room.getSubject());
dataForm.addField(field);
field = new XFormFieldImpl("muc#roominfo_occupants");
field.setLabel(LocaleUtils.getLocalizedString("muc.extended.info.occupants"));
field.addValue(Integer.toString(room.getOccupantsCount()));
dataForm.addField(field);
/*field = new XFormFieldImpl("muc#roominfo_lang");
field.setLabel(LocaleUtils.getLocalizedString("muc.extended.info.language"));
field.addValue(room.getLanguage());
dataForm.addField(field);*/
field = new XFormFieldImpl("x-muc#roominfo_creationdate");
field.setLabel(LocaleUtils.getLocalizedString("muc.extended.info.creationdate"));
field.addValue(dateFormatter.format(room.getCreationDate()));
dataForm.addField(field);
return dataForm;
}
}
return null;
}
public boolean hasInfo(String name, String node, JID senderJID) {
// Check if the service is disabled. Info is not available when disabled.
if (!isServiceEnabled()) {
return false;
}
if (name == null && node == null) {
// We always have info about the MUC service
return true;
}
else if (name != null && node == null) {
// We only have info if the room exists
return hasChatRoom(name);
}
else if (name != null && "x-roomuser-item".equals(node)) {
// We always have info about reserved names as long as the room exists
return hasChatRoom(name);
}
return false;
}
public Iterator<DiscoItem> getItems(String name, String node, JID senderJID) {
// Check if the service is disabled. Info is not available when disabled.
if (!isServiceEnabled()) {
return null;
}
List<DiscoItem> answer = new ArrayList<DiscoItem>();
if (name == null && node == null)
{
// Answer all the public rooms as items
for (MUCRoom room : rooms.values())
{
if (canDiscoverRoom(room))
{
answer.add(new DiscoItem(room.getRole().getRoleAddress(),
room.getNaturalLanguageName(), null, null));
}
}
}
else if (name != null && node == null) {
// Answer the room occupants as items if that info is publicly available
MUCRoom room = getChatRoom(name);
if (room != null && canDiscoverRoom(room)) {
for (MUCRole role : room.getOccupants()) {
// TODO Should we filter occupants that are invisible (presence is not broadcasted)?
answer.add(new DiscoItem(role.getRoleAddress(), null, null, null));
}
}
}
return answer.iterator();
}
private boolean canDiscoverRoom(MUCRoom room) {
// Check if locked rooms may be discovered
if (!allowToDiscoverLockedRooms && room.isLocked()) {
return false;
}
return room.isPublicRoom();
}
/**
* Converts an array to a comma-delimitted String.
*
* @param array the array.
* @return a comma delimtted String of the array values.
*/
private static String fromArray(String [] array) {
StringBuilder buf = new StringBuilder();
for (int i=0; i<array.length; i++) {
buf.append(array[i]);
if (i != array.length-1) {
buf.append(",");
}
}
return buf.toString();
}
public boolean isServicePrivate() {
return false;
}
}
\ No newline at end of file
......@@ -17,7 +17,7 @@ import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.cluster.NodeID;
import org.jivesoftware.openfire.muc.MUCRole;
import org.jivesoftware.openfire.muc.MUCRoom;
import org.jivesoftware.openfire.muc.MultiUserChatServer;
import org.jivesoftware.openfire.muc.MultiUserChatService;
import org.jivesoftware.openfire.muc.cluster.OccupantAddedEvent;
import org.jivesoftware.util.cache.ExternalizableUtil;
import org.xmpp.packet.JID;
......@@ -38,7 +38,7 @@ import java.io.ObjectOutput;
* @author Gaston Dombiak
*/
public class RemoteMUCRole implements MUCRole, Externalizable {
private MultiUserChatServer server;
private MultiUserChatService server;
private Presence presence;
private Role role;
private Affiliation affiliation;
......@@ -55,7 +55,7 @@ public class RemoteMUCRole implements MUCRole, Externalizable {
public RemoteMUCRole() {
}
public RemoteMUCRole(MultiUserChatServer server, OccupantAddedEvent event) {
public RemoteMUCRole(MultiUserChatService server, OccupantAddedEvent event) {
this.server = server;
presence = event.getPresence();
role = event.getRole();
......
......@@ -21,6 +21,7 @@ public class JiveConstants {
public static final int OFFLINE = 19;
public static final int MUC_ROOM = 23;
public static final int SECURITY_AUDIT = 25;
public static final int MUC_SERVICE = 26;
public static final long SECOND = 1000;
public static final long MINUTE = 60 * SECOND;
......
......@@ -16,7 +16,8 @@ import org.jivesoftware.openfire.security.SecurityAuditManager;
import org.jivesoftware.openfire.lockout.LockOutManager;
import org.jivesoftware.openfire.auth.AuthToken;
import org.jivesoftware.openfire.group.GroupManager;
import org.jivesoftware.openfire.muc.MultiUserChatServer;
import org.jivesoftware.openfire.muc.MultiUserChatService;
import org.jivesoftware.openfire.muc.MultiUserChatManager;
import org.jivesoftware.openfire.roster.RosterManager;
import org.jivesoftware.openfire.user.User;
import org.jivesoftware.openfire.user.UserManager;
......@@ -99,8 +100,8 @@ public class WebManager extends WebBean {
return getXMPPServer().getSessionManager();
}
public MultiUserChatServer getMultiUserChatServer() {
return getXMPPServer().getMultiUserChatServer();
public MultiUserChatManager getMultiUserChatManager() {
return getXMPPServer().getMultiUserChatManager();
}
public XMPPServerInfo getServerInfo() {
......
......@@ -304,31 +304,50 @@
<!-- Group Chat Settings -->
<sidebar id="sidebar-groupchat-settings" name="${sidebar.sidebar-groupchat-settings}">
<!-- Group Chat Service Summary -->
<item id="muc-service-summary" name="${sidebar.muc-service-summary}"
url="muc-service-summary.jsp"
description="${sidebar.muc-service-summary.descr}">
<!-- Service Options -->
<sidebar id="sidebar-muc-service-options" name="${sidebar.sidebar-muc-service-options}">
<!-- Service Properties -->
<item id="muc-service-edit-form" name="${sidebar.muc-server-props}"
url="muc-service-edit-form.jsp"
description="${sidebar.muc-server-props.descr}"/>
<!-- Service History Settings -->
<item id="muc-history" name="${sidebar.muc-history}"
url="muc-history-settings.jsp"
description="${sidebar.muc-history.descr}"/>
<!-- Service Administrators -->
<item id="muc-sysadmin" name="${sidebar.muc-sysadmin}"
url="muc-sysadmins.jsp"
description="${sidebar.muc-sysadmin.descr}"/>
<!-- Service Room Creation Permissions -->
<item id="muc-perms" name="${sidebar.muc-perms}"
url="muc-create-permission.jsp"
description="${sidebar.muc-perms.descr}"/>
<!-- Service Other Settings -->
<item id="muc-tasks" name="${sidebar.muc-tasks}"
url="muc-tasks.jsp"
description="${sidebar.muc-tasks.descr}"/>
<!-- Delete Service -->
<item id="muc-service-delete" name="${sidebar.muc-service-delete}"
url="muc-service-delete.jsp"
description="${sidebar.muc-service-delete.descr}"/>
</sidebar>
</item>
<!-- Service Properties -->
<item id="muc-server-props" name="${sidebar.muc-server-props}"
url="muc-server-props-edit-form.jsp"
description="${sidebar.muc-server-props.descr}"/>
<!-- History Settings -->
<item id="muc-history" name="${sidebar.muc-history}"
url="muc-history-settings.jsp"
description="${sidebar.muc-history.descr}"/>
<!-- Administrators -->
<item id="muc-sysadmin" name="${sidebar.muc-sysadmin}"
url="muc-sysadmins.jsp"
description="${sidebar.muc-sysadmin.descr}"/>
<!-- Room Creation Permissions -->
<item id="muc-perms" name="${sidebar.muc-perms}"
url="muc-create-permission.jsp"
description="${sidebar.muc-perms.descr}"/>
<!-- Other Settings -->
<item id="muc-tasks" name="${sidebar.muc-tasks}"
url="muc-tasks.jsp"
description="${sidebar.muc-tasks.descr}"/>
<!-- Create New MUC Service -->
<item id="muc-service-create" name="${sidebar.muc-service-create}"
url="muc-service-create.jsp"
description="${sidebar.muc-service-create.descr}"/>
</sidebar>
</tab>
......
......@@ -11,7 +11,7 @@
<%@ page import="org.jivesoftware.util.*,
java.util.*,
org.jivesoftware.openfire.muc.HistoryStrategy,
org.jivesoftware.openfire.muc.MultiUserChatServer"
org.jivesoftware.openfire.muc.MultiUserChatService"
errorPage="error.jsp"
%>
......@@ -24,7 +24,7 @@
<html>
<head>
<title><fmt:message key="chatroom.history.settings.title"/></title>
<meta name="pageID" content="server-chatroom-history"/>
<meta name="subPageID" content="server-chatroom-history"/>
<meta name="helpPage" content="edit_group_chat_history_settings.html"/>
</head>
<body>
......@@ -35,13 +35,16 @@
static final int NUMBER = 3;
%>
<% // Get parameters:
<%
// TODO: This file is never used currently.
// Get parameters:
boolean update = request.getParameter("update") != null;
int policy = ParamUtils.getIntParameter(request,"policy",-1);
int numMessages = ParamUtils.getIntParameter(request,"numMessages",0);
String mucname = ParamUtils.getParameter(request, "mucname");
// Get an audit manager:
MultiUserChatServer muc = webManager.getMultiUserChatServer();
MultiUserChatService muc = webManager.getMultiUserChatManager().getMultiUserChatService(mucname);
HistoryStrategy historyStrat = muc.getHistoryStrategy();
Map<String, String> errors = new HashMap<String, String>();
......
......@@ -10,9 +10,10 @@
<%@ page import="org.jivesoftware.util.*,
java.util.*,
org.jivesoftware.openfire.muc.MultiUserChatServer"
org.jivesoftware.openfire.muc.MultiUserChatService"
errorPage="error.jsp"
%>
<%@ page import="java.net.URLEncoder" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
......@@ -28,9 +29,16 @@
boolean deletesuccess = request.getParameter("deletesuccess") != null;
boolean delete = ParamUtils.getBooleanParameter(request,"delete");
boolean openPerms = ParamUtils.getBooleanParameter(request,"openPerms");
String mucname = ParamUtils.getParameter(request,"mucname");
// Get muc server
MultiUserChatServer mucServer = webManager.getMultiUserChatServer();
if (!webManager.getMultiUserChatManager().isServiceRegistered(mucname)) {
// The requested service name does not exist so return to the list of the existing rooms
response.sendRedirect("muc-service-summary.jsp");
return;
}
// Get muc server
MultiUserChatService mucService = webManager.getMultiUserChatManager().getMultiUserChatService(mucname);
// Handle a save
Map<String,String> errors = new HashMap<String,String>();
......@@ -38,23 +46,23 @@
if (openPerms) {
// Remove all users who have the ability to create rooms
List<String> removeables = new ArrayList<String>();
for (Object obj : mucServer.getUsersAllowedToCreate()) {
for (Object obj : mucService.getUsersAllowedToCreate()) {
String user = (String)obj;
removeables.add(user);
}
for (String user : removeables) {
mucServer.removeUserAllowedToCreate(user);
mucService.removeUserAllowedToCreate(user);
}
mucServer.setRoomCreationRestricted(false);
mucService.setRoomCreationRestricted(false);
// Log the event
webManager.logEvent("set MUC room creation to restricted", null);
webManager.logEvent("set MUC room creation to restricted for service "+mucname, null);
response.sendRedirect("muc-create-permission.jsp?success=true");
return;
}
else {
mucServer.setRoomCreationRestricted(true);
mucService.setRoomCreationRestricted(true);
// Log the event
webManager.logEvent("set MUC room creation to not restricted", null);
webManager.logEvent("set MUC room creation to not restricted for service "+mucname, null);
response.sendRedirect("muc-create-permission.jsp?success=true");
return;
}
......@@ -67,9 +75,9 @@
errors.put("userJID","userJID");
}
if (errors.size() == 0) {
mucServer.addUserAllowedToCreate(userJID);
mucService.addUserAllowedToCreate(userJID);
// Log the event
webManager.logEvent("added MUC room creation permission to "+userJID, null);
webManager.logEvent("added MUC room creation permission to "+userJID+" for service "+mucname, null);
response.sendRedirect("muc-create-permission.jsp?addsuccess=true");
return;
}
......@@ -77,9 +85,9 @@
if (delete) {
// Remove the user from the allowed list
mucServer.removeUserAllowedToCreate(userJID);
mucService.removeUserAllowedToCreate(userJID);
// Log the event
webManager.logEvent("removed MUC room creation permission from "+userJID, null);
webManager.logEvent("removed MUC room creation permission from "+userJID+" for service "+mucname, null);
// done, return
response.sendRedirect("muc-create-permission.jsp?deletesuccess=true");
return;
......@@ -89,13 +97,15 @@
<html>
<head>
<title><fmt:message key="muc.create.permission.title"/></title>
<meta name="pageID" content="muc-perms"/>
<meta name="subPageID" content="muc-perms"/>
<meta name="extraParams" content="<%= "mucname="+URLEncoder.encode(mucname, "UTF-8") %>"/>
<meta name="helpPage" content="set_group_chat_room_creation_permissions.html"/>
</head>
<body>
<p>
<fmt:message key="muc.create.permission.info" />
<fmt:message key="groupchat.service.settings_affect" /> <b><a href="muc-service-edit-form.jsp?mucname=<%= URLEncoder.encode(mucname, "UTF-8") %>"><%= mucname %></a></b>
</p>
<% if (errors.size() > 0) { %>
......@@ -149,7 +159,7 @@
<tr>
<td width="1%">
<input type="radio" name="openPerms" value="true" id="rb01"
<%= ((!mucServer.isRoomCreationRestricted()) ? "checked" : "") %>>
<%= ((!mucService.isRoomCreationRestricted()) ? "checked" : "") %>>
</td>
<td width="99%">
<label for="rb01"><fmt:message key="muc.create.permission.anyone_created" /></label>
......@@ -159,7 +169,7 @@
<td width="1%">
<input type="radio" name="openPerms" value="false" id="rb02"
onfocus="this.form.userJID.focus();"
<%= ((mucServer.isRoomCreationRestricted()) ? "checked" : "") %>>
<%= ((mucService.isRoomCreationRestricted()) ? "checked" : "") %>>
</td>
<td width="99%">
<label for="rb02"><fmt:message key="muc.create.permission.specific_created" /></label>
......@@ -175,7 +185,7 @@
<br>
<% if (mucServer.isRoomCreationRestricted()) { %>
<% if (mucService.isRoomCreationRestricted()) { %>
<!-- BEGIN 'Allowed Users' -->
<form action="muc-create-permission.jsp?add" method="post">
<div class="jive-contentBoxHeader">
......@@ -198,7 +208,7 @@
</tr>
</thead>
<tbody>
<% if (mucServer.getUsersAllowedToCreate().size() == 0) { %>
<% if (mucService.getUsersAllowedToCreate().size() == 0) { %>
<tr>
<td colspan="2">
......@@ -208,7 +218,7 @@
<% } %>
<% for (Object obj : mucServer.getUsersAllowedToCreate()) {
<% for (Object obj : mucService.getUsersAllowedToCreate()) {
String user = (String)obj;
%>
<tr>
......
......@@ -11,9 +11,10 @@
<%@ page import="org.jivesoftware.util.*,
java.util.*,
org.jivesoftware.openfire.muc.HistoryStrategy,
org.jivesoftware.openfire.muc.MultiUserChatServer"
org.jivesoftware.openfire.muc.MultiUserChatService"
errorPage="error.jsp"
%>
<%@ page import="java.net.URLEncoder" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt"%>
......@@ -33,10 +34,18 @@
boolean update = request.getParameter("update") != null;
int policy = ParamUtils.getIntParameter(request,"policy",-1);
int numMessages = ParamUtils.getIntParameter(request,"numMessages",0);
String mucname = ParamUtils.getParameter(request,"mucname");
// Get muc history
MultiUserChatServer mucServer = webManager.getMultiUserChatServer();
HistoryStrategy historyStrat = mucServer.getHistoryStrategy();
if (!webManager.getMultiUserChatManager().isServiceRegistered(mucname)) {
// The requested service name does not exist so return to the list of the existing rooms
response.sendRedirect("muc-service-summary.jsp");
return;
}
// Get muc server
MultiUserChatService mucService = webManager.getMultiUserChatManager().getMultiUserChatService(mucname);
HistoryStrategy historyStrat = mucService.getHistoryStrategy();
Map<String,String> errors = new HashMap<String,String>();
if (update) {
......@@ -63,7 +72,7 @@
historyStrat.setMaxNumber(numMessages);
}
// Log the event
webManager.logEvent("set MUC history settings", "type = "+policy+"\nmax messages = "+numMessages);
webManager.logEvent("set MUC history settings for service "+mucname, "type = "+policy+"\nmax messages = "+numMessages);
// All done, redirect
response.sendRedirect("muc-history-settings.jsp?success=true");
return;
......@@ -88,13 +97,15 @@
<html>
<head>
<title><fmt:message key="groupchat.history.settings.title"/></title>
<meta name="pageID" content="muc-history"/>
<meta name="subPageID" content="muc-history"/>
<meta name="extraParams" content="<%= "mucname="+URLEncoder.encode(mucname, "UTF-8") %>"/>
<meta name="helpPage" content="edit_group_chat_history_settings.html"/>
</head>
<body>
<p>
<fmt:message key="groupchat.history.settings.introduction" />
<fmt:message key="groupchat.service.settings_affect" /> <b><a href="muc-service-edit-form.jsp?mucname=<%= URLEncoder.encode(mucname, "UTF-8") %>"><%= mucname %></a></b>
</p>
<% if ("true".equals(request.getParameter("success"))) { %>
......
......@@ -29,9 +29,10 @@
<% webManager.init(request, response, session, application, out ); %>
<% // Get parameters
String roomName = ParamUtils.getParameter(request,"roomName");
JID roomJID = new JID(ParamUtils.getParameter(request,"roomJID"));
String affiliation = ParamUtils.getParameter(request,"affiliation");
String userJID = ParamUtils.getParameter(request,"userJID");
String roomName = roomJID.getNode();
boolean add = request.getParameter("add") != null;
boolean addsuccess = request.getParameter("addsuccess") != null;
......@@ -39,7 +40,7 @@
boolean delete = ParamUtils.getBooleanParameter(request,"delete");
// Load the room object
MUCRoom room = webManager.getMultiUserChatServer().getChatRoom(roomName);
MUCRoom room = webManager.getMultiUserChatManager().getMultiUserChatService(roomJID).getChatRoom(roomName);
if (room == null) {
// The requested room name does not exist so return to the list of the existing rooms
......@@ -81,7 +82,7 @@
// Log the event
webManager.logEvent("set MUC affilation to "+affiliation+" for "+userJID+" in "+roomName, null);
// done, return
response.sendRedirect("muc-room-affiliations.jsp?addsuccess=true&roomName="+URLEncoder.encode(roomName, "UTF-8"));
response.sendRedirect("muc-room-affiliations.jsp?addsuccess=true&roomJID="+URLEncoder.encode(roomJID.toBareJID(), "UTF-8"));
return;
}
catch (ConflictException e) {
......@@ -104,7 +105,7 @@
// Send the IQ packet that will modify the room's configuration
room.getIQOwnerHandler().handleIQ(iq, room.getRole());
// done, return
response.sendRedirect("muc-room-affiliations.jsp?deletesuccess=true&roomName="+URLEncoder.encode(roomName, "UTF-8"));
response.sendRedirect("muc-room-affiliations.jsp?deletesuccess=true&roomJID="+URLEncoder.encode(roomJID.toBareJID(), "UTF-8"));
return;
}
catch (ConflictException e) {
......@@ -124,7 +125,7 @@
<p>
<fmt:message key="muc.room.affiliations.info" />
<b><a href="muc-room-edit-form.jsp?roomName=<%= URLEncoder.encode(room.getName(), "UTF-8") %>"><%= room.getName() %></a></b>.
<b><a href="muc-room-edit-form.jsp?roomJID=<%= URLEncoder.encode(room.getJID().toBareJID(), "UTF-8") %>"><%= room.getName() %></a></b>.
<fmt:message key="muc.room.affiliations.info_detail" />
</p>
......@@ -230,7 +231,7 @@
<%= userDisplay %>
</td>
<td width="1%" align="center">
<a href="muc-room-affiliations.jsp?roomName=<%= URLEncoder.encode(roomName, "UTF-8") %>&userJID=<%= user %>&delete=true&affiliation=owner"
<a href="muc-room-affiliations.jsp?roomJID=<%= URLEncoder.encode(roomJID.toBareJID(), "UTF-8") %>&userJID=<%= user %>&delete=true&affiliation=owner"
title="<fmt:message key="global.click_delete" />"
onclick="return confirm('<fmt:message key="muc.room.affiliations.confirm_removed" />');"
><img src="images/delete-16x16.gif" width="16" height="16" border="0" alt=""></a>
......@@ -263,7 +264,7 @@
<%= userDisplay %>
</td>
<td width="1%" align="center">
<a href="muc-room-affiliations.jsp?roomName=<%= URLEncoder.encode(roomName, "UTF-8") %>&userJID=<%= user %>&delete=true&affiliation=admin"
<a href="muc-room-affiliations.jsp?roomJID=<%= URLEncoder.encode(roomJID.toBareJID(), "UTF-8") %>&userJID=<%= user %>&delete=true&affiliation=admin"
title="<fmt:message key="global.click_delete" />"
onclick="return confirm('<fmt:message key="muc.room.affiliations.confirm_removed" />');"
><img src="images/delete-16x16.gif" width="16" height="16" border="0" alt=""></a>
......@@ -299,7 +300,7 @@
<%= userDisplay %><%= nickname %>
</td>
<td width="1%" align="center">
<a href="muc-room-affiliations.jsp?roomName=<%= URLEncoder.encode(roomName, "UTF-8") %>&userJID=<%= user %>&delete=true&affiliation=member"
<a href="muc-room-affiliations.jsp?roomJID=<%= URLEncoder.encode(roomJID.toBareJID(), "UTF-8") %>&userJID=<%= user %>&delete=true&affiliation=member"
title="<fmt:message key="global.click_delete" />"
onclick="return confirm('<fmt:message key="muc.room.affiliations.confirm_removed" />');"
><img src="images/delete-16x16.gif" width="16" height="16" border="0" alt=""></a>
......@@ -332,7 +333,7 @@
<%= userDisplay %>
</td>
<td width="1%" align="center">
<a href="muc-room-affiliations.jsp?roomName=<%= URLEncoder.encode(roomName, "UTF-8") %>&userJID=<%= user %>&delete=true&affiliation=outcast"
<a href="muc-room-affiliations.jsp?roomJID=<%= URLEncoder.encode(roomJID.toBareJID(), "UTF-8") %>&userJID=<%= user %>&delete=true&affiliation=outcast"
title="<fmt:message key="global.click_delete" />"
onclick="return confirm('<fmt:message key="muc.room.affiliations.confirm_removed" />');"
><img src="images/delete-16x16.gif" width="16" height="16" border="0" alt=""></a>
......
......@@ -10,6 +10,6 @@
--%>
<% // Redirect to muc-room-edit-form and set that a room will be created
response.sendRedirect("muc-room-edit-form.jsp?&create=true");
response.sendRedirect("muc-room-edit-form.jsp?create=true");
return;
%>
\ No newline at end of file
......@@ -13,6 +13,7 @@
java.net.URLEncoder"
errorPage="error.jsp"
%>
<%@ page import="org.xmpp.packet.JID" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
......@@ -22,9 +23,10 @@
<% // Get parameters //
boolean cancel = request.getParameter("cancel") != null;
boolean delete = request.getParameter("delete") != null;
String roomName = ParamUtils.getParameter(request,"roomName");
JID roomJID = new JID(ParamUtils.getParameter(request,"roomJID"));
String alternateJID = ParamUtils.getParameter(request,"alternateJID");
String reason = ParamUtils.getParameter(request,"reason");
String roomName = roomJID.getNode();
// Handle a cancel
if (cancel) {
......@@ -33,7 +35,7 @@
}
// Load the room object
MUCRoom room = webManager.getMultiUserChatServer().getChatRoom(roomName);
MUCRoom room = webManager.getMultiUserChatManager().getMultiUserChatService(roomJID).getChatRoom(roomName);
// Handle a room delete:
if (delete) {
......@@ -54,14 +56,14 @@
<head>
<title><fmt:message key="muc.room.delete.title"/></title>
<meta name="subPageID" content="muc-room-delete"/>
<meta name="extraParams" content="<%= "roomName="+URLEncoder.encode(roomName, "UTF-8") %>"/>
<meta name="extraParams" content="<%= "roomJID="+URLEncoder.encode(roomJID.toBareJID(), "UTF-8") %>"/>
<meta name="helpPage" content="delete_a_group_chat_room.html"/>
</head>
<body>
<p>
<fmt:message key="muc.room.delete.info" />
<b><a href="muc-room-edit-form.jsp?roomName=<%= URLEncoder.encode(room.getName(), "UTF-8") %>"><%= room.getName() %></a></b>
<b><a href="muc-room-edit-form.jsp?roomJID=<%= URLEncoder.encode(room.getJID().toBareJID(), "UTF-8") %>"><%= room.getName() %></a></b>
<fmt:message key="muc.room.delete.detail" />
</p>
......
......@@ -25,6 +25,7 @@
errorPage="error.jsp"
%>
<%@ page import="org.jivesoftware.openfire.muc.NotAllowedException"%>
<%@ page import="org.jivesoftware.openfire.muc.MultiUserChatService" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
......@@ -36,7 +37,7 @@
boolean save = ParamUtils.getBooleanParameter(request,"save");
boolean success = ParamUtils.getBooleanParameter(request,"success");
boolean addsuccess = ParamUtils.getBooleanParameter(request,"addsuccess");
String roomName = ParamUtils.getParameter(request,"roomName");
JID roomJID = new JID(ParamUtils.getParameter(request,"roomJID"));
String naturalName = ParamUtils.getParameter(request,"roomconfig_roomname");
String description = ParamUtils.getParameter(request,"roomconfig_roomdesc");
String maxUsers = ParamUtils.getParameter(request, "roomconfig_maxusers");
......@@ -58,6 +59,14 @@
String registrationEnabled = ParamUtils.getParameter(request, "roomconfig_registration");
String roomSubject = ParamUtils.getParameter(request, "room_topic");
String roomName = roomJID.getNode();
if (webManager.getMultiUserChatManager().getMultiUserChatServicesCount() < 1) {
// No services exist, so redirect to where one can configure the services
response.sendRedirect("muc-service-summary.jsp");
return;
}
// Handle a cancel
if (request.getParameter("cancel") != null) {
response.sendRedirect("muc-room-summary.jsp");
......@@ -67,7 +76,7 @@
// Load the room object
MUCRoom room = null;
if (!create) {
room = webManager.getMultiUserChatServer().getChatRoom(roomName);
room = webManager.getMultiUserChatManager().getMultiUserChatService(roomJID).getChatRoom(roomName);
if (room == null) {
// The requested room name does not exist so return to the list of the existing rooms
......@@ -112,7 +121,7 @@
if (errors.size() == 0) {
// Check that the requested room ID is available
room = webManager.getMultiUserChatServer().getChatRoom(roomName);
room = webManager.getMultiUserChatManager().getMultiUserChatService(roomJID).getChatRoom(roomName);
if (room != null) {
errors.put("room_already_exists", "room_already_exists");
}
......@@ -120,7 +129,7 @@
// Try to create a new room
JID address = new JID(webManager.getUser().getUsername(), webManager.getServerInfo().getXMPPDomain(), null);
try {
room = webManager.getMultiUserChatServer().getChatRoom(roomName, address);
room = webManager.getMultiUserChatManager().getMultiUserChatService(roomJID).getChatRoom(roomName, address);
// Check if the room was created concurrently by another user
if (!room.getOwners().contains(address.toBareJID())) {
errors.put("room_already_exists", "room_already_exists");
......@@ -254,12 +263,12 @@
// Changes good, so redirect
String params;
if (create) {
params = "addsuccess=true&roomName=" + URLEncoder.encode(roomName, "UTF-8");
params = "addsuccess=true&roomJID=" + URLEncoder.encode(roomJID.toBareJID(), "UTF-8");
// Log the event
webManager.logEvent("created new MUC room "+roomName, "subject = "+roomSubject+"\nroomdesc = "+description+"\nroomname = "+naturalName+"\nmaxusers = "+maxUsers);
}
else {
params = "success=true&roomName=" + URLEncoder.encode(roomName, "UTF-8");
params = "success=true&roomJID=" + URLEncoder.encode(roomJID.toBareJID(), "UTF-8");
// Log the event
webManager.logEvent("updated MUC room "+roomName, "subject = "+roomSubject+"\nroomdesc = "+description+"\nroomname = "+naturalName+"\nmaxusers = "+maxUsers);
}
......@@ -317,7 +326,7 @@
<% } else { %>
<meta name="subPageID" content="muc-room-edit-form"/>
<% } %>
<meta name="extraParams" content="<%= "roomName="+URLEncoder.encode(roomName, "UTF-8")+"&create="+create %>"/>
<meta name="extraParams" content="<%= "roomJID="+URLEncoder.encode(roomJID.toBareJID(), "UTF-8")+"&create="+create %>"/>
<meta name="helpPage" content="view_group_chat_room_summary.html"/>
</head>
<body>
......@@ -399,7 +408,7 @@
<% if (room.getOccupantsCount() == 0) { %>
<td><%= room.getOccupantsCount() %> / <%= room.getMaxUsers() %></td>
<% } else { %>
<td><a href="muc-room-occupants.jsp?roomName=<%= URLEncoder.encode(roomName, "UTF-8")%>"><%= room.getOccupantsCount() %> / <%= room.getMaxUsers() %></a></td>
<td><a href="muc-room-occupants.jsp?roomJID=<%= URLEncoder.encode(roomJID.toBareJID(), "UTF-8")%>"><%= room.getOccupantsCount() %> / <%= room.getMaxUsers() %></a></td>
<% } %>
<td><%= dateFormatter.format(room.getCreationDate()) %></td>
<td><%= dateFormatter.format(room.getModificationDate()) %></td>
......@@ -414,7 +423,7 @@
<% } %>
<form action="muc-room-edit-form.jsp">
<% if (!create) { %>
<input type="hidden" name="roomName" value="<%= roomName %>">
<input type="hidden" name="roomJID" value="<%= roomJID.toBareJID() %>">
<% } %>
<input type="hidden" name="save" value="true">
<input type="hidden" name="create" value="<%= create %>">
......@@ -427,7 +436,26 @@
<% if (create) { %>
<tr>
<td><fmt:message key="muc.room.edit.form.room_id" />:</td>
<td><input type="text" name="roomName" value="<%= roomName %>"> @<%= webManager.getMultiUserChatServer().getServiceDomain()%>
<td><input type="text" name="roomName" value="<%= roomName %>">
<% if (webManager.getMultiUserChatManager().getMultiUserChatServicesCount() > 1) { %>
@<select name="mucname">
<% for (MultiUserChatService service : webManager.getMultiUserChatManager().getMultiUserChatServices()) { %>
<option value="<%= service.getServiceName() %>"><%= service.getServiceDomain() %></option>
<% } %>
</select>
<% } else { %>
@<%
// We only have one service, none-the-less, we have to run through the list to get the first
for (MultiUserChatService service : webManager.getMultiUserChatManager().getMultiUserChatServices()) {
if (service.isServicePrivate()) {
// Private and hidden, skip it.
continue;
}
out.print(service.getServiceDomain());
break;
}
%>
<% } %>
</td>
</tr>
<% } %>
......
......@@ -18,6 +18,7 @@
%>
<%@ page import="org.jivesoftware.openfire.XMPPServer" %>
<%@ page import="org.jivesoftware.openfire.muc.NotAllowedException" %>
<%@ page import="org.xmpp.packet.JID" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
......@@ -25,12 +26,13 @@
<% webManager.init(request, response, session, application, out); %>
<% // Get parameters
String roomName = ParamUtils.getParameter(request,"roomName");
JID roomJID = new JID(ParamUtils.getParameter(request,"roomJID"));
String nickName = ParamUtils.getParameter(request,"nickName");
String kick = ParamUtils.getParameter(request,"kick");
String roomName = roomJID.getNode();
// Load the room object
MUCRoom room = webManager.getMultiUserChatServer().getChatRoom(roomName);
MUCRoom room = webManager.getMultiUserChatManager().getMultiUserChatService(roomJID).getChatRoom(roomName);
if (room == null) {
// The requested room name does not exist so return to the list of the existing rooms
response.sendRedirect("muc-room-summary.jsp");
......@@ -46,12 +48,12 @@
// Log the event
webManager.logEvent("kicked MUC occupant "+nickName+" from "+roomName, null);
// Done, so redirect
response.sendRedirect("muc-room-occupants.jsp?roomName="+URLEncoder.encode(room.getName(), "UTF-8")+"&nickName="+URLEncoder.encode(role.getNickname(), "UTF-8")+"&deletesuccess=true");
response.sendRedirect("muc-room-occupants.jsp?roomJID="+URLEncoder.encode(room.getJID().toBareJID(), "UTF-8")+"&nickName="+URLEncoder.encode(role.getNickname(), "UTF-8")+"&deletesuccess=true");
return;
}
catch (NotAllowedException e) {
// Done, so redirect
response.sendRedirect("muc-room-occupants.jsp?roomName="+URLEncoder.encode(room.getName(), "UTF-8")+"&nickName="+URLEncoder.encode(role.getNickname(), "UTF-8")+"&deletefailed=true");
response.sendRedirect("muc-room-occupants.jsp?roomJID="+URLEncoder.encode(room.getJID().toBareJID(), "UTF-8")+"&nickName="+URLEncoder.encode(role.getNickname(), "UTF-8")+"&deletefailed=true");
return;
}
}
......@@ -151,7 +153,7 @@
<td><%= role.getNickname() %></td>
<td><%= role.getRole() %></td>
<td><%= role.getAffiliation() %></td>
<td><a href="muc-room-occupants.jsp?roomName=<%= URLEncoder.encode(room.getName(), "UTF-8") %>&nickName=<%= URLEncoder.encode(role.getNickname(), "UTF-8") %>&kick=1" title="<fmt:message key="muc.room.occupants.kick"/>"><img src="images/delete-16x16.gif" alt="<fmt:message key="muc.room.occupants.kick"/>" border="0" width="16" height="16"/></a></td>
<td><a href="muc-room-occupants.jsp?roomJID=<%= URLEncoder.encode(room.getJID().toBareJID(), "UTF-8") %>&nickName=<%= URLEncoder.encode(role.getNickname(), "UTF-8") %>&kick=1" title="<fmt:message key="muc.room.occupants.kick"/>"><img src="images/delete-16x16.gif" alt="<fmt:message key="muc.room.occupants.kick"/>" border="0" width="16" height="16"/></a></td>
</tr>
<% } %>
</tbody>
......
......@@ -14,6 +14,7 @@
java.net.URLEncoder"
errorPage="error.jsp"
%>
<%@ page import="org.jivesoftware.openfire.muc.MultiUserChatService" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
......@@ -31,13 +32,35 @@
<% // Get parameters
int start = ParamUtils.getIntParameter(request,"start",0);
int range = ParamUtils.getIntParameter(request,"range",webManager.getRowsPerPage("muc-room-summary", 15));
String mucname = ParamUtils.getParameter(request,"mucname");
MultiUserChatService mucService = null;
if (webManager.getMultiUserChatManager().isServiceRegistered(mucname)) {
mucService = webManager.getMultiUserChatManager().getMultiUserChatService(mucname);
}
else {
for (MultiUserChatService muc : webManager.getMultiUserChatManager().getMultiUserChatServices()) {
if (muc.isServicePrivate()) {
// Private and hidden, skip it.
continue;
}
mucService = muc;
break;
}
}
if (mucService == null) {
// No services exist, so redirect to where one can configure the services
response.sendRedirect("muc-service-summary.jsp");
return;
}
if (request.getParameter("range") != null) {
webManager.setRowsPerPage("muc-room-summary", range);
}
// Get the rooms in the server
List<MUCRoom> rooms = webManager.getMultiUserChatServer().getChatRooms();
List<MUCRoom> rooms = mucService.getChatRooms();
Collections.sort(rooms, new Comparator<MUCRoom>() {
public int compare(MUCRoom room1, MUCRoom room2) {
return room1.getName().toLowerCase().compareTo(room2.getName().toLowerCase());
......@@ -78,6 +101,21 @@
<% } %>
<fmt:message key="muc.room.summary.sorted_id" />
<% if (webManager.getMultiUserChatManager().getMultiUserChatServicesCount() > 1) { %>
-- <fmt:message key="muc.room.summary.service" />:
<select name="mucname" onchange="location.href='muc-room-summary.jsp?mucname=' + this.options[this.selectedIndex].value;">
<% for (MultiUserChatService service : webManager.getMultiUserChatManager().getMultiUserChatServices()) {
if (service.isServicePrivate()) {
// Private and hidden, skip it.
continue;
}
%>
<option value="<%= service.getServiceName() %>"<%= mucService.getServiceName().equals(service.getServiceName()) ? " selected='selected'" : "" %>><%= service.getServiceDomain() %></option>
<% } %>
</select>
<% } %>
</p>
<% if (numPages > 1) { %>
......@@ -89,7 +127,7 @@
String sep = ((i+1)<numPages) ? " " : "";
boolean isCurrent = (i+1) == curPage;
%>
<a href="muc-room-summary.jsp?start=<%= (i*range) %>"
<a href="muc-room-summary.jsp?mucname=<%= mucname == null ? "" : mucname %>&start=<%= (i*range) %>"
class="<%= ((isCurrent) ? "jive-current" : "") %>"
><%= (i+1) %></a><%= sep %>
......@@ -137,12 +175,12 @@
</td>
<td width="45%" valign="middle">
<% if (room.getName().equals(room.getNaturalLanguageName())) { %>
<a href="muc-room-edit-form.jsp?roomName=<%= URLEncoder.encode(room.getName(), "UTF-8") %>"title="<fmt:message key="global.click_edit" />">
<a href="muc-room-edit-form.jsp?roomJID=<%= URLEncoder.encode(room.getJID().toBareJID(), "UTF-8") %>"title="<fmt:message key="global.click_edit" />">
<%= room.getName() %>
</a>
<% }
else { %>
<a href="muc-room-edit-form.jsp?roomName=<%= URLEncoder.encode(room.getName(), "UTF-8") %>"title="<fmt:message key="global.click_edit" />">
<a href="muc-room-edit-form.jsp?roomJID=<%= URLEncoder.encode(room.getJID().toBareJID(), "UTF-8") %>"title="<fmt:message key="global.click_edit" />">
<%= room.getNaturalLanguageName() %> (<%= room.getName() %>)
</a>
<% } %>
......@@ -158,15 +196,15 @@
<% } %>
</td>
<td width="1%" align="center">
<%= room.getOccupantsCount() %> / <%= room.getMaxUsers() %>
<nobr><%= room.getOccupantsCount() %> / <%= room.getMaxUsers() %></nobr>
</td>
<td width="1%" align="center">
<a href="muc-room-edit-form.jsp?roomName=<%= URLEncoder.encode(room.getName(), "UTF-8") %>"
<a href="muc-room-edit-form.jsp?roomJID=<%= URLEncoder.encode(room.getJID().toBareJID(), "UTF-8") %>"
title="<fmt:message key="global.click_edit" />"
><img src="images/edit-16x16.gif" width="17" height="17" border="0" alt=""></a>
</td>
<td width="1%" align="center" style="border-right:1px #ccc solid;">
<a href="muc-room-delete.jsp?roomName=<%= URLEncoder.encode(room.getName(), "UTF-8") %>"
<a href="muc-room-delete.jsp?roomJID=<%= URLEncoder.encode(room.getJID().toBareJID(), "UTF-8") %>"
title="<fmt:message key="global.click_delete" />"
><img src="images/delete-16x16.gif" width="16" height="16" border="0" alt=""></a>
</td>
......@@ -188,7 +226,7 @@
String sep = ((i+1)<numPages) ? " " : "";
boolean isCurrent = (i+1) == curPage;
%>
<a href="muc-room-summary.jsp?start=<%= (i*range) %>"
<a href="muc-room-summary.jsp?mucname=<%= mucname == null ? "" : mucname %>&start=<%= (i*range) %>"
class="<%= ((isCurrent) ? "jive-current" : "") %>"
><%= (i+1) %></a><%= sep %>
......
<%--
- $RCSfile:$
- $Revision$
- $Date$
-
- Copyright (C) 2008 Jive Software. All rights reserved.
-
- This software is the proprietary information of Jive Software.
- Use is subject to license terms.
--%>
<% // Redirect to muc-service-edit-form and set that a service will be created
response.sendRedirect("muc-service-edit-form.jsp?create=true");
return;
%>
\ No newline at end of file
<%--
- $Revision: 9934 $
- $Date: 2008-02-18 23:21:33 -0500 (Mon, 18 Feb 2008) $
-
- Copyright (C) 2004 Jive Software. All rights reserved.
-
- This software is the proprietary information of Jive Software.
- Use is subject to license terms.
--%>
<%@ page import="org.jivesoftware.util.*,
org.jivesoftware.openfire.muc.MUCRoom,
java.net.URLEncoder"
errorPage="error.jsp"
%>
<%@ page import="org.jivesoftware.openfire.muc.MultiUserChatService" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<jsp:useBean id="webManager" class="org.jivesoftware.util.WebManager" />
<% webManager.init(request, response, session, application, out ); %>
<% // Get parameters //
boolean cancel = request.getParameter("cancel") != null;
boolean delete = request.getParameter("delete") != null;
String mucname = ParamUtils.getParameter(request,"mucname");
String reason = ParamUtils.getParameter(request,"reason");
// Handle a cancel
if (cancel) {
response.sendRedirect("muc-service-summary.jsp");
return;
}
// Load the room object
MultiUserChatService muc = webManager.getMultiUserChatManager().getMultiUserChatService(mucname);
// Handle a room delete:
if (delete) {
// Delete the rooms in the service
if (muc != null) {
for (MUCRoom room : muc.getChatRooms()) {
// If the room still exists then destroy it
room.destroyRoom(null, reason);
}
// Log the event
webManager.logEvent("destroyed MUC service "+mucname, "reason = "+reason);
// Remove the service itself
webManager.getMultiUserChatManager().removeMultiUserChatService(mucname);
}
// Done, so redirect
response.sendRedirect("muc-service-summary.jsp?deletesuccess=true");
return;
}
%>
<html>
<head>
<title><fmt:message key="muc.service.delete.title"/></title>
<meta name="subPageID" content="muc-service-delete"/>
<meta name="extraParams" content="<%= "mucname="+URLEncoder.encode(mucname, "UTF-8") %>"/>
</head>
<body>
<p>
<fmt:message key="muc.service.delete.info" />
<b><a href="muc-service-edit-form.jsp?mucname=<%= URLEncoder.encode(mucname, "UTF-8") %>"><%= mucname %></a></b>
<fmt:message key="muc.service.delete.detail" />
</p>
<form action="muc-service-delete.jsp">
<input type="hidden" name="mucname" value="<%= mucname %>">
<fieldset>
<legend><fmt:message key="muc.service.delete.destructon_title" /></legend>
<div>
<table cellpadding="3" cellspacing="0" border="0" width="100%">
<tbody>
<tr>
<td class="c1">
<fmt:message key="muc.service.delete.service_name" />
</td>
<td>
<%= mucname %>
</td>
</tr>
<tr>
<td class="c1">
<fmt:message key="muc.service.delete.reason" />
</td>
<td>
<input type="text" size="50" maxlength="150" name="reason">
</td>
</tr>
</tbody>
</table>
</div>
</fieldset>
<br><br>
<input type="submit" name="delete" value="<fmt:message key="muc.service.delete.destroy_service" />">
<input type="submit" name="cancel" value="<fmt:message key="global.cancel" />">
</form>
</body>
</html>
\ No newline at end of file
......@@ -12,14 +12,14 @@
java.util.*"
errorPage="error.jsp"
%>
<%@ page import="java.net.URLEncoder" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%
// Handle a cancel
if (request.getParameter("cancel") != null) {
response.sendRedirect("muc-server-props-edit-form.jsp");
response.sendRedirect("muc-service-edit-form.jsp");
return;
}
%>
......@@ -29,41 +29,61 @@
<% webManager.init(request, response, session, application, out ); %>
<% // Get parameters
boolean create = ParamUtils.getBooleanParameter(request,"create");
boolean save = request.getParameter("save") != null;
boolean success = request.getParameter("success") != null;
String muc = ParamUtils.getParameter(request,"mucname");
String mucname = ParamUtils.getParameter(request,"mucname");
String mucdesc = ParamUtils.getParameter(request,"mucdesc");
// Load the service object
if (!create && !webManager.getMultiUserChatManager().isServiceRegistered(mucname)) {
// The requested service name does not exist so return to the list of the existing rooms
response.sendRedirect("muc-service-summary.jsp");
return;
}
if (!create && mucdesc == null) {
mucdesc = webManager.getMultiUserChatManager().getMultiUserChatService(mucname).getDescription();
}
// Handle a save
Map<String,String> errors = new HashMap<String,String>();
if (save) {
// Make sure that the MUC Service is lower cased.
muc = muc.toLowerCase();
mucname = mucname.toLowerCase();
// do validation
if (muc == null || muc.indexOf('.') >= 0) {
if (mucname == null || mucname.indexOf('.') >= 0 || mucname.length() < 1) {
errors.put("mucname","mucname");
}
if (errors.size() == 0) {
webManager.getMultiUserChatServer().setServiceName(muc);
// Log the event
webManager.logEvent("set MUC service name to "+muc, null);
response.sendRedirect("muc-server-props-edit-form.jsp?success=true&mucname="+muc);
return;
if (!create) {
webManager.getMultiUserChatManager().updateMultiUserChatService(mucname, mucname, mucdesc);
// Log the event
webManager.logEvent("updated MUC service configuration for "+mucname, "name = "+mucname+"\ndescription = "+mucdesc);
response.sendRedirect("muc-service-edit-form.jsp?success=true&mucname="+mucname);
return;
}
else {
webManager.getMultiUserChatManager().createMultiUserChatService(mucname, mucdesc);
// Log the event
webManager.logEvent("created MUC service "+mucname, "name = "+mucname+"\ndescription = "+mucdesc);
response.sendRedirect("muc-service-edit-form.jsp?success=true&mucname="+mucname);
return;
}
}
}
else if(muc == null) {
muc = webManager.getMultiUserChatServer().getServiceName() == null ? "" : webManager.getMultiUserChatServer().getServiceName();
}
if (errors.size() == 0 && muc == null) {
muc = webManager.getMultiUserChatServer().getServiceName();
}
%>
<html>
<head>
<title><fmt:message key="groupchat.service.properties.title"/></title>
<meta name="pageID" content="muc-server-props"/>
<% if (create) { %>
<meta name="pageID" content="muc-service-create"/>
<% } else { %>
<meta name="subPageID" content="muc-service-edit-form"/>
<meta name="extraParams" content="<%= "mucname="+URLEncoder.encode(mucname, "UTF-8") %>"/>
<% } %>
<meta name="helpPage" content="edit_group_chat_service_properties.html"/>
</head>
<body>
......@@ -79,7 +99,7 @@
<tbody>
<tr><td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16" border="0" alt=""></td>
<td class="jive-icon-label">
<fmt:message key="groupchat.service.properties.saved_successfully" /> <b><fmt:message key="global.restart" /></b> <fmt:message key="groupchat.service.properties.saved_successfully2" /> <a href="index.jsp"><fmt:message key="global.server_status" /></a>).
<fmt:message key="groupchat.service.properties.saved_successfully" />
</td></tr>
</tbody>
</table>
......@@ -92,7 +112,9 @@
<tbody>
<tr><td class="jive-icon"><img src="images/error-16x16.gif" width="16" height="16" border="0" alt=""></td>
<td class="jive-icon-label">
<fmt:message key="groupchat.service.properties.error_service_name" />
<% if (errors.get("mucname") != null) { %>
<fmt:message key="groupchat.service.properties.error_service_name" />
<% } %>
</td></tr>
</tbody>
</table>
......@@ -101,31 +123,48 @@
<% } %>
<!-- BEGIN 'Service Name'-->
<form action="muc-server-props-edit-form.jsp" method="post">
<form action="muc-service-edit-form.jsp" method="post">
<input type="hidden" name="save" value="true">
<div class="jive-contentBoxHeader">
<% if (!create) { %>
<input type="hidden" name="mucname" value="<%= mucname %>">
<% } else { %>
<input type="hidden" name="create" value="true" />
<% } %>
<div class="jive-contentBoxHeader">
<fmt:message key="groupchat.service.properties.legend" />
</div>
<div class="jive-contentBox">
<table cellpadding="3" cellspacing="0" border="0">
<tr>
<td class="c1">
<fmt:message key="groupchat.service.properties.label_service_name" />
</td>
<td>
<input type="text" size="30" maxlength="150" name="mucname" value="<%= (muc != null ? muc : "") %>">
<% if (errors.get("mucname") != null) { %>
<span class="jive-error-text">
<br><fmt:message key="groupchat.service.properties.error_service_name" />
</span>
<% } %>
</td>
</tr>
</table>
<tr>
<td class="c1">
<fmt:message key="groupchat.service.properties.label_service_name" />
</td>
<td>
<% if (create) { %>
<input type="text" size="30" maxlength="150" name="mucname" value="<%= (mucname != null ? mucname : "") %>">
<% if (errors.get("mucname") != null) { %>
<span class="jive-error-text">
<br><fmt:message key="groupchat.service.properties.error_service_name" />
</span>
<% } %>
<% } else { %>
<%= mucname %>
<% } %>
</td>
</tr>
<tr>
<td class="c1">
<fmt:message key="groupchat.service.properties.label_service_description" />
</td>
<td>
<input type="text" size="30" maxlength="150" name="mucdesc" value="<%= (mucdesc != null ? mucdesc : "") %>">
</td>
</tr>
</table>
</div>
<input type="submit" value="<fmt:message key="groupchat.service.properties.save" />">
</form>
......
<%--
- $RCSfile$
- $Revision: 9909 $
- $Date: 2008-02-13 22:32:17 -0500 (Wed, 13 Feb 2008) $
-
- 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.
--%>
<%@ page import="org.jivesoftware.util.LocaleUtils,
org.jivesoftware.util.ParamUtils"
%><%@ page import="org.xmpp.packet.JID"%>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="java.util.Collection" %>
<%@ page import="org.jivesoftware.openfire.muc.MultiUserChatService" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%!
final int DEFAULT_RANGE = 15;
final int[] RANGE_PRESETS = {15, 25, 50, 75, 100};
%>
<jsp:useBean id="webManager" class="org.jivesoftware.util.WebManager" />
<% webManager.init(request, response, session, application, out ); %>
<html>
<head>
<title><fmt:message key="muc.service.summary.title"/></title>
<meta name="pageID" content="muc-service-summary"/>
</head>
<body>
<% // Get parameters
int start = ParamUtils.getIntParameter(request,"start",0);
int range = ParamUtils.getIntParameter(request,"range",webManager.getRowsPerPage("muc-service-summary", DEFAULT_RANGE));
if (request.getParameter("range") != null) {
webManager.setRowsPerPage("muc-service-summary", range);
}
// Get the number of registered services
int servicesCount = webManager.getMultiUserChatManager().getServicesCount(false);
// paginator vars
int numPages = (int)Math.ceil((double)servicesCount/(double)range);
int curPage = (start/range) + 1;
%>
<% if (request.getParameter("deletesuccess") != null) { %>
<div class="jive-success">
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr><td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16" border="0" alt=""></td>
<td class="jive-icon-label">
<fmt:message key="muc.service.summary.deleted" />
</td></tr>
</tbody>
</table>
</div><br>
<% } %>
<% if (webManager.getMultiUserChatManager().getMultiUserChatServicesCount() < 1) { %>
<div class="jive-info">
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr><td class="jive-icon"><img src="images/info-16x16.gif" width="16" height="16" border="0" alt=""></td>
<td class="jive-icon-label">
<fmt:message key="muc.service.summary.no_services_warning" />
</td></tr>
</tbody>
</table>
</div><br>
<% } %>
<p>
<fmt:message key="muc.service.summary.total_services" />:
<b><%= LocaleUtils.getLocalizedNumber(servicesCount) %></b> --
<% if (numPages > 1) { %>
<fmt:message key="global.showing" />
<%= LocaleUtils.getLocalizedNumber(start+1) %>-<%= LocaleUtils.getLocalizedNumber(start+range > servicesCount ? servicesCount:start+range) %>,
<% } %>
<fmt:message key="muc.service.summary.sorted" />
-- <fmt:message key="muc.service.summary.services_per_page" />:
<select size="1" onchange="location.href='muc-service-summary.jsp?start=0&range=' + this.options[this.selectedIndex].value;">
<% for (int aRANGE_PRESETS : RANGE_PRESETS) { %>
<option value="<%= aRANGE_PRESETS %>"
<%= (aRANGE_PRESETS == range ? "selected" : "") %>><%= aRANGE_PRESETS %>
</option>
<% } %>
</select>
</p>
<% if (numPages > 1) { %>
<p>
<fmt:message key="global.pages" />:
[
<% int num = 15 + curPage;
int s = curPage-1;
if (s > 5) {
s -= 5;
}
if (s < 5) {
s = 0;
}
if (s > 2) {
%>
<a href="muc-service-summary.jsp?start=0&range=<%= range %>">1</a> ...
<%
}
int i;
for (i=s; i<numPages && i<num; i++) {
String sep = ((i+1)<numPages) ? " " : "";
boolean isCurrent = (i+1) == curPage;
%>
<a href="muc-service-summary.jsp?start=<%= (i*range) %>&range=<%= range %>"
class="<%= ((isCurrent) ? "jive-current" : "") %>"
><%= (i+1) %></a><%= sep %>
<% } %>
<% if (i < numPages) { %>
... <a href="muc-service-summary.jsp?start=<%= ((numPages-1)*range) %>&range=<%= range %>"><%= numPages %></a>
<% } %>
]
</p>
<% } %>
<div class="jive-table">
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<thead>
<tr>
<th>&nbsp;</th>
<th nowrap><fmt:message key="muc.service.summary.subdomain" /></th>
<th nowrap><fmt:message key="muc.service.summary.description" /></th>
<th nowrap><fmt:message key="muc.service.summary.numrooms" /></th>
<th nowrap><fmt:message key="muc.service.summary.numusers" /></th>
<th nowrap><fmt:message key="global.edit" /></th>
<th nowrap><fmt:message key="global.delete" /></th>
</tr>
</thead>
<tbody>
<% // Print the list of users
Collection<MultiUserChatService> services = webManager.getMultiUserChatManager().getMultiUserChatServices();
if (services.isEmpty()) {
%>
<tr>
<td align="center" colspan="7">
<fmt:message key="muc.service.summary.no_services" />
</td>
</tr>
<%
}
int i = start;
for (MultiUserChatService service : services) {
if (service.isServicePrivate()) {
// Private and hidden, skip it.
continue;
}
i++;
%>
<tr class="jive-<%= (((i%2)==0) ? "even" : "odd") %>">
<td width="1%">
<%= i %>
</td>
<td width="23%">
<a href="muc-service-edit-form.jsp?mucname=<%= URLEncoder.encode(service.getServiceName(), "UTF-8") %>"><%= JID.unescapeNode(service.getServiceName()) %></a>
</td>
<td width="33%">
<%= service.getDescription() %> &nbsp;
</td>
<td width="5%">
<%= service.getNumberChatRooms() %>
</td>
<td width="5%">
<%= service.getNumberConnectedUsers(false) %>
</td>
<td width="1%" align="center">
<a href="muc-service-edit-form.jsp?mucname=<%= URLEncoder.encode(service.getServiceName(), "UTF-8") %>"
title="<fmt:message key="global.click_edit" />"
><img src="images/edit-16x16.gif" width="16" height="16" border="0" alt="<fmt:message key="global.click_edit" />"></a>
</td>
<td width="1%" align="center" style="border-right:1px #ccc solid;">
<a href="muc-service-delete.jsp?mucname=<%= URLEncoder.encode(service.getServiceName(), "UTF-8") %>"
title="<fmt:message key="global.click_delete" />"
><img src="images/delete-16x16.gif" width="16" height="16" border="0" alt="<fmt:message key="global.click_delete" />"></a>
</td>
</tr>
<%
}
%>
</tbody>
</table>
</div>
<% if (numPages > 1) { %>
<p>
<fmt:message key="global.pages" />:
[
<% int num = 15 + curPage;
int s = curPage-1;
if (s > 5) {
s -= 5;
}
if (s < 5) {
s = 0;
}
if (s > 2) {
%>
<a href="muc-service-summary.jsp?start=0&range=<%= range %>">1</a> ...
<%
}
for (i=s; i<numPages && i<num; i++) {
String sep = ((i+1)<numPages) ? " " : "";
boolean isCurrent = (i+1) == curPage;
%>
<a href="muc-service-summary.jsp?start=<%= (i*range) %>&range=<%= range %>"
class="<%= ((isCurrent) ? "jive-current" : "") %>"
><%= (i+1) %></a><%= sep %>
<% } %>
<% if (i < numPages) { %>
... <a href="muc-service-summary.jsp?start=<%= ((numPages-1)*range) %>&range=<%= range %>"><%= numPages %></a>
<% } %>
]
</p>
<% } %>
</body>
</html>
......@@ -10,8 +10,10 @@
<%@ page import="org.jivesoftware.util.*,
java.util.*,
org.jivesoftware.openfire.muc.MultiUserChatServer"
org.jivesoftware.openfire.muc.MultiUserChatService"
errorPage="error.jsp"
%>
<%@ page import="java.net.URLEncoder" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt"%>
......@@ -23,9 +25,16 @@
String userJID = ParamUtils.getParameter(request,"userJID");
boolean add = request.getParameter("add") != null;
boolean delete = ParamUtils.getBooleanParameter(request,"delete");
String mucname = ParamUtils.getParameter(request,"mucname");
// Get muc server
MultiUserChatServer mucServer = webManager.getMultiUserChatServer();
if (!webManager.getMultiUserChatManager().isServiceRegistered(mucname)) {
// The requested service name does not exist so return to the list of the existing rooms
response.sendRedirect("muc-service-summary.jsp");
return;
}
// Get muc server
MultiUserChatService mucService = webManager.getMultiUserChatManager().getMultiUserChatService(mucname);
// Handle a save
Map<String,String> errors = new HashMap<String,String>();
......@@ -35,9 +44,9 @@
errors.put("userJID","userJID");
}
if (errors.size() == 0) {
mucServer.addSysadmin(userJID);
mucService.addSysadmin(userJID);
// Log the event
webManager.logEvent("added muc sysadmin "+userJID, null);
webManager.logEvent("added muc sysadmin "+userJID+" for service "+mucname, null);
response.sendRedirect("muc-sysadmins.jsp?addsuccess=true");
return;
}
......@@ -45,9 +54,9 @@
if (delete) {
// Remove the user from the list of system administrators
mucServer.removeSysadmin(userJID);
mucService.removeSysadmin(userJID);
// Log the event
webManager.logEvent("removed muc sysadmin "+userJID, null);
webManager.logEvent("removed muc sysadmin "+userJID+" for service "+mucname, null);
// done, return
response.sendRedirect("muc-sysadmins.jsp?deletesuccess=true");
return;
......@@ -57,13 +66,15 @@
<html>
<head>
<title><fmt:message key="groupchat.admins.title"/></title>
<meta name="pageID" content="muc-sysadmin"/>
<meta name="subPageID" content="muc-sysadmin"/>
<meta name="extraParams" content="<%= "mucname="+URLEncoder.encode(mucname, "UTF-8") %>"/>
<meta name="helpPage" content="edit_group_chat_service_administrators.html"/>
</head>
<body>
<p>
<fmt:message key="groupchat.admins.introduction" />
<fmt:message key="groupchat.service.settings_affect" /> <b><a href="muc-service-edit-form.jsp?mucname=<%= URLEncoder.encode(mucname, "UTF-8") %>"><%= mucname %></a></b>
</p>
<% if ("true".equals(request.getParameter("deletesuccess"))) { %>
......@@ -129,7 +140,7 @@
</tr>
</thead>
<tbody>
<% if (mucServer.getSysadmins().size() == 0) { %>
<% if (mucService.getSysadmins().size() == 0) { %>
<tr>
<td colspan="2">
......@@ -139,7 +150,7 @@
<% } %>
<% for (String user : mucServer.getSysadmins()) { %>
<% for (String user : mucService.getSysadmins()) { %>
<tr>
<td width="99%">
......
......@@ -10,9 +10,10 @@
<%@ page import="org.jivesoftware.util.*,
java.util.*,
org.jivesoftware.openfire.muc.MultiUserChatServer"
org.jivesoftware.openfire.muc.MultiUserChatService"
errorPage="error.jsp"
%>
<%@ page import="java.net.URLEncoder" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
......@@ -29,18 +30,25 @@
boolean logSettings = request.getParameter("logSettings") != null;
boolean kickSettingSuccess = request.getParameter("kickSettingSuccess") != null;
boolean logSettingSuccess = request.getParameter("logSettingSuccess") != null;
String mucname = ParamUtils.getParameter(request,"mucname");
// Get muc server
MultiUserChatServer mucServer = webManager.getMultiUserChatServer();
if (!webManager.getMultiUserChatManager().isServiceRegistered(mucname)) {
// The requested service name does not exist so return to the list of the existing rooms
response.sendRedirect("muc-service-summary.jsp");
return;
}
// Get muc server
MultiUserChatService mucService = webManager.getMultiUserChatManager().getMultiUserChatService(mucname);
Map<String, String> errors = new HashMap<String, String>();
// Handle an update of the kicking task settings
if (kickSettings) {
if (!kickEnabled) {
// Disable kicking users by setting a value of -1
mucServer.setUserIdleTime(-1);
mucService.setUserIdleTime(-1);
// Log the event
webManager.logEvent("disabled muc idle kick timeout", null);
webManager.logEvent("disabled muc idle kick timeout for service "+mucname, null);
response.sendRedirect("muc-tasks.jsp?kickSettingSuccess=true");
return;
}
......@@ -63,9 +71,9 @@
}
if (errors.size() == 0) {
mucServer.setUserIdleTime(idle);
mucService.setUserIdleTime(idle);
// Log the event
webManager.logEvent("edited muc idle kick timeout", "timeout = "+idle);
webManager.logEvent("edited muc idle kick timeout for service "+mucname, "timeout = "+idle);
response.sendRedirect("muc-tasks.jsp?kickSettingSuccess=true");
return;
}
......@@ -99,10 +107,10 @@
}
if (errors.size() == 0) {
mucServer.setLogConversationsTimeout(frequency);
mucServer.setLogConversationBatchSize(batchSize);
mucService.setLogConversationsTimeout(frequency);
mucService.setLogConversationBatchSize(batchSize);
// Log the event
webManager.logEvent("edited muc conversation log settings", "timeout = "+frequency+"\nbatchSize = "+batchSize);
webManager.logEvent("edited muc conversation log settings for service "+mucname, "timeout = "+frequency+"\nbatchSize = "+batchSize);
response.sendRedirect("muc-tasks.jsp?logSettingSuccess=true");
return;
}
......@@ -112,13 +120,15 @@
<html>
<head>
<title><fmt:message key="muc.tasks.title"/></title>
<meta name="pageID" content="muc-tasks"/>
<meta name="subPageID" content="muc-tasks"/>
<meta name="extraParams" content="<%= "mucname="+URLEncoder.encode(mucname, "UTF-8") %>"/>
<meta name="helpPage" content="edit_idle_user_settings.html"/>
</head>
<body>
<p>
<fmt:message key="muc.tasks.info" />
<fmt:message key="groupchat.service.settings_affect" /> <b><a href="muc-service-edit-form.jsp?mucname=<%= URLEncoder.encode(mucname, "UTF-8") %>"><%= mucname %></a></b>
</p>
<% if (kickSettingSuccess || logSettingSuccess) { %>
......@@ -177,7 +187,7 @@
<tr valign="middle">
<td width="1%" nowrap>
<input type="radio" name="kickEnabled" value="false" id="rb01"
<%= ((mucServer.getUserIdleTime() < 0) ? "checked" : "") %>>
<%= ((mucService.getUserIdleTime() < 0) ? "checked" : "") %>>
</td>
<td width="99%">
<label for="rb01"><fmt:message key="muc.tasks.never_kick" /></label>
......@@ -186,13 +196,13 @@
<tr valign="middle">
<td width="1%" nowrap>
<input type="radio" name="kickEnabled" value="true" id="rb02"
<%= ((mucServer.getUserIdleTime() > -1) ? "checked" : "") %>>
<%= ((mucService.getUserIdleTime() > -1) ? "checked" : "") %>>
</td>
<td width="99%">
<label for="rb02"><fmt:message key="muc.tasks.kick_user" /></label>
<input type="text" name="idletime" size="5" maxlength="5"
onclick="this.form.kickEnabled[1].checked=true;"
value="<%= mucServer.getUserIdleTime() == -1 ? 30 : mucServer.getUserIdleTime() / 1000 / 60 %>">
value="<%= mucService.getUserIdleTime() == -1 ? 30 : mucService.getUserIdleTime() / 1000 / 60 %>">
<fmt:message key="global.minutes" />.
</td>
</tr>
......@@ -219,7 +229,7 @@
</td>
<td width="99%">
<input type="text" name="logfreq" size="15" maxlength="50"
value="<%= mucServer.getLogConversationsTimeout() / 1000 %>">
value="<%= mucService.getLogConversationsTimeout() / 1000 %>">
</td>
</tr>
<tr valign="middle">
......@@ -228,7 +238,7 @@
</td>
<td width="99%">
<input type="text" name="logbatchsize" size="15" maxlength="50"
value="<%= mucServer.getLogConversationBatchSize() %>">
value="<%= mucService.getLogConversationBatchSize() %>">
</td>
</tr>
</table>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment