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

Side by Side Diff: extensions/common/features/json_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
« no previous file with comments | « extensions/common/features/json_feature_provider.h ('k') | extensions/extensions.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/json_feature_provider.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <stack> 9 #include <stack>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/strings/string_split.h" 12 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "base/values.h" 14 #include "base/values.h"
15 #include "extensions/common/extensions_client.h" 15 #include "extensions/common/extensions_client.h"
(...skipping 20 matching lines...) Expand all
36 SimpleFeature* feature) { 36 SimpleFeature* feature) {
37 feature->set_name(name); 37 feature->set_name(name);
38 std::string error = feature->Parse(value); 38 std::string error = feature->Parse(value);
39 if (!error.empty()) 39 if (!error.empty())
40 LOG(ERROR) << error; 40 LOG(ERROR) << error;
41 return error.empty(); 41 return error.empty();
42 } 42 }
43 43
44 } // namespace 44 } // namespace
45 45
46 BaseFeatureProvider::BaseFeatureProvider(const base::DictionaryValue& root, 46 JSONFeatureProvider::JSONFeatureProvider(const base::DictionaryValue& root,
47 FeatureFactory factory) 47 FeatureFactory factory)
48 : factory_(factory) { 48 : factory_(factory) {
49 for (base::DictionaryValue::Iterator iter(root); !iter.IsAtEnd(); 49 for (base::DictionaryValue::Iterator iter(root); !iter.IsAtEnd();
50 iter.Advance()) { 50 iter.Advance()) {
51 if (IsNocompile(iter.value())) { 51 if (IsNocompile(iter.value())) {
52 continue; 52 continue;
53 } 53 }
54 54
55 if (iter.value().GetType() == base::Value::TYPE_DICTIONARY) { 55 if (iter.value().GetType() == base::Value::TYPE_DICTIONARY) {
56 std::unique_ptr<SimpleFeature> feature((*factory_)()); 56 std::unique_ptr<SimpleFeature> feature((*factory_)());
57 57
58 std::vector<std::string> split = base::SplitString( 58 std::vector<std::string> split = base::SplitString(
59 iter.key(), ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 59 iter.key(), ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
60 60
61 // Push parent features on the stack, starting with the current feature. 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 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 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. 64 // the farthest parent that is either top level or has "noparent" set.
65 std::stack<std::pair<std::string, const base::DictionaryValue*> > 65 std::stack<std::pair<std::string, const base::DictionaryValue*>>
66 parse_stack; 66 parse_stack;
67 while (!split.empty()) { 67 while (!split.empty()) {
68 std::string parent_name = base::JoinString(split, "."); 68 std::string parent_name = base::JoinString(split, ".");
69 split.pop_back(); 69 split.pop_back();
70 if (root.HasKey(parent_name)) { 70 if (root.HasKey(parent_name)) {
71 const base::DictionaryValue* parent = nullptr; 71 const base::DictionaryValue* parent = nullptr;
72 if (!root.GetDictionaryWithoutPathExpansion(parent_name, &parent)) { 72 if (!root.GetDictionaryWithoutPathExpansion(parent_name, &parent)) {
73 // If the parent is a complex feature, find the parent with the 73 // If the parent is a complex feature, find the parent with the
74 // 'default_parent' flag. 74 // 'default_parent' flag.
75 const base::ListValue* parent_list = nullptr; 75 const base::ListValue* parent_list = nullptr;
76 CHECK(root.GetListWithoutPathExpansion(parent_name, &parent_list)); 76 CHECK(root.GetListWithoutPathExpansion(parent_name, &parent_list));
77 for (size_t i = 0; i < parent_list->GetSize(); ++i) { 77 for (size_t i = 0; i < parent_list->GetSize(); ++i) {
78 CHECK(parent_list->GetDictionary(i, &parent)); 78 CHECK(parent_list->GetDictionary(i, &parent));
79 if (parent->HasKey("default_parent")) 79 if (parent->HasKey("default_parent"))
80 break; 80 break;
81 parent = nullptr; 81 parent = nullptr;
82 } 82 }
83 CHECK(parent) << parent_name << " must declare one of its features" 83 CHECK(parent)
84 << parent_name << " must declare one of its features"
84 << " the default parent, with {\"default_parent\": true}."; 85 << " the default parent, with {\"default_parent\": true}.";
85 } 86 }
86 parse_stack.push(std::make_pair(parent_name, parent)); 87 parse_stack.push(std::make_pair(parent_name, parent));
87 bool no_parent = false; 88 bool no_parent = false;
88 parent->GetBoolean("noparent", &no_parent); 89 parent->GetBoolean("noparent", &no_parent);
89 if (no_parent) 90 if (no_parent)
90 break; 91 break;
91 } 92 }
92 } 93 }
93 94
94 CHECK(!parse_stack.empty()); 95 CHECK(!parse_stack.empty());
95 // Parse all parent features. 96 // Parse all parent features.
96 bool parse_error = false; 97 bool parse_error = false;
97 while (!parse_stack.empty()) { 98 while (!parse_stack.empty()) {
98 if (!ParseFeature(parse_stack.top().second, 99 if (!ParseFeature(parse_stack.top().second, parse_stack.top().first,
99 parse_stack.top().first,
100 feature.get())) { 100 feature.get())) {
101 parse_error = true; 101 parse_error = true;
102 break; 102 break;
103 } 103 }
104 parse_stack.pop(); 104 parse_stack.pop();
105 } 105 }
106 106
107 if (parse_error) 107 if (parse_error)
108 continue; 108 continue;
109 109
(...skipping 27 matching lines...) Expand all
137 feature->set_name(iter.key()); 137 feature->set_name(iter.key());
138 138
139 features_[iter.key()] = std::move(feature); 139 features_[iter.key()] = std::move(feature);
140 } else { 140 } else {
141 LOG(ERROR) << iter.key() << ": Feature description must be dictionary or" 141 LOG(ERROR) << iter.key() << ": Feature description must be dictionary or"
142 << " list of dictionaries."; 142 << " list of dictionaries.";
143 } 143 }
144 } 144 }
145 } 145 }
146 146
147 BaseFeatureProvider::~BaseFeatureProvider() { 147 JSONFeatureProvider::~JSONFeatureProvider() {}
148 }
149
150 const FeatureMap& BaseFeatureProvider::GetAllFeatures() const {
151 return features_;
152 }
153
154 Feature* BaseFeatureProvider::GetFeature(const std::string& name) const {
155 FeatureMap::const_iterator iter = features_.find(name);
156 if (iter != features_.end())
157 return iter->second.get();
158 else
159 return nullptr;
160 }
161
162 Feature* BaseFeatureProvider::GetParent(Feature* feature) const {
163 CHECK(feature);
164 if (feature->no_parent())
165 return nullptr;
166
167 std::vector<std::string> split = base::SplitString(
168 feature->name(), ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
169 if (split.size() < 2)
170 return nullptr;
171 split.pop_back();
172 return GetFeature(base::JoinString(split, "."));
173 }
174
175 // Children of a given API are named starting with parent.name()+".", which
176 // means they'll be contiguous in the features_ std::map.
177 std::vector<Feature*> BaseFeatureProvider::GetChildren(const Feature& parent)
178 const {
179 std::string prefix = parent.name() + ".";
180 const FeatureMap::const_iterator first_child = features_.lower_bound(prefix);
181
182 // All children have names before (parent.name() + ('.'+1)).
183 ++prefix.back();
184 const FeatureMap::const_iterator after_children =
185 features_.lower_bound(prefix);
186
187 std::vector<Feature*> result;
188 result.reserve(std::distance(first_child, after_children));
189 for (FeatureMap::const_iterator it = first_child; it != after_children;
190 ++it) {
191 result.push_back(it->second.get());
192 }
193 return result;
194 }
195 148
196 } // namespace extensions 149 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/common/features/json_feature_provider.h ('k') | extensions/extensions.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698