Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/common/extensions/features/base_feature_provider.h" | 5 #include "chrome/common/extensions/features/base_feature_provider.h" |
| 6 | 6 |
| 7 #include <stack> | |
| 8 | |
| 7 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
| 8 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 11 #include "base/strings/string_split.h" | |
| 12 #include "base/strings/string_util.h" | |
| 9 #include "chrome/common/extensions/features/api_feature.h" | 13 #include "chrome/common/extensions/features/api_feature.h" |
| 10 #include "chrome/common/extensions/features/complex_feature.h" | 14 #include "chrome/common/extensions/features/complex_feature.h" |
| 11 #include "chrome/common/extensions/features/manifest_feature.h" | 15 #include "chrome/common/extensions/features/manifest_feature.h" |
| 12 #include "chrome/common/extensions/features/permission_feature.h" | 16 #include "chrome/common/extensions/features/permission_feature.h" |
| 13 #include "grit/common_resources.h" | 17 #include "grit/common_resources.h" |
| 14 #include "ui/base/resource/resource_bundle.h" | 18 #include "ui/base/resource/resource_bundle.h" |
| 15 | 19 |
| 16 namespace extensions { | 20 namespace extensions { |
| 17 | 21 |
| 18 namespace { | 22 namespace { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 29 int resource_id) | 33 int resource_id) |
| 30 : name_(name), | 34 : name_(name), |
| 31 factory_(factory), | 35 factory_(factory), |
| 32 resource_id_(resource_id) { | 36 resource_id_(resource_id) { |
| 33 } | 37 } |
| 34 | 38 |
| 35 virtual Feature* GetFeature(const std::string& name) OVERRIDE { | 39 virtual Feature* GetFeature(const std::string& name) OVERRIDE { |
| 36 return GetBaseFeatureProvider()->GetFeature(name); | 40 return GetBaseFeatureProvider()->GetFeature(name); |
| 37 } | 41 } |
| 38 | 42 |
| 39 virtual std::set<std::string> GetAllFeatureNames() OVERRIDE { | 43 virtual const std::vector<std::string>& GetAllFeatureNames() OVERRIDE { |
| 40 return GetBaseFeatureProvider()->GetAllFeatureNames(); | 44 return GetBaseFeatureProvider()->GetAllFeatureNames(); |
| 41 } | 45 } |
| 42 | 46 |
| 43 private: | 47 private: |
| 44 BaseFeatureProvider* GetBaseFeatureProvider() { | 48 BaseFeatureProvider* GetBaseFeatureProvider() { |
| 45 if (!features_) | 49 if (!features_) |
| 46 features_ = LoadProvider(); | 50 features_ = LoadProvider(); |
| 47 return features_.get(); | 51 return features_.get(); |
| 48 } | 52 } |
| 49 | 53 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 } // namespace | 122 } // namespace |
| 119 | 123 |
| 120 BaseFeatureProvider::BaseFeatureProvider(const DictionaryValue& root, | 124 BaseFeatureProvider::BaseFeatureProvider(const DictionaryValue& root, |
| 121 FeatureFactory factory) | 125 FeatureFactory factory) |
| 122 : factory_(factory ? factory : | 126 : factory_(factory ? factory : |
| 123 static_cast<FeatureFactory>(&CreateFeature<SimpleFeature>)) { | 127 static_cast<FeatureFactory>(&CreateFeature<SimpleFeature>)) { |
| 124 for (DictionaryValue::Iterator iter(root); !iter.IsAtEnd(); iter.Advance()) { | 128 for (DictionaryValue::Iterator iter(root); !iter.IsAtEnd(); iter.Advance()) { |
| 125 if (iter.value().GetType() == Value::TYPE_DICTIONARY) { | 129 if (iter.value().GetType() == Value::TYPE_DICTIONARY) { |
| 126 linked_ptr<SimpleFeature> feature((*factory_)()); | 130 linked_ptr<SimpleFeature> feature((*factory_)()); |
| 127 | 131 |
| 128 if (!ParseFeature(static_cast<const DictionaryValue*>(&iter.value()), | 132 std::vector<std::string> split; |
| 129 iter.key(), | 133 base::SplitString(iter.key(), '.', &split); |
| 130 feature.get())) | 134 |
| 135 // Push parent features on the stack, starting with the current feature. | |
| 136 // If one of the features has "noparent" set, stop pushing features on | |
| 137 // the stack. The features will then be parsed in order, starting with | |
| 138 // the farthest parent that is either top level or has "noparent" set. | |
| 139 std::stack<std::pair<std::string, const DictionaryValue*> > parse_stack; | |
| 140 while (!split.empty()) { | |
| 141 std::string parent_name = JoinString(split, '.'); | |
| 142 split.pop_back(); | |
| 143 if (root.HasKey(parent_name)) { | |
| 144 const DictionaryValue* parent = NULL; | |
| 145 CHECK(root.GetDictionaryWithoutPathExpansion(parent_name, &parent)); | |
| 146 parse_stack.push(std::make_pair(parent_name, parent)); | |
| 147 bool no_parent = false; | |
| 148 parent->GetBoolean("noparent", &no_parent); | |
| 149 if (no_parent) | |
| 150 break; | |
| 151 } | |
| 152 } | |
| 153 | |
| 154 CHECK(!parse_stack.empty()); | |
| 155 // Parse all parent features. | |
| 156 feature->SetHasParent(parse_stack.size() > 1); | |
|
cduvall
2013/06/12 01:22:19
Instead of using SetHasParent() here, and then usi
not at google - send to devlin
2013/06/12 22:34:18
The only thing I'm worried about is that the paren
cduvall
2013/06/13 01:02:28
Done.
| |
| 157 bool parse_error = false; | |
| 158 while (!parse_stack.empty()) { | |
| 159 if (!ParseFeature(parse_stack.top().second, | |
| 160 parse_stack.top().first, | |
| 161 feature.get())) { | |
| 162 parse_error = true; | |
| 163 break; | |
| 164 } | |
| 165 parse_stack.pop(); | |
| 166 } | |
| 167 | |
| 168 if (parse_error) | |
| 131 continue; | 169 continue; |
| 132 | 170 |
| 133 features_[iter.key()] = feature; | 171 features_[iter.key()] = feature; |
| 134 } else if (iter.value().GetType() == Value::TYPE_LIST) { | 172 } else if (iter.value().GetType() == Value::TYPE_LIST) { |
| 135 // This is a complex feature. | 173 // This is a complex feature. |
| 136 const ListValue* list = static_cast<const ListValue*>(&iter.value()); | 174 const ListValue* list = static_cast<const ListValue*>(&iter.value()); |
| 137 CHECK_GT(list->GetSize(), 0UL); | 175 CHECK_GT(list->GetSize(), 0UL); |
| 138 | 176 |
| 139 scoped_ptr<ComplexFeature::FeatureList> features( | 177 scoped_ptr<ComplexFeature::FeatureList> features( |
| 140 new ComplexFeature::FeatureList()); | 178 new ComplexFeature::FeatureList()); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 169 | 207 |
| 170 BaseFeatureProvider::~BaseFeatureProvider() { | 208 BaseFeatureProvider::~BaseFeatureProvider() { |
| 171 } | 209 } |
| 172 | 210 |
| 173 // static | 211 // static |
| 174 FeatureProvider* BaseFeatureProvider::GetByName( | 212 FeatureProvider* BaseFeatureProvider::GetByName( |
| 175 const std::string& name) { | 213 const std::string& name) { |
| 176 return g_static.Get().LazyGetFeatures(name); | 214 return g_static.Get().LazyGetFeatures(name); |
| 177 } | 215 } |
| 178 | 216 |
| 179 std::set<std::string> BaseFeatureProvider::GetAllFeatureNames() { | 217 const std::vector<std::string>& BaseFeatureProvider::GetAllFeatureNames() { |
| 180 std::set<std::string> result; | 218 if (feature_names_.empty()) { |
| 181 for (FeatureMap::const_iterator iter = features_.begin(); | 219 for (FeatureMap::const_iterator iter = features_.begin(); |
| 182 iter != features_.end(); ++iter) { | 220 iter != features_.end(); ++iter) { |
| 183 result.insert(iter->first); | 221 feature_names_.push_back(iter->first); |
| 222 } | |
| 184 } | 223 } |
| 185 return result; | 224 return feature_names_; |
| 186 } | 225 } |
| 187 | 226 |
| 188 Feature* BaseFeatureProvider::GetFeature(const std::string& name) { | 227 Feature* BaseFeatureProvider::GetFeature(const std::string& name) { |
| 189 FeatureMap::iterator iter = features_.find(name); | 228 FeatureMap::iterator iter = features_.find(name); |
| 190 if (iter != features_.end()) | 229 if (iter != features_.end()) |
| 191 return iter->second.get(); | 230 return iter->second.get(); |
| 192 else | 231 else |
| 193 return NULL; | 232 return NULL; |
| 194 } | 233 } |
| 195 | 234 |
| 196 } // namespace | 235 } // namespace extensions |
| OLD | NEW |