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

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

Issue 15091002: Lazily load API schemas from resource files and convert all APIs to features (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: optimize and "parent" property Created 7 years, 7 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 | Annotate | Revision Log
OLDNEW
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 "base/json/json_reader.h" 7 #include "base/json/json_reader.h"
8 #include "base/lazy_instance.h" 8 #include "base/lazy_instance.h"
9 #include "chrome/common/extensions/features/api_feature.h" 9 #include "chrome/common/extensions/features/api_feature.h"
10 #include "chrome/common/extensions/features/complex_feature.h" 10 #include "chrome/common/extensions/features/complex_feature.h"
(...skipping 18 matching lines...) Expand all
29 int resource_id) 29 int resource_id)
30 : name_(name), 30 : name_(name),
31 factory_(factory), 31 factory_(factory),
32 resource_id_(resource_id) { 32 resource_id_(resource_id) {
33 } 33 }
34 34
35 virtual Feature* GetFeature(const std::string& name) OVERRIDE { 35 virtual Feature* GetFeature(const std::string& name) OVERRIDE {
36 return GetBaseFeatureProvider()->GetFeature(name); 36 return GetBaseFeatureProvider()->GetFeature(name);
37 } 37 }
38 38
39 virtual std::set<std::string> GetAllFeatureNames() OVERRIDE { 39 virtual std::vector<std::string> GetAllFeatureNames() OVERRIDE {
40 return GetBaseFeatureProvider()->GetAllFeatureNames(); 40 return GetBaseFeatureProvider()->GetAllFeatureNames();
41 } 41 }
42 42
43 virtual std::vector<std::string> GetAllTopLevelFeatureNames() OVERRIDE {
44 return GetBaseFeatureProvider()->GetAllTopLevelFeatureNames();
45 }
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
50 scoped_ptr<BaseFeatureProvider> LoadProvider() { 54 scoped_ptr<BaseFeatureProvider> LoadProvider() {
51 const std::string& features_file = 55 const std::string& features_file =
52 ResourceBundle::GetSharedInstance().GetRawDataResource( 56 ResourceBundle::GetSharedInstance().GetRawDataResource(
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 return it->second.get(); 104 return it->second.get();
101 } 105 }
102 106
103 LazyFeatureProviderMap lazy_feature_providers; 107 LazyFeatureProviderMap lazy_feature_providers;
104 }; 108 };
105 109
106 base::LazyInstance<Static> g_static = LAZY_INSTANCE_INITIALIZER; 110 base::LazyInstance<Static> g_static = LAZY_INSTANCE_INITIALIZER;
107 111
108 bool ParseFeature(const DictionaryValue* value, 112 bool ParseFeature(const DictionaryValue* value,
109 const std::string& name, 113 const std::string& name,
110 SimpleFeature* feature) { 114 SimpleFeature* feature) {
not at google - send to devlin 2013/05/23 00:09:40 perhaps: std::string error; std::string parent_na
cduvall 2013/05/24 03:13:49 Done.
111 feature->set_name(name); 115 feature->set_name(name);
112 std::string error = feature->Parse(value); 116 std::string error = feature->Parse(value);
113 if (!error.empty()) 117 if (!error.empty())
114 LOG(ERROR) << error; 118 LOG(ERROR) << error;
115 return error.empty(); 119 return error.empty();
116 } 120 }
117 121
122 bool ParseFeature(const DictionaryValue* value,
123 SimpleFeature* feature) {
124 std::string error = feature->Parse(value);
125 if (!error.empty())
126 LOG(ERROR) << error;
127 return error.empty();
128 }
129
130 bool MaybeParseParentFeature(const DictionaryValue& root,
131 const DictionaryValue* feature_dict,
132 SimpleFeature* feature) {
133 std::string parent;
134 const DictionaryValue* value;
135 if (!feature_dict->GetString("parent", &parent))
136 return true;
137 if (!root.GetDictionary(parent, &value))
138 return false;
139 return ParseFeature(value, feature);
140 }
141
118 } // namespace 142 } // namespace
119 143
120 BaseFeatureProvider::BaseFeatureProvider(const DictionaryValue& root, 144 BaseFeatureProvider::BaseFeatureProvider(const DictionaryValue& root,
121 FeatureFactory factory) 145 FeatureFactory factory)
122 : factory_(factory ? factory : 146 : factory_(factory ? factory :
123 static_cast<FeatureFactory>(&CreateFeature<SimpleFeature>)) { 147 static_cast<FeatureFactory>(&CreateFeature<SimpleFeature>)) {
124 for (DictionaryValue::Iterator iter(root); !iter.IsAtEnd(); iter.Advance()) { 148 for (DictionaryValue::Iterator iter(root); !iter.IsAtEnd(); iter.Advance()) {
125 if (iter.value().GetType() == Value::TYPE_DICTIONARY) { 149 if (iter.value().GetType() == Value::TYPE_DICTIONARY) {
126 linked_ptr<SimpleFeature> feature((*factory_)()); 150 linked_ptr<SimpleFeature> feature((*factory_)());
127 151
128 if (!ParseFeature(static_cast<const DictionaryValue*>(&iter.value()), 152 const DictionaryValue* feature_dict =
129 iter.key(), 153 static_cast<const DictionaryValue*>(&iter.value());
not at google - send to devlin 2013/05/23 00:09:40 this could be a bit more straightforward by changi
cduvall 2013/05/24 03:13:49 Done.
130 feature.get())) 154 if (!MaybeParseParentFeature(root, feature_dict, feature.get()))
155 continue;
156 if (!ParseFeature(feature_dict, iter.key(), feature.get()))
131 continue; 157 continue;
132 158
133 features_[iter.key()] = feature; 159 features_[iter.key()] = feature;
134 } else if (iter.value().GetType() == Value::TYPE_LIST) { 160 } else if (iter.value().GetType() == Value::TYPE_LIST) {
135 // This is a complex feature. 161 // This is a complex feature.
136 const ListValue* list = static_cast<const ListValue*>(&iter.value()); 162 const ListValue* list = static_cast<const ListValue*>(&iter.value());
137 CHECK_GT(list->GetSize(), 0UL); 163 CHECK_GT(list->GetSize(), 0UL);
138 164
139 scoped_ptr<ComplexFeature::FeatureList> features( 165 scoped_ptr<ComplexFeature::FeatureList> features(
140 new ComplexFeature::FeatureList()); 166 new ComplexFeature::FeatureList());
141 167
142 // Parse and add all SimpleFeatures from the list. 168 // Parse and add all SimpleFeatures from the list.
143 for (ListValue::const_iterator list_iter = list->begin(); 169 for (ListValue::const_iterator list_iter = list->begin();
144 list_iter != list->end(); ++list_iter) { 170 list_iter != list->end(); ++list_iter) {
145 if ((*list_iter)->GetType() != Value::TYPE_DICTIONARY) { 171 if ((*list_iter)->GetType() != Value::TYPE_DICTIONARY) {
146 LOG(ERROR) << iter.key() << ": Feature rules must be dictionaries."; 172 LOG(ERROR) << iter.key() << ": Feature rules must be dictionaries.";
147 continue; 173 continue;
148 } 174 }
149 175
176 const DictionaryValue* feature_dict =
177 static_cast<const DictionaryValue*>(*list_iter);
150 scoped_ptr<SimpleFeature> feature((*factory_)()); 178 scoped_ptr<SimpleFeature> feature((*factory_)());
151 if (!ParseFeature(static_cast<const DictionaryValue*>(*list_iter), 179 if (!MaybeParseParentFeature(root, feature_dict, feature.get()))
152 iter.key(), 180 continue;
153 feature.get())) 181 if (!ParseFeature(feature_dict, iter.key(), feature.get()))
154 continue; 182 continue;
155 183
156 features->push_back(feature.release()); 184 features->push_back(feature.release());
157 } 185 }
158 186
159 linked_ptr<ComplexFeature> feature(new ComplexFeature(features.Pass())); 187 linked_ptr<ComplexFeature> feature(new ComplexFeature(features.Pass()));
160 feature->set_name(iter.key()); 188 feature->set_name(iter.key());
161 189
162 features_[iter.key()] = feature; 190 features_[iter.key()] = feature;
163 } else { 191 } else {
164 LOG(ERROR) << iter.key() << ": Feature description must be dictionary or" 192 LOG(ERROR) << iter.key() << ": Feature description must be dictionary or"
165 << " list of dictionaries."; 193 << " list of dictionaries.";
166 } 194 }
167 } 195 }
168 } 196 }
169 197
170 BaseFeatureProvider::~BaseFeatureProvider() { 198 BaseFeatureProvider::~BaseFeatureProvider() {
171 } 199 }
172 200
173 // static 201 // static
174 FeatureProvider* BaseFeatureProvider::GetByName( 202 FeatureProvider* BaseFeatureProvider::GetByName(
175 const std::string& name) { 203 const std::string& name) {
176 return g_static.Get().LazyGetFeatures(name); 204 return g_static.Get().LazyGetFeatures(name);
177 } 205 }
178 206
179 std::set<std::string> BaseFeatureProvider::GetAllFeatureNames() { 207 std::vector<std::string> BaseFeatureProvider::GetAllTopLevelFeatureNames() {
180 std::set<std::string> result; 208 std::vector<std::string> result;
181 for (FeatureMap::const_iterator iter = features_.begin(); 209 for (FeatureMap::const_iterator iter = features_.begin();
182 iter != features_.end(); ++iter) { 210 iter != features_.end(); ++iter) {
183 result.insert(iter->first); 211 if (!iter->second->HasParent())
212 result.push_back(iter->first);
184 } 213 }
185 return result; 214 return result;
186 } 215 }
216
217 std::vector<std::string> BaseFeatureProvider::GetAllFeatureNames() {
218 std::vector<std::string> result;
219 for (FeatureMap::const_iterator iter = features_.begin();
220 iter != features_.end(); ++iter) {
221 result.push_back(iter->first);
222 }
223 return result;
224 }
187 225
188 Feature* BaseFeatureProvider::GetFeature(const std::string& name) { 226 Feature* BaseFeatureProvider::GetFeature(const std::string& name) {
189 FeatureMap::iterator iter = features_.find(name); 227 FeatureMap::iterator iter = features_.find(name);
190 if (iter != features_.end()) 228 if (iter != features_.end())
191 return iter->second.get(); 229 return iter->second.get();
192 else 230 else
193 return NULL; 231 return NULL;
194 } 232 }
195 233
196 } // namespace 234 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698