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