15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved.
25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Use of this source code is governed by a BSD-style license that can be
35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// found in the LICENSE file.
45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "extensions/common/features/json_feature_provider_source.h"
65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/json/json_reader.h"
85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/logging.h"
95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/base/resource/resource_bundle.h"
105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace extensions {
125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuJSONFeatureProviderSource::JSONFeatureProviderSource(const std::string& name)
145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    : name_(name) {
155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuJSONFeatureProviderSource::~JSONFeatureProviderSource() {
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid JSONFeatureProviderSource::LoadJSON(int resource_id) {
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const std::string& features_file = ResourceBundle::GetSharedInstance()
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                         .GetRawDataResource(resource_id)
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                         .as_string();
245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int error_code = 0;
255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  std::string error_message;
265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError(
275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      features_file, base::JSON_PARSE_RFC, &error_code, &error_message));
285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DCHECK(value) << "Could not load features: " << name_ << " " << error_message;
295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<base::DictionaryValue> value_as_dict;
315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (value) {
325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    CHECK(value->IsType(base::Value::TYPE_DICTIONARY)) << name_;
335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    value_as_dict.reset(static_cast<base::DictionaryValue*>(value.release()));
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  } else {
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // There was some error loading the features file.
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // http://crbug.com/176381
375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    value_as_dict.reset(new base::DictionaryValue());
385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Ensure there are no key collisions.
415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  for (base::DictionaryValue::Iterator iter(*value_as_dict); !iter.IsAtEnd();
425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu       iter.Advance()) {
435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (dictionary_.GetWithoutPathExpansion(iter.key(), NULL))
445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      LOG(FATAL) << "Key " << iter.key() << " is defined in " << name_
455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                 << " JSON feature files more than once.";
465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Merge.
495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  dictionary_.MergeDictionary(value_as_dict.get());
505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace extensions
53