18a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// Copyright (c) 2011 The Chromium Authors. All rights reserved.
28a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// Use of this source code is governed by a BSD-style license that can be
38a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// found in the LICENSE file.
48a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
58a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "chrome/browser/autofill/address.h"
68a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
78a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include <stddef.h>
88a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
98a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "base/basictypes.h"
108a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "base/logging.h"
118a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "base/string_util.h"
128a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "chrome/browser/autofill/autofill_country.h"
138a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "chrome/browser/autofill/autofill_type.h"
148a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "chrome/browser/autofill/field_types.h"
158a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
168a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocknamespace {
178a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
188a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockconst char16 kAddressSplitChars[] = {'-', ',', '#', '.', ' ', 0};
198a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
208a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockconst AutofillType::FieldTypeSubGroup kAutofillAddressTypes[] = {
218a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  AutofillType::ADDRESS_LINE1,
228a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  AutofillType::ADDRESS_LINE2,
238a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  AutofillType::ADDRESS_CITY,
248a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  AutofillType::ADDRESS_STATE,
258a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  AutofillType::ADDRESS_ZIP,
268a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  AutofillType::ADDRESS_COUNTRY,
278a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block};
288a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
298a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockconst int kAutofillAddressLength = arraysize(kAutofillAddressTypes);
308a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
318a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}  // namespace
328a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
338a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve BlockAddress::Address() {}
34ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
358a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve BlockAddress::Address(const Address& address) : FormGroup() {
368a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  *this = address;
378a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
38ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
39ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve BlockAddress::~Address() {}
408a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
418a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve BlockAddress& Address::operator=(const Address& address) {
428a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  if (this == &address)
438a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    return *this;
44ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
458a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  line1_tokens_ = address.line1_tokens_;
468a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  line2_tokens_= address.line2_tokens_;
478a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  line1_ = address.line1_;
488a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  line2_ = address.line2_;
49ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block  city_ = address.city_;
508a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  state_ = address.state_;
51ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block  country_code_ = address.country_code_;
52ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block  zip_code_ = address.zip_code_;
53ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block  return *this;
54ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
558a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
56ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockvoid Address::GetPossibleFieldTypes(const string16& text,
57ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block                                    FieldTypeSet* possible_types) const {
588a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  DCHECK(possible_types);
59ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
60967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch  // If the text to match against the field types is empty, then no results will
61967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch  // match.
62967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch  if (text.empty())
630617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    return;
640617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
650617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen  if (IsLine1(text))
66ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    possible_types->insert(ADDRESS_HOME_LINE1);
678a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
688a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  if (IsLine2(text))
69967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    possible_types->insert(ADDRESS_HOME_LINE2);
70967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
71967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch  if (IsCity(text))
72ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    possible_types->insert(ADDRESS_HOME_CITY);
73dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
74ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block  if (IsState(text))
75545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    possible_types->insert(ADDRESS_HOME_STATE);
76dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
77dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch  if (IsZipCode(text))
78dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    possible_types->insert(ADDRESS_HOME_ZIP);
79dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
80dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch  if (IsCountry(text))
816b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    possible_types->insert(ADDRESS_HOME_COUNTRY);
82ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
83ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
84ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockvoid Address::GetAvailableFieldTypes(FieldTypeSet* available_types) const {
85ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block  DCHECK(available_types);
86ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
87ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block  if (!line1_.empty())
88ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    available_types->insert(ADDRESS_HOME_LINE1);
89ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
90545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch  if (!line2_.empty())
91545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    available_types->insert(ADDRESS_HOME_LINE2);
92ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
93ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block  if (!city_.empty())
94ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    available_types->insert(ADDRESS_HOME_CITY);
95ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
96ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block  if (!state_.empty())
97ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    available_types->insert(ADDRESS_HOME_STATE);
98ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
99ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block  if (!zip_code_.empty())
100ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    available_types->insert(ADDRESS_HOME_ZIP);
101ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
102ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block  if (!country_code_.empty())
103dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    available_types->insert(ADDRESS_HOME_COUNTRY);
1048a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
1058a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1068a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockstring16 Address::GetInfo(AutofillFieldType type) const {
1070617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen  if (type == ADDRESS_HOME_LINE1)
108967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    return line1_;
109545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
1108a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  if (type == ADDRESS_HOME_LINE2)
1118a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    return line2_;
112545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
1130617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen  if (type == ADDRESS_HOME_CITY)
114967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    return city_;
115545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
1168a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  if (type == ADDRESS_HOME_STATE)
1178a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    return state_;
118967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
119967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch  if (type ==  ADDRESS_HOME_ZIP)
120967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    return zip_code_;
121967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
122ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block  if (type == ADDRESS_HOME_COUNTRY)
123ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    return Country();
124ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
125ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block  return string16();
126ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
127ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
128ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockvoid Address::SetInfo(AutofillFieldType type, const string16& value) {
1296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner  FieldTypeSubGroup subgroup = AutofillType(type).subgroup();
1306b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner  if (subgroup == AutofillType::ADDRESS_LINE1)
1310617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    set_line1(value);
132dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch  else if (subgroup == AutofillType::ADDRESS_LINE2)
133dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    set_line2(value);
134dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch  else if (subgroup == AutofillType::ADDRESS_CITY)
135967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    city_ = value;
136545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch  else if (subgroup == AutofillType::ADDRESS_STATE)
137545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    state_ = value;
138545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch  else if (subgroup == AutofillType::ADDRESS_COUNTRY)
139ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    SetCountry(value);
140ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block  else if (subgroup == AutofillType::ADDRESS_ZIP)
141ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    zip_code_ = value;
142ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block  else
143ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    NOTREACHED();
1446b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner}
1456b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
1468a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockvoid Address::Clear() {
1478a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  line1_tokens_.clear();
1488a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  line1_.clear();
1498a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  line2_tokens_.clear();
1508a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block  line2_.clear();
151  city_.clear();
152  state_.clear();
153  country_code_.clear();
154  zip_code_.clear();
155}
156
157string16 Address::Country() const {
158  if (country_code().empty())
159    return string16();
160
161  std::string app_locale = AutofillCountry::ApplicationLocale();
162  return AutofillCountry(country_code(), app_locale).name();
163}
164
165void Address::set_line1(const string16& line1) {
166  line1_ = line1;
167  line1_tokens_.clear();
168  Tokenize(line1, kAddressSplitChars, &line1_tokens_);
169  LineTokens::iterator iter;
170  for (iter = line1_tokens_.begin(); iter != line1_tokens_.end(); ++iter)
171    *iter = StringToLowerASCII(*iter);
172}
173
174void Address::set_line2(const string16& line2) {
175  line2_ = line2;
176  line2_tokens_.clear();
177  Tokenize(line2, kAddressSplitChars, &line2_tokens_);
178  LineTokens::iterator iter;
179  for (iter = line2_tokens_.begin(); iter != line2_tokens_.end(); ++iter)
180    *iter = StringToLowerASCII(*iter);
181}
182
183void Address::SetCountry(const string16& country) {
184  std::string app_locale = AutofillCountry::ApplicationLocale();
185  country_code_ = AutofillCountry::GetCountryCode(country, app_locale);
186}
187
188bool Address::IsLine1(const string16& text) const {
189  return IsLineMatch(text, line1_tokens_);
190}
191
192bool Address::IsLine2(const string16& text) const {
193  return IsLineMatch(text, line2_tokens_);
194}
195
196bool Address::IsCity(const string16& text) const {
197  return (StringToLowerASCII(city_) == StringToLowerASCII(text));
198}
199
200bool Address::IsState(const string16& text) const {
201  return (StringToLowerASCII(state_) == StringToLowerASCII(text));
202}
203
204bool Address::IsCountry(const string16& text) const {
205  std::string app_locale = AutofillCountry::ApplicationLocale();
206  std::string country_code = AutofillCountry::GetCountryCode(text, app_locale);
207  return (!country_code.empty() && country_code_ == country_code);
208}
209
210bool Address::IsZipCode(const string16& text) const {
211  return zip_code_ == text;
212}
213
214bool Address::IsLineMatch(const string16& text,
215                          const LineTokens& line_tokens) const {
216  size_t line_tokens_size = line_tokens.size();
217  if (line_tokens_size == 0)
218    return false;
219
220  LineTokens text_tokens;
221  Tokenize(text, kAddressSplitChars, &text_tokens);
222  size_t text_tokens_size = text_tokens.size();
223  if (text_tokens_size == 0)
224    return false;
225
226  if (text_tokens_size > line_tokens_size)
227    return false;
228
229  // If each of the 'words' contained in the text are also present in the line,
230  // then we will consider the text to match the line.
231  LineTokens::iterator iter;
232  for (iter = text_tokens.begin(); iter != text_tokens.end(); ++iter) {
233    if (!IsWordInLine(*iter, line_tokens))
234      return false;
235  }
236
237  return true;
238}
239
240bool Address::IsWordInLine(const string16& word,
241                           const LineTokens& line_tokens) const {
242  LineTokens::const_iterator iter;
243  for (iter = line_tokens.begin(); iter != line_tokens.end(); ++iter) {
244    if (StringToLowerASCII(word) == *iter)
245      return true;
246  }
247
248  return false;
249}
250