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() {}
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
) {
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
);
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
);
67 if ((!mime_types
|| mime_types
->GetSize() == 0) &&
68 (!file_extensions
|| file_extensions
->GetSize() == 0)) {
69 *error
= ErrorUtils::FormatErrorMessageUTF16(
70 errors::kInvalidFileHandlerNoTypeOrExtension
,
75 if (handler_info
.HasKey(keys::kFileHandlerTitle
) &&
76 !handler_info
.GetString(keys::kFileHandlerTitle
, &handler
.title
)) {
77 *error
= base::ASCIIToUTF16(errors::kInvalidFileHandlerTitle
);
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
,
88 std::string(base::IntToString(i
)));
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
,
102 std::string(base::IntToString(i
)));
105 handler
.extensions
.insert(file_extension
);
109 file_handlers
->push_back(handler
);
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
,
118 *error
= base::ASCIIToUTF16(errors::kInvalidFileHandlers
);
122 DCHECK(extension
->is_platform_app());
124 for (base::DictionaryValue::Iterator
iter(*all_handlers
); !iter
.IsAtEnd();
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
))
132 *error
= base::ASCIIToUTF16(errors::kInvalidFileHandlers
);
138 for (std::vector
<FileHandlerInfo
>::iterator iter
=
139 info
->file_handlers
.begin();
140 iter
< info
->file_handlers
.end();
142 filterCount
+= iter
->types
.size();
143 filterCount
+= iter
->extensions
.size();
146 if (filterCount
> kMaxTypeAndExtensionHandlers
) {
147 *error
= base::ASCIIToUTF16(
148 errors::kInvalidFileHandlersTooManyTypesAndExtensions
);
152 extension
->SetManifestData(keys::kFileHandlers
, info
.release());
156 const std::vector
<std::string
> FileHandlersParser::Keys() const {
157 return SingleKey(keys::kFileHandlers
);
160 } // namespace extensions