Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / components / autofill / core / browser / address.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/autofill/core/browser/address.h"
6
7 #include <stddef.h>
8 #include <algorithm>
9
10 #include "base/basictypes.h"
11 #include "base/logging.h"
12 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "components/autofill/core/browser/autofill_country.h"
16 #include "components/autofill/core/browser/autofill_field.h"
17 #include "components/autofill/core/browser/autofill_type.h"
18
19 namespace autofill {
20
21 Address::Address() {}
22
23 Address::Address(const Address& address) : FormGroup() {
24   *this = address;
25 }
26
27 Address::~Address() {}
28
29 Address& Address::operator=(const Address& address) {
30   if (this == &address)
31     return *this;
32
33   street_address_ = address.street_address_;
34   dependent_locality_ = address.dependent_locality_;
35   city_ = address.city_;
36   state_ = address.state_;
37   country_code_ = address.country_code_;
38   zip_code_ = address.zip_code_;
39   sorting_code_ = address.sorting_code_;
40   return *this;
41 }
42
43 base::string16 Address::GetRawInfo(ServerFieldType type) const {
44   DCHECK_EQ(ADDRESS_HOME, AutofillType(type).group());
45   switch (type) {
46     case ADDRESS_HOME_LINE1:
47       return street_address_.size() > 0 ? street_address_[0] : base::string16();
48
49     case ADDRESS_HOME_LINE2:
50       return street_address_.size() > 1 ? street_address_[1] : base::string16();
51
52     case ADDRESS_HOME_LINE3:
53       return street_address_.size() > 2 ? street_address_[2] : base::string16();
54
55     case ADDRESS_HOME_DEPENDENT_LOCALITY:
56       return dependent_locality_;
57
58     case ADDRESS_HOME_CITY:
59       return city_;
60
61     case ADDRESS_HOME_STATE:
62       return state_;
63
64     case ADDRESS_HOME_ZIP:
65       return zip_code_;
66
67     case ADDRESS_HOME_SORTING_CODE:
68       return sorting_code_;
69
70     case ADDRESS_HOME_COUNTRY:
71       return base::ASCIIToUTF16(country_code_);
72
73     case ADDRESS_HOME_STREET_ADDRESS:
74       return JoinString(street_address_, '\n');
75
76     default:
77       NOTREACHED();
78       return base::string16();
79   }
80 }
81
82 void Address::SetRawInfo(ServerFieldType type, const base::string16& value) {
83   DCHECK_EQ(ADDRESS_HOME, AutofillType(type).group());
84   switch (type) {
85     case ADDRESS_HOME_LINE1:
86       if (street_address_.empty())
87         street_address_.resize(1);
88       street_address_[0] = value;
89       TrimStreetAddress();
90       break;
91
92     case ADDRESS_HOME_LINE2:
93       if (street_address_.size() < 2)
94         street_address_.resize(2);
95       street_address_[1] = value;
96       TrimStreetAddress();
97       break;
98
99     case ADDRESS_HOME_LINE3:
100       if (street_address_.size() < 3)
101         street_address_.resize(3);
102       street_address_[2] = value;
103       TrimStreetAddress();
104       break;
105
106     case ADDRESS_HOME_DEPENDENT_LOCALITY:
107       dependent_locality_ = value;
108       break;
109
110     case ADDRESS_HOME_CITY:
111       city_ = value;
112       break;
113
114     case ADDRESS_HOME_STATE:
115       state_ = value;
116       break;
117
118     case ADDRESS_HOME_COUNTRY:
119       DCHECK(value.empty() ||
120              (value.length() == 2u && base::IsStringASCII(value)));
121       country_code_ = base::UTF16ToASCII(value);
122       break;
123
124     case ADDRESS_HOME_ZIP:
125       zip_code_ = value;
126       break;
127
128     case ADDRESS_HOME_SORTING_CODE:
129       sorting_code_ = value;
130       break;
131
132     case ADDRESS_HOME_STREET_ADDRESS:
133       base::SplitString(value, base::char16('\n'), &street_address_);
134       break;
135
136     default:
137       NOTREACHED();
138   }
139 }
140
141 base::string16 Address::GetInfo(const AutofillType& type,
142                                 const std::string& app_locale) const {
143   if (type.html_type() == HTML_TYPE_COUNTRY_CODE)
144     return base::ASCIIToUTF16(country_code_);
145
146   ServerFieldType storable_type = type.GetStorableType();
147   if (storable_type == ADDRESS_HOME_COUNTRY && !country_code_.empty())
148     return AutofillCountry(country_code_, app_locale).name();
149
150   return GetRawInfo(storable_type);
151 }
152
153 bool Address::SetInfo(const AutofillType& type,
154                       const base::string16& value,
155                       const std::string& app_locale) {
156   if (type.html_type() == HTML_TYPE_COUNTRY_CODE) {
157     if (!value.empty() && (value.size() != 2u || !base::IsStringASCII(value))) {
158       country_code_ = std::string();
159       return false;
160     }
161
162     country_code_ = StringToUpperASCII(base::UTF16ToASCII(value));
163     return true;
164   } else if (type.html_type() == HTML_TYPE_FULL_ADDRESS) {
165     // Parsing a full address is too hard.
166     return false;
167   }
168
169   ServerFieldType storable_type = type.GetStorableType();
170   if (storable_type == ADDRESS_HOME_COUNTRY && !value.empty()) {
171     country_code_ = AutofillCountry::GetCountryCode(value, app_locale);
172     return !country_code_.empty();
173   }
174
175   SetRawInfo(storable_type, value);
176
177   // Give up when importing addresses with any entirely blank lines.
178   // There's a good chance that this formatting is not intentional, but it's
179   // also not obviously safe to just strip the newlines.
180   if (storable_type == ADDRESS_HOME_STREET_ADDRESS &&
181       std::find(street_address_.begin(), street_address_.end(),
182                 base::string16()) != street_address_.end()) {
183     street_address_.clear();
184     return false;
185   }
186
187   return true;
188 }
189
190 void Address::GetMatchingTypes(const base::string16& text,
191                                const std::string& app_locale,
192                                ServerFieldTypeSet* matching_types) const {
193   FormGroup::GetMatchingTypes(text, app_locale, matching_types);
194
195   // Check to see if the |text| canonicalized as a country name is a match.
196   std::string country_code = AutofillCountry::GetCountryCode(text, app_locale);
197   if (!country_code.empty() && country_code_ == country_code)
198     matching_types->insert(ADDRESS_HOME_COUNTRY);
199 }
200
201 void Address::GetSupportedTypes(ServerFieldTypeSet* supported_types) const {
202   supported_types->insert(ADDRESS_HOME_LINE1);
203   supported_types->insert(ADDRESS_HOME_LINE2);
204   supported_types->insert(ADDRESS_HOME_LINE3);
205   supported_types->insert(ADDRESS_HOME_STREET_ADDRESS);
206   supported_types->insert(ADDRESS_HOME_DEPENDENT_LOCALITY);
207   supported_types->insert(ADDRESS_HOME_CITY);
208   supported_types->insert(ADDRESS_HOME_STATE);
209   supported_types->insert(ADDRESS_HOME_ZIP);
210   supported_types->insert(ADDRESS_HOME_SORTING_CODE);
211   supported_types->insert(ADDRESS_HOME_COUNTRY);
212 }
213
214 void Address::TrimStreetAddress() {
215   while (!street_address_.empty() && street_address_.back().empty()) {
216     street_address_.pop_back();
217   }
218 }
219
220 }  // namespace autofill