c17e0f3ca3d4aef29f868ff2f1497d99b39fc6c8
[platform/core/api/webapi-plugins.git] / src / bookmark / bookmark_instance.cc
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16
17 #include "bookmark/bookmark_instance.h"
18
19 #include <web/bookmark-adaptor.h>
20 #include <string>
21
22 #include "common/platform_exception.h"
23 #include "common/converter.h"
24 #include "common/logger.h"
25
26 using common::ErrorCode;
27 using common::PlatformResult;
28
29 namespace extension {
30 namespace bookmark {
31
32 namespace {
33   const char kId[] = "id";
34   const char kTitle[] = "title";
35   const char kType[] = "type";
36   const char kParentId[] = "parentId";
37   const char kUrl[] = "url";
38 }  // namespace
39
40 BookmarkInstance::BookmarkInstance() {
41   LoggerD("Enter");
42   using std::placeholders::_1;
43   using std::placeholders::_2;
44
45 #define REGISTER_SYNC(c,x) \
46     RegisterSyncHandler(c, std::bind(&BookmarkInstance::x, this, _1, _2));
47   REGISTER_SYNC("Bookmark_get", BookmarkGet);
48   REGISTER_SYNC("Bookmark_add", BookmarkAdd);
49   REGISTER_SYNC("Bookmark_remove", BookmarkRemove);
50   REGISTER_SYNC("Bookmark_removeAll", BookmarkRemoveAll);
51   REGISTER_SYNC("Bookmark_getRootId", BookmarkGetRootId);
52 #undef REGISTER_SYNC
53 }
54
55 BookmarkInstance::~BookmarkInstance() {
56   LoggerD("Enter");
57 }
58
59 bool BookmarkInstance::bookmark_foreach(
60     Context& ctx, bp_bookmark_info_fmt& info) {
61
62   LoggerD("Enter");
63   int ids_count = 0;
64   int* ids = NULL;
65   BookmarkObject item;
66   if (bp_bookmark_adaptor_get_ids_p(&ids, &ids_count, -1, 0, -1, -1, -1, -1,
67                                     BP_BOOKMARK_O_DATE_CREATED, 0) < 0)
68     return false;
69
70
71   if (ids_count > 0) {
72     for (int i = 0; i < ids_count; i++) {
73       bp_bookmark_adaptor_get_easy_all(ids[i], &info);
74       item.id = ids[i];
75       item.bookmark_info = info;
76       if ((ctx.shouldGetItems && item.bookmark_info.parent != ctx.id) ||
77         (!ctx.shouldGetItems && item.id != ctx.id))
78         continue;
79       ctx.folders.push_back(item);
80     }
81   }
82   free(ids);
83   return true;
84 }
85
86 PlatformResult BookmarkInstance::BookmarkUrlExists(const char* url,
87                                                    bool* exists) {
88   LoggerD("Enter");
89   int ids_count = 0;
90   int* ids = nullptr;
91   char* compare_url = nullptr;
92
93   int ntv_ret = bp_bookmark_adaptor_get_ids_p(
94                     &ids,  // ids
95                     &ids_count,  // count
96                     -1,  //limit
97                     0,  // offset
98                     -1,  //parent
99                     -1,  //type
100                     -1,  // is_operator
101                     -1,  // is_editable
102                     BP_BOOKMARK_O_DATE_CREATED,  // order_offset
103                     0  // ordering ASC
104                     );
105   if (ntv_ret < 0) {
106     return LogAndCreateResult(
107                 ErrorCode::UNKNOWN_ERR, "Failed to obtain bookmarks",
108                 ("bp_bookmark_adaptor_get_ids_p error: %d (%s)", ntv_ret, get_error_message(ntv_ret)));
109   }
110
111   PlatformResult result{ErrorCode::NO_ERROR};
112   bool url_found = false;
113   for (int i = 0; (i < ids_count) && result && !url_found; ++i) {
114     ntv_ret = bp_bookmark_adaptor_get_url(ids[i], &compare_url);
115     if (ntv_ret < 0) {
116       result = LogAndCreateResult(
117                     ErrorCode::UNKNOWN_ERR, "Failed to obtain URL",
118                     ("bp_bookmark_adaptor_get_url error: %d (%s)", ntv_ret, get_error_message(ntv_ret)));
119     } else {
120       url_found = (0 == strcmp(url, compare_url));
121       free(compare_url);
122       compare_url = nullptr;
123     }
124   }
125
126   if (result) {
127     *exists = url_found;
128   }
129
130   free(ids);
131
132   return result;
133 }
134
135 PlatformResult BookmarkInstance::BookmarkTitleExistsInParent(const char* title,
136                                                              int parent,
137                                                              bool* exists) {
138
139   LoggerD("Enter");
140   int ids_count = 0;
141   int compare_parent = -1;
142   int* ids = nullptr;
143   char* compare_title = nullptr;
144
145   int ntv_ret = bp_bookmark_adaptor_get_ids_p(
146                     &ids,  // ids
147                     &ids_count,  // count
148                     -1,  //limit
149                     0,  // offset
150                     -1,  //parent
151                     -1,  //type
152                     -1,  // is_operator
153                     -1,  // is_editable
154                     BP_BOOKMARK_O_DATE_CREATED,  // order_offset
155                     0  // ordering ASC
156                     );
157   if (ntv_ret < 0) {
158     return LogAndCreateResult(
159                 ErrorCode::UNKNOWN_ERR, "Failed to obtain bookmarks",
160                 ("bp_bookmark_adaptor_get_ids_p error: %d (%s)",
161                     ntv_ret, get_error_message(ntv_ret)));
162   }
163
164   PlatformResult result{ErrorCode::NO_ERROR};
165   bool title_found = false;
166   for (int i = 0; (i < ids_count) && result && !title_found; ++i) {
167     if ((ntv_ret = bp_bookmark_adaptor_get_parent_id(ids[i], &compare_parent)) < 0) {
168       result = LogAndCreateResult(
169                     ErrorCode::UNKNOWN_ERR, "Failed to obtain parent ID",
170                     ("bp_bookmark_adaptor_get_parent_id error: %d (%s)",
171                         ntv_ret, get_error_message(ntv_ret)));
172     } else if ((ntv_ret = bp_bookmark_adaptor_get_title(ids[i], &compare_title)) < 0) {
173       result = LogAndCreateResult(
174                     ErrorCode::UNKNOWN_ERR, "Failed to obtain title",
175                     ("bp_bookmark_adaptor_get_title error: %d (%s)",
176                         ntv_ret, get_error_message(ntv_ret)));
177     } else {
178       title_found = (parent == compare_parent) && (0 == strcmp(title, compare_title));
179       free(compare_title);
180       compare_title = nullptr;
181       compare_parent = -1;
182     }
183   }
184
185   if (result) {
186     *exists = title_found;
187   }
188
189   free(ids);
190
191   return result;
192 }
193
194 void BookmarkInstance::BookmarkGet(
195     const picojson::value& arg, picojson::object& o) {
196
197   LoggerD("Enter");
198   Context ctx = {0};
199   bp_bookmark_info_fmt info = {0};
200   picojson::value::array arr;
201
202   ctx.shouldGetItems = arg.get("shouldGetItems").get<double>();
203   ctx.id             = arg.get(kId).get<double>();
204
205   if (!bookmark_foreach(ctx, info)) {
206     LoggerE("BookmarkGet error");
207     ReportError(o);
208     return;
209   }
210
211   std::vector<BookmarkObject>::iterator it;
212   for (it = ctx.folders.begin(); it!= ctx.folders.end(); ++it) {
213     picojson::object obj;
214     BookmarkObject entry = *it;
215
216     obj[kTitle] = picojson::value(entry.bookmark_info.title);
217     obj[kId] = picojson::value(std::to_string(entry.id));
218     obj[kType] = picojson::value(std::to_string(entry.bookmark_info.type));
219     obj[kParentId] = picojson::value(std::to_string(
220         entry.bookmark_info.parent));
221     if (!entry.bookmark_info.type)
222       obj[kUrl] = picojson::value(entry.bookmark_info.url);
223
224     arr.push_back(picojson::value(obj));
225   }
226   ReportSuccess(picojson::value(arr), o);
227 }
228
229 void BookmarkInstance::BookmarkAdd(
230     const picojson::value& arg, picojson::object& o) {
231
232   LoggerD("Enter");
233   int saved_id =-1;
234
235   const auto& title = arg.get(kTitle).get<std::string>();
236   const int parent = static_cast<int>(arg.get(kParentId).get<double>());
237   const int type = static_cast<int>(arg.get(kType).get<double>());
238   const auto& url = arg.get(kUrl).get<std::string>();
239
240   if (0 == type) {  // bookmark
241     bool exists = false;
242     auto result = BookmarkUrlExists(url.c_str(), &exists);
243     if (!result) {
244       LogAndReportError(result, &o);
245       return;
246     } else if (exists) {
247       LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Bookmark already exists"), &o);
248       return;
249     }
250   }
251
252   if (1 == type) {  // folder
253     bool exists = false;
254     auto result = BookmarkTitleExistsInParent(title.c_str(), parent, &exists);
255     if (!result) {
256       LogAndReportError(result, &o);
257       return;
258     } else if (exists) {
259       LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Bookmark already exists"), &o);
260       return;
261     }
262   }
263
264   int ntv_ret;
265
266   ntv_ret = bp_bookmark_adaptor_create(&saved_id);
267   if (ntv_ret < 0) {
268     LoggerE("bp_bookmark_adaptor_create error: %d (%s)", ntv_ret, get_error_message(ntv_ret));
269     ReportError(o);
270     return;
271   }
272
273   ntv_ret = bp_bookmark_adaptor_set_title(saved_id, title.c_str());
274   if (ntv_ret < 0) {
275     bp_bookmark_adaptor_delete(saved_id);
276     LoggerE("bp_bookmark_adaptor_set_title error: %d (%s)", ntv_ret, get_error_message(ntv_ret));
277     ReportError(o);
278     return;
279   }
280
281   ntv_ret = bp_bookmark_adaptor_set_parent_id(saved_id, parent);
282   if (ntv_ret < 0) {
283     bp_bookmark_adaptor_delete(saved_id);
284     LoggerE("bp_bookmark_adaptor_set_parent_id error: %d (%s)", ntv_ret, get_error_message(ntv_ret));
285     ReportError(o);
286     return;
287   }
288
289   ntv_ret = bp_bookmark_adaptor_set_type(saved_id, type);
290   if (ntv_ret < 0) {
291     bp_bookmark_adaptor_delete(saved_id);
292     LoggerE("bp_bookmark_adaptor_set_type error: %d (%s)", ntv_ret, get_error_message(ntv_ret));
293     ReportError(o);
294     return;
295   }
296
297   ntv_ret = bp_bookmark_adaptor_set_url(saved_id, url.c_str());
298   if (ntv_ret < 0) {
299     bp_bookmark_adaptor_delete(saved_id);
300     LoggerE("bp_bookmark_adaptor_set_url error: %d (%s)", ntv_ret, get_error_message(ntv_ret));
301     ReportError(o);
302     return;
303   }
304   ReportSuccess(picojson::value(std::to_string(saved_id)), o);
305 }
306
307 void BookmarkInstance::BookmarkRemove(
308     const picojson::value& arg, picojson::object& o) {
309
310   LoggerD("Enter");
311   int id = common::stol(
312       common::FromJson<std::string>(arg.get<picojson::object>(), kId));
313
314   int ntv_ret = bp_bookmark_adaptor_delete(id);
315   if (ntv_ret < 0) {
316     LoggerE("bp_bookmark_adaptor_delete error: %d (%s)", ntv_ret, get_error_message(ntv_ret));
317     ReportError(o);
318     return;
319   }
320   ReportSuccess(o);
321 }
322
323 void BookmarkInstance::BookmarkRemoveAll(
324     const picojson::value& msg, picojson::object& o) {
325
326   LoggerD("Enter");
327   int ntv_ret = bp_bookmark_adaptor_reset();
328   if (ntv_ret < 0) {
329     LoggerE("bp_bookmark_adaptor_reset error: %d (%s)", ntv_ret, get_error_message(ntv_ret));
330     ReportError(o);
331     return;
332   }
333   ReportSuccess(o);
334 }
335
336 void BookmarkInstance::BookmarkGetRootId(
337     const picojson::value& msg, picojson::object& o) {
338
339   LoggerD("Enter");
340   int rootId(0);
341   int ntv_ret = bp_bookmark_adaptor_get_root(&rootId);
342   if (ntv_ret < 0) {
343     LoggerE("bp_bookmark_adaptor_get_root error: %d (%s)", ntv_ret, get_error_message(ntv_ret));
344     ReportError(o);
345     return;
346   }
347   ReportSuccess(picojson::value(std::to_string(rootId)), o);
348 }
349 }  // namespace bookmark
350 }  // namespace extension