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