Package com.google.common.net

Source Code of com.google.common.net.HostSpecifier

/*
* Copyright (C) 2009 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.common.net;

import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;

import java.net.InetAddress;
import java.text.ParseException;

import javax.annotation.Nullable;

/**
* A syntactically valid host specifier, suitable for use in a URI.
* This may be either a numeric IP address in IPv4 or IPv6 notation, or a
* domain name.
*
* <p>Because this class is intended to represent host specifiers which can
* reasonably be used in a URI, the domain name case is further restricted to
* include only those domain names which end in a recognized public suffix; see
* {@link InternetDomainName#isPublicSuffix()} for details.
*
* <p>Note that no network lookups are performed by any {@code HostSpecifier}
* methods.  No attempt is made to verify that a provided specifier corresponds
* to a real or accessible host.  Only syntactic and pattern-based checks are
* performed.
*
* <p>If you know that a given string represents a numeric IP address, use
* {@link InetAddresses} to obtain and manipulate a
* {@link java.net.InetAddress} instance from it rather than using this class.
* Similarly, if you know that a given string represents a domain name, use
* {@link InternetDomainName} rather than this class.
*
* @author Craig Berry
* @since Guava release 05
*/
@Beta
public final class HostSpecifier {

  private final String canonicalForm;

  private HostSpecifier(String canonicalForm) {
    this.canonicalForm = canonicalForm;
  }

  /**
   * Returns a {@code HostSpecifier} built from the provided {@code specifier},
   * which is already known to be valid.  If the {@code specifier} might be
   * invalid, use {@link #from(String)} instead.
   *
   * <p>The specifier must be in one of these formats:
   * <ul>
   * <li>A domain name, like {@code google.com}
   * <li>A IPv4 address string, like {@code 127.0.0.1}
   * <li>An IPv6 address string with or without brackets, like
   *     {@code [2001:db8::1]} or {@code 2001:db8::1}
   * <li>An IPv6 address string enclosed in square brackets, like
   *     {[2001:db8::1]}
   * </ul>
   *
   * @throws IllegalArgumentException if the specifier is not valid.
   */
  public static HostSpecifier fromValid(String specifier) {
    // Verify that no port was specified, and strip optional brackets from
    // IPv6 literals.
    final HostAndPort parsedHost = HostAndPort.fromString(specifier);
    Preconditions.checkArgument(!parsedHost.hasPort());
    final String host = parsedHost.getHostText();

    // Try to interpret the specifier as an IP address.  Note we build
    // the address rather than using the .is* methods because we want to
    // use InetAddresses.toUriString to convert the result to a string in
    // canonical form.
    InetAddress addr = null;
    try {
      addr = InetAddresses.forString(host);
    } catch (IllegalArgumentException e) {
      // It is not an IPv4 or IPv6 literal
    }

    if (addr != null) {
      return new HostSpecifier(InetAddresses.toUriString(addr));
    }

    // It is not any kind of IP address; must be a domain name or invalid.

    // TODO(user): different versions of this for different factories?
    final InternetDomainName domain = InternetDomainName.from(host);

    if (domain.hasPublicSuffix()) {
      return new HostSpecifier(domain.name());
    }

    throw new IllegalArgumentException(
        "Domain name does not have a recognized public suffix: " + host);
  }

  /**
   * Attempts to return a {@code HostSpecifier} for the given string, throwing
   * an exception if parsing fails. Always use this method in preference to
   * {@link #fromValid(String)} for a specifier that is not already known to be
   * valid.
   *
   * @throws ParseException if the specifier is not valid.
   */
  public static HostSpecifier from(String specifier)
      throws ParseException {
    try {
      return fromValid(specifier);
    } catch (IllegalArgumentException e) {
      // Since the IAE can originate at several different points inside
      // fromValid(), we implement this method in terms of that one rather
      // than the reverse.

      ParseException parseException =
          new ParseException("Invalid host specifier: " + specifier, 0);
      parseException.initCause(e);
      throw parseException;
    }
  }

  /**
   * Determines whether {@code specifier} represents a valid
   * {@link HostSpecifier} as described in the documentation for
   * {@link #fromValid(String)}.
   */
  public static boolean isValid(String specifier) {
    try {
      fromValid(specifier);
      return true;
    } catch (IllegalArgumentException e) {
      return false;
    }
  }

  @Override
  public boolean equals(@Nullable Object other) {
    if (this == other) {
      return true;
    }

    if (other instanceof HostSpecifier) {
      final HostSpecifier that = (HostSpecifier) other;
      return this.canonicalForm.equals(that.canonicalForm);
    }

    return false;
  }

  @Override
  public int hashCode() {
    return canonicalForm.hashCode();
  }

  /**
   * Returns a string representation of the host specifier suitable for
   * inclusion in a URI.  If the host specifier is a domain name, the
   * string will be normalized to all lower case.  If the specifier was
   * an IPv6 address without brackets, brackets are added so that the
   * result will be usable in the host part of a URI.
   */
  @Override
  public String toString() {
    return canonicalForm;
  }
}
TOP

Related Classes of com.google.common.net.HostSpecifier

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.