- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / api / file_handlers / file_handlers_parser.cc
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.
4
5 #include "chrome/common/extensions/api/file_handlers/file_handlers_parser.h"
6
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"
14
15 namespace extensions {
16
17 namespace keys = manifest_keys;
18 namespace errors = manifest_errors;
19
20 FileHandlerInfo::FileHandlerInfo() {}
21 FileHandlerInfo::~FileHandlerInfo() {}
22
23 FileHandlers::FileHandlers() {}
24 FileHandlers::~FileHandlers() {}
25
26 // static
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;
32 }
33
34 FileHandlersParser::FileHandlersParser() {
35 }
36
37 FileHandlersParser::~FileHandlersParser() {
38 }
39
40 bool LoadFileHandler(const std::string& handler_id,
41                      const base::DictionaryValue& handler_info,
42                      std::vector<FileHandlerInfo>* file_handlers,
43                      string16* error) {
44   DCHECK(error);
45   FileHandlerInfo handler;
46
47   handler.id = handler_id;
48
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);
54     return false;
55   }
56
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);
62     return false;
63   }
64
65   if ((!mime_types || mime_types->GetSize() == 0) &&
66       (!file_extensions || file_extensions->GetSize() == 0)) {
67     *error = ErrorUtils::FormatErrorMessageUTF16(
68         errors::kInvalidFileHandlerNoTypeOrExtension,
69         handler_id);
70     return false;
71   }
72
73   if (handler_info.HasKey(keys::kFileHandlerTitle) &&
74       !handler_info.GetString(keys::kFileHandlerTitle, &handler.title)) {
75     *error = ASCIIToUTF16(errors::kInvalidFileHandlerTitle);
76     return false;
77   }
78
79   if (mime_types) {
80     std::string type;
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,
85             handler_id,
86             std::string(base::IntToString(i)));
87         return false;
88       }
89       handler.types.insert(type);
90     }
91   }
92
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,
99             handler_id,
100             std::string(base::IntToString(i)));
101         return false;
102       }
103       handler.extensions.insert(file_extension);
104     }
105   }
106
107   file_handlers->push_back(handler);
108   return true;
109 }
110
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,
115                                             &all_handlers)) {
116     *error = ASCIIToUTF16(errors::kInvalidFileHandlers);
117     return false;
118   }
119
120   DCHECK(extension->is_platform_app());
121
122   for (base::DictionaryValue::Iterator iter(*all_handlers); !iter.IsAtEnd();
123        iter.Advance()) {
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))
128         return false;
129     } else {
130       *error = ASCIIToUTF16(errors::kInvalidFileHandlers);
131       return false;
132     }
133   }
134
135   extension->SetManifestData(keys::kFileHandlers, info.release());
136   return true;
137 }
138
139 const std::vector<std::string> FileHandlersParser::Keys() const {
140   return SingleKey(keys::kFileHandlers);
141 }
142
143 }  // namespace extensions