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}