001/** 002 * 003 * Copyright © 2014-2022 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 java.io.UnsupportedEncodingException; 020import java.net.URLDecoder; 021 022import org.jxmpp.JxmppContext; 023import org.jxmpp.jid.BareJid; 024import org.jxmpp.jid.EntityBareJid; 025import org.jxmpp.jid.DomainBareJid; 026import org.jxmpp.jid.DomainFullJid; 027import org.jxmpp.jid.EntityFullJid; 028import org.jxmpp.jid.EntityJid; 029import org.jxmpp.jid.FullJid; 030import org.jxmpp.jid.Jid; 031import org.jxmpp.jid.parts.Domainpart; 032import org.jxmpp.jid.parts.Localpart; 033import org.jxmpp.jid.parts.Resourcepart; 034import org.jxmpp.stringprep.XmppStringprep; 035import org.jxmpp.stringprep.XmppStringprepException; 036import org.jxmpp.util.cache.Cache; 037import org.jxmpp.util.cache.LruCache; 038import org.jxmpp.util.XmppStringUtils; 039 040/** 041 * API to create JIDs (XMPP addresses) from Strings and CharSequences. 042 * <p> 043 * If the input was user generated, e.g. captured from some sort of user 044 * interface, {@link #fromUnescaped(String)} should be used instead. This allows 045 * the user to enter unescaped JID values. You can use 046 * {@link org.jxmpp.jid.util.JidUtil#isValidEntityBareJid(CharSequence)} to 047 * query, e.g. while the user it entering it, if a given CharSequence is a valid 048 * bare JID. 049 * </p> 050 * <p> 051 * JIDs created from input received from an XMPP source should use 052 * {@link #from(String)}. 053 * </p> 054 * <p> 055 * JidCreate uses caches for efficient Jid construction, But it's not guaranteed 056 * that the same String or CharSequence will yield the same Jid instance. 057 * </p> 058 * 059 * @see Jid 060 */ 061public class JidCreate { 062 063 private static class JidStringAndStringprep { 064 private final String jidString; 065 private final XmppStringprep stringprep; 066 067 private JidStringAndStringprep(String jidString, JxmppContext context) { 068 this(jidString, context.xmppStringprep); 069 } 070 071 private JidStringAndStringprep(String jidString, XmppStringprep stringprep) { 072 this.jidString = jidString; 073 this.stringprep = stringprep; 074 } 075 076 @Override 077 public boolean equals(Object other) { 078 if (!(other instanceof JidStringAndStringprep)) 079 return false; 080 081 JidStringAndStringprep otherJidStringAndStringprep = (JidStringAndStringprep) other; 082 return jidString.equals(otherJidStringAndStringprep.jidString) && stringprep.equals(otherJidStringAndStringprep.stringprep); 083 } 084 085 private transient Integer hashCode; 086 087 @Override 088 public int hashCode() { 089 if (hashCode == null) { 090 int result = 17; 091 result = 31 * result + jidString.hashCode(); 092 result = 31 * result + stringprep.hashCode(); 093 hashCode = result; 094 } 095 return hashCode; 096 } 097 } 098 099 private static final Cache<JidStringAndStringprep, Jid> JID_CACHE = new LruCache<>(100); 100 private static final Cache<JidStringAndStringprep, BareJid> BAREJID_CACHE = new LruCache<>(100); 101 private static final Cache<JidStringAndStringprep, EntityJid> ENTITYJID_CACHE = new LruCache<>(100); 102 private static final Cache<JidStringAndStringprep, FullJid> FULLJID_CACHE = new LruCache<>(100); 103 private static final Cache<JidStringAndStringprep, EntityBareJid> ENTITY_BAREJID_CACHE = new LruCache<>(100); 104 private static final Cache<JidStringAndStringprep, EntityFullJid> ENTITY_FULLJID_CACHE = new LruCache<>(100); 105 private static final Cache<JidStringAndStringprep, DomainBareJid> DOMAINJID_CACHE = new LruCache<>(100); 106 private static final Cache<JidStringAndStringprep, DomainFullJid> DOMAINRESOURCEJID_CACHE = new LruCache<>(100); 107 108 /** 109 * Get a {@link Jid} from the given parts. 110 * <p> 111 * Only the domainpart is required. 112 * </p> 113 * 114 * @param localpart a optional localpart. 115 * @param domainpart a required domainpart. 116 * @param resource a optional resourcepart. 117 * @return a JID which consists of the given parts. 118 * @throws XmppStringprepException if an error occurs. 119 */ 120 public static Jid from(CharSequence localpart, CharSequence domainpart, CharSequence resource) 121 throws XmppStringprepException { 122 return from(localpart.toString(), domainpart.toString(), resource.toString()); 123 } 124 125 /** 126 * Get a {@link Jid} from the given parts. 127 * <p> 128 * Only the domainpart is required. 129 * </p> 130 * 131 * @param localpart a optional localpart. 132 * @param domainpart a required domainpart. 133 * @param resource a optional resourcepart. 134 * @return a JID which consists of the given parts. 135 * @throws XmppStringprepException if an error occurs. 136 */ 137 public static Jid from(String localpart, String domainpart, String resource) throws XmppStringprepException { 138 return from(localpart, domainpart, resource, JxmppContext.getDefaultContext()); 139 } 140 141 /** 142 * Get a {@link Jid} from the given parts. 143 * <p> 144 * Only the domainpart is required. 145 * </p> 146 * 147 * @param localpart a optional localpart. 148 * @param domainpart a required domainpart. 149 * @param resource a optional resourcepart. 150 * @param context the JXMPP context. 151 * @return a JID which consists of the given parts. 152 * @throws XmppStringprepException if an error occurs. 153 */ 154 public static Jid from(String localpart, String domainpart, String resource, JxmppContext context) throws XmppStringprepException { 155 String jid = XmppStringUtils.completeJidFrom(localpart, domainpart, resource); 156 return from(localpart, domainpart, resource, jid, context); 157 } 158 159 /** 160 * Get a {@link Jid} from the given parts. 161 162 * 163 * @param localpart a optional localpart. 164 * @param domainpart a required domainpart. 165 * @param resource a optional resourcepart. 166 * @param jidString the raw String of the as parsed. 167 * @param context the JXMPP context. 168 * @return a JID which consists of the given parts. 169 * @throws XmppStringprepException if an error occurs. 170 */ 171 private static Jid from(String localpart, String domainpart, String resource, String jidString, JxmppContext context) throws XmppStringprepException { 172 // Every JID must come with an domainpart. 173 if (domainpart.isEmpty()) { 174 throw XmppStringprepException.MissingDomainpart.from(localpart, resource); 175 } 176 177 // The provided jidString must be equal to the assembled parts. 178 assert jidString.equals(XmppStringUtils.completeJidFrom(localpart, domainpart, resource)); 179 180 Jid jid; 181 182 JidStringAndStringprep jidStringAndStringprep = null; 183 if (context.isCachingEnabled()) { 184 jidStringAndStringprep = new JidStringAndStringprep(jidString, context); 185 } 186 if (jidStringAndStringprep != null) { 187 jid = JID_CACHE.lookup(jidStringAndStringprep); 188 if (jid != null) { 189 return jid; 190 } 191 } 192 193 jid = null; 194 if (localpart != null && resource != null) { 195 jid = new LocalDomainAndResourcepartJid(localpart, domainpart, resource, context); 196 } else if (localpart != null && resource == null) { 197 jid = new LocalAndDomainpartJid(localpart, domainpart, context); 198 } else if (localpart == null && resource == null) { 199 jid = new DomainpartJid(domainpart, context); 200 } else if (localpart == null && resource != null) { 201 jid = new DomainAndResourcepartJid(domainpart, resource, context); 202 } 203 assert jid != null; 204 205 if (jidStringAndStringprep != null) { 206 JID_CACHE.put(jidStringAndStringprep, jid); 207 } 208 return jid; 209 } 210 211 /** 212 * Like {@link #from(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 213 * {@link XmppStringprepException}. 214 * 215 * @param cs the character sequence which should be transformed to a {@link Jid} 216 * @return the {@link Jid} if no exception occurs 217 * @throws IllegalArgumentException if the given input is not a valid JID 218 * @see #from(String) 219 * @since 0.6.2 220 */ 221 public static Jid fromOrThrowUnchecked(CharSequence cs) { 222 try { 223 return from(cs); 224 } catch (XmppStringprepException e) { 225 throw new IllegalArgumentException(e); 226 } 227 } 228 229 /** 230 * Get a {@link Jid} from a CharSequence. 231 * 232 * @param jid the input CharSequence. 233 * @return the Jid represented by the input CharSequence. 234 * @throws XmppStringprepException if an error occurs. 235 * @see #from(String) 236 */ 237 public static Jid from(CharSequence jid) throws XmppStringprepException { 238 return from(jid.toString()); 239 } 240 241 /** 242 * Get a {@link Jid} from the given String. 243 * 244 * @param jidString the input String. 245 * @return the Jid represented by the input String. 246 * @throws XmppStringprepException if an error occurs. 247 * @see #from(CharSequence) 248 */ 249 public static Jid from(String jidString) throws XmppStringprepException { 250 return from(jidString, JxmppContext.getDefaultContext()); 251 } 252 253 /** 254 * Get a {@link Jid} from the given String. 255 * 256 * @param jidString the input String. 257 * @param context the JXMPP context. 258 * @return the Jid represented by the input String. 259 * @throws XmppStringprepException if an error occurs. 260 * @see #from(CharSequence) 261 */ 262 public static Jid from(String jidString, JxmppContext context) throws XmppStringprepException { 263 String localpart = XmppStringUtils.parseLocalpart(jidString); 264 String domainpart = XmppStringUtils.parseDomain(jidString); 265 String resource = XmppStringUtils.parseResource(jidString); 266 try { 267 return from(localpart, domainpart, resource, jidString, context); 268 } catch (XmppStringprepException e) { 269 throw new XmppStringprepException(jidString, e); 270 } 271 } 272 273 /** 274 * Get a {@link Jid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 275 * 276 * @param cs the input {@link CharSequence} 277 * @return a JID or {@code null} 278 */ 279 public static Jid fromOrNull(CharSequence cs) { 280 try { 281 return from(cs); 282 } catch (XmppStringprepException e) { 283 return null; 284 } 285 } 286 287 /** 288 * Like {@link #fromUnescaped(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 289 * {@link XmppStringprepException}. 290 * 291 * @param cs the character sequence which should be transformed to a {@link Jid} 292 * @return the {@link Jid} if no exception occurs 293 * @throws IllegalArgumentException if the given input is not a valid JID 294 * @see #fromUnescaped(CharSequence) 295 * @since 0.6.2 296 */ 297 public static Jid fromUnescapedOrThrowUnchecked(CharSequence cs) { 298 try { 299 return fromUnescaped(cs); 300 } catch (XmppStringprepException e) { 301 throw new IllegalArgumentException(e); 302 } 303 } 304 305 /** 306 * Get a {@link Jid} from the given unescaped CharSequence. 307 * 308 * @param unescapedJid an unescaped CharSequence representing a JID. 309 * @return a JID. 310 * @throws XmppStringprepException if an error occurs. 311 */ 312 public static Jid fromUnescaped(CharSequence unescapedJid) throws XmppStringprepException { 313 return fromUnescaped(unescapedJid.toString()); 314 } 315 316 /** 317 * Get a {@link Jid} from the given unescaped String. 318 * 319 * @param unescapedJidString a unescaped String representing a JID. 320 * @return a JID. 321 * @throws XmppStringprepException if an error occurs. 322 */ 323 public static Jid fromUnescaped(String unescapedJidString) throws XmppStringprepException { 324 String localpart = XmppStringUtils.parseLocalpart(unescapedJidString); 325 // Some as from(String), but we escape the localpart 326 localpart = XmppStringUtils.escapeLocalpart(localpart); 327 328 String domainpart = XmppStringUtils.parseDomain(unescapedJidString); 329 String resource = XmppStringUtils.parseResource(unescapedJidString); 330 try { 331 return from(localpart, domainpart, resource); 332 } catch (XmppStringprepException e) { 333 throw new XmppStringprepException(unescapedJidString, e); 334 } 335 } 336 337 /** 338 * Get a {@link Jid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 339 * 340 * @param cs the input {@link CharSequence} 341 * @return a JID or {@code null} 342 */ 343 public static Jid fromUnescapedOrNull(CharSequence cs) { 344 try { 345 return fromUnescaped(cs); 346 } catch (XmppStringprepException e) { 347 return null; 348 } 349 } 350 351 /** 352 * Get a {@link Jid} from an URL encoded CharSequence. 353 * 354 * @param cs a CharSequence representing an URL encoded JID. 355 * @return a JID 356 * @throws XmppStringprepException if an error occurs. 357 * @see URLDecoder 358 */ 359 public static Jid fromUrlEncoded(CharSequence cs) throws XmppStringprepException { 360 String decoded = urlDecode(cs); 361 return from(decoded); 362 } 363 364 /** 365 * Like {@link #bareFrom(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 366 * {@link XmppStringprepException}. 367 * 368 * @param cs the character sequence which should be transformed to a {@link BareJid} 369 * @return the {@link BareJid} if no exception occurs 370 * @throws IllegalArgumentException if the given input is not a valid JID 371 * @see #bareFrom(CharSequence) 372 * @since 0.6.2 373 */ 374 public static BareJid bareFromOrThrowUnchecked(CharSequence cs) { 375 try { 376 return bareFrom(cs); 377 } catch (XmppStringprepException e) { 378 throw new IllegalArgumentException(e); 379 } 380 } 381 382 /** 383 * Get a {@link BareJid} representing the given CharSequence. 384 * 385 * @param jid the input CharSequence. 386 * @return a bare JID representing the given CharSequence. 387 * @throws XmppStringprepException if an error occurs. 388 */ 389 public static BareJid bareFrom(CharSequence jid) throws XmppStringprepException { 390 return bareFrom(jid.toString()); 391 } 392 393 /** 394 * Get a {@link BareJid} representing the given String. 395 * 396 * @param jid the input String. 397 * @return a bare JID representing the given String. 398 * @throws XmppStringprepException if an error occurs. 399 */ 400 public static BareJid bareFrom(String jid) throws XmppStringprepException { 401 return bareFrom(jid, JxmppContext.getDefaultContext()); 402 } 403 404 /** 405 * Get a {@link BareJid} representing the given String. 406 * 407 * @param jid the input String. 408 * @param context the JXMPP context. 409 * @return a bare JID representing the given String. 410 * @throws XmppStringprepException if an error occurs. 411 */ 412 public static BareJid bareFrom(String jid, JxmppContext context) throws XmppStringprepException { 413 BareJid bareJid; 414 JidStringAndStringprep jidStringAndStringprep = null; 415 if (context.isCachingEnabled()) { 416 jidStringAndStringprep = new JidStringAndStringprep(jid, context); 417 } 418 419 if (jidStringAndStringprep != null) { 420 bareJid = BAREJID_CACHE.lookup(jidStringAndStringprep); 421 if (bareJid != null) { 422 return bareJid; 423 } 424 } 425 426 String localpart = XmppStringUtils.parseLocalpart(jid); 427 String domainpart = XmppStringUtils.parseDomain(jid); 428 try { 429 if (localpart == null || localpart.length() == 0) { 430 bareJid = new DomainpartJid(domainpart, context); 431 } else { 432 bareJid = new LocalAndDomainpartJid(localpart, domainpart, context); 433 } 434 } catch (XmppStringprepException e) { 435 throw new XmppStringprepException(jid, e); 436 } 437 438 if (jidStringAndStringprep != null) { 439 BAREJID_CACHE.put(jidStringAndStringprep, bareJid); 440 } 441 return bareJid; 442 } 443 444 /** 445 * Get a {@link BareJid} constructed from the optionally given {@link Localpart} and {link DomainBareJid}. 446 * 447 * @param localpart a optional localpart. 448 * @param domainBareJid a domain bare JID. 449 * @return a bare JID. 450 */ 451 public static BareJid bareFrom(Localpart localpart, DomainBareJid domainBareJid) { 452 return bareFrom(localpart, domainBareJid.getDomain()); 453 } 454 455 /** 456 * Get a {@link BareJid} constructed from the optionally given {@link Localpart} and {@link Domainpart}. 457 * 458 * @param localpart a optional localpart. 459 * @param domain a domainpart. 460 * @return a bare JID constructed from the given parts. 461 */ 462 public static BareJid bareFrom(Localpart localpart, Domainpart domain) { 463 if (localpart != null) { 464 return new LocalAndDomainpartJid(localpart, domain); 465 } else { 466 return new DomainpartJid(domain); 467 } 468 } 469 470 /** 471 * Get a {@link BareJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 472 * 473 * @param cs the input {@link CharSequence} 474 * @return a JID or {@code null} 475 */ 476 public static BareJid bareFromOrNull(CharSequence cs) { 477 try { 478 return bareFrom(cs); 479 } catch (XmppStringprepException e) { 480 return null; 481 } 482 } 483 484 /** 485 * Get a {@link BareJid} from an URL encoded CharSequence. 486 * 487 * @param cs a CharSequence representing an URL encoded bare JID. 488 * @return a bare JID 489 * @throws XmppStringprepException if an error occurs. 490 * @see URLDecoder 491 */ 492 public static BareJid bareFromUrlEncoded(CharSequence cs) throws XmppStringprepException { 493 String decoded = urlDecode(cs.toString()); 494 return bareFrom(decoded); 495 } 496 497 /** 498 * Like {@link #fullFrom(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 499 * {@link XmppStringprepException}. 500 * 501 * @param cs the character sequence which should be transformed to a {@link FullJid} 502 * @return the {@link FullJid} if no exception occurs 503 * @throws IllegalArgumentException if the given input is not a valid JID 504 * @see #fullFrom(CharSequence) 505 * @since 0.6.2 506 */ 507 public static FullJid fullFromOrThrowUnchecked(CharSequence cs) { 508 try { 509 return fullFrom(cs); 510 } catch (XmppStringprepException e) { 511 throw new IllegalArgumentException(e); 512 } 513 } 514 515 /** 516 * Get a {@link FullJid} representing the given CharSequence. 517 * 518 * @param jid a CharSequence representing a JID. 519 * @return a full JID representing the given CharSequence. 520 * @throws XmppStringprepException if an error occurs. 521 */ 522 public static FullJid fullFrom(CharSequence jid) throws XmppStringprepException { 523 return fullFrom(jid.toString()); 524 } 525 526 /** 527 * Get a {@link FullJid} representing the given String. 528 * 529 * @param jid the JID's String. 530 * @return a full JID representing the input String. 531 * @throws XmppStringprepException if an error occurs. 532 */ 533 public static FullJid fullFrom(String jid) throws XmppStringprepException { 534 return fullFrom(jid, JxmppContext.getDefaultContext()); 535 } 536 537 /** 538 * Get a {@link FullJid} representing the given String. 539 * 540 * @param jid the JID's String. 541 * @param context the JXMPP context. 542 * @return a full JID representing the input String. 543 * @throws XmppStringprepException if an error occurs. 544 */ 545 public static FullJid fullFrom(String jid, JxmppContext context) throws XmppStringprepException { 546 JidStringAndStringprep jidStringAndStringprep = null; 547 if (context.isCachingEnabled()) { 548 jidStringAndStringprep = new JidStringAndStringprep(jid, context); 549 } 550 551 FullJid fullJid; 552 if (jidStringAndStringprep != null) { 553 fullJid = FULLJID_CACHE.lookup(jidStringAndStringprep); 554 if (fullJid != null) { 555 return fullJid; 556 } 557 } 558 559 String localpart = XmppStringUtils.parseLocalpart(jid); 560 String domainpart = XmppStringUtils.parseDomain(jid); 561 String resource = XmppStringUtils.parseResource(jid); 562 try { 563 fullJid = fullFrom(localpart, domainpart, resource); 564 } catch (XmppStringprepException e) { 565 throw new XmppStringprepException(jid, e); 566 } 567 568 if (jidStringAndStringprep != null) { 569 FULLJID_CACHE.put(jidStringAndStringprep, fullJid); 570 } 571 572 return fullJid; 573 } 574 575 /** 576 * Get a {@link FullJid} constructed from the given parts. 577 * 578 * @param localpart a optional localpart. 579 * @param domainpart a domainpart. 580 * @param resource a resourcepart. 581 * @return a full JID. 582 * @throws XmppStringprepException if an error occurs. 583 */ 584 public static FullJid fullFrom(String localpart, String domainpart, String resource) throws XmppStringprepException { 585 return fullFrom(localpart, domainpart, resource, JxmppContext.getDefaultContext()); 586 } 587 588 /** 589 * Get a {@link FullJid} constructed from the given parts. 590 * 591 * @param localpart a optional localpart. 592 * @param domainpart a domainpart. 593 * @param resource a resourcepart. 594 * @param context the JXMPP context. 595 * @return a full JID. 596 * @throws XmppStringprepException if an error occurs. 597 */ 598 public static FullJid fullFrom(String localpart, String domainpart, String resource, JxmppContext context) throws XmppStringprepException { 599 FullJid fullJid; 600 try { 601 if (localpart == null || localpart.length() == 0) { 602 fullJid = new DomainAndResourcepartJid(domainpart, resource, context); 603 } else { 604 fullJid = new LocalDomainAndResourcepartJid(localpart, domainpart, resource, context); 605 } 606 } catch (XmppStringprepException e) { 607 throw new XmppStringprepException(localpart + '@' + domainpart + '/' + resource, e); 608 } 609 return fullJid; 610 } 611 612 /** 613 * Get a {@link FullJid} constructed from the given parts. 614 * 615 * @param localpart a optional localpart. 616 * @param domainBareJid a domain bare JID. 617 * @param resource a resourcepart 618 * @return a full JID. 619 */ 620 public static FullJid fullFrom(Localpart localpart, DomainBareJid domainBareJid, Resourcepart resource) { 621 return fullFrom(localpart, domainBareJid.getDomain(), resource); 622 } 623 624 /** 625 * Get a {@link FullJid} constructed from the given parts. 626 * 627 * @param localpart the optional localpart. 628 * @param domainpart the domainpart. 629 * @param resource the resourcepart. 630 * @return a full JID. 631 */ 632 public static FullJid fullFrom(Localpart localpart, Domainpart domainpart, Resourcepart resource) { 633 return fullFrom(entityBareFrom(localpart, domainpart), resource); 634 } 635 636 /** 637 * Get a {@link FullJid} constructed from a {@link BareJid} and a {@link Resourcepart}. 638 * 639 * @param bareJid a entity bare JID. 640 * @param resource a resourcepart. 641 * @return a full JID. 642 */ 643 public static FullJid fullFrom(BareJid bareJid, Resourcepart resource) { 644 if (bareJid.isEntityBareJid()) { 645 EntityBareJid entityBareJid = (EntityBareJid) bareJid; 646 return new LocalDomainAndResourcepartJid(entityBareJid, resource); 647 } else { 648 DomainBareJid domainBareJid = (DomainBareJid) bareJid; 649 return new DomainAndResourcepartJid(domainBareJid, resource); 650 } 651 } 652 653 /** 654 * Get a {@link FullJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 655 * 656 * @param cs the input {@link CharSequence} 657 * @return a JID or {@code null} 658 */ 659 public static FullJid fullFromOrNull(CharSequence cs) { 660 try { 661 return fullFrom(cs); 662 } catch (XmppStringprepException e) { 663 return null; 664 } 665 } 666 667 /** 668 * Get a {@link FullJid} from an URL encoded CharSequence. 669 * 670 * @param cs a CharSequence representing an URL encoded full JID. 671 * @return a full JID 672 * @throws XmppStringprepException if an error occurs. 673 * @see URLDecoder 674 */ 675 public static FullJid fullFromUrlEncoded(CharSequence cs) throws XmppStringprepException { 676 String decoded = urlDecode(cs); 677 return fullFrom(decoded); 678 } 679 680 /** 681 * Like {@link #entityFrom(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 682 * {@link XmppStringprepException}. 683 * 684 * @param cs the character sequence which should be transformed to a {@link EntityJid} 685 * @return the {@link EntityJid} if no exception occurs 686 * @throws IllegalArgumentException if the given input is not a valid JID 687 * @see #entityFrom(CharSequence) 688 * @since 0.6.2 689 */ 690 public static EntityJid entityFromOrThrowUnchecked(CharSequence cs) { 691 try { 692 return entityFrom(cs); 693 } catch (XmppStringprepException e) { 694 throw new IllegalArgumentException(e); 695 } 696 } 697 698 /** 699 * Get a {@link EntityJid} representing the given String. 700 * 701 * @param jid the JID's string. 702 * @return an entity JID representing the given String. 703 * @throws XmppStringprepException if an error occurs. 704 */ 705 public static EntityJid entityFrom(CharSequence jid) throws XmppStringprepException { 706 return entityFrom(jid.toString()); 707 } 708 709 /** 710 * Get a {@link EntityJid} representing the given String. 711 * 712 * @param jidString the JID's string. 713 * @return an entity JID representing the given String. 714 * @throws XmppStringprepException if an error occurs. 715 */ 716 public static EntityJid entityFrom(String jidString) throws XmppStringprepException { 717 return entityFrom(jidString, JxmppContext.getDefaultContext()); 718 } 719 720 /** 721 * Get a {@link EntityJid} representing the given String. 722 * 723 * @param jidString the JID's string. 724 * @param context the JXMPP context. 725 * @return an entity JID representing the given String. 726 * @throws XmppStringprepException if an error occurs. 727 */ 728 public static EntityJid entityFrom(String jidString, JxmppContext context) throws XmppStringprepException { 729 return entityFrom(jidString, false, context); 730 } 731 732 /** 733 * Like {@link #entityFromUnescaped(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 734 * {@link XmppStringprepException}. 735 * 736 * @param cs the character sequence which should be transformed to a {@link EntityJid} 737 * @return the {@link EntityJid} if no exception occurs 738 * @throws IllegalArgumentException if the given input is not a valid JID 739 * @see #entityFromUnescaped(CharSequence) 740 * @since 0.6.2 741 */ 742 public static EntityJid entityFromUnescapedOrThrowUnchecked(CharSequence cs) { 743 return entityFromUnescapedOrThrowUnchecked(cs, JxmppContext.getDefaultContext()); 744 } 745 746 /** 747 * Like {@link #entityFromUnescaped(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 748 * {@link XmppStringprepException}. 749 * 750 * @param cs the character sequence which should be transformed to a {@link EntityJid} 751 * @param context the JXMPP context. 752 * @return the {@link EntityJid} if no exception occurs 753 * @throws IllegalArgumentException if the given input is not a valid JID 754 * @see #entityFromUnescaped(CharSequence) 755 * @since 0.6.2 756 */ 757 public static EntityJid entityFromUnescapedOrThrowUnchecked(CharSequence cs, JxmppContext context) { 758 try { 759 return entityFromUnescaped(cs, context); 760 } catch (XmppStringprepException e) { 761 throw new IllegalArgumentException(e); 762 } 763 } 764 765 /** 766 * Get a {@link EntityJid} representing the given String. 767 * 768 * @param jid the JID. 769 * @return an entity JID representing the given input.. 770 * @throws XmppStringprepException if an error occurs. 771 */ 772 public static EntityJid entityFromUnescaped(CharSequence jid) throws XmppStringprepException { 773 return entityFromUnescaped(jid, JxmppContext.getDefaultContext()); 774 } 775 776 /** 777 * Get a {@link EntityJid} representing the given String. 778 * 779 * @param jid the JID. 780 * @param context the JXMPP context. 781 * @return an entity JID representing the given input. 782 * @throws XmppStringprepException if an error occurs. 783 */ 784 public static EntityJid entityFromUnescaped(CharSequence jid, JxmppContext context) throws XmppStringprepException { 785 return entityFromUnescaped(jid.toString(), context); 786 } 787 788 /** 789 * Get a {@link EntityJid} representing the given String. 790 * 791 * @param jidString the JID's string. 792 * @return an entity JID representing the given String. 793 * @throws XmppStringprepException if an error occurs. 794 */ 795 public static EntityJid entityFromUnescaped(String jidString) throws XmppStringprepException { 796 return entityFromUnescaped(jidString, JxmppContext.getDefaultContext()); 797 } 798 799 /** 800 * Get a {@link EntityJid} representing the given String. 801 * 802 * @param jidString the JID's string. 803 * @param context the JXMPP context. 804 * @return an entity JID representing the given String. 805 * @throws XmppStringprepException if an error occurs. 806 */ 807 public static EntityJid entityFromUnescaped(String jidString, JxmppContext context) throws XmppStringprepException { 808 return entityFrom(jidString, true, context); 809 } 810 811 /** 812 * Get a {@link EntityJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 813 * 814 * @param cs the input {@link CharSequence} 815 * @return a JID or {@code null} 816 * @deprecated use {@link #entityFromUnescapedOrNull(CharSequence)} instead. 817 */ 818 // TODO: remove in jxmpp 1.1 819 @Deprecated 820 public static EntityJid entityFromUnesacpedOrNull(CharSequence cs) { 821 return entityFromUnescapedOrNull(cs); 822 } 823 824 /** 825 * Get a {@link EntityJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 826 * 827 * @param cs the input {@link CharSequence} 828 * @return a JID or {@code null} 829 */ 830 public static EntityJid entityFromUnescapedOrNull(CharSequence cs) { 831 try { 832 return entityFromUnescaped(cs.toString()); 833 } catch (XmppStringprepException e) { 834 return null; 835 } 836 } 837 838 /** 839 * Get a {@link EntityJid} representing the given String. 840 * 841 * @param jidString the JID's string. 842 * @param unescaped if the JID string is unescaped. 843 * @return an entity JID representing the given String. 844 * @throws XmppStringprepException if an error occurs. 845 */ 846 private static EntityJid entityFrom(String jidString, boolean unescaped, JxmppContext context) throws XmppStringprepException { 847 JidStringAndStringprep jidStringAndStringprep = null; 848 if (context.isCachingEnabled()) { 849 jidStringAndStringprep = new JidStringAndStringprep(jidString, context); 850 } 851 852 EntityJid entityJid; 853 if (jidStringAndStringprep != null) { 854 entityJid = ENTITYJID_CACHE.lookup(jidStringAndStringprep); 855 if (entityJid != null) { 856 return entityJid; 857 } 858 } 859 String localpartString = XmppStringUtils.parseLocalpart(jidString); 860 if (localpartString == null) { 861 throw new XmppStringprepException("Does not contain a localpart", jidString); 862 } 863 Localpart localpart; 864 try { 865 if (unescaped) { 866 localpart = Localpart.fromUnescaped(localpartString); 867 } else { 868 localpart = Localpart.from(localpartString); 869 } 870 } catch (XmppStringprepException e) { 871 throw new XmppStringprepException(jidString, e); 872 } 873 874 String domainpartString = XmppStringUtils.parseDomain(jidString); 875 Domainpart domainpart; 876 try { 877 domainpart = Domainpart.from(domainpartString); 878 } catch (XmppStringprepException e) { 879 throw new XmppStringprepException(jidString, e); 880 } 881 882 String resourceString = XmppStringUtils.parseResource(jidString); 883 if (resourceString != null) { 884 Resourcepart resourcepart; 885 try { 886 resourcepart = Resourcepart.from(resourceString); 887 } catch (XmppStringprepException e) { 888 throw new XmppStringprepException(jidString, e); 889 } 890 entityJid = entityFullFrom(localpart, domainpart, resourcepart); 891 } else { 892 entityJid = entityBareFrom(localpart, domainpart); 893 } 894 895 if (jidStringAndStringprep != null) { 896 ENTITYJID_CACHE.put(jidStringAndStringprep, entityJid); 897 } 898 return entityJid; 899 } 900 901 /** 902 * Get a {@link EntityJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 903 * 904 * @param cs the input {@link CharSequence} 905 * @return a JID or {@code null} 906 */ 907 public static EntityJid entityFromOrNull(CharSequence cs) { 908 try { 909 return entityFrom(cs); 910 } catch (XmppStringprepException e) { 911 return null; 912 } 913 } 914 915 /** 916 * Get a {@link EntityJid} from an URL encoded CharSequence. 917 * 918 * @param cs a CharSequence representing an URL encoded entity JID. 919 * @return an entity JID 920 * @throws XmppStringprepException if an error occurs. 921 * @see URLDecoder 922 */ 923 public static EntityJid entityFromUrlEncoded(CharSequence cs) throws XmppStringprepException { 924 String decoded = urlDecode(cs); 925 return entityFrom(decoded); 926 } 927 928 /** 929 * Like {@link #entityBareFrom(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 930 * {@link XmppStringprepException}. 931 * 932 * @param cs the character sequence which should be transformed to a {@link EntityBareJid} 933 * @return the {@link EntityBareJid} if no exception occurs 934 * @throws IllegalArgumentException if the given input is not a valid JID 935 * @see #entityBareFrom(CharSequence) 936 * @since 0.6.2 937 */ 938 public static EntityBareJid entityBareFromOrThrowUnchecked(CharSequence cs) { 939 try { 940 return entityBareFrom(cs); 941 } catch (XmppStringprepException e) { 942 throw new IllegalArgumentException(e); 943 } 944 } 945 946 /** 947 * Get a {@link EntityBareJid} representing the given CharSequence. 948 * 949 * @param jid the input CharSequence. 950 * @return a bare JID representing the given CharSequence. 951 * @throws XmppStringprepException if an error occurs. 952 */ 953 public static EntityBareJid entityBareFrom(CharSequence jid) throws XmppStringprepException { 954 return entityBareFrom(jid.toString()); 955 } 956 957 /** 958 * Get a {@link EntityBareJid} representing the given String. 959 * 960 * @param jid the input String. 961 * @return a bare JID representing the given String. 962 * @throws XmppStringprepException if an error occurs. 963 */ 964 public static EntityBareJid entityBareFrom(String jid) throws XmppStringprepException { 965 return entityBareFrom(jid, JxmppContext.getDefaultContext()); 966 } 967 968 /** 969 * Get a {@link EntityBareJid} representing the given String. 970 * 971 * @param jid the input String. 972 * @param context the JXMPP context. 973 * @return a bare JID representing the given String. 974 * @throws XmppStringprepException if an error occurs. 975 */ 976 public static EntityBareJid entityBareFrom(String jid, JxmppContext context) throws XmppStringprepException { 977 JidStringAndStringprep jidStringAndStringprep = null; 978 if (context.isCachingEnabled()) { 979 jidStringAndStringprep = new JidStringAndStringprep(jid, context); 980 } 981 982 EntityBareJid bareJid; 983 if (jidStringAndStringprep != null) { 984 bareJid = ENTITY_BAREJID_CACHE.lookup(jidStringAndStringprep); 985 if (bareJid != null) { 986 return bareJid; 987 } 988 } 989 990 String localpart = XmppStringUtils.parseLocalpart(jid); 991 String domainpart = XmppStringUtils.parseDomain(jid); 992 try { 993 bareJid = new LocalAndDomainpartJid(localpart, domainpart, context); 994 } catch (XmppStringprepException e) { 995 throw new XmppStringprepException(jid, e); 996 } 997 998 if (jidStringAndStringprep != null) { 999 ENTITY_BAREJID_CACHE.put(jidStringAndStringprep, bareJid); 1000 } 1001 return bareJid; 1002 } 1003 1004 /** 1005 * Like {@link #entityBareFromUnescaped(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 1006 * {@link XmppStringprepException}. 1007 * 1008 * @param cs the character sequence which should be transformed to a {@link EntityBareJid} 1009 * @return the {@link EntityBareJid} if no exception occurs 1010 * @throws IllegalArgumentException if the given input is not a valid JID 1011 * @see #entityBareFromUnescaped(CharSequence) 1012 * @since 0.6.2 1013 */ 1014 public static EntityBareJid entityBareFromUnescapedOrThrowUnchecked(CharSequence cs) { 1015 try { 1016 return entityBareFromUnescaped(cs); 1017 } catch (XmppStringprepException e) { 1018 throw new IllegalArgumentException(e); 1019 } 1020 } 1021 1022 /** 1023 * Get a {@link EntityBareJid} representing the given unescaped CharSequence. 1024 * 1025 * @param unescapedJid the input CharSequence. 1026 * @return a bare JID representing the given CharSequence. 1027 * @throws XmppStringprepException if an error occurs. 1028 */ 1029 public static EntityBareJid entityBareFromUnescaped(CharSequence unescapedJid) throws XmppStringprepException { 1030 return entityBareFromUnescaped(unescapedJid.toString()); 1031 } 1032 1033 /** 1034 * Get a {@link EntityBareJid} representing the given unescaped String. 1035 * 1036 * @param unescapedJidString the input String. 1037 * @return a bare JID representing the given String. 1038 * @throws XmppStringprepException if an error occurs. 1039 */ 1040 public static EntityBareJid entityBareFromUnescaped(String unescapedJidString) throws XmppStringprepException { 1041 return entityBareFromUnescaped(unescapedJidString, JxmppContext.getDefaultContext()); 1042 } 1043 1044 /** 1045 * Get a {@link EntityBareJid} representing the given unescaped String. 1046 * 1047 * @param unescapedJidString the input String. 1048 * @param context the JXMPP context. 1049 * @return a bare JID representing the given String. 1050 * @throws XmppStringprepException if an error occurs. 1051 */ 1052 public static EntityBareJid entityBareFromUnescaped(String unescapedJidString, JxmppContext context) throws XmppStringprepException { 1053 JidStringAndStringprep jidStringAndStringprep = null; 1054 if (context.isCachingEnabled()) { 1055 jidStringAndStringprep = new JidStringAndStringprep(unescapedJidString, context); 1056 } 1057 1058 EntityBareJid bareJid; 1059 if (jidStringAndStringprep != null) { 1060 bareJid = ENTITY_BAREJID_CACHE.lookup(jidStringAndStringprep); 1061 if (bareJid != null) { 1062 return bareJid; 1063 } 1064 } 1065 1066 String localpart = XmppStringUtils.parseLocalpart(unescapedJidString); 1067 // Some as from(String), but we escape the localpart 1068 localpart = XmppStringUtils.escapeLocalpart(localpart); 1069 1070 String domainpart = XmppStringUtils.parseDomain(unescapedJidString); 1071 try { 1072 bareJid = new LocalAndDomainpartJid(localpart, domainpart, context); 1073 } catch (XmppStringprepException e) { 1074 throw new XmppStringprepException(unescapedJidString, e); 1075 } 1076 1077 if (jidStringAndStringprep != null) { 1078 ENTITY_BAREJID_CACHE.put(jidStringAndStringprep, bareJid); 1079 } 1080 1081 return bareJid; 1082 } 1083 1084 /** 1085 * Get a {@link EntityBareJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 1086 * 1087 * @param cs the input {@link CharSequence} 1088 * @return a JID or {@code null} 1089 */ 1090 public static EntityBareJid entityBareFromUnescapedOrNull(CharSequence cs) { 1091 try { 1092 return entityBareFromUnescaped(cs.toString()); 1093 } catch (XmppStringprepException e) { 1094 return null; 1095 } 1096 } 1097 1098 /** 1099 * Get a {@link EntityBareJid} constructed from the given {@link Localpart} and {link DomainBareJid}. 1100 * 1101 * @param localpart a localpart. 1102 * @param domainBareJid a domain bare JID. 1103 * @return a bare JID. 1104 */ 1105 public static EntityBareJid entityBareFrom(Localpart localpart, DomainBareJid domainBareJid) { 1106 return entityBareFrom(localpart, domainBareJid.getDomain()); 1107 } 1108 1109 /** 1110 * Get a {@link EntityBareJid} constructed from the given {@link Localpart} and {@link Domainpart}. 1111 * 1112 * @param localpart a localpart. 1113 * @param domain a domainpart. 1114 * @return a bare JID constructed from the given parts. 1115 */ 1116 public static EntityBareJid entityBareFrom(Localpart localpart, Domainpart domain) { 1117 return new LocalAndDomainpartJid(localpart, domain); 1118 } 1119 1120 /** 1121 * Get a {@link EntityBareJid} constructed from the given {@link Localpart} and {@link Domainpart}. 1122 * 1123 * @param localpart a localpart. 1124 * @param domain a domainpart. 1125 * @return a bare JID constructed from the given parts. 1126 * @throws XmppStringprepException if an error occurs. 1127 */ 1128 public static EntityBareJid entityBareFrom(CharSequence localpart, Domainpart domain) throws XmppStringprepException { 1129 return new LocalAndDomainpartJid(Localpart.fromUnescaped(localpart), domain); 1130 } 1131 1132 /** 1133 * Get a {@link EntityBareJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 1134 * 1135 * @param cs the input {@link CharSequence} 1136 * @return a JID or {@code null} 1137 */ 1138 public static EntityBareJid entityBareFromOrNull(CharSequence cs) { 1139 try { 1140 return entityBareFrom(cs); 1141 } catch (XmppStringprepException e) { 1142 return null; 1143 } 1144 } 1145 1146 /** 1147 * Get a {@link EntityBareJid} from an URL encoded CharSequence. 1148 * 1149 * @param cs a CharSequence representing an URL encoded entity bare JID. 1150 * @return an entity bare JID 1151 * @throws XmppStringprepException if an error occurs. 1152 * @see URLDecoder 1153 */ 1154 public static EntityBareJid entityBareFromUrlEncoded(CharSequence cs) throws XmppStringprepException { 1155 String decoded = urlDecode(cs); 1156 return entityBareFrom(decoded); 1157 } 1158 1159 /** 1160 * Like {@link #entityFullFrom(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 1161 * {@link XmppStringprepException}. 1162 * 1163 * @param cs the character sequence which should be transformed to a {@link EntityFullJid} 1164 * @return the {@link EntityFullJid} if no exception occurs 1165 * @throws IllegalArgumentException if the given input is not a valid JID 1166 * @see #entityFullFrom(CharSequence) 1167 * @since 0.6.2 1168 */ 1169 public static EntityFullJid entityFullFromOrThrowUnchecked(CharSequence cs) { 1170 try { 1171 return entityFullFrom(cs); 1172 } catch (XmppStringprepException e) { 1173 throw new IllegalArgumentException(e); 1174 } 1175 } 1176 1177 /** 1178 * Get a {@link EntityFullJid} representing the given CharSequence. 1179 * 1180 * @param jid a CharSequence representing a JID. 1181 * @return a full JID representing the given CharSequence. 1182 * @throws XmppStringprepException if an error occurs. 1183 */ 1184 public static EntityFullJid entityFullFrom(CharSequence jid) throws XmppStringprepException { 1185 return entityFullFrom(jid.toString(), JxmppContext.getDefaultContext()); 1186 } 1187 1188 /** 1189 * Get a {@link EntityFullJid} representing the given String. 1190 * 1191 * @param jid the JID's String. 1192 * @param context the JXMPP context. 1193 * @return a full JID representing the input String. 1194 * @throws XmppStringprepException if an error occurs. 1195 */ 1196 public static EntityFullJid entityFullFrom(String jid, JxmppContext context) throws XmppStringprepException { 1197 JidStringAndStringprep jidStringAndStringprep = null; 1198 if (context.isCachingEnabled()) { 1199 jidStringAndStringprep = new JidStringAndStringprep(jid, context); 1200 } 1201 1202 EntityFullJid fullJid; 1203 if (jidStringAndStringprep != null) { 1204 fullJid = ENTITY_FULLJID_CACHE.lookup(jidStringAndStringprep); 1205 if (fullJid != null) { 1206 return fullJid; 1207 } 1208 } 1209 1210 String localpart = XmppStringUtils.parseLocalpart(jid); 1211 String domainpart = XmppStringUtils.parseDomain(jid); 1212 String resource = XmppStringUtils.parseResource(jid); 1213 try { 1214 fullJid = entityFullFrom(localpart, domainpart, resource); 1215 } catch (XmppStringprepException e) { 1216 throw new XmppStringprepException(jid, e); 1217 } 1218 1219 if (jidStringAndStringprep != null) { 1220 ENTITY_FULLJID_CACHE.put(jidStringAndStringprep, fullJid); 1221 } 1222 1223 return fullJid; 1224 } 1225 1226 /** 1227 * Get a {@link EntityFullJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 1228 * 1229 * @param cs the input {@link CharSequence} 1230 * @return a JID or {@code null} 1231 */ 1232 public static EntityFullJid entityFullFromOrNull(CharSequence cs) { 1233 try { 1234 return entityFullFrom(cs); 1235 } catch (XmppStringprepException e) { 1236 return null; 1237 } 1238 } 1239 1240 /** 1241 * Like {@link #entityFullFromUnescaped(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 1242 * {@link XmppStringprepException}. 1243 * 1244 * @param cs the character sequence which should be transformed to a {@link EntityFullJid} 1245 * @return the {@link EntityFullJid} if no exception occurs 1246 * @throws IllegalArgumentException if the given input is not a valid JID 1247 * @see #entityFullFromUnescaped(CharSequence) 1248 * @since 0.6.2 1249 */ 1250 public static EntityFullJid entityFullFromUnescapedOrThrowUnchecked(CharSequence cs) { 1251 try { 1252 return entityFullFromUnescaped(cs); 1253 } catch (XmppStringprepException e) { 1254 throw new IllegalArgumentException(e); 1255 } 1256 } 1257 1258 /** 1259 * Get a {@link EntityFullJid} representing the given unescaped CharSequence. 1260 * 1261 * @param unescapedJid a CharSequence representing a JID. 1262 * @return a full JID representing the given CharSequence. 1263 * @throws XmppStringprepException if an error occurs. 1264 */ 1265 public static EntityFullJid entityFullFromUnescaped(CharSequence unescapedJid) throws XmppStringprepException { 1266 return entityFullFromUnescaped(unescapedJid.toString()); 1267 } 1268 1269 /** 1270 * Get a {@link EntityFullJid} representing the given unescaped String. 1271 * 1272 * @param unescapedJidString the JID's String. 1273 * @return a full JID representing the input String. 1274 * @throws XmppStringprepException if an error occurs. 1275 */ 1276 public static EntityFullJid entityFullFromUnescaped(String unescapedJidString) throws XmppStringprepException { 1277 return entityFullFromUnescaped(unescapedJidString, JxmppContext.getDefaultContext()); 1278 } 1279 1280 /** 1281 * Get a {@link EntityFullJid} representing the given unescaped String. 1282 * 1283 * @param unescapedJidString the JID's String. 1284 * @param context the JXMPP context. 1285 * @return a full JID representing the input String. 1286 * @throws XmppStringprepException if an error occurs. 1287 */ 1288 public static EntityFullJid entityFullFromUnescaped(String unescapedJidString, JxmppContext context) throws XmppStringprepException { 1289 JidStringAndStringprep jidStringAndStringprep = null; 1290 if (context.isCachingEnabled()) { 1291 jidStringAndStringprep = new JidStringAndStringprep(unescapedJidString, context); 1292 } 1293 1294 EntityFullJid fullJid; 1295 if (jidStringAndStringprep != null) { 1296 fullJid = ENTITY_FULLJID_CACHE.lookup(jidStringAndStringprep); 1297 if (fullJid != null) { 1298 return fullJid; 1299 } 1300 } 1301 1302 String localpart = XmppStringUtils.parseLocalpart(unescapedJidString); 1303 // Some as from(String), but we escape the localpart 1304 localpart = XmppStringUtils.escapeLocalpart(localpart); 1305 1306 String domainpart = XmppStringUtils.parseDomain(unescapedJidString); 1307 String resource = XmppStringUtils.parseResource(unescapedJidString); 1308 try { 1309 fullJid = new LocalDomainAndResourcepartJid(localpart, domainpart, resource, context); 1310 } catch (XmppStringprepException e) { 1311 throw new XmppStringprepException(unescapedJidString, e); 1312 } 1313 1314 if (jidStringAndStringprep != null) { 1315 ENTITY_FULLJID_CACHE.put(jidStringAndStringprep, fullJid); 1316 } 1317 1318 return fullJid; 1319 } 1320 1321 /** 1322 * Get a {@link EntityFullJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 1323 * 1324 * @param cs the input {@link CharSequence} 1325 * @return a JID or {@code null} 1326 */ 1327 public static EntityFullJid entityFullFromUnescapedOrNull(CharSequence cs) { 1328 try { 1329 return entityFullFromUnescaped(cs.toString()); 1330 } catch (XmppStringprepException e) { 1331 return null; 1332 } 1333 } 1334 1335 /** 1336 * Get a {@link EntityFullJid} constructed from the given parts. 1337 * 1338 * @param localpart a localpart. 1339 * @param domainpart a domainpart. 1340 * @param resource a resourcepart. 1341 * @return a full JID. 1342 * @throws XmppStringprepException if an error occurs. 1343 */ 1344 public static EntityFullJid entityFullFrom(String localpart, String domainpart, String resource) throws XmppStringprepException { 1345 return entityFullFrom(localpart, domainpart, resource, JxmppContext.getDefaultContext()); 1346 } 1347 1348 /** 1349 * Get a {@link EntityFullJid} constructed from the given parts. 1350 * 1351 * @param localpart a localpart. 1352 * @param domainpart a domainpart. 1353 * @param resource a resourcepart. 1354 * @param context the JXMPP context. 1355 * @return a full JID. 1356 * @throws XmppStringprepException if an error occurs. 1357 */ 1358 public static EntityFullJid entityFullFrom(String localpart, String domainpart, String resource, JxmppContext context) throws XmppStringprepException { 1359 EntityFullJid fullJid; 1360 try { 1361 fullJid = new LocalDomainAndResourcepartJid(localpart, domainpart, resource, context); 1362 } catch (XmppStringprepException e) { 1363 throw new XmppStringprepException(localpart + '@' + domainpart + '/' + resource, e); 1364 } 1365 return fullJid; 1366 } 1367 1368 /** 1369 * Get a {@link EntityFullJid} constructed from the given parts. 1370 * 1371 * @param localpart a localpart. 1372 * @param domainBareJid a domain bare JID.. 1373 * @param resource a resourcepart 1374 * @return a full JID. 1375 */ 1376 public static EntityFullJid entityFullFrom(Localpart localpart, DomainBareJid domainBareJid, Resourcepart resource) { 1377 return entityFullFrom(localpart, domainBareJid.getDomain(), resource); 1378 } 1379 1380 /** 1381 * Get a {@link EntityFullJid} constructed from the given parts. 1382 * 1383 * @param localpart the localpart. 1384 * @param domainpart the domainpart. 1385 * @param resource the resourcepart. 1386 * @return a full JID. 1387 */ 1388 public static EntityFullJid entityFullFrom(Localpart localpart, Domainpart domainpart, Resourcepart resource) { 1389 return entityFullFrom(entityBareFrom(localpart, domainpart), resource); 1390 } 1391 1392 /** 1393 * Get a {@link EntityFullJid} constructed from the given parts. 1394 * 1395 * @param localpart the localpart. 1396 * @param domainpart the domainpart. 1397 * @param resource the resourcepart. 1398 * @return a full JID. 1399 * @throws XmppStringprepException if an error occurs. 1400 */ 1401 public static EntityFullJid entityFullFrom(CharSequence localpart, Domainpart domainpart, CharSequence resource) throws XmppStringprepException { 1402 return entityFullFrom(entityBareFrom(Localpart.fromUnescaped(localpart), domainpart), Resourcepart.from(resource)); 1403 } 1404 1405 /** 1406 * Get a {@link EntityFullJid} constructed from a {@link EntityBareJid} and a {@link Resourcepart}. 1407 * 1408 * @param bareJid a bare JID. 1409 * @param resource a resourcepart. 1410 * @return a full JID. 1411 */ 1412 public static EntityFullJid entityFullFrom(EntityBareJid bareJid, Resourcepart resource) { 1413 return new LocalDomainAndResourcepartJid(bareJid, resource); 1414 } 1415 1416 /** 1417 * Get a {@link EntityFullJid} from an URL encoded CharSequence. 1418 * 1419 * @param cs a CharSequence representing an URL encoded entity full JID. 1420 * @return an entity full JID 1421 * @throws XmppStringprepException if an error occurs. 1422 * @see URLDecoder 1423 */ 1424 public static EntityFullJid entityFullFromUrlEncoded(CharSequence cs) throws XmppStringprepException { 1425 String decoded = urlDecode(cs); 1426 return entityFullFrom(decoded); 1427 } 1428 1429 /** 1430 * Like {@link #domainBareFrom(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 1431 * {@link XmppStringprepException}. 1432 * 1433 * @param cs the character sequence which should be transformed to a {@link EntityFullJid} 1434 * @return the {@link EntityFullJid} if no exception occurs 1435 * @see #from(String) 1436 * @since 0.6.2 1437 */ 1438 public static DomainBareJid domainBareFromOrThrowUnchecked(CharSequence cs) { 1439 try { 1440 return domainBareFrom(cs); 1441 } catch (XmppStringprepException e) { 1442 throw new IllegalArgumentException(e); 1443 } 1444 } 1445 1446 /** 1447 * Get a domain bare JID. 1448 * 1449 * @param jid the JID CharSequence. 1450 * @return a domain bare JID. 1451 * @throws XmppStringprepException if an error occurs. 1452 */ 1453 public static DomainBareJid domainBareFrom(CharSequence jid) throws XmppStringprepException { 1454 return domainBareFrom(jid.toString()); 1455 } 1456 1457 /** 1458 * Get a domain bare JID. 1459 * 1460 * @param jid the JID String. 1461 * @return a domain bare JID. 1462 * @throws XmppStringprepException if an error occurs. 1463 */ 1464 public static DomainBareJid domainBareFrom(String jid) throws XmppStringprepException { 1465 return domainBareFrom(jid, JxmppContext.getDefaultContext()); 1466 } 1467 1468 /** 1469 * Get a domain bare JID. 1470 * 1471 * @param jid the JID String. 1472 * @param context the JXMPP context. 1473 * @return a domain bare JID. 1474 * @throws XmppStringprepException if an error occurs. 1475 */ 1476 public static DomainBareJid domainBareFrom(String jid, JxmppContext context) throws XmppStringprepException { 1477 JidStringAndStringprep jidStringAndStringprep = null; 1478 if (context.isCachingEnabled()) { 1479 jidStringAndStringprep = new JidStringAndStringprep(jid, context); 1480 } 1481 1482 DomainBareJid domainJid; 1483 if (jidStringAndStringprep != null) { 1484 domainJid = DOMAINJID_CACHE.lookup(jidStringAndStringprep); 1485 if (domainJid != null) { 1486 return domainJid; 1487 } 1488 } 1489 1490 String domain = XmppStringUtils.parseDomain(jid); 1491 try { 1492 domainJid = new DomainpartJid(domain, context); 1493 } catch (XmppStringprepException e) { 1494 throw new XmppStringprepException(jid, e); 1495 } 1496 1497 if (context.isCachingEnabled()) { 1498 DOMAINJID_CACHE.put(jidStringAndStringprep, domainJid); 1499 } 1500 return domainJid; 1501 } 1502 1503 /** 1504 * Get a {@link DomainBareJid} consisting of the given {@link Domainpart}. 1505 * 1506 * @param domainpart the domainpart. 1507 * @return a domain bare JID. 1508 */ 1509 public static DomainBareJid domainBareFrom(Domainpart domainpart) { 1510 return new DomainpartJid(domainpart); 1511 } 1512 1513 /** 1514 * Get a {@link DomainBareJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 1515 * 1516 * @param cs the input {@link CharSequence} 1517 * @return a JID or {@code null} 1518 */ 1519 public static DomainBareJid domainBareFromOrNull(CharSequence cs) { 1520 try { 1521 return domainBareFrom(cs); 1522 } catch (XmppStringprepException e) { 1523 return null; 1524 } 1525 } 1526 1527 /** 1528 * Get a {@link DomainBareJid} from an URL encoded CharSequence. 1529 * 1530 * @param cs a CharSequence representing an URL encoded domain bare JID. 1531 * @return a domain bare JID 1532 * @throws XmppStringprepException if an error occurs. 1533 * @see URLDecoder 1534 */ 1535 public static DomainBareJid domainBareFromUrlEncoded(CharSequence cs) throws XmppStringprepException { 1536 String decode = urlDecode(cs); 1537 return domainBareFrom(decode); 1538 } 1539 1540 /** 1541 * Like {@link #domainFullFrom(CharSequence)} but does throw an unchecked {@link IllegalArgumentException} instead of a 1542 * {@link XmppStringprepException}. 1543 * 1544 * @param cs the character sequence which should be transformed to a {@link DomainFullJid} 1545 * @return the {@link DomainFullJid} if no exception occurs 1546 * @throws IllegalArgumentException if the given input is not a valid JID 1547 * @see #domainFullFrom(CharSequence) 1548 * @since 0.6.2 1549 */ 1550 public static DomainFullJid domainFullFromOrThrowUnchecked(CharSequence cs) { 1551 try { 1552 return domainFullFrom(cs); 1553 } catch (XmppStringprepException e) { 1554 throw new IllegalArgumentException(e); 1555 } 1556 } 1557 1558 /** 1559 * Get a domain full JID from the given CharSequence. 1560 * 1561 * @param jid the JID. 1562 * @return a domain full JID. 1563 * @throws XmppStringprepException if an error happens. 1564 */ 1565 public static DomainFullJid domainFullFrom(CharSequence jid) throws XmppStringprepException { 1566 return domainFullFrom(jid.toString()); 1567 } 1568 1569 /** 1570 * Get a domain full JID from the given String. 1571 * 1572 * @param jid the JID. 1573 * @return a DomainFullJid. 1574 * @throws XmppStringprepException if an error happens. 1575 */ 1576 public static DomainFullJid domainFullFrom(String jid) throws XmppStringprepException { 1577 return domainFullFrom(jid, JxmppContext.getDefaultContext()); 1578 } 1579 1580 /** 1581 * Get a domain full JID from the given String. 1582 * 1583 * @param jid the JID. 1584 * @param context the JXMPP context. 1585 * @return a DomainFullJid. 1586 * @throws XmppStringprepException if an error happens. 1587 */ 1588 public static DomainFullJid domainFullFrom(String jid, JxmppContext context) throws XmppStringprepException { 1589 JidStringAndStringprep jidStringAndStringprep = null; 1590 if (context.isCachingEnabled()) { 1591 jidStringAndStringprep = new JidStringAndStringprep(jid, context); 1592 } 1593 1594 DomainFullJid domainResourceJid; 1595 if (jidStringAndStringprep != null) { 1596 domainResourceJid = DOMAINRESOURCEJID_CACHE.lookup(jidStringAndStringprep); 1597 if (domainResourceJid != null) { 1598 return domainResourceJid; 1599 } 1600 } 1601 1602 String domain = XmppStringUtils.parseDomain(jid); 1603 String resource = XmppStringUtils.parseResource(jid); 1604 try { 1605 domainResourceJid = new DomainAndResourcepartJid(domain, resource, context); 1606 } catch (XmppStringprepException e) { 1607 throw new XmppStringprepException(jid, e); 1608 } 1609 1610 if (jidStringAndStringprep != null) { 1611 DOMAINRESOURCEJID_CACHE.put(jidStringAndStringprep, domainResourceJid); 1612 } 1613 1614 return domainResourceJid; 1615 } 1616 1617 /** 1618 * Get a domain full JID. 1619 * 1620 * @param domainpart the domainpart. 1621 * @param resource the resourcepart. 1622 * @return a domain full JID. 1623 */ 1624 public static DomainFullJid domainFullFrom(Domainpart domainpart, Resourcepart resource) { 1625 return domainFullFrom(domainBareFrom(domainpart), resource); 1626 } 1627 1628 /** 1629 * Get a domain full JID. 1630 * 1631 * @param domainBareJid a domain bare JID. 1632 * @param resource a resourcepart. 1633 * @return a domain full JID. 1634 */ 1635 public static DomainFullJid domainFullFrom(DomainBareJid domainBareJid, Resourcepart resource) { 1636 return new DomainAndResourcepartJid(domainBareJid, resource); 1637 } 1638 1639 /** 1640 * Get a {@link DomainFullJid} from a given {@link CharSequence} or {@code null} if the input does not represent a JID. 1641 * 1642 * @param cs the input {@link CharSequence} 1643 * @return a JID or {@code null} 1644 */ 1645 public static DomainFullJid domainFullFromOrNull(CharSequence cs) { 1646 try { 1647 return domainFullFrom(cs); 1648 } catch (XmppStringprepException e) { 1649 return null; 1650 } 1651 } 1652 1653 /** 1654 * Get a {@link DomainFullJid} from an URL encoded CharSequence. 1655 * 1656 * @param cs a CharSequence representing an URL encoded domain full JID. 1657 * @return a domain full JID 1658 * @throws XmppStringprepException if an error occurs. 1659 * @see URLDecoder 1660 */ 1661 public static DomainFullJid domainFullFromUrlEncoded(CharSequence cs) throws XmppStringprepException { 1662 String decoded = urlDecode(cs); 1663 return domainFullFrom(decoded); 1664 } 1665 1666 private static String urlDecode(CharSequence cs) { 1667 try { 1668 return URLDecoder.decode(cs.toString(), "UTF-8"); 1669 } catch (UnsupportedEncodingException e) { 1670 throw new AssertionError(e); 1671 } 1672 } 1673}