diff --git a/build/junit.jar b/build/junit.jar
index 02ac8fb5b..ff5d1888f 100644
Binary files a/build/junit.jar and b/build/junit.jar differ
diff --git a/build/projects/Smack.iml b/build/projects/Smack.iml
index ab5a89e70..41776e4f0 100644
--- a/build/projects/Smack.iml
+++ b/build/projects/Smack.iml
@@ -9,6 +9,7 @@
+
@@ -31,15 +32,6 @@
-
-
-
-
-
-
-
-
-
@@ -49,12 +41,23 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/projects/Smack.ipr b/build/projects/Smack.ipr
index 6dc40be2a..51eb13f8f 100644
--- a/build/projects/Smack.ipr
+++ b/build/projects/Smack.ipr
@@ -286,10 +286,43 @@
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/projects/SmackUnitTest.iml b/build/projects/SmackUnitTest.iml
new file mode 100644
index 000000000..195964750
--- /dev/null
+++ b/build/projects/SmackUnitTest.iml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/org/jivesoftware/smack/packet/Message.java b/source/org/jivesoftware/smack/packet/Message.java
index 7f6429465..0e9bcfc69 100644
--- a/source/org/jivesoftware/smack/packet/Message.java
+++ b/source/org/jivesoftware/smack/packet/Message.java
@@ -22,6 +22,8 @@ package org.jivesoftware.smack.packet;
import org.jivesoftware.smack.util.StringUtils;
+import java.util.*;
+
/**
* Represents XMPP message packets. A message can be one of several types:
*
@@ -50,8 +52,10 @@ public class Message extends Packet {
private Type type = Type.normal;
private String subject = null;
- private String body = null;
private String thread = null;
+ private String language;
+
+ private final Set bodies = new HashSet();
/**
* Creates a new, "normal" message.
@@ -65,9 +69,6 @@ public class Message extends Packet {
* @param to the recipient of the message.
*/
public Message(String to) {
- if (to == null) {
- throw new IllegalArgumentException("Parameter cannot be null");
- }
setTo(to);
}
@@ -78,15 +79,13 @@ public class Message extends Packet {
* @param type the message type.
*/
public Message(String to, Type type) {
- if (to == null || type == null) {
- throw new IllegalArgumentException("Parameters cannot be null.");
- }
setTo(to);
this.type = type;
}
/**
- * Returns the type of the message.
+ * Returns the type of the message. If no type has been set this method will return {@link
+ * org.jivesoftware.smack.packet.Message.Type#normal}.
*
* @return the type of the message.
*/
@@ -98,6 +97,7 @@ public class Message extends Packet {
* Sets the type of the message.
*
* @param type the type of the message.
+ * @throws IllegalArgumentException if null is passed in as the type
*/
public void setType(Type type) {
if (type == null) {
@@ -133,16 +133,115 @@ public class Message extends Packet {
* @return the body of the message.
*/
public String getBody() {
- return body;
+ return getBody(null);
+ }
+
+ /**
+ * Returns the body corresponding to the language. If the language is null, the method result
+ * will be the same as {@link #getBody()}. Null will be returned if the language does not have
+ * a corresponding body.
+ *
+ * @param language the language of the body to return.
+ * @return the body related to the passed in language.
+ * @since 3.0.2
+ */
+ public String getBody(String language) {
+ language = parseXMLLang(language);
+ for (Body body : bodies) {
+ if ((body.langauge == null && language == null)
+ || (body != null && body.langauge.equals(language))) {
+ return body.message;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns a set of all bodies in this Message, including the default message body accessible
+ * from {@link #getBody()}.
+ *
+ * @return a collection of all bodies in this Message.
+ * @since 3.0.2
+ */
+ public Collection getBodies() {
+ return Collections.unmodifiableCollection(bodies);
}
/**
* Sets the body of the message. The body is the main message contents.
- *
+ *
* @param body the body of the message.
*/
public void setBody(String body) {
- this.body = body;
+ if (body == null) {
+ removeBody("");
+ return;
+ }
+ addBody(null, body);
+ }
+
+ /**
+ * Adds a body with a corresponding language.
+ *
+ * @param language the language of the body being added.
+ * @param body the body being added to the message.
+ * @return the new {@link org.jivesoftware.smack.packet.Message.Body}
+ * @throws NullPointerException if the body is null, a null pointer exception is thrown
+ * @since 3.0.2
+ */
+ public Body addBody(String language, String body) {
+ if (body == null) {
+ throw new NullPointerException("Body must be specified");
+ }
+ language = parseXMLLang(language);
+
+ Body messageBody = new Body(language, body);
+ bodies.add(messageBody);
+ return messageBody;
+ }
+
+ /**
+ * Removes the body with the given language from the message.
+ *
+ * @param language the language of the body which is to be removed
+ * @return true if a body was removed and false if it was not.
+ */
+ public boolean removeBody(String language) {
+ language = parseXMLLang(language);
+
+ for (Body body : bodies) {
+ if (language.equals(body.langauge)) {
+ return bodies.remove(body);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Removes the body from the message and returns true if the body was removed.
+ *
+ * @param body the body being removed from the message.
+ * @return true if the body was successfully removed and false if it was not.
+ * @since 3.0.2
+ */
+ public boolean removeBody(Body body) {
+ return bodies.remove(body);
+ }
+
+ /**
+ * Returns all the languages being used for the bodies, not including the default body.
+ *
+ * @return the languages being used for the bodies.
+ * @since 3.0.2
+ */
+ public Collection getBodyLanguages() {
+ List languages = new ArrayList(bodies.size());
+ for (Body body : bodies) {
+ if (!parseXMLLang(body.langauge).equals(getDefaultLanguage())) {
+ languages.add(body.langauge);
+ }
+ }
+ return Collections.unmodifiableCollection(languages);
}
/**
@@ -165,9 +264,35 @@ public class Message extends Packet {
this.thread = thread;
}
+ /**
+ * Returns the xml:lang of this Message.
+ *
+ * @return the xml:lang of this Message.
+ * @since 3.0.2
+ */
+ private String getLanguage() {
+ return language;
+ }
+
+ /**
+ * Sets the xml:lang of this Message.
+ *
+ * @param language the xml:lang of this Message.
+ * @since 3.0.2
+ */
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
public String toXML() {
StringBuilder buf = new StringBuilder();
buf.append("").append(StringUtils.escapeForXML(subject)).append("");
}
- if (body != null) {
- buf.append("").append(StringUtils.escapeForXML(body)).append("");
+ // Add the body in the default language
+ if (getBody() != null) {
+ buf.append("").append(StringUtils.escapeForXML(getBody())).append("");
+ }
+ // Add the bodies in other languages
+ for (Body body : getBodies()) {
+ // Skip the default language
+ if (DEFAULT_LANGUAGE.equals(body.getLanguage()) || body.getLanguage() == null) {
+ continue;
+ }
+ buf.append("");
+ buf.append(StringUtils.escapeForXML(body.getMessage()));
+ buf.append("");
}
if (thread != null) {
buf.append("").append(thread).append("");
@@ -203,6 +339,102 @@ public class Message extends Packet {
return buf.toString();
}
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Message message = (Message) o;
+
+ if(!super.equals(message)) { return false; }
+ if (bodies.size() != message.bodies.size() || !bodies.containsAll(message.bodies)) {
+ return false;
+ }
+ if (language != null ? !language.equals(message.language) : message.language != null) {
+ return false;
+ }
+ if (subject != null ? !subject.equals(message.subject) : message.subject != null) {
+ return false;
+ }
+ if (thread != null ? !thread.equals(message.thread) : message.thread != null) {
+ return false;
+ }
+ return type == message.type;
+
+ }
+
+ public int hashCode() {
+ int result;
+ result = (type != null ? type.hashCode() : 0);
+ result = 31 * result + (subject != null ? subject.hashCode() : 0);
+ result = 31 * result + (thread != null ? thread.hashCode() : 0);
+ result = 31 * result + (language != null ? language.hashCode() : 0);
+ result = 31 * result + bodies.hashCode();
+ return result;
+ }
+
+ /**
+ * Represents a message body, its language and the content of the message.
+ */
+ public static class Body {
+
+ private String message;
+ private String langauge;
+
+ private Body(String language, String message) {
+ if (message == null) {
+ throw new NullPointerException("Message cannot be null.");
+ }
+ this.langauge = language;
+ this.message = message;
+ }
+
+ /**
+ * Returns the language of this message body. If the language is null, then, no language
+ * was specified.
+ *
+ * @return the language of this message body.
+ */
+ public String getLanguage() {
+ if (DEFAULT_LANGUAGE.equals(langauge)) {
+ return null;
+ }
+ else {
+ return langauge;
+ }
+ }
+
+ /**
+ * Returns the message content.
+ *
+ * @return the content of the message.
+ */
+ public String getMessage() {
+ return message;
+ }
+
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) { return false; }
+
+ Body body = (Body) o;
+
+ if (langauge != null ? !langauge.equals(body.langauge) : body.langauge != null) {
+ return false;
+ }
+ return message.equals(body.message);
+
+ }
+
+ public int hashCode() {
+ int result;
+ result = message.hashCode();
+ result = 31 * result + (langauge != null ? langauge.hashCode() : 0);
+ return result;
+ }
+ }
+
/**
* Represents the type of a message.
*/
diff --git a/source/org/jivesoftware/smack/packet/Packet.java b/source/org/jivesoftware/smack/packet/Packet.java
index dc7f3d9ff..d6ca9a42d 100644
--- a/source/org/jivesoftware/smack/packet/Packet.java
+++ b/source/org/jivesoftware/smack/packet/Packet.java
@@ -42,6 +42,11 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
public abstract class Packet {
+ protected static final String DEFAULT_LANGUAGE =
+ java.util.Locale.getDefault().getLanguage().toLowerCase();
+
+ private static String DEFAULT_XML_NS = null;
+
/**
* Constant used as packetID to indicate that a packet has no id. To indicate that a packet
* has no id set this constant as the packet's id. When the packet is asked for its id the
@@ -60,23 +65,29 @@ public abstract class Packet {
*/
private static long id = 0;
+ private String xmlns = DEFAULT_XML_NS;
+
/**
* Returns the next unique id. Each id made up of a short alphanumeric
* prefix along with a unique numeric value.
*
* @return the next id.
*/
- private static synchronized String nextID() {
+ public static synchronized String nextID() {
return prefix + Long.toString(id++);
}
+ public static void setDefaultXmlns(String defaultXmlns) {
+ DEFAULT_XML_NS = defaultXmlns;
+ }
+
private String packetID = null;
private String to = null;
private String from = null;
private final List packetExtensions
= new CopyOnWriteArrayList();
- private Map properties = null;
+ private final Map properties = null;
private XMPPError error = null;
/**
@@ -280,9 +291,6 @@ public abstract class Packet {
if (!(value instanceof Serializable)) {
throw new IllegalArgumentException("Value must be serialiazble");
}
- if (properties == null) {
- properties = new HashMap();
- }
properties.put(name, value);
}
@@ -403,4 +411,52 @@ public abstract class Packet {
}
return buf.toString();
}
+
+ public String getXmlns() {
+ return this.xmlns;
+ }
+
+ protected static String parseXMLLang(String language) {
+ if (language == null || "".equals(language)) {
+ language = DEFAULT_LANGUAGE;
+ }
+ return language;
+ }
+
+ protected static String getDefaultLanguage() {
+ return DEFAULT_LANGUAGE;
+ }
+
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Packet packet = (Packet) o;
+
+ if (error != null ? !error.equals(packet.error) : packet.error != null) { return false; }
+ if (from != null ? !from.equals(packet.from) : packet.from != null) { return false; }
+ if (!packetExtensions.equals(packet.packetExtensions)) { return false; }
+ if (packetID != null ? !packetID.equals(packet.packetID) : packet.packetID != null) {
+ return false;
+ }
+ if (properties != null ? !properties.equals(packet.properties)
+ : packet.properties != null) {
+ return false;
+ }
+ if (to != null ? !to.equals(packet.to) : packet.to != null) { return false; }
+ return !(xmlns != null ? !xmlns.equals(packet.xmlns) : packet.xmlns != null);
+ }
+
+ public int hashCode() {
+ int result;
+ result = (xmlns != null ? xmlns.hashCode() : 0);
+ result = 31 * result + (packetID != null ? packetID.hashCode() : 0);
+ result = 31 * result + (to != null ? to.hashCode() : 0);
+ result = 31 * result + (from != null ? from.hashCode() : 0);
+ result = 31 * result + packetExtensions.hashCode();
+ result = 31 * result + properties.hashCode();
+ result = 31 * result + (error != null ? error.hashCode() : 0);
+ return result;
+ }
}
\ No newline at end of file
diff --git a/source/org/jivesoftware/smack/packet/Presence.java b/source/org/jivesoftware/smack/packet/Presence.java
index f75a21eaa..5e6941c3d 100644
--- a/source/org/jivesoftware/smack/packet/Presence.java
+++ b/source/org/jivesoftware/smack/packet/Presence.java
@@ -62,6 +62,7 @@ public class Presence extends Packet {
private String status = null;
private int priority = Integer.MIN_VALUE;
private Mode mode = null;
+ private String language;
/**
* Creates a new presence update. Status, priority, and mode are left un-set.
@@ -69,7 +70,7 @@ public class Presence extends Packet {
* @param type the type.
*/
public Presence(Type type) {
- this.type = type;
+ setType(type);
}
/**
@@ -81,10 +82,10 @@ public class Presence extends Packet {
* @param mode the mode type for this presence update.
*/
public Presence(Type type, String status, int priority, Mode mode) {
- this.type = type;
- this.status = status;
- this.priority = priority;
- this.mode = mode;
+ setType(type);
+ setStatus(status);
+ setPriority(priority);
+ setMode(mode);
}
/**
@@ -128,6 +129,9 @@ public class Presence extends Packet {
* @param type the type of the presence packet.
*/
public void setType(Type type) {
+ if(type == null) {
+ throw new NullPointerException("Type cannot be null");
+ }
this.type = type;
}
@@ -196,9 +200,35 @@ public class Presence extends Packet {
this.mode = mode;
}
+ /**
+ * Returns the xml:lang of this Presence, or null if one has not been set.
+ *
+ * @return the xml:lang of this Presence, or null if one has not been set.
+ * @since 3.0.2
+ */
+ private String getLanguage() {
+ return language;
+ }
+
+ /**
+ * Sets the xml:lang of this Presence.
+ *
+ * @param language the xml:lang of this Presence.
+ * @since 3.0.2
+ */
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
public String toXML() {
StringBuilder buf = new StringBuilder();
buf.append(" properties = null;
while (!done) {
@@ -81,9 +85,9 @@ public class PacketParserUtils {
}
}
else if (elementName.equals("body")) {
- if (body == null) {
- body = parser.nextText();
- }
+ String xmlLang = getLanguageAttribute(parser);
+ body = parser.nextText();
+ message.addBody(xmlLang, body);
}
else if (elementName.equals("thread")) {
if (thread == null) {
@@ -111,7 +115,6 @@ public class PacketParserUtils {
}
}
message.setSubject(subject);
- message.setBody(body);
message.setThread(thread);
// Set packet properties.
if (properties != null) {
@@ -140,13 +143,18 @@ public class PacketParserUtils {
System.err.println("Found invalid presence type " + typeString);
}
}
-
Presence presence = new Presence(type);
presence.setTo(parser.getAttributeValue("", "to"));
presence.setFrom(parser.getAttributeValue("", "from"));
String id = parser.getAttributeValue("", "id");
presence.setPacketID(id == null ? Packet.ID_NOT_AVAILABLE : id);
+ String language = getLanguageAttribute(parser);
+ if (language != null && !"".equals(language.trim())) {
+ presence.setLanguage(language);
+ }
+ presence.setPacketID(id == null ? Packet.ID_NOT_AVAILABLE : id);
+
// Parse sub-elements
boolean done = false;
while (!done) {
@@ -403,6 +411,18 @@ public class PacketParserUtils {
return extension;
}
+ private static String getLanguageAttribute(XmlPullParser parser) {
+ for (int i = 0; i < parser.getAttributeCount(); i++) {
+ String attributeName = parser.getAttributeName(i);
+ if ( "xml:lang".equals(attributeName) ||
+ ("lang".equals(attributeName) &&
+ "xml".equals(parser.getAttributePrefix(i)))) {
+ return parser.getAttributeValue(i);
+ }
+ }
+ return null;
+ }
+
public static Object parseWithIntrospection(String elementName,
Class objectClass, XmlPullParser parser) throws Exception
{
diff --git a/test-unit/org/jivesoftware/smack/packet/MessageTest.java b/test-unit/org/jivesoftware/smack/packet/MessageTest.java
new file mode 100644
index 000000000..7292560eb
--- /dev/null
+++ b/test-unit/org/jivesoftware/smack/packet/MessageTest.java
@@ -0,0 +1,244 @@
+/**
+ * $Revision:$
+ * $Date:$
+ *
+ * Copyright (C) 2007 Jive Software. All rights reserved.
+ * This software is the proprietary information of Jive Software. Use is subject to license terms.
+ */
+package org.jivesoftware.smack.packet;
+
+import static org.custommonkey.xmlunit.XMLAssert.*;
+import org.xml.sax.SAXException;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ *
+ */
+public class MessageTest {
+
+ @Test
+ public void setMessageTypeTest() throws IOException, SAXException {
+ Message.Type type = Message.Type.chat;
+ Message.Type type2 = Message.Type.headline;
+
+ StringBuilder controlBuilder = new StringBuilder();
+ controlBuilder.append("")
+ .append("");
+ String control = controlBuilder.toString();
+
+ Message messageTypeInConstructor = new Message(null, Message.Type.chat);
+ messageTypeInConstructor.setPacketID(Packet.ID_NOT_AVAILABLE);
+ assertEquals(type, messageTypeInConstructor.getType());
+ assertXMLEqual(control, messageTypeInConstructor.toXML());
+
+ controlBuilder = new StringBuilder();
+ controlBuilder.append("")
+ .append("");
+ control = controlBuilder.toString();
+
+ Message messageTypeSet = getNewMessage();
+ messageTypeSet.setType(type2);
+ assertEquals(type2, messageTypeSet.getType());
+ assertXMLEqual(control, messageTypeSet.toXML());
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void setMessageTypeNullTest() {
+ Message message = getNewMessage();
+ message.setType(null);
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void setNullMessageBodyTest() {
+ Message message = getNewMessage();
+ message.addBody(null, null);
+ }
+
+ @Test
+ public void setMessageSubjectTest() throws IOException, SAXException {
+ final String messageSubject = "This is a test of the emergency broadcast system.";
+
+ StringBuilder controlBuilder = new StringBuilder();
+ controlBuilder.append("")
+ .append("")
+ .append(messageSubject)
+ .append("")
+ .append("");
+ String control = controlBuilder.toString();
+
+ Message message = getNewMessage();
+ message.setSubject(messageSubject);
+
+ assertEquals(messageSubject, message.getSubject());
+ assertXMLEqual(control, message.toXML());
+ }
+
+ @Test
+ public void oneMessageBodyTest() throws IOException, SAXException {
+ final String messageBody = "This is a test of the emergency broadcast system.";
+
+ StringBuilder controlBuilder = new StringBuilder();
+ controlBuilder.append("")
+ .append("")
+ .append(messageBody)
+ .append("")
+ .append("");
+ String control = controlBuilder.toString();
+
+ Message message = getNewMessage();
+ message.setBody(messageBody);
+
+ assertEquals(messageBody, message.getBody());
+ assertXMLEqual(control, message.toXML());
+ }
+
+ @Test
+ public void multipleMessageBodiesTest() throws IOException, SAXException {
+ final String messageBody1 = "This is a test of the emergency broadcast system, 1.";
+ final String lang2 = "ru";
+ final String messageBody2 = "This is a test of the emergency broadcast system, 2.";
+ final String lang3 = "sp";
+ final String messageBody3 = "This is a test of the emergency broadcast system, 3.";
+
+ StringBuilder controlBuilder = new StringBuilder();
+ controlBuilder.append("")
+ .append("")
+ .append(messageBody1)
+ .append("")
+ .append("")
+ .append(messageBody2)
+ .append("")
+ .append("")
+ .append(messageBody3)
+ .append("")
+ .append("");
+ String control = controlBuilder.toString();
+
+ Message message = getNewMessage();
+ message.addBody(null, messageBody1);
+ message.addBody(lang2, messageBody2);
+ message.addBody(lang3, messageBody3);
+ assertXMLEqual(control, message.toXML());
+
+ Collection languages = message.getBodyLanguages();
+ List controlLanguages = new ArrayList();
+ controlLanguages.add(lang2);
+ controlLanguages.add(lang3);
+ controlLanguages.removeAll(languages);
+ assertTrue(controlLanguages.size() == 0);
+ }
+
+ @Test
+ public void removeMessageBodyTest() {
+ Message message = getNewMessage();
+ message.setBody("test");
+ assertTrue(message.getBodies().size() == 1);
+
+ message.setBody(null);
+ assertTrue(message.getBodies().size() == 0);
+
+ assertFalse(message.removeBody("sp"));
+
+ Message.Body body = message.addBody("es", "test");
+ assertTrue(message.getBodies().size() == 1);
+
+ message.removeBody(body);
+ assertTrue(message.getBodies().size() == 0);
+ }
+
+ @Test
+ public void setMessageThreadTest() throws IOException, SAXException {
+ final String messageThread = "1234";
+
+ StringBuilder controlBuilder = new StringBuilder();
+ controlBuilder.append("")
+ .append("")
+ .append(messageThread)
+ .append("")
+ .append("");
+ String control = controlBuilder.toString();
+
+ Message message = getNewMessage();
+ message.setThread(messageThread);
+
+ assertEquals(messageThread, message.getThread());
+ assertXMLEqual(control, message.toXML());
+ }
+
+ @Test
+ public void messageXmlLangTest() throws IOException, SAXException {
+ final String lang = "sp";
+
+ StringBuilder controlBuilder = new StringBuilder();
+ controlBuilder.append("")
+ .append("");
+ String control = controlBuilder.toString();
+
+ Message message = getNewMessage();
+ message.setLanguage(lang);
+
+ assertXMLEqual(control, message.toXML());
+ }
+
+ @Test
+ public void messageEqualityTest() {
+ Message message = getNewMessage();
+ assertTrue(message.equals(message));
+ //noinspection ObjectEqualsNull
+ assertFalse(message.equals(null));
+ assertFalse(message.equals("test"));
+ Message message2 = getNewMessage();
+
+ assertTrue(message.equals(message2));
+
+ message.setTo("joe@shmoe.com");
+ assertFalse(message.equals(message2));
+ message2.setTo("joe@shmoe.com");
+
+ message.setSubject("subject");
+ assertFalse(message.equals(message2));
+ message2.setSubject("subject");
+
+ message.setThread("thread");
+ assertFalse(message.equals(message2));
+ message2.setThread("thread");
+
+ message.setBody("body1");
+ assertFalse(message.equals(message2));
+ message2.setBody("body1");
+
+ message.setLanguage("language");
+ assertFalse(message.equals(message2));
+ message2.setLanguage("language");
+
+ message.setType(Message.Type.chat);
+ assertFalse(message.equals(message2));
+ message2.setType(Message.Type.chat);
+
+ assertTrue(message.equals(message2));
+ }
+
+ private static Message getNewMessage() {
+ Message message = new Message();
+ message.setPacketID(Packet.ID_NOT_AVAILABLE);
+ return message;
+ }
+}
diff --git a/test-unit/org/jivesoftware/smack/packet/PresenceTest.java b/test-unit/org/jivesoftware/smack/packet/PresenceTest.java
new file mode 100644
index 000000000..5b3c0499e
--- /dev/null
+++ b/test-unit/org/jivesoftware/smack/packet/PresenceTest.java
@@ -0,0 +1,186 @@
+/**
+ * $Revision:$
+ * $Date:$
+ *
+ * Copyright (C) 2007 Jive Software. All rights reserved.
+ * This software is the proprietary information of Jive Software. Use is subject to license terms.
+ */
+package org.jivesoftware.smack.packet;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import org.xml.sax.SAXException;
+import static junit.framework.Assert.assertEquals;
+
+import java.io.IOException;
+
+/**
+ *
+ */
+public class PresenceTest {
+ @Test
+ public void setPresenceTypeTest() throws IOException, SAXException {
+ Presence.Type type = Presence.Type.unavailable;
+ Presence.Type type2 = Presence.Type.subscribe;
+
+ StringBuilder controlBuilder = new StringBuilder();
+ controlBuilder.append("")
+ .append("");
+ String control = controlBuilder.toString();
+
+ Presence presenceTypeInConstructor = new Presence(type);
+ presenceTypeInConstructor.setPacketID(Packet.ID_NOT_AVAILABLE);
+ assertEquals(type, presenceTypeInConstructor.getType());
+ assertXMLEqual(control, presenceTypeInConstructor.toXML());
+
+ controlBuilder = new StringBuilder();
+ controlBuilder.append("")
+ .append("");
+ control = controlBuilder.toString();
+
+ Presence presenceTypeSet = getNewPresence();
+ presenceTypeSet.setType(type2);
+ assertEquals(type2, presenceTypeSet.getType());
+ assertXMLEqual(control, presenceTypeSet.toXML());
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void setNullPresenceTypeTest() {
+ getNewPresence().setType(null);
+ }
+
+ @Test
+ public void isPresenceAvailableTest() {
+ Presence presence = getNewPresence();
+ presence.setType(Presence.Type.available);
+ assertTrue(presence.isAvailable());
+
+ presence.setType(Presence.Type.unavailable);
+ assertFalse(presence.isAvailable());
+ }
+
+ @Test
+ public void setPresenceStatusTest() throws IOException, SAXException {
+ final String status = "This is a test of the emergency broadcast system.";
+
+ StringBuilder controlBuilder = new StringBuilder();
+ controlBuilder.append("")
+ .append("")
+ .append(status)
+ .append("")
+ .append("");
+ String control = controlBuilder.toString();
+
+ Presence presence = getNewPresence();
+ presence.setStatus(status);
+
+ assertEquals(status, presence.getStatus());
+ assertXMLEqual(control, presence.toXML());
+ }
+
+ @Test
+ public void setPresencePriorityTest() throws IOException, SAXException {
+ final int priority = 10;
+
+ StringBuilder controlBuilder = new StringBuilder();
+ controlBuilder.append("")
+ .append("")
+ .append(priority)
+ .append("")
+ .append("");
+ String control = controlBuilder.toString();
+
+ Presence presence = getNewPresence();
+ presence.setPriority(priority);
+
+ assertEquals(priority, presence.getPriority());
+ assertXMLEqual(control, presence.toXML());
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void setIllegalPriorityTest() {
+ getNewPresence().setPriority(Integer.MIN_VALUE);
+ }
+
+ @Test
+ public void setPresenceModeTest() throws IOException, SAXException {
+ Presence.Mode mode1 = Presence.Mode.dnd;
+ final int priority = 10;
+ final String status = "This is a test of the emergency broadcast system.";
+ Presence.Mode mode2 = Presence.Mode.chat;
+
+ StringBuilder controlBuilder = new StringBuilder();
+ controlBuilder.append("")
+ .append("")
+ .append(status)
+ .append("")
+ .append("")
+ .append(priority)
+ .append("")
+ .append("")
+ .append(mode1)
+ .append("")
+ .append("");
+ String control = controlBuilder.toString();
+
+ Presence presenceModeInConstructor = new Presence(Presence.Type.available, status, priority,
+ mode1);
+ presenceModeInConstructor.setPacketID(Packet.ID_NOT_AVAILABLE);
+ assertEquals(mode1, presenceModeInConstructor.getMode());
+ assertXMLEqual(control, presenceModeInConstructor.toXML());
+
+ controlBuilder = new StringBuilder();
+ controlBuilder.append("")
+ .append("")
+ .append(mode2)
+ .append("")
+ .append("");
+ control = controlBuilder.toString();
+
+ Presence presenceModeSet = getNewPresence();
+ presenceModeSet.setMode(mode2);
+ assertEquals(mode2, presenceModeSet.getMode());
+ assertXMLEqual(control, presenceModeSet.toXML());
+ }
+
+ @Test
+ public void isModeAwayTest() {
+ Presence presence = getNewPresence();
+ presence.setMode(Presence.Mode.away);
+ assertTrue(presence.isAway());
+
+ presence.setMode(Presence.Mode.chat);
+ assertFalse(presence.isAway());
+ }
+
+ @Test
+ public void presenceXmlLangTest() throws IOException, SAXException {
+ final String lang = "sp";
+
+ StringBuilder controlBuilder = new StringBuilder();
+ controlBuilder.append("")
+ .append("");
+ String control = controlBuilder.toString();
+
+ Presence presence = getNewPresence();
+ presence.setLanguage(lang);
+
+ assertXMLEqual(control, presence.toXML());
+ }
+
+ private static Presence getNewPresence() {
+ Presence presence = new Presence(Presence.Type.available);
+ presence.setPacketID(Packet.ID_NOT_AVAILABLE);
+ return presence;
+ }
+}
diff --git a/test-unit/org/jivesoftware/smack/util/PacketParserUtilsTest.java b/test-unit/org/jivesoftware/smack/util/PacketParserUtilsTest.java
new file mode 100644
index 000000000..a243cc932
--- /dev/null
+++ b/test-unit/org/jivesoftware/smack/util/PacketParserUtilsTest.java
@@ -0,0 +1,63 @@
+/**
+ * $Revision:$
+ * $Date:$
+ *
+ * Copyright (C) 2007 Jive Software. All rights reserved.
+ * This software is the proprietary information of Jive Software. Use is subject to license terms.
+ */
+package org.jivesoftware.smack.util;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import org.jivesoftware.smack.packet.Packet;
+import org.junit.Test;
+import org.xmlpull.mxp1.MXParser;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+/**
+ *
+ */
+public class PacketParserUtilsTest {
+ @Test
+ public void multipleMessageBodiesParsingTest() throws Exception {
+ final String messageBody1 = "This is a test of the emergency broadcast system, 1.";
+ final String lang2 = "ru";
+ final String messageBody2 = "This is a test of the emergency broadcast system, 2.";
+ final String lang3 = "sp";
+ final String messageBody3 = "This is a test of the emergency broadcast system, 3.";
+
+ StringBuilder controlBuilder = new StringBuilder();
+ controlBuilder.append("")
+ .append("")
+ .append(messageBody1)
+ .append("")
+ .append("")
+ .append(messageBody2)
+ .append("")
+ .append("")
+ .append(messageBody3)
+ .append("")
+ .append("");
+ String control = controlBuilder.toString();
+
+ Packet message = PacketParserUtils.parseMessage(getParser(control));
+ assertXMLEqual(control, message.toXML());
+ }
+
+ private XmlPullParser getParser(String control) throws XmlPullParserException, IOException {
+ XmlPullParser parser = new MXParser();
+ parser.setInput(new StringReader(control));
+ while(true) {
+ if(parser.next() == XmlPullParser.START_TAG
+ && parser.getName().equals("message")) { break; }
+ }
+ return parser;
+ }
+}