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 Feature* GetParent(Feature* feature) OVERRIDE { |
| 44 return GetBaseFeatureProvider()->GetParent(feature); |
| 45 } |
| 46 |
| 47 virtual const std::vector<std::string>& GetAllFeatureNames() OVERRIDE { |
40 return GetBaseFeatureProvider()->GetAllFeatureNames(); | 48 return GetBaseFeatureProvider()->GetAllFeatureNames(); |
41 } | 49 } |
42 | 50 |
43 private: | 51 private: |
44 BaseFeatureProvider* GetBaseFeatureProvider() { | 52 BaseFeatureProvider* GetBaseFeatureProvider() { |
45 if (!features_) | 53 if (!features_) |
46 features_ = LoadProvider(); | 54 features_ = LoadProvider(); |
47 return features_.get(); | 55 return features_.get(); |
48 } | 56 } |
49 | 57 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 } // namespace | 126 } // namespace |
119 | 127 |
120 BaseFeatureProvider::BaseFeatureProvider(const DictionaryValue& root, | 128 BaseFeatureProvider::BaseFeatureProvider(const DictionaryValue& root, |
121 FeatureFactory factory) | 129 FeatureFactory factory) |
122 : factory_(factory ? factory : | 130 : factory_(factory ? factory : |
123 static_cast<FeatureFactory>(&CreateFeature<SimpleFeature>)) { | 131 static_cast<FeatureFactory>(&CreateFeature<SimpleFeature>)) { |
124 for (DictionaryValue::Iterator iter(root); !iter.IsAtEnd(); iter.Advance()) { | 132 for (DictionaryValue::Iterator iter(root); !iter.IsAtEnd(); iter.Advance()) { |
125 if (iter.value().GetType() == Value::TYPE_DICTIONARY) { | 133 if (iter.value().GetType() == Value::TYPE_DICTIONARY) { |
126 linked_ptr<SimpleFeature> feature((*factory_)()); | 134 linked_ptr<SimpleFeature> feature((*factory_)()); |
127 | 135 |
128 if (!ParseFeature(static_cast<const DictionaryValue*>(&iter.value()), | 136 std::vector<std::string> split; |
129 iter.key(), | 137 base::SplitString(iter.key(), '.', &split); |
130 feature.get())) | 138 |
| 139 // Push parent features on the stack, starting with the current feature. |
| 140 // If one of the features has "noparent" set, stop pushing features on |
| 141 // the stack. The features will then be parsed in order, starting with |
| 142 // the farthest parent that is either top level or has "noparent" set. |
| 143 std::stack<std::pair<std::string, const DictionaryValue*> > parse_stack; |
| 144 while (!split.empty()) { |
| 145 std::string parent_name = JoinString(split, '.'); |
| 146 split.pop_back(); |
| 147 if (root.HasKey(parent_name)) { |
| 148 const DictionaryValue* parent = NULL; |
| 149 CHECK(root.GetDictionaryWithoutPathExpansion(parent_name, &parent)); |
| 150 parse_stack.push(std::make_pair(parent_name, parent)); |
| 151 bool no_parent = false; |
| 152 parent->GetBoolean("noparent", &no_parent); |
| 153 if (no_parent) |
| 154 break; |
| 155 } |
| 156 } |
| 157 |
| 158 CHECK(!parse_stack.empty()); |
| 159 // Parse all parent features. |
| 160 bool parse_error = false; |
| 161 while (!parse_stack.empty()) { |
| 162 if (!ParseFeature(parse_stack.top().second, |
| 163 parse_stack.top().first, |
| 164 feature.get())) { |
| 165 parse_error = true; |
| 166 break; |
| 167 } |
| 168 parse_stack.pop(); |
| 169 } |
| 170 |
| 171 if (parse_error) |
131 continue; | 172 continue; |
132 | 173 |
133 features_[iter.key()] = feature; | 174 features_[iter.key()] = feature; |
134 } else if (iter.value().GetType() == Value::TYPE_LIST) { | 175 } else if (iter.value().GetType() == Value::TYPE_LIST) { |
135 // This is a complex feature. | 176 // This is a complex feature. |
136 const ListValue* list = static_cast<const ListValue*>(&iter.value()); | 177 const ListValue* list = static_cast<const ListValue*>(&iter.value()); |
137 CHECK_GT(list->GetSize(), 0UL); | 178 CHECK_GT(list->GetSize(), 0UL); |
138 | 179 |
139 scoped_ptr<ComplexFeature::FeatureList> features( | 180 scoped_ptr<ComplexFeature::FeatureList> features( |
140 new ComplexFeature::FeatureList()); | 181 new ComplexFeature::FeatureList()); |
(...skipping 28 matching lines...) Expand all Loading... |
169 | 210 |
170 BaseFeatureProvider::~BaseFeatureProvider() { | 211 BaseFeatureProvider::~BaseFeatureProvider() { |
171 } | 212 } |
172 | 213 |
173 // static | 214 // static |
174 FeatureProvider* BaseFeatureProvider::GetByName( | 215 FeatureProvider* BaseFeatureProvider::GetByName( |
175 const std::string& name) { | 216 const std::string& name) { |
176 return g_static.Get().LazyGetFeatures(name); | 217 return g_static.Get().LazyGetFeatures(name); |
177 } | 218 } |
178 | 219 |
179 std::set<std::string> BaseFeatureProvider::GetAllFeatureNames() { | 220 const std::vector<std::string>& BaseFeatureProvider::GetAllFeatureNames() { |
180 std::set<std::string> result; | 221 if (feature_names_.empty()) { |
181 for (FeatureMap::const_iterator iter = features_.begin(); | 222 for (FeatureMap::const_iterator iter = features_.begin(); |
182 iter != features_.end(); ++iter) { | 223 iter != features_.end(); ++iter) { |
183 result.insert(iter->first); | 224 feature_names_.push_back(iter->first); |
| 225 } |
184 } | 226 } |
185 return result; | 227 return feature_names_; |
186 } | 228 } |
187 | 229 |
188 Feature* BaseFeatureProvider::GetFeature(const std::string& name) { | 230 Feature* BaseFeatureProvider::GetFeature(const std::string& name) { |
189 FeatureMap::iterator iter = features_.find(name); | 231 FeatureMap::iterator iter = features_.find(name); |
190 if (iter != features_.end()) | 232 if (iter != features_.end()) |
191 return iter->second.get(); | 233 return iter->second.get(); |
192 else | 234 else |
193 return NULL; | 235 return NULL; |
194 } | 236 } |
195 | 237 |
196 } // namespace | 238 Feature* BaseFeatureProvider::GetParent(Feature* feature) { |
| 239 CHECK(feature); |
| 240 if (feature->no_parent()) |
| 241 return NULL; |
| 242 |
| 243 std::vector<std::string> split; |
| 244 base::SplitString(feature->name(), '.', &split); |
| 245 if (split.size() < 2) |
| 246 return NULL; |
| 247 split.pop_back(); |
| 248 return GetFeature(JoinString(split, '.')); |
| 249 } |
| 250 |
| 251 } // namespace extensions |
OLD | NEW |