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"
9 #include "base/callback.h"
10 #include "base/stl_util.h"
14 PolicyMap::Entry::Entry()
15 : level(POLICY_LEVEL_RECOMMENDED
),
16 scope(POLICY_SCOPE_USER
),
18 external_data_fetcher(NULL
) {}
20 void PolicyMap::Entry::DeleteOwnedMembers() {
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
);
32 copy
->value
= value
->DeepCopy();
33 if (external_data_fetcher
) {
34 copy
->external_data_fetcher
=
35 new ExternalDataFetcher(*external_data_fetcher
);
40 bool PolicyMap::Entry::has_higher_priority_than(
41 const PolicyMap::Entry
& other
) const {
42 if (level
== other
.level
)
43 return scope
> other
.scope
;
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() {
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
,
77 ExternalDataFetcher
* external_data_fetcher
) {
78 Entry
& entry
= map_
[policy
];
79 entry
.DeleteOwnedMembers();
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();
94 void PolicyMap::Swap(PolicyMap
* other
) {
95 map_
.swap(other
->map_
);
98 void PolicyMap::CopyFrom(const PolicyMap
& other
) {
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
) :
126 void PolicyMap::LoadFrom(
127 const base::DictionaryValue
* policies
,
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
);
144 if (!iter_this
->second
.Equals(iter_other
->second
))
145 differing_keys
->insert(iter_this
->first
);
148 } else if (diff
< 0) {
149 differing_keys
->insert(iter_this
->first
);
152 differing_keys
->insert(iter_other
->first
);
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();
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 {
185 size_t PolicyMap::size() const {
189 PolicyMap::const_iterator
PolicyMap::begin() const {
193 PolicyMap::const_iterator
PolicyMap::end() const {
197 void PolicyMap::Clear() {
198 for (PolicyMapType::iterator it
= map_
.begin(); it
!= map_
.end(); ++it
)
199 it
->second
.DeleteOwnedMembers();
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