| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/common/extensions/api/file_handlers/file_handlers_parser.h" |
| |
| #include "base/memory/scoped_ptr.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/values.h" |
| #include "extensions/common/error_utils.h" |
| #include "extensions/common/manifest.h" |
| #include "extensions/common/manifest_constants.h" |
| |
| namespace extensions { |
| |
| namespace keys = manifest_keys; |
| namespace errors = manifest_errors; |
| |
| FileHandlerInfo::FileHandlerInfo() {} |
| FileHandlerInfo::~FileHandlerInfo() {} |
| |
| FileHandlers::FileHandlers() {} |
| FileHandlers::~FileHandlers() {} |
| |
| // static |
| const std::vector<FileHandlerInfo>* FileHandlers::GetFileHandlers( |
| const Extension* extension) { |
| FileHandlers* info = static_cast<FileHandlers*>( |
| extension->GetManifestData(keys::kFileHandlers)); |
| return info ? &info->file_handlers : NULL; |
| } |
| |
| FileHandlersParser::FileHandlersParser() { |
| } |
| |
| FileHandlersParser::~FileHandlersParser() { |
| } |
| |
| bool LoadFileHandler(const std::string& handler_id, |
| const base::DictionaryValue& handler_info, |
| std::vector<FileHandlerInfo>* file_handlers, |
| string16* error) { |
| DCHECK(error); |
| FileHandlerInfo handler; |
| |
| handler.id = handler_id; |
| |
| const base::ListValue* mime_types = NULL; |
| if (handler_info.HasKey(keys::kFileHandlerTypes) && |
| !handler_info.GetList(keys::kFileHandlerTypes, &mime_types)) { |
| *error = ErrorUtils::FormatErrorMessageUTF16( |
| errors::kInvalidFileHandlerType, handler_id); |
| return false; |
| } |
| |
| const base::ListValue* file_extensions = NULL; |
| if (handler_info.HasKey(keys::kFileHandlerExtensions) && |
| !handler_info.GetList(keys::kFileHandlerExtensions, &file_extensions)) { |
| *error = ErrorUtils::FormatErrorMessageUTF16( |
| errors::kInvalidFileHandlerExtension, handler_id); |
| return false; |
| } |
| |
| if ((!mime_types || mime_types->GetSize() == 0) && |
| (!file_extensions || file_extensions->GetSize() == 0)) { |
| *error = ErrorUtils::FormatErrorMessageUTF16( |
| errors::kInvalidFileHandlerNoTypeOrExtension, |
| handler_id); |
| return false; |
| } |
| |
| if (handler_info.HasKey(keys::kFileHandlerTitle) && |
| !handler_info.GetString(keys::kFileHandlerTitle, &handler.title)) { |
| *error = ASCIIToUTF16(errors::kInvalidFileHandlerTitle); |
| return false; |
| } |
| |
| if (mime_types) { |
| std::string type; |
| for (size_t i = 0; i < mime_types->GetSize(); ++i) { |
| if (!mime_types->GetString(i, &type)) { |
| *error = ErrorUtils::FormatErrorMessageUTF16( |
| errors::kInvalidFileHandlerTypeElement, |
| handler_id, |
| std::string(base::IntToString(i))); |
| return false; |
| } |
| handler.types.insert(type); |
| } |
| } |
| |
| if (file_extensions) { |
| std::string file_extension; |
| for (size_t i = 0; i < file_extensions->GetSize(); ++i) { |
| if (!file_extensions->GetString(i, &file_extension)) { |
| *error = ErrorUtils::FormatErrorMessageUTF16( |
| errors::kInvalidFileHandlerExtensionElement, |
| handler_id, |
| std::string(base::IntToString(i))); |
| return false; |
| } |
| handler.extensions.insert(file_extension); |
| } |
| } |
| |
| file_handlers->push_back(handler); |
| return true; |
| } |
| |
| bool FileHandlersParser::Parse(Extension* extension, string16* error) { |
| scoped_ptr<FileHandlers> info(new FileHandlers); |
| const base::DictionaryValue* all_handlers = NULL; |
| if (!extension->manifest()->GetDictionary(keys::kFileHandlers, |
| &all_handlers)) { |
| *error = ASCIIToUTF16(errors::kInvalidFileHandlers); |
| return false; |
| } |
| |
| DCHECK(extension->is_platform_app()); |
| |
| for (base::DictionaryValue::Iterator iter(*all_handlers); !iter.IsAtEnd(); |
| iter.Advance()) { |
| // A file handler entry is a title and a list of MIME types to handle. |
| const base::DictionaryValue* handler = NULL; |
| if (iter.value().GetAsDictionary(&handler)) { |
| if (!LoadFileHandler(iter.key(), *handler, &info->file_handlers, error)) |
| return false; |
| } else { |
| *error = ASCIIToUTF16(errors::kInvalidFileHandlers); |
| return false; |
| } |
| } |
| |
| extension->SetManifestData(keys::kFileHandlers, info.release()); |
| return true; |
| } |
| |
| const std::vector<std::string> FileHandlersParser::Keys() const { |
| return SingleKey(keys::kFileHandlers); |
| } |
| |
| } // namespace extensions |