001/** 002 * 003 * Copyright © 2014-2024 Florian Schmaus 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jxmpp.jid; 018 019import java.io.Serializable; 020 021import org.jxmpp.jid.parts.Domainpart; 022import org.jxmpp.jid.parts.Localpart; 023import org.jxmpp.jid.parts.Resourcepart; 024 025/** 026 * An <b>XMPP address</b>, also known as JID (formerly for "Jabber Identifier"), which acts as globally unique address 027 * within the XMPP network. 028 * <p> 029 * JIDs are created from {@link String} or {@link CharSequence} with the {@link org.jxmpp.jid.impl.JidCreate} utility. 030 * </p> 031 * 032 * <pre> 033 * Jid jid = JidCreate.from("juliet@capulet.org/balcony"); 034 * EntityBareJid bareJid = JidCreate.entityBareFrom("romeo@montague.net"); 035 * </pre> 036 * <p> 037 * This is the super interface for all JID types, which are constructed from two dimensions: Bare/Full and 038 * Domain/Entity. Every JID consists at least of a {@link Domainpart}. Bare JID types do not come with a 039 * {@link Resourcepart}, full JID types always have a {@link Resourcepart}. Domain JID types do not possess a 040 * {@link Localpart}, whereas entity JID types always do. 041 * </p> 042 * <p> 043 * The following table shows a few examples of JID types. 044 * </p> 045 * <table> 046 * <caption>XMPP Address Types</caption> 047 * <tr> 048 * <td>Example</td> 049 * <td>Type</td> 050 * </tr> 051 * <tr> 052 * <td><code>example.org</code></td> 053 * <td>{@link DomainBareJid}</td> 054 * </tr> 055 * <tr> 056 * <td><code>example.org/resource</code></td> 057 * <td>{@link DomainFullJid}</td> 058 * </tr> 059 * <tr> 060 * <td><code>user@example.org</code></td> 061 * <td>{@link EntityBareJid}</td> 062 * </tr> 063 * <tr> 064 * <td><code>user@example.org/resource</code></td> 065 * <td>{@link EntityFullJid}</td> 066 * </tr> 067 * </table> 068 * <p> 069 * You can retrieve the escaped String representing the Jid with {@link #toString()} or the unescaped String of the JID 070 * with {@link #asUnescapedString()}. 071 * </p> 072 * <h2>URL Encoded JIDs</h2> 073 * <p> 074 * The URL encoded representation of a JID is ideal if a JID should be stored as part of a path name, e.g. as file name. 075 * You can retrieve this information using {@link #asUrlEncodedString()}. The JidCreate API provides methods to create 076 * JIDs from URL encoded Strings like {@link org.jxmpp.jid.impl.JidCreate#fromUrlEncoded(CharSequence)}. 077 * </p> 078 * 079 * 080 * @see <a href="http://xmpp.org/rfcs/rfc6120.html#arch-addresses">RFC 6120 (XMPP: Core) § 2.1 Global Addresses</a> 081 * @see <a href="http://xmpp.org/rfcs/rfc6122.html#addressing-fundamentals">RFC 6122 (XMPP: Address Format) § 2.1 082 * Fundamentals</a> 083 */ 084public interface Jid extends Comparable<Jid>, CharSequence, Serializable { 085 086 /** 087 * Get the {@link Domainpart} of this Jid. 088 * 089 * @return the domainpart. 090 */ 091 Domainpart getDomain(); 092 093 /** 094 * Returns the String representation of this JID. 095 * 096 * @return the String representation of this JID. 097 */ 098 @Override 099 String toString(); 100 101 /** 102 * Return the <b>unescaped</b> String representation of this JID. 103 * <p> 104 * Since certain Unicode code points are disallowed in the localpart of a JID by the required stringprep profile, 105 * those need to get escaped when used in a real JID. The unescaped representation of the JID is only for 106 * presentation to a human user or for gatewaying to a non-XMPP system. 107 * </p> 108 * For example, if the users inputs {@code 'at&t guy@example.com'}, the escaped real JID created with 109 * {@link org.jxmpp.jid.impl.JidCreate} will be {@code 'at\26t\20guy@example.com'}, which is what 110 * {@link Jid#toString()} will return. But {@link Jid#asUnescapedString()} will return again 111 * {@code 'at&t guy@example.com'}. 112 * 113 * @return the unescaped String representation of this JID. 114 */ 115 String asUnescapedString(); 116 117 /** 118 * Get the URL encoded version of this JID. 119 * 120 * @return the URL encoded version of this JID. 121 * @since 0.7.0 122 */ 123 String asUrlEncodedString(); 124 125 /** 126 * Check if this is a {@link EntityBareJid} or {@link EntityFullJid}. 127 * 128 * @return true if this is an instance of BareJid or FullJid. 129 */ 130 boolean isEntityJid(); 131 132 /** 133 * Check if this is an instance of {@link EntityBareJid}. 134 * 135 * @return true if this is an instance of EntityBareJid 136 */ 137 boolean isEntityBareJid(); 138 139 /** 140 * Check if this is an instance of {@link EntityFullJid}. 141 * 142 * @return true if this is an instance of EntityFullJid 143 */ 144 boolean isEntityFullJid(); 145 146 /** 147 * Check if this is an instance of {@link DomainBareJid}. 148 * 149 * @return true if this is an instance of DomainBareJid 150 */ 151 boolean isDomainBareJid(); 152 153 /** 154 * Check if this is an instance of {@link DomainFullJid}. 155 * 156 * @return true if this is an instance of DomainFullJid 157 */ 158 boolean isDomainFullJid(); 159 160 /** 161 * Check if this is an instance of {@link EntityBareJid} or {@link DomainBareJid}. 162 * 163 * @return true if this is an instance of BareJid or DomainBareJid 164 */ 165 boolean hasNoResource(); 166 167 /** 168 * Check if this is a Jid with a {@link Resourcepart}. 169 * 170 * @return true if this Jid has a resourcepart. 171 */ 172 boolean hasResource(); 173 174 /** 175 * Check if this is a Jid with a {@link Localpart}. 176 * 177 * @return true if this Jid has a localpart. 178 */ 179 boolean hasLocalpart(); 180 181 /** 182 * Return a JID created by removing the Resourcepart from this JID. 183 * 184 * @return this Jid without a Resourcepart. 185 */ 186 BareJid asBareJid(); 187 188 /** 189 * Convert this Jid to a {@link EntityBareJid} if possible. 190 * 191 * @return the corresponding {@link EntityBareJid} or null. 192 */ 193 EntityBareJid asEntityBareJidIfPossible(); 194 195 /** 196 * Convert this Jid to a {@link EntityBareJid} or throw an {@code IllegalStateException} if this is not possible. 197 * 198 * @return the corresponding {@link EntityBareJid}. 199 */ 200 EntityBareJid asEntityBareJidOrThrow(); 201 202 /** 203 * Convert this Jid to a {@link EntityFullJid} if possible. 204 * 205 * @return the corresponding {@link EntityFullJid} or null. 206 */ 207 EntityFullJid asEntityFullJidIfPossible(); 208 209 /** 210 * Convert this Jid to a {@link EntityFullJid} or throw an {@code IllegalStateException} if this is not possible. 211 * 212 * @return the corresponding {@link EntityFullJid}. 213 */ 214 EntityFullJid asEntityFullJidOrThrow(); 215 216 /** 217 * Convert this Jid to a {@link EntityJid} if possible. 218 * 219 * @return the corresponding {@link EntityJid} or null. 220 */ 221 EntityJid asEntityJidIfPossible(); 222 223 /** 224 * Convert this Jid to a {@link EntityJid} or throw an {@code IllegalStateException} if this is not possible. 225 * 226 * @return the corresponding {@link EntityJid}. 227 */ 228 EntityJid asEntityJidOrThrow(); 229 230 /** 231 * Convert this Jid to a {@link FullJid} if possible. 232 * 233 * @return the corresponding {@link FullJid} or null. 234 */ 235 FullJid asFullJidIfPossible(); 236 237 /** 238 * Convert this Jid to a {@link FullJid} or throw an {@code IllegalStateException} if this is not possible. 239 * 240 * @return the corresponding {@link FullJid}. 241 */ 242 EntityFullJid asFullJidOrThrow(); 243 244 /** 245 * Convert this Jid to a {@link DomainBareJid}. 246 * <p> 247 * Note that it is always possible to convert a Jid to a DomainBareJid, since every Jid has a domain part. 248 * </p> 249 * 250 * @return the corresponding DomainBareJid. 251 */ 252 DomainBareJid asDomainBareJid(); 253 254 /** 255 * Convert this Jid to a {@link DomainFullJid} if possible. 256 * 257 * @return the corresponding DomainFullJid or null. 258 */ 259 DomainFullJid asDomainFullJidIfPossible(); 260 261 /** 262 * Convert this Jid to a {@link DomainFullJid} or throw an {@code IllegalStateException} if this is not possible. 263 * 264 * @return the corresponding {@link DomainFullJid}. 265 */ 266 DomainFullJid asDomainFullJidOrThrow(); 267 268 /** 269 * Get the resourcepart of this JID or null. 270 * <p> 271 * If the JID is of form {@code <localpart@domain.example/resource>} then this method returns 'resource'. If the JID no 272 * resourcepart, then <code>null</code> is returned. 273 * </p> 274 * 275 * @return the resource of this JID or null. 276 */ 277 Resourcepart getResourceOrNull(); 278 279 /** 280 * Get the resourcepart of this JID or return the empty resourcepart. 281 * <p> 282 * If the JID is of form {@code <localpart@domain.example/resource>} then this method returns 'resource'. If the JID no 283 * resourcepart, then {@link org.jxmpp.jid.parts.Resourcepart#EMPTY} is returned. 284 * </p> 285 * 286 * @return the resource of this JID or the empty resourcepart. 287 */ 288 Resourcepart getResourceOrEmpty(); 289 290 /** 291 * Get the resourcepart of this JID or throw an {@code IllegalStateException}. 292 * <p> 293 * If the JID is of form {@code <localpart@domain.example/resource>} then this method returns 'resource'. If the JID no 294 * resourcepart, then an {@code IllegalStateException} is thrown. 295 * </p> 296 * 297 * @return the resource of this JID. 298 */ 299 Resourcepart getResourceOrThrow(); 300 301 /** 302 * Get the localpart of this JID or null. 303 * <p> 304 * If the JID is of form {@code <localpart@domain.example>} then this method returns 'localpart'. If the JID has no 305 * localpart, then <code>null</code> is returned. 306 * </p> 307 * 308 * @return the localpart of this JID or null. 309 */ 310 Localpart getLocalpartOrNull(); 311 312 /** 313 * Get the localpart of this JID or throw an {@code IllegalStateException}. 314 * <p> 315 * If the JID is of form {@code <localpart@domain.example>} then this method returns 'localpart'. If the JID has no 316 * localpart, then <code>null</code> is returned. 317 * </p> 318 * 319 * @return the localpart of this JID. 320 */ 321 Localpart getLocalpartOrThrow(); 322 323 /** 324 * Check if this JID is the parent of another JID. The <b>parent of</b> relation is defined, under the 325 * precondition that the JID parts (localpart, domainpart and resourcepart) are equal, as follows: 326 * <pre> 327 * | this JID (parentOf) | other JID | result | 328 * |---------------------+---------------------+--------| 329 * | dom.example | dom.example | true | 330 * | dom.example | dom.example/res | true | 331 * | dom.example | loc@dom.example | true | 332 * | dom.example | loc@dom.example/res | true | 333 * | dom.example/res | dom.exmple | false | 334 * | dom.example/res | dom.example/res | true | 335 * | dom.example/res | loc@dom.example | false | 336 * | dom.example/res | loc@dom.example/res | false | 337 * | loc@dom.example | dom.example | false | 338 * | loc@dom.example | dom.example/res | false | 339 * | loc@dom.example | loc@dom.example | true | 340 * | loc@dom.example | loc@dom.example/res | true | 341 * | loc@dom.example/res | dom.example | false | 342 * | loc@dom.example/res | dom.example/res | false | 343 * | loc@dom.example/res | loc@dom.example | false | 344 * | loc@dom.example/res | loc@dom.example/res | true | 345 * </pre> 346 * 347 * @param jid 348 * the other JID to compare with 349 * @return true if this JID is a parent of the given JID. 350 */ 351 boolean isParentOf(Jid jid); 352 353 /** 354 * See {@link #isParentOf(Jid)}. 355 * 356 * @param bareJid the bare JID. 357 * @return true if this JID is a parent of the given JID. 358 */ 359 boolean isParentOf(EntityBareJid bareJid); 360 361 /** 362 * See {@link #isParentOf(Jid)}. 363 * 364 * @param fullJid the full JID. 365 * @return true if this JID is a parent of the given JID. 366 */ 367 boolean isParentOf(EntityFullJid fullJid); 368 369 /** 370 * See {@link #isParentOf(Jid)}. 371 * 372 * @param domainBareJid the domain bare JID. 373 * @return true if this JID is a parent of the given JID. 374 */ 375 boolean isParentOf(DomainBareJid domainBareJid); 376 377 /** 378 * See {@link #isParentOf(Jid)}. 379 * 380 * @param domainFullJid the domain full JID. 381 * @return true if this JID is a parent of the given JID. 382 */ 383 boolean isParentOf(DomainFullJid domainFullJid); 384 385 /** 386 * Check if this JID is the strict parent of another JID. In other words, all parts of this JID must 387 * exist on the other JID, and match this JID's values. Furthermore, and this is what makes this 388 * method different from {@link #isParentOf(Jid)}, the other JID must have one additional part, 389 * that this JID does not have. The <b>parent of</b> relation is defined, under the 390 * precondition that the JID parts (localpart, domainpart and resourcepart) are equal, as follows: 391 * <pre> 392 * | this JID | other JID | result | 393 * |---------------------+---------------------+--------| 394 * | dom.example | dom.example | false | (different from isParentOf) 395 * | dom.example | dom.example/res | true | 396 * | dom.example | loc@dom.example | true | 397 * | dom.example | loc@dom.example/res | true | 398 * | dom.example/res | dom.exmple | false | 399 * | dom.example/res | dom.example/res | false | (different from isParentOf) 400 * | dom.example/res | loc@dom.example | false | 401 * | dom.example/res | loc@dom.example/res | false | 402 * | loc@dom.example | dom.example | false | 403 * | loc@dom.example | dom.example/res | false | 404 * | loc@dom.example | loc@dom.example | false | (different from isParentOf) 405 * | loc@dom.example | loc@dom.example/res | true | 406 * | loc@dom.example/res | dom.example | false | 407 * | loc@dom.example/res | dom.example/res | false | 408 * | loc@dom.example/res | loc@dom.example | false | 409 * | loc@dom.example/res | loc@dom.example/res | false | (different from isParentOf) 410 * </pre> 411 * 412 * @param jid 413 * the other JID to compare with 414 * @return true if this JID is a parent of the given JID. 415 */ 416 boolean isStrictParentOf(Jid jid); 417 418 /** 419 * See {@link #isParentOf(Jid)}. 420 * 421 * @param bareJid the bare JID. 422 * @return true if this JID is a parent of the given JID. 423 */ 424 boolean isStrictParentOf(EntityBareJid bareJid); 425 426 /** 427 * See {@link #isStrictParentOf(Jid)}. 428 * 429 * @param fullJid the full JID. 430 * @return true if this JID is a parent of the given JID. 431 */ 432 boolean isStrictParentOf(EntityFullJid fullJid); 433 434 /** 435 * See {@link #isStrictParentOf(Jid)}. 436 * 437 * @param domainBareJid the domain bare JID. 438 * @return true if this JID is a parent of the given JID. 439 */ 440 boolean isStrictParentOf(DomainBareJid domainBareJid); 441 442 /** 443 * See {@link #isStrictParentOf(Jid)}. 444 * 445 * @param domainFullJid the domain full JID. 446 * @return true if this JID is a parent of the given JID. 447 */ 448 boolean isStrictParentOf(DomainFullJid domainFullJid); 449 450 /** 451 * 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. 452 * 453 * @param jidClass the class of JID to downcast too. 454 * @param <T> the Jid type to downcast to. 455 * @return the downcasted instanced of this 456 * @throws ClassCastException if this JID is not assignable to the type T. 457 */ 458 <T extends Jid> T downcast(Class<T> jidClass) throws ClassCastException; 459 460 /** 461 * Compares the given CharSequence with this JID. Returns true if {@code equals(charSequence.toString()} would 462 * return true. 463 * 464 * @param charSequence the CharSequence to compare this JID with. 465 * @return true if if {@code equals(charSequence.toString()} would return true. 466 * @see #equals(String) 467 */ 468 @SuppressWarnings("NonOverridingEquals") 469 boolean equals(CharSequence charSequence); 470 471 /** 472 * Compares the given String wit this JID. 473 * <p> 474 * Returns true if {@code toString().equals(string)}, that is if the String representation of this JID matches the given string. 475 * </p> 476 * 477 * @param string the String to compare this JID with. 478 * @return true if {@code toString().equals(string)}. 479 */ 480 @SuppressWarnings("NonOverridingEquals") 481 boolean equals(String string); 482 483 /** 484 * Returns the canonical String representation of this JID. See {@link String#intern} for details. 485 * 486 * @return the canonical String representation. 487 */ 488 String intern(); 489}