2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
18 #include "BookmarkManager.h"
19 #include "JSBookmarkFolder.h"
20 #include "JSBookmarkItem.h"
23 #include <JSTizenException.h>
24 #include <JSTizenExceptionFactory.h>
25 #include <PlatformException.h>
26 #include <favorites.h>
29 using namespace WrtDeviceApis::CommonsJavaScript;
30 using namespace DeviceAPI::Common;
34 static bool favorites_bookmark_foreach_cb(favorites_bookmark_entry_s *entry, void *user_data) {
37 BookmarkSearchData *searchData = static_cast<BookmarkSearchData*>(user_data);
39 if (searchData->m_bookmark)
40 parentId = (searchData->m_bookmark)->m_id;
42 parentId = BookmarkManager::getInstance()->getRootFolderId();
44 LoggerD("parentId : " << parentId);
45 LoggerD("m_reculsive : " << searchData->m_reculsive);
46 LoggerD("entry title : " << entry->title);
47 LoggerD("entry id : " << entry->id);
48 if (!(searchData->isAlive) && (entry->id == parentId))
49 searchData->isAlive = true;
51 LoggerD("isAlive : " << searchData->isAlive);
53 if ((searchData->m_reculsive) || (entry->folder_id == parentId)) {
54 LoggerD("found subitem : " << entry->title);
55 BookmarkDataPtr bookmark;
57 bookmark = BookmarkDataPtr(new BookmarkData(BOOKMARKFOLDER_TYPE, entry->title, "", entry->id, entry->folder_id));
59 bookmark = BookmarkDataPtr(new BookmarkData(BOOKMARKITEM_TYPE, entry->title, entry->address, entry->id, entry->folder_id));
61 (searchData->m_results).insert(std::pair<int,BookmarkDataPtr>(entry->folder_id, bookmark));
63 if (!(searchData->isAlive) || (searchData->m_reculsive) || (parentId == BookmarkManager::getInstance()->getRootFolderId()) || ((searchData->m_bookmark)->m_type == BOOKMARKFOLDER_TYPE))
66 LoggerD("user_data is null");
72 static bool favorites_bookmark_parent_search_cb(favorites_bookmark_entry_s *entry, void *user_data) {
74 BookmarkParentSearchData *parentSearchData = static_cast<BookmarkParentSearchData *>(user_data);
75 LoggerD("entry->id : " << entry->id);
77 if (entry->id == parentSearchData->m_id) {
78 parentSearchData->isAlive = true;
79 } else if (entry->id == parentSearchData->m_parentId){
80 LoggerD("Found parent");
81 parentSearchData->isParentAlive = true;
82 parentSearchData->m_parent = BookmarkDataPtr(new BookmarkData(BOOKMARKFOLDER_TYPE, entry->title, "", entry->id, entry->folder_id));
86 if (parentSearchData->isAlive && parentSearchData->isParentAlive) {
87 LoggerD("Found parent.Stop.");
93 LoggerD("user_data is null");
98 std::vector<BookmarkDataPtr> BookmarkManager::get(BookmarkSearchDataPtr &searchData){
101 std::vector<BookmarkDataPtr> bookmarkArray;
102 if (favorites_bookmark_get_count(&count) == FAVORITES_ERROR_NONE) {
104 if (searchData->m_bookmark == NULL) {
105 return bookmarkArray;
107 throw NotFoundException("No Bookmark in DB");
110 if (searchData->m_bookmark == NULL)
111 searchData->isAlive = true;
113 int result = favorites_bookmark_foreach(favorites_bookmark_foreach_cb, searchData.get());
114 if (result == FAVORITES_ERROR_NONE)
115 return _getCompleteCB(searchData);
116 else if (result == FAVORITES_ERROR_DB_FAILED)
117 throw UnknownException("DB Failed");
119 throw UnknownException("Unknown Error");
122 throw IOException("DB failed");
126 std::vector<BookmarkDataPtr> BookmarkManager::_getCompleteCB(BookmarkSearchDataPtr &searchData){
128 std::vector<BookmarkDataPtr> bookmarkArray;
129 //check if searchData->m_bookmark is in db or not
130 if (searchData->isAlive) {
131 //find sub items. If it is empty, it will return empty array
132 if ((searchData->m_results).size() > 0) {
133 std::multimap<int,BookmarkDataPtr>::iterator it;
134 //If searchData->m_bookmark is null, it is to get bookmarks under root folder.
135 //If it is root folder or reculsive is false, it is no need to filter because bookmarks excluding from list doesn't exist.
136 if (searchData->m_reculsive && searchData->m_bookmark) {
137 std::queue<BookmarkData *> folders; // It is the queue of finding item
139 BookmarkData *parent = searchData->m_bookmark;
140 for (it=(searchData->m_results).begin(); it!=(searchData->m_results).end(); ++it)
141 LoggerD("it->first:"<<it->first << " it->second:" <<(it->second)->m_id);
143 int lastItemId = (((searchData->m_results).rbegin())->second)->m_id;
144 LoggerD("end's first:"<<((searchData->m_results).rbegin())->first << "end's second:"<<lastItemId);
146 it = (searchData->m_results).find(parent->m_id);
147 LoggerD("it->first:"<<it->first << " parent->m_id:" <<parent->m_id);
148 while (it->first == parent->m_id) {
149 LoggerD("it->second:"<<(it->second)->m_id);
150 bookmarkArray.push_back(it->second);
151 LoggerD("m_type:"<<(it->second)->m_type);
152 //if it is folder, it will be pushed in folders vector
153 if ((it->second)->m_type == BOOKMARKFOLDER_TYPE)
154 folders.push((it->second).get());
156 if ((it->second)->m_id != lastItemId) {
157 LoggerD("not last item");
159 LoggerD("it->first:"<<it->first << " it->second:" <<(it->second)->m_id);
165 if (folders.size()) {
166 parent = folders.front();
167 LoggerD("parent->m_id:" <<parent->m_id);
174 for (it=(searchData->m_results).begin(); it!=(searchData->m_results).end(); ++it) {
175 bookmarkArray.push_back(it->second);
179 } else { // Not found Error because it is not in db
180 throw NotFoundException("Can't find the parent folder");
183 return bookmarkArray;
186 int BookmarkManager::add(bookmarkType type, const int parent_id, const std::string& title, const std::string& url) {
188 int id = UNDEFINED_ID;
189 int result = favorites_bookmark_add(title.c_str(), url.c_str(), parent_id, static_cast<int>(type), &id);
190 if (result == FAVORITES_ERROR_NONE)
192 else if (result == FAVORITES_ERROR_ITEM_ALREADY_EXIST)
193 throw InvalidValuesException("Already Exist");
194 else if (result == FAVORITES_ERROR_INVALID_PARAMETER)
195 throw InvalidValuesException("Wrong parameter");
196 else if (result == FAVORITES_ERROR_DB_FAILED)
197 throw UnknownException("DB Failed");
198 else if (result == FAVORITES_ERROR_NO_SUCH_FILE)
199 throw NotFoundException("Can't find the parent folder");
201 throw UnknownException("Unknown Error");
204 void BookmarkManager::remove(BookmarkSearchDataPtr &searchData) {
206 int result = FAVORITES_ERROR_NONE;
207 if (searchData->m_bookmark == NULL)
208 result = favorites_bookmark_delete_all_bookmarks();
209 else if ((searchData->m_bookmark)->m_type == BOOKMARKITEM_TYPE)
210 result = favorites_bookmark_delete_bookmark((searchData->m_bookmark)->m_id);
213 result = favorites_bookmark_foreach(favorites_bookmark_foreach_cb, searchData.get());
214 if (result == FAVORITES_ERROR_NONE) {
215 std::vector<BookmarkDataPtr> deletebookmarks = _getCompleteCB(searchData);
216 result = favorites_bookmark_delete_bookmark((searchData->m_bookmark)->m_id);
217 if (result == FAVORITES_ERROR_NONE) {
218 for (std::size_t i = 0; i < deletebookmarks.size(); ++i) {
219 result = favorites_bookmark_delete_bookmark(deletebookmarks[i]->m_id);
220 if (result != FAVORITES_ERROR_NONE)
225 } catch( const NotFoundException& err) {
226 LoggerD("Not Found");
231 if (result == FAVORITES_ERROR_NONE)
233 else if (result == FAVORITES_ERROR_DB_FAILED)
234 throw UnknownException("DB Failed");
236 throw UnknownException("Unknown Error");
239 bool BookmarkManager::findParent(BookmarkParentSearchDataPtr &parentSearchData) {
240 if (parentSearchData->m_parentId == getRootFolderId())
241 parentSearchData->isParentAlive = true;
243 int result = favorites_bookmark_foreach(favorites_bookmark_parent_search_cb, parentSearchData.get());
244 if ((result == FAVORITES_ERROR_NONE) && parentSearchData->isAlive && parentSearchData->isParentAlive)
250 int BookmarkManager::getRootFolderId() {
255 BookmarkManager* BookmarkManager::getInstance(){
256 static BookmarkManager instance;
260 BookmarkManager::BookmarkManager(){
262 favorites_bookmark_get_root_folder_id(&rootFolderId);
264 BookmarkManager::~BookmarkManager(){