Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / libaddressinput / chromium / cpp / src / address_validator.cc
index b08dc83..fe36bd8 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "country_rules_aggregator.h"
 #include "grit/libaddressinput_strings.h"
+#include "region_data_constants.h"
 #include "retriever.h"
 #include "rule.h"
 #include "ruleset.h"
@@ -111,34 +112,32 @@ class AddressValidatorImpl : public AddressValidator {
       AddressProblems* problems) const {
     std::map<std::string, const Ruleset*>::const_iterator ruleset_it =
         rules_.find(address.country_code);
+
+    // We can still validate the required fields even if the full ruleset isn't
+    // ready.
     if (ruleset_it == rules_.end()) {
+      if (problems != NULL) {
+        Rule rule;
+        rule.CopyFrom(Rule::GetDefault());
+        if (rule.ParseSerializedRule(
+                 RegionDataConstants::GetRegionData(address.country_code))) {
+          EnforceRequiredFields(rule, address, filter, problems);
+        }
+      }
+
       return loading_rules_.find(address.country_code) != loading_rules_.end()
           ? RULES_NOT_READY
           : RULES_UNAVAILABLE;
     }
 
+    if (problems == NULL)
+      return SUCCESS;
+
     const Ruleset* ruleset = ruleset_it->second;
     assert(ruleset != NULL);
     const Rule& country_rule =
         ruleset->GetLanguageCodeRule(address.language_code);
-
-    // Validate required fields.
-    for (std::vector<AddressField>::const_iterator
-             field_it = country_rule.GetRequired().begin();
-         field_it != country_rule.GetRequired().end();
-         ++field_it) {
-      bool field_empty = *field_it != STREET_ADDRESS
-          ? address.GetFieldValue(*field_it).empty()
-          : IsEmptyStreetAddress(address.address_lines);
-      if (field_empty &&
-          FilterAllows(
-              filter, *field_it, AddressProblem::MISSING_REQUIRED_FIELD)) {
-        problems->push_back(AddressProblem(
-            *field_it,
-            AddressProblem::MISSING_REQUIRED_FIELD,
-            IDS_LIBADDRESSINPUT_I18N_MISSING_REQUIRED_FIELD));
-      }
-    }
+    EnforceRequiredFields(country_rule, address, filter, problems);
 
     // Validate general postal code format. A country-level rule specifies the
     // regular expression for the whole postal code.
@@ -161,13 +160,11 @@ class AddressValidatorImpl : public AddressValidator {
       // Validate the field values, e.g. state names in US.
       AddressField sub_field_type =
           static_cast<AddressField>(ruleset->field() + 1);
-      const std::string& sub_field = address.GetFieldValue(sub_field_type);
-      const std::vector<std::string>& sub_keys = rule.GetSubKeys();
-      if (!sub_field.empty() &&
-          !sub_keys.empty() &&
+      std::string sub_key;
+      const std::string& user_input = address.GetFieldValue(sub_field_type);
+      if (!user_input.empty() &&
           FilterAllows(filter, sub_field_type, AddressProblem::UNKNOWN_VALUE) &&
-          std::find(sub_keys.begin(), sub_keys.end(), sub_field) ==
-              sub_keys.end()) {
+          !rule.CanonicalizeSubKey(user_input, &sub_key)) {
         problems->push_back(AddressProblem(
             sub_field_type,
             AddressProblem::UNKNOWN_VALUE,
@@ -176,29 +173,39 @@ class AddressValidatorImpl : public AddressValidator {
 
       // Validate sub-region specific postal code format. A sub-region specifies
       // the regular expression for a prefix of the postal code.
-      int match_position = -1;
       if (ruleset->field() > COUNTRY &&
           !address.postal_code.empty() &&
           !rule.GetPostalCodeFormat().empty() &&
           FilterAllows(filter,
                        POSTAL_CODE,
                        AddressProblem::MISMATCHING_VALUE) &&
-          (!RE2::PartialMatch(address.postal_code,
-                              rule.GetPostalCodeFormat(),
-                              &match_position) ||
-           match_position != 0)) {
+          !RE2::FullMatch(address.postal_code,
+                          "^(" + rule.GetPostalCodeFormat() + ").*")) {
         problems->push_back(AddressProblem(
             POSTAL_CODE,
             AddressProblem::MISMATCHING_VALUE,
             country_rule.GetInvalidPostalCodeMessageId()));
       }
 
-      ruleset = ruleset->GetSubRegionRuleset(sub_field);
+      ruleset = ruleset->GetSubRegionRuleset(sub_key);
     }
 
     return SUCCESS;
   }
 
+  virtual bool CanonicalizeAdministrativeArea(AddressData* address_data) const {
+    std::map<std::string, const Ruleset*>::const_iterator ruleset_it =
+        rules_.find(address_data->country_code);
+    if (ruleset_it == rules_.end()) {
+      return false;
+    }
+    const Rule& rule =
+        ruleset_it->second->GetLanguageCodeRule(address_data->language_code);
+
+    return rule.CanonicalizeSubKey(address_data->administrative_area,
+                                   &address_data->administrative_area);
+  }
+
  private:
   // Called when CountryRulesAggregator::AggregateRules loads the |ruleset| for
   // the |country_code|.
@@ -218,6 +225,30 @@ class AddressValidatorImpl : public AddressValidator {
     }
   }
 
+  // Adds problems for just the required fields portion of |country_rule|.
+  void EnforceRequiredFields(const Rule& country_rule,
+                             const AddressData& address,
+                             const AddressProblemFilter& filter,
+                             AddressProblems* problems) const {
+    assert(problems != NULL);
+    for (std::vector<AddressField>::const_iterator
+             field_it = country_rule.GetRequired().begin();
+         field_it != country_rule.GetRequired().end();
+         ++field_it) {
+      bool field_empty = *field_it != STREET_ADDRESS
+          ? address.GetFieldValue(*field_it).empty()
+          : IsEmptyStreetAddress(address.address_lines);
+      if (field_empty &&
+          FilterAllows(
+              filter, *field_it, AddressProblem::MISSING_REQUIRED_FIELD)) {
+        problems->push_back(AddressProblem(
+            *field_it,
+            AddressProblem::MISSING_REQUIRED_FIELD,
+            IDS_LIBADDRESSINPUT_I18N_MISSING_REQUIRED_FIELD));
+      }
+    }
+  }
+
   // Loads the ruleset for a country code.
   CountryRulesAggregator aggregator_;