| /** |
| * $RCSfile$ |
| * $Revision$ |
| * $Date$ |
| * |
| * Copyright 2003-2007 Jive Software. |
| * |
| * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.jivesoftware.smackx.packet; |
| |
| import org.jivesoftware.smack.packet.PacketExtension; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| |
| /** |
| * Represents message events relating to the delivery, display, composition and cancellation of |
| * messages.<p> |
| * |
| * There are four message events currently defined in this namespace: |
| * <ol> |
| * <li>Offline<br> |
| * Indicates that the message has been stored offline by the intended recipient's server. This |
| * event is triggered only if the intended recipient's server supports offline storage, has that |
| * support enabled, and the recipient is offline when the server receives the message for delivery.</li> |
| * |
| * <li>Delivered<br> |
| * Indicates that the message has been delivered to the recipient. This signifies that the message |
| * has reached the recipient's XMPP client, but does not necessarily mean that the message has |
| * been displayed. This event is to be raised by the XMPP client.</li> |
| * |
| * <li>Displayed<br> |
| * Once the message has been received by the recipient's XMPP client, it may be displayed to the |
| * user. This event indicates that the message has been displayed, and is to be raised by the |
| * XMPP client. Even if a message is displayed multiple times, this event should be raised only |
| * once.</li> |
| * |
| * <li>Composing<br> |
| * In threaded chat conversations, this indicates that the recipient is composing a reply to a |
| * message. The event is to be raised by the recipient's XMPP client. A XMPP client is allowed |
| * to raise this event multiple times in response to the same request, providing the original |
| * event is cancelled first.</li> |
| * </ol> |
| * |
| * @author Gaston Dombiak |
| */ |
| public class MessageEvent implements PacketExtension { |
| |
| public static final String OFFLINE = "offline"; |
| public static final String COMPOSING = "composing"; |
| public static final String DISPLAYED = "displayed"; |
| public static final String DELIVERED = "delivered"; |
| public static final String CANCELLED = "cancelled"; |
| |
| private boolean offline = false; |
| private boolean delivered = false; |
| private boolean displayed = false; |
| private boolean composing = false; |
| private boolean cancelled = true; |
| |
| private String packetID = null; |
| |
| /** |
| * Returns the XML element name of the extension sub-packet root element. |
| * Always returns "x" |
| * |
| * @return the XML element name of the packet extension. |
| */ |
| public String getElementName() { |
| return "x"; |
| } |
| |
| /** |
| * Returns the XML namespace of the extension sub-packet root element. |
| * According the specification the namespace is always "jabber:x:event" |
| * |
| * @return the XML namespace of the packet extension. |
| */ |
| public String getNamespace() { |
| return "jabber:x:event"; |
| } |
| |
| /** |
| * When the message is a request returns if the sender of the message requests to be notified |
| * when the receiver is composing a reply. |
| * When the message is a notification returns if the receiver of the message is composing a |
| * reply. |
| * |
| * @return true if the sender is requesting to be notified when composing or when notifying |
| * that the receiver of the message is composing a reply |
| */ |
| public boolean isComposing() { |
| return composing; |
| } |
| |
| /** |
| * When the message is a request returns if the sender of the message requests to be notified |
| * when the message is delivered. |
| * When the message is a notification returns if the message was delivered or not. |
| * |
| * @return true if the sender is requesting to be notified when delivered or when notifying |
| * that the message was delivered |
| */ |
| public boolean isDelivered() { |
| return delivered; |
| } |
| |
| /** |
| * When the message is a request returns if the sender of the message requests to be notified |
| * when the message is displayed. |
| * When the message is a notification returns if the message was displayed or not. |
| * |
| * @return true if the sender is requesting to be notified when displayed or when notifying |
| * that the message was displayed |
| */ |
| public boolean isDisplayed() { |
| return displayed; |
| } |
| |
| /** |
| * When the message is a request returns if the sender of the message requests to be notified |
| * when the receiver of the message is offline. |
| * When the message is a notification returns if the receiver of the message was offline. |
| * |
| * @return true if the sender is requesting to be notified when offline or when notifying |
| * that the receiver of the message is offline |
| */ |
| public boolean isOffline() { |
| return offline; |
| } |
| |
| /** |
| * When the message is a notification returns if the receiver of the message cancelled |
| * composing a reply. |
| * |
| * @return true if the receiver of the message cancelled composing a reply |
| */ |
| public boolean isCancelled() { |
| return cancelled; |
| } |
| |
| /** |
| * Returns the unique ID of the message that requested to be notified of the event. |
| * The packet id is not used when the message is a request for notifications |
| * |
| * @return the message id that requested to be notified of the event. |
| */ |
| public String getPacketID() { |
| return packetID; |
| } |
| |
| /** |
| * Returns the types of events. The type of event could be: |
| * "offline", "composing","delivered","displayed", "offline" |
| * |
| * @return an iterator over all the types of events of the MessageEvent. |
| */ |
| public Iterator<String> getEventTypes() { |
| ArrayList<String> allEvents = new ArrayList<String>(); |
| if (isDelivered()) { |
| allEvents.add(MessageEvent.DELIVERED); |
| } |
| if (!isMessageEventRequest() && isCancelled()) { |
| allEvents.add(MessageEvent.CANCELLED); |
| } |
| if (isComposing()) { |
| allEvents.add(MessageEvent.COMPOSING); |
| } |
| if (isDisplayed()) { |
| allEvents.add(MessageEvent.DISPLAYED); |
| } |
| if (isOffline()) { |
| allEvents.add(MessageEvent.OFFLINE); |
| } |
| return allEvents.iterator(); |
| } |
| |
| /** |
| * When the message is a request sets if the sender of the message requests to be notified |
| * when the receiver is composing a reply. |
| * When the message is a notification sets if the receiver of the message is composing a |
| * reply. |
| * |
| * @param composing sets if the sender is requesting to be notified when composing or when |
| * notifying that the receiver of the message is composing a reply |
| */ |
| public void setComposing(boolean composing) { |
| this.composing = composing; |
| setCancelled(false); |
| } |
| |
| /** |
| * When the message is a request sets if the sender of the message requests to be notified |
| * when the message is delivered. |
| * When the message is a notification sets if the message was delivered or not. |
| * |
| * @param delivered sets if the sender is requesting to be notified when delivered or when |
| * notifying that the message was delivered |
| */ |
| public void setDelivered(boolean delivered) { |
| this.delivered = delivered; |
| setCancelled(false); |
| } |
| |
| /** |
| * When the message is a request sets if the sender of the message requests to be notified |
| * when the message is displayed. |
| * When the message is a notification sets if the message was displayed or not. |
| * |
| * @param displayed sets if the sender is requesting to be notified when displayed or when |
| * notifying that the message was displayed |
| */ |
| public void setDisplayed(boolean displayed) { |
| this.displayed = displayed; |
| setCancelled(false); |
| } |
| |
| /** |
| * When the message is a request sets if the sender of the message requests to be notified |
| * when the receiver of the message is offline. |
| * When the message is a notification sets if the receiver of the message was offline. |
| * |
| * @param offline sets if the sender is requesting to be notified when offline or when |
| * notifying that the receiver of the message is offline |
| */ |
| public void setOffline(boolean offline) { |
| this.offline = offline; |
| setCancelled(false); |
| } |
| |
| /** |
| * When the message is a notification sets if the receiver of the message cancelled |
| * composing a reply. |
| * The Cancelled event is never requested explicitly. It is requested implicitly when |
| * requesting to be notified of the Composing event. |
| * |
| * @param cancelled sets if the receiver of the message cancelled composing a reply |
| */ |
| public void setCancelled(boolean cancelled) { |
| this.cancelled = cancelled; |
| } |
| |
| /** |
| * Sets the unique ID of the message that requested to be notified of the event. |
| * The packet id is not used when the message is a request for notifications |
| * |
| * @param packetID the message id that requested to be notified of the event. |
| */ |
| public void setPacketID(String packetID) { |
| this.packetID = packetID; |
| } |
| |
| /** |
| * Returns true if this MessageEvent is a request for notifications. |
| * Returns false if this MessageEvent is a notification of an event. |
| * |
| * @return true if this message is a request for notifications. |
| */ |
| public boolean isMessageEventRequest() { |
| return this.packetID == null; |
| } |
| |
| /** |
| * Returns the XML representation of a Message Event according the specification. |
| * |
| * Usually the XML representation will be inside of a Message XML representation like |
| * in the following examples:<p> |
| * |
| * Request to be notified when displayed: |
| * <pre> |
| * <message |
| * to='romeo@montague.net/orchard' |
| * from='juliet@capulet.com/balcony' |
| * id='message22'> |
| * <x xmlns='jabber:x:event'> |
| * <displayed/> |
| * </x> |
| * </message> |
| * </pre> |
| * |
| * Notification of displayed: |
| * <pre> |
| * <message |
| * from='romeo@montague.net/orchard' |
| * to='juliet@capulet.com/balcony'> |
| * <x xmlns='jabber:x:event'> |
| * <displayed/> |
| * <id>message22</id> |
| * </x> |
| * </message> |
| * </pre> |
| * |
| */ |
| public String toXML() { |
| StringBuilder buf = new StringBuilder(); |
| buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append( |
| "\">"); |
| // Note: Cancellation events don't specify any tag. They just send the packetID |
| |
| // Add the offline tag if the sender requests to be notified of offline events or if |
| // the target is offline |
| if (isOffline()) |
| buf.append("<").append(MessageEvent.OFFLINE).append("/>"); |
| // Add the delivered tag if the sender requests to be notified when the message is |
| // delivered or if the target notifies that the message has been delivered |
| if (isDelivered()) |
| buf.append("<").append(MessageEvent.DELIVERED).append("/>"); |
| // Add the displayed tag if the sender requests to be notified when the message is |
| // displayed or if the target notifies that the message has been displayed |
| if (isDisplayed()) |
| buf.append("<").append(MessageEvent.DISPLAYED).append("/>"); |
| // Add the composing tag if the sender requests to be notified when the target is |
| // composing a reply or if the target notifies that he/she is composing a reply |
| if (isComposing()) |
| buf.append("<").append(MessageEvent.COMPOSING).append("/>"); |
| // Add the id tag only if the MessageEvent is a notification message (not a request) |
| if (getPacketID() != null) |
| buf.append("<id>").append(getPacketID()).append("</id>"); |
| buf.append("</").append(getElementName()).append(">"); |
| return buf.toString(); |
| } |
| |
| } |