1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file.
4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/search_engines/search_host_to_urls_map.h"
6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
8bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/task.h"
9bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/search_engines/template_url.h"
10bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/search_engines/template_url_model.h"
11bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
12bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenSearchHostToURLsMap::SearchHostToURLsMap()
13bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    : initialized_(false) {
14bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
15bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
16bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenSearchHostToURLsMap::~SearchHostToURLsMap() {
17bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
18bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
19bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SearchHostToURLsMap::Init(
20bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    const std::vector<const TemplateURL*>& template_urls,
21bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    const SearchTermsData& search_terms_data) {
22bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(!initialized_);
23bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Set as initialized here so Add doesn't assert.
25bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  initialized_ = true;
26bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
27bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  for (size_t i = 0; i < template_urls.size(); ++i)
28bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    Add(template_urls[i], search_terms_data);
29bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
30bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
31bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SearchHostToURLsMap::Add(const TemplateURL* template_url,
32bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                              const SearchTermsData& search_terms_data) {
33bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(initialized_);
34bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(template_url);
35bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
36bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  const GURL url(TemplateURLModel::GenerateSearchURLUsingTermsData(
37bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      template_url, search_terms_data));
38bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (!url.is_valid() || !url.has_host())
39bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return;
40bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
41bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  host_to_urls_map_[url.host()].insert(template_url);
42bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
43bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
44bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SearchHostToURLsMap::Remove(const TemplateURL* template_url) {
45bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(initialized_);
46bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(template_url);
47bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
48bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  const GURL url(TemplateURLModel::GenerateSearchURL(template_url));
49bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (!url.is_valid() || !url.has_host())
50bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return;
51bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
52bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  const std::string host(url.host());
53bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(host_to_urls_map_.find(host) != host_to_urls_map_.end());
54bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
55bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  TemplateURLSet& urls = host_to_urls_map_[host];
56bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(urls.find(template_url) != urls.end());
57bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
58bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  urls.erase(urls.find(template_url));
59bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (urls.empty())
60bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    host_to_urls_map_.erase(host_to_urls_map_.find(host));
61bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
62bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
63bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SearchHostToURLsMap::Update(const TemplateURL* existing_turl,
64bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                 const TemplateURL& new_values,
65bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                 const SearchTermsData& search_terms_data) {
66bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(initialized_);
67bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(existing_turl);
68bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
69bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  Remove(existing_turl);
70bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
71bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Use the information from new_values but preserve existing_turl's id.
72bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  TemplateURLID previous_id = existing_turl->id();
73bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  TemplateURL* modifiable_turl = const_cast<TemplateURL*>(existing_turl);
74bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  *modifiable_turl = new_values;
75bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  modifiable_turl->set_id(previous_id);
76bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
77bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  Add(existing_turl, search_terms_data);
78bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
79bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
80bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SearchHostToURLsMap::UpdateGoogleBaseURLs(
81bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    const SearchTermsData& search_terms_data) {
82bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(initialized_);
83bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
84bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Create a list of the the TemplateURLs to update.
85bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  std::vector<const TemplateURL*> t_urls_using_base_url;
86bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  for (HostToURLsMap::iterator host_map_iterator = host_to_urls_map_.begin();
87bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen       host_map_iterator != host_to_urls_map_.end(); ++host_map_iterator) {
88bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    const TemplateURLSet& urls = host_map_iterator->second;
89bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    for (TemplateURLSet::const_iterator url_set_iterator = urls.begin();
90bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen         url_set_iterator != urls.end(); ++url_set_iterator) {
91bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      const TemplateURL* t_url = *url_set_iterator;
92bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      if ((t_url->url() && t_url->url()->HasGoogleBaseURLs()) ||
93bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          (t_url->suggestions_url() &&
94bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen           t_url->suggestions_url()->HasGoogleBaseURLs())) {
95bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        t_urls_using_base_url.push_back(t_url);
96bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
97bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    }
98bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
99bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
100bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  for (size_t i = 0; i < t_urls_using_base_url.size(); ++i)
101bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    RemoveByPointer(t_urls_using_base_url[i]);
102bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
103bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  for (size_t i = 0; i < t_urls_using_base_url.size(); ++i)
104bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    Add(t_urls_using_base_url[i], search_terms_data);
105bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
106bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
107bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst TemplateURL* SearchHostToURLsMap::GetTemplateURLForHost(
108bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    const std::string& host) const {
109bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(initialized_);
110bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
111bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  HostToURLsMap::const_iterator iter = host_to_urls_map_.find(host);
112bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (iter == host_to_urls_map_.end() || iter->second.empty())
113bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return NULL;
114bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return *(iter->second.begin());  // Return the 1st element.
115bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
116bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
117bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SearchHostToURLsMap::TemplateURLSet* SearchHostToURLsMap::GetURLsForHost(
118bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    const std::string& host) const {
119bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(initialized_);
120bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
121bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  HostToURLsMap::const_iterator urls_for_host = host_to_urls_map_.find(host);
122bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (urls_for_host == host_to_urls_map_.end() || urls_for_host->second.empty())
123bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return NULL;
124bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return &urls_for_host->second;
125bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
126bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
127bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SearchHostToURLsMap::RemoveByPointer(
128bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    const TemplateURL* template_url) {
129bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  for (HostToURLsMap::iterator i = host_to_urls_map_.begin();
130bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen       i != host_to_urls_map_.end(); ++i) {
131bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    TemplateURLSet::iterator url_set_iterator = i->second.find(template_url);
132bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (url_set_iterator != i->second.end()) {
133bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      i->second.erase(url_set_iterator);
134bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      if (i->second.empty())
135bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        host_to_urls_map_.erase(i);
136bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // A given TemplateURL only occurs once in the map. As soon as we find the
137bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // entry, stop.
138bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return;
139bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    }
140bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
141bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
142