Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / common / extensions / api / file_handlers / file_handlers_parser.cc
blob74a0864eb8543f07004ad32c2cb85dba7469edcb
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
3 // found in the LICENSE file.
5 #include "chrome/common/extensions/api/file_handlers/file_handlers_parser.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/values.h"
11 #include "extensions/common/error_utils.h"
12 #include "extensions/common/manifest.h"
13 #include "extensions/common/manifest_constants.h"
15 namespace extensions {
17 namespace keys = manifest_keys;
18 namespace errors = manifest_errors;
20 const int kMaxTypeAndExtensionHandlers = 200;
22 FileHandlerInfo::FileHandlerInfo() {}
23 FileHandlerInfo::~FileHandlerInfo() {}
25 FileHandlers::FileHandlers() {}
26 FileHandlers::~FileHandlers() {}
28 // static
29 const std::vector<FileHandlerInfo>* FileHandlers::GetFileHandlers(
30 const Extension* extension) {
31 FileHandlers* info = static_cast<FileHandlers*>(
32 extension->GetManifestData(keys::kFileHandlers));
33 return info ? &info->file_handlers : NULL;
36 FileHandlersParser::FileHandlersParser() {
39 FileHandlersParser::~FileHandlersParser() {
42 bool LoadFileHandler(const std::string& handler_id,
43 const base::DictionaryValue& handler_info,
44 std::vector<FileHandlerInfo>* file_handlers,
45 base::string16* error) {
46 DCHECK(error);
47 FileHandlerInfo handler;
49 handler.id = handler_id;
51 const base::ListValue* mime_types = NULL;
52 if (handler_info.HasKey(keys::kFileHandlerTypes) &&
53 !handler_info.GetList(keys::kFileHandlerTypes, &mime_types)) {
54 *error = ErrorUtils::FormatErrorMessageUTF16(
55 errors::kInvalidFileHandlerType, handler_id);
56 return false;
59 const base::ListValue* file_extensions = NULL;
60 if (handler_info.HasKey(keys::kFileHandlerExtensions) &&
61 !handler_info.GetList(keys::kFileHandlerExtensions, &file_extensions)) {
62 *error = ErrorUtils::FormatErrorMessageUTF16(
63 errors::kInvalidFileHandlerExtension, handler_id);
64 return false;
67 if ((!mime_types || mime_types->GetSize() == 0) &&
68 (!file_extensions || file_extensions->GetSize() == 0)) {
69 *error = ErrorUtils::FormatErrorMessageUTF16(
70 errors::kInvalidFileHandlerNoTypeOrExtension,
71 handler_id);
72 return false;
75 if (handler_info.HasKey(keys::kFileHandlerTitle) &&
76 !handler_info.GetString(keys::kFileHandlerTitle, &handler.title)) {
77 *error = base::ASCIIToUTF16(errors::kInvalidFileHandlerTitle);
78 return false;
81 if (mime_types) {
82 std::string type;
83 for (size_t i = 0; i < mime_types->GetSize(); ++i) {
84 if (!mime_types->GetString(i, &type)) {
85 *error = ErrorUtils::FormatErrorMessageUTF16(
86 errors::kInvalidFileHandlerTypeElement,
87 handler_id,
88 std::string(base::IntToString(i)));
89 return false;
91 handler.types.insert(type);
95 if (file_extensions) {
96 std::string file_extension;
97 for (size_t i = 0; i < file_extensions->GetSize(); ++i) {
98 if (!file_extensions->GetString(i, &file_extension)) {
99 *error = ErrorUtils::FormatErrorMessageUTF16(
100 errors::kInvalidFileHandlerExtensionElement,
101 handler_id,
102 std::string(base::IntToString(i)));
103 return false;
105 handler.extensions.insert(file_extension);
109 file_handlers->push_back(handler);
110 return true;
113 bool FileHandlersParser::Parse(Extension* extension, base::string16* error) {
114 scoped_ptr<FileHandlers> info(new FileHandlers);
115 const base::DictionaryValue* all_handlers = NULL;
116 if (!extension->manifest()->GetDictionary(keys::kFileHandlers,
117 &all_handlers)) {
118 *error = base::ASCIIToUTF16(errors::kInvalidFileHandlers);
119 return false;
122 DCHECK(extension->is_platform_app());
124 for (base::DictionaryValue::Iterator iter(*all_handlers); !iter.IsAtEnd();
125 iter.Advance()) {
126 // A file handler entry is a title and a list of MIME types to handle.
127 const base::DictionaryValue* handler = NULL;
128 if (iter.value().GetAsDictionary(&handler)) {
129 if (!LoadFileHandler(iter.key(), *handler, &info->file_handlers, error))
130 return false;
131 } else {
132 *error = base::ASCIIToUTF16(errors::kInvalidFileHandlers);
133 return false;
137 int filterCount = 0;
138 for (std::vector<FileHandlerInfo>::iterator iter =
139 info->file_handlers.begin();
140 iter < info->file_handlers.end();
141 iter++) {
142 filterCount += iter->types.size();
143 filterCount += iter->extensions.size();
146 if (filterCount > kMaxTypeAndExtensionHandlers) {
147 *error = base::ASCIIToUTF16(
148 errors::kInvalidFileHandlersTooManyTypesAndExtensions);
149 return false;
152 extension->SetManifestData(keys::kFileHandlers, info.release());
153 return true;
156 const std::vector<std::string> FileHandlersParser::Keys() const {
157 return SingleKey(keys::kFileHandlers);
160 } // namespace extensions