Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: extensions/common/features/base_feature_provider.cc

Issue 2133783002: [Extensions] Break up BaseFeatureProvider, create JSONFeatureProvider (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Latest master Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "extensions/common/features/base_feature_provider.h" 5 #include "extensions/common/features/base_feature_provider.h"
6 6
7 #include <stddef.h>
8
9 #include <stack>
10 #include <utility>
11
12 #include "base/strings/string_split.h" 7 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h" 8 #include "base/strings/string_util.h"
14 #include "base/values.h" 9 #include "extensions/common/features/feature.h"
15 #include "extensions/common/extensions_client.h"
16 #include "extensions/common/features/complex_feature.h"
17 #include "extensions/common/features/simple_feature.h"
18 10
19 namespace extensions { 11 namespace extensions {
20 12
21 namespace { 13 BaseFeatureProvider::BaseFeatureProvider() {}
22 14 BaseFeatureProvider::~BaseFeatureProvider() {}
23 bool IsNocompile(const base::Value& value) {
24 bool nocompile = false;
25 const base::DictionaryValue* as_dict = nullptr;
26 if (value.GetAsDictionary(&as_dict)) {
27 as_dict->GetBoolean("nocompile", &nocompile);
28 } else {
29 // "nocompile" is not supported for any other feature type.
30 }
31 return nocompile;
32 }
33
34 bool ParseFeature(const base::DictionaryValue* value,
35 const std::string& name,
36 SimpleFeature* feature) {
37 feature->set_name(name);
38 std::string error = feature->Parse(value);
39 if (!error.empty())
40 LOG(ERROR) << error;
41 return error.empty();
42 }
43
44 } // namespace
45
46 BaseFeatureProvider::BaseFeatureProvider(const base::DictionaryValue& root,
47 FeatureFactory factory)
48 : factory_(factory) {
49 for (base::DictionaryValue::Iterator iter(root); !iter.IsAtEnd();
50 iter.Advance()) {
51 if (IsNocompile(iter.value())) {
52 continue;
53 }
54
55 if (iter.value().GetType() == base::Value::TYPE_DICTIONARY) {
56 std::unique_ptr<SimpleFeature> feature((*factory_)());
57
58 std::vector<std::string> split = base::SplitString(
59 iter.key(), ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
60
61 // Push parent features on the stack, starting with the current feature.
62 // If one of the features has "noparent" set, stop pushing features on
63 // the stack. The features will then be parsed in order, starting with
64 // the farthest parent that is either top level or has "noparent" set.
65 std::stack<std::pair<std::string, const base::DictionaryValue*> >
66 parse_stack;
67 while (!split.empty()) {
68 std::string parent_name = base::JoinString(split, ".");
69 split.pop_back();
70 if (root.HasKey(parent_name)) {
71 const base::DictionaryValue* parent = nullptr;
72 if (!root.GetDictionaryWithoutPathExpansion(parent_name, &parent)) {
73 // If the parent is a complex feature, find the parent with the
74 // 'default_parent' flag.
75 const base::ListValue* parent_list = nullptr;
76 CHECK(root.GetListWithoutPathExpansion(parent_name, &parent_list));
77 for (size_t i = 0; i < parent_list->GetSize(); ++i) {
78 CHECK(parent_list->GetDictionary(i, &parent));
79 if (parent->HasKey("default_parent"))
80 break;
81 parent = nullptr;
82 }
83 CHECK(parent) << parent_name << " must declare one of its features"
84 << " the default parent, with {\"default_parent\": true}.";
85 }
86 parse_stack.push(std::make_pair(parent_name, parent));
87 bool no_parent = false;
88 parent->GetBoolean("noparent", &no_parent);
89 if (no_parent)
90 break;
91 }
92 }
93
94 CHECK(!parse_stack.empty());
95 // Parse all parent features.
96 bool parse_error = false;
97 while (!parse_stack.empty()) {
98 if (!ParseFeature(parse_stack.top().second,
99 parse_stack.top().first,
100 feature.get())) {
101 parse_error = true;
102 break;
103 }
104 parse_stack.pop();
105 }
106
107 if (parse_error)
108 continue;
109
110 features_[iter.key()] = std::move(feature);
111 } else if (iter.value().GetType() == base::Value::TYPE_LIST) {
112 // This is a complex feature.
113 const base::ListValue* list =
114 static_cast<const base::ListValue*>(&iter.value());
115 CHECK_GT(list->GetSize(), 0UL);
116
117 std::unique_ptr<ComplexFeature::FeatureList> features(
118 new ComplexFeature::FeatureList());
119
120 // Parse and add all SimpleFeatures from the list.
121 for (const auto& entry : *list) {
122 base::DictionaryValue* dict;
123 if (!entry->GetAsDictionary(&dict)) {
124 LOG(ERROR) << iter.key() << ": Feature rules must be dictionaries.";
125 continue;
126 }
127
128 std::unique_ptr<SimpleFeature> feature((*factory_)());
129 if (!ParseFeature(dict, iter.key(), feature.get()))
130 continue;
131
132 features->push_back(std::move(feature));
133 }
134
135 std::unique_ptr<ComplexFeature> feature(
136 new ComplexFeature(std::move(features)));
137 feature->set_name(iter.key());
138
139 features_[iter.key()] = std::move(feature);
140 } else {
141 LOG(ERROR) << iter.key() << ": Feature description must be dictionary or"
142 << " list of dictionaries.";
143 }
144 }
145 }
146
147 BaseFeatureProvider::~BaseFeatureProvider() {
148 }
149 15
150 const FeatureMap& BaseFeatureProvider::GetAllFeatures() const { 16 const FeatureMap& BaseFeatureProvider::GetAllFeatures() const {
151 return features_; 17 return features_;
152 } 18 }
153 19
154 Feature* BaseFeatureProvider::GetFeature(const std::string& name) const { 20 Feature* BaseFeatureProvider::GetFeature(const std::string& name) const {
155 FeatureMap::const_iterator iter = features_.find(name); 21 FeatureMap::const_iterator iter = features_.find(name);
156 if (iter != features_.end()) 22 if (iter != features_.end())
157 return iter->second.get(); 23 return iter->second.get();
158 else 24 else
(...skipping 28 matching lines...) Expand all
187 std::vector<Feature*> result; 53 std::vector<Feature*> result;
188 result.reserve(std::distance(first_child, after_children)); 54 result.reserve(std::distance(first_child, after_children));
189 for (FeatureMap::const_iterator it = first_child; it != after_children; 55 for (FeatureMap::const_iterator it = first_child; it != after_children;
190 ++it) { 56 ++it) {
191 result.push_back(it->second.get()); 57 result.push_back(it->second.get());
192 } 58 }
193 return result; 59 return result;
194 } 60 }
195 61
196 } // namespace extensions 62 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/common/features/base_feature_provider.h ('k') | extensions/common/features/json_feature_provider.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698