Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(573)

Side by Side Diff: third_party/libaddressinput/chromium/cpp/src/address_validator.cc

Issue 116363003: [rac] Validate an address. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Constify and remove .get() Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (C) 2013 Google Inc. 1 // Copyright (C) 2013 Google Inc.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 #include <libaddressinput/address_validator.h> 15 #include <libaddressinput/address_validator.h>
16 16
17 #include <libaddressinput/address_data.h>
17 #include <libaddressinput/downloader.h> 18 #include <libaddressinput/downloader.h>
18 #include <libaddressinput/load_rules_delegate.h> 19 #include <libaddressinput/load_rules_delegate.h>
19 #include <libaddressinput/localization.h> 20 #include <libaddressinput/localization.h>
20 #include <libaddressinput/storage.h> 21 #include <libaddressinput/storage.h>
21 #include <libaddressinput/util/basictypes.h> 22 #include <libaddressinput/util/basictypes.h>
22 #include <libaddressinput/util/scoped_ptr.h> 23 #include <libaddressinput/util/scoped_ptr.h>
23 24
25 #include <algorithm>
24 #include <cassert> 26 #include <cassert>
25 #include <cstddef> 27 #include <cstddef>
26 #include <map> 28 #include <map>
27 #include <set> 29 #include <set>
28 #include <string> 30 #include <string>
29 31
32 #include <re2/re2.h>
33
30 #include "country_rules_aggregator.h" 34 #include "country_rules_aggregator.h"
35 #include "messages.h"
31 #include "retriever.h" 36 #include "retriever.h"
37 #include "rule.h"
32 #include "ruleset.h" 38 #include "ruleset.h"
33 #include "util/stl_util.h" 39 #include "util/stl_util.h"
34 40
35 namespace i18n { 41 namespace i18n {
36 namespace addressinput { 42 namespace addressinput {
37 43
38 namespace { 44 namespace {
39 45
46 // Returns true if the filter is empty (all problems allowed) or contains the
47 // |field|->|problem| mapping (explicitly allowed).
48 bool FilterAllows(const AddressProblemFilter& filter,
49 AddressField field,
50 AddressProblem::Type problem) {
51 if (filter.empty()) {
52 return true;
53 }
54
55 for (AddressProblemFilter::const_iterator it = filter.begin();
56 it != filter.end(); ++it) {
57 if (it->first == field && it->second == problem) {
58 return true;
59 }
60 }
61
62 return false;
63 }
64
40 // Validates AddressData structure. 65 // Validates AddressData structure.
41 class AddressValidatorImpl : public AddressValidator { 66 class AddressValidatorImpl : public AddressValidator {
42 public: 67 public:
43 // Takes ownership of |downloader| and |storage|. Does not take ownership of 68 // Takes ownership of |downloader| and |storage|. Does not take ownership of
44 // |load_rules_delegate|. 69 // |load_rules_delegate|.
45 AddressValidatorImpl(scoped_ptr<const Downloader> downloader, 70 AddressValidatorImpl(scoped_ptr<const Downloader> downloader,
46 scoped_ptr<Storage> storage, 71 scoped_ptr<Storage> storage,
47 LoadRulesDelegate* load_rules_delegate) 72 LoadRulesDelegate* load_rules_delegate)
48 : aggregator_(scoped_ptr<Retriever>(new Retriever( 73 : aggregator_(scoped_ptr<Retriever>(new Retriever(
49 VALIDATION_DATA_URL, 74 VALIDATION_DATA_URL,
(...skipping 17 matching lines...) Expand all
67 BuildScopedPtrCallback(this, &AddressValidatorImpl::OnRulesLoaded)); 92 BuildScopedPtrCallback(this, &AddressValidatorImpl::OnRulesLoaded));
68 } 93 }
69 } 94 }
70 95
71 // AddressValidator implementation. 96 // AddressValidator implementation.
72 virtual Status ValidateAddress( 97 virtual Status ValidateAddress(
73 const AddressData& address, 98 const AddressData& address,
74 const AddressProblemFilter& filter, 99 const AddressProblemFilter& filter,
75 const Localization& localization, 100 const Localization& localization,
76 AddressProblems* problems) const { 101 AddressProblems* problems) const {
77 // TODO(rouslan): Validate the address. 102 std::map<std::string, const Ruleset*>::const_iterator ruleset_it =
78 return RULES_UNAVAILABLE; 103 rules_.find(address.country_code);
104 if (ruleset_it == rules_.end()) {
105 return loading_rules_.find(address.country_code) != loading_rules_.end()
106 ? RULES_NOT_READY
107 : RULES_UNAVAILABLE;
108 }
109
110 const Ruleset* ruleset = ruleset_it->second;
111 assert(ruleset != NULL);
112 const Rule& country_rule =
113 ruleset->GetLanguageCodeRule(address.language_code);
114
115 // Validate required fields.
116 for (std::vector<AddressField>::const_iterator
117 field_it = country_rule.GetRequired().begin();
118 field_it != country_rule.GetRequired().end();
119 ++field_it) {
120 if (address.GetField(*field_it).empty() &&
121 FilterAllows(
122 filter, *field_it, AddressProblem::MISSING_REQUIRED_FIELD)) {
123 problems->push_back(AddressProblem(
124 *field_it,
125 AddressProblem::MISSING_REQUIRED_FIELD,
126 localization.GetString(
127 IDS_LIBADDRESSINPUT_I18N_MISSING_REQUIRED_FIELD)));
128 }
129 }
130
131 // Validate general postal code format. A country-level rule specifies the
132 // regular expression for the whole postal code.
133 if (!address.postal_code.empty() &&
134 !country_rule.GetPostalCodeFormat().empty() &&
135 FilterAllows(filter,
136 POSTAL_CODE,
137 AddressProblem::UNRECOGNIZED_FORMAT) &&
138 !RE2::FullMatch(
139 address.postal_code, country_rule.GetPostalCodeFormat())) {
140 problems->push_back(AddressProblem(
141 POSTAL_CODE,
142 AddressProblem::UNRECOGNIZED_FORMAT,
143 localization.GetString(
144 country_rule.GetInvalidPostalCodeMessageId())));
145 }
146
147 while (ruleset != NULL) {
148 const Rule& rule = ruleset->GetLanguageCodeRule(address.language_code);
149
150 // Validate the field values, e.g. state names in US.
151 AddressField sub_field_type =
152 static_cast<AddressField>(ruleset->field() + 1);
153 const std::string& sub_field = address.GetField(sub_field_type);
154 const std::vector<std::string>& sub_keys = rule.GetSubKeys();
155 if (!sub_field.empty() &&
156 !sub_keys.empty() &&
157 FilterAllows(filter, sub_field_type, AddressProblem::UNKNOWN_VALUE) &&
158 std::find(sub_keys.begin(), sub_keys.end(), sub_field) ==
159 sub_keys.end()) {
160 problems->push_back(AddressProblem(
161 sub_field_type,
162 AddressProblem::UNKNOWN_VALUE,
163 localization.GetString(
164 country_rule.GetInvalidFieldMessageId(sub_field_type))));
165 }
166
167 // Validate sub-region specific postal code format. A sub-region specifies
168 // the regular expression for a prefix of the postal code.
169 int match_position = -1;
170 if (ruleset->field() > COUNTRY &&
171 !address.postal_code.empty() &&
172 !rule.GetPostalCodeFormat().empty() &&
173 FilterAllows(filter,
174 POSTAL_CODE,
175 AddressProblem::MISMATCHING_VALUE) &&
176 (!RE2::PartialMatch(address.postal_code,
177 rule.GetPostalCodeFormat(),
178 &match_position) ||
179 match_position != 0)) {
180 problems->push_back(AddressProblem(
181 POSTAL_CODE,
182 AddressProblem::MISMATCHING_VALUE,
183 localization.GetString(
184 country_rule.GetInvalidPostalCodeMessageId())));
185 }
186
187 ruleset = ruleset->GetSubRegionRuleset(sub_field);
188 }
189
190 return SUCCESS;
79 } 191 }
80 192
81 private: 193 private:
82 // Called when CountryRulesAggregator::AggregateRules loads the |ruleset| for 194 // Called when CountryRulesAggregator::AggregateRules loads the |ruleset| for
83 // the |country_code|. 195 // the |country_code|.
84 void OnRulesLoaded(bool success, 196 void OnRulesLoaded(bool success,
85 const std::string& country_code, 197 const std::string& country_code,
86 scoped_ptr<Ruleset> ruleset) { 198 scoped_ptr<Ruleset> ruleset) {
87 assert(rules_.find(country_code) == rules_.end()); 199 assert(rules_.find(country_code) == rules_.end());
88 loading_rules_.erase(country_code); 200 loading_rules_.erase(country_code);
89 if (success) { 201 if (success) {
202 assert(ruleset != NULL);
203 assert(ruleset->field() == COUNTRY);
90 rules_[country_code] = ruleset.release(); 204 rules_[country_code] = ruleset.release();
91 } 205 }
92 if (load_rules_delegate_ != NULL) { 206 if (load_rules_delegate_ != NULL) {
93 load_rules_delegate_->OnAddressValidationRulesLoaded( 207 load_rules_delegate_->OnAddressValidationRulesLoaded(
94 country_code, success); 208 country_code, success);
95 } 209 }
96 } 210 }
97 211
98 // Loads the ruleset for a country code. 212 // Loads the ruleset for a country code.
99 CountryRulesAggregator aggregator_; 213 CountryRulesAggregator aggregator_;
100 214
101 // An optional delegate to be invoked when a ruleset finishes loading. 215 // An optional delegate to be invoked when a ruleset finishes loading.
102 LoadRulesDelegate* load_rules_delegate_; 216 LoadRulesDelegate* load_rules_delegate_;
103 217
104 // A set of country codes for which a ruleset is being loaded. 218 // A set of country codes for which a ruleset is being loaded.
105 std::set<std::string> loading_rules_; 219 std::set<std::string> loading_rules_;
106 220
107 // A mapping of a country code to the owned ruleset for that country code. 221 // A mapping of a country code to the owned ruleset for that country code.
108 std::map<std::string, Ruleset*> rules_; 222 std::map<std::string, const Ruleset*> rules_;
109 223
110 DISALLOW_COPY_AND_ASSIGN(AddressValidatorImpl); 224 DISALLOW_COPY_AND_ASSIGN(AddressValidatorImpl);
111 }; 225 };
112 226
113 } // namespace 227 } // namespace
114 228
115 AddressValidator::~AddressValidator() {} 229 AddressValidator::~AddressValidator() {}
116 230
117 // static 231 // static
118 scoped_ptr<AddressValidator> AddressValidator::Build( 232 scoped_ptr<AddressValidator> AddressValidator::Build(
119 scoped_ptr<const Downloader> downloader, 233 scoped_ptr<const Downloader> downloader,
120 scoped_ptr<Storage> storage, 234 scoped_ptr<Storage> storage,
121 LoadRulesDelegate* load_rules_delegate) { 235 LoadRulesDelegate* load_rules_delegate) {
122 return scoped_ptr<AddressValidator>(new AddressValidatorImpl( 236 return scoped_ptr<AddressValidator>(new AddressValidatorImpl(
123 downloader.Pass(), storage.Pass(), load_rules_delegate)); 237 downloader.Pass(), storage.Pass(), load_rules_delegate));
124 } 238 }
125 239
126 } // namespace addressinput 240 } // namespace addressinput
127 } // namespace i18n 241 } // namespace i18n
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698