MUCUser.java

  1. /**
  2.  *
  3.  * Copyright 2003-2007 Jive Software.
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.jivesoftware.smackx.muc.packet;

  18. import org.jivesoftware.smack.packet.NamedElement;
  19. import org.jivesoftware.smack.packet.Stanza;

  20. import java.util.HashMap;
  21. import java.util.HashSet;
  22. import java.util.Map;
  23. import java.util.Set;

  24. import org.jivesoftware.smack.packet.ExtensionElement;
  25. import org.jivesoftware.smack.util.XmlStringBuilder;

  26. /**
  27.  * Represents extended presence information about roles, affiliations, full JIDs,
  28.  * or status codes scoped by the 'http://jabber.org/protocol/muc#user' namespace.
  29.  *
  30.  * @author Gaston Dombiak
  31.  */
  32. public class MUCUser implements ExtensionElement {

  33.     public static final String ELEMENT = "x";
  34.     public static final String NAMESPACE = MUCInitialPresence.NAMESPACE + "#user";

  35.     private final Set<Status> statusCodes = new HashSet<Status>(4);

  36.     private Invite invite;
  37.     private Decline decline;
  38.     private MUCItem item;
  39.     private String password;
  40.     private Destroy destroy;

  41.     public String getElementName() {
  42.         return ELEMENT;
  43.     }

  44.     public String getNamespace() {
  45.         return NAMESPACE;
  46.     }

  47.     @Override
  48.     public XmlStringBuilder toXML() {
  49.         XmlStringBuilder xml = new XmlStringBuilder(this);
  50.         xml.rightAngleBracket();
  51.         xml.optElement(getInvite());
  52.         xml.optElement(getDecline());
  53.         xml.optElement(getItem());
  54.         xml.optElement("password", getPassword());
  55.         xml.append(statusCodes);
  56.         xml.optElement(getDestroy());
  57.         xml.closeElement(this);
  58.         return xml;
  59.     }

  60.     /**
  61.      * Returns the invitation for another user to a room. The sender of the invitation
  62.      * must be an occupant of the room. The invitation will be sent to the room which in turn
  63.      * will forward the invitation to the invitee.
  64.      *
  65.      * @return an invitation for another user to a room.
  66.      */
  67.     public Invite getInvite() {
  68.         return invite;
  69.     }

  70.     /**
  71.      * Returns the rejection to an invitation from another user to a room. The rejection will be
  72.      * sent to the room which in turn will forward the refusal to the inviter.
  73.      *
  74.      * @return a rejection to an invitation from another user to a room.
  75.      */
  76.     public Decline getDecline() {
  77.         return decline;
  78.     }

  79.     /**
  80.      * Returns the item child that holds information about roles, affiliation, jids and nicks.
  81.      *
  82.      * @return an item child that holds information about roles, affiliation, jids and nicks.
  83.      */
  84.     public MUCItem getItem() {
  85.         return item;
  86.     }

  87.     /**
  88.      * Returns the password to use to enter Password-Protected Room. A Password-Protected Room is
  89.      * a room that a user cannot enter without first providing the correct password.
  90.      *
  91.      * @return the password to use to enter Password-Protected Room.
  92.      */
  93.     public String getPassword() {
  94.         return password;
  95.     }

  96.     /**
  97.      * Returns a set of status which holds the status code that assist in presenting notification messages.
  98.      *
  99.      * @return the set of status which holds the status code that assist in presenting notification messages.
  100.      */
  101.     public Set<Status> getStatus() {
  102.         return statusCodes;
  103.     }

  104.     /**
  105.      * Returns true if this MUCUser instance has also {@link Status} information.
  106.      * <p>
  107.      * If <code>true</code> is returned, then {@link #getStatus()} will return a non-empty set.
  108.      * </p>
  109.      *
  110.      * @return true if this MUCUser has status information.
  111.      * @since 4.1
  112.      */
  113.     public boolean hasStatus() {
  114.         return !statusCodes.isEmpty();
  115.     }

  116.     /**
  117.      * Returns the notification that the room has been destroyed. After a room has been destroyed,
  118.      * the room occupants will receive a Presence packet of type 'unavailable' with the reason for
  119.      * the room destruction if provided by the room owner.
  120.      *
  121.      * @return a notification that the room has been destroyed.
  122.      */
  123.     public Destroy getDestroy() {
  124.         return destroy;
  125.     }

  126.     /**
  127.      * Sets the invitation for another user to a room. The sender of the invitation
  128.      * must be an occupant of the room. The invitation will be sent to the room which in turn
  129.      * will forward the invitation to the invitee.
  130.      *
  131.      * @param invite the invitation for another user to a room.
  132.      */
  133.     public void setInvite(Invite invite) {
  134.         this.invite = invite;
  135.     }

  136.     /**
  137.      * Sets the rejection to an invitation from another user to a room. The rejection will be
  138.      * sent to the room which in turn will forward the refusal to the inviter.
  139.      *
  140.      * @param decline the rejection to an invitation from another user to a room.
  141.      */
  142.     public void setDecline(Decline decline) {
  143.         this.decline = decline;
  144.     }

  145.     /**
  146.      * Sets the item child that holds information about roles, affiliation, jids and nicks.
  147.      *
  148.      * @param item the item child that holds information about roles, affiliation, jids and nicks.
  149.      */
  150.     public void setItem(MUCItem item) {
  151.         this.item = item;
  152.     }

  153.     /**
  154.      * Sets the password to use to enter Password-Protected Room. A Password-Protected Room is
  155.      * a room that a user cannot enter without first providing the correct password.
  156.      *
  157.      * @param string the password to use to enter Password-Protected Room.
  158.      */
  159.     public void setPassword(String string) {
  160.         password = string;
  161.     }

  162.     /**
  163.      * Add the status codes which holds the codes that assists in presenting notification messages.
  164.      *
  165.      * @param statusCodes the status codes which hold the codes that assists in presenting notification
  166.      * messages.
  167.      */
  168.     public void addStatusCodes(Set<Status> statusCodes) {
  169.         this.statusCodes.addAll(statusCodes);
  170.     }

  171.     /**
  172.      * Add a status code which hold a code that assists in presenting notification messages.
  173.      *
  174.      * @param status the status code which olds a code that assists in presenting notification messages.
  175.      */
  176.     public void addStatusCode(Status status) {
  177.         this.statusCodes.add(status);
  178.     }

  179.     /**
  180.      * Sets the notification that the room has been destroyed. After a room has been destroyed,
  181.      * the room occupants will receive a Presence packet of type 'unavailable' with the reason for
  182.      * the room destruction if provided by the room owner.
  183.      *
  184.      * @param destroy the notification that the room has been destroyed.
  185.      */
  186.     public void setDestroy(Destroy destroy) {
  187.         this.destroy = destroy;
  188.     }

  189.     /**
  190.      * Retrieve the MUCUser PacketExtension from packet, if any.
  191.      *
  192.      * @param packet
  193.      * @return the MUCUser PacketExtension or {@code null}
  194.      * @deprecated use {@link #from(Stanza)} instead
  195.      */
  196.     @Deprecated
  197.     public static MUCUser getFrom(Stanza packet) {
  198.         return from(packet);
  199.     }

  200.     /**
  201.      * Retrieve the MUCUser PacketExtension from packet, if any.
  202.      *
  203.      * @param packet
  204.      * @return the MUCUser PacketExtension or {@code null}
  205.      */
  206.     public static MUCUser from(Stanza packet) {
  207.         return packet.getExtension(ELEMENT, NAMESPACE);
  208.     }

  209.     /**
  210.      * Represents an invitation for another user to a room. The sender of the invitation
  211.      * must be an occupant of the room. The invitation will be sent to the room which in turn
  212.      * will forward the invitation to the invitee.
  213.      *
  214.      * @author Gaston Dombiak
  215.      */
  216.     public static class Invite implements NamedElement {
  217.         public static final String ELEMENT ="invite";

  218.         private String reason;
  219.         private String from;
  220.         private String to;

  221.         /**
  222.          * Returns the bare JID of the inviter or, optionally, the room JID. (e.g.
  223.          * 'crone1@shakespeare.lit/desktop').
  224.          *
  225.          * @return the room's occupant that sent the invitation.
  226.          */
  227.         public String getFrom() {
  228.             return from;
  229.         }

  230.         /**
  231.          * Returns the message explaining the invitation.
  232.          *
  233.          * @return the message explaining the invitation.
  234.          */
  235.         public String getReason() {
  236.             return reason;
  237.         }

  238.         /**
  239.          * Returns the bare JID of the invitee. (e.g. 'hecate@shakespeare.lit')
  240.          *
  241.          * @return the bare JID of the invitee.
  242.          */
  243.         public String getTo() {
  244.             return to;
  245.         }

  246.         /**
  247.          * Sets the bare JID of the inviter or, optionally, the room JID. (e.g.
  248.          * 'crone1@shakespeare.lit/desktop')
  249.          *
  250.          * @param from the bare JID of the inviter or, optionally, the room JID.
  251.          */
  252.         public void setFrom(String from) {
  253.             this.from = from;
  254.         }

  255.         /**
  256.          * Sets the message explaining the invitation.
  257.          *
  258.          * @param reason the message explaining the invitation.
  259.          */
  260.         public void setReason(String reason) {
  261.             this.reason = reason;
  262.         }

  263.         /**
  264.          * Sets the bare JID of the invitee. (e.g. 'hecate@shakespeare.lit')
  265.          *
  266.          * @param to the bare JID of the invitee.
  267.          */
  268.         public void setTo(String to) {
  269.             this.to = to;
  270.         }

  271.         @Override
  272.         public XmlStringBuilder toXML() {
  273.             XmlStringBuilder xml = new XmlStringBuilder(this);
  274.             xml.optAttribute("to", getTo());
  275.             xml.optAttribute("from", getFrom());
  276.             xml.rightAngleBracket();
  277.             xml.optElement("reason", getReason());
  278.             xml.closeElement(this);
  279.             return xml;
  280.         }

  281.         @Override
  282.         public String getElementName() {
  283.             return ELEMENT;
  284.         }
  285.     }

  286.     /**
  287.      * Represents a rejection to an invitation from another user to a room. The rejection will be
  288.      * sent to the room which in turn will forward the refusal to the inviter.
  289.      *
  290.      * @author Gaston Dombiak
  291.      */
  292.     public static class Decline implements NamedElement {
  293.         public static final String ELEMENT = "decline";

  294.         private String reason;
  295.         private String from;
  296.         private String to;

  297.         /**
  298.          * Returns the bare JID of the invitee that rejected the invitation. (e.g.
  299.          * 'crone1@shakespeare.lit/desktop').
  300.          *
  301.          * @return the bare JID of the invitee that rejected the invitation.
  302.          */
  303.         public String getFrom() {
  304.             return from;
  305.         }

  306.         /**
  307.          * Returns the message explaining why the invitation was rejected.
  308.          *
  309.          * @return the message explaining the reason for the rejection.
  310.          */
  311.         public String getReason() {
  312.             return reason;
  313.         }

  314.         /**
  315.          * Returns the bare JID of the inviter. (e.g. 'hecate@shakespeare.lit')
  316.          *
  317.          * @return the bare JID of the inviter.
  318.          */
  319.         public String getTo() {
  320.             return to;
  321.         }

  322.         /**
  323.          * Sets the bare JID of the invitee that rejected the invitation. (e.g.
  324.          * 'crone1@shakespeare.lit/desktop').
  325.          *
  326.          * @param from the bare JID of the invitee that rejected the invitation.
  327.          */
  328.         public void setFrom(String from) {
  329.             this.from = from;
  330.         }

  331.         /**
  332.          * Sets the message explaining why the invitation was rejected.
  333.          *
  334.          * @param reason the message explaining the reason for the rejection.
  335.          */
  336.         public void setReason(String reason) {
  337.             this.reason = reason;
  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.         @Override
  348.         public XmlStringBuilder toXML() {
  349.             XmlStringBuilder xml = new XmlStringBuilder(this);
  350.             xml.optAttribute("to", getTo());
  351.             xml.optAttribute("from", getFrom());
  352.             xml.rightAngleBracket();
  353.             xml.optElement("reason", getReason());
  354.             xml.closeElement(this);
  355.             return xml;
  356.         }

  357.         @Override
  358.         public String getElementName() {
  359.             return ELEMENT;
  360.         }
  361.     }

  362.     /**
  363.      * Status code assists in presenting notification messages. The following link provides the
  364.      * list of existing error codes <a href="http://xmpp.org/registrar/mucstatus.html">Multi-User Chat Status Codes</a>.
  365.      *
  366.      * @author Gaston Dombiak
  367.      */
  368.     public static class Status implements NamedElement {
  369.         public static final String ELEMENT = "status";

  370.         private static final Map<Integer, Status> statusMap = new HashMap<Integer, Status>(8);

  371.         public static final Status ROOM_CREATED_201 = Status.create(201);
  372.         public static final Status BANNED_301 = Status.create(301);
  373.         public static final Status NEW_NICKNAME_303 = Status.create(303);
  374.         public static final Status KICKED_307 = Status.create(307);
  375.         public static final Status REMOVED_AFFIL_CHANGE_321 = Status.create(321);

  376.         private final Integer code;

  377.         public static Status create(String string) {
  378.             Integer integer = Integer.valueOf(string);
  379.             return create(integer);
  380.         }

  381.         public static Status create(Integer i) {
  382.             Status status = statusMap.get(i);
  383.             if (status == null) {
  384.                 status = new Status(i);
  385.                 statusMap.put(i, status);
  386.             }
  387.             return status;
  388.         }

  389.         /**
  390.          * Creates a new instance of Status with the specified code.
  391.          *
  392.          * @param code the code that uniquely identifies the reason of the error.
  393.          */
  394.         private Status(int code) {
  395.             this.code = code;
  396.         }

  397.         /**
  398.          * Returns the code that uniquely identifies the reason of the error. The code
  399.          * assists in presenting notification messages.
  400.          *
  401.          * @return the code that uniquely identifies the reason of the error.
  402.          */
  403.         public int getCode() {
  404.             return code;
  405.         }

  406.         @Override
  407.         public XmlStringBuilder toXML() {
  408.             XmlStringBuilder xml = new XmlStringBuilder(this);
  409.             xml.attribute("code", getCode());
  410.             xml.closeEmptyElement();
  411.             return xml;
  412.         }

  413.         @Override
  414.         public boolean equals(Object other) {
  415.             if (other == null) {
  416.                 return false;
  417.             }
  418.             if (other instanceof Status) {
  419.                 Status otherStatus = (Status) other;
  420.                 return code.equals(otherStatus.getCode());
  421.             }
  422.             return false;
  423.         }

  424.         @Override
  425.         public int hashCode() {
  426.             return code;
  427.         }

  428.         @Override
  429.         public String getElementName() {
  430.             return ELEMENT;
  431.         }
  432.     }
  433. }