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.impl; 018 019import org.jxmpp.jid.BareJid; 020import org.jxmpp.jid.EntityBareJid; 021import org.jxmpp.jid.DomainBareJid; 022import org.jxmpp.jid.DomainFullJid; 023import org.jxmpp.jid.EntityFullJid; 024import org.jxmpp.jid.EntityJid; 025import org.jxmpp.jid.FullJid; 026import org.jxmpp.jid.Jid; 027import org.jxmpp.jid.parts.Domainpart; 028import org.jxmpp.jid.parts.Localpart; 029import org.jxmpp.jid.parts.Resourcepart; 030import org.jxmpp.stringprep.XmppStringprepException; 031import org.jxmpp.util.cache.Cache; 032import org.jxmpp.util.cache.LruCache; 033import org.jxmpp.util.XmppStringUtils; 034 035/** 036 * API to create JIDs (XMPP addresses) from Strings and CharSequences. 037 * <p> 038 * If the input was user generated, e.g. captured from some sort of user 039 * interface, {@link #fromUnescaped(String)} should be used instead. This allows 040 * the user to enter unescaped JID values. You can use 041 * {@link org.jxmpp.jid.util.JidUtil#isValidEntityBareJid(CharSequence)} to 042 * query, e.g. while the user it entering it, if a given CharSequence is a valid 043 * bare JID. 044 * </p> 045 * <p> 046 * JIDs created from input received from an XMPP source should use 047 * {@link #from(String)}. 048 * </p> 049 * <p> 050 * JidCreate uses caches for efficient Jid construction, But it's not guaranteed 051 * that the same String or CharSequence will yield the same Jid instance. 052 * </p> 053 * 054 * @see Jid 055 */ 056public class JidCreate { 057 058 private static final Cache<String, Jid> JID_CACHE = new LruCache<String, Jid>(100); 059 private static final Cache<String, BareJid> BAREJID_CACHE = new LruCache<>(100); 060 private static final Cache<String, EntityJid> ENTITYJID_CACHE = new LruCache<>(100); 061 private static final Cache<String, FullJid> FULLJID_CACHE = new LruCache<>(100); 062 private static final Cache<String, EntityBareJid> ENTITY_BAREJID_CACHE = new LruCache<>(100); 063 private static final Cache<String, EntityFullJid> ENTITY_FULLJID_CACHE = new LruCache<>(100); 064 private static final Cache<String, DomainBareJid> DOMAINJID_CACHE = new LruCache<String, DomainBareJid>(100); 065 private static final Cache<String, DomainFullJid> DOMAINRESOURCEJID_CACHE = new LruCache<String, DomainFullJid>(100); 066 067 /** 068 * Get a {@link Jid} from the given parts. 069 * <p> 070 * Only the domainpart is required. 071 * </p> 072 * 073 * @param localpart a optional localpart. 074 * @param domainpart a required domainpart. 075 * @param resource a optional resourcepart. 076 * @return a JID which consists of the given parts. 077 * @throws XmppStringprepException if an error occurs. 078 */ 079 public static Jid from(CharSequence localpart, CharSequence domainpart, CharSequence resource) 080 throws XmppStringprepException { 081 return from(localpart.toString(), domainpart.toString(), resource.toString()); 082 } 083 084 /** 085 * Get a {@link Jid} from the given parts. 086 * <p> 087 * Only the domainpart is required. 088 * </p> 089 * 090 * @param localpart a optional localpart. 091 * @param domainpart a required domainpart. 092 * @param resource a optional resourcepart. 093 * @return a JID which consists of the given parts. 094 * @throws XmppStringprepException if an error occurs. 095 */ 096 public static Jid from(String localpart, String domainpart, String resource) throws XmppStringprepException { 097 String jidString = XmppStringUtils.completeJidFrom(localpart, domainpart, resource); 098 Jid jid = JID_CACHE.lookup(jidString); 099 if (jid != null) { 100 return jid; 101 } 102 if (localpart.length() > 0 && domainpart.length() > 0 && resource.length() > 0) { 103 jid = new LocalDomainAndResourcepartJid(localpart, domainpart, resource); 104 } else if (localpart.length() > 0 && domainpart.length() > 0 && resource.length() == 0) { 105 jid = new LocalAndDomainpartJid(localpart, domainpart); 106 } else if (localpart.length() == 0 && domainpart.length() > 0 && resource.length() == 0) { 107 jid = new DomainpartJid(domainpart); 108 } else if (localpart.length() == 0 && domainpart.length() > 0 && resource.length() > 0) { 109 jid = new DomainAndResourcepartJid(domainpart, resource); 110 } else { 111 throw new IllegalArgumentException("Not a valid combination of localpart, domainpart and resource"); 112 } 113 JID_CACHE.put(jidString, jid); 114 return jid; 115 } 116 117 /** 118 * Like {@link #from(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 119 * {@link XmppStringprepException}. 120 * 121 * @param cs the character sequence which should be transformed to a {@link Jid} 122 * @return the {@link Jid} if no exception occurs 123 * @throws IllegalArgumentException if the given input is not a valid JID 124 * @see #from(String) 125 * @since 0.6.2 126 */ 127 public static Jid fromOrThrowUnchecked(CharSequence cs) { 128 try { 129 return from(cs); 130 } catch (XmppStringprepException e) { 131 throw new IllegalArgumentException(e); 132 } 133 } 134 135 /** 136 * Get a {@link Jid} from a CharSequence. 137 * 138 * @param jid the input CharSequence. 139 * @return the Jid represented by the input CharSequence. 140 * @throws XmppStringprepException if an error occurs. 141 * @see #from(String) 142 */ 143 public static Jid from(CharSequence jid) throws XmppStringprepException { 144 return from(jid.toString()); 145 } 146 147 /** 148 * Get a {@link Jid} from the given String. 149 * 150 * @param jidString the input String. 151 * @return the Jid represented by the input String. 152 * @throws XmppStringprepException if an error occurs. 153 * @see #from(CharSequence) 154 */ 155 public static Jid from(String jidString) throws XmppStringprepException { 156 String localpart = XmppStringUtils.parseLocalpart(jidString); 157 String domainpart = XmppStringUtils.parseDomain(jidString); 158 String resource = XmppStringUtils.parseResource(jidString); 159 try { 160 return from(localpart, domainpart, resource); 161 } catch (XmppStringprepException e) { 162 throw new XmppStringprepException(jidString, e); 163 } 164 } 165 166 /** 167 * Get a {@link Jid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 168 * 169 * @param cs the input {@link CharSequence} 170 * @return a JID or {@code null} 171 */ 172 public static Jid fromOrNull(CharSequence cs) { 173 try { 174 return from(cs); 175 } catch (XmppStringprepException e) { 176 return null; 177 } 178 } 179 180 /** 181 * Like {@link #fromUnescaped(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 182 * {@link XmppStringprepException}. 183 * 184 * @param cs the character sequence which should be transformed to a {@link Jid} 185 * @return the {@link Jid} if no exception occurs 186 * @throws IllegalArgumentException if the given input is not a valid JID 187 * @see #fromUnescaped(CharSequence) 188 * @since 0.6.2 189 */ 190 public static Jid fromUnescapedOrThrowUnchecked(CharSequence cs) { 191 try { 192 return fromUnescaped(cs); 193 } catch (XmppStringprepException e) { 194 throw new IllegalArgumentException(e); 195 } 196 } 197 198 /** 199 * Get a {@link Jid} from the given unescaped CharSequence. 200 * 201 * @param unescapedJid an unescaped CharSequence representing a JID. 202 * @return a JID. 203 * @throws XmppStringprepException if an error occurs. 204 */ 205 public static Jid fromUnescaped(CharSequence unescapedJid) throws XmppStringprepException { 206 return fromUnescaped(unescapedJid.toString()); 207 } 208 209 /** 210 * Get a {@link Jid} from the given unescaped String. 211 * 212 * @param unescapedJidString a unescaped String representing a JID. 213 * @return a JID. 214 * @throws XmppStringprepException if an error occurs. 215 */ 216 public static Jid fromUnescaped(String unescapedJidString) throws XmppStringprepException { 217 String localpart = XmppStringUtils.parseLocalpart(unescapedJidString); 218 // Some as from(String), but we escape the localpart 219 localpart = XmppStringUtils.escapeLocalpart(localpart); 220 221 String domainpart = XmppStringUtils.parseDomain(unescapedJidString); 222 String resource = XmppStringUtils.parseResource(unescapedJidString); 223 try { 224 return from(localpart, domainpart, resource); 225 } catch (XmppStringprepException e) { 226 throw new XmppStringprepException(unescapedJidString, e); 227 } 228 } 229 230 /** 231 * Get a {@link Jid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 232 * 233 * @param cs the input {@link CharSequence} 234 * @return a JID or {@code null} 235 */ 236 public static Jid fromUnescapedOrNull(CharSequence cs) { 237 try { 238 return fromUnescaped(cs); 239 } catch (XmppStringprepException e) { 240 return null; 241 } 242 } 243 244 /** 245 * Like {@link #bareFrom(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 246 * {@link XmppStringprepException}. 247 * 248 * @param cs the character sequence which should be transformed to a {@link BareJid} 249 * @return the {@link BareJid} if no exception occurs 250 * @throws IllegalArgumentException if the given input is not a valid JID 251 * @see #bareFrom(CharSequence) 252 * @since 0.6.2 253 */ 254 public static BareJid bareFromOrThrowUnchecked(CharSequence cs) { 255 try { 256 return bareFrom(cs); 257 } catch (XmppStringprepException e) { 258 throw new IllegalArgumentException(e); 259 } 260 } 261 262 /** 263 * Get a {@link BareJid} representing the given CharSequence. 264 * 265 * @param jid the input CharSequence. 266 * @return a bare JID representing the given CharSequence. 267 * @throws XmppStringprepException if an error occurs. 268 */ 269 public static BareJid bareFrom(CharSequence jid) throws XmppStringprepException { 270 return bareFrom(jid.toString()); 271 } 272 273 /** 274 * Get a {@link BareJid} representing the given String. 275 * 276 * @param jid the input String. 277 * @return a bare JID representing the given String. 278 * @throws XmppStringprepException if an error occurs. 279 */ 280 public static BareJid bareFrom(String jid) throws XmppStringprepException { 281 BareJid bareJid = BAREJID_CACHE.lookup(jid); 282 if (bareJid != null) { 283 return bareJid; 284 } 285 286 String localpart = XmppStringUtils.parseLocalpart(jid); 287 String domainpart = XmppStringUtils.parseDomain(jid); 288 try { 289 if (localpart.length() != 0) { 290 bareJid = new LocalAndDomainpartJid(localpart, domainpart); 291 } else { 292 bareJid = new DomainpartJid(domainpart); 293 } 294 } catch (XmppStringprepException e) { 295 throw new XmppStringprepException(jid, e); 296 } 297 BAREJID_CACHE.put(jid, bareJid); 298 return bareJid; 299 } 300 301 /** 302 * Get a {@link BareJid} constructed from the optionally given {@link Localpart} and {link DomainBareJid}. 303 * 304 * @param localpart a optional localpart. 305 * @param domainBareJid a domain bare JID. 306 * @return a bare JID. 307 */ 308 public static BareJid bareFrom(Localpart localpart, DomainBareJid domainBareJid) { 309 return bareFrom(localpart, domainBareJid.getDomain()); 310 } 311 312 /** 313 * Get a {@link BareJid} constructed from the optionally given {@link Localpart} and {@link Domainpart}. 314 * 315 * @param localpart a optional localpart. 316 * @param domain a domainpart. 317 * @return a bare JID constructed from the given parts. 318 */ 319 public static BareJid bareFrom(Localpart localpart, Domainpart domain) { 320 if (localpart != null) { 321 return new LocalAndDomainpartJid(localpart, domain); 322 } else { 323 return new DomainpartJid(domain); 324 } 325 } 326 327 /** 328 * Get a {@link BareJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 329 * 330 * @param cs the input {@link CharSequence} 331 * @return a JID or {@code null} 332 */ 333 public static BareJid bareFromOrNull(CharSequence cs) { 334 try { 335 return bareFrom(cs); 336 } catch (XmppStringprepException e) { 337 return null; 338 } 339 } 340 341 /** 342 * Like {@link #fullFrom(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 343 * {@link XmppStringprepException}. 344 * 345 * @param cs the character sequence which should be transformed to a {@link FullJid} 346 * @return the {@link FullJid} if no exception occurs 347 * @throws IllegalArgumentException if the given input is not a valid JID 348 * @see #fullFrom(CharSequence) 349 * @since 0.6.2 350 */ 351 public static FullJid fullFromOrThrowUnchecked(CharSequence cs) { 352 try { 353 return fullFrom(cs); 354 } catch (XmppStringprepException e) { 355 throw new IllegalArgumentException(e); 356 } 357 } 358 359 /** 360 * Get a {@link FullJid} representing the given CharSequence. 361 * 362 * @param jid a CharSequence representing a JID. 363 * @return a full JID representing the given CharSequence. 364 * @throws XmppStringprepException if an error occurs. 365 */ 366 public static FullJid fullFrom(CharSequence jid) throws XmppStringprepException { 367 return fullFrom(jid.toString()); 368 } 369 370 /** 371 * Get a {@link FullJid} representing the given String. 372 * 373 * @param jid the JID's String. 374 * @return a full JID representing the input String. 375 * @throws XmppStringprepException if an error occurs. 376 */ 377 public static FullJid fullFrom(String jid) throws XmppStringprepException { 378 FullJid fullJid = FULLJID_CACHE.lookup(jid); 379 if (fullJid != null) { 380 return fullJid; 381 } 382 383 String localpart = XmppStringUtils.parseLocalpart(jid); 384 String domainpart = XmppStringUtils.parseDomain(jid); 385 String resource = XmppStringUtils.parseResource(jid); 386 try { 387 fullJid = fullFrom(localpart, domainpart, resource); 388 } catch (XmppStringprepException e) { 389 throw new XmppStringprepException(jid, e); 390 } 391 FULLJID_CACHE.put(jid, fullJid); 392 return fullJid; 393 } 394 395 /** 396 * Get a {@link FullJid} constructed from the given parts. 397 * 398 * @param localpart a optional localpart. 399 * @param domainpart a domainpart. 400 * @param resource a resourcepart. 401 * @return a full JID. 402 * @throws XmppStringprepException if an error occurs. 403 */ 404 public static FullJid fullFrom(String localpart, String domainpart, String resource) throws XmppStringprepException { 405 FullJid fullJid; 406 try { 407 if (localpart == null || localpart.length() == 0) { 408 fullJid = new DomainAndResourcepartJid(domainpart, resource); 409 } else { 410 fullJid = new LocalDomainAndResourcepartJid(localpart, domainpart, resource); 411 } 412 } catch (XmppStringprepException e) { 413 throw new XmppStringprepException(localpart + '@' + domainpart + '/' + resource, e); 414 } 415 return fullJid; 416 } 417 418 /** 419 * Get a {@link FullJid} constructed from the given parts. 420 * 421 * @param localpart a optional localpart. 422 * @param domainBareJid a domain bare JID. 423 * @param resource a resourcepart 424 * @return a full JID. 425 */ 426 public static FullJid fullFrom(Localpart localpart, DomainBareJid domainBareJid, Resourcepart resource) { 427 return fullFrom(localpart, domainBareJid.getDomain(), resource); 428 } 429 430 /** 431 * Get a {@link FullJid} constructed from the given parts. 432 * 433 * @param localpart the optional localpart. 434 * @param domainpart the domainpart. 435 * @param resource the resourcepart. 436 * @return a full JID. 437 */ 438 public static FullJid fullFrom(Localpart localpart, Domainpart domainpart, Resourcepart resource) { 439 return fullFrom(entityBareFrom(localpart, domainpart), resource); 440 } 441 442 /** 443 * Get a {@link FullJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 444 * 445 * @param cs the input {@link CharSequence} 446 * @return a JID or {@code null} 447 */ 448 public static FullJid fullFromOrNull(CharSequence cs) { 449 try { 450 return fullFrom(cs); 451 } catch (XmppStringprepException e) { 452 return null; 453 } 454 } 455 456 /** 457 * Like {@link #entityFrom(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 458 * {@link XmppStringprepException}. 459 * 460 * @param cs the character sequence which should be transformed to a {@link EntityJid} 461 * @return the {@link EntityJid} if no exception occurs 462 * @throws IllegalArgumentException if the given input is not a valid JID 463 * @see #entityFrom(CharSequence) 464 * @since 0.6.2 465 */ 466 public static EntityJid entityFromOrThrowUnchecked(CharSequence cs) { 467 try { 468 return entityFrom(cs); 469 } catch (XmppStringprepException e) { 470 throw new IllegalArgumentException(e); 471 } 472 } 473 474 /** 475 * Get a {@link EntityFullJid} constructed from a {@link EntityBareJid} and a {@link Resourcepart}. 476 * 477 * @param bareJid a entity bare JID. 478 * @param resource a resourcepart. 479 * @return a full JID. 480 */ 481 public static EntityFullJid fullFrom(EntityBareJid bareJid, Resourcepart resource) { 482 return new LocalDomainAndResourcepartJid(bareJid, resource); 483 } 484 485 /** 486 * Get a {@link EntityJid} representing the given String. 487 * 488 * @param jid the JID's string. 489 * @return an entity JID representing the given String. 490 * @throws XmppStringprepException if an error occurs. 491 */ 492 public static EntityJid entityFrom(CharSequence jid) throws XmppStringprepException { 493 return entityFrom(jid.toString()); 494 } 495 496 /** 497 * Get a {@link EntityJid} representing the given String. 498 * 499 * @param jidString the JID's string. 500 * @return an entity JID representing the given String. 501 * @throws XmppStringprepException if an error occurs. 502 */ 503 public static EntityJid entityFrom(String jidString) throws XmppStringprepException { 504 return entityFrom(jidString, false); 505 } 506 507 /** 508 * Like {@link #entityFromUnescaped(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 509 * {@link XmppStringprepException}. 510 * 511 * @param cs the character sequence which should be transformed to a {@link EntityJid} 512 * @return the {@link EntityJid} if no exception occurs 513 * @throws IllegalArgumentException if the given input is not a valid JID 514 * @see #entityFromUnescaped(CharSequence) 515 * @since 0.6.2 516 */ 517 public static EntityJid entityFromUnescapedOrThrowUnchecked(CharSequence cs) { 518 try { 519 return entityFromUnescaped(cs); 520 } catch (XmppStringprepException e) { 521 throw new IllegalArgumentException(e); 522 } 523 } 524 525 /** 526 * Get a {@link EntityJid} representing the given String. 527 * 528 * @param jid the JID. 529 * @return an entity JID representing the given input.. 530 * @throws XmppStringprepException if an error occurs. 531 */ 532 public static EntityJid entityFromUnescaped(CharSequence jid) throws XmppStringprepException { 533 return entityFromUnescaped(jid.toString()); 534 } 535 536 /** 537 * Get a {@link EntityJid} representing the given String. 538 * 539 * @param jidString the JID's string. 540 * @return an entity JID representing the given String. 541 * @throws XmppStringprepException if an error occurs. 542 */ 543 public static EntityJid entityFromUnescaped(String jidString) throws XmppStringprepException { 544 return entityFrom(jidString, true); 545 } 546 547 /** 548 * Get a {@link EntityJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 549 * 550 * @param cs the input {@link CharSequence} 551 * @return a JID or {@code null} 552 */ 553 public static EntityJid entityFromUnesacpedOrNull(CharSequence cs) { 554 try { 555 return entityFromUnescaped(cs.toString()); 556 } catch (XmppStringprepException e) { 557 return null; 558 } 559 } 560 561 /** 562 * Get a {@link EntityJid} representing the given String. 563 * 564 * @param jidString the JID's string. 565 * @param unescaped if the JID string is unescaped. 566 * @return an entity JID representing the given String. 567 * @throws XmppStringprepException if an error occurs. 568 */ 569 private static EntityJid entityFrom(String jidString, boolean unescaped) throws XmppStringprepException { 570 EntityJid entityJid = ENTITYJID_CACHE.lookup(jidString); 571 if (entityJid != null) { 572 return entityJid; 573 } 574 String localpartString = XmppStringUtils.parseLocalpart(jidString); 575 if (localpartString.length() == 0) { 576 throw new XmppStringprepException("Does not contain a localpart", jidString); 577 } 578 Localpart localpart; 579 try { 580 if (unescaped) { 581 localpart = Localpart.fromUnescaped(localpartString); 582 } else { 583 localpart = Localpart.from(localpartString); 584 } 585 } catch (XmppStringprepException e) { 586 throw new XmppStringprepException(jidString, e); 587 } 588 589 String domainpartString = XmppStringUtils.parseDomain(jidString); 590 Domainpart domainpart; 591 try { 592 domainpart = Domainpart.from(domainpartString); 593 } catch (XmppStringprepException e) { 594 throw new XmppStringprepException(jidString, e); 595 } 596 597 String resourceString = XmppStringUtils.parseResource(jidString); 598 if (resourceString.length() > 0) { 599 Resourcepart resourcepart; 600 try { 601 resourcepart = Resourcepart.from(resourceString); 602 } catch (XmppStringprepException e) { 603 throw new XmppStringprepException(jidString, e); 604 } 605 entityJid = entityFullFrom(localpart, domainpart, resourcepart); 606 } else { 607 entityJid = entityBareFrom(localpart, domainpart); 608 } 609 610 ENTITYJID_CACHE.put(jidString, entityJid); 611 return entityJid; 612 } 613 614 /** 615 * Get a {@link EntityJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 616 * 617 * @param cs the input {@link CharSequence} 618 * @return a JID or {@code null} 619 */ 620 public static EntityJid entityFromOrNull(CharSequence cs) { 621 try { 622 return entityFrom(cs); 623 } catch (XmppStringprepException e) { 624 return null; 625 } 626 } 627 628 /** 629 * Like {@link #entityBareFrom(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 630 * {@link XmppStringprepException}. 631 * 632 * @param cs the character sequence which should be transformed to a {@link EntityBareJid} 633 * @return the {@link EntityBareJid} if no exception occurs 634 * @throws IllegalArgumentException if the given input is not a valid JID 635 * @see #entityBareFrom(CharSequence) 636 * @since 0.6.2 637 */ 638 public static EntityBareJid entityBareFromOrThrowUnchecked(CharSequence cs) { 639 try { 640 return entityBareFrom(cs); 641 } catch (XmppStringprepException e) { 642 throw new IllegalArgumentException(e); 643 } 644 } 645 646 /** 647 * Get a {@link EntityBareJid} representing the given CharSequence. 648 * 649 * @param jid the input CharSequence. 650 * @return a bare JID representing the given CharSequence. 651 * @throws XmppStringprepException if an error occurs. 652 */ 653 public static EntityBareJid entityBareFrom(CharSequence jid) throws XmppStringprepException { 654 return entityBareFrom(jid.toString()); 655 } 656 657 /** 658 * Get a {@link EntityBareJid} representing the given String. 659 * 660 * @param jid the input String. 661 * @return a bare JID representing the given String. 662 * @throws XmppStringprepException if an error occurs. 663 */ 664 public static EntityBareJid entityBareFrom(String jid) throws XmppStringprepException { 665 EntityBareJid bareJid = ENTITY_BAREJID_CACHE.lookup(jid); 666 if (bareJid != null) { 667 return bareJid; 668 } 669 670 String localpart = XmppStringUtils.parseLocalpart(jid); 671 String domainpart = XmppStringUtils.parseDomain(jid); 672 try { 673 bareJid = new LocalAndDomainpartJid(localpart, domainpart); 674 } catch (XmppStringprepException e) { 675 throw new XmppStringprepException(jid, e); 676 } 677 ENTITY_BAREJID_CACHE.put(jid, bareJid); 678 return bareJid; 679 } 680 681 /** 682 * Like {@link #entityBareFromUnescaped(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 683 * {@link XmppStringprepException}. 684 * 685 * @param cs the character sequence which should be transformed to a {@link EntityBareJid} 686 * @return the {@link EntityBareJid} if no exception occurs 687 * @throws IllegalArgumentException if the given input is not a valid JID 688 * @see #entityBareFromUnescaped(CharSequence) 689 * @since 0.6.2 690 */ 691 public static EntityBareJid entityBareFromUnescapedOrThrowUnchecked(CharSequence cs) { 692 try { 693 return entityBareFromUnescaped(cs); 694 } catch (XmppStringprepException e) { 695 throw new IllegalArgumentException(e); 696 } 697 } 698 699 /** 700 * Get a {@link EntityBareJid} representing the given unescaped CharSequence. 701 * 702 * @param unescapedJid the input CharSequence. 703 * @return a bare JID representing the given CharSequence. 704 * @throws XmppStringprepException if an error occurs. 705 */ 706 public static EntityBareJid entityBareFromUnescaped(CharSequence unescapedJid) throws XmppStringprepException { 707 return entityBareFromUnescaped(unescapedJid.toString()); 708 } 709 710 /** 711 * Get a {@link EntityBareJid} representing the given unescaped String. 712 * 713 * @param unescapedJidString the input String. 714 * @return a bare JID representing the given String. 715 * @throws XmppStringprepException if an error occurs. 716 */ 717 public static EntityBareJid entityBareFromUnescaped(String unescapedJidString) throws XmppStringprepException { 718 EntityBareJid bareJid = ENTITY_BAREJID_CACHE.lookup(unescapedJidString); 719 if (bareJid != null) { 720 return bareJid; 721 } 722 723 String localpart = XmppStringUtils.parseLocalpart(unescapedJidString); 724 // Some as from(String), but we escape the localpart 725 localpart = XmppStringUtils.escapeLocalpart(localpart); 726 727 String domainpart = XmppStringUtils.parseDomain(unescapedJidString); 728 try { 729 bareJid = new LocalAndDomainpartJid(localpart, domainpart); 730 } catch (XmppStringprepException e) { 731 throw new XmppStringprepException(unescapedJidString, e); 732 } 733 ENTITY_BAREJID_CACHE.put(unescapedJidString, bareJid); 734 return bareJid; 735 } 736 737 /** 738 * Get a {@link EntityBareJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 739 * 740 * @param cs the input {@link CharSequence} 741 * @return a JID or {@code null} 742 */ 743 public static EntityBareJid entityBareFromUnescapedOrNull(CharSequence cs) { 744 try { 745 return entityBareFromUnescaped(cs.toString()); 746 } catch (XmppStringprepException e) { 747 return null; 748 } 749 } 750 751 /** 752 * Get a {@link EntityBareJid} constructed from the given {@link Localpart} and {link DomainBareJid}. 753 * 754 * @param localpart a localpart. 755 * @param domainBareJid a domain bare JID. 756 * @return a bare JID. 757 */ 758 public static EntityBareJid entityBareFrom(Localpart localpart, DomainBareJid domainBareJid) { 759 return entityBareFrom(localpart, domainBareJid.getDomain()); 760 } 761 762 /** 763 * Get a {@link EntityBareJid} constructed from the given {@link Localpart} and {@link Domainpart}. 764 * 765 * @param localpart a localpart. 766 * @param domain a domainpart. 767 * @return a bare JID constructed from the given parts. 768 */ 769 public static EntityBareJid entityBareFrom(Localpart localpart, Domainpart domain) { 770 return new LocalAndDomainpartJid(localpart, domain); 771 } 772 773 /** 774 * Get a {@link EntityBareJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 775 * 776 * @param cs the input {@link CharSequence} 777 * @return a JID or {@code null} 778 */ 779 public static EntityBareJid entityBareFromOrNull(CharSequence cs) { 780 try { 781 return entityBareFrom(cs); 782 } catch (XmppStringprepException e) { 783 return null; 784 } 785 } 786 787 /** 788 * Like {@link #entityFullFrom(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 789 * {@link XmppStringprepException}. 790 * 791 * @param cs the character sequence which should be transformed to a {@link EntityFullJid} 792 * @return the {@link EntityFullJid} if no exception occurs 793 * @throws IllegalArgumentException if the given input is not a valid JID 794 * @see #entityFullFrom(CharSequence) 795 * @since 0.6.2 796 */ 797 public static EntityFullJid entityFullFromOrThrowUnchecked(CharSequence cs) { 798 try { 799 return entityFullFrom(cs); 800 } catch (XmppStringprepException e) { 801 throw new IllegalArgumentException(e); 802 } 803 } 804 805 /** 806 * Get a {@link EntityFullJid} representing the given CharSequence. 807 * 808 * @param jid a CharSequence representing a JID. 809 * @return a full JID representing the given CharSequence. 810 * @throws XmppStringprepException if an error occurs. 811 */ 812 public static EntityFullJid entityFullFrom(CharSequence jid) throws XmppStringprepException { 813 return entityFullFrom(jid.toString()); 814 } 815 816 /** 817 * Get a {@link EntityFullJid} representing the given String. 818 * 819 * @param jid the JID's String. 820 * @return a full JID representing the input String. 821 * @throws XmppStringprepException if an error occurs. 822 */ 823 public static EntityFullJid entityFullFrom(String jid) throws XmppStringprepException { 824 EntityFullJid fullJid = ENTITY_FULLJID_CACHE.lookup(jid); 825 if (fullJid != null) { 826 return fullJid; 827 } 828 829 String localpart = XmppStringUtils.parseLocalpart(jid); 830 String domainpart = XmppStringUtils.parseDomain(jid); 831 String resource = XmppStringUtils.parseResource(jid); 832 try { 833 fullJid = entityFullFrom(localpart, domainpart, resource); 834 } catch (XmppStringprepException e) { 835 throw new XmppStringprepException(jid, e); 836 } 837 ENTITY_FULLJID_CACHE.put(jid, fullJid); 838 return fullJid; 839 } 840 841 /** 842 * Get a {@link EntityFullJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 843 * 844 * @param cs the input {@link CharSequence} 845 * @return a JID or {@code null} 846 */ 847 public static EntityFullJid entityFullFromOrNull(CharSequence cs) { 848 try { 849 return entityFullFrom(cs); 850 } catch (XmppStringprepException e) { 851 return null; 852 } 853 } 854 855 /** 856 * Like {@link #entityFullFromUnescaped(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 857 * {@link XmppStringprepException}. 858 * 859 * @param cs the character sequence which should be transformed to a {@link EntityFullJid} 860 * @return the {@link EntityFullJid} if no exception occurs 861 * @throws IllegalArgumentException if the given input is not a valid JID 862 * @see #entityFullFromUnescaped(CharSequence) 863 * @since 0.6.2 864 */ 865 public static EntityFullJid entityFullFromUnescapedOrThrowUnchecked(CharSequence cs) { 866 try { 867 return entityFullFromUnescaped(cs); 868 } catch (XmppStringprepException e) { 869 throw new IllegalArgumentException(e); 870 } 871 } 872 873 /** 874 * Get a {@link EntityFullJid} representing the given unescaped CharSequence. 875 * 876 * @param unescapedJid a CharSequence representing a JID. 877 * @return a full JID representing the given CharSequence. 878 * @throws XmppStringprepException if an error occurs. 879 */ 880 public static EntityFullJid entityFullFromUnescaped(CharSequence unescapedJid) throws XmppStringprepException { 881 return entityFullFromUnescaped(unescapedJid.toString()); 882 } 883 884 /** 885 * Get a {@link EntityFullJid} representing the given unescaped String. 886 * 887 * @param unescapedJidString the JID's String. 888 * @return a full JID representing the input String. 889 * @throws XmppStringprepException if an error occurs. 890 */ 891 public static EntityFullJid entityFullFromUnescaped(String unescapedJidString) throws XmppStringprepException { 892 EntityFullJid fullJid = ENTITY_FULLJID_CACHE.lookup(unescapedJidString); 893 if (fullJid != null) { 894 return fullJid; 895 } 896 897 String localpart = XmppStringUtils.parseLocalpart(unescapedJidString); 898 // Some as from(String), but we escape the localpart 899 localpart = XmppStringUtils.escapeLocalpart(localpart); 900 901 String domainpart = XmppStringUtils.parseDomain(unescapedJidString); 902 String resource = XmppStringUtils.parseResource(unescapedJidString); 903 try { 904 fullJid = new LocalDomainAndResourcepartJid(localpart, domainpart, resource); 905 } catch (XmppStringprepException e) { 906 throw new XmppStringprepException(unescapedJidString, e); 907 } 908 909 ENTITY_FULLJID_CACHE.put(unescapedJidString, fullJid); 910 return fullJid; 911 } 912 913 /** 914 * Get a {@link EntityFullJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 915 * 916 * @param cs the input {@link CharSequence} 917 * @return a JID or {@code null} 918 */ 919 public static EntityFullJid entityFullFromUnescapedOrNull(CharSequence cs) { 920 try { 921 return entityFullFromUnescaped(cs.toString()); 922 } catch (XmppStringprepException e) { 923 return null; 924 } 925 } 926 927 /** 928 * Get a {@link EntityFullJid} constructed from the given parts. 929 * 930 * @param localpart a localpart. 931 * @param domainpart a domainpart. 932 * @param resource a resourcepart. 933 * @return a full JID. 934 * @throws XmppStringprepException if an error occurs. 935 */ 936 public static EntityFullJid entityFullFrom(String localpart, String domainpart, String resource) throws XmppStringprepException { 937 EntityFullJid fullJid; 938 try { 939 fullJid = new LocalDomainAndResourcepartJid(localpart, domainpart, resource); 940 } catch (XmppStringprepException e) { 941 throw new XmppStringprepException(localpart + '@' + domainpart + '/' + resource, e); 942 } 943 return fullJid; 944 } 945 946 /** 947 * Get a {@link EntityFullJid} constructed from the given parts. 948 * 949 * @param localpart a localpart. 950 * @param domainBareJid a domain bare JID.. 951 * @param resource a resourcepart 952 * @return a full JID. 953 */ 954 public static EntityFullJid entityFullFrom(Localpart localpart, DomainBareJid domainBareJid, Resourcepart resource) { 955 return entityFullFrom(localpart, domainBareJid.getDomain(), resource); 956 } 957 958 /** 959 * Get a {@link EntityFullJid} constructed from the given parts. 960 * 961 * @param localpart the localpart. 962 * @param domainpart the domainpart. 963 * @param resource the resourcepart. 964 * @return a full JID. 965 */ 966 public static EntityFullJid entityFullFrom(Localpart localpart, Domainpart domainpart, Resourcepart resource) { 967 return entityFullFrom(entityBareFrom(localpart, domainpart), resource); 968 } 969 970 /** 971 * Get a {@link EntityFullJid} constructed from a {@link EntityBareJid} and a {@link Resourcepart}. 972 * 973 * @param bareJid a bare JID. 974 * @param resource a resourcepart. 975 * @return a full JID. 976 */ 977 public static EntityFullJid entityFullFrom(EntityBareJid bareJid, Resourcepart resource) { 978 return new LocalDomainAndResourcepartJid(bareJid, resource); 979 } 980 981 /** 982 * Deprecated. 983 * 984 * @param jid the JID. 985 * @return a DopmainBareJid 986 * @throws XmppStringprepException if an error happens. 987 * @deprecated use {@link #domainBareFrom(String)} instead 988 */ 989 @Deprecated 990 public static DomainBareJid serverBareFrom(String jid) throws XmppStringprepException { 991 return domainBareFrom(jid); 992 } 993 994 /** 995 * Like {@link #domainBareFrom(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 996 * {@link XmppStringprepException}. 997 * 998 * @param cs the character sequence which should be transformed to a {@link EntityFullJid} 999 * @return the {@link EntityFullJid} if no exception occurs 1000 * @see #from(String) 1001 * @since 0.6.2 1002 */ 1003 public static DomainBareJid domainBareFromOrThrowUnchecked(CharSequence cs) { 1004 try { 1005 return domainBareFrom(cs); 1006 } catch (XmppStringprepException e) { 1007 throw new IllegalArgumentException(e); 1008 } 1009 } 1010 1011 /** 1012 * Get a domain bare JID. 1013 * 1014 * @param jid the JID CharSequence. 1015 * @return a domain bare JID. 1016 * @throws XmppStringprepException if an error occurs. 1017 */ 1018 public static DomainBareJid domainBareFrom(CharSequence jid) throws XmppStringprepException { 1019 return domainBareFrom(jid.toString()); 1020 } 1021 1022 /** 1023 * Get a domain bare JID. 1024 * 1025 * @param jid the JID String. 1026 * @return a domain bare JID. 1027 * @throws XmppStringprepException if an error occurs. 1028 */ 1029 public static DomainBareJid domainBareFrom(String jid) throws XmppStringprepException { 1030 DomainBareJid domainJid = DOMAINJID_CACHE.lookup(jid); 1031 if (domainJid != null) { 1032 return domainJid; 1033 } 1034 1035 String domain = XmppStringUtils.parseDomain(jid); 1036 try { 1037 domainJid = new DomainpartJid(domain); 1038 } catch (XmppStringprepException e) { 1039 throw new XmppStringprepException(jid, e); 1040 } 1041 DOMAINJID_CACHE.put(jid, domainJid); 1042 return domainJid; 1043 } 1044 1045 /** 1046 * Get a {@link DomainBareJid} consisting of the given {@link Domainpart}. 1047 * 1048 * @param domainpart the domainpart. 1049 * @return a domain bare JID. 1050 */ 1051 public static DomainBareJid domainBareFrom(Domainpart domainpart) { 1052 return new DomainpartJid(domainpart); 1053 } 1054 1055 /** 1056 * Get a {@link DomainBareJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 1057 * 1058 * @param cs the input {@link CharSequence} 1059 * @return a JID or {@code null} 1060 */ 1061 public static DomainBareJid domainBareFromOrNull(CharSequence cs) { 1062 try { 1063 return domainBareFrom(cs); 1064 } catch (XmppStringprepException e) { 1065 return null; 1066 } 1067 } 1068 1069 /** 1070 * Deprecated. 1071 * 1072 * @param jid the JID. 1073 * @return a DomainFullJid 1074 * @throws XmppStringprepException if an error happens. 1075 * @deprecated use {@link #domainFullFrom(String)} instead 1076 */ 1077 @Deprecated 1078 public static DomainFullJid serverFullFrom(String jid) throws XmppStringprepException { 1079 return donmainFullFrom(jid); 1080 } 1081 1082 /** 1083 * Get a domain full JID from the given String. 1084 * 1085 * @param jid the JID. 1086 * @return a DomainFullJid. 1087 * @throws XmppStringprepException if an error happens. 1088 * @deprecated use {@link #domainFullFrom(String)} instead. 1089 */ 1090 @Deprecated 1091 public static DomainFullJid donmainFullFrom(String jid) throws XmppStringprepException { 1092 return domainFullFrom(jid); 1093 } 1094 1095 /** 1096 * Like {@link #domainFullFrom(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 1097 * {@link XmppStringprepException}. 1098 * 1099 * @param cs the character sequence which should be transformed to a {@link DomainFullJid} 1100 * @return the {@link DomainFullJid} if no exception occurs 1101 * @throws IllegalArgumentException if the given input is not a valid JID 1102 * @see #domainFullFrom(CharSequence) 1103 * @since 0.6.2 1104 */ 1105 public static DomainFullJid domainFullFromOrThrowUnchecked(CharSequence cs) { 1106 try { 1107 return domainFullFrom(cs); 1108 } catch (XmppStringprepException e) { 1109 throw new IllegalArgumentException(e); 1110 } 1111 } 1112 1113 /** 1114 * Get a domain full JID from the given CharSequence. 1115 * 1116 * @param jid the JID. 1117 * @return a domain full JID. 1118 * @throws XmppStringprepException if an error happens. 1119 */ 1120 public static DomainFullJid domainFullFrom(CharSequence jid) throws XmppStringprepException { 1121 return domainFullFrom(jid.toString()); 1122 } 1123 1124 /** 1125 * Get a domain full JID from the given String. 1126 * 1127 * @param jid the JID. 1128 * @return a DomainFullJid. 1129 * @throws XmppStringprepException if an error happens. 1130 */ 1131 public static DomainFullJid domainFullFrom(String jid) throws XmppStringprepException { 1132 DomainFullJid domainResourceJid = DOMAINRESOURCEJID_CACHE.lookup(jid); 1133 if (domainResourceJid != null) { 1134 return domainResourceJid; 1135 } 1136 1137 String domain = XmppStringUtils.parseDomain(jid); 1138 String resource = XmppStringUtils.parseResource(jid); 1139 try { 1140 domainResourceJid = new DomainAndResourcepartJid(domain, resource); 1141 } catch (XmppStringprepException e) { 1142 throw new XmppStringprepException(jid, e); 1143 } 1144 DOMAINRESOURCEJID_CACHE.put(jid, domainResourceJid); 1145 return domainResourceJid; 1146 } 1147 1148 /** 1149 * Get a domain full JID. 1150 * 1151 * @param domainpart the domainpart. 1152 * @param resource the resourcepart. 1153 * @return a domain full JID. 1154 */ 1155 public static DomainFullJid domainFullFrom(Domainpart domainpart, Resourcepart resource) { 1156 return domainFullFrom(domainBareFrom(domainpart), resource); 1157 } 1158 1159 /** 1160 * Get a domain full JID. 1161 * 1162 * @param domainBareJid a domain bare JID. 1163 * @param resource a resourcepart. 1164 * @return a domain full JID. 1165 */ 1166 public static DomainFullJid domainFullFrom(DomainBareJid domainBareJid, Resourcepart resource) { 1167 return new DomainAndResourcepartJid(domainBareJid, resource); 1168 } 1169 1170 /** 1171 * Get a {@link DomainFullJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 1172 * 1173 * @param cs the input {@link CharSequence} 1174 * @return a JID or {@code null} 1175 */ 1176 public static DomainFullJid domainFullFromOrNull(CharSequence cs) { 1177 try { 1178 return domainFullFrom(cs); 1179 } catch (XmppStringprepException e) { 1180 return null; 1181 } 1182 } 1183}