From c2ed130b2356a4a1b10a0a7854517bcdfcb13ff6 Mon Sep 17 00:00:00 2001 From: Tarun Gupta Date: Tue, 30 Jun 2015 01:45:15 +0530 Subject: Completes JID functionalities. Completes JID by providing all features Swiften provides including Escaped and Unescaped Node. License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details. Test-Information: Test added for JID, which passes. Change-Id: Ia61dad0ed93a153186b9f78e2669f675f51e3734 diff --git a/src/com/isode/stroke/jid/JID.java b/src/com/isode/stroke/jid/JID.java index 841b84b..6067afc 100644 --- a/src/com/isode/stroke/jid/JID.java +++ b/src/com/isode/stroke/jid/JID.java @@ -6,10 +6,20 @@ * Copyright (c) 2010, Remko Tronçon. * All rights reserved. */ +/* + * Copyright (c) 2015 Tarun Gupta. + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + package com.isode.stroke.jid; -import com.ibm.icu.text.StringPrep; +import com.isode.stroke.idn.ICUConverter; +import com.isode.stroke.idn.IDNConverter; import com.ibm.icu.text.StringPrepParseException; +import com.isode.stroke.base.NotNull; +import java.util.Arrays; +import java.util.List; /** * JID helper. @@ -31,254 +41,345 @@ import com.ibm.icu.text.StringPrepParseException; * This is an immutable class. */ public class JID implements Comparable { - public enum CompareType { - WithResource, WithoutResource - }; + public enum CompareType { + WithResource, WithoutResource + }; - private final String node_; - private final String domain_; - private final String resource_; + private boolean valid_ = true; + private boolean hasResource_ = true; + private String node_ = ""; + private String domain_ = ""; + private String resource_ = ""; + private static IDNConverter idnConverter = new ICUConverter(); - /** - * Create an invalid JID. - */ - public JID() { - this("", "", null); - } + /** + * Create an invalid JID. + */ + public JID() { + this("", "", null); + } - /** - * Create a JID using the JID(String) constructor. - * @param jid String formatted JID, not null - * @return Jabber ID, not null - */ - public static JID fromString(final String jid) { - return new JID(jid); - } + /** + * Create a JID using the JID(String) constructor. + * @param jid String formatted JID, not null + * @return Jabber ID, not null + */ + public static JID fromString(String jid) { + NotNull.exceptIfNull(jid, "jid"); + return new JID(jid); + } - /** - * Create a JID from its String representation. - * - * e.g. - * wonderland.lit - * wonderland.lit/rabbithole - * alice@wonderland.lit - * alice@wonderland.lit/TeaParty - * - * @param jid String representation. Invalid JID if null or invalid. - */ - public JID(final String jid) { - //FIXME: This doesn't nameprep! - if (jid == null || jid.startsWith("@")) { - node_ = ""; - domain_ = ""; - resource_ = ""; - return; - } + /** + * Create a JID from its String representation. + * + * e.g. + * wonderland.lit + * wonderland.lit/rabbithole + * alice@wonderland.lit + * alice@wonderland.lit/TeaParty + * + * @param jid String representation. Invalid JID if null or invalid. + */ + public JID(String jid) { + NotNull.exceptIfNull(jid, "jid"); + valid_ = true; + initializeFromString(jid); + } - String bare; - String resource; - String[] parts = jid.split("/", 2); - if (parts.length > 1) { - bare = parts[0]; - resource = parts[1]; - } else { - resource = null; - bare = jid; - } - String[] nodeAndDomain = bare.split("@", 2); - String node; - String domain; - if (nodeAndDomain.length == 1) { - node = ""; - domain = nodeAndDomain[0]; - } else { - node = nodeAndDomain[0]; - domain = nodeAndDomain[1]; - } - StringPrep nodePrep = StringPrep.getInstance(StringPrep.RFC3491_NAMEPREP); - StringPrep domainPrep = StringPrep.getInstance(StringPrep.RFC3920_NODEPREP); - StringPrep resourcePrep = StringPrep.getInstance(StringPrep.RFC3920_RESOURCEPREP); - try { - node = nodePrep.prepare(node, StringPrep.DEFAULT); - domain = domainPrep.prepare(domain, StringPrep.DEFAULT); - resource = resource != null ? resourcePrep.prepare(resource, StringPrep.DEFAULT) : null; - } catch (StringPrepParseException ex) { - node = ""; - domain = ""; - resource = ""; - } - node_ = node; - domain_ = domain; - resource_ = resource; - } + private void initializeFromString(String jid) { + if (jid.startsWith("@")) { + valid_ = false; + node_ = ""; + domain_ = ""; + resource_ = ""; + return; + } - /** - * Create a bare JID from the node and domain parts. - * - * JID("node@domain") == JID("node", "domain") - * Use a different constructor instead of passing nulls. - * - * @param node JID node part. - * @param domain JID domain part. - */ - public JID(final String node, final String domain) { - this(node, domain, null); - } + String bare; + String resource; + String[] parts = jid.split("/", 2); + if (parts.length > 1) { + bare = parts[0]; + resource = parts[1]; + } else { + hasResource_ = false; + resource = null; + bare = jid; + } + String[] nodeAndDomain = bare.split("@", 2); + String node; + String domain; + if (nodeAndDomain.length == 1) { + node = ""; + domain = nodeAndDomain[0]; + } else { + node = nodeAndDomain[0]; + domain = nodeAndDomain[1]; + } + nameprepAndSetComponents(node, domain, resource); + } - /** - * Create a bare JID from the node, domain and resource parts. - * - * JID("node@domain/resource") == JID("node", "domain", "resource") - * Use a different constructor instead of passing nulls. - * - * @param node JID node part. - * @param domain JID domain part. - * @param resource JID resource part. - */ - public JID(final String node, final String domain, final String resource) { - StringPrep nodePrep = StringPrep.getInstance(StringPrep.RFC3491_NAMEPREP); - StringPrep domainPrep = StringPrep.getInstance(StringPrep.RFC3920_NODEPREP); - StringPrep resourcePrep = StringPrep.getInstance(StringPrep.RFC3920_RESOURCEPREP); - String preppedNode; - String preppedDomain; - String preppedResource; - try { - preppedNode = nodePrep.prepare(node, StringPrep.DEFAULT); - preppedDomain = domainPrep.prepare(domain, StringPrep.DEFAULT); - preppedResource = resource != null ? resourcePrep.prepare(resource, StringPrep.DEFAULT) : null; - } catch (StringPrepParseException ex) { - preppedNode = ""; - preppedDomain = ""; - preppedResource = ""; - } - node_ = preppedNode; - domain_ = preppedDomain; - resource_ = preppedResource; + /** + * Create a bare JID from the node and domain parts. + * + * JID("node@domain") == JID("node", "domain") + * Use a different constructor instead of passing nulls. + * + * @param node JID node part. + * @param domain JID domain part. + */ + public JID(String node, String domain) { + this(node, domain, null); + } - } + /** + * Create a bare JID from the node, domain and resource parts. + * + * JID("node@domain/resource") == JID("node", "domain", "resource") + * Use a different constructor instead of passing nulls. + * + * @param node JID node part. + * @param domain JID domain part. + * @param resource JID resource part. + */ + public JID(String node, String domain, String resource) { + NotNull.exceptIfNull(node, "node"); + NotNull.exceptIfNull(domain, "domain"); + valid_ = true; + hasResource_ = (resource != null); + nameprepAndSetComponents(node, domain, resource); + } - /** - * @return Is a correctly-formatted JID. - */ - public boolean isValid() { - return (domain_.length()!=0); - } + private void nameprepAndSetComponents(String node, String domain, String resource) { + if (domain.isEmpty() || idnConverter.getIDNAEncoded(domain) == null) { + valid_ = false; + return; + } - /** - * e.g. JID("node@domain").getNode() == "node" - * @return Node, or null for nodeless JIDs. - */ - public String getNode() { - return node_; - } + try { + node_ = idnConverter.getStringPrepared(node, IDNConverter.StringPrepProfile.XMPPNodePrep); + domain_ = idnConverter.getStringPrepared(domain, IDNConverter.StringPrepProfile.NamePrep); + resource_ = resource != null ? idnConverter.getStringPrepared(resource, IDNConverter.StringPrepProfile.XMPPResourcePrep) : null; + } catch (StringPrepParseException e) { + valid_ = false; + return; + } + if (domain_.isEmpty()) { + valid_ = false; + return; + } + } - /** - * e.g. JID("node@domain").getDomain() == "domain" - * @return only null for invalid JIDs. - */ - public String getDomain() { - return domain_; - } + /** + * @return Is a correctly-formatted JID. + */ + public boolean isValid() { + return valid_; + } - /** - * e.g. JID("node@domain/resource").getResource() == "resource" - * @return null for bare JIDs. - */ - public String getResource() { - return resource_ != null ? resource_ : ""; - } + /** + * e.g. JID("node@domain").getNode() == "node" + * @return Node, or null for nodeless JIDs. + */ + public String getNode() { + return node_; + } - /** - * Is a bare JID, i.e. has no resource part. - * @return true if the resource part of JID is null, false if not - */ - public boolean isBare() { - return resource_ == null; - } + /** + * e.g. JID("node@domain").getDomain() == "domain" + * @return only null for invalid JIDs. + */ + public String getDomain() { + return domain_; + } - /** - * Get the JID without a resource. - * @return non-null. Invalid if the original is invalid. - */ - public JID toBare() { - return new JID(getNode(), getDomain()); - } - - @Override - public String toString() { - String string = new String(); - if (node_.length()!=0) { - string += node_ + "@"; - } - string += domain_; - if (!isBare()) { - string += "/" + resource_; - } - return string; - } + /** + * e.g. JID("node@domain/resource").getResource() == "resource" + * @return "" for bare JIDs. + */ + public String getResource() { + return resource_ != null ? resource_ : ""; + } - @Override - public boolean equals(final Object otherObject) { - if (otherObject == this) { - return true; - } - if (!(otherObject instanceof JID)) { - return false; - } - JID other = (JID)otherObject; - String node1 = getNode(); - String node2 = other.getNode(); - String domain1 = getDomain(); - String domain2 = other.getDomain(); - String resource1 = getResource(); - String resource2 = other.getResource(); - boolean nodeMatch = (node1 == null && node2 == null) || (node1 != null && node1.equals(node2)); - boolean domainMatch = (domain1 == null && domain2 == null) || (domain1 != null && domain1.equals(domain2)); - boolean resourceMatch = (resource1 == null && resource2 == null) || (resource1 != null && resource1.equals(resource2)); - return nodeMatch && domainMatch && resourceMatch; - } + /** + * Is a bare JID, i.e. has no resource part. + * @return true if the resource part of JID is null, false if not + */ + public boolean isBare() { + return !hasResource_; + } - /** - * Compare two Jabber IDs by either including the resource part or - * excluding it - * @param o other JID to which this JID should be compared, can be null - * @param compareType comparison type - * @return 0 if equal, 1 if other JID is greater or -1 if this JID is greater - */ - public int compare(final JID o, CompareType compareType) { - if(this == o) return 0; - if(o == null) return 1; - if (!node_ .equals(o.node_)) { - return node_.compareTo(o.node_); - } - if (!domain_ .equals(o.domain_)) { - return domain_.compareTo(o.domain_); + /** + * Get the JID without a resource. + * @return non-null. Invalid if the original is invalid. + */ + public JID toBare() { + return new JID(getNode(), getDomain()); + } + + static List escapedChars = Arrays.asList(' ', '"', '&', '\'', '/', '<', '>', '@', ':'); + private static String getEscaped(char c) { + return "\\" + Integer.toHexString((int)c); + } + + private static boolean getEscapeSequenceValue(String sequence) { + try { + int v = Integer.parseInt(sequence, 16); + char value = (char)(v); + return ((value == 0x5C) || escapedChars.contains(value)); + } catch (NumberFormatException e) { + return false; + } + } + + /** + * Returns the given node, escaped according to XEP-0106. + * The resulting node is a valid node for a JID, whereas the input value can contain characters + * that are not allowed. + */ + public static String getEscapedNode(String node) { + String result = ""; + int startIndex = 0; + + for(char i : node.toCharArray()) { + if(escapedChars.contains(i)) { + result += getEscaped(i); + continue; + } + else if (i == '\\') { + int index = node.indexOf(i, startIndex); + startIndex = index + 1; + // Check if we have an escaped dissalowed character sequence + int innerBegin = index + 1; + if(innerBegin < node.length() && (innerBegin + 1) < node.length()) { + int innerEnd = innerBegin + 2; + String subs = node.substring(innerBegin, innerEnd); + if(getEscapeSequenceValue(subs)) { + result += getEscaped(i); + continue; + } + } + } + result += i; + } + return result; + } + + /** + * Returns the node of the current JID, unescaped according to XEP-0106. + */ + public String getUnescapedNode() { + String result = ""; + int len = node_.length(); + for(int j = 0; j != len;) { + if (node_.charAt(j) == '\\') { + int innerEnd = j + 1; + for (int i = 0; i < 2 && innerEnd != node_.length(); ++i, ++innerEnd) { + + } + char value; + String subs = node_.substring(j+1, innerEnd); + if (getEscapeSequenceValue(subs)) { + int x = Integer.parseInt(subs, 16); + value = (char)(x); + result += value; + j = innerEnd; + continue; + } + } + result += node_.charAt(j); + ++j; + } + return result; + } + + /** + * Get the full JID with the supplied resource. + */ + public JID withResource(String resource) { + return new JID (this.getNode(), this.getDomain(), resource); + } + + public void setIDNConverter(IDNConverter converter) { + idnConverter = converter; + } + + @Override + public String toString() { + if (!valid_) { + return ""; } - if (compareType == CompareType.WithResource) { - String res1 = getResource(); - String res2 = o.getResource(); - if(res1 != null && res2 != null) { - return res1.compareTo(res2); - } + String string = new String(); + if (node_.length()!=0) { + string += node_ + "@"; + } + string += domain_; + if (!isBare()) { + string += "/" + resource_; + } + return string; + } + + @Override + public boolean equals(Object otherObject) { + if (!(otherObject instanceof JID)) { + return false; + } + return (compare((JID)otherObject, CompareType.WithResource) == 0); + } + + /** + * Compare two Jabber IDs by either including the resource part or + * excluding it + * @param o other JID to which this JID should be compared, can be null + * @param compareType comparison type + * @return 0 if equal, 1 if other JID is greater or -1 if this JID is greater + */ + public int compare(JID o, CompareType compareType) { + if(this == o) return 0; + if(o == null) return 1; + if (!node_ .equals(o.node_)) { + return node_.compareTo(o.node_); + } + if (!domain_ .equals(o.domain_)) { + return domain_.compareTo(o.domain_); + } + if (compareType == CompareType.WithResource) { + String res1 = resource_; + String res2 = o.resource_; + if(res1 != null && res2 != null) { + return res1.compareTo(res2); + } + if(res1 == null && res2 == null) { return 0; } if (res1 == null) { return -1; } if (res2 == null) { return 1; } - } - return 0; + } + return 0; + } - } + @Override + public int hashCode() { + int hash = 5; + hash = 73 * hash + (this.node_ != null ? this.node_.hashCode() : 0); + hash = 73 * hash + (this.domain_ != null ? this.domain_.hashCode() : 0); + hash = 73 * hash + (this.resource_ != null ? this.resource_.hashCode() : 0); + return hash; + } - @Override - public int hashCode() { - int hash = 5; - hash = 73 * hash + (this.node_ != null ? this.node_.hashCode() : 0); - hash = 73 * hash + (this.domain_ != null ? this.domain_.hashCode() : 0); - hash = 73 * hash + (this.resource_ != null ? this.resource_.hashCode() : 0); - return hash; - } + @Override + public int compareTo(JID o) { + return compare(o, CompareType.WithResource); + } - @Override - public int compareTo(JID o) { - return compare(o, CompareType.WithResource); - } + /** + * Returns a JID object corresponding to the given + * String, or null if the String does not represent a valid JID + * @param s value to be parsed + * @return a JID, or null if s does not parse as a valid JID + */ + public JID parse(String s) { + JID jid = new JID(s); + return jid.isValid() ? jid : null; + } } diff --git a/test/com/isode/stroke/jid/JIDTest.java b/test/com/isode/stroke/jid/JIDTest.java new file mode 100644 index 0000000..9a7b16a --- /dev/null +++ b/test/com/isode/stroke/jid/JIDTest.java @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2010 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ +/* + * Copyright (c) 2015 Tarun Gupta. + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +package com.isode.stroke.jid; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import org.junit.Test; +import com.isode.stroke.jid.JID; + +public class JIDTest { + + public JIDTest() { + + } + + @Test + public void testConstructorWithString() { + JID testling = new JID("foo@bar/baz"); + + assertEquals("foo", testling.getNode()); + assertEquals("bar", testling.getDomain()); + assertEquals("baz", testling.getResource()); + assertFalse(testling.isBare()); + } + + + @Test + public void testConstructorWithString_NoResource() { + JID testling = new JID("foo@bar"); + + assertEquals("foo", testling.getNode()); + assertEquals("bar", testling.getDomain()); + assertEquals("", testling.getResource()); + assertTrue(testling.isBare()); + } + + + @Test + public void testConstructorWithString_EmptyResource() { + JID testling = new JID("bar/"); + + assertTrue(testling.isValid()); + assertFalse(testling.isBare()); + } + + + @Test + public void testConstructorWithString_NoNode() { + JID testling = new JID("bar/baz"); + + assertEquals("", testling.getNode()); + assertEquals("bar", testling.getDomain()); + assertEquals("baz", testling.getResource()); + assertFalse(testling.isBare()); + } + + + @Test + public void testConstructorWithString_OnlyDomain() { + JID testling = new JID("bar"); + + assertEquals("", testling.getNode()); + assertEquals("bar", testling.getDomain()); + assertEquals("", testling.getResource()); + assertTrue(testling.isBare()); + } + + + @Test + public void testConstructorWithString_InvalidDomain() { + assertFalse(new JID("foo@bar,baz").isValid()); + } + + + @Test + public void testConstructorWithString_UpperCaseNode() { + JID testling = new JID("FoΩ@bar"); + + assertEquals("foω", testling.getNode()); + assertEquals("bar", testling.getDomain()); + } + + + @Test + public void testConstructorWithString_UpperCaseDomain() { + JID testling = new JID("FoΩ"); + + assertEquals("foω", testling.getDomain()); + } + + + @Test + public void testConstructorWithString_UpperCaseResource() { + JID testling = new JID("bar/FoΩ"); + + assertEquals(testling.getResource(), "FoΩ"); + } + + + @Test + public void testConstructorWithString_EmptyNode() { + JID testling = new JID("@bar"); + + assertFalse(testling.isValid()); + } + + + @Test + public void testConstructorWithString_IllegalResource() { + JID testling = new JID("foo@bar.com/رمقه ترنس "); + + assertFalse(testling.isValid()); + } + + + @Test + public void testConstructorWithString_SpacesInNode() { + assertFalse(new JID(" alice@wonderland.lit").isValid()); + assertFalse(new JID("alice @wonderland.lit").isValid()); + } + + + @Test + public void testConstructorWithStrings() { + JID testling = new JID("foo", "bar", "baz"); + + assertEquals("foo", testling.getNode()); + assertEquals("bar", testling.getDomain()); + assertEquals("baz", testling.getResource()); + } + + + @Test + public void testConstructorWithStrings_EmptyDomain() { + JID testling = new JID("foo", "", "baz"); + + assertFalse(testling.isValid()); + } + + + @Test + public void testIsBare() { + assertTrue(new JID("foo@bar").isBare()); + } + + + @Test + public void testIsBare_NotBare() { + assertFalse(new JID("foo@bar/baz").isBare()); + } + + + @Test + public void testToBare() { + JID testling = new JID("foo@bar/baz"); + + assertEquals("foo", testling.toBare().getNode()); + assertEquals("bar", testling.toBare().getDomain()); + assertTrue(testling.toBare().isBare()); + } + + + @Test + public void testToBare_EmptyNode() { + JID testling = new JID("bar/baz"); + + assertEquals("", testling.toBare().getNode()); + assertEquals("bar", testling.toBare().getDomain()); + assertTrue(testling.toBare().isBare()); + } + + + @Test + public void testToBare_EmptyResource() { + JID testling = new JID("bar/"); + + assertEquals("", testling.toBare().getNode()); + assertEquals("bar", testling.toBare().getDomain()); + assertTrue(testling.toBare().isBare()); + } + + + @Test + public void testToString() { + JID testling = new JID("foo@bar/baz"); + + assertEquals("foo@bar/baz", testling.toString()); + } + + + @Test + public void testToString_EmptyNode() { + JID testling = new JID("bar/baz"); + + assertEquals("bar/baz", testling.toString()); + } + + + @Test + public void testToString_NoResource() { + JID testling = new JID("foo@bar"); + + assertEquals("foo@bar", testling.toString()); + } + + + @Test + public void testToString_EmptyResource() { + JID testling = new JID("foo@bar/"); + + assertEquals("foo@bar/", testling.toString()); + } + + + @Test + public void testCompare_SmallerNode() { + JID testling1 = new JID("a@c"); + JID testling2 = new JID("b@b"); + + assertEquals(-1, testling1.compare(testling2, JID.CompareType.WithResource)); + } + + + @Test + public void testCompare_LargerNode() { + JID testling1 = new JID("c@a"); + JID testling2 = new JID("b@b"); + + assertEquals(1, testling1.compare(testling2, JID.CompareType.WithResource)); + } + + + @Test + public void testCompare_SmallerDomain() { + JID testling1 = new JID("x@a/c"); + JID testling2 = new JID("x@b/b"); + + assertEquals(-1, testling1.compare(testling2, JID.CompareType.WithResource)); + } + + + @Test + public void testCompare_LargerDomain() { + JID testling1 = new JID("x@b/b"); + JID testling2 = new JID("x@a/c"); + + assertEquals(1, testling1.compare(testling2, JID.CompareType.WithResource)); + } + + + @Test + public void testCompare_SmallerResource() { + JID testling1 = new JID("x@y/a"); + JID testling2 = new JID("x@y/b"); + + assertEquals(-1, testling1.compare(testling2, JID.CompareType.WithResource)); + } + + + @Test + public void testCompare_LargerResource() { + JID testling1 = new JID("x@y/b"); + JID testling2 = new JID("x@y/a"); + + assertEquals(1, testling1.compare(testling2, JID.CompareType.WithResource)); + } + + + @Test + public void testCompare_Equal() { + JID testling1 = new JID("x@y/z"); + JID testling2 = new JID("x@y/z"); + + assertEquals(0, testling1.compare(testling2, JID.CompareType.WithResource)); + } + + + @Test + public void testCompare_EqualWithoutResource() { + JID testling1 = new JID("x@y/a"); + JID testling2 = new JID("x@y/b"); + + assertEquals(0, testling1.compare(testling2, JID.CompareType.WithoutResource)); + } + + + @Test + public void testCompare_NoResourceAndEmptyResource() { + JID testling1 = new JID("x@y/"); + JID testling2 = new JID("x@y"); + + assertEquals(1, testling1.compare(testling2, JID.CompareType.WithResource)); + } + + + @Test + public void testCompare_EmptyResourceAndNoResource() { + JID testling1 = new JID("x@y"); + JID testling2 = new JID("x@y/"); + + assertEquals(-1, testling1.compare(testling2, JID.CompareType.WithResource)); + } + + + @Test + public void testEquals() { + JID testling1 = new JID("x@y/c"); + JID testling2 = new JID("x@y/c"); + + assertTrue(testling1.compare(testling2, JID.CompareType.WithResource) == 0); + } + + + @Test + public void testEquals_NotEqual() { + JID testling1 = new JID("x@y/c"); + JID testling2 = new JID("x@y/d"); + + assertFalse(testling1.compare(testling2, JID.CompareType.WithResource) == 0); + } + + + @Test + public void testEquals_WithoutResource() { + JID testling1 = new JID("x@y/c"); + JID testling2 = new JID("x@y/d"); + + assertTrue(testling1.compare(testling2, JID.CompareType.WithoutResource) == 0); + } + + + @Test + public void testSmallerThan() { + JID testling1 = new JID("x@y/c"); + JID testling2 = new JID("x@y/d"); + + assertTrue(testling1.compare(testling2, JID.CompareType.WithResource) < 0); + } + + + @Test + public void testSmallerThan_Equal() { + JID testling1 = new JID("x@y/d"); + JID testling2 = new JID("x@y/d"); + + assertFalse(testling1.compare(testling2, JID.CompareType.WithResource) < 0); + } + + + @Test + public void testSmallerThan_Larger() { + JID testling1 = new JID("x@y/d"); + JID testling2 = new JID("x@y/c"); + + assertFalse(testling1.compare(testling2, JID.CompareType.WithResource) < 0); + } + + + @Test + public void testHasResource() { + JID testling = new JID("x@y/d"); + + assertFalse(testling.isBare()); + } + + + @Test + public void testHasResource_NoResource() { + JID testling = new JID("x@y"); + + assertTrue(testling.isBare()); + } + + + @Test + public void testGetEscapedNode() { + String escaped = JID.getEscapedNode("alice@wonderland.lit"); + assertEquals("alice\\40wonderland.lit", escaped); + + escaped = JID.getEscapedNode("\\& \" ' / <\\\\> @ :\\3a\\40"); + assertEquals("\\\\26\\20\\22\\20\\27\\20\\2f\\20\\3c\\\\\\3e\\20\\40\\20\\3a\\5c3a\\5c40", escaped); + } + + + @Test + public void testGetEscapedNode_XEP106Examples() { + assertEquals("\\2plus\\2is\\4", JID.getEscapedNode("\\2plus\\2is\\4")); + assertEquals("foo\\bar", JID.getEscapedNode("foo\\bar")); + assertEquals("foob\\41r", JID.getEscapedNode("foob\\41r")); + assertEquals(JID.getEscapedNode("space cadet"), "space\\20cadet"); + assertEquals(JID.getEscapedNode("call me \"ishmael\""), "call\\20me\\20\\22ishmael\\22"); + assertEquals(JID.getEscapedNode("at&t guy"), "at\\26t\\20guy"); + assertEquals(JID.getEscapedNode("d'artagnan"), "d\\27artagnan"); + assertEquals(JID.getEscapedNode("/.fanboy"), "\\2f.fanboy"); + assertEquals(JID.getEscapedNode("::foo::"), "\\3a\\3afoo\\3a\\3a"); + assertEquals(JID.getEscapedNode(""), "\\3cfoo\\3e"); + assertEquals(JID.getEscapedNode("user@host"), "user\\40host"); + assertEquals(JID.getEscapedNode("c:\\net"), "c\\3a\\net"); + assertEquals(JID.getEscapedNode("c:\\\\net"), "c\\3a\\\\net"); + assertEquals(JID.getEscapedNode("c:\\cool stuff"), "c\\3a\\cool\\20stuff"); + assertEquals(JID.getEscapedNode("c:\\5commas"), "c\\3a\\5c5commas"); + } + + + @Test + public void testGetEscapedNode_BackslashAtEnd() { + assertEquals("foo\\", JID.getEscapedNode("foo\\")); + } + + + @Test + public void testGetUnescapedNode() { + String input = "\\& \" ' / <\\\\> @ : \\5c\\40"; + JID testling = new JID((JID.getEscapedNode(input) + "@y")); + assertTrue(testling.isValid()); + assertEquals(input, testling.getUnescapedNode()); + } + + @Test + public void testGetUnescapedNode_XEP106Examples() { + assertEquals("\\2plus\\2is\\4", new JID("\\2plus\\2is\\4@example.com").getUnescapedNode()); + assertEquals("foo\\bar", new JID("foo\\bar@example.com").getUnescapedNode()); + assertEquals("foob\\41r", new JID("foob\\41r@example.com").getUnescapedNode()); + assertEquals("space cadet", new JID("space\\20cadet@example.com").getUnescapedNode()); + assertEquals("call me \"ishmael\"", new JID("call\\20me\\20\\22ishmael\\22@example.com").getUnescapedNode()); + assertEquals("at&t guy", new JID("at\\26t\\20guy@example.com").getUnescapedNode()); + assertEquals("d'artagnan", new JID("d\\27artagnan@example.com").getUnescapedNode()); + assertEquals("/.fanboy", new JID("\\2f.fanboy@example.com").getUnescapedNode()); + assertEquals("::foo::", new JID("\\3a\\3afoo\\3a\\3a@example.com").getUnescapedNode()); + assertEquals("", new JID("\\3cfoo\\3e@example.com").getUnescapedNode()); + assertEquals("user@host", new JID("user\\40host@example.com").getUnescapedNode()); + assertEquals("c:\\net", new JID("c\\3a\\net@example.com").getUnescapedNode()); + assertEquals("c:\\\\net", new JID("c\\3a\\\\net@example.com").getUnescapedNode()); + assertEquals("c:\\cool stuff", new JID("c\\3a\\cool\\20stuff@example.com").getUnescapedNode()); + assertEquals("c:\\5commas", new JID("c\\3a\\5c5commas@example.com").getUnescapedNode()); + } +} \ No newline at end of file -- cgit v0.10.2-6-g49f6