OLD | NEW |
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/address_data.h> |
18 #include <libaddressinput/downloader.h> | 18 #include <libaddressinput/downloader.h> |
19 #include <libaddressinput/load_rules_delegate.h> | 19 #include <libaddressinput/load_rules_delegate.h> |
20 #include <libaddressinput/localization.h> | |
21 #include <libaddressinput/storage.h> | 20 #include <libaddressinput/storage.h> |
22 #include <libaddressinput/util/basictypes.h> | 21 #include <libaddressinput/util/basictypes.h> |
23 #include <libaddressinput/util/scoped_ptr.h> | 22 #include <libaddressinput/util/scoped_ptr.h> |
24 | 23 |
25 #include <algorithm> | 24 #include <algorithm> |
26 #include <cassert> | 25 #include <cassert> |
27 #include <cstddef> | 26 #include <cstddef> |
28 #include <map> | 27 #include <map> |
29 #include <set> | 28 #include <set> |
30 #include <string> | 29 #include <string> |
31 | 30 |
32 #include <re2/re2.h> | 31 #include <re2/re2.h> |
33 | 32 |
34 #include "country_rules_aggregator.h" | 33 #include "country_rules_aggregator.h" |
35 #include "messages.h" | 34 #include "grit/libaddressinput_strings.h" |
36 #include "retriever.h" | 35 #include "retriever.h" |
37 #include "rule.h" | 36 #include "rule.h" |
38 #include "ruleset.h" | 37 #include "ruleset.h" |
39 #include "util/stl_util.h" | 38 #include "util/stl_util.h" |
40 | 39 |
41 namespace i18n { | 40 namespace i18n { |
42 namespace addressinput { | 41 namespace addressinput { |
43 | 42 |
44 namespace { | 43 namespace { |
45 | 44 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 aggregator_.AggregateRules( | 89 aggregator_.AggregateRules( |
91 country_code, | 90 country_code, |
92 BuildScopedPtrCallback(this, &AddressValidatorImpl::OnRulesLoaded)); | 91 BuildScopedPtrCallback(this, &AddressValidatorImpl::OnRulesLoaded)); |
93 } | 92 } |
94 } | 93 } |
95 | 94 |
96 // AddressValidator implementation. | 95 // AddressValidator implementation. |
97 virtual Status ValidateAddress( | 96 virtual Status ValidateAddress( |
98 const AddressData& address, | 97 const AddressData& address, |
99 const AddressProblemFilter& filter, | 98 const AddressProblemFilter& filter, |
100 const Localization& localization, | |
101 AddressProblems* problems) const { | 99 AddressProblems* problems) const { |
102 std::map<std::string, const Ruleset*>::const_iterator ruleset_it = | 100 std::map<std::string, const Ruleset*>::const_iterator ruleset_it = |
103 rules_.find(address.country_code); | 101 rules_.find(address.country_code); |
104 if (ruleset_it == rules_.end()) { | 102 if (ruleset_it == rules_.end()) { |
105 return loading_rules_.find(address.country_code) != loading_rules_.end() | 103 return loading_rules_.find(address.country_code) != loading_rules_.end() |
106 ? RULES_NOT_READY | 104 ? RULES_NOT_READY |
107 : RULES_UNAVAILABLE; | 105 : RULES_UNAVAILABLE; |
108 } | 106 } |
109 | 107 |
110 const Ruleset* ruleset = ruleset_it->second; | 108 const Ruleset* ruleset = ruleset_it->second; |
111 assert(ruleset != NULL); | 109 assert(ruleset != NULL); |
112 const Rule& country_rule = | 110 const Rule& country_rule = |
113 ruleset->GetLanguageCodeRule(address.language_code); | 111 ruleset->GetLanguageCodeRule(address.language_code); |
114 | 112 |
115 // Validate required fields. | 113 // Validate required fields. |
116 for (std::vector<AddressField>::const_iterator | 114 for (std::vector<AddressField>::const_iterator |
117 field_it = country_rule.GetRequired().begin(); | 115 field_it = country_rule.GetRequired().begin(); |
118 field_it != country_rule.GetRequired().end(); | 116 field_it != country_rule.GetRequired().end(); |
119 ++field_it) { | 117 ++field_it) { |
120 if (address.GetField(*field_it).empty() && | 118 if (address.GetField(*field_it).empty() && |
121 FilterAllows( | 119 FilterAllows( |
122 filter, *field_it, AddressProblem::MISSING_REQUIRED_FIELD)) { | 120 filter, *field_it, AddressProblem::MISSING_REQUIRED_FIELD)) { |
123 problems->push_back(AddressProblem( | 121 problems->push_back(AddressProblem( |
124 *field_it, | 122 *field_it, |
125 AddressProblem::MISSING_REQUIRED_FIELD, | 123 AddressProblem::MISSING_REQUIRED_FIELD, |
126 localization.GetString( | 124 IDS_LIBADDRESSINPUT_I18N_MISSING_REQUIRED_FIELD)); |
127 IDS_LIBADDRESSINPUT_I18N_MISSING_REQUIRED_FIELD))); | |
128 } | 125 } |
129 } | 126 } |
130 | 127 |
131 // Validate general postal code format. A country-level rule specifies the | 128 // Validate general postal code format. A country-level rule specifies the |
132 // regular expression for the whole postal code. | 129 // regular expression for the whole postal code. |
133 if (!address.postal_code.empty() && | 130 if (!address.postal_code.empty() && |
134 !country_rule.GetPostalCodeFormat().empty() && | 131 !country_rule.GetPostalCodeFormat().empty() && |
135 FilterAllows(filter, | 132 FilterAllows(filter, |
136 POSTAL_CODE, | 133 POSTAL_CODE, |
137 AddressProblem::UNRECOGNIZED_FORMAT) && | 134 AddressProblem::UNRECOGNIZED_FORMAT) && |
138 !RE2::FullMatch( | 135 !RE2::FullMatch( |
139 address.postal_code, country_rule.GetPostalCodeFormat())) { | 136 address.postal_code, country_rule.GetPostalCodeFormat())) { |
140 problems->push_back(AddressProblem( | 137 problems->push_back(AddressProblem( |
141 POSTAL_CODE, | 138 POSTAL_CODE, |
142 AddressProblem::UNRECOGNIZED_FORMAT, | 139 AddressProblem::UNRECOGNIZED_FORMAT, |
143 localization.GetString( | 140 country_rule.GetInvalidPostalCodeMessageId())); |
144 country_rule.GetInvalidPostalCodeMessageId()))); | |
145 } | 141 } |
146 | 142 |
147 while (ruleset != NULL) { | 143 while (ruleset != NULL) { |
148 const Rule& rule = ruleset->GetLanguageCodeRule(address.language_code); | 144 const Rule& rule = ruleset->GetLanguageCodeRule(address.language_code); |
149 | 145 |
150 // Validate the field values, e.g. state names in US. | 146 // Validate the field values, e.g. state names in US. |
151 AddressField sub_field_type = | 147 AddressField sub_field_type = |
152 static_cast<AddressField>(ruleset->field() + 1); | 148 static_cast<AddressField>(ruleset->field() + 1); |
153 const std::string& sub_field = address.GetField(sub_field_type); | 149 const std::string& sub_field = address.GetField(sub_field_type); |
154 const std::vector<std::string>& sub_keys = rule.GetSubKeys(); | 150 const std::vector<std::string>& sub_keys = rule.GetSubKeys(); |
155 if (!sub_field.empty() && | 151 if (!sub_field.empty() && |
156 !sub_keys.empty() && | 152 !sub_keys.empty() && |
157 FilterAllows(filter, sub_field_type, AddressProblem::UNKNOWN_VALUE) && | 153 FilterAllows(filter, sub_field_type, AddressProblem::UNKNOWN_VALUE) && |
158 std::find(sub_keys.begin(), sub_keys.end(), sub_field) == | 154 std::find(sub_keys.begin(), sub_keys.end(), sub_field) == |
159 sub_keys.end()) { | 155 sub_keys.end()) { |
160 problems->push_back(AddressProblem( | 156 problems->push_back(AddressProblem( |
161 sub_field_type, | 157 sub_field_type, |
162 AddressProblem::UNKNOWN_VALUE, | 158 AddressProblem::UNKNOWN_VALUE, |
163 localization.GetString( | 159 country_rule.GetInvalidFieldMessageId(sub_field_type))); |
164 country_rule.GetInvalidFieldMessageId(sub_field_type)))); | |
165 } | 160 } |
166 | 161 |
167 // Validate sub-region specific postal code format. A sub-region specifies | 162 // Validate sub-region specific postal code format. A sub-region specifies |
168 // the regular expression for a prefix of the postal code. | 163 // the regular expression for a prefix of the postal code. |
169 int match_position = -1; | 164 int match_position = -1; |
170 if (ruleset->field() > COUNTRY && | 165 if (ruleset->field() > COUNTRY && |
171 !address.postal_code.empty() && | 166 !address.postal_code.empty() && |
172 !rule.GetPostalCodeFormat().empty() && | 167 !rule.GetPostalCodeFormat().empty() && |
173 FilterAllows(filter, | 168 FilterAllows(filter, |
174 POSTAL_CODE, | 169 POSTAL_CODE, |
175 AddressProblem::MISMATCHING_VALUE) && | 170 AddressProblem::MISMATCHING_VALUE) && |
176 (!RE2::PartialMatch(address.postal_code, | 171 (!RE2::PartialMatch(address.postal_code, |
177 rule.GetPostalCodeFormat(), | 172 rule.GetPostalCodeFormat(), |
178 &match_position) || | 173 &match_position) || |
179 match_position != 0)) { | 174 match_position != 0)) { |
180 problems->push_back(AddressProblem( | 175 problems->push_back(AddressProblem( |
181 POSTAL_CODE, | 176 POSTAL_CODE, |
182 AddressProblem::MISMATCHING_VALUE, | 177 AddressProblem::MISMATCHING_VALUE, |
183 localization.GetString( | 178 country_rule.GetInvalidPostalCodeMessageId())); |
184 country_rule.GetInvalidPostalCodeMessageId()))); | |
185 } | 179 } |
186 | 180 |
187 ruleset = ruleset->GetSubRegionRuleset(sub_field); | 181 ruleset = ruleset->GetSubRegionRuleset(sub_field); |
188 } | 182 } |
189 | 183 |
190 return SUCCESS; | 184 return SUCCESS; |
191 } | 185 } |
192 | 186 |
193 private: | 187 private: |
194 // Called when CountryRulesAggregator::AggregateRules loads the |ruleset| for | 188 // Called when CountryRulesAggregator::AggregateRules loads the |ruleset| for |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 scoped_ptr<AddressValidator> AddressValidator::Build( | 226 scoped_ptr<AddressValidator> AddressValidator::Build( |
233 scoped_ptr<Downloader> downloader, | 227 scoped_ptr<Downloader> downloader, |
234 scoped_ptr<Storage> storage, | 228 scoped_ptr<Storage> storage, |
235 LoadRulesDelegate* load_rules_delegate) { | 229 LoadRulesDelegate* load_rules_delegate) { |
236 return scoped_ptr<AddressValidator>(new AddressValidatorImpl( | 230 return scoped_ptr<AddressValidator>(new AddressValidatorImpl( |
237 downloader.Pass(), storage.Pass(), load_rules_delegate)); | 231 downloader.Pass(), storage.Pass(), load_rules_delegate)); |
238 } | 232 } |
239 | 233 |
240 } // namespace addressinput | 234 } // namespace addressinput |
241 } // namespace i18n | 235 } // namespace i18n |
OLD | NEW |