MUCRoleImpl.java 6.67 KB
Newer Older
Matt Tucker's avatar
Matt Tucker committed
1 2 3 4 5
/**
 * $RCSfile$
 * $Revision$
 * $Date$
 *
Matt Tucker's avatar
Matt Tucker committed
6
 * Copyright (C) 2004 Jive Software. All rights reserved.
Matt Tucker's avatar
Matt Tucker committed
7
 *
Matt Tucker's avatar
Matt Tucker committed
8 9
 * This software is published under the terms of the GNU Public License (GPL),
 * a copy of which is included in this distribution.
Matt Tucker's avatar
Matt Tucker committed
10
 */
Matt Tucker's avatar
Matt Tucker committed
11

Matt Tucker's avatar
Matt Tucker committed
12 13
package org.jivesoftware.messenger.muc.spi;

Derek DeMoro's avatar
Derek DeMoro committed
14 15
import org.dom4j.Element;
import org.dom4j.DocumentHelper;
Gaston Dombiak's avatar
Gaston Dombiak committed
16
import org.dom4j.QName;
Matt Tucker's avatar
Matt Tucker committed
17
import org.jivesoftware.messenger.PacketRouter;
Derek DeMoro's avatar
Derek DeMoro committed
18 19 20 21 22 23
import org.jivesoftware.messenger.muc.MUCRole;
import org.jivesoftware.messenger.muc.MUCRoom;
import org.jivesoftware.messenger.muc.MUCUser;
import org.jivesoftware.messenger.muc.MultiUserChatServer;
import org.jivesoftware.messenger.muc.NotAllowedException;
import org.jivesoftware.util.ElementUtil;
Matt Tucker's avatar
Matt Tucker committed
24
import org.xmpp.packet.*;
Matt Tucker's avatar
Matt Tucker committed
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58

/**
 * Simple in-memory implementation of a role in a chatroom
 * 
 * @author Gaston Dombiak
 */
public class MUCRoleImpl implements MUCRole {

    /**
     * The room this role is valid in.
     */
    private MUCRoomImpl room;

    /**
     * The user of the role.
     */
    private MUCUserImpl user;

    /**
     * The user's nickname in the room.
     */
    private String nick;

    /**
     * The user's presence in the room.
     */
    private Presence presence;

    /**
     * The chatserver that hosts this role.
     */
    private MultiUserChatServer server;

    /**
Matt Tucker's avatar
Matt Tucker committed
59
     * The role.
Matt Tucker's avatar
Matt Tucker committed
60
     */
Matt Tucker's avatar
Matt Tucker committed
61
    private MUCRole.Role role;
Matt Tucker's avatar
Matt Tucker committed
62 63

    /**
Matt Tucker's avatar
Matt Tucker committed
64
     * The affiliation.
Matt Tucker's avatar
Matt Tucker committed
65
     */
Matt Tucker's avatar
Matt Tucker committed
66
    private MUCRole.Affiliation affiliation;
Matt Tucker's avatar
Matt Tucker committed
67 68 69 70 71 72 73 74 75

    /**
     * The router used to send packets from this role.
     */
    private PacketRouter router;

    /**
     * The address of the person masquerading in this role.
     */
76
    private JID rJID;
Matt Tucker's avatar
Matt Tucker committed
77 78 79 80

    /**
     * A fragment containing the x-extension for non-anonymous rooms.
     */
81
    private Element extendedInformation;
Matt Tucker's avatar
Matt Tucker committed
82 83 84 85 86 87 88 89 90 91

    /**
     * Create a new role.
     * 
     * @param chatserver the server hosting the role.
     * @param chatroom the room the role is valid in.
     * @param nickname the nickname of the user in the role.
     * @param role the role of the user in the room.
     * @param affiliation the affiliation of the user in the room.
     * @param chatuser the user on the chat server.
92
     * @param presence the presence sent by the user to join the room.
Matt Tucker's avatar
Matt Tucker committed
93 94
     * @param packetRouter the packet router for sending messages from this role.
     */
95
    public MUCRoleImpl(MultiUserChatServer chatserver, MUCRoomImpl chatroom, String nickname,
Matt Tucker's avatar
Matt Tucker committed
96
            MUCRole.Role role, MUCRole.Affiliation affiliation, MUCUserImpl chatuser, Presence presence,
97
            PacketRouter packetRouter)
98
    {
Matt Tucker's avatar
Matt Tucker committed
99 100 101 102 103 104 105
        this.room = chatroom;
        this.nick = nickname;
        this.user = chatuser;
        this.server = chatserver;
        this.router = packetRouter;
        this.role = role;
        this.affiliation = affiliation;
Gaston Dombiak's avatar
Gaston Dombiak committed
106 107
        extendedInformation =
                DocumentHelper.createElement(QName.get("x", "http://jabber.org/protocol/muc#user"));
Matt Tucker's avatar
Matt Tucker committed
108
        calculateExtendedInformation();
109
        rJID = new JID(room.getName(), server.getServiceDomain(), nick);
110
        setPresence(presence);
Matt Tucker's avatar
Matt Tucker committed
111 112
    }

113
    public Presence getPresence() {
Matt Tucker's avatar
Matt Tucker committed
114 115 116
        return presence;
    }

117
    public Element getExtendedPresenceInformation() {
Matt Tucker's avatar
Matt Tucker committed
118 119 120
        return extendedInformation;
    }

121
    public void setPresence(Presence newPresence) {
122 123 124 125 126 127
        // Try to remove the element whose namespace is "http://jabber.org/protocol/muc" since we
        // don't need to include that element in future presence broadcasts
        Element element = newPresence.getElement().element(QName.get("x", "http://jabber.org/protocol/muc"));
        if (element != null) {
            newPresence.getElement().remove(element);
        }
Matt Tucker's avatar
Matt Tucker committed
128
        this.presence = newPresence;
129
        this.presence.setFrom(getRoleAddress());
Matt Tucker's avatar
Matt Tucker committed
130
        if (extendedInformation != null) {
Gaston Dombiak's avatar
Gaston Dombiak committed
131 132
            extendedInformation.setParent(null);
            presence.getElement().add(extendedInformation);
Matt Tucker's avatar
Matt Tucker committed
133 134 135
        }
    }

Matt Tucker's avatar
Matt Tucker committed
136
    public void setRole(MUCRole.Role newRole) throws NotAllowedException {
Matt Tucker's avatar
Matt Tucker committed
137
        // Don't allow to change the role to an owner or admin unless the new role is moderator
Matt Tucker's avatar
Matt Tucker committed
138 139
        if (MUCRole.Affiliation.owner == affiliation || MUCRole.Affiliation.admin == affiliation) {
            if (MUCRole.Role.moderator != newRole) {
Matt Tucker's avatar
Matt Tucker committed
140 141 142 143
                throw new NotAllowedException();
            }
        }
        // A moderator cannot be kicked from a room
Matt Tucker's avatar
Matt Tucker committed
144
        if (MUCRole.Role.moderator == role && MUCRole.Role.none == newRole) {
Matt Tucker's avatar
Matt Tucker committed
145 146 147
            throw new NotAllowedException();
        }
        // TODO A moderator MUST NOT be able to revoke voice from a user whose affiliation is at or
Matt Tucker's avatar
Matt Tucker committed
148
        // TODO above the moderator's level.
Matt Tucker's avatar
Matt Tucker committed
149 150

        role = newRole;
Matt Tucker's avatar
Matt Tucker committed
151
        if (MUCRole.Role.none == role) {
152
            presence.setType(Presence.Type.unavailable);
153
            presence.setStatus(null);
Matt Tucker's avatar
Matt Tucker committed
154 155 156 157
        }
        calculateExtendedInformation();
    }

Matt Tucker's avatar
Matt Tucker committed
158
    public MUCRole.Role getRole() {
Matt Tucker's avatar
Matt Tucker committed
159 160 161
        return role;
    }

Matt Tucker's avatar
Matt Tucker committed
162
    public void setAffiliation(MUCRole.Affiliation newAffiliation) throws NotAllowedException {
Matt Tucker's avatar
Matt Tucker committed
163
        // Don't allow to ban an owner or an admin
Matt Tucker's avatar
Matt Tucker committed
164 165
        if (MUCRole.Affiliation.owner == affiliation || MUCRole.Affiliation.admin== affiliation) {
            if (MUCRole.Affiliation.outcast == newAffiliation) {
Matt Tucker's avatar
Matt Tucker committed
166 167 168 169 170 171 172 173
                throw new NotAllowedException();
            }
        }
        affiliation = newAffiliation;
        // TODO The fragment is being calculated twice (1. setting the role & 2. setting the aff)
        calculateExtendedInformation();
    }

Matt Tucker's avatar
Matt Tucker committed
174
    public MUCRole.Affiliation getAffiliation() {
Matt Tucker's avatar
Matt Tucker committed
175 176 177 178 179 180 181 182 183
        return affiliation;
    }

    public String getNickname() {
        return nick;
    }

    public void changeNickname(String nickname) {
        this.nick = nickname;
184
        setRoleAddress(new JID(room.getName(), server.getServiceDomain(), nick));
Matt Tucker's avatar
Matt Tucker committed
185 186 187 188 189 190 191 192 193 194
    }

    public MUCUser getChatUser() {
        return user;
    }

    public MUCRoom getChatRoom() {
        return room;
    }

195
    public JID getRoleAddress() {
Matt Tucker's avatar
Matt Tucker committed
196 197 198
        return rJID;
    }

199 200 201 202 203 204
    private void setRoleAddress(JID jid) {
        rJID = jid;
        // Set the new sender of the user presence in the room
        presence.setFrom(jid);
    }

Matt Tucker's avatar
Matt Tucker committed
205
    public void send(Packet packet) {
206
        packet.setTo(user.getAddress());
Matt Tucker's avatar
Matt Tucker committed
207 208 209 210
        router.route(packet);
    }

    /**
211 212
     * Calculates and sets the extended presence information to add to the presence.
     * The information to add contains the user's jid, affiliation and role.
Matt Tucker's avatar
Matt Tucker committed
213
     */
214
    private void calculateExtendedInformation() {
Derek DeMoro's avatar
Derek DeMoro committed
215
        ElementUtil.setProperty(extendedInformation, "x.item:jid", user.getAddress().toString());
Matt Tucker's avatar
Matt Tucker committed
216 217
        ElementUtil.setProperty(extendedInformation, "x.item:affiliation", affiliation.toString());
        ElementUtil.setProperty(extendedInformation, "x.item:role", role.toString());
Matt Tucker's avatar
Matt Tucker committed
218 219
    }
}