1// Copyright (c) 2012 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/common/extensions/extension_set.h"
6
7#include "base/logging.h"
8#include "base/stl_util.h"
9#include "chrome/common/extensions/extension.h"
10#include "chrome/common/extensions/manifest_handlers/sandboxed_page_info.h"
11#include "chrome/common/url_constants.h"
12#include "extensions/common/constants.h"
13
14using extensions::Extension;
15
16ExtensionSet::const_iterator::const_iterator() {}
17
18ExtensionSet::const_iterator::const_iterator(const const_iterator& other)
19    : it_(other.it_) {
20}
21
22ExtensionSet::const_iterator::const_iterator(ExtensionMap::const_iterator it)
23    : it_(it) {
24}
25
26ExtensionSet::ExtensionSet() {
27}
28
29ExtensionSet::~ExtensionSet() {
30}
31
32size_t ExtensionSet::size() const {
33  return extensions_.size();
34}
35
36bool ExtensionSet::is_empty() const {
37  return extensions_.empty();
38}
39
40bool ExtensionSet::Contains(const std::string& extension_id) const {
41  return extensions_.find(extension_id) != extensions_.end();
42}
43
44bool ExtensionSet::Insert(const scoped_refptr<const Extension>& extension) {
45  bool was_present = ContainsKey(extensions_, extension->id());
46  extensions_[extension->id()] = extension;
47  return !was_present;
48}
49
50bool ExtensionSet::InsertAll(const ExtensionSet& extensions) {
51  size_t before = size();
52  for (ExtensionSet::const_iterator iter = extensions.begin();
53       iter != extensions.end(); ++iter) {
54    Insert(*iter);
55  }
56  return size() != before;
57}
58
59bool ExtensionSet::Remove(const std::string& id) {
60  return extensions_.erase(id) > 0;
61}
62
63void ExtensionSet::Clear() {
64  extensions_.clear();
65}
66
67std::string ExtensionSet::GetExtensionOrAppIDByURL(const GURL& url) const {
68  if (url.SchemeIs(extensions::kExtensionScheme))
69    return url.host();
70
71  const Extension* extension = GetExtensionOrAppByURL(url);
72  if (!extension)
73    return std::string();
74
75  return extension->id();
76}
77
78const Extension* ExtensionSet::GetExtensionOrAppByURL(const GURL& url) const {
79  if (url.SchemeIs(extensions::kExtensionScheme))
80    return GetByID(url.host());
81
82  return GetHostedAppByURL(url);
83}
84
85const Extension* ExtensionSet::GetHostedAppByURL(const GURL& url) const {
86  for (ExtensionMap::const_iterator iter = extensions_.begin();
87       iter != extensions_.end(); ++iter) {
88    if (iter->second->web_extent().MatchesURL(url))
89      return iter->second.get();
90  }
91
92  return NULL;
93}
94
95const Extension* ExtensionSet::GetHostedAppByOverlappingWebExtent(
96    const extensions::URLPatternSet& extent) const {
97  for (ExtensionMap::const_iterator iter = extensions_.begin();
98       iter != extensions_.end(); ++iter) {
99    if (iter->second->web_extent().OverlapsWith(extent))
100      return iter->second.get();
101  }
102
103  return NULL;
104}
105
106bool ExtensionSet::InSameExtent(const GURL& old_url,
107                                const GURL& new_url) const {
108  return GetExtensionOrAppByURL(old_url) ==
109      GetExtensionOrAppByURL(new_url);
110}
111
112const Extension* ExtensionSet::GetByID(const std::string& id) const {
113  ExtensionMap::const_iterator i = extensions_.find(id);
114  if (i != extensions_.end())
115    return i->second.get();
116  else
117    return NULL;
118}
119
120std::set<std::string> ExtensionSet::GetIDs() const {
121  std::set<std::string> ids;
122  for (ExtensionMap::const_iterator it = extensions_.begin();
123       it != extensions_.end(); ++it) {
124    ids.insert(it->first);
125  }
126  return ids;
127}
128
129bool ExtensionSet::ExtensionBindingsAllowed(const GURL& url) const {
130  if (url.SchemeIs(extensions::kExtensionScheme))
131    return true;
132
133  ExtensionMap::const_iterator i = extensions_.begin();
134  for (; i != extensions_.end(); ++i) {
135    if (i->second->location() == extensions::Manifest::COMPONENT &&
136        i->second->web_extent().MatchesURL(url))
137      return true;
138  }
139
140  return false;
141}
142