a331bfeefeb7975e653048836b9fff16092ef68a
[framework/web/wrt-plugins-tizen.git] / src / Bookmark / BookmarkManager.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
18 #include "BookmarkManager.h"
19 #include "JSBookmarkFolder.h"
20 #include "JSBookmarkItem.h"
21 #include <queue>
22 #include <Ecore.h>
23 #include <dpl/log/log.h>
24 #include <JSTizenException.h>
25 #include <JSTizenExceptionFactory.h>
26 #include <PlatformException.h>
27 #include <favorites.h>
28
29 using namespace WrtDeviceApis::CommonsJavaScript;
30 using namespace DeviceAPI::Common;
31
32 namespace DeviceAPI {
33 namespace Bookmark{
34 static bool favorites_bookmark_foreach_cb(favorites_bookmark_entry_s *entry, void *user_data) {
35         LogDebug("Entered");
36         if (user_data) {
37                 BookmarkSearchData *searchData = static_cast<BookmarkSearchData*>(user_data);
38                 int parentId = 0;
39                 if (searchData->m_bookmark)
40                         parentId = (searchData->m_bookmark)->m_id;
41                 else
42                         parentId = BookmarkManager::getInstance()->getRootFolderId();
43
44                 LogDebug("parentId : " << parentId);
45                 LogDebug("m_reculsive : " << searchData->m_reculsive);
46                 LogDebug("entry title : " << entry->title);
47                 LogDebug("entry id : " << entry->id);
48                 if (!(searchData->isAlive) && (entry->id == parentId))
49                         searchData->isAlive = true;
50
51                 LogDebug("isAlive : " << searchData->isAlive);
52
53                 if ((searchData->m_reculsive) || (entry->folder_id == parentId)) {
54                         LogDebug("found subitem : " << entry->title);
55                         BookmarkDataPtr bookmark;
56                         if (entry->is_folder)
57                                 bookmark = BookmarkDataPtr(new BookmarkData(BOOKMARKFOLDER_TYPE, entry->title, "", entry->id, entry->folder_id));
58                         else
59                                 bookmark = BookmarkDataPtr(new BookmarkData(BOOKMARKITEM_TYPE, entry->title, entry->address, entry->id, entry->folder_id));
60                         
61                         (searchData->m_results).insert(std::pair<int,BookmarkDataPtr>(entry->folder_id, bookmark));
62                 }
63                 if (!(searchData->isAlive) || (searchData->m_reculsive) || (parentId == BookmarkManager::getInstance()->getRootFolderId()) || ((searchData->m_bookmark)->m_type == BOOKMARKFOLDER_TYPE))
64                         return true;    
65         } else
66                 LogDebug("user_data is null");
67
68         LogDebug("stop ");
69         return false;
70 }
71
72 static bool favorites_bookmark_parent_search_cb(favorites_bookmark_entry_s *entry, void *user_data) {
73         if (user_data){
74                 BookmarkParentSearchData *parentSearchData = static_cast<BookmarkParentSearchData *>(user_data);
75                 LogDebug("entry->id : " << entry->id);
76                 
77                 if (entry->id == parentSearchData->m_id) {
78                         parentSearchData->isAlive = true;
79                 } else if (entry->id == parentSearchData->m_parentId){
80                         LogDebug("Found parent");
81                         parentSearchData->isParentAlive = true;
82                         parentSearchData->m_parent = BookmarkDataPtr(new BookmarkData(BOOKMARKFOLDER_TYPE, entry->title, "", entry->id, entry->folder_id));
83                 } else
84                         return true;
85
86                 if (parentSearchData->isAlive && parentSearchData->isParentAlive) {
87                         LogDebug("Found parent.Stop.");
88                         return false;
89                 } else
90                         return true;
91         }
92
93         LogDebug("user_data is null");
94         return false;
95 }
96
97
98 std::vector<BookmarkDataPtr> BookmarkManager::get(BookmarkSearchDataPtr &searchData){
99         LogDebug("Entered");
100         int count;
101         std::vector<BookmarkDataPtr> bookmarkArray;
102         if (favorites_bookmark_get_count(&count) == FAVORITES_ERROR_NONE) {
103                 if (!count) {
104                         if (searchData->m_bookmark == NULL) {
105                                 return bookmarkArray;
106                         } else {
107                                 throw NotFoundException("No Bookmark in DB");
108                         }
109                 } else {
110                         if (searchData->m_bookmark == NULL)
111                                 searchData->isAlive = true;
112
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 IOException("DB Failed");
118                         else
119                                 throw UnknownException("Unknown Error");
120                 }
121         } else {
122                 throw IOException("DB failed");
123         }
124 }
125
126 std::vector<BookmarkDataPtr> BookmarkManager::_getCompleteCB(BookmarkSearchDataPtr &searchData){
127     LogDebug("Enter");
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
138                                 
139                                 BookmarkData *parent = searchData->m_bookmark;
140                                 for (it=(searchData->m_results).begin(); it!=(searchData->m_results).end(); ++it)
141                                         LogDebug("it->first:"<<it->first << " it->second:" <<(it->second)->m_id);
142
143                                 int lastItemId = (((searchData->m_results).rbegin())->second)->m_id;
144                                 LogDebug("end's first:"<<((searchData->m_results).rbegin())->first << "end's second:"<<lastItemId);
145                                 while (1) {
146                                         it = (searchData->m_results).find(parent->m_id);
147                                         LogDebug("it->first:"<<it->first << " parent->m_id:" <<parent->m_id);
148                                         while (it->first == parent->m_id) {
149                                                 LogDebug("it->second:"<<(it->second)->m_id);
150                                                 bookmarkArray.push_back(it->second);
151                                                 LogDebug("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());
155
156                                                 if ((it->second)->m_id != lastItemId) {
157                                                         LogDebug("not last item");
158                                                         it++;
159                                                         LogDebug("it->first:"<<it->first << " it->second:" <<(it->second)->m_id);
160                                                 } else
161                                                         break;
162                                                 
163                                         }
164
165                                         if (folders.size()) {
166                                                 parent = folders.front();
167                                                 LogDebug("parent->m_id:" <<parent->m_id);
168                                                 folders.pop();
169                                         } else
170                                                 break;
171                                                 
172                                 }
173                         } else {
174                                 for (it=(searchData->m_results).begin(); it!=(searchData->m_results).end(); ++it) {
175                                         bookmarkArray.push_back(it->second);
176                                 }
177                         }
178                 } 
179         } else { // Not found Error because it is not in db
180                 throw NotFoundException("Can't find the parent folder");
181         }
182         LogDebug("Success!");
183         return bookmarkArray;
184 }
185
186 int BookmarkManager::add(bookmarkType type, const int parent_id, const std::string& title, const std::string& url) {
187         LogDebug("Entered");
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)
191                 return id;
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 IOException("DB Failed");
198         else if (result == FAVORITES_ERROR_NO_SUCH_FILE)
199                 throw NotFoundException("Can't find the parent folder");
200         else
201                 throw UnknownException("Unknown Error");        
202 }
203
204 void BookmarkManager::remove(BookmarkSearchDataPtr &searchData) {
205         LogDebug("Entered");
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);
211         else {
212                 result = favorites_bookmark_foreach(favorites_bookmark_foreach_cb, searchData.get());
213                 if (result == FAVORITES_ERROR_NONE) {
214                         std::vector<BookmarkDataPtr> deletebookmarks = _getCompleteCB(searchData);
215                         result = favorites_bookmark_delete_bookmark((searchData->m_bookmark)->m_id);
216                         if (result == FAVORITES_ERROR_NONE) {
217                                 for (int i = 0; i < deletebookmarks.size(); ++i) {
218                                         result = favorites_bookmark_delete_bookmark(deletebookmarks[i]->m_id);
219                                         if (result != FAVORITES_ERROR_NONE)
220                                                 break;
221                                 }
222                         }
223                 }
224         }
225
226         if (result == FAVORITES_ERROR_NONE)
227                 return;
228         else if (result == FAVORITES_ERROR_DB_FAILED)
229                 throw IOException("DB Failed");
230         else
231                 throw UnknownException("Unknown Error");                
232 }
233
234 bool BookmarkManager::findParent(BookmarkParentSearchDataPtr &parentSearchData) {
235         if (parentSearchData->m_parentId == getRootFolderId())
236                 parentSearchData->isParentAlive = true;
237
238         int result = favorites_bookmark_foreach(favorites_bookmark_parent_search_cb, parentSearchData.get());
239         if ((result == FAVORITES_ERROR_NONE) && parentSearchData->isAlive && parentSearchData->isParentAlive)
240                 return true;
241         else
242                 return false;
243 }
244
245 int BookmarkManager::getRootFolderId() {
246         return rootFolderId;
247         
248 }
249
250 BookmarkManager* BookmarkManager::getInstance(){
251     static BookmarkManager instance;
252     return &instance;
253 }
254
255 BookmarkManager::BookmarkManager(){
256         rootFolderId = 0;
257         favorites_bookmark_get_root_folder_id(&rootFolderId);
258 }
259 BookmarkManager::~BookmarkManager(){
260 }
261
262 }
263 }
264