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