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 12 SearchHostToURLsMap::SearchHostToURLsMap() 13 : initialized_(false) { 14 } 15 16 SearchHostToURLsMap::~SearchHostToURLsMap() { 17 } 18 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 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 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 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 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 107 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 117 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 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