001/* 002 * Copyright (C) 2009 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 005 * in compliance with the License. You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software distributed under the License 010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 011 * or implied. See the License for the specific language governing permissions and limitations under 012 * the License. 013 */ 014 015package com.google.common.net; 016 017import static com.google.common.base.Preconditions.checkArgument; 018import static com.google.common.base.Preconditions.checkNotNull; 019import static com.google.common.base.Preconditions.checkState; 020 021import com.google.common.annotations.Beta; 022import com.google.common.annotations.GwtCompatible; 023import com.google.common.base.Ascii; 024import com.google.common.base.CharMatcher; 025import com.google.common.base.Joiner; 026import com.google.common.base.Optional; 027import com.google.common.base.Splitter; 028import com.google.common.collect.ImmutableList; 029import com.google.errorprone.annotations.Immutable; 030import com.google.thirdparty.publicsuffix.PublicSuffixPatterns; 031import com.google.thirdparty.publicsuffix.PublicSuffixType; 032import java.util.List; 033import org.checkerframework.checker.nullness.qual.Nullable; 034 035/** 036 * An immutable well-formed internet domain name, such as {@code com} or {@code foo.co.uk}. Only 037 * syntactic analysis is performed; no DNS lookups or other network interactions take place. Thus 038 * there is no guarantee that the domain actually exists on the internet. 039 * 040 * <p>One common use of this class is to determine whether a given string is likely to represent an 041 * addressable domain on the web -- that is, for a candidate string {@code "xxx"}, might browsing to 042 * {@code "http://xxx/"} result in a webpage being displayed? In the past, this test was frequently 043 * done by determining whether the domain ended with a {@linkplain #isPublicSuffix() public suffix} 044 * but was not itself a public suffix. However, this test is no longer accurate. There are many 045 * domains which are both public suffixes and addressable as hosts; {@code "uk.com"} is one example. 046 * Using the subset of public suffixes that are {@linkplain #isRegistrySuffix() registry suffixes}, 047 * one can get a better result, as only a few registry suffixes are addressable. However, the most 048 * useful test to determine if a domain is a plausible web host is {@link #hasPublicSuffix()}. This 049 * will return {@code true} for many domains which (currently) are not hosts, such as {@code "com"}, 050 * but given that any public suffix may become a host without warning, it is better to err on the 051 * side of permissiveness and thus avoid spurious rejection of valid sites. Of course, to actually 052 * determine addressability of any host, clients of this class will need to perform their own DNS 053 * lookups. 054 * 055 * <p>During construction, names are normalized in two ways: 056 * 057 * <ol> 058 * <li>ASCII uppercase characters are converted to lowercase. 059 * <li>Unicode dot separators other than the ASCII period ({@code '.'}) are converted to the ASCII 060 * period. 061 * </ol> 062 * 063 * <p>The normalized values will be returned from {@link #toString()} and {@link #parts()}, and will 064 * be reflected in the result of {@link #equals(Object)}. 065 * 066 * <p><a href="http://en.wikipedia.org/wiki/Internationalized_domain_name">Internationalized domain 067 * names</a> such as {@code 网络.cn} are supported, as are the equivalent <a 068 * href="http://en.wikipedia.org/wiki/Internationalized_domain_name">IDNA Punycode-encoded</a> 069 * versions. 070 * 071 * @author Catherine Berry 072 * @since 5.0 073 */ 074@Beta 075@GwtCompatible(emulated = true) 076@Immutable 077public final class InternetDomainName { 078 079 private static final CharMatcher DOTS_MATCHER = CharMatcher.anyOf(".\u3002\uFF0E\uFF61"); 080 private static final Splitter DOT_SPLITTER = Splitter.on('.'); 081 private static final Joiner DOT_JOINER = Joiner.on('.'); 082 083 /** 084 * Value of {@link #publicSuffixIndex} or {@link #registrySuffixIndex} which indicates that no 085 * relevant suffix was found. 086 */ 087 private static final int NO_SUFFIX_FOUND = -1; 088 089 /** 090 * Maximum parts (labels) in a domain name. This value arises from the 255-octet limit described 091 * in <a href="http://www.ietf.org/rfc/rfc2181.txt">RFC 2181</a> part 11 with the fact that the 092 * encoding of each part occupies at least two bytes (dot plus label externally, length byte plus 093 * label internally). Thus, if all labels have the minimum size of one byte, 127 of them will fit. 094 */ 095 private static final int MAX_PARTS = 127; 096 097 /** 098 * Maximum length of a full domain name, including separators, and leaving room for the root 099 * label. See <a href="http://www.ietf.org/rfc/rfc2181.txt">RFC 2181</a> part 11. 100 */ 101 private static final int MAX_LENGTH = 253; 102 103 /** 104 * Maximum size of a single part of a domain name. See <a 105 * href="http://www.ietf.org/rfc/rfc2181.txt">RFC 2181</a> part 11. 106 */ 107 private static final int MAX_DOMAIN_PART_LENGTH = 63; 108 109 /** The full domain name, converted to lower case. */ 110 private final String name; 111 112 /** The parts of the domain name, converted to lower case. */ 113 private final ImmutableList<String> parts; 114 115 /** 116 * The index in the {@link #parts()} list at which the public suffix begins. For example, for the 117 * domain name {@code myblog.blogspot.co.uk}, the value would be 1 (the index of the {@code 118 * blogspot} part). The value is negative (specifically, {@link #NO_SUFFIX_FOUND}) if no public 119 * suffix was found. 120 */ 121 private final int publicSuffixIndex; 122 123 /** 124 * The index in the {@link #parts()} list at which the registry suffix begins. For example, for 125 * the domain name {@code myblog.blogspot.co.uk}, the value would be 2 (the index of the {@code 126 * co} part). The value is negative (specifically, {@link #NO_SUFFIX_FOUND}) if no registry suffix 127 * was found. 128 */ 129 private final int registrySuffixIndex; 130 131 /** Constructor used to implement {@link #from(String)}, and from subclasses. */ 132 InternetDomainName(String name) { 133 // Normalize: 134 // * ASCII characters to lowercase 135 // * All dot-like characters to '.' 136 // * Strip trailing '.' 137 138 name = Ascii.toLowerCase(DOTS_MATCHER.replaceFrom(name, '.')); 139 140 if (name.endsWith(".")) { 141 name = name.substring(0, name.length() - 1); 142 } 143 144 checkArgument(name.length() <= MAX_LENGTH, "Domain name too long: '%s':", name); 145 this.name = name; 146 147 this.parts = ImmutableList.copyOf(DOT_SPLITTER.split(name)); 148 checkArgument(parts.size() <= MAX_PARTS, "Domain has too many parts: '%s'", name); 149 checkArgument(validateSyntax(parts), "Not a valid domain name: '%s'", name); 150 151 this.publicSuffixIndex = findSuffixOfType(Optional.<PublicSuffixType>absent()); 152 this.registrySuffixIndex = findSuffixOfType(Optional.of(PublicSuffixType.REGISTRY)); 153 } 154 155 /** 156 * Returns the index of the leftmost part of the suffix, or -1 if not found. Note that the value 157 * defined as a suffix may not produce {@code true} results from {@link #isPublicSuffix()} or 158 * {@link #isRegistrySuffix()} if the domain ends with an excluded domain pattern such as {@code 159 * "nhs.uk"}. 160 * 161 * <p>If a {@code desiredType} is specified, this method only finds suffixes of the given type. 162 * Otherwise, it finds the first suffix of any type. 163 */ 164 private int findSuffixOfType(Optional<PublicSuffixType> desiredType) { 165 final int partsSize = parts.size(); 166 167 for (int i = 0; i < partsSize; i++) { 168 String ancestorName = DOT_JOINER.join(parts.subList(i, partsSize)); 169 170 if (matchesType( 171 desiredType, Optional.fromNullable(PublicSuffixPatterns.EXACT.get(ancestorName)))) { 172 return i; 173 } 174 175 // Excluded domains (e.g. !nhs.uk) use the next highest 176 // domain as the effective public suffix (e.g. uk). 177 178 if (PublicSuffixPatterns.EXCLUDED.containsKey(ancestorName)) { 179 return i + 1; 180 } 181 182 if (matchesWildcardSuffixType(desiredType, ancestorName)) { 183 return i; 184 } 185 } 186 187 return NO_SUFFIX_FOUND; 188 } 189 190 /** 191 * Returns an instance of {@link InternetDomainName} after lenient validation. Specifically, 192 * validation against <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a> 193 * ("Internationalizing Domain Names in Applications") is skipped, while validation against <a 194 * href="http://www.ietf.org/rfc/rfc1035.txt">RFC 1035</a> is relaxed in the following ways: 195 * 196 * <ul> 197 * <li>Any part containing non-ASCII characters is considered valid. 198 * <li>Underscores ('_') are permitted wherever dashes ('-') are permitted. 199 * <li>Parts other than the final part may start with a digit, as mandated by <a 200 * href="https://tools.ietf.org/html/rfc1123#section-2">RFC 1123</a>. 201 * </ul> 202 * 203 * @param domain A domain name (not IP address) 204 * @throws IllegalArgumentException if {@code domain} is not syntactically valid according to 205 * {@link #isValid} 206 * @since 10.0 (previously named {@code fromLenient}) 207 */ 208 public static InternetDomainName from(String domain) { 209 return new InternetDomainName(checkNotNull(domain)); 210 } 211 212 /** 213 * Validation method used by {@code from} to ensure that the domain name is syntactically valid 214 * according to RFC 1035. 215 * 216 * @return Is the domain name syntactically valid? 217 */ 218 private static boolean validateSyntax(List<String> parts) { 219 final int lastIndex = parts.size() - 1; 220 221 // Validate the last part specially, as it has different syntax rules. 222 223 if (!validatePart(parts.get(lastIndex), true)) { 224 return false; 225 } 226 227 for (int i = 0; i < lastIndex; i++) { 228 String part = parts.get(i); 229 if (!validatePart(part, false)) { 230 return false; 231 } 232 } 233 234 return true; 235 } 236 237 private static final CharMatcher DASH_MATCHER = CharMatcher.anyOf("-_"); 238 239 private static final CharMatcher DIGIT_MATCHER = CharMatcher.inRange('0', '9'); 240 241 private static final CharMatcher LETTER_MATCHER = 242 CharMatcher.inRange('a', 'z').or(CharMatcher.inRange('A', 'Z')); 243 244 private static final CharMatcher PART_CHAR_MATCHER = 245 DIGIT_MATCHER.or(LETTER_MATCHER).or(DASH_MATCHER); 246 247 /** 248 * Helper method for {@link #validateSyntax(List)}. Validates that one part of a domain name is 249 * valid. 250 * 251 * @param part The domain name part to be validated 252 * @param isFinalPart Is this the final (rightmost) domain part? 253 * @return Whether the part is valid 254 */ 255 private static boolean validatePart(String part, boolean isFinalPart) { 256 257 // These tests could be collapsed into one big boolean expression, but 258 // they have been left as independent tests for clarity. 259 260 if (part.length() < 1 || part.length() > MAX_DOMAIN_PART_LENGTH) { 261 return false; 262 } 263 264 /* 265 * GWT claims to support java.lang.Character's char-classification methods, but it actually only 266 * works for ASCII. So for now, assume any non-ASCII characters are valid. The only place this 267 * seems to be documented is here: 268 * https://groups.google.com/d/topic/google-web-toolkit-contributors/1UEzsryq1XI 269 * 270 * <p>ASCII characters in the part are expected to be valid per RFC 1035, with underscore also 271 * being allowed due to widespread practice. 272 */ 273 274 String asciiChars = CharMatcher.ascii().retainFrom(part); 275 276 if (!PART_CHAR_MATCHER.matchesAllOf(asciiChars)) { 277 return false; 278 } 279 280 // No initial or final dashes or underscores. 281 282 if (DASH_MATCHER.matches(part.charAt(0)) 283 || DASH_MATCHER.matches(part.charAt(part.length() - 1))) { 284 return false; 285 } 286 287 /* 288 * Note that we allow (in contravention of a strict interpretation of the relevant RFCs) domain 289 * parts other than the last may begin with a digit (for example, "3com.com"). It's important to 290 * disallow an initial digit in the last part; it's the only thing that stops an IPv4 numeric 291 * address like 127.0.0.1 from looking like a valid domain name. 292 */ 293 294 if (isFinalPart && DIGIT_MATCHER.matches(part.charAt(0))) { 295 return false; 296 } 297 298 return true; 299 } 300 301 /** 302 * Returns the individual components of this domain name, normalized to all lower case. For 303 * example, for the domain name {@code mail.google.com}, this method returns the list {@code 304 * ["mail", "google", "com"]}. 305 */ 306 public ImmutableList<String> parts() { 307 return parts; 308 } 309 310 /** 311 * Indicates whether this domain name represents a <i>public suffix</i>, as defined by the Mozilla 312 * Foundation's <a href="http://publicsuffix.org/">Public Suffix List</a> (PSL). A public suffix 313 * is one under which Internet users can directly register names, such as {@code com}, {@code 314 * co.uk} or {@code pvt.k12.wy.us}. Examples of domain names that are <i>not</i> public suffixes 315 * include {@code google.com}, {@code foo.co.uk}, and {@code myblog.blogspot.com}. 316 * 317 * <p>Public suffixes are a proper superset of {@linkplain #isRegistrySuffix() registry suffixes}. 318 * The list of public suffixes additionally contains privately owned domain names under which 319 * Internet users can register subdomains. An example of a public suffix that is not a registry 320 * suffix is {@code blogspot.com}. Note that it is true that all public suffixes <i>have</i> 321 * registry suffixes, since domain name registries collectively control all internet domain names. 322 * 323 * <p>For considerations on whether the public suffix or registry suffix designation is more 324 * suitable for your application, see <a 325 * href="https://github.com/google/guava/wiki/InternetDomainNameExplained">this article</a>. 326 * 327 * @return {@code true} if this domain name appears exactly on the public suffix list 328 * @since 6.0 329 */ 330 public boolean isPublicSuffix() { 331 return publicSuffixIndex == 0; 332 } 333 334 /** 335 * Indicates whether this domain name ends in a {@linkplain #isPublicSuffix() public suffix}, 336 * including if it is a public suffix itself. For example, returns {@code true} for {@code 337 * www.google.com}, {@code foo.co.uk} and {@code com}, but not for {@code invalid} or {@code 338 * google.invalid}. This is the recommended method for determining whether a domain is potentially 339 * an addressable host. 340 * 341 * <p>Note that this method is equivalent to {@link #hasRegistrySuffix()} because all registry 342 * suffixes are public suffixes <i>and</i> all public suffixes have registry suffixes. 343 * 344 * @since 6.0 345 */ 346 public boolean hasPublicSuffix() { 347 return publicSuffixIndex != NO_SUFFIX_FOUND; 348 } 349 350 /** 351 * Returns the {@linkplain #isPublicSuffix() public suffix} portion of the domain name, or {@code 352 * null} if no public suffix is present. 353 * 354 * @since 6.0 355 */ 356 public InternetDomainName publicSuffix() { 357 return hasPublicSuffix() ? ancestor(publicSuffixIndex) : null; 358 } 359 360 /** 361 * Indicates whether this domain name ends in a {@linkplain #isPublicSuffix() public suffix}, 362 * while not being a public suffix itself. For example, returns {@code true} for {@code 363 * www.google.com}, {@code foo.co.uk} and {@code myblog.blogspot.com}, but not for {@code com}, 364 * {@code co.uk}, {@code google.invalid}, or {@code blogspot.com}. 365 * 366 * <p>This method can be used to determine whether it will probably be possible to set cookies on 367 * the domain, though even that depends on individual browsers' implementations of cookie 368 * controls. See <a href="http://www.ietf.org/rfc/rfc2109.txt">RFC 2109</a> for details. 369 * 370 * @since 6.0 371 */ 372 public boolean isUnderPublicSuffix() { 373 return publicSuffixIndex > 0; 374 } 375 376 /** 377 * Indicates whether this domain name is composed of exactly one subdomain component followed by a 378 * {@linkplain #isPublicSuffix() public suffix}. For example, returns {@code true} for {@code 379 * google.com} {@code foo.co.uk}, and {@code myblog.blogspot.com}, but not for {@code 380 * www.google.com}, {@code co.uk}, or {@code blogspot.com}. 381 * 382 * <p>This method can be used to determine whether a domain is probably the highest level for 383 * which cookies may be set, though even that depends on individual browsers' implementations of 384 * cookie controls. See <a href="http://www.ietf.org/rfc/rfc2109.txt">RFC 2109</a> for details. 385 * 386 * @since 6.0 387 */ 388 public boolean isTopPrivateDomain() { 389 return publicSuffixIndex == 1; 390 } 391 392 /** 393 * Returns the portion of this domain name that is one level beneath the {@linkplain 394 * #isPublicSuffix() public suffix}. For example, for {@code x.adwords.google.co.uk} it returns 395 * {@code google.co.uk}, since {@code co.uk} is a public suffix. Similarly, for {@code 396 * myblog.blogspot.com} it returns the same domain, {@code myblog.blogspot.com}, since {@code 397 * blogspot.com} is a public suffix. 398 * 399 * <p>If {@link #isTopPrivateDomain()} is true, the current domain name instance is returned. 400 * 401 * <p>This method can be used to determine the probable highest level parent domain for which 402 * cookies may be set, though even that depends on individual browsers' implementations of cookie 403 * controls. 404 * 405 * @throws IllegalStateException if this domain does not end with a public suffix 406 * @since 6.0 407 */ 408 public InternetDomainName topPrivateDomain() { 409 if (isTopPrivateDomain()) { 410 return this; 411 } 412 checkState(isUnderPublicSuffix(), "Not under a public suffix: %s", name); 413 return ancestor(publicSuffixIndex - 1); 414 } 415 416 /** 417 * Indicates whether this domain name represents a <i>registry suffix</i>, as defined by a subset 418 * of the Mozilla Foundation's <a href="http://publicsuffix.org/">Public Suffix List</a> (PSL). A 419 * registry suffix is one under which Internet users can directly register names via a domain name 420 * registrar, and have such registrations lawfully protected by internet-governing bodies such as 421 * ICANN. Examples of registry suffixes include {@code com}, {@code co.uk}, and {@code 422 * pvt.k12.wy.us}. Examples of domain names that are <i>not</i> registry suffixes include {@code 423 * google.com} and {@code foo.co.uk}. 424 * 425 * <p>Registry suffixes are a proper subset of {@linkplain #isPublicSuffix() public suffixes}. The 426 * list of public suffixes additionally contains privately owned domain names under which Internet 427 * users can register subdomains. An example of a public suffix that is not a registry suffix is 428 * {@code blogspot.com}. Note that it is true that all public suffixes <i>have</i> registry 429 * suffixes, since domain name registries collectively control all internet domain names. 430 * 431 * <p>For considerations on whether the public suffix or registry suffix designation is more 432 * suitable for your application, see <a 433 * href="https://github.com/google/guava/wiki/InternetDomainNameExplained">this article</a>. 434 * 435 * @return {@code true} if this domain name appears exactly on the public suffix list as part of 436 * the registry suffix section (labelled "ICANN"). 437 * @since 23.3 438 */ 439 public boolean isRegistrySuffix() { 440 return registrySuffixIndex == 0; 441 } 442 443 /** 444 * Indicates whether this domain name ends in a {@linkplain #isRegistrySuffix() registry suffix}, 445 * including if it is a registry suffix itself. For example, returns {@code true} for {@code 446 * www.google.com}, {@code foo.co.uk} and {@code com}, but not for {@code invalid} or {@code 447 * google.invalid}. 448 * 449 * <p>Note that this method is equivalent to {@link #hasPublicSuffix()} because all registry 450 * suffixes are public suffixes <i>and</i> all public suffixes have registry suffixes. 451 * 452 * @since 23.3 453 */ 454 public boolean hasRegistrySuffix() { 455 return registrySuffixIndex != NO_SUFFIX_FOUND; 456 } 457 458 /** 459 * Returns the {@linkplain #isRegistrySuffix() registry suffix} portion of the domain name, or 460 * {@code null} if no registry suffix is present. 461 * 462 * @since 23.3 463 */ 464 public InternetDomainName registrySuffix() { 465 return hasRegistrySuffix() ? ancestor(registrySuffixIndex) : null; 466 } 467 468 /** 469 * Indicates whether this domain name ends in a {@linkplain #isRegistrySuffix() registry suffix}, 470 * while not being a registry suffix itself. For example, returns {@code true} for {@code 471 * www.google.com}, {@code foo.co.uk} and {@code blogspot.com}, but not for {@code com}, {@code 472 * co.uk}, or {@code google.invalid}. 473 * 474 * @since 23.3 475 */ 476 public boolean isUnderRegistrySuffix() { 477 return registrySuffixIndex > 0; 478 } 479 480 /** 481 * Indicates whether this domain name is composed of exactly one subdomain component followed by a 482 * {@linkplain #isRegistrySuffix() registry suffix}. For example, returns {@code true} for {@code 483 * google.com}, {@code foo.co.uk}, and {@code blogspot.com}, but not for {@code www.google.com}, 484 * {@code co.uk}, or {@code myblog.blogspot.com}. 485 * 486 * <p><b>Warning:</b> This method should not be used to determine the probable highest level 487 * parent domain for which cookies may be set. Use {@link #topPrivateDomain()} for that purpose. 488 * 489 * @since 23.3 490 */ 491 public boolean isTopDomainUnderRegistrySuffix() { 492 return registrySuffixIndex == 1; 493 } 494 495 /** 496 * Returns the portion of this domain name that is one level beneath the {@linkplain 497 * #isRegistrySuffix() registry suffix}. For example, for {@code x.adwords.google.co.uk} it 498 * returns {@code google.co.uk}, since {@code co.uk} is a registry suffix. Similarly, for {@code 499 * myblog.blogspot.com} it returns {@code blogspot.com}, since {@code com} is a registry suffix. 500 * 501 * <p>If {@link #isTopDomainUnderRegistrySuffix()} is true, the current domain name instance is 502 * returned. 503 * 504 * <p><b>Warning:</b> This method should not be used to determine whether a domain is probably the 505 * highest level for which cookies may be set. Use {@link #isTopPrivateDomain()} for that purpose. 506 * 507 * @throws IllegalStateException if this domain does not end with a registry suffix 508 * @since 23.3 509 */ 510 public InternetDomainName topDomainUnderRegistrySuffix() { 511 if (isTopDomainUnderRegistrySuffix()) { 512 return this; 513 } 514 checkState(isUnderRegistrySuffix(), "Not under a registry suffix: %s", name); 515 return ancestor(registrySuffixIndex - 1); 516 } 517 518 /** Indicates whether this domain is composed of two or more parts. */ 519 public boolean hasParent() { 520 return parts.size() > 1; 521 } 522 523 /** 524 * Returns an {@code InternetDomainName} that is the immediate ancestor of this one; that is, the 525 * current domain with the leftmost part removed. For example, the parent of {@code 526 * www.google.com} is {@code google.com}. 527 * 528 * @throws IllegalStateException if the domain has no parent, as determined by {@link #hasParent} 529 */ 530 public InternetDomainName parent() { 531 checkState(hasParent(), "Domain '%s' has no parent", name); 532 return ancestor(1); 533 } 534 535 /** 536 * Returns the ancestor of the current domain at the given number of levels "higher" (rightward) 537 * in the subdomain list. The number of levels must be non-negative, and less than {@code N-1}, 538 * where {@code N} is the number of parts in the domain. 539 * 540 * <p>TODO: Reasonable candidate for addition to public API. 541 */ 542 private InternetDomainName ancestor(int levels) { 543 return from(DOT_JOINER.join(parts.subList(levels, parts.size()))); 544 } 545 546 /** 547 * Creates and returns a new {@code InternetDomainName} by prepending the argument and a dot to 548 * the current name. For example, {@code InternetDomainName.from("foo.com").child("www.bar")} 549 * returns a new {@code InternetDomainName} with the value {@code www.bar.foo.com}. Only lenient 550 * validation is performed, as described {@link #from(String) here}. 551 * 552 * @throws NullPointerException if leftParts is null 553 * @throws IllegalArgumentException if the resulting name is not valid 554 */ 555 public InternetDomainName child(String leftParts) { 556 return from(checkNotNull(leftParts) + "." + name); 557 } 558 559 /** 560 * Indicates whether the argument is a syntactically valid domain name using lenient validation. 561 * Specifically, validation against <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a> 562 * ("Internationalizing Domain Names in Applications") is skipped. 563 * 564 * <p>The following two code snippets are equivalent: 565 * 566 * <pre>{@code 567 * domainName = InternetDomainName.isValid(name) 568 * ? InternetDomainName.from(name) 569 * : DEFAULT_DOMAIN; 570 * }</pre> 571 * 572 * <pre>{@code 573 * try { 574 * domainName = InternetDomainName.from(name); 575 * } catch (IllegalArgumentException e) { 576 * domainName = DEFAULT_DOMAIN; 577 * } 578 * }</pre> 579 * 580 * @since 8.0 (previously named {@code isValidLenient}) 581 */ 582 public static boolean isValid(String name) { 583 try { 584 from(name); 585 return true; 586 } catch (IllegalArgumentException e) { 587 return false; 588 } 589 } 590 591 /** 592 * Does the domain name match one of the "wildcard" patterns (e.g. {@code "*.ar"})? If a {@code 593 * desiredType} is specified, the wildcard pattern must also match that type. 594 */ 595 private static boolean matchesWildcardSuffixType( 596 Optional<PublicSuffixType> desiredType, String domain) { 597 List<String> pieces = DOT_SPLITTER.limit(2).splitToList(domain); 598 return pieces.size() == 2 599 && matchesType( 600 desiredType, Optional.fromNullable(PublicSuffixPatterns.UNDER.get(pieces.get(1)))); 601 } 602 603 /** 604 * If a {@code desiredType} is specified, returns true only if the {@code actualType} is 605 * identical. Otherwise, returns true as long as {@code actualType} is present. 606 */ 607 private static boolean matchesType( 608 Optional<PublicSuffixType> desiredType, Optional<PublicSuffixType> actualType) { 609 return desiredType.isPresent() ? desiredType.equals(actualType) : actualType.isPresent(); 610 } 611 612 /** Returns the domain name, normalized to all lower case. */ 613 @Override 614 public String toString() { 615 return name; 616 } 617 618 /** 619 * Equality testing is based on the text supplied by the caller, after normalization as described 620 * in the class documentation. For example, a non-ASCII Unicode domain name and the Punycode 621 * version of the same domain name would not be considered equal. 622 */ 623 @Override 624 public boolean equals(@Nullable Object object) { 625 if (object == this) { 626 return true; 627 } 628 629 if (object instanceof InternetDomainName) { 630 InternetDomainName that = (InternetDomainName) object; 631 return this.name.equals(that.name); 632 } 633 634 return false; 635 } 636 637 @Override 638 public int hashCode() { 639 return name.hashCode(); 640 } 641}