1/**
2 * $RCSfile$
3 * $Revision$
4 * $Date$
5 *
6 * Copyright 2003-2007 Jive Software.
7 *
8 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 *     http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21package org.jivesoftware.smackx.packet;
22
23import org.jivesoftware.smack.packet.PacketExtension;
24
25/**
26 * Represents extended presence information about roles, affiliations, full JIDs,
27 * or status codes scoped by the 'http://jabber.org/protocol/muc#user' namespace.
28 *
29 * @author Gaston Dombiak
30 */
31public class MUCUser implements PacketExtension {
32
33    private Invite invite;
34    private Decline decline;
35    private Item item;
36    private String password;
37    private Status status;
38    private Destroy destroy;
39
40    public String getElementName() {
41        return "x";
42    }
43
44    public String getNamespace() {
45        return "http://jabber.org/protocol/muc#user";
46    }
47
48    public String toXML() {
49        StringBuilder buf = new StringBuilder();
50        buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append(
51            "\">");
52        if (getInvite() != null) {
53            buf.append(getInvite().toXML());
54        }
55        if (getDecline() != null) {
56            buf.append(getDecline().toXML());
57        }
58        if (getItem() != null) {
59            buf.append(getItem().toXML());
60        }
61        if (getPassword() != null) {
62            buf.append("<password>").append(getPassword()).append("</password>");
63        }
64        if (getStatus() != null) {
65            buf.append(getStatus().toXML());
66        }
67        if (getDestroy() != null) {
68            buf.append(getDestroy().toXML());
69        }
70        buf.append("</").append(getElementName()).append(">");
71        return buf.toString();
72    }
73
74    /**
75     * Returns the invitation for another user to a room. The sender of the invitation
76     * must be an occupant of the room. The invitation will be sent to the room which in turn
77     * will forward the invitation to the invitee.
78     *
79     * @return an invitation for another user to a room.
80     */
81    public Invite getInvite() {
82        return invite;
83    }
84
85    /**
86     * Returns the rejection to an invitation from another user to a room. The rejection will be
87     * sent to the room which in turn will forward the refusal to the inviter.
88     *
89     * @return a rejection to an invitation from another user to a room.
90     */
91    public Decline getDecline() {
92        return decline;
93    }
94
95    /**
96     * Returns the item child that holds information about roles, affiliation, jids and nicks.
97     *
98     * @return an item child that holds information about roles, affiliation, jids and nicks.
99     */
100    public Item getItem() {
101        return item;
102    }
103
104    /**
105     * Returns the password to use to enter Password-Protected Room. A Password-Protected Room is
106     * a room that a user cannot enter without first providing the correct password.
107     *
108     * @return the password to use to enter Password-Protected Room.
109     */
110    public String getPassword() {
111        return password;
112    }
113
114    /**
115     * Returns the status which holds a code that assists in presenting notification messages.
116     *
117     * @return the status which holds a code that assists in presenting notification messages.
118     */
119    public Status getStatus() {
120        return status;
121    }
122
123    /**
124     * Returns the notification that the room has been destroyed. After a room has been destroyed,
125     * the room occupants will receive a Presence packet of type 'unavailable' with the reason for
126     * the room destruction if provided by the room owner.
127     *
128     * @return a notification that the room has been destroyed.
129     */
130    public Destroy getDestroy() {
131        return destroy;
132    }
133
134    /**
135     * Sets the invitation for another user to a room. The sender of the invitation
136     * must be an occupant of the room. The invitation will be sent to the room which in turn
137     * will forward the invitation to the invitee.
138     *
139     * @param invite the invitation for another user to a room.
140     */
141    public void setInvite(Invite invite) {
142        this.invite = invite;
143    }
144
145    /**
146     * Sets the rejection to an invitation from another user to a room. The rejection will be
147     * sent to the room which in turn will forward the refusal to the inviter.
148     *
149     * @param decline the rejection to an invitation from another user to a room.
150     */
151    public void setDecline(Decline decline) {
152        this.decline = decline;
153    }
154
155    /**
156     * Sets the item child that holds information about roles, affiliation, jids and nicks.
157     *
158     * @param item the item child that holds information about roles, affiliation, jids and nicks.
159     */
160    public void setItem(Item item) {
161        this.item = item;
162    }
163
164    /**
165     * Sets the password to use to enter Password-Protected Room. A Password-Protected Room is
166     * a room that a user cannot enter without first providing the correct password.
167     *
168     * @param string the password to use to enter Password-Protected Room.
169     */
170    public void setPassword(String string) {
171        password = string;
172    }
173
174    /**
175     * Sets the status which holds a code that assists in presenting notification messages.
176     *
177     * @param status the status which holds a code that assists in presenting notification
178     * messages.
179     */
180    public void setStatus(Status status) {
181        this.status = status;
182    }
183
184    /**
185     * Sets the notification that the room has been destroyed. After a room has been destroyed,
186     * the room occupants will receive a Presence packet of type 'unavailable' with the reason for
187     * the room destruction if provided by the room owner.
188     *
189     * @param destroy the notification that the room has been destroyed.
190     */
191    public void setDestroy(Destroy destroy) {
192        this.destroy = destroy;
193    }
194
195    /**
196     * Represents an invitation for another user to a room. The sender of the invitation
197     * must be an occupant of the room. The invitation will be sent to the room which in turn
198     * will forward the invitation to the invitee.
199     *
200     * @author Gaston Dombiak
201     */
202    public static class Invite {
203        private String reason;
204        private String from;
205        private String to;
206
207        /**
208         * Returns the bare JID of the inviter or, optionally, the room JID. (e.g.
209         * 'crone1@shakespeare.lit/desktop').
210         *
211         * @return the room's occupant that sent the invitation.
212         */
213        public String getFrom() {
214            return from;
215        }
216
217        /**
218         * Returns the message explaining the invitation.
219         *
220         * @return the message explaining the invitation.
221         */
222        public String getReason() {
223            return reason;
224        }
225
226        /**
227         * Returns the bare JID of the invitee. (e.g. 'hecate@shakespeare.lit')
228         *
229         * @return the bare JID of the invitee.
230         */
231        public String getTo() {
232            return to;
233        }
234
235        /**
236         * Sets the bare JID of the inviter or, optionally, the room JID. (e.g.
237         * 'crone1@shakespeare.lit/desktop')
238         *
239         * @param from the bare JID of the inviter or, optionally, the room JID.
240         */
241        public void setFrom(String from) {
242            this.from = from;
243        }
244
245        /**
246         * Sets the message explaining the invitation.
247         *
248         * @param reason the message explaining the invitation.
249         */
250        public void setReason(String reason) {
251            this.reason = reason;
252        }
253
254        /**
255         * Sets the bare JID of the invitee. (e.g. 'hecate@shakespeare.lit')
256         *
257         * @param to the bare JID of the invitee.
258         */
259        public void setTo(String to) {
260            this.to = to;
261        }
262
263        public String toXML() {
264            StringBuilder buf = new StringBuilder();
265            buf.append("<invite ");
266            if (getTo() != null) {
267                buf.append(" to=\"").append(getTo()).append("\"");
268            }
269            if (getFrom() != null) {
270                buf.append(" from=\"").append(getFrom()).append("\"");
271            }
272            buf.append(">");
273            if (getReason() != null) {
274                buf.append("<reason>").append(getReason()).append("</reason>");
275            }
276            buf.append("</invite>");
277            return buf.toString();
278        }
279    }
280
281    /**
282     * Represents a rejection to an invitation from another user to a room. The rejection will be
283     * sent to the room which in turn will forward the refusal to the inviter.
284     *
285     * @author Gaston Dombiak
286     */
287    public static class Decline {
288        private String reason;
289        private String from;
290        private String to;
291
292        /**
293         * Returns the bare JID of the invitee that rejected the invitation. (e.g.
294         * 'crone1@shakespeare.lit/desktop').
295         *
296         * @return the bare JID of the invitee that rejected the invitation.
297         */
298        public String getFrom() {
299            return from;
300        }
301
302        /**
303         * Returns the message explaining why the invitation was rejected.
304         *
305         * @return the message explaining the reason for the rejection.
306         */
307        public String getReason() {
308            return reason;
309        }
310
311        /**
312         * Returns the bare JID of the inviter. (e.g. 'hecate@shakespeare.lit')
313         *
314         * @return the bare JID of the inviter.
315         */
316        public String getTo() {
317            return to;
318        }
319
320        /**
321         * Sets the bare JID of the invitee that rejected the invitation. (e.g.
322         * 'crone1@shakespeare.lit/desktop').
323         *
324         * @param from the bare JID of the invitee that rejected the invitation.
325         */
326        public void setFrom(String from) {
327            this.from = from;
328        }
329
330        /**
331         * Sets the message explaining why the invitation was rejected.
332         *
333         * @param reason the message explaining the reason for the rejection.
334         */
335        public void setReason(String reason) {
336            this.reason = reason;
337        }
338
339        /**
340         * Sets the bare JID of the inviter. (e.g. 'hecate@shakespeare.lit')
341         *
342         * @param to the bare JID of the inviter.
343         */
344        public void setTo(String to) {
345            this.to = to;
346        }
347
348        public String toXML() {
349            StringBuilder buf = new StringBuilder();
350            buf.append("<decline ");
351            if (getTo() != null) {
352                buf.append(" to=\"").append(getTo()).append("\"");
353            }
354            if (getFrom() != null) {
355                buf.append(" from=\"").append(getFrom()).append("\"");
356            }
357            buf.append(">");
358            if (getReason() != null) {
359                buf.append("<reason>").append(getReason()).append("</reason>");
360            }
361            buf.append("</decline>");
362            return buf.toString();
363        }
364    }
365
366    /**
367     * Item child that holds information about roles, affiliation, jids and nicks.
368     *
369     * @author Gaston Dombiak
370     */
371    public static class Item {
372        private String actor;
373        private String reason;
374        private String affiliation;
375        private String jid;
376        private String nick;
377        private String role;
378
379        /**
380         * Creates a new item child.
381         *
382         * @param affiliation the actor's affiliation to the room
383         * @param role the privilege level of an occupant within a room.
384         */
385        public Item(String affiliation, String role) {
386            this.affiliation = affiliation;
387            this.role = role;
388        }
389
390        /**
391         * Returns the actor (JID of an occupant in the room) that was kicked or banned.
392         *
393         * @return the JID of an occupant in the room that was kicked or banned.
394         */
395        public String getActor() {
396            return actor == null ? "" : actor;
397        }
398
399        /**
400         * Returns the reason for the item child. The reason is optional and could be used to
401         * explain the reason why a user (occupant) was kicked or banned.
402         *
403         * @return the reason for the item child.
404         */
405        public String getReason() {
406            return reason == null ? "" : reason;
407        }
408
409        /**
410         * Returns the occupant's affiliation to the room. The affiliation is a semi-permanent
411         * association or connection with a room. The possible affiliations are "owner", "admin",
412         * "member", and "outcast" (naturally it is also possible to have no affiliation). An
413         * affiliation lasts across a user's visits to a room.
414         *
415         * @return the actor's affiliation to the room
416         */
417        public String getAffiliation() {
418            return affiliation;
419        }
420
421        /**
422         * Returns the <room@service/nick> by which an occupant is identified within the context
423         * of a room. If the room is non-anonymous, the JID will be included in the item.
424         *
425         * @return the room JID by which an occupant is identified within the room.
426         */
427        public String getJid() {
428            return jid;
429        }
430
431        /**
432         * Returns the new nickname of an occupant that is changing his/her nickname. The new
433         * nickname is sent as part of the unavailable presence.
434         *
435         * @return the new nickname of an occupant that is changing his/her nickname.
436         */
437        public String getNick() {
438            return nick;
439        }
440
441        /**
442         * Returns the temporary position or privilege level of an occupant within a room. The
443         * possible roles are "moderator", "participant", and "visitor" (it is also possible to
444         * have no defined role). A role lasts only for the duration of an occupant's visit to
445         * a room.
446         *
447         * @return the privilege level of an occupant within a room.
448         */
449        public String getRole() {
450            return role;
451        }
452
453        /**
454         * Sets the actor (JID of an occupant in the room) that was kicked or banned.
455         *
456         * @param actor the actor (JID of an occupant in the room) that was kicked or banned.
457         */
458        public void setActor(String actor) {
459            this.actor = actor;
460        }
461
462        /**
463         * Sets the reason for the item child. The reason is optional and could be used to
464         * explain the reason why a user (occupant) was kicked or banned.
465         *
466         * @param reason the reason why a user (occupant) was kicked or banned.
467         */
468        public void setReason(String reason) {
469            this.reason = reason;
470        }
471
472        /**
473         * Sets the <room@service/nick> by which an occupant is identified within the context
474         * of a room. If the room is non-anonymous, the JID will be included in the item.
475         *
476         * @param jid the JID by which an occupant is identified within a room.
477         */
478        public void setJid(String jid) {
479            this.jid = jid;
480        }
481
482        /**
483         * Sets the new nickname of an occupant that is changing his/her nickname. The new
484         * nickname is sent as part of the unavailable presence.
485         *
486         * @param nick the new nickname of an occupant that is changing his/her nickname.
487         */
488        public void setNick(String nick) {
489            this.nick = nick;
490        }
491
492        public String toXML() {
493            StringBuilder buf = new StringBuilder();
494            buf.append("<item");
495            if (getAffiliation() != null) {
496                buf.append(" affiliation=\"").append(getAffiliation()).append("\"");
497            }
498            if (getJid() != null) {
499                buf.append(" jid=\"").append(getJid()).append("\"");
500            }
501            if (getNick() != null) {
502                buf.append(" nick=\"").append(getNick()).append("\"");
503            }
504            if (getRole() != null) {
505                buf.append(" role=\"").append(getRole()).append("\"");
506            }
507            if (getReason() == null && getActor() == null) {
508                buf.append("/>");
509            }
510            else {
511                buf.append(">");
512                if (getReason() != null) {
513                    buf.append("<reason>").append(getReason()).append("</reason>");
514                }
515                if (getActor() != null) {
516                    buf.append("<actor jid=\"").append(getActor()).append("\"/>");
517                }
518                buf.append("</item>");
519            }
520            return buf.toString();
521        }
522    }
523
524    /**
525     * Status code assists in presenting notification messages. The following link provides the
526     * list of existing error codes (@link http://www.jabber.org/jeps/jep-0045.html#errorstatus).
527     *
528     * @author Gaston Dombiak
529     */
530    public static class Status {
531        private String code;
532
533        /**
534         * Creates a new instance of Status with the specified code.
535         *
536         * @param code the code that uniquely identifies the reason of the error.
537         */
538        public Status(String code) {
539            this.code = code;
540        }
541
542        /**
543         * Returns the code that uniquely identifies the reason of the error. The code
544         * assists in presenting notification messages.
545         *
546         * @return the code that uniquely identifies the reason of the error.
547         */
548        public String getCode() {
549            return code;
550        }
551
552        public String toXML() {
553            StringBuilder buf = new StringBuilder();
554            buf.append("<status code=\"").append(getCode()).append("\"/>");
555            return buf.toString();
556        }
557    }
558
559    /**
560     * Represents a notification that the room has been destroyed. After a room has been destroyed,
561     * the room occupants will receive a Presence packet of type 'unavailable' with the reason for
562     * the room destruction if provided by the room owner.
563     *
564     * @author Gaston Dombiak
565     */
566    public static class Destroy {
567        private String reason;
568        private String jid;
569
570
571        /**
572         * Returns the JID of an alternate location since the current room is being destroyed.
573         *
574         * @return the JID of an alternate location.
575         */
576        public String getJid() {
577            return jid;
578        }
579
580        /**
581         * Returns the reason for the room destruction.
582         *
583         * @return the reason for the room destruction.
584         */
585        public String getReason() {
586            return reason;
587        }
588
589        /**
590         * Sets the JID of an alternate location since the current room is being destroyed.
591         *
592         * @param jid the JID of an alternate location.
593         */
594        public void setJid(String jid) {
595            this.jid = jid;
596        }
597
598        /**
599         * Sets the reason for the room destruction.
600         *
601         * @param reason the reason for the room destruction.
602         */
603        public void setReason(String reason) {
604            this.reason = reason;
605        }
606
607        public String toXML() {
608            StringBuilder buf = new StringBuilder();
609            buf.append("<destroy");
610            if (getJid() != null) {
611                buf.append(" jid=\"").append(getJid()).append("\"");
612            }
613            if (getReason() == null) {
614                buf.append("/>");
615            }
616            else {
617                buf.append(">");
618                if (getReason() != null) {
619                    buf.append("<reason>").append(getReason()).append("</reason>");
620                }
621                buf.append("</destroy>");
622            }
623            return buf.toString();
624        }
625
626    }
627}