Home | History | Annotate | Download | only in chromium
      1 // Copyright 2014 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 #ifndef THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_ADDRESS_VALIDATOR_H_
      6 #define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_ADDRESS_VALIDATOR_H_
      7 
      8 #include <map>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/macros.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/memory/weak_ptr.h"
     15 #include "base/time/time.h"
     16 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_field.h"
     17 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_validator.h"
     18 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h"
     19 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/preload_supplier.h"
     20 
     21 namespace i18n {
     22 namespace addressinput {
     23 class AddressNormalizer;
     24 class Source;
     25 class Storage;
     26 struct AddressData;
     27 }
     28 }
     29 
     30 namespace autofill {
     31 
     32 class InputSuggester;
     33 
     34 // The object to be notified when loading of address validation rules is
     35 // finished.
     36 class LoadRulesListener {
     37  public:
     38   virtual ~LoadRulesListener() {}
     39 
     40   // Called when the validation rules for the |region_code| have been loaded.
     41   // The validation rules include the generic rules for the |region_code| and
     42   // specific rules for the country's administrative areas, localities, and
     43   // dependent localities. If a country has language-specific validation rules,
     44   // then these are also loaded.
     45   //
     46   // The |success| parameter is true when the rules were loaded successfully.
     47   virtual void OnAddressValidationRulesLoaded(const std::string& region_code,
     48                                               bool success) = 0;
     49 };
     50 
     51 // Interface to the libaddressinput AddressValidator for Chromium Autofill. The
     52 // class is named AddressValidator to simplify switching between libaddressinput
     53 // and this version.
     54 //
     55 // It's not possible to name this file address_validator.h because some
     56 // compilers do not handle multiple files with the same name (although in
     57 // different directories) gracefully. This class is a shim between upstream
     58 // libaddressinput API and the API that Chrome expects, hence the file name
     59 // chrome_address_validator.h.
     60 class AddressValidator {
     61  public:
     62   // The status of address validation.
     63   enum Status {
     64     // Address validation completed successfully. Check |problems| to see if any
     65     // problems were found.
     66     SUCCESS,
     67 
     68     // The validation rules are not available, because LoadRules() was not
     69     // called or failed. Reload the rules.
     70     RULES_UNAVAILABLE,
     71 
     72     // The validation rules are being loaded. Try again later.
     73     RULES_NOT_READY
     74   };
     75 
     76   // Takes ownership of |source| and |storage|.
     77   AddressValidator(scoped_ptr< ::i18n::addressinput::Source> source,
     78                    scoped_ptr< ::i18n::addressinput::Storage> storage,
     79                    LoadRulesListener* load_rules_listener);
     80 
     81   virtual ~AddressValidator();
     82 
     83   // Loads the generic validation rules for |region_code| and specific rules
     84   // for the region's administrative areas, localities, and dependent
     85   // localities. A typical data size is 10KB. The largest is 250KB. If a region
     86   // has language-specific validation rules, then these are also loaded.
     87   //
     88   // Example rule:
     89   // https://i18napis.appspot.com/ssl-aggregate-address/data/US
     90   //
     91   // If the rules are already in progress of being loaded, it does nothing.
     92   // Invokes |load_rules_listener| when the loading has finished.
     93   virtual void LoadRules(const std::string& region_code);
     94 
     95   // Validates the |address| and populates |problems| with the validation
     96   // problems, filtered according to the |filter| parameter.
     97   //
     98   // If the |filter| is empty, then all discovered validation problems are
     99   // returned. If the |filter| contains problem elements, then only the problems
    100   // in the |filter| may be returned.
    101   virtual Status ValidateAddress(
    102       const ::i18n::addressinput::AddressData& address,
    103       const ::i18n::addressinput::FieldProblemMap* filter,
    104       ::i18n::addressinput::FieldProblemMap* problems) const;
    105 
    106   // Fills in |suggestions| for the partially typed in |user_input|, assuming
    107   // the user is typing in the |focused_field|. If the number of |suggestions|
    108   // is over the |suggestion_limit|, then returns no |suggestions| at all.
    109   //
    110   // If the |solutions| parameter is NULL, the checks whether the validation
    111   // rules are available, but does not fill in suggestions.
    112   //
    113   // Sample user input 1:
    114   //   country code = "US"
    115   //   postal code = "90066"
    116   //   focused field = POSTAL_CODE
    117   //   suggestions limit = 1
    118   // Suggestion:
    119   //   [{administrative_area: "CA"}]
    120   //
    121   // Sample user input 2:
    122   //   country code = "CN"
    123   //   dependent locality = "Zongyang"
    124   //   focused field = DEPENDENT_LOCALITY
    125   //   suggestions limit = 10
    126   // Suggestion:
    127   //   [{dependent_locality: "Zongyang Xian",
    128   //     locality: "Anqing Shi",
    129   //     administrative_area: "Anhui Sheng"}]
    130   virtual Status GetSuggestions(
    131       const ::i18n::addressinput::AddressData& user_input,
    132       ::i18n::addressinput::AddressField focused_field,
    133       size_t suggestion_limit,
    134       std::vector< ::i18n::addressinput::AddressData>* suggestions) const;
    135 
    136   // Canonicalizes the administrative area in |address_data|. For example,
    137   // "texas" changes to "TX". Returns true on success, otherwise leaves
    138   // |address_data| alone and returns false.
    139   virtual bool CanonicalizeAdministrativeArea(
    140       ::i18n::addressinput::AddressData* address) const;
    141 
    142  protected:
    143   // Constructor used only for MockAddressValidator.
    144   AddressValidator();
    145 
    146   // Returns the period of time to wait between the first attempt's failure and
    147   // the second attempt's initiation to load rules. Exposed for testing.
    148   virtual base::TimeDelta GetBaseRetryPeriod() const;
    149 
    150  private:
    151   // Verifies that |validator_| succeeded. Invoked by |validated_| callback.
    152   void Validated(bool success,
    153                  const ::i18n::addressinput::AddressData&,
    154                  const ::i18n::addressinput::FieldProblemMap&);
    155 
    156   // Invokes the |load_rules_listener_|, if it's not NULL. Called by
    157   // |rules_loaded_| callback.
    158   void RulesLoaded(bool success, const std::string& region_code, int);
    159 
    160   // Retries loading rules without resetting the retry counter.
    161   void RetryLoadRules(const std::string& region_code);
    162 
    163   // Loads and stores aggregate rules at COUNTRY level.
    164   const scoped_ptr< ::i18n::addressinput::PreloadSupplier> supplier_;
    165 
    166   // Suggests addresses based on user input.
    167   const scoped_ptr<InputSuggester> input_suggester_;
    168 
    169   // Normalizes addresses into a canonical form.
    170   const scoped_ptr< ::i18n::addressinput::AddressNormalizer> normalizer_;
    171 
    172   // Validates addresses.
    173   const scoped_ptr<const ::i18n::addressinput::AddressValidator> validator_;
    174 
    175   // The callback that |validator_| invokes when it finished validating an
    176   // address.
    177   const scoped_ptr<const ::i18n::addressinput::AddressValidator::Callback>
    178       validated_;
    179 
    180   // The callback that |supplier_| invokes when it finished loading rules.
    181   const scoped_ptr<const ::i18n::addressinput::PreloadSupplier::Callback>
    182       rules_loaded_;
    183 
    184   // Not owned delegate to invoke when |suppler_| finished loading rules. Can be
    185   // NULL.
    186   LoadRulesListener* const load_rules_listener_;
    187 
    188   // A mapping of region codes to the number of attempts to retry loading rules.
    189   std::map<std::string, int> attempts_number_;
    190 
    191   // Member variables should appear before the WeakPtrFactory, to ensure that
    192   // any WeakPtrs to AddressValidator are invalidated before its members
    193   // variable's destructors are executed, rendering them invalid.
    194   base::WeakPtrFactory<AddressValidator> weak_factory_;
    195 
    196   DISALLOW_COPY_AND_ASSIGN(AddressValidator);
    197 };
    198 
    199 }  // namespace autofill
    200 
    201 #endif  // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_ADDRESS_VALIDATOR_H_
    202