Add abhijeet.k@samsung.com to AUTHORS list.
[chromium-blink-merge.git] / components / policy / core / common / policy_map.cc
blob5e1fd5b06375e385c61a8bb66bd9b67e702c1ea6
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.
5 #include "components/policy/core/common/policy_map.h"
7 #include <algorithm>
9 #include "base/callback.h"
10 #include "base/stl_util.h"
12 namespace policy {
14 PolicyMap::Entry::Entry()
15 : level(POLICY_LEVEL_RECOMMENDED),
16 scope(POLICY_SCOPE_USER),
17 value(NULL),
18 external_data_fetcher(NULL) {}
20 void PolicyMap::Entry::DeleteOwnedMembers() {
21 delete value;
22 value = NULL;
23 delete external_data_fetcher;
24 external_data_fetcher = NULL;
27 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);
37 return copy.Pass();
40 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;
48 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);
56 PolicyMap::PolicyMap() {
59 PolicyMap::~PolicyMap() {
60 Clear();
63 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;
68 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;
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;
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);
94 void PolicyMap::Swap(PolicyMap* other) {
95 map_.swap(other->map_);
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);
108 scoped_ptr<PolicyMap> PolicyMap::DeepCopy() const {
109 PolicyMap* copy = new PolicyMap();
110 copy->CopyFrom(*this);
111 return make_scoped_ptr(copy);
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);
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);
136 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;
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);
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;
176 bool PolicyMap::Equals(const PolicyMap& other) const {
177 return other.size() == size() &&
178 std::equal(begin(), end(), other.begin(), MapEntryEquals);
181 bool PolicyMap::empty() const {
182 return map_.empty();
185 size_t PolicyMap::size() const {
186 return map_.size();
189 PolicyMap::const_iterator PolicyMap::begin() const {
190 return map_.begin();
193 PolicyMap::const_iterator PolicyMap::end() const {
194 return map_.end();
197 void PolicyMap::Clear() {
198 for (PolicyMapType::iterator it = map_.begin(); it != map_.end(); ++it)
199 it->second.DeleteOwnedMembers();
200 map_.clear();
203 // static
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);
209 } // namespace policy