001/**
002 *
003 * Copyright © 2014-2018 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 summary="XMPP Address Types">
046 * <tr>
047 * <td>Example</td>
048 * <td>Type</td>
049 * </tr>
050 * <tr>
051 * <td><code>example.org</code></td>
052 * <td>{@link DomainBareJid}</td>
053 * </tr>
054 * <tr>
055 * <td><code>example.org/resource</code></td>
056 * <td>{@link DomainFullJid}</td>
057 * </tr>
058 * <tr>
059 * <td><code>user@example.org</code></td>
060 * <td>{@link EntityBareJid}</td>
061 * </tr>
062 * <tr>
063 * <td><code>user@example.org/resource</code></td>
064 * <td>{@link EntityFullJid}</td>
065 * </tr>
066 * </table>
067 * <p>
068 * You can retrieve the escaped String representing the Jid with {@link #toString()} or the unsecaped String of the JID
069 * with {@link #asUnescapedString()}.
070 * </p>
071 *
072 * @see <a href="http://xmpp.org/rfcs/rfc6120.html#arch-addresses">RFC 6120 (XMPP: Core) § 2.1 Global Addresses</a>
073 * @see <a href="http://xmpp.org/rfcs/rfc6122.html#addressing-fundamentals">RFC 6122 (XMPP: Address Format) § 2.1
074 * Fundamentals</a>
075 */
076public interface Jid extends Comparable<Jid>, CharSequence, Serializable {
077
078        /**
079         * Get the {@link Domainpart} of this Jid.
080         *
081         * @return the domainpart.
082         */
083        Domainpart getDomain();
084
085        /**
086         * Returns the String representation of this JID.
087         *
088         * @return the String representation of this JID.
089         */
090        @Override
091        String toString();
092
093        /**
094         * Return the <b>unescaped</b> String representation of this JID.
095         * <p>
096         * Since certain Unicode code points are disallowed in the localpart of a JID by the required stringprep profile,
097         * those need to get escaped when used in a real JID. The unescaped representation of the JID is only for
098         * presentation to a human user or for gatewaying to a non-XMPP system.
099         * </p>
100         * For example, if the users inputs {@code 'at&t guy@example.com'}, the escaped real JID created with
101         * {@link org.jxmpp.jid.impl.JidCreate} will be {@code 'at\26t\20guy@example.com'}, which is what
102         * {@link Jid#toString()} will return. But {@link Jid#asUnescapedString()} will return again
103         * {@code 'at&t guy@example.com'}.
104         *
105         * @return the unescaped String representation of this JID.
106         */
107        String asUnescapedString();
108
109        /**
110         * Check if this is a {@link EntityBareJid} or {@link EntityFullJid}.
111         *
112         * @return true if this is an instance of BareJid or FullJid.
113         */
114        boolean isEntityJid();
115
116        /**
117         * Check if this is an instance of {@link EntityBareJid}.
118         * 
119         * @return true if this is an instance of BareJid
120         */
121        boolean isEntityBareJid();
122
123        /**
124         * Check if this is an instance of {@link EntityFullJid}.
125         * 
126         * @return true if this is an instance of FullJid
127         */
128        boolean isEntityFullJid();
129
130        /**
131         * Check if this is an instance of {@link DomainBareJid}.
132         *  
133         * @return true if this is an instance of DomainBareJid
134         */
135        boolean isDomainBareJid();
136
137        /**
138         * Check if this is an instance of {@link DomainFullJid}.
139         * 
140         * @return true if this is an instance of DomainFullJid
141         */
142        boolean isDomainFullJid();
143
144        /**
145         * Check if this is an instance of {@link EntityBareJid} or {@link DomainBareJid}.
146         * 
147         * @return true if this is an instance of BareJid or DomainBareJid
148         */
149        boolean hasNoResource();
150
151        /**
152         * Check if this is a Jid with a {@link Resourcepart}.
153         *
154         * @return true if this Jid has a resourcepart.
155         */
156        boolean hasResource();
157
158        /**
159         * Check if this is a Jid with a {@link Localpart}.
160         *
161         * @return true if this Jid has a localpart.
162         */
163        boolean hasLocalpart();
164
165        /**
166         * Return a JID created by removing the Resourcepart from this JID.
167         *
168         * @return this Jid without a Resourcepart.
169         */
170        BareJid asBareJid();
171
172        /**
173         * Convert this Jid to a {@link EntityBareJid} if possible.
174         *
175         * @return the corresponding {@link EntityBareJid} or null.
176         */
177        EntityBareJid asEntityBareJidIfPossible();
178
179        /**
180         * Convert this Jid to a {@link EntityBareJid} or throw an {@code IllegalStateException} if this is not possible.
181         * 
182         * @return the corresponding {@link EntityBareJid}.
183         */
184        EntityBareJid asEntityBareJidOrThrow();
185
186        /**
187         * Convert this Jid to a {@link EntityFullJid} if possible.
188         *
189         * @return the corresponding {@link EntityFullJid} or null.
190         */
191        EntityFullJid asEntityFullJidIfPossible();
192
193        /**
194         * Convert this Jid to a {@link EntityFullJid} or throw an {@code IllegalStateException} if this is not possible.
195         * 
196         * @return the corresponding {@link EntityFullJid}.
197         */
198        EntityFullJid asEntityFullJidOrThrow();
199
200        /**
201         * Convert this Jid to a {@link EntityJid} if possible.
202         *
203         * @return the corresponding {@link EntityJid} or null.
204         */
205        EntityJid asEntityJidIfPossible();
206
207        /**
208         * Convert this Jid to a {@link EntityJid} or throw an {@code IllegalStateException} if this is not possible.
209         * 
210         * @return the corresponding {@link EntityJid}.
211         */
212        EntityJid asEntityJidOrThrow();
213
214        /**
215         * Convert this Jid to a {@link FullJid} if possible.
216         *
217         * @return the corresponding {@link FullJid} or null.
218         */
219        FullJid asFullJidIfPossible();
220
221        /**
222         * Convert this Jid to a {@link FullJid} or throw an {@code IllegalStateException} if this is not possible.
223         * 
224         * @return the corresponding {@link FullJid}.
225         */
226        EntityFullJid asFullJidOrThrow();
227
228        /**
229         * Convert this Jid to a {@link DomainBareJid}.
230         * <p>
231         * Note that it is always possible to convert a Jid to a DomainBareJid, since every Jid has a domain part.
232         * </p>
233         *
234         * @return the corresponding DomainBareJid.
235         */
236        DomainBareJid asDomainBareJid();
237
238        /**
239         * Convert this Jid to a {@link DomainFullJid} if possible.
240         *
241         * @return the corresponding DomainFullJid or null.
242         */
243        DomainFullJid asDomainFullJidIfPossible();
244
245        /**
246         * Convert this Jid to a {@link DomainFullJid} or throw an {@code IllegalStateException} if this is not possible.
247         * 
248         * @return the corresponding {@link DomainFullJid}.
249         */
250        DomainFullJid asDomainFullJidOrThrow();
251
252        /**
253         * Get the resourcepart of this JID or null.
254         * <p>
255         * If the JID is of form {@code <localpart@domain.example/resource>} then this method returns 'resource'. If the JID no
256         * resourcepart, then <code>null</code> is returned.
257         * </p>
258         * 
259         * @return the resource of this JID or null.
260         */
261        Resourcepart getResourceOrNull();
262
263        /**
264         * Get the resourcepart of this JID or return the empty resourcepart.
265         * <p>
266         * If the JID is of form {@code <localpart@domain.example/resource>} then this method returns 'resource'. If the JID no
267         * resourcepart, then {@link org.jxmpp.jid.parts.Resourcepart#EMPTY} is returned.
268         * </p>
269         * 
270         * @return the resource of this JID or the empty resourcepart.
271         */
272        Resourcepart getResourceOrEmpty();
273
274        /**
275         * Get the resourcepart of this JID or throw an {@code IllegalStateException}.
276         * <p>
277         * If the JID is of form {@code <localpart@domain.example/resource>} then this method returns 'resource'. If the JID no
278         * resourcepart, then an {@code IllegalStateException} is thrown.
279         * </p>
280         * 
281         * @return the resource of this JID.
282         */
283        Resourcepart getResourceOrThrow();
284
285        /**
286         * Get the localpart of this JID or null.
287         * <p>
288         * If the JID is of form {@code <localpart@domain.example>} then this method returns 'localpart'. If the JID has no
289         * localpart, then <code>null</code> is returned.
290         * </p>
291         * 
292         * @return the localpart of this JID or null.
293         */
294        Localpart getLocalpartOrNull();
295
296        /**
297         * Get the localpart of this JID or throw an {@code IllegalStateException}.
298         * <p>
299         * If the JID is of form {@code <localpart@domain.example>} then this method returns 'localpart'. If the JID has no
300         * localpart, then <code>null</code> is returned.
301         * </p>
302         * 
303         * @return the localpart of this JID.
304         */
305        Localpart getLocalpartOrThrow();
306
307        /**
308         * Check if this JID is the parent of another JID. The <b>parent of</b> relation is defined, under the
309         * precondition that the JID parts (localpart, domainpart and resourcepart) are equal, as follows:
310         * <pre>
311         * | this JID (parentOf) | other JID           | result |
312         * |---------------------+---------------------+--------|
313         * | dom.example         | dom.example         | true   |
314         * | dom.example         | dom.example/res     | true   |
315         * | dom.example         | loc@dom.example     | true   |
316         * | dom.example         | loc@dom.example/res | true   |
317         * | dom.example/res     | dom.exmple          | false  |
318         * | dom.example/res     | dom.example/res     | true   |
319         * | dom.example/res     | loc@dom.example     | false  |
320         * | dom.example/res     | loc@dom.example/res | false  |
321         * | loc@dom.example     | dom.example         | false  |
322         * | loc@dom.example     | dom.example/res     | false  |
323         * | loc@dom.example     | loc@dom.example     | true   |
324         * | loc@dom.example     | loc@dom.example/res | true   |
325         * | loc@dom.example/res | dom.example         | false  |
326         * | loc@dom.example/res | dom.example/res     | false  |
327         * | loc@dom.example/res | loc@dom.example     | false  |
328         * | loc@dom.example/res | loc@dom.example/res | true   |
329         * </pre>
330         * 
331         * @param jid
332         *            the other JID to compare with
333         * @return true if this JID is a parent of the given JID.
334         */
335        boolean isParentOf(Jid jid);
336
337        /**
338         * See {@link #isParentOf(Jid)}.
339         *
340         * @param bareJid the bare JID.
341         * @return true if this JID is a parent of the given JID.
342         */
343        boolean isParentOf(EntityBareJid bareJid);
344
345        /**
346         * See {@link #isParentOf(Jid)}.
347         *
348         * @param fullJid the full JID.
349         * @return true if this JID is a parent of the given JID.
350         */
351        boolean isParentOf(EntityFullJid fullJid);
352
353        /**
354         * See {@link #isParentOf(Jid)}.
355         *
356         * @param domainBareJid the domain bare JID.
357         * @return true if this JID is a parent of the given JID.
358         */
359        boolean isParentOf(DomainBareJid domainBareJid);
360
361        /**
362         * See {@link #isParentOf(Jid)}.
363         *
364         * @param domainFullJid the domain full JID.
365         * @return true if this JID is a parent of the given JID.
366         */
367        boolean isParentOf(DomainFullJid domainFullJid);
368
369        /**
370         * 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.
371         *
372         * @param jidClass the class of JID to downcast too.
373         * @param <T> the Jid type to downcast to.
374         * @return the downcasted instanced of this
375         * @throws ClassCastException if this JID is not assignable to the type T.
376         */
377        <T extends Jid> T downcast(Class<T> jidClass) throws ClassCastException;
378
379        /**
380         * Compares the given CharSequence with this JID. Returns true if {@code equals(charSequence.toString()} would
381         * return true.
382         *
383         * @param charSequence the CharSequence to compare this JID with.
384         * @return true if if {@code equals(charSequence.toString()} would return true.
385         * @see #equals(String)
386         */
387        @SuppressWarnings("NonOverridingEquals")
388        boolean equals(CharSequence charSequence);
389
390        /**
391         * Compares the given String wit this JID.
392         * <p>
393         * Returns true if {@code toString().equals(string)}, that is if the String representation of this JID matches the given string.
394         * </p>
395         *
396         * @param string the String to compare this JID with.
397         * @return true if {@code toString().equals(string)}.
398         */
399        @SuppressWarnings("NonOverridingEquals")
400        boolean equals(String string);
401
402        /**
403         * Returns the canonical String representation of this JID. See {@link String#intern} for details.
404         * 
405         * @return the canonical String representation.
406         */
407        String intern();
408}