policy_map.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_map.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/callback.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PolicyMap::Entry::DeleteOwnedMembers() { 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) delete value; 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) value = NULL; 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) delete external_data_fetcher; 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) external_data_fetcher = NULL; 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)scoped_ptr<PolicyMap::Entry> PolicyMap::Entry::DeepCopy() const { 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<Entry> copy(new Entry); 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) copy->level = level; 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) copy->scope = scope; 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (value) 26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) copy->value = value->DeepCopy(); 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (external_data_fetcher) { 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) copy->external_data_fetcher = 29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new ExternalDataFetcher(*external_data_fetcher); 30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return copy.Pass(); 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PolicyMap::Entry::has_higher_priority_than( 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PolicyMap::Entry& other) const { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (level == other.level) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scope > other.scope; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return level > other.level; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PolicyMap::Entry::Equals(const PolicyMap::Entry& other) const { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return level == other.level && 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scope == other.scope && 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Value::Equals(value, other.value) && 467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ExternalDataFetcher::Equals(external_data_fetcher, 477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch other.external_data_fetcher); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyMap::PolicyMap() { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyMap::~PolicyMap() { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Clear(); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PolicyMap::Entry* PolicyMap::Get(const std::string& policy) const { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyMapType::const_iterator entry = map_.find(policy); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return entry == map_.end() ? NULL : &entry->second; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Value* PolicyMap::GetValue(const std::string& policy) const { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyMapType::const_iterator entry = map_.find(policy); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return entry == map_.end() ? NULL : entry->second.value; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyMap::Set(const std::string& policy, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyLevel level, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyScope scope, 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Value* value, 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ExternalDataFetcher* external_data_fetcher) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Entry& entry = map_[policy]; 73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) entry.DeleteOwnedMembers(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.level = level; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.scope = scope; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.value = value; 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch entry.external_data_fetcher = external_data_fetcher; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyMap::Erase(const std::string& policy) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyMapType::iterator it = map_.find(policy); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != map_.end()) { 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) it->second.DeleteOwnedMembers(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map_.erase(it); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyMap::Swap(PolicyMap* other) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map_.swap(other->map_); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyMap::CopyFrom(const PolicyMap& other) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Clear(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (const_iterator it = other.begin(); it != other.end(); ++it) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Entry& entry = it->second; 967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Set(it->first, entry.level, entry.scope, 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch entry.value->DeepCopy(), entry.external_data_fetcher ? 987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch new ExternalDataFetcher(*entry.external_data_fetcher) : NULL); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<PolicyMap> PolicyMap::DeepCopy() const { 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyMap* copy = new PolicyMap(); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) copy->CopyFrom(*this); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return make_scoped_ptr(copy); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyMap::MergeFrom(const PolicyMap& other) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (const_iterator it = other.begin(); it != other.end(); ++it) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Entry* entry = Get(it->first); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry || it->second.has_higher_priority_than(*entry)) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Set(it->first, it->second.level, it->second.scope, 1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch it->second.value->DeepCopy(), it->second.external_data_fetcher ? 1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch new ExternalDataFetcher(*it->second.external_data_fetcher) : 1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NULL); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyMap::LoadFrom( 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DictionaryValue* policies, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyLevel level, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyScope scope) { 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (DictionaryValue::Iterator it(*policies); !it.IsAtEnd(); it.Advance()) 1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Set(it.key(), level, scope, it.value().DeepCopy(), NULL); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyMap::GetDifferingKeys(const PolicyMap& other, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<std::string>* differing_keys) const { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Walk over the maps in lockstep, adding everything that is different. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_iterator iter_this(begin()); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_iterator iter_other(other.begin()); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (iter_this != end() && iter_other != other.end()) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int diff = iter_this->first.compare(iter_other->first); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (diff == 0) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!iter_this->second.Equals(iter_other->second)) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) differing_keys->insert(iter_this->first); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++iter_this; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++iter_other; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (diff < 0) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) differing_keys->insert(iter_this->first); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++iter_this; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) differing_keys->insert(iter_other->first); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++iter_other; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the remaining entries. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for ( ; iter_this != end(); ++iter_this) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) differing_keys->insert(iter_this->first); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for ( ; iter_other != other.end(); ++iter_other) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) differing_keys->insert(iter_other->first); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyMap::FilterLevel(PolicyLevel level) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyMapType::iterator iter(map_.begin()); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (iter != map_.end()) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter->second.level != level) { 160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) iter->second.DeleteOwnedMembers(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map_.erase(iter++); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++iter; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PolicyMap::Equals(const PolicyMap& other) const { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return other.size() == size() && 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::equal(begin(), end(), other.begin(), MapEntryEquals); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PolicyMap::empty() const { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return map_.empty(); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t PolicyMap::size() const { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return map_.size(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyMap::const_iterator PolicyMap::begin() const { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return map_.begin(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyMap::const_iterator PolicyMap::end() const { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return map_.end(); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyMap::Clear() { 190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (PolicyMapType::iterator it = map_.begin(); it != map_.end(); ++it) 191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) it->second.DeleteOwnedMembers(); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map_.clear(); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PolicyMap::MapEntryEquals(const PolicyMap::PolicyMapType::value_type& a, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PolicyMap::PolicyMapType::value_type& b) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return a.first == b.first && a.second.Equals(b.second); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace policy 202