152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia/*
2ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia * Copyright (C) 2011 The Libphonenumber Authors
352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia *
452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * Licensed under the Apache License, Version 2.0 (the "License");
552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * you may not use this file except in compliance with the License.
652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * You may obtain a copy of the License at
752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia *
852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * http://www.apache.org/licenses/LICENSE-2.0
952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia *
1052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * Unless required by applicable law or agreed to in writing, software
1152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * distributed under the License is distributed on an "AS IS" BASIS,
1252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * See the License for the specific language governing permissions and
1452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * limitations under the License.
1552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia */
1652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia
17a77faddfc3b3e4cca8f585c82d669054aec221f4Narayan Kamathpackage com.google.i18n.phonenumbers;
1852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia
19a77faddfc3b3e4cca8f585c82d669054aec221f4Narayan Kamathimport com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
2052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia
2152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jiaimport java.util.Arrays;
2252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia
2352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia/**
2452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * The immutable match of a phone number within a piece of text. Matches may be found using
2552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * {@link PhoneNumberUtil#findNumbers}.
2652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia *
2752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * <p>A match consists of the {@linkplain #number() phone number} as well as the
2852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * {@linkplain #start() start} and {@linkplain #end() end} offsets of the corresponding subsequence
2952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * of the searched text. Use {@link #rawString()} to obtain a copy of the matched subsequence.
3052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia *
3152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * <p>The following annotated example clarifies the relationship between the searched text, the
3252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * match offsets, and the parsed number:
3352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia
3452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * <pre>
3552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * CharSequence text = "Call me at +1 425 882-8080 for details.";
3652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * RegionCode country = RegionCode.US;
3752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * PhoneNumberUtil util = PhoneNumberUtil.getInstance();
3852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia *
3952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * // Find the first phone number match:
4052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * PhoneNumberMatch m = util.findNumbers(text, country).iterator().next();
4152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia *
4252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * // rawString() contains the phone number as it appears in the text.
4352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * "+1 425 882-8080".equals(m.rawString());
4452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia *
4552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * // start() and end() define the range of the matched subsequence.
4652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * CharSequence subsequence = text.subSequence(m.start(), m.end());
4752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * "+1 425 882-8080".contentEquals(subsequence);
4852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia *
4952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * // number() returns the the same result as PhoneNumberUtil.{@link PhoneNumberUtil#parse parse()}
5052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * // invoked on rawString().
5152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * util.parse(m.rawString(), country).equals(m.number());
5252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * </pre>
5352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia */
5452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jiapublic final class PhoneNumberMatch {
5552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  /** The start index into the text. */
5652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  private final int start;
5752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  /** The raw substring matched. */
58d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia  private final String rawString;
5952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  /** The matched phone number. */
6052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  private final PhoneNumber number;
6152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia
6252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  /**
6352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia   * Creates a new match.
6452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia   *
6552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia   * @param start  the start index into the target text
66d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia   * @param rawString  the matched substring of the target text
6752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia   * @param number  the matched phone number
6852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia   */
69d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia  PhoneNumberMatch(int start, String rawString, PhoneNumber number) {
7052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia    if (start < 0) {
7152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia      throw new IllegalArgumentException("Start index must be >= 0.");
7252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia    }
73d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia    if (rawString == null || number == null) {
7452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia      throw new NullPointerException();
7552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia    }
7652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia    this.start = start;
77d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia    this.rawString = rawString;
7852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia    this.number = number;
7952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  }
8052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia
8152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  /** Returns the phone number matched by the receiver. */
8252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  public PhoneNumber number() {
8352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia    return number;
8452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  }
8552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia
8652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  /** Returns the start index of the matched phone number within the searched text. */
8752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  public int start() {
8852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia    return start;
8952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  }
9052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia
9152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  /** Returns the exclusive end index of the matched phone number within the searched text. */
9252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  public int end() {
93d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia    return start + rawString.length();
9452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  }
9552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia
9652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  /** Returns the raw string matched as a phone number in the searched text. */
9752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  public String rawString() {
98d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia    return rawString;
9952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  }
10052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia
10152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  @Override
10252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  public int hashCode() {
103d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia    return Arrays.hashCode(new Object[]{start, rawString, number});
10452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  }
10552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia
10652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  @Override
10752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  public boolean equals(Object obj) {
10852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia    if (this == obj) {
10952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia      return true;
11052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia    }
11152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia    if (!(obj instanceof PhoneNumberMatch)) {
11252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia      return false;
11352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia    }
11452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia    PhoneNumberMatch other = (PhoneNumberMatch) obj;
115d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia    return rawString.equals(other.rawString) && (start == other.start) &&
116d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia        number.equals(other.number);
11752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  }
11852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia
11952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  @Override
12052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  public String toString() {
121d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia    return "PhoneNumberMatch [" + start() + "," + end() + ") " + rawString;
12252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia  }
12352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia}
124