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 FileHandlerInfo::FileHandlerInfo() {}
21 FileHandlerInfo::~FileHandlerInfo() {}
23 FileHandlers::FileHandlers() {}
24 FileHandlers::~FileHandlers() {}
27 const std::vector<FileHandlerInfo>* FileHandlers::GetFileHandlers(
28 const Extension* extension) {
29 FileHandlers* info = static_cast<FileHandlers*>(
30 extension->GetManifestData(keys::kFileHandlers));
31 return info ? &info->file_handlers : NULL;
34 FileHandlersParser::FileHandlersParser() {
37 FileHandlersParser::~FileHandlersParser() {
40 bool LoadFileHandler(const std::string& handler_id,
41 const base::DictionaryValue& handler_info,
42 std::vector<FileHandlerInfo>* file_handlers,
45 FileHandlerInfo handler;
47 handler.id = handler_id;
49 const base::ListValue* mime_types = NULL;
50 if (handler_info.HasKey(keys::kFileHandlerTypes) &&
51 !handler_info.GetList(keys::kFileHandlerTypes, &mime_types)) {
52 *error = ErrorUtils::FormatErrorMessageUTF16(
53 errors::kInvalidFileHandlerType, handler_id);
57 const base::ListValue* file_extensions = NULL;
58 if (handler_info.HasKey(keys::kFileHandlerExtensions) &&
59 !handler_info.GetList(keys::kFileHandlerExtensions, &file_extensions)) {
60 *error = ErrorUtils::FormatErrorMessageUTF16(
61 errors::kInvalidFileHandlerExtension, handler_id);
65 if ((!mime_types || mime_types->GetSize() == 0) &&
66 (!file_extensions || file_extensions->GetSize() == 0)) {
67 *error = ErrorUtils::FormatErrorMessageUTF16(
68 errors::kInvalidFileHandlerNoTypeOrExtension,
73 if (handler_info.HasKey(keys::kFileHandlerTitle) &&
74 !handler_info.GetString(keys::kFileHandlerTitle, &handler.title)) {
75 *error = ASCIIToUTF16(errors::kInvalidFileHandlerTitle);
81 for (size_t i = 0; i < mime_types->GetSize(); ++i) {
82 if (!mime_types->GetString(i, &type)) {
83 *error = ErrorUtils::FormatErrorMessageUTF16(
84 errors::kInvalidFileHandlerTypeElement,
86 std::string(base::IntToString(i)));
89 handler.types.insert(type);
93 if (file_extensions) {
94 std::string file_extension;
95 for (size_t i = 0; i < file_extensions->GetSize(); ++i) {
96 if (!file_extensions->GetString(i, &file_extension)) {
97 *error = ErrorUtils::FormatErrorMessageUTF16(
98 errors::kInvalidFileHandlerExtensionElement,
100 std::string(base::IntToString(i)));
103 handler.extensions.insert(file_extension);
107 file_handlers->push_back(handler);
111 bool FileHandlersParser::Parse(Extension* extension, string16* error) {
112 scoped_ptr<FileHandlers> info(new FileHandlers);
113 const base::DictionaryValue* all_handlers = NULL;
114 if (!extension->manifest()->GetDictionary(keys::kFileHandlers,
116 *error = ASCIIToUTF16(errors::kInvalidFileHandlers);
120 DCHECK(extension->is_platform_app());
122 for (base::DictionaryValue::Iterator iter(*all_handlers); !iter.IsAtEnd();
124 // A file handler entry is a title and a list of MIME types to handle.
125 const base::DictionaryValue* handler = NULL;
126 if (iter.value().GetAsDictionary(&handler)) {
127 if (!LoadFileHandler(iter.key(), *handler, &info->file_handlers, error))
130 *error = ASCIIToUTF16(errors::kInvalidFileHandlers);
135 extension->SetManifestData(keys::kFileHandlers, info.release());
139 const std::vector<std::string> FileHandlersParser::Keys() const {
140 return SingleKey(keys::kFileHandlers);
143 } // namespace extensions