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