Ignore title parameter for navigator.registerProtocolHandler
[chromium-blink-merge.git] / components / policy / core / common / schema_registry.cc
blobff9557956f3fcde42a78097caccd60f814d825bc
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/schema_registry.h"
7 #include "base/logging.h"
9 namespace policy {
11 SchemaRegistry::Observer::~Observer() {}
13 SchemaRegistry::SchemaRegistry() : schema_map_(new SchemaMap) {
14 for (int i = 0; i < POLICY_DOMAIN_SIZE; ++i)
15 domains_ready_[i] = false;
16 #if !defined(ENABLE_EXTENSIONS)
17 domains_ready_[POLICY_DOMAIN_EXTENSIONS] = true;
18 #endif
21 SchemaRegistry::~SchemaRegistry() {}
23 void SchemaRegistry::RegisterComponent(const PolicyNamespace& ns,
24 const Schema& schema) {
25 ComponentMap map;
26 map[ns.component_id] = schema;
27 RegisterComponents(ns.domain, map);
30 void SchemaRegistry::RegisterComponents(PolicyDomain domain,
31 const ComponentMap& components) {
32 // Don't issue notifications if nothing is being registered.
33 if (components.empty())
34 return;
35 // Assume that a schema was updated if the namespace was already registered
36 // before.
37 DomainMap map(schema_map_->GetDomains());
38 for (ComponentMap::const_iterator it = components.begin();
39 it != components.end(); ++it) {
40 map[domain][it->first] = it->second;
42 schema_map_ = new SchemaMap(map);
43 Notify(true);
46 void SchemaRegistry::UnregisterComponent(const PolicyNamespace& ns) {
47 DomainMap map(schema_map_->GetDomains());
48 if (map[ns.domain].erase(ns.component_id) != 0) {
49 schema_map_ = new SchemaMap(map);
50 Notify(false);
51 } else {
52 NOTREACHED();
56 bool SchemaRegistry::IsReady() const {
57 for (int i = 0; i < POLICY_DOMAIN_SIZE; ++i) {
58 if (!domains_ready_[i])
59 return false;
61 return true;
64 void SchemaRegistry::SetReady(PolicyDomain domain) {
65 if (domains_ready_[domain])
66 return;
67 domains_ready_[domain] = true;
68 if (IsReady())
69 FOR_EACH_OBSERVER(Observer, observers_, OnSchemaRegistryReady());
72 void SchemaRegistry::AddObserver(Observer* observer) {
73 observers_.AddObserver(observer);
76 void SchemaRegistry::RemoveObserver(Observer* observer) {
77 observers_.RemoveObserver(observer);
80 void SchemaRegistry::Notify(bool has_new_schemas) {
81 FOR_EACH_OBSERVER(
82 Observer, observers_, OnSchemaRegistryUpdated(has_new_schemas));
85 bool SchemaRegistry::HasObservers() const {
86 return observers_.might_have_observers();
89 CombinedSchemaRegistry::CombinedSchemaRegistry()
90 : own_schema_map_(new SchemaMap) {
91 // The combined registry is always ready, since it can always start tracking
92 // another registry that is not ready yet and going from "ready" to "not
93 // ready" is not allowed.
94 for (int i = 0; i < POLICY_DOMAIN_SIZE; ++i)
95 SetReady(static_cast<PolicyDomain>(i));
98 CombinedSchemaRegistry::~CombinedSchemaRegistry() {}
100 void CombinedSchemaRegistry::Track(SchemaRegistry* registry) {
101 registries_.insert(registry);
102 registry->AddObserver(this);
103 // Recombine the maps only if the |registry| has any components other than
104 // POLICY_DOMAIN_CHROME.
105 if (registry->schema_map()->HasComponents())
106 Combine(true);
109 void CombinedSchemaRegistry::Untrack(SchemaRegistry* registry) {
110 registry->RemoveObserver(this);
111 if (registries_.erase(registry) != 0) {
112 if (registry->schema_map()->HasComponents())
113 Combine(false);
114 } else {
115 NOTREACHED();
119 void CombinedSchemaRegistry::RegisterComponents(
120 PolicyDomain domain,
121 const ComponentMap& components) {
122 DomainMap map(own_schema_map_->GetDomains());
123 for (ComponentMap::const_iterator it = components.begin();
124 it != components.end(); ++it) {
125 map[domain][it->first] = it->second;
127 own_schema_map_ = new SchemaMap(map);
128 Combine(true);
131 void CombinedSchemaRegistry::UnregisterComponent(const PolicyNamespace& ns) {
132 DomainMap map(own_schema_map_->GetDomains());
133 if (map[ns.domain].erase(ns.component_id) != 0) {
134 own_schema_map_ = new SchemaMap(map);
135 Combine(false);
136 } else {
137 NOTREACHED();
141 void CombinedSchemaRegistry::OnSchemaRegistryUpdated(bool has_new_schemas) {
142 Combine(has_new_schemas);
145 void CombinedSchemaRegistry::OnSchemaRegistryReady() {
146 // Ignore.
149 void CombinedSchemaRegistry::Combine(bool has_new_schemas) {
150 // If two registries publish a Schema for the same component then it's
151 // undefined which version gets in the combined registry.
153 // The common case is that both registries want policy for the same component,
154 // and the Schemas should be the same; in that case this makes no difference.
156 // But if the Schemas are different then one of the components is out of date.
157 // In that case the policy loaded will be valid only for one of them, until
158 // the outdated components are updated. This is a known limitation of the
159 // way policies are loaded currently, but isn't a problem worth fixing for
160 // the time being.
161 DomainMap map(own_schema_map_->GetDomains());
162 for (std::set<SchemaRegistry*>::const_iterator reg_it = registries_.begin();
163 reg_it != registries_.end(); ++reg_it) {
164 const DomainMap& reg_domain_map = (*reg_it)->schema_map()->GetDomains();
165 for (DomainMap::const_iterator domain_it = reg_domain_map.begin();
166 domain_it != reg_domain_map.end(); ++domain_it) {
167 const ComponentMap& reg_component_map = domain_it->second;
168 for (ComponentMap::const_iterator comp_it = reg_component_map.begin();
169 comp_it != reg_component_map.end(); ++comp_it) {
170 map[domain_it->first][comp_it->first] = comp_it->second;
174 schema_map_ = new SchemaMap(map);
175 Notify(has_new_schemas);
178 } // namespace policy