diff --git a/jxmpp-jid/src/main/java/org/jxmpp/jid/Jid.java b/jxmpp-jid/src/main/java/org/jxmpp/jid/Jid.java index 7fb45cd..ad8ac1c 100644 --- a/jxmpp-jid/src/main/java/org/jxmpp/jid/Jid.java +++ b/jxmpp-jid/src/main/java/org/jxmpp/jid/Jid.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014-2020 Florian Schmaus + * Copyright © 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -382,6 +382,71 @@ public interface Jid extends Comparable, CharSequence, Serializable { */ boolean isParentOf(DomainFullJid domainFullJid); + /** + * Check if this JID is the strict parent of another JID. In other words, all parts of this JID must + * exist on the other JID, and match this JID's values. Furthermore, and this is what makes this + * method different from {@link #isParentOf(Jid)}, the other JID must have one additional part, + * that this JID does not have. The parent of relation is defined, under the + * precondition that the JID parts (localpart, domainpart and resourcepart) are equal, as follows: + *
+	 * | this JID            | other JID           | result |
+	 * |---------------------+---------------------+--------|
+	 * | dom.example         | dom.example         | false  | (different from isParentOf)
+	 * | dom.example         | dom.example/res     | true   |
+	 * | dom.example         | loc@dom.example     | true   |
+	 * | dom.example         | loc@dom.example/res | true   |
+	 * | dom.example/res     | dom.exmple          | false  |
+	 * | dom.example/res     | dom.example/res     | false  | (different from isParentOf)
+	 * | dom.example/res     | loc@dom.example     | false  |
+	 * | dom.example/res     | loc@dom.example/res | false  |
+	 * | loc@dom.example     | dom.example         | false  |
+	 * | loc@dom.example     | dom.example/res     | false  |
+	 * | loc@dom.example     | loc@dom.example     | false  | (different from isParentOf)
+	 * | loc@dom.example     | loc@dom.example/res | true   |
+	 * | loc@dom.example/res | dom.example         | false  |
+	 * | loc@dom.example/res | dom.example/res     | false  |
+	 * | loc@dom.example/res | loc@dom.example     | false  |
+	 * | loc@dom.example/res | loc@dom.example/res | false  | (different from isParentOf)
+	 * 
+ * + * @param jid + * the other JID to compare with + * @return true if this JID is a parent of the given JID. + */ + boolean isStrictParentOf(Jid jid); + + /** + * See {@link #isParentOf(Jid)}. + * + * @param bareJid the bare JID. + * @return true if this JID is a parent of the given JID. + */ + boolean isStrictParentOf(EntityBareJid bareJid); + + /** + * See {@link #isStrictParentOf(Jid)}. + * + * @param fullJid the full JID. + * @return true if this JID is a parent of the given JID. + */ + boolean isStrictParentOf(EntityFullJid fullJid); + + /** + * See {@link #isStrictParentOf(Jid)}. + * + * @param domainBareJid the domain bare JID. + * @return true if this JID is a parent of the given JID. + */ + boolean isStrictParentOf(DomainBareJid domainBareJid); + + /** + * See {@link #isStrictParentOf(Jid)}. + * + * @param domainFullJid the domain full JID. + * @return true if this JID is a parent of the given JID. + */ + boolean isStrictParentOf(DomainFullJid domainFullJid); + /** * Return the downcasted instance of this Jid. This method is unsafe, make sure to check that this is actually of the type of are casting to. * diff --git a/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/AbstractJid.java b/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/AbstractJid.java index 74bf05b..3efdad4 100644 --- a/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/AbstractJid.java +++ b/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/AbstractJid.java @@ -180,6 +180,24 @@ public final boolean isParentOf(Jid jid) { return isParentOf(jid.asDomainBareJid()); } + @Override + public final boolean isStrictParentOf(Jid jid) { + EntityFullJid fullJid = jid.asEntityFullJidIfPossible(); + if (fullJid != null) { + return isStrictParentOf(fullJid); + } + EntityBareJid bareJid = jid.asEntityBareJidIfPossible(); + if (bareJid != null) { + return isStrictParentOf(bareJid); + } + DomainFullJid domainFullJid = jid.asDomainFullJidIfPossible(); + if (domainFullJid != null) { + return isStrictParentOf(domainFullJid); + } + + return isStrictParentOf(jid.asDomainBareJid()); + } + @Override public final int hashCode() { return toString().hashCode(); diff --git a/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/DomainAndResourcepartJid.java b/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/DomainAndResourcepartJid.java index eb89daf..6f95edf 100644 --- a/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/DomainAndResourcepartJid.java +++ b/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/DomainAndResourcepartJid.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014-2019 Florian Schmaus + * Copyright © 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -115,6 +115,27 @@ public boolean isParentOf(DomainFullJid domainFullJid) { return domainBareJid.equals(domainFullJid.getDomain()) && resource.equals(domainFullJid.getResourcepart()); } + @Override + public boolean isStrictParentOf(EntityBareJid bareJid) { + return false; + } + + @Override + public boolean isStrictParentOf(EntityFullJid fullJid) { + return false; + } + + @Override + public boolean isStrictParentOf(DomainBareJid domainBareJid) { + return false; + } + + @Override + public boolean isStrictParentOf(DomainFullJid domainFullJid) { + // A DomainFullJid can never be the strict parent of another DomainFullJid. + return false; + } + @Override public Resourcepart getResourcepart() { return resource; diff --git a/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/DomainpartJid.java b/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/DomainpartJid.java index 21ec762..716a1df 100644 --- a/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/DomainpartJid.java +++ b/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/DomainpartJid.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014-2021 Florian Schmaus + * Copyright © 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -114,6 +114,26 @@ public boolean isParentOf(DomainFullJid domainFullJid) { return domain.equals(domainFullJid.getDomain()); } + @Override + public boolean isStrictParentOf(EntityBareJid bareJid) { + return isParentOf(bareJid); + } + + @Override + public boolean isStrictParentOf(EntityFullJid fullJid) { + return isParentOf(fullJid); + } + + @Override + public boolean isStrictParentOf(DomainBareJid domainBareJid) { + return false; + } + + @Override + public boolean isStrictParentOf(DomainFullJid domainFullJid) { + return isParentOf(domainFullJid); + } + @Override public BareJid asBareJid() { return this; diff --git a/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/LocalAndDomainpartJid.java b/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/LocalAndDomainpartJid.java index 836639e..845b6d7 100644 --- a/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/LocalAndDomainpartJid.java +++ b/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/LocalAndDomainpartJid.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014-2019 Florian Schmaus + * Copyright © 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -110,6 +110,26 @@ public boolean isParentOf(DomainFullJid domainFullJid) { return false; } + @Override + public boolean isStrictParentOf(EntityBareJid bareJid) { + return false; + } + + @Override + public boolean isStrictParentOf(EntityFullJid fullJid) { + return isParentOf(fullJid); + } + + @Override + public boolean isStrictParentOf(DomainBareJid domainBareJid) { + return false; + } + + @Override + public boolean isStrictParentOf(DomainFullJid domainFullJid) { + return false; + } + @Override public DomainBareJid asDomainBareJid() { return domainBareJid; diff --git a/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/LocalDomainAndResourcepartJid.java b/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/LocalDomainAndResourcepartJid.java index 7e4eb06..4f6be3b 100644 --- a/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/LocalDomainAndResourcepartJid.java +++ b/jxmpp-jid/src/main/java/org/jxmpp/jid/impl/LocalDomainAndResourcepartJid.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014-2019 Florian Schmaus + * Copyright © 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -128,6 +128,26 @@ public boolean isParentOf(DomainFullJid domainFullJid) { return false; } + @Override + public boolean isStrictParentOf(EntityBareJid bareJid) { + return false; + } + + @Override + public boolean isStrictParentOf(EntityFullJid fullJid) { + return false; + } + + @Override + public boolean isStrictParentOf(DomainBareJid domainBareJid) { + return false; + } + + @Override + public boolean isStrictParentOf(DomainFullJid domainFullJid) { + return false; + } + @Override public DomainBareJid asDomainBareJid() { return bareJid.asDomainBareJid(); diff --git a/jxmpp-jid/src/test/java/org/jxmpp/jid/JidTest.java b/jxmpp-jid/src/test/java/org/jxmpp/jid/JidTest.java index 4769742..d732134 100644 --- a/jxmpp-jid/src/test/java/org/jxmpp/jid/JidTest.java +++ b/jxmpp-jid/src/test/java/org/jxmpp/jid/JidTest.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014 Florian Schmaus + * Copyright © 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,6 +54,34 @@ public void testJidIsParentOf() throws XmppStringprepException { assertTrue(fullJid.isParentOf(fullJid)); } + @Test + public void testJidIsStrictParentOf() throws XmppStringprepException { + final Jid domainBareJid = JidCreate.from("dom.example"); + final Jid domainFullJid = JidCreate.from("dom.example/res"); + final Jid bareJid = JidCreate.from("loc@dom.example"); + final Jid fullJid = JidCreate.from("loc@dom.example/res"); + + assertFalse(domainBareJid.isStrictParentOf(domainBareJid)); // different from isParentOf + assertTrue(domainBareJid.isStrictParentOf(domainFullJid)); + assertTrue(domainBareJid.isStrictParentOf(bareJid)); + assertTrue(domainBareJid.isStrictParentOf(fullJid)); + + assertFalse(domainFullJid.isStrictParentOf(domainBareJid)); + assertFalse(domainFullJid.isStrictParentOf(domainFullJid)); // different from isParentOf + assertFalse(domainFullJid.isStrictParentOf(bareJid)); + assertFalse(domainFullJid.isStrictParentOf(fullJid)); + + assertFalse(bareJid.isStrictParentOf(domainBareJid)); + assertFalse(bareJid.isStrictParentOf(domainFullJid)); + assertFalse(bareJid.isStrictParentOf(bareJid)); // different from isParentOf + assertTrue(bareJid.isStrictParentOf(fullJid)); + + assertFalse(fullJid.isStrictParentOf(domainBareJid)); + assertFalse(fullJid.isStrictParentOf(domainFullJid)); + assertFalse(fullJid.isStrictParentOf(bareJid)); + assertFalse(fullJid.isStrictParentOf(fullJid)); // different from isParentOf + } + @Test public void stripFinalDot() throws XmppStringprepException { String domain = "foo.bar.";