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

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

Issue 2202733003: [Extensions] Remove JSONFeatureProvider, SimpleFeature::Parse (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Lei's Created 4 years, 4 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "extensions/common/features/json_feature_provider.h"
6
7 #include <stddef.h>
8
9 #include <stack>
10 #include <utility>
11
12 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h"
14 #include "base/values.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
19 namespace extensions {
20
21 namespace {
22
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 feature->Parse(value);
39 std::string error;
40 bool valid = feature->Validate(&error);
41 if (!valid)
42 LOG(ERROR) << error;
43 return valid;
44 }
45
46 } // namespace
47
48 JSONFeatureProvider::JSONFeatureProvider(const base::DictionaryValue& root,
49 FeatureFactory factory)
50 : factory_(factory) {
51 for (base::DictionaryValue::Iterator iter(root); !iter.IsAtEnd();
52 iter.Advance()) {
53 if (IsNocompile(iter.value())) {
54 continue;
55 }
56
57 if (iter.value().GetType() == base::Value::TYPE_DICTIONARY) {
58 std::unique_ptr<SimpleFeature> feature((*factory_)());
59
60 std::vector<std::string> split = base::SplitString(
61 iter.key(), ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
62
63 // Push parent features on the stack, starting with the current feature.
64 // If one of the features has "noparent" set, stop pushing features on
65 // the stack. The features will then be parsed in order, starting with
66 // the farthest parent that is either top level or has "noparent" set.
67 std::stack<std::pair<std::string, const base::DictionaryValue*>>
68 parse_stack;
69 while (!split.empty()) {
70 std::string parent_name = base::JoinString(split, ".");
71 split.pop_back();
72 if (root.HasKey(parent_name)) {
73 const base::DictionaryValue* parent = nullptr;
74 if (!root.GetDictionaryWithoutPathExpansion(parent_name, &parent)) {
75 // If the parent is a complex feature, find the parent with the
76 // 'default_parent' flag.
77 const base::ListValue* parent_list = nullptr;
78 CHECK(root.GetListWithoutPathExpansion(parent_name, &parent_list));
79 for (size_t i = 0; i < parent_list->GetSize(); ++i) {
80 CHECK(parent_list->GetDictionary(i, &parent));
81 if (parent->HasKey("default_parent"))
82 break;
83 parent = nullptr;
84 }
85 CHECK(parent)
86 << parent_name << " must declare one of its features"
87 << " the default parent, with {\"default_parent\": true}.";
88 }
89 parse_stack.push(std::make_pair(parent_name, parent));
90 bool no_parent = false;
91 parent->GetBoolean("noparent", &no_parent);
92 if (no_parent)
93 break;
94 }
95 }
96
97 CHECK(!parse_stack.empty());
98 // Parse all parent features.
99 bool parse_error = false;
100 while (!parse_stack.empty()) {
101 if (!ParseFeature(parse_stack.top().second, parse_stack.top().first,
102 feature.get())) {
103 parse_error = true;
104 break;
105 }
106 parse_stack.pop();
107 }
108
109 if (parse_error)
110 continue;
111
112 AddFeature(iter.key(), std::move(feature));
113 } else if (iter.value().GetType() == base::Value::TYPE_LIST) {
114 // This is a complex feature.
115 const base::ListValue* list =
116 static_cast<const base::ListValue*>(&iter.value());
117 CHECK_GT(list->GetSize(), 0UL);
118
119 std::vector<Feature*> features;
120
121 // Parse and add all SimpleFeatures from the list.
122 for (const auto& entry : *list) {
123 base::DictionaryValue* dict;
124 if (!entry->GetAsDictionary(&dict)) {
125 LOG(ERROR) << iter.key() << ": Feature rules must be dictionaries.";
126 continue;
127 }
128
129 std::unique_ptr<SimpleFeature> feature((*factory_)());
130 if (!ParseFeature(dict, iter.key(), feature.get()))
131 continue;
132
133 features.push_back(feature.release());
134 }
135
136 std::unique_ptr<ComplexFeature> feature(new ComplexFeature(&features));
137 feature->set_name(iter.key());
138
139 AddFeature(iter.key(), feature.release());
140 } else {
141 LOG(ERROR) << iter.key() << ": Feature description must be dictionary or"
142 << " list of dictionaries.";
143 }
144 }
145 }
146
147 JSONFeatureProvider::~JSONFeatureProvider() {}
148
149 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/common/features/json_feature_provider.h ('k') | extensions/common/features/manifest_feature.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698