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

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: Addressed comments. 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>
27 #include <cstddef>
25 #include <map> 28 #include <map>
26 #include <string> 29 #include <string>
27 #include <utility> 30 #include <utility>
28 31
32 #include <re2/re2.h>
33
29 #include "country_rules_retriever.h" 34 #include "country_rules_retriever.h"
35 #include "messages.h"
30 #include "retriever.h" 36 #include "retriever.h"
37 #include "rule.h"
31 #include "ruleset.h" 38 #include "ruleset.h"
32 #include "util/stl_util.h" 39 #include "util/stl_util.h"
33 #include "validating_storage.h" 40 #include "validating_storage.h"
34 41
35 namespace i18n { 42 namespace i18n {
36 namespace addressinput { 43 namespace addressinput {
37 44
38 namespace { 45 namespace {
39 46
47 // Returns true if the filter is empty (all problems allowed) or contains the
48 // |field|->|problem| mapping (explicitly allowed).
49 bool FilterAllows(const AddressProblemFilter& filter,
50 AddressField field,
51 AddressProblem::Type problem) {
52 if (filter.empty()) {
53 return true;
54 }
55
56 for (AddressProblemFilter::const_iterator it = filter.begin();
57 it != filter.end(); ++it) {
58 if (it->first == field && it->second == problem) {
59 return true;
60 }
61 }
62
63 return false;
64 }
65
40 // Validates AddressData structure. 66 // Validates AddressData structure.
41 class AddressValidatorImpl : public AddressValidator { 67 class AddressValidatorImpl : public AddressValidator {
42 public: 68 public:
43 // Takes ownership of |downloader| and |storage|. Does not take ownership of 69 // Takes ownership of |downloader| and |storage|. Does not take ownership of
44 // |load_rules_delegate|. 70 // |load_rules_delegate|.
45 AddressValidatorImpl(scoped_ptr<const Downloader> downloader, 71 AddressValidatorImpl(scoped_ptr<const Downloader> downloader,
46 scoped_ptr<Storage> storage, 72 scoped_ptr<Storage> storage,
47 LoadRulesDelegate* load_rules_delegate) 73 LoadRulesDelegate* load_rules_delegate)
48 : retriever_(scoped_ptr<Retriever>(new Retriever( 74 : retriever_(scoped_ptr<Retriever>(new Retriever(
49 VALIDATION_DATA_URL, 75 VALIDATION_DATA_URL,
(...skipping 19 matching lines...) Expand all
69 BuildScopedPtrCallback(this, &AddressValidatorImpl::OnRulesLoaded)); 95 BuildScopedPtrCallback(this, &AddressValidatorImpl::OnRulesLoaded));
70 } 96 }
71 } 97 }
72 98
73 // AddressValidator implementation. 99 // AddressValidator implementation.
74 virtual Status ValidateAddress( 100 virtual Status ValidateAddress(
75 const AddressData& address, 101 const AddressData& address,
76 const AddressProblemFilter& filter, 102 const AddressProblemFilter& filter,
77 const Localization& localization, 103 const Localization& localization,
78 AddressProblems* problems) const { 104 AddressProblems* problems) const {
79 return RULES_UNAVAILABLE; 105 std::map<std::string, Status>::const_iterator status_it =
106 status_.find(address.country_code);
107 if (status_it == status_.end()) {
108 return RULES_UNAVAILABLE;
109 } else if (status_it->second == RULES_NOT_READY) {
110 return RULES_NOT_READY;
111 }
112
113 std::map<std::string, Ruleset*>::const_iterator ruleset_it =
114 rules_.find(address.country_code);
115 assert(ruleset_it != rules_.end());
116 Ruleset* ruleset = ruleset_it->second;
117 assert(ruleset != NULL);
118
119 std::map<AddressField, const Rule*> rules =
120 ruleset->BuildRulesForAddress(address);
121 const Rule& country_rule = *rules[COUNTRY];
122
123 // Validate required fields.
124 for (std::vector<AddressField>::const_iterator
125 field_it = country_rule.GetRequired().begin();
126 field_it != country_rule.GetRequired().end();
127 ++field_it) {
128 if (address.GetField(*field_it).empty() &&
129 FilterAllows(
130 filter, *field_it, AddressProblem::MISSING_REQUIRED_FIELD)) {
131 problems->push_back(AddressProblem(
132 *field_it,
133 AddressProblem::MISSING_REQUIRED_FIELD,
134 localization.GetString(
135 IDS_LIBADDRESSINPUT_I18N_MISSING_REQUIRED_FIELD)));
136 }
137 }
138
139 // Validate general postal code format. A country-level rule specifies the
140 // regular expression for the whole postal code.
141 if (!address.postal_code.empty() &&
142 !country_rule.GetPostalCodeFormat().empty() &&
143 FilterAllows(filter,
144 POSTAL_CODE,
145 AddressProblem::UNRECOGNIZED_FORMAT) &&
146 !RE2::FullMatch(
147 address.postal_code, country_rule.GetPostalCodeFormat())) {
148 problems->push_back(AddressProblem(
149 POSTAL_CODE,
150 AddressProblem::UNRECOGNIZED_FORMAT,
151 localization.GetString(
152 country_rule.GetInvalidPostalCodeMessageId())));
153 }
154
155 for (std::map<AddressField, const Rule*>::const_iterator
156 rule_it = rules.begin();
157 rule_it != rules.end();
158 ++rule_it) {
159 AddressField field_type = rule_it->first;
160 const Rule* rule = rule_it->second;
161 assert(rule != NULL);
162
163 // Validate the field values, e.g. state names in US.
164 AddressField sub_field_type = static_cast<AddressField>(field_type + 1);
165 const std::string& sub_field = address.GetField(sub_field_type);
166 const std::vector<std::string>& sub_keys = rule->GetSubKeys();
167 if (!sub_field.empty() &&
168 !sub_keys.empty() &&
169 FilterAllows(filter, sub_field_type, AddressProblem::UNKNOWN_VALUE) &&
170 std::find(sub_keys.begin(), sub_keys.end(), sub_field) ==
171 sub_keys.end()) {
172 problems->push_back(AddressProblem(
173 sub_field_type,
174 AddressProblem::UNKNOWN_VALUE,
175 localization.GetString(
176 country_rule.GetInvalidFieldMessageId(sub_field_type))));
177 }
178
179 // Validate sub-region specific postal code format. A sub-region specifies
180 // the regular expression for a prefix of the postal code.
181 int match_position = -1;
182 if (field_type > COUNTRY &&
183 !address.postal_code.empty() &&
184 !rule->GetPostalCodeFormat().empty() &&
185 FilterAllows(filter,
186 POSTAL_CODE,
187 AddressProblem::MISMATCHING_VALUE) &&
188 (!RE2::PartialMatch(address.postal_code,
189 rule->GetPostalCodeFormat(),
190 &match_position) ||
191 match_position != 0)) {
192 problems->push_back(AddressProblem(
193 POSTAL_CODE,
194 AddressProblem::MISMATCHING_VALUE,
195 localization.GetString(
196 country_rule.GetInvalidPostalCodeMessageId())));
197 }
198 }
199
200 return SUCCESS;
80 } 201 }
81 202
82 private: 203 private:
83 // Called when CountryRulesRetriever::RetrieveRules finishes loading all rules 204 // Called when CountryRulesRetriever::RetrieveRules finishes loading all rules
84 // for the |country_code|. 205 // for the |country_code|.
85 void OnRulesLoaded(bool success, 206 void OnRulesLoaded(bool success,
86 const std::string& country_code, 207 const std::string& country_code,
87 scoped_ptr<Ruleset> ruleset) { 208 scoped_ptr<Ruleset> ruleset) {
88 assert(rules_.find(country_code) == rules_.end()); 209 assert(rules_.find(country_code) == rules_.end());
89 if (success) { 210 if (success) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 scoped_ptr<AddressValidator> AddressValidator::Build( 243 scoped_ptr<AddressValidator> AddressValidator::Build(
123 scoped_ptr<const Downloader> downloader, 244 scoped_ptr<const Downloader> downloader,
124 scoped_ptr<Storage> storage, 245 scoped_ptr<Storage> storage,
125 LoadRulesDelegate* load_rules_delegate) { 246 LoadRulesDelegate* load_rules_delegate) {
126 return scoped_ptr<AddressValidator>(new AddressValidatorImpl( 247 return scoped_ptr<AddressValidator>(new AddressValidatorImpl(
127 downloader.Pass(), storage.Pass(), load_rules_delegate)); 248 downloader.Pass(), storage.Pass(), load_rules_delegate));
128 } 249 }
129 250
130 } // namespace addressinput 251 } // namespace addressinput
131 } // namespace i18n 252 } // namespace i18n
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698