[Widget-manifest-parser] Remove LocalManifestData
[platform/core/appfw/app-installers.git] / src / widget-manifest-parser / widget_manifest_parser.cc
1 // Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
2 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE-xwalk file.
5
6 #include "widget-manifest-parser/widget_manifest_parser.h"
7
8 #include <boost/filesystem/path.hpp>
9
10 #include <algorithm>
11 #include <memory>
12 #include <set>
13 #include <string>
14 #include <vector>
15
16 #include "utils/macros.h"
17 #include "utils/values.h"
18
19 #include "widget-manifest-parser/application_data.h"
20 #include "widget-manifest-parser/application_manifest_constants.h"
21 #include "widget-manifest-parser/manifest_util.h"
22 #include "widget-manifest-parser/manifest_handlers/permissions_handler.h"
23 #include "widget-manifest-parser/manifest_handlers/tizen_application_handler.h"
24 #include "widget-manifest-parser/manifest_handlers/widget_handler.h"
25 #include "widget-manifest-parser/permission_types.h"
26
27 #define API_EXPORT __attribute__((visibility("default")))
28
29 namespace bf = boost::filesystem;
30 namespace keys = common_installer::application_widget_keys;
31 namespace parser = common_installer::widget_manifest_parser;
32
33 namespace {
34
35 const char kErrMsgNoPath[] =
36     "Path not specified.";
37 const char kErrMsgInvalidPath[] =
38     "Invalid path.";
39 const char kErrMsgValueNotFound[] =
40     "Value not found. Value name: ";
41 const char kErrMsgInvalidDictionary[] =
42     "Cannot get key value as a dictionary. Key name: ";
43 const char kErrMsgInvalidList[] =
44     "Cannot get key value as a list. Key name: ";
45 const char kErrMsgNoMandatoryKey[] =
46     "Cannot find mandatory key. Key name: ";
47
48 const char kName[] = "name";
49 const char kShortName[] = "shortName";
50 const char kVersion[] = "version";
51 const char kWidgetIconFullKey[] = "widget.icon";
52 const char kWidgetIconSrcKey[] = "@src";
53
54 typedef std::string LocalError;
55
56 void SetError(const std::string& message, const char** error) {
57   if (error)
58     *error = strdup(message.c_str());
59 }
60
61 void SetError(const std::string& message, const std::string& arg,
62     const char** error) {
63   if (error)
64     *error = strdup((message + arg).c_str());
65 }
66
67 bool ExtractPackage(
68     const parser::ApplicationData& app_data, std::string* value) {
69   parser::TizenApplicationInfo* info =
70       static_cast<parser::TizenApplicationInfo*>(
71           app_data.GetManifestData(keys::kTizenApplicationKey));
72   if (info)
73     *value = info->package();
74   return info;
75 }
76
77 bool ExtractId(
78     const parser::ApplicationData& app_data, std::string* value) {
79   parser::TizenApplicationInfo* info =
80       static_cast<parser::TizenApplicationInfo*>(
81           app_data.GetManifestData(keys::kTizenApplicationKey));
82   if (info)
83     *value = info->id();
84   return info;
85 }
86
87 bool ExtractName(const parser::ApplicationData& app_data, std::string* value) {
88   parser::WidgetInfo* info = static_cast<parser::WidgetInfo*>(
89       app_data.GetManifestData(keys::kWidgetKey));
90   if (!info)
91     return false;
92   return info->GetWidgetInfo()->GetString(kName, value);
93 }
94
95 bool ExtractShortName(const parser::ApplicationData& app_data,
96                       std::string* value) {
97   parser::WidgetInfo* info = static_cast<parser::WidgetInfo*>(
98       app_data.GetManifestData(keys::kWidgetKey));
99   if (!info)
100     return false;
101   return info->GetWidgetInfo()->GetString(kShortName, value);
102 }
103
104 bool ExtractVersion(const parser::ApplicationData& app_data,
105                     std::string* value) {
106   parser::WidgetInfo* info = static_cast<parser::WidgetInfo*>(
107       app_data.GetManifestData(keys::kWidgetKey));
108   if (!info)
109     return false;
110   return info->GetWidgetInfo()->GetString(kVersion, value);
111 }
112
113 bool ExtractIconSrc(const common_installer::utils::Value& dict,
114     std::string* value, const char** error) {
115   const common_installer::utils::DictionaryValue* inner_dict;
116   if (!dict.GetAsDictionary(&inner_dict)) {
117     SetError(kErrMsgInvalidDictionary, kWidgetIconFullKey, error);
118     return false;
119   }
120   std::string src;
121   if (!inner_dict->GetString(kWidgetIconSrcKey, &src)) {
122     SetError(kErrMsgNoMandatoryKey, kWidgetIconSrcKey, error);
123     return false;
124   }
125   *value = src;
126   return  true;
127 }
128
129 bool ExtractIcons(const parser::Manifest& manifest,
130                   std::vector<std::string>* value, const char** error) {
131   common_installer::utils::Value* key_value;
132   if (!manifest.Get(kWidgetIconFullKey, &key_value)) {
133     value->clear();
134     return true;  // no icon, no error
135   }
136
137   std::vector<std::string> icons;
138   if (key_value->IsType(common_installer::utils::Value::TYPE_DICTIONARY)) {
139     std::string icon;
140     if (!ExtractIconSrc(*key_value, &icon, error))
141       return false;
142     icons.push_back(icon);
143   } else if (key_value->IsType(common_installer::utils::Value::TYPE_LIST)) {
144     const common_installer::utils::ListValue* list;
145     if (!key_value->GetAsList(&list)) {
146       SetError(kErrMsgInvalidList, kWidgetIconFullKey, error);
147       return false;
148     }
149     for (const common_installer::utils::Value* list_value : *list) {
150       std::string icon;
151       if (!ExtractIconSrc(*list_value, &icon, error))
152         return false;
153       icons.push_back(icon);
154     }
155   }
156
157   value->swap(icons);
158   return true;
159 }
160
161 bool ExtractApiVersion(const parser::ApplicationData& app_data,
162                        std::string* value) {
163   parser::TizenApplicationInfo* info =
164       static_cast<parser::TizenApplicationInfo*>(
165         app_data.GetManifestData(keys::kTizenApplicationKey));
166   if (!info)
167     return false;
168   *value = info->required_version();
169   return true;
170 }
171
172 bool ExtractPrivileges(const parser::ApplicationData& app_data,
173                        std::set<std::string>* value, const char** error) {
174   const parser::PermissionsInfo* perm_info =
175        static_cast<parser::PermissionsInfo*>(
176             app_data.GetManifestData(keys::kTizenPermissionsKey));
177   parser::PermissionSet permissions = perm_info->GetAPIPermissions();
178   *value = permissions;
179   return true;
180 }
181
182 }  // namespace
183
184 extern "C" {
185
186 API_EXPORT bool ParseManifest(const char* path,
187     const ManifestData** data, const char** error) {
188   if (!path) {
189     SetError(kErrMsgNoPath, error);
190     return false;
191   }
192   std::string str_path = path;
193   if (str_path.empty()) {
194     SetError(kErrMsgInvalidPath, error);
195     return false;
196   }
197
198   std::string local_error;
199
200   std::unique_ptr<parser::Manifest> manifest = parser::LoadManifest(
201       path, parser::Manifest::TYPE_WIDGET, &local_error);
202   if (!manifest) {
203     SetError(local_error, error);
204     return false;
205   }
206
207   std::shared_ptr<parser::ApplicationData> app_data =
208       parser::ApplicationData::Create(bf::path(), std::string(),
209                                       parser::ApplicationData::INTERNAL,
210                                       std::move(manifest), &local_error);
211   if (!app_data.get()) {
212     SetError(local_error, error);
213     return false;
214   }
215
216   std::string package;
217   if (!ExtractPackage(*app_data, &package)) {
218     SetError(kErrMsgValueNotFound, "package id", error);
219     return false;
220   }
221
222   std::string id;
223   if (!ExtractId(*app_data, &id)) {
224     SetError(kErrMsgValueNotFound, "application id", error);
225     return false;
226   }
227
228   std::string name;
229   if (!ExtractName(*app_data, &name)) {
230     SetError(kErrMsgValueNotFound, "application name", error);
231     return false;
232   }
233
234   std::string short_name;
235   if (!ExtractShortName(*app_data, &short_name)) {
236     SetError(kErrMsgValueNotFound, "application short name", error);
237     return false;
238   }
239
240   std::string version;
241   if (!ExtractVersion(*app_data, &version)) {
242     SetError(kErrMsgValueNotFound, "application version", error);
243     return false;
244   }
245
246   std::vector<std::string> icons;
247   if (!ExtractIcons(*app_data->GetManifest(), &icons, error))
248     return false;
249
250   std::string api_version;
251   if (!ExtractApiVersion(*app_data, &api_version)) {
252     SetError(kErrMsgValueNotFound, "required api version", error);
253     return false;
254   }
255
256   std::set<std::string> privileges;
257   if (!ExtractPrivileges(*app_data, &privileges, error))
258     return false;
259
260   if (data) {
261     ManifestData* manifest_data = new ManifestData;
262     manifest_data->package = strdup(package.c_str());
263     manifest_data->id = strdup(id.c_str());
264     manifest_data->name = strdup(name.c_str());
265     manifest_data->short_name = strdup(short_name.c_str());
266     manifest_data->version = strdup(version.c_str());
267     manifest_data->icon =
268         icons.empty() ? strdup("") : strdup(icons.front().c_str());
269     manifest_data->api_version = strdup(api_version.c_str());
270     manifest_data->privilege_count = privileges.size();
271     manifest_data->privilege_list = new char*[privileges.size()];
272     char** privileges_it = manifest_data->privilege_list;
273     for (const std::string& p : privileges) {
274       *privileges_it = strdup(p.c_str());
275       ++privileges_it;
276     }
277     *data = manifest_data;
278   }
279
280   return true;
281 }
282
283 API_EXPORT void ReleaseData(const ManifestData* data, const char* error) {
284   free(data->package);
285   free(data->id);
286   free(data->name);
287   free(data->short_name);
288   free(data->version);
289   free(data->icon);
290   free(data->api_version);
291   for (int i = 0; i < data->privilege_count; ++i)
292     free(data->privilege_list[i]);
293   delete[] data->privilege_list;
294   delete data;
295   free((void*)error);
296 }
297
298 }  // extern "C"