Chromium Code Reviews| Index: chrome/browser/extensions/api/declarative/initializing_rules_registry.cc |
| diff --git a/chrome/browser/extensions/api/declarative/initializing_rules_registry.cc b/chrome/browser/extensions/api/declarative/initializing_rules_registry.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b895197189b3f29a63b2af55345bbd54eff74368 |
| --- /dev/null |
| +++ b/chrome/browser/extensions/api/declarative/initializing_rules_registry.cc |
| @@ -0,0 +1,134 @@ |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/extensions/api/declarative/initializing_rules_registry.h" |
| + |
| +#include "base/logging.h" |
| +#include "base/stl_util.h" |
| +#include "base/string_number_conversions.h" |
| +#include "chrome/browser/extensions/api/declarative/declarative_api_constants.h" |
| +#include "chrome/browser/extensions/api/declarative/rule_identifier.h" |
| + |
| +namespace keys = extensions::declarative_api_constants; |
| + |
| +namespace { |
| + std::string ToId(int identifier) { |
| + return "_" + base::IntToString(identifier) + "_"; |
|
not at google - send to devlin
2012/02/07 03:25:10
I think c++ will automatically cast int -> std::st
battre
2012/02/07 18:45:33
No.
not at google - send to devlin
2012/02/07 23:54:57
Yeah, that's not what I meant though, just uninden
|
| + } |
| +} |
| + |
| +namespace extensions { |
| + |
| +InitializingRulesRegistry::InitializingRulesRegistry( |
| + scoped_ptr<RulesRegistry> delegate) |
| + : delegate_(delegate.Pass()), |
|
not at google - send to devlin
2012/02/07 03:25:10
I don't think you need the .Pass().
battre
2012/02/07 18:45:33
I do: error: 'scoped_ptr<C>::scoped_ptr(scoped_ptr
not at google - send to devlin
2012/02/07 23:54:57
cool, good to know.
|
| + last_generated_rule_identifier_id_(0) { |
| +} |
| + |
| +InitializingRulesRegistry::~InitializingRulesRegistry() {} |
| + |
| +bool InitializingRulesRegistry::AddRules( |
| + const std::string& extension_id, |
| + const std::vector<DictionaryValue*>& rules, |
| + std::string* error) { |
| + if (!CheckAndFillInOptionalRules(extension_id, rules, error)) |
| + return false; |
| + FillInOptionalPriorities(rules); |
| + return delegate_->AddRules(extension_id, rules, error); |
| +} |
| + |
| +bool InitializingRulesRegistry::RemoveRules( |
| + const std::string& extension_id, |
| + const std::vector<std::string>& rule_identifiers, |
| + std::string* error) { |
| + if (!delegate_->RemoveRules(extension_id, rule_identifiers, error)) |
| + return false; |
| + RemoveUsedRuleIdentifiers(extension_id, rule_identifiers); |
| + return true; |
| +} |
| + |
| +void InitializingRulesRegistry::GetRules( |
| + const std::string& extension_id, |
| + const std::vector<std::string>& rule_identifiers, |
| + std::vector<DictionaryValue*>* out) { |
| + delegate_->GetRules(extension_id, rule_identifiers, out); |
| +} |
| + |
| +void InitializingRulesRegistry::OnExtensionUnloaded( |
| + const std::string& extension_id) { |
| + delegate_->OnExtensionUnloaded(extension_id); |
| +} |
| + |
| +bool InitializingRulesRegistry::IsUniqueId(const RuleIdentifier& id) const { |
| + return used_rule_identifiers_.find(id) == used_rule_identifiers_.end(); |
| +} |
| + |
| +std::string InitializingRulesRegistry::GenerateUniqueId( |
| + std::string extension_id) { |
| + while ( |
| + !IsUniqueId( |
| + RuleIdentifier(extension_id, |
| + ToId(last_generated_rule_identifier_id_)))) { |
|
not at google - send to devlin
2012/02/07 03:25:10
indentation doesn't need to be this whitespacey?
battre
2012/02/07 18:45:33
Hm, I am not a big fan of arbitrary line breaks. B
|
| + ++last_generated_rule_identifier_id_; |
| + } |
| + RuleIdentifier new_id(extension_id, |
| + ToId(last_generated_rule_identifier_id_)); |
| + used_rule_identifiers_.insert(new_id); |
| + return new_id.rule_id(); |
| +} |
| + |
| +void InitializingRulesRegistry::RemoveUsedRuleIdentifiers( |
| + const std::string& extension_id, |
| + const std::vector<std::string>& identifiers) { |
| + std::vector<std::string>::const_iterator i; |
| + for (i = identifiers.begin(); i != identifiers.end(); ++i) |
| + used_rule_identifiers_.erase(RuleIdentifier(extension_id, *i)); |
| +} |
| + |
| +bool InitializingRulesRegistry::CheckAndFillInOptionalRules( |
| + const std::string& extension_id, |
| + const std::vector<DictionaryValue*>& rules, |
| + std::string* error) { |
| + // IDs we have inserted, in case we need to rollback this operation. |
| + std::vector<std::string> rollback_log; |
| + |
| + std::vector<DictionaryValue*>::const_iterator i; |
| + |
| + // First we insert all rules with existing identifier, so that generated |
| + // identifiers cannot collide with identifiers passed by the caller. |
| + for (i = rules.begin(); i != rules.end(); ++i) { |
| + DictionaryValue* rule = *i; |
| + if (rule->HasKey(keys::kId)) { |
| + std::string id; |
| + CHECK(rule->GetString(keys::kId, &id)); |
| + RuleIdentifier rule_identifier(extension_id, id); |
| + if (!IsUniqueId(rule_identifier)) { |
| + *error = "Id " + id + " was used multiple times."; |
| + RemoveUsedRuleIdentifiers(extension_id, rollback_log); |
| + return false; |
| + } |
| + used_rule_identifiers_.insert(rule_identifier); |
| + } |
| + } |
| + // Now we generate IDs in case they were not specificed in the rules. This |
| + // cannot fail so we do not need to keep track of a rollback log. |
| + for (i = rules.begin(); i != rules.end(); ++i) { |
| + DictionaryValue* rule = *i; |
| + if (!rule->HasKey(keys::kId)) |
| + rule->SetString(keys::kId, GenerateUniqueId(extension_id)); |
| + } |
| + return true; |
| +} |
| + |
| +void InitializingRulesRegistry::FillInOptionalPriorities( |
| + const std::vector<DictionaryValue*>& rules) { |
| + std::vector<DictionaryValue*>::const_iterator i; |
| + for (i = rules.begin(); i != rules.end(); ++i) { |
| + DictionaryValue* rule = *i; |
| + if (!rule->HasKey(keys::kPriority)) |
| + rule->SetInteger(keys::kPriority, 100); |
| + } |
| +} |
| + |
| +} // namespace extensions |