| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/policy/core/common/policy_map.h" | 5 #include "components/policy/core/common/policy_map.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 bool PolicyMap::Entry::Equals(const PolicyMap::Entry& other) const { | 49 bool PolicyMap::Entry::Equals(const PolicyMap::Entry& other) const { |
| 50 return level == other.level && | 50 return level == other.level && |
| 51 scope == other.scope && | 51 scope == other.scope && |
| 52 source == other.source && // Necessary for PolicyUIHandler observers. | 52 source == other.source && // Necessary for PolicyUIHandler observers. |
| 53 // They have to update when sources change. | 53 // They have to update when sources change. |
| 54 base::Value::Equals(value, other.value) && | 54 base::Value::Equals(value, other.value) && |
| 55 ExternalDataFetcher::Equals(external_data_fetcher, | 55 ExternalDataFetcher::Equals(external_data_fetcher, |
| 56 other.external_data_fetcher); | 56 other.external_data_fetcher); |
| 57 } | 57 } |
| 58 | 58 |
| 59 PolicyMap::PolicyMapKey::PolicyMapKey() { |
| 60 } |
| 61 |
| 62 PolicyMap::PolicyMapKey::PolicyMapKey(const std::string& name_in) |
| 63 : name(name_in) { |
| 64 } |
| 65 |
| 66 PolicyMap::PolicyMapKey::PolicyMapKey(const std::string& name_in, |
| 67 PolicyLevel level_in) |
| 68 : name(name_in), level(level_in) { |
| 69 } |
| 70 |
| 71 bool PolicyMap::PolicyMapKey::operator==(const PolicyMapKey& other) const { |
| 72 return name == other.name && level == other.level; |
| 73 } |
| 74 |
| 75 bool PolicyMap::PolicyMapKey::operator<(const PolicyMapKey& other) const { |
| 76 int name_comp = name.compare(other.name); |
| 77 if (name_comp) |
| 78 return name_comp < 0; |
| 79 // Compare policy level. Should be consistent with has_higher_priority_than(). |
| 80 return level > other.level; |
| 81 } |
| 82 |
| 83 int PolicyMap::PolicyMapKey::compare(const PolicyMapKey& other) const { |
| 84 int name_comp = name.compare(other.name); |
| 85 if (name_comp) |
| 86 return name_comp; |
| 87 return level > other.level ? -1 : (level < other.level ? 1 : 0); |
| 88 } |
| 89 |
| 59 PolicyMap::PolicyMap() { | 90 PolicyMap::PolicyMap() { |
| 60 } | 91 } |
| 61 | 92 |
| 62 PolicyMap::~PolicyMap() { | 93 PolicyMap::~PolicyMap() { |
| 63 Clear(); | 94 Clear(); |
| 64 } | 95 } |
| 65 | 96 |
| 66 const PolicyMap::Entry* PolicyMap::Get(const std::string& policy) const { | 97 const PolicyMap::Entry* PolicyMap::Get(const std::string& policy) const { |
| 67 PolicyMapType::const_iterator entry = map_.find(policy); | 98 const_iterator entry = lower_bound(policy); |
| 68 return entry == map_.end() ? NULL : &entry->second; | 99 return entry == map_.end() || entry->first.name != policy ? |
| 100 nullptr : &entry->second; |
| 69 } | 101 } |
| 70 | 102 |
| 71 const base::Value* PolicyMap::GetValue(const std::string& policy) const { | 103 const base::Value* PolicyMap::GetValue(const std::string& policy) const { |
| 72 PolicyMapType::const_iterator entry = map_.find(policy); | 104 const_iterator entry = lower_bound(policy); |
| 73 return entry == map_.end() ? NULL : entry->second.value; | 105 return entry == map_.end() || entry->first.name != policy ? |
| 106 nullptr : entry->second.value; |
| 74 } | 107 } |
| 75 | 108 |
| 76 void PolicyMap::Set(const std::string& policy, | 109 void PolicyMap::Set(const std::string& policy, |
| 77 PolicyLevel level, | 110 PolicyLevel level, |
| 78 PolicyScope scope, | 111 PolicyScope scope, |
| 79 PolicySource source, | 112 PolicySource source, |
| 80 base::Value* value, | 113 base::Value* value, |
| 81 ExternalDataFetcher* external_data_fetcher) { | 114 ExternalDataFetcher* external_data_fetcher) { |
| 82 Entry& entry = map_[policy]; | 115 Entry& entry = map_[PolicyMapKey(policy, level)]; |
| 83 entry.DeleteOwnedMembers(); | 116 entry.DeleteOwnedMembers(); |
| 84 entry.level = level; | 117 entry.level = level; |
| 85 entry.scope = scope; | 118 entry.scope = scope; |
| 86 entry.source = source; | 119 entry.source = source; |
| 87 entry.value = value; | 120 entry.value = value; |
| 88 entry.external_data_fetcher = external_data_fetcher; | 121 entry.external_data_fetcher = external_data_fetcher; |
| 89 } | 122 } |
| 90 | 123 |
| 91 void PolicyMap::Erase(const std::string& policy) { | 124 void PolicyMap::Erase(const std::string& policy) { |
| 92 PolicyMapType::iterator it = map_.find(policy); | 125 PolicyMapType::iterator it = lower_bound(policy); |
| 93 if (it != map_.end()) { | 126 PolicyMapType::iterator end_it = map_.end(); |
| 127 while (it != map_.end() && it->first.name == policy) { |
| 128 PolicyMapType::iterator next_it = it; |
| 129 ++next_it; |
| 94 it->second.DeleteOwnedMembers(); | 130 it->second.DeleteOwnedMembers(); |
| 95 map_.erase(it); | 131 map_.erase(it); |
| 132 it = next_it; |
| 96 } | 133 } |
| 97 } | 134 } |
| 98 | 135 |
| 99 void PolicyMap::Swap(PolicyMap* other) { | 136 void PolicyMap::Swap(PolicyMap* other) { |
| 100 map_.swap(other->map_); | 137 map_.swap(other->map_); |
| 101 } | 138 } |
| 102 | 139 |
| 103 void PolicyMap::CopyFrom(const PolicyMap& other) { | 140 void PolicyMap::CopyFrom(const PolicyMap& other) { |
| 104 Clear(); | 141 Clear(); |
| 105 for (const_iterator it = other.begin(); it != other.end(); ++it) { | 142 for (const_iterator it = other.begin(); it != other.end(); ++it) { |
| 106 const Entry& entry = it->second; | 143 const Entry& entry = it->second; |
| 107 Set(it->first, entry.level, entry.scope, entry.source, | 144 Set(it->first.name, it->first.level, entry.scope, entry.source, |
| 108 entry.value->DeepCopy(), | 145 entry.value->DeepCopy(), |
| 109 entry.external_data_fetcher | 146 entry.external_data_fetcher |
| 110 ? new ExternalDataFetcher(*entry.external_data_fetcher) | 147 ? new ExternalDataFetcher(*entry.external_data_fetcher) |
| 111 : nullptr); | 148 : nullptr); |
| 112 } | 149 } |
| 113 } | 150 } |
| 114 | 151 |
| 115 scoped_ptr<PolicyMap> PolicyMap::DeepCopy() const { | 152 scoped_ptr<PolicyMap> PolicyMap::DeepCopy() const { |
| 116 PolicyMap* copy = new PolicyMap(); | 153 PolicyMap* copy = new PolicyMap(); |
| 117 copy->CopyFrom(*this); | 154 copy->CopyFrom(*this); |
| 118 return make_scoped_ptr(copy); | 155 return make_scoped_ptr(copy); |
| 119 } | 156 } |
| 120 | 157 |
| 121 void PolicyMap::MergeFrom(const PolicyMap& other) { | 158 void PolicyMap::MergeFrom(const PolicyMap& other) { |
| 122 for (const_iterator it = other.begin(); it != other.end(); ++it) { | 159 for (const_iterator it = other.begin(); it != other.end(); ++it) { |
| 123 const Entry* entry = Get(it->first); | 160 const_iterator this_it = map_.find(it->first); |
| 124 if (!entry || it->second.has_higher_priority_than(*entry)) { | 161 if (this_it == map_.end() || |
| 125 Set(it->first, it->second.level, it->second.scope, it->second.source, | 162 it->second.has_higher_priority_than(this_it->second)) { |
| 163 Set(it->first.name, it->first.level, it->second.scope, it->second.source, |
| 126 it->second.value->DeepCopy(), | 164 it->second.value->DeepCopy(), |
| 127 it->second.external_data_fetcher | 165 it->second.external_data_fetcher |
| 128 ? new ExternalDataFetcher( | 166 ? new ExternalDataFetcher(*it->second.external_data_fetcher) |
| 129 *it->second.external_data_fetcher) | |
| 130 : nullptr); | 167 : nullptr); |
| 131 } | 168 } |
| 132 } | 169 } |
| 133 } | 170 } |
| 134 | 171 |
| 135 void PolicyMap::LoadFrom( | 172 void PolicyMap::LoadFrom( |
| 136 const base::DictionaryValue* policies, | 173 const base::DictionaryValue* policies, |
| 137 PolicyLevel level, | 174 PolicyLevel level, |
| 138 PolicyScope scope, | 175 PolicyScope scope, |
| 139 PolicySource source) { | 176 PolicySource source) { |
| 140 for (base::DictionaryValue::Iterator it(*policies); | 177 for (base::DictionaryValue::Iterator it(*policies); |
| 141 !it.IsAtEnd(); it.Advance()) { | 178 !it.IsAtEnd(); it.Advance()) { |
| 142 Set(it.key(), level, scope, source, it.value().DeepCopy(), nullptr); | 179 Set(it.key(), level, scope, source, it.value().DeepCopy(), nullptr); |
| 143 } | 180 } |
| 144 } | 181 } |
| 145 | 182 |
| 146 void PolicyMap::GetDifferingKeys(const PolicyMap& other, | 183 void PolicyMap::GetDifferingKeys(const PolicyMap& other, |
| 147 std::set<std::string>* differing_keys) const { | 184 std::set<PolicyMap::PolicyMapKey>* differing_keys) const { |
| 148 // Walk over the maps in lockstep, adding everything that is different. | 185 // Walk over the maps in lockstep, adding everything that is different. |
| 149 const_iterator iter_this(begin()); | 186 const_iterator iter_this(begin()); |
| 150 const_iterator iter_other(other.begin()); | 187 const_iterator iter_other(other.begin()); |
| 151 while (iter_this != end() && iter_other != other.end()) { | 188 while (iter_this != end() && iter_other != other.end()) { |
| 152 const int diff = iter_this->first.compare(iter_other->first); | 189 const int diff = iter_this->first.compare(iter_other->first); |
| 153 if (diff == 0) { | 190 if (diff == 0) { |
| 154 if (!iter_this->second.Equals(iter_other->second)) | 191 if (!iter_this->second.Equals(iter_other->second)) |
| 155 differing_keys->insert(iter_this->first); | 192 differing_keys->insert(iter_this->first); |
| 156 ++iter_this; | 193 ++iter_this; |
| 157 ++iter_other; | 194 ++iter_other; |
| 158 } else if (diff < 0) { | 195 } else if (diff < 0) { |
| 159 differing_keys->insert(iter_this->first); | 196 differing_keys->insert(iter_this->first); |
| 160 ++iter_this; | 197 ++iter_this; |
| 161 } else { | 198 } else { |
| 162 differing_keys->insert(iter_other->first); | 199 differing_keys->insert(iter_other->first); |
| 163 ++iter_other; | 200 ++iter_other; |
| 164 } | 201 } |
| 165 } | 202 } |
| 166 | 203 |
| 167 // Add the remaining entries. | 204 // Add the remaining entries. |
| 168 for ( ; iter_this != end(); ++iter_this) | 205 for ( ; iter_this != end(); ++iter_this) |
| 169 differing_keys->insert(iter_this->first); | 206 differing_keys->insert(iter_this->first); |
| 170 for ( ; iter_other != other.end(); ++iter_other) | 207 for ( ; iter_other != other.end(); ++iter_other) |
| 171 differing_keys->insert(iter_other->first); | 208 differing_keys->insert(iter_other->first); |
| 172 } | 209 } |
| 173 | 210 |
| 211 void PolicyMap::GetDifferingKeyNames(const PolicyMap& other, |
| 212 std::set<std::string>* differing_key_names) const { |
| 213 std::set<PolicyMap::PolicyMapKey> differing_keys; |
| 214 GetDifferingKeys(other, &differing_keys); |
| 215 for (const auto& key : differing_keys) { |
| 216 differing_key_names->insert(key.name); |
| 217 } |
| 218 } |
| 219 |
| 174 void PolicyMap::FilterLevel(PolicyLevel level) { | 220 void PolicyMap::FilterLevel(PolicyLevel level) { |
| 175 PolicyMapType::iterator iter(map_.begin()); | 221 PolicyMapType::iterator iter(map_.begin()); |
| 176 while (iter != map_.end()) { | 222 while (iter != map_.end()) { |
| 177 if (iter->second.level != level) { | 223 if (iter->first.level != level) { |
| 178 iter->second.DeleteOwnedMembers(); | 224 iter->second.DeleteOwnedMembers(); |
| 179 map_.erase(iter++); | 225 map_.erase(iter++); |
| 180 } else { | 226 } else { |
| 181 ++iter; | 227 ++iter; |
| 182 } | 228 } |
| 183 } | 229 } |
| 184 } | 230 } |
| 185 | 231 |
| 186 bool PolicyMap::Equals(const PolicyMap& other) const { | 232 bool PolicyMap::Equals(const PolicyMap& other) const { |
| 187 return other.size() == size() && | 233 return other.size() == size() && |
| 188 std::equal(begin(), end(), other.begin(), MapEntryEquals); | 234 std::equal(begin(), end(), other.begin(), MapEntryEquals); |
| 189 } | 235 } |
| 190 | 236 |
| 191 bool PolicyMap::empty() const { | 237 bool PolicyMap::empty() const { |
| 192 return map_.empty(); | 238 return map_.empty(); |
| 193 } | 239 } |
| 194 | 240 |
| 195 size_t PolicyMap::size() const { | 241 size_t PolicyMap::size() const { |
| 196 return map_.size(); | 242 return map_.size(); |
| 197 } | 243 } |
| 198 | 244 |
| 199 PolicyMap::const_iterator PolicyMap::begin() const { | 245 PolicyMap::const_iterator PolicyMap::begin() const { |
| 200 return map_.begin(); | 246 return map_.begin(); |
| 201 } | 247 } |
| 202 | 248 |
| 203 PolicyMap::const_iterator PolicyMap::end() const { | 249 PolicyMap::const_iterator PolicyMap::end() const { |
| 204 return map_.end(); | 250 return map_.end(); |
| 205 } | 251 } |
| 206 | 252 |
| 253 void PolicyMap::next_dominant(PolicyMap::const_iterator* it) const { |
| 254 DCHECK((*it) != map_.end()); |
| 255 const std::string& prev_name = (*it)->first.name; |
| 256 do { |
| 257 ++(*it); |
| 258 } while ((*it) != map_.end() && (*it)->first.name == prev_name); |
| 259 } |
| 260 |
| 261 void PolicyMap::next_all(PolicyMap::const_iterator* it) const { |
| 262 DCHECK((*it) != map_.end()); |
| 263 ++(*it); |
| 264 } |
| 265 |
| 207 void PolicyMap::Clear() { | 266 void PolicyMap::Clear() { |
| 208 for (PolicyMapType::iterator it = map_.begin(); it != map_.end(); ++it) | 267 for (PolicyMapType::iterator it = map_.begin(); it != map_.end(); ++it) |
| 209 it->second.DeleteOwnedMembers(); | 268 it->second.DeleteOwnedMembers(); |
| 210 map_.clear(); | 269 map_.clear(); |
| 211 } | 270 } |
| 212 | 271 |
| 213 // static | 272 // static |
| 214 bool PolicyMap::MapEntryEquals(const PolicyMap::PolicyMapType::value_type& a, | 273 bool PolicyMap::MapEntryEquals(const PolicyMap::PolicyMapType::value_type& a, |
| 215 const PolicyMap::PolicyMapType::value_type& b) { | 274 const PolicyMap::PolicyMapType::value_type& b) { |
| 216 return a.first == b.first && a.second.Equals(b.second); | 275 return a.first == b.first && a.second.Equals(b.second); |
| 217 } | 276 } |
| 218 | 277 |
| 278 PolicyMap::PolicyMapType::iterator PolicyMap::lower_bound( |
| 279 const std::string& policy) { |
| 280 PolicyMapKey key(policy); |
| 281 return map_.lower_bound(key); |
| 282 } |
| 283 |
| 284 PolicyMap::const_iterator PolicyMap::lower_bound( |
| 285 const std::string& policy) const { |
| 286 PolicyMapKey key(policy); |
| 287 return map_.lower_bound(key); |
| 288 } |
| 289 |
| 219 } // namespace policy | 290 } // namespace policy |
| OLD | NEW |