Initial check-in of message event support.

git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@2024 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
Gaston Dombiak 2003-08-13 12:59:24 +00:00 committed by gdombiak
parent 7a78ab7aa4
commit 243c73ef49
9 changed files with 1773 additions and 0 deletions

View File

@ -0,0 +1,122 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx;
/**
*
* Default implementation of the MessageEventRequestListener interface.<p>
*
* This class automatically sends a delivered notification to the sender of the message
* if the sender has requested to be notified when the message is delivered.
*
* @author Gaston Dombiak
*/
public class DefaultMessageEventRequestListener implements MessageEventRequestListener {
/**
* Called when a request of message delivered notification is received. The default
* behavior is to automatically respond that the message has been delivered.
*
* @param from the user that sent the notification.
* @param packetId the id of the message that was sent.
* @param messageEventManager the messageEventManager that fired the listener.
*/
public void deliveredNotificationRequested(
String from,
String packetID,
MessageEventManager messageEventManager) {
// Send to the message's sender that the message has been delivered
messageEventManager.sendDeliveredNotification(from, packetID);
}
/**
* Called when a request of message displayed notification is received.
*
* @param from the user that sent the notification.
* @param packetId the id of the message that was sent.
* @param messageEventManager the messageEventManager that fired the listener.
*/
public void displayedNotificationRequested(
String from,
String packetID,
MessageEventManager messageEventManager) {
}
/**
* Called when a request that the receiver of the message is composing a reply notification is
* received.
*
* @param from the user that sent the notification.
* @param packetId the id of the message that was sent.
* @param messageEventManager the messageEventManager that fired the listener.
*/
public void composingNotificationRequested(
String from,
String packetID,
MessageEventManager messageEventManager) {
}
/**
* Called when a request that the receiver of the message is offline is received.
*
* @param from the user that sent the notification.
* @param packetId the id of the message that was sent.
* @param messageEventManager the messageEventManager that fired the listener.
*/
public void offlineNotificationRequested(
String from,
String packetID,
MessageEventManager messageEventManager) {
}
}

View File

@ -0,0 +1,338 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.filter.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smackx.packet.*;
/**
*
* Manages message events requests and notifications. A MessageEventManager provides a high
* level access to request for notifications and send event notifications. It also provides
* an easy way to hook up custom logic when requests or notifications are received.
*
* @author Gaston Dombiak
*/
public class MessageEventManager {
private List messageEventNotificationListeners = new ArrayList();
private List messageEventRequestListeners = new ArrayList();
private XMPPConnection con;
private PacketFilter packetFilter = new PacketExtensionFilter("x", "jabber:x:event");
private PacketListener packetListener;
/**
* Creates a new roster exchange manager.
*
* @param con an XMPPConnection.
*/
public MessageEventManager(XMPPConnection con) {
this.con = con;
init();
}
/**
* Adds to the message the requests to notify to the sender of the message for certain events.
*
* @param message the message to add the requested notifications
* @param offline specifies if the offline event is requested
* @param delivered specifies if the delivered event is requested
* @param displayed specifies if the displayed event is requested
* @param composing specifies if the composing event is requested
*/
public static void addNotificationsRequests(
Message message,
boolean offline,
boolean delivered,
boolean displayed,
boolean composing) {
// Create a MessageEvent Package and add it to the message
MessageEvent messageEvent = new MessageEvent();
messageEvent.setOffline(offline);
messageEvent.setDelivered(delivered);
messageEvent.setDisplayed(displayed);
messageEvent.setComposing(composing);
message.addExtension(messageEvent);
}
/**
* Adds a message event request listener. The listener will be fired anytime a request for
* event notification is received.
*
* @param messageEventRequestListener a message event request listener.
*/
public void addMessageEventRequestListener(MessageEventRequestListener messageEventRequestListener) {
synchronized (messageEventRequestListeners) {
if (!messageEventRequestListeners.contains(messageEventRequestListener)) {
messageEventRequestListeners.add(messageEventRequestListener);
}
}
}
/**
* Removes a message event request listener. The listener will be fired anytime a request for
* event notification is received.
*
* @param messageEventRequestListener a message event request listener.
*/
public void removeMessageEventRequestListener(MessageEventRequestListener messageEventRequestListener) {
synchronized (messageEventRequestListeners) {
messageEventRequestListeners.remove(messageEventRequestListener);
}
}
/**
* Adds a message event notification listener. The listener will be fired anytime a notification
* event is received.
*
* @param messageEventNotificationListener a message event notification listener.
*/
public void addMessageEventNotificationListener(MessageEventNotificationListener messageEventNotificationListener) {
synchronized (messageEventNotificationListeners) {
if (!messageEventNotificationListeners.contains(messageEventNotificationListener)) {
messageEventNotificationListeners.add(messageEventNotificationListener);
}
}
}
/**
* Removes a message event notification listener. The listener will be fired anytime a notification
* event is received.
*
* @param messageEventNotificationListener a message event notification listener.
*/
public void removeMessageEventNotificationListener(MessageEventNotificationListener messageEventNotificationListener) {
synchronized (messageEventNotificationListeners) {
messageEventNotificationListeners.remove(messageEventNotificationListener);
}
}
/**
* Fires message event request listeners.
*/
private void fireMessageEventRequestListeners(
String from,
String packetID,
String methodName) {
MessageEventRequestListener[] listeners = null;
Method method;
synchronized (messageEventRequestListeners) {
listeners = new MessageEventRequestListener[messageEventRequestListeners.size()];
messageEventRequestListeners.toArray(listeners);
}
try {
method =
MessageEventRequestListener.class.getDeclaredMethod(
methodName,
new Class[] { String.class, String.class, MessageEventManager.class });
for (int i = 0; i < listeners.length; i++) {
method.invoke(listeners[i], new Object[] { from, packetID, this });
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
/**
* Fires message event notification listeners.
*/
private void fireMessageEventNotificationListeners(
String from,
String packetID,
String methodName) {
MessageEventNotificationListener[] listeners = null;
Method method;
synchronized (messageEventNotificationListeners) {
listeners =
new MessageEventNotificationListener[messageEventNotificationListeners.size()];
messageEventNotificationListeners.toArray(listeners);
}
try {
method =
MessageEventNotificationListener.class.getDeclaredMethod(
methodName,
new Class[] { String.class, String.class });
for (int i = 0; i < listeners.length; i++) {
method.invoke(listeners[i], new Object[] { from, packetID });
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
private void init() {
// Listens for all message event packets and fire the proper message event listeners.
packetListener = new PacketListener() {
public void processPacket(Packet packet) {
Message message = (Message) packet;
MessageEvent messageEvent =
(MessageEvent) message.getExtension("x", "jabber:x:event");
if (messageEvent.isMessageEventRequest()) {
// Fire event for requests of message events
for (Iterator it = messageEvent.getEventTypes(); it.hasNext();)
fireMessageEventRequestListeners(
message.getFrom(),
message.getPacketID(),
((String) it.next()).concat("NotificationRequested"));
} else
// Fire event for notifications of message events
for (Iterator it = messageEvent.getEventTypes(); it.hasNext();)
fireMessageEventNotificationListeners(
message.getFrom(),
messageEvent.getPacketID(),
((String) it.next()).concat("Notification"));
};
};
con.addPacketListener(packetListener, packetFilter);
}
/**
* Sends the notification that the message was delivered to the sender of the original message
*
* @param to the recipient of the notification.
* @param packetId the id of the message to send.
*/
public void sendDeliveredNotification(String to, String packetID) {
// Create the message to send
Message msg = new Message(to);
// Create a MessageEvent Package and add it to the message
MessageEvent messageEvent = new MessageEvent();
messageEvent.setDelivered(true);
messageEvent.setPacketID(packetID);
msg.addExtension(messageEvent);
// Send the packet
con.sendPacket(msg);
}
/**
* Sends the notification that the message was displayed to the sender of the original message
*
* @param to the recipient of the notification.
* @param packetId the id of the message to send.
*/
public void sendDisplayedNotification(String to, String packetID) {
// Create the message to send
Message msg = new Message(to);
// Create a MessageEvent Package and add it to the message
MessageEvent messageEvent = new MessageEvent();
messageEvent.setDisplayed(true);
messageEvent.setPacketID(packetID);
msg.addExtension(messageEvent);
// Send the packet
con.sendPacket(msg);
}
/**
* Sends the notification that the receiver of the message is composing a reply
*
* @param to the recipient of the notification.
* @param packetId the id of the message to send.
*/
public void sendComposingNotification(String to, String packetID) {
// Create the message to send
Message msg = new Message(to);
// Create a MessageEvent Package and add it to the message
MessageEvent messageEvent = new MessageEvent();
messageEvent.setComposing(true);
messageEvent.setPacketID(packetID);
msg.addExtension(messageEvent);
// Send the packet
con.sendPacket(msg);
}
/**
* Sends the notification that the receiver of the message has cancelled composing a reply
*
* @param to the recipient of the notification.
* @param packetId the id of the message to send.
*/
public void sendCancelledNotification(String to, String packetID) {
// Create the message to send
Message msg = new Message(to);
// Create a MessageEvent Package and add it to the message
MessageEvent messageEvent = new MessageEvent();
messageEvent.setCancelled(true);
messageEvent.setPacketID(packetID);
msg.addExtension(messageEvent);
// Send the packet
con.sendPacket(msg);
}
public void destroy() {
if (con != null)
con.removePacketListener(packetListener);
}
public void finalize() {
destroy();
}
}

View File

@ -0,0 +1,106 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx;
/**
*
* A listener that is fired anytime a message event notification is received.
* Message event notifications are received as a consequence of the request
* to receive notifications when sending a message.
*
* @author Gaston Dombiak
*/
public interface MessageEventNotificationListener {
/**
* Called when a notification of message delivered is received.
*
* @param from the user that sent the notification.
* @param packetId the id of the message that was sent.
*/
public void deliveredNotification(String from, String packetID);
/**
* Called when a notification of message displayed is received.
*
* @param from the user that sent the notification.
* @param packetId the id of the message that was sent.
*/
public void displayedNotification(String from, String packetID);
/**
* Called when a notification that the receiver of the message is composing a reply is
* received.
*
* @param from the user that sent the notification.
* @param packetId the id of the message that was sent.
*/
public void composingNotification(String from, String packetID);
/**
* Called when a notification that the receiver of the message is offline is received.
*
* @param from the user that sent the notification.
* @param packetId the id of the message that was sent.
*/
public void offlineNotification(String from, String packetID);
/**
* Called when a notification that the receiver of the message cancelled the reply
* is received.
*
* @param from the user that sent the notification.
* @param packetId the id of the message that was sent.
*/
public void cancelledNotification(String from, String packetID);
}

View File

@ -0,0 +1,124 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx;
/**
*
* A listener that is fired anytime a message event request is received.
* Message event requests are received when the received message includes an extension
* like this:
*
* <x xmlns='jabber:x:event'>
* <offline/>
* <delivered/>
* <composing/>
* </x>
*
* In this example you can see that the sender of the message requests to be notified
* when the user couldn't receive the message because he/she is offline, the message
* was delivered or when the receiver of the message is composing a reply.
*
* @author Gaston Dombiak
*/
public interface MessageEventRequestListener {
/**
* Called when a request for message delivered notification is received.
*
* @param from the user that sent the notification.
* @param packetId the id of the message that was sent.
* @param messageEventManager the messageEventManager that fired the listener.
*/
public void deliveredNotificationRequested(
String from,
String packetID,
MessageEventManager messageEventManager);
/**
* Called when a request for message displayed notification is received.
*
* @param from the user that sent the notification.
* @param packetId the id of the message that was sent.
* @param messageEventManager the messageEventManager that fired the listener.
*/
public void displayedNotificationRequested(
String from,
String packetID,
MessageEventManager messageEventManager);
/**
* Called when a request that the receiver of the message is composing a reply notification is
* received.
*
* @param from the user that sent the notification.
* @param packetId the id of the message that was sent.
* @param messageEventManager the messageEventManager that fired the listener.
*/
public void composingNotificationRequested(
String from,
String packetID,
MessageEventManager messageEventManager);
/**
* Called when a request that the receiver of the message is offline is received.
*
* @param from the user that sent the notification.
* @param packetId the id of the message that was sent.
* @param messageEventManager the messageEventManager that fired the listener.
*/
public void offlineNotificationRequested(
String from,
String packetID,
MessageEventManager messageEventManager);
}

View File

@ -0,0 +1,360 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx.packet;
import java.util.*;
import org.jivesoftware.smack.packet.PacketExtension;
/**
* Represents message events relating to the delivery, display, composition and cancellation of
* messages.
*
* There are four message events currently defined in this namespace:
* 1.Offline
* 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.
*
* 2.Delivered
* 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.
*
* 3.Displayed
* 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.
*
* 4.Composing
* 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.
*
* @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 getEventTypes() {
ArrayList allEvents = new ArrayList();
if (isDelivered()) {
allEvents.add(MessageEvent.DELIVERED);
}
if (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:
*
* Request to be notified when displayed:
* <message
* to='romeo@montague.net/orchard'
* from='juliet@capulet.com/balcony'
* id='message22'>
* <x xmlns='jabber:x:event'>
* <displayed/>
* </x>
* </message>
*
* Notification of displayed:
* <message
* from='romeo@montague.net/orchard'
* to='juliet@capulet.com/balcony'>
* <x xmlns='jabber:x:event'>
* <displayed/>
* <id>message22</id>
* </x>
* </message>
*
*/
public String toXML() {
StringBuffer buf = new StringBuffer();
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();
}
}

View File

@ -0,0 +1,109 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx.provider;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.provider.PacketExtensionProvider;
import org.jivesoftware.smackx.packet.MessageEvent;
import org.xmlpull.v1.XmlPullParser;
/**
*
* The MessageEventProvider parses Message Event packets.
*
* @author Gaston Dombiak
*/
public class MessageEventProvider implements PacketExtensionProvider {
/**
* Creates a new MessageEventProvider.
* ProviderManager requires that every PacketExtensionProvider has a public, no-argument constructor
*/
public MessageEventProvider() {
}
/**
* Parses a MessageEvent packet (extension sub-packet).
*
* @param parser the XML parser, positioned at the starting element of the extension.
* @return a PacketExtension.
* @throws Exception if a parsing error occurs.
*/
public PacketExtension parseExtension(XmlPullParser parser)
throws Exception {
MessageEvent messageEvent = new MessageEvent();
boolean done = false;
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("id"))
messageEvent.setPacketID(parser.nextText());
if (parser.getName().equals(MessageEvent.COMPOSING))
messageEvent.setComposing(true);
if (parser.getName().equals(MessageEvent.DELIVERED))
messageEvent.setDelivered(true);
if (parser.getName().equals(MessageEvent.DISPLAYED))
messageEvent.setDisplayed(true);
if (parser.getName().equals(MessageEvent.OFFLINE))
messageEvent.setOffline(true);
} else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("x")) {
done = true;
}
}
}
return messageEvent;
}
}

View File

@ -0,0 +1,335 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx;
import java.util.ArrayList;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.packet.*;
import junit.framework.TestCase;
/**
*
* Test the MessageEvent extension using the high level API.
*
* @author Gaston Dombiak
*/
public class MessageEventManagerTest extends TestCase {
/**
* Constructor for MessageEventManagerTest.
* @param name
*/
public MessageEventManagerTest(String name) {
super(name);
}
/**
* High level API test.
* This is a simple test to use with a XMPP client and check if the client receives the
* message
* 1. User_1 will send a message to user_2 requesting to be notified when any of these events
* occurs: offline, composing, displayed or delivered
*/
public void testSendMessageEventRequest() {
String host = "localhost";
String server_user1 = "gato3";
String user1 = "gato3@localhost";
String pass1 = "gato3";
String user2 = "gato4@localhost";
XMPPConnection conn1 = null;
try {
// Connect to the server and log in the users
conn1 = new XMPPConnection(host);
conn1.login(server_user1, pass1);
// Create a chat for each connection
Chat chat1 = conn1.createChat(user2);
// Create the message to send with the roster
Message msg = chat1.createMessage();
msg.setSubject("Any subject you want");
msg.setBody("An interesting body comes here...");
// Add to the message all the notifications requests (offline, delivered, displayed,
// composing)
MessageEventManager.addNotificationsRequests(msg, true, true, true, true);
// Send the message that contains the notifications request
try {
chat1.sendMessage(msg);
} catch (Exception e) {
fail("An error occured sending the message");
}
} catch (Exception e) {
fail(e.toString());
} finally {
if (conn1 != null)
conn1.close();
}
}
/**
* High level API test.
* This is a simple test to use with a XMPP client, check if the client receives the
* message and display in the console any notification
* 1. User_1 will send a message to user_2 requesting to be notified when any of these events
* occurs: offline, composing, displayed or delivered
* 2. User_2 will use a XMPP client (like Exodus) to display the message and compose a reply
* 3. User_1 will display any notification that receives
*/
public void testSendMessageEventRequestAndDisplayNotifications() {
String host = "localhost";
String server_user1 = "gato3";
String user1 = "gato3@localhost";
String pass1 = "gato3";
String user2 = "gato4@localhost";
XMPPConnection conn1 = null;
try {
// Connect to the server and log in the users
conn1 = new XMPPConnection(host);
conn1.login(server_user1, pass1);
// Create a chat for each connection
Chat chat1 = conn1.createChat(user2);
MessageEventManager messageEventManager = new MessageEventManager(conn1);
messageEventManager
.addMessageEventNotificationListener(new MessageEventNotificationListener() {
public void deliveredNotification(String from, String packetID) {
System.out.println("From: " + from + " PacketID: " + packetID + "(delivered)");
}
public void displayedNotification(String from, String packetID) {
System.out.println("From: " + from + " PacketID: " + packetID + "(displayed)");
}
public void composingNotification(String from, String packetID) {
System.out.println("From: " + from + " PacketID: " + packetID + "(composing)");
}
public void offlineNotification(String from, String packetID) {
System.out.println("From: " + from + " PacketID: " + packetID + "(offline)");
}
public void cancelledNotification(String from, String packetID) {
System.out.println("From: " + from + " PacketID: " + packetID + "(cancelled)");
}
});
// Create the message to send with the roster
Message msg = chat1.createMessage();
msg.setSubject("Any subject you want");
msg.setBody("An interesting body comes here...");
// Add to the message all the notifications requests (offline, delivered, displayed,
// composing)
MessageEventManager.addNotificationsRequests(msg, true, true, true, true);
// Send the message that contains the notifications request
try {
chat1.sendMessage(msg);
// Wait a few seconds so that the XMPP client can send any event
Thread.sleep(5000);
} catch (Exception e) {
fail("An error occured sending the message");
}
} catch (Exception e) {
fail(e.toString());
} finally {
if (conn1 != null)
conn1.close();
}
}
/**
* High level API test.
* 1. User_1 will send a message to user_2 requesting to be notified when any of these events
* occurs: offline, composing, displayed or delivered
* 2. User_2 will receive the message
* 3. User_2 will simulate that the message was displayed
* 4. User_2 will simulate that he/she is composing a reply
* 5. User_2 will simulate that he/she has cancelled the reply
*/
public void testRequestsAndNotifications() {
String host = "localhost";
String server_user1 = "gato3";
String user1 = "gato3@localhost";
String pass1 = "gato3";
String server_user2 = "gato4";
String user2 = "gato4@localhost";
String pass2 = "gato4";
XMPPConnection conn1 = null;
XMPPConnection conn2 = null;
final ArrayList results = new ArrayList();
ArrayList resultsExpected = new ArrayList();
resultsExpected.add("deliveredNotificationRequested");
resultsExpected.add("composingNotificationRequested");
resultsExpected.add("displayedNotificationRequested");
resultsExpected.add("offlineNotificationRequested");
resultsExpected.add("deliveredNotification");
resultsExpected.add("displayedNotification");
resultsExpected.add("composingNotification");
resultsExpected.add("cancelledNotification");
try {
// Connect to the server and log in the users
conn1 = new XMPPConnection(host);
conn1.login(server_user1, pass1);
conn2 = new XMPPConnection(host);
conn2.login(server_user2, pass2);
// Create a chat for each connection
Chat chat1 = conn1.createChat(user2);
MessageEventManager messageEventManager1 = new MessageEventManager(conn1);
messageEventManager1
.addMessageEventNotificationListener(new MessageEventNotificationListener() {
public void deliveredNotification(String from, String packetID) {
results.add("deliveredNotification");
}
public void displayedNotification(String from, String packetID) {
results.add("displayedNotification");
}
public void composingNotification(String from, String packetID) {
results.add("composingNotification");
}
public void offlineNotification(String from, String packetID) {
results.add("offlineNotification");
}
public void cancelledNotification(String from, String packetID) {
results.add("cancelledNotification");
}
});
MessageEventManager messageEventManager2 = new MessageEventManager(conn2);
messageEventManager2
.addMessageEventRequestListener(new DefaultMessageEventRequestListener() {
public void deliveredNotificationRequested(
String from,
String packetID,
MessageEventManager messageEventManager) {
super.deliveredNotificationRequested(from, packetID, messageEventManager);
results.add("deliveredNotificationRequested");
}
public void displayedNotificationRequested(
String from,
String packetID,
MessageEventManager messageEventManager) {
super.displayedNotificationRequested(from, packetID, messageEventManager);
results.add("displayedNotificationRequested");
}
public void composingNotificationRequested(
String from,
String packetID,
MessageEventManager messageEventManager) {
super.composingNotificationRequested(from, packetID, messageEventManager);
results.add("composingNotificationRequested");
}
public void offlineNotificationRequested(
String from,
String packetID,
MessageEventManager messageEventManager) {
super.offlineNotificationRequested(from, packetID, messageEventManager);
results.add("offlineNotificationRequested");
}
});
// Create the message to send with the roster
Message msg = chat1.createMessage();
msg.setSubject("Any subject you want");
msg.setBody("An interesting body comes here...");
// Add to the message all the notifications requests (offline, delivered, displayed,
// composing)
MessageEventManager.addNotificationsRequests(msg, true, true, true, true);
// Send the message that contains the notifications request
try {
chat1.sendMessage(msg);
messageEventManager2.sendDisplayedNotification(user1, msg.getPacketID());
messageEventManager2.sendComposingNotification(user1, msg.getPacketID());
messageEventManager2.sendCancelledNotification(user1, msg.getPacketID());
// Wait half second so that the complete test can run
Thread.sleep(500);
assertTrue("Test failed due to bad results (1)" + resultsExpected, resultsExpected.containsAll(results));
assertTrue("Test failed due to bad results (2)" + results, results.containsAll(resultsExpected));
} catch (Exception e) {
fail("An error occured sending the message");
}
} catch (Exception e) {
fail(e.toString());
} finally {
if (conn1 != null)
conn1.close();
if (conn2 != null)
conn2.close();
}
}
}

View File

@ -0,0 +1,76 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx;
import org.jivesoftware.smackx.packet.MessageEventTest;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
*
* Test suite that runs all the Message Event extension tests
*
* @author Gaston Dombiak
*/
public class MessageEventTests extends RosterExchangeTests {
public static Test suite() {
TestSuite suite = new TestSuite("High and low level API tests for message event extension");
//$JUnit-BEGIN$
suite.addTest(new TestSuite(MessageEventManagerTest.class));
suite.addTest(new TestSuite(MessageEventTest.class));
//$JUnit-END$
return suite;
}
}

View File

@ -0,0 +1,203 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx.packet;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.filter.*;
import org.jivesoftware.smack.packet.*;
import junit.framework.TestCase;
/**
*
* Test the MessageEvent extension using the low level API
*
* @author Gaston Dombiak
*/
public class MessageEventTest extends TestCase {
/**
* Constructor for MessageEventTest.
* @param name
*/
public MessageEventTest(String name) {
super(name);
}
/**
* Low level API test.
* This is a simple test to use with a XMPP client and check if the client receives the
* message
* 1. User_1 will send a message to user_2 requesting to be notified when any of these events
* occurs: offline, composing, displayed or delivered
*/
public void testSendMessageEventRequest() {
String host = "localhost";
String server_user1 = "gato3";
String user1 = "gato3@localhost";
String pass1 = "gato3";
String user2 = "gato4@localhost";
XMPPConnection conn1 = null;
try {
// Connect to the server and log in the users
conn1 = new XMPPConnection(host);
conn1.login(server_user1, pass1);
// Create a chat for each connection
Chat chat1 = conn1.createChat(user2);
// Create the message to send with the roster
Message msg = chat1.createMessage();
msg.setSubject("Any subject you want");
msg.setBody("An interesting body comes here...");
// Create a MessageEvent Package and add it to the message
MessageEvent messageEvent = new MessageEvent();
messageEvent.setComposing(true);
messageEvent.setDelivered(true);
messageEvent.setDisplayed(true);
messageEvent.setOffline(true);
msg.addExtension(messageEvent);
// Send the message that contains the notifications request
try {
chat1.sendMessage(msg);
// Wait half second so that the complete test can run
Thread.sleep(500);
} catch (Exception e) {
fail("An error occured sending the message");
}
} catch (Exception e) {
fail(e.toString());
} finally {
if (conn1 != null)
conn1.close();
}
}
/**
* Low level API test.
* This is a simple test to use with a XMPP client, check if the client receives the
* message and display in the console any notification
* 1. User_1 will send a message to user_2 requesting to be notified when any of these events
* occurs: offline, composing, displayed or delivered
* 2. User_2 will use a XMPP client (like Exodus) to display the message and compose a reply
* 3. User_1 will display any notification that receives
*/
public void testSendMessageEventRequestAndDisplayNotifications() {
String host = "localhost";
String server_user1 = "gato3";
String user1 = "gato3@localhost";
String pass1 = "gato3";
String user2 = "gato4@localhost";
XMPPConnection conn1 = null;
try {
// Connect to the server and log in the users
conn1 = new XMPPConnection(host);
conn1.login(server_user1, pass1);
// Create a chat for each connection
Chat chat1 = conn1.createChat(user2);
// Create a Listener that listens for Messages with the extension "jabber:x:roster"
// This listener will listen on the conn2 and answer an ACK if everything is ok
PacketFilter packetFilter = new PacketExtensionFilter("x", "jabber:x:event");
PacketListener packetListener = new PacketListener() {
public void processPacket(Packet packet) {
Message message = (Message) packet;
try {
MessageEvent messageEvent = (MessageEvent) message.getExtension("x", "jabber:x:event");
assertNotNull("Message without extension \"jabber:x:event\"", messageEvent);
assertTrue("Message event is a request not a notification", !messageEvent.isMessageEventRequest());
System.out.println(messageEvent.toXML());
} catch (ClassCastException e) {
fail("ClassCastException - Most probable cause is that smack providers is misconfigured");
}
}
};
conn1.addPacketListener(packetListener, packetFilter);
// Create the message to send with the roster
Message msg = chat1.createMessage();
msg.setSubject("Any subject you want");
msg.setBody("An interesting body comes here...");
// Create a MessageEvent Package and add it to the message
MessageEvent messageEvent = new MessageEvent();
messageEvent.setComposing(true);
messageEvent.setDelivered(true);
messageEvent.setDisplayed(true);
messageEvent.setOffline(true);
msg.addExtension(messageEvent);
// Send the message that contains the notifications request
try {
chat1.sendMessage(msg);
// Wait half second so that the complete test can run
Thread.sleep(500);
} catch (Exception e) {
fail("An error occured sending the message");
}
} catch (Exception e) {
fail(e.toString());
} finally {
if (conn1 != null)
conn1.close();
}
}
}