Home | History | Annotate | Download | only in src
      1 // Copyright (C) 2013 Google Inc.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (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
      6 //
      7 // http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 //
     15 // An object to retrieve data.
     16 
     17 #ifndef I18N_ADDRESSINPUT_RETRIEVER_H_
     18 #define I18N_ADDRESSINPUT_RETRIEVER_H_
     19 
     20 #include <libaddressinput/callback.h>
     21 #include <libaddressinput/util/basictypes.h>
     22 #include <libaddressinput/util/scoped_ptr.h>
     23 
     24 #include <map>
     25 #include <string>
     26 
     27 namespace i18n {
     28 namespace addressinput {
     29 
     30 class Downloader;
     31 class Storage;
     32 
     33 // Manages downloading data and caching it locally. Sample usage:
     34 //    scoped_ptr<Downloader> downloader(new Downloader);
     35 //    scoped_ptr<Storage> storage(new Storage);
     36 //    Retriever retriever("https://i18napis.appspot.com/ssl-aggregate-address/",
     37 //                        downloader.Pass(), storage.Pass());
     38 //    retriever.Retrieve("data/CA/AB--fr",
     39 //                       BuildCallback(this, &MyClass::OnDataRetrieved));
     40 class Retriever {
     41  public:
     42   // The return value indicates whether the data is valid (should be kept) or is
     43   // invalid (should be discarded).
     44   typedef i18n::addressinput::Callback<bool(std::string, std::string)> Callback;
     45 
     46   Retriever(const std::string& validation_data_url,
     47             scoped_ptr<Downloader> downloader,
     48             scoped_ptr<Storage> storage);
     49   ~Retriever();
     50 
     51   // Retrieves the data for |key| and invokes the |retrieved| callback. Checks
     52   // for the data in storage first. If storage does not have the data for |key|,
     53   // then downloads the data and places it in storage.
     54   void Retrieve(const std::string& key, scoped_ptr<Callback> retrieved);
     55 
     56  private:
     57   friend class RetrieverTest;
     58 
     59   // Callback for when a rule is retrieved from |storage_|.
     60   void OnDataRetrievedFromStorage(bool success,
     61                                   const std::string& key,
     62                                   const std::string& stored_data);
     63 
     64   // Callback for when a rule is retrieved by |downloader_|.
     65   void OnDownloaded(bool success,
     66                     const std::string& url,
     67                     scoped_ptr<std::string> downloaded_data);
     68 
     69   // Returns the URL where the |key| can be retrieved. For example, returns
     70   // "https://i18napis.appspot.com/ssl-aggregate-address/data/US" for input
     71   // "data/US". Assumes that the input string is a valid URL segment.
     72   std::string GetUrlForKey(const std::string& key) const;
     73 
     74   // Returns the key for the |url|. For example, returns "data/US" for
     75   // "https://i18napis.appspot.com/ssl-aggregate-address/data/US". If the |url|
     76   // does not start with |validation_data_url| that was passed to the
     77   // constructor, then returns an empty string. (This can happen if the user of
     78   // the library returns a bad URL in their Downloader implementation.)
     79   std::string GetKeyForUrl(const std::string& url) const;
     80 
     81   // Returns true if the |url| starts with |validation_data_url| that was passed
     82   // to the constructor.
     83   bool IsValidationDataUrl(const std::string& url) const;
     84 
     85   // Looks up the callback for |key| in |requests_|, removes it from the map and
     86   // invokes it with |key|, |success|, and |data| parameters.
     87   bool InvokeCallbackForKey(const std::string& key,
     88                             bool success,
     89                             const std::string& data);
     90 
     91   const std::string validation_data_url_;
     92   scoped_ptr<Downloader> downloader_;
     93   scoped_ptr<Storage> storage_;
     94 
     95   // Holds pending requests. The callback pointers are owned.
     96   std::map<std::string, Callback*> requests_;
     97 
     98   // Holds data from storage that has expired timestamps. If a download fails,
     99   // then this data is used as fallback.
    100   std::map<std::string, std::string> stale_data_;
    101 
    102   DISALLOW_COPY_AND_ASSIGN(Retriever);
    103 };
    104 
    105 }  // namespace addressinput
    106 }  // namespace i18n
    107 
    108 #endif  // I18N_ADDRESSINPUT_RETRIEVER_H_
    109