• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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 "components/policy/core/common/policy_map.h"
6 
7 #include <algorithm>
8 
9 #include "base/callback.h"
10 #include "base/stl_util.h"
11 
12 namespace policy {
13 
Entry()14 PolicyMap::Entry::Entry()
15     : level(POLICY_LEVEL_RECOMMENDED),
16       scope(POLICY_SCOPE_USER),
17       value(NULL),
18       external_data_fetcher(NULL) {}
19 
DeleteOwnedMembers()20 void PolicyMap::Entry::DeleteOwnedMembers() {
21   delete value;
22   value = NULL;
23   delete external_data_fetcher;
24   external_data_fetcher = NULL;
25 }
26 
DeepCopy() const27 scoped_ptr<PolicyMap::Entry> PolicyMap::Entry::DeepCopy() const {
28   scoped_ptr<Entry> copy(new Entry);
29   copy->level = level;
30   copy->scope = scope;
31   if (value)
32     copy->value = value->DeepCopy();
33   if (external_data_fetcher) {
34     copy->external_data_fetcher =
35         new ExternalDataFetcher(*external_data_fetcher);
36   }
37   return copy.Pass();
38 }
39 
has_higher_priority_than(const PolicyMap::Entry & other) const40 bool PolicyMap::Entry::has_higher_priority_than(
41     const PolicyMap::Entry& other) const {
42   if (level == other.level)
43     return scope > other.scope;
44   else
45     return level > other.level;
46 }
47 
Equals(const PolicyMap::Entry & other) const48 bool PolicyMap::Entry::Equals(const PolicyMap::Entry& other) const {
49   return level == other.level &&
50          scope == other.scope &&
51          base::Value::Equals(value, other.value) &&
52          ExternalDataFetcher::Equals(external_data_fetcher,
53                                      other.external_data_fetcher);
54 }
55 
PolicyMap()56 PolicyMap::PolicyMap() {
57 }
58 
~PolicyMap()59 PolicyMap::~PolicyMap() {
60   Clear();
61 }
62 
Get(const std::string & policy) const63 const PolicyMap::Entry* PolicyMap::Get(const std::string& policy) const {
64   PolicyMapType::const_iterator entry = map_.find(policy);
65   return entry == map_.end() ? NULL : &entry->second;
66 }
67 
GetValue(const std::string & policy) const68 const base::Value* PolicyMap::GetValue(const std::string& policy) const {
69   PolicyMapType::const_iterator entry = map_.find(policy);
70   return entry == map_.end() ? NULL : entry->second.value;
71 }
72 
Set(const std::string & policy,PolicyLevel level,PolicyScope scope,base::Value * value,ExternalDataFetcher * external_data_fetcher)73 void PolicyMap::Set(const std::string& policy,
74                     PolicyLevel level,
75                     PolicyScope scope,
76                     base::Value* value,
77                     ExternalDataFetcher* external_data_fetcher) {
78   Entry& entry = map_[policy];
79   entry.DeleteOwnedMembers();
80   entry.level = level;
81   entry.scope = scope;
82   entry.value = value;
83   entry.external_data_fetcher = external_data_fetcher;
84 }
85 
Erase(const std::string & policy)86 void PolicyMap::Erase(const std::string& policy) {
87   PolicyMapType::iterator it = map_.find(policy);
88   if (it != map_.end()) {
89     it->second.DeleteOwnedMembers();
90     map_.erase(it);
91   }
92 }
93 
Swap(PolicyMap * other)94 void PolicyMap::Swap(PolicyMap* other) {
95   map_.swap(other->map_);
96 }
97 
CopyFrom(const PolicyMap & other)98 void PolicyMap::CopyFrom(const PolicyMap& other) {
99   Clear();
100   for (const_iterator it = other.begin(); it != other.end(); ++it) {
101     const Entry& entry = it->second;
102     Set(it->first, entry.level, entry.scope,
103         entry.value->DeepCopy(), entry.external_data_fetcher ?
104             new ExternalDataFetcher(*entry.external_data_fetcher) : NULL);
105   }
106 }
107 
DeepCopy() const108 scoped_ptr<PolicyMap> PolicyMap::DeepCopy() const {
109   PolicyMap* copy = new PolicyMap();
110   copy->CopyFrom(*this);
111   return make_scoped_ptr(copy);
112 }
113 
MergeFrom(const PolicyMap & other)114 void PolicyMap::MergeFrom(const PolicyMap& other) {
115   for (const_iterator it = other.begin(); it != other.end(); ++it) {
116     const Entry* entry = Get(it->first);
117     if (!entry || it->second.has_higher_priority_than(*entry)) {
118       Set(it->first, it->second.level, it->second.scope,
119           it->second.value->DeepCopy(), it->second.external_data_fetcher ?
120               new ExternalDataFetcher(*it->second.external_data_fetcher) :
121               NULL);
122     }
123   }
124 }
125 
LoadFrom(const base::DictionaryValue * policies,PolicyLevel level,PolicyScope scope)126 void PolicyMap::LoadFrom(
127     const base::DictionaryValue* policies,
128     PolicyLevel level,
129     PolicyScope scope) {
130   for (base::DictionaryValue::Iterator it(*policies);
131        !it.IsAtEnd(); it.Advance()) {
132     Set(it.key(), level, scope, it.value().DeepCopy(), NULL);
133   }
134 }
135 
GetDifferingKeys(const PolicyMap & other,std::set<std::string> * differing_keys) const136 void PolicyMap::GetDifferingKeys(const PolicyMap& other,
137                                  std::set<std::string>* differing_keys) const {
138   // Walk over the maps in lockstep, adding everything that is different.
139   const_iterator iter_this(begin());
140   const_iterator iter_other(other.begin());
141   while (iter_this != end() && iter_other != other.end()) {
142     const int diff = iter_this->first.compare(iter_other->first);
143     if (diff == 0) {
144       if (!iter_this->second.Equals(iter_other->second))
145         differing_keys->insert(iter_this->first);
146       ++iter_this;
147       ++iter_other;
148     } else if (diff < 0) {
149       differing_keys->insert(iter_this->first);
150       ++iter_this;
151     } else {
152       differing_keys->insert(iter_other->first);
153       ++iter_other;
154     }
155   }
156 
157   // Add the remaining entries.
158   for ( ; iter_this != end(); ++iter_this)
159       differing_keys->insert(iter_this->first);
160   for ( ; iter_other != other.end(); ++iter_other)
161       differing_keys->insert(iter_other->first);
162 }
163 
FilterLevel(PolicyLevel level)164 void PolicyMap::FilterLevel(PolicyLevel level) {
165   PolicyMapType::iterator iter(map_.begin());
166   while (iter != map_.end()) {
167     if (iter->second.level != level) {
168       iter->second.DeleteOwnedMembers();
169       map_.erase(iter++);
170     } else {
171       ++iter;
172     }
173   }
174 }
175 
Equals(const PolicyMap & other) const176 bool PolicyMap::Equals(const PolicyMap& other) const {
177   return other.size() == size() &&
178       std::equal(begin(), end(), other.begin(), MapEntryEquals);
179 }
180 
empty() const181 bool PolicyMap::empty() const {
182   return map_.empty();
183 }
184 
size() const185 size_t PolicyMap::size() const {
186   return map_.size();
187 }
188 
begin() const189 PolicyMap::const_iterator PolicyMap::begin() const {
190   return map_.begin();
191 }
192 
end() const193 PolicyMap::const_iterator PolicyMap::end() const {
194   return map_.end();
195 }
196 
Clear()197 void PolicyMap::Clear() {
198   for (PolicyMapType::iterator it = map_.begin(); it != map_.end(); ++it)
199     it->second.DeleteOwnedMembers();
200   map_.clear();
201 }
202 
203 // static
MapEntryEquals(const PolicyMap::PolicyMapType::value_type & a,const PolicyMap::PolicyMapType::value_type & b)204 bool PolicyMap::MapEntryEquals(const PolicyMap::PolicyMapType::value_type& a,
205                                const PolicyMap::PolicyMapType::value_type& b) {
206   return a.first == b.first && a.second.Equals(b.second);
207 }
208 
209 }  // namespace policy
210