1e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org// Copyright (C) 2013 Google Inc. 2e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org// 3e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org// Licensed under the Apache License, Version 2.0 (the "License"); 4e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org// you may not use this file except in compliance with the License. 5e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org// You may obtain a copy of the License at 6e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org// 7e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org// http://www.apache.org/licenses/LICENSE-2.0 8e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org// 9e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org// Unless required by applicable law or agreed to in writing, software 10e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org// distributed under the License is distributed on an "AS IS" BASIS, 11e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org// See the License for the specific language governing permissions and 13e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org// limitations under the License. 14e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 15e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org#include "retriever.h" 16e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 17e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org#include <libaddressinput/callback.h> 188466869ca5e66ec41d133c8ca2f25789028ef4dfroubert@google.com#include <libaddressinput/source.h> 19e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org#include <libaddressinput/storage.h> 20e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org#include <libaddressinput/util/basictypes.h> 21e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org#include <libaddressinput/util/scoped_ptr.h> 22e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 23e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org#include <cassert> 24e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org#include <cstddef> 25e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org#include <string> 26e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 27bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org#include "validating_storage.h" 28e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 29e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.orgnamespace i18n { 30e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.orgnamespace addressinput { 31e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 32e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.orgnamespace { 33e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 34e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.orgclass Helper { 35e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org public: 36e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org // Does not take ownership of its parameters. 37e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org Helper(const std::string& key, 38e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org const Retriever::Callback& retrieved, 398466869ca5e66ec41d133c8ca2f25789028ef4dfroubert@google.com const Source& source, 40bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org ValidatingStorage* storage) 41e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org : retrieved_(retrieved), 428466869ca5e66ec41d133c8ca2f25789028ef4dfroubert@google.com source_(source), 43e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org storage_(storage), 448466869ca5e66ec41d133c8ca2f25789028ef4dfroubert@google.com fresh_data_ready_(BuildCallback(this, &Helper::OnFreshDataReady)), 45bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org validated_data_ready_( 46bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org BuildCallback(this, &Helper::OnValidatedDataReady)), 47bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org stale_data_() { 48e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org assert(storage_ != NULL); 49bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org storage_->Get(key, *validated_data_ready_); 50e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org } 51e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 52e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org private: 53e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org ~Helper() {} 54e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 55bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org void OnValidatedDataReady(bool success, 56bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org const std::string& key, 57128ae075bbf50996c1068740746f27430f89136droubert@google.com std::string* data) { 58e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org if (success) { 59128ae075bbf50996c1068740746f27430f89136droubert@google.com assert(data != NULL); 60128ae075bbf50996c1068740746f27430f89136droubert@google.com retrieved_(success, key, *data); 61e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org delete this; 62e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org } else { 63bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org // Validating storage returns (false, key, stale-data) for valid but stale 64bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org // data. If |data| is empty, however, then it's either missing or invalid. 65128ae075bbf50996c1068740746f27430f89136droubert@google.com if (data != NULL && !data->empty()) { 66128ae075bbf50996c1068740746f27430f89136droubert@google.com stale_data_ = *data; 67bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org } 688466869ca5e66ec41d133c8ca2f25789028ef4dfroubert@google.com source_.Get(key, *fresh_data_ready_); 69e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org } 70128ae075bbf50996c1068740746f27430f89136droubert@google.com delete data; 71e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org } 72e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 738466869ca5e66ec41d133c8ca2f25789028ef4dfroubert@google.com void OnFreshDataReady(bool success, 748466869ca5e66ec41d133c8ca2f25789028ef4dfroubert@google.com const std::string& key, 758466869ca5e66ec41d133c8ca2f25789028ef4dfroubert@google.com std::string* data) { 76e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org if (success) { 77128ae075bbf50996c1068740746f27430f89136droubert@google.com assert(data != NULL); 78128ae075bbf50996c1068740746f27430f89136droubert@google.com retrieved_(true, key, *data); 79e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org storage_->Put(key, data); 80128ae075bbf50996c1068740746f27430f89136droubert@google.com data = NULL; // Deleted by Storage::Put(). 81bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org } else if (!stale_data_.empty()) { 82bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org // Reuse the stale data if a download fails. It's better to have slightly 83bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org // outdated validation rules than to suddenly lose validation ability. 84bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org retrieved_(true, key, stale_data_); 85bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org } else { 86bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org retrieved_(false, key, std::string()); 87e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org } 88128ae075bbf50996c1068740746f27430f89136droubert@google.com delete data; 89e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org delete this; 90e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org } 91e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 92e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org const Retriever::Callback& retrieved_; 938466869ca5e66ec41d133c8ca2f25789028ef4dfroubert@google.com const Source& source_; 94bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org ValidatingStorage* storage_; 958466869ca5e66ec41d133c8ca2f25789028ef4dfroubert@google.com const scoped_ptr<const Source::Callback> fresh_data_ready_; 96e543c57d2256e9f144bbfc3783cc30a5d2129eaeroubert@google.com const scoped_ptr<const Storage::Callback> validated_data_ready_; 97bf030e4c78d86bd72699e6d06d645ebb130bf8e4rouslan@chromium.org std::string stale_data_; 98e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 99e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org DISALLOW_COPY_AND_ASSIGN(Helper); 100e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org}; 101e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 102e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org} // namespace 103e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 1048466869ca5e66ec41d133c8ca2f25789028ef4dfroubert@google.comRetriever::Retriever(const Source* source, Storage* storage) 1058466869ca5e66ec41d133c8ca2f25789028ef4dfroubert@google.com : source_(source), storage_(new ValidatingStorage(storage)) { 1068466869ca5e66ec41d133c8ca2f25789028ef4dfroubert@google.com assert(source_ != NULL); 107e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org assert(storage_ != NULL); 108e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org} 109e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 110e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.orgRetriever::~Retriever() {} 111e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 112e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.orgvoid Retriever::Retrieve(const std::string& key, 113e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org const Callback& retrieved) const { 1148466869ca5e66ec41d133c8ca2f25789028ef4dfroubert@google.com new Helper(key, retrieved, *source_, storage_.get()); 115e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org} 116e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org 117e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org} // namespace addressinput 118e281bd3ef5806b0cfd58079a7215a6ae94ecef96rouslan@chromium.org} // namespace i18n 119