From: Wojciech Kosowicz Date: Wed, 17 Dec 2014 08:59:44 +0000 (+0100) Subject: [Calendar] Updated C++ files X-Git-Tag: submit/tizen_tv/20150603.064601~1^2~775 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ece430eb6a81ca1d1fa2690cc0d412f9abfdd03e;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Calendar] Updated C++ files Commit contains updated C++ files. One synchronuous method already works. [Verification] It builts Change-Id: If96bfa95c2947b31016df358922bf8c5c57ca61e Signed-off-by: Wojciech Kosowicz --- diff --git a/src/calendar/calendar.cc b/src/calendar/calendar.cc new file mode 100644 index 00000000..fc9b1246 --- /dev/null +++ b/src/calendar/calendar.cc @@ -0,0 +1,700 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "calendar.h" + +#include "common/platform_exception.h" +#include "common/logger.h" +#include "common/converter.h" +#include "common/task-queue.h" +#include "calendar/calendar_manager.h" +#include "calendar/calendar_privilege.h" +#include "calendar/calendar_item.h" + +namespace extension { +namespace calendar { + +using namespace common; + +int Calendar::current_db_version_ = 0; +std::map Calendar::listeners_registered_; + +Calendar& Calendar::GetInstance() { + static Calendar instance; + return instance; +} + +Calendar::~Calendar() { + int ret; + + if (listeners_registered_.find("EVENT") != listeners_registered_.end()) { + ret = calendar_db_remove_changed_cb(_calendar_event._uri, ChangeCallback, + nullptr); + if (CALENDAR_ERROR_NONE != ret) { + LoggerE("Remove calendar event change callback error"); + } + } + + if (listeners_registered_.find("TASK") != listeners_registered_.end()) { + ret = calendar_db_remove_changed_cb(_calendar_todo._uri, ChangeCallback, + nullptr); + if (CALENDAR_ERROR_NONE != ret) { + LoggerE("Remove calendar todo change callback error"); + } + } +} + +void Calendar::Get(const picojson::object& args, picojson::object& out) { + LoggerD("enter"); + +// NativePlugin::CheckAccess(Privilege::kCalendarRead); + + if (!CalendarManager::GetInstance().IsConnected()) { + throw UnknownException("DB Connection failed."); + } + + int calendar_id = common::stol(FromJson(args, "calendarId")); + CalendarRecordPtr calendar_ptr = + CalendarRecord::GetById(calendar_id, _calendar_book._uri); + int type = + CalendarRecord::GetInt(calendar_ptr.get(), _calendar_book.store_type); + + int id; + if (type == CALENDAR_BOOK_TYPE_EVENT) { + id = common::stol(FromJson(args, "id", "uid")); + } else { + id = common::stol(FromJson(args, "id")); + } + + CalendarRecordPtr record_ptr = + CalendarRecord::GetById(id, CalendarRecord::TypeToUri(type)); + picojson::value record_obj = picojson::value(picojson::object()); + CalendarItem::ToJson(type, record_ptr.get(), &record_obj.get()); + +} + +void Calendar::Add(const picojson::object& args, picojson::object& out) { + LoggerD("enter"); + + if (!CalendarManager::GetInstance().IsConnected()) { + throw UnknownException("DB Connection failed."); + } + + const auto& item = FromJson(args, "item"); + int type = CalendarRecord::TypeToInt(FromJson(args, "type")); + + CalendarRecordPtr item_ptr = CalendarItem::Create(type); + CalendarItem::FromJson(type, item_ptr.get(), item); + int record_id = CalendarRecord::Insert(item_ptr.get()); + + picojson::value result = picojson::value(picojson::object()); + picojson::object& result_obj = result.get(); + result_obj.insert(std::make_pair("uid", std::to_string(record_id))); + + if (type == CALENDAR_BOOK_TYPE_EVENT) { + std::string rid = CalendarRecord::GetString(item_ptr.get(), + _calendar_event.recurrence_id); + if (!rid.empty()) { + result_obj["rid"] = picojson::value(rid); + } else { + result_obj["rid"] = picojson::value(); + } + } + +} + +void Calendar::AddBatch(const picojson::object& args, + picojson::object& out) { + LoggerD("enter"); + + + if (!CalendarManager::GetInstance().IsConnected()) { + throw UnknownException("DB Connection failed."); + } + + auto& items = FromJson(args, "items"); + if (items.empty()) { + throw InvalidValuesException("No items"); + } + + int type = CalendarRecord::TypeToInt(FromJson(args, "type")); + const char* view_uri = CalendarRecord::TypeToUri(type); + + auto batch_func = [=](const JsonValuePtr & response)->void { + picojson::object& response_obj = response->get(); + + try { + calendar_list_h list = NULL; + if (CALENDAR_ERROR_NONE != calendar_list_create(&list)) { + LoggerE("Could not create list for batch operation"); + throw UnknownException("Could not create list for batch operation"); + } + CalendarListPtr list_ptr = + CalendarListPtr(list, CalendarRecord::ListDeleter); + + int ret; + calendar_record_h record; + + for (auto& item : items) { + ret = calendar_record_create(view_uri, &record); + if (CALENDAR_ERROR_NONE != ret) { + LoggerW("Can't create platform record %d", ret); + throw UnknownException("Can't create platform record"); + } + CalendarItem::FromJson(type, record, item.get()); + + if (CALENDAR_ERROR_NONE != calendar_list_add(list_ptr.get(), record)) { + LoggerE("Could not add record to list events"); + throw InvalidValuesException("Could not add record to list"); + } + } + + int* ids; + int count; + ret = calendar_db_insert_records(list_ptr.get(), &ids, &count); + if (CALENDAR_ERROR_NONE != ret) { + LoggerE("calendar_db_insert_records failed."); + if (CALENDAR_ERROR_INVALID_PARAMETER == ret) { + LoggerE("CALENDAR_ERROR_INVALID_PARAMETER."); + throw InvalidValuesException("Parameter is invalid"); + } else { + LoggerE("CALENDAR_ERROR_DB_FAILED"); + throw UnknownException("CALENDAR_ERROR_DB_FAILED occurred"); + } + } + + picojson::value result = picojson::value(picojson::array()); + picojson::array& array = result.get(); + + for (int i = 0; i < count; i++) { + picojson::value id = picojson::value(picojson::object()); + picojson::object& id_obj = id.get(); + + id_obj.insert(std::make_pair("uid", std::to_string(ids[i]))); + + if (type == CALENDAR_BOOK_TYPE_EVENT) { + id_obj.insert(std::make_pair("rid", picojson::value())); + } + + array.push_back(id); + } + free(ids); + + } + catch(...) {//(const BasePlatformException& e) { + } + }; + + int callback_handle;// = NativePlugin::GetAsyncCallbackHandle(args); + auto after_batch_func = [callback_handle](const JsonValuePtr& response) { + }; + + TaskQueue::GetInstance().Queue( + batch_func, after_batch_func, + JsonValuePtr(new picojson::value(picojson::object()))); +} + +void Calendar::Update(const picojson::object& args, + picojson::object& /*out*/) { + LoggerD("enter"); + + if (!CalendarManager::GetInstance().IsConnected()) { + throw UnknownException("DB Connection failed."); + } + + const auto& item = FromJson(args, "item"); + int type = CalendarRecord::TypeToInt(FromJson(args, "type")); + + bool update_all = true; + + int id; + if (type == CALENDAR_BOOK_TYPE_EVENT) { + id = common::stol(FromJson(item, "id", "uid")); + if (!IsNull(args, "updateAllInstances")) { + update_all = FromJson(args, "updateAllInstances"); + } + } else { + id = common::stol(FromJson(item, "id")); + } + + CalendarRecordPtr record_ptr = + CalendarRecord::GetById(id, CalendarRecord::TypeToUri(type)); + CalendarItem::FromJson(type, record_ptr.get(), item); + + if (type == CALENDAR_BOOK_TYPE_TODO || update_all || + common::IsNull(item, "recurrenceRule")) { + if (CALENDAR_ERROR_NONE != calendar_db_update_record(record_ptr.get())) { + LoggerE("Can't update calendar item"); + throw UnknownException("Can't update calendar item"); + } + } else { + // first update the parent event + std::string exdate = CalendarItem::ExceptionsFromJson( + common::FromJson(item, "recurrenceRule", "exceptions")); + if (!common::IsNull(common::FromJson(item, "id"), "rid")) { + exdate.append(common::FromJson(item, "id", "rid")); + } + CalendarRecord::SetString(record_ptr.get(), _calendar_event.exdate, exdate); + + // don't set the recurrence id for the parent event + CalendarRecord::SetString(record_ptr.get(), _calendar_event.recurrence_id, + ""); + + if (CALENDAR_ERROR_NONE != calendar_db_update_record(record_ptr.get())) { + LoggerE("Can't update calendar item"); + throw UnknownException("Can't update calendar item"); + } + + // now add the detached child event + CalendarRecordPtr item_ptr = CalendarItem::Create(type); + CalendarItem::FromJson(type, item_ptr.get(), item); + CalendarRecord::Insert(item_ptr.get()); + } +} + +void Calendar::UpdateBatch(const picojson::object& args, + picojson::object& out) { + LoggerD("enter"); + + if (!CalendarManager::GetInstance().IsConnected()) { + throw UnknownException("DB Connection failed."); + } + + auto& items = FromJson(args, "items"); + if (items.empty()) { + throw InvalidValuesException("No items"); + } + + bool update_all = true; + if (!IsNull(args, "updateAllInstances")) { + update_all = FromJson(args, "updateAllInstances"); + } + + int type = CalendarRecord::TypeToInt(FromJson(args, "type")); + const char* view_uri = CalendarRecord::TypeToUri(type); + + auto batch_func = [=](const JsonValuePtr & response)->void { + picojson::object& response_obj = response->get(); + + try { + calendar_list_h list = NULL; + if (CALENDAR_ERROR_NONE != calendar_list_create(&list)) { + LoggerE("Could not create list for batch operation"); + throw UnknownException("Could not create list for batch operation"); + } + CalendarListPtr list_ptr = + CalendarListPtr(list, CalendarRecord::ListDeleter); + + int ret, id; + calendar_record_h record; + + for (auto& item : items) { + const picojson::object& item_obj = item.get(); + if (type == CALENDAR_BOOK_TYPE_EVENT) { + id = common::stol(FromJson(item_obj, "id", "uid")); + } else { + id = common::stol(FromJson(item_obj, "id")); + } + + ret = calendar_db_get_record(view_uri, id, &record); + if (CALENDAR_ERROR_NONE != ret) { + LoggerW("Can't get platform record %d", ret); + throw UnknownException("Can't get platform record"); + } + CalendarItem::FromJson(type, record, item.get()); + + if (CALENDAR_ERROR_NONE != calendar_list_add(list_ptr.get(), record)) { + LoggerE("Could not add record to list events"); + throw InvalidValuesException("Could not add record to list"); + } + } + + if (type == CALENDAR_BOOK_TYPE_TODO || update_all) { + if (CALENDAR_ERROR_NONE != calendar_db_update_records(list_ptr.get())) { + LoggerE("Can't update calendar items"); + throw UnknownException("Can't update calendar items"); + } + } else { + // @todo update the exdate for a recurring parent event and add a new + // child event + } + + } + catch (...) {//const BasePlatformException& e) { + } + }; + + int callback_handle; //= NativePlugin::GetAsyncCallbackHandle(args); + auto after_batch_func = [callback_handle](const JsonValuePtr& response) { + }; + + TaskQueue::GetInstance().Queue( + batch_func, after_batch_func, + JsonValuePtr(new picojson::value(picojson::object()))); +} + +void Calendar::Remove(const picojson::object& args, + picojson::object& out) { + LoggerD("enter"); + + if (!CalendarManager::GetInstance().IsConnected()) { + throw UnknownException("DB Connection failed."); + } + + int type = CalendarRecord::TypeToInt(FromJson(args, "type")); + + int id; + if (type == CALENDAR_BOOK_TYPE_EVENT) { + id = common::stol(FromJson(args, "id", "uid")); + } else { + id = common::stol(FromJson(args, "id")); + } + + CalendarItem::Remove(type, id); +} + +void Calendar::Find(const picojson::object& args, picojson::object& out) { + LoggerD("enter"); + + if (!CalendarManager::GetInstance().IsConnected()) { + throw UnknownException("DB Connection failed."); + } + + // TODO implement calendar filter and sorting in native code. + int calendar_id = common::stol(FromJson(args, "calendarId")); + int callback_handle; //=NativePlugin::GetAsyncCallbackHandle(args); + + auto get = [calendar_id](const std::shared_ptr & response) + ->void { + LoggerD("Entered"); + try { + int error_code = 0; + CalendarRecordPtr calendar_ptr = + CalendarRecord::GetById(calendar_id, _calendar_book._uri); + int type = + CalendarRecord::GetInt(calendar_ptr.get(), _calendar_book.store_type); + calendar_query_h calendar_query = nullptr; + if (type == CALENDAR_BOOK_TYPE_EVENT) { + error_code = + calendar_query_create(_calendar_event._uri, &calendar_query); + } else { + error_code = + calendar_query_create(_calendar_todo._uri, &calendar_query); + } + if (CALENDAR_ERROR_NONE != error_code) { + throw UnknownException("calendar_query_create failed"); + } + + CalendarQueryPtr calendar_query_ptr(calendar_query, + CalendarRecord::QueryDeleter); + + calendar_list_h record_list = nullptr; + error_code = calendar_db_get_records_with_query(calendar_query, 0, 0, + &record_list); + if (CALENDAR_ERROR_NONE != error_code) { + throw UnknownException("calendar_db_get_records_with_query failed"); + } + CalendarListPtr record_list_ptr(record_list, CalendarRecord::ListDeleter); + + int record_count = 0; + error_code = calendar_list_get_count(record_list, &record_count); + if (CALENDAR_ERROR_NONE != error_code) { + throw UnknownException("calendar_list_get_count failed"); + } + error_code = calendar_list_first(record_list); + if (CALENDAR_ERROR_NONE != error_code) { + throw UnknownException("calendar_list_first failed"); + } + + picojson::value result{picojson::array{}}; + picojson::array& calendarItems = result.get(); + calendarItems.reserve(record_count); + for (int i = 0; i < record_count; ++i) { + calendar_record_h current_record = NULL; + error_code = + calendar_list_get_current_record_p(record_list, ¤t_record); + if (CALENDAR_ERROR_NONE != error_code) { + throw UnknownException("calendar_list_get_current_record_p failed"); + } + picojson::value record_obj = picojson::value(picojson::object()); + CalendarItem::ToJson(type, current_record, + &record_obj.get()); + calendarItems.push_back(record_obj); + + error_code = calendar_list_next(record_list); + if (CALENDAR_ERROR_NONE != error_code) { + LoggerE("calendar_list_next failed (%i/%i)", i, record_count); + break; + } + } + } + catch (...) {//const BasePlatformException& e) { + // LoggerE("error: %s: %s", e.name().c_str(), e.message().c_str()); + } + }; + + auto get_response = [callback_handle](const std::shared_ptr & + response)->void { + }; + + TaskQueue::GetInstance().Queue( + get, get_response, + std::shared_ptr(new picojson::value(picojson::object()))); + +// NativePlugin::ReportSuccess(out); +} + +void Calendar::RemoveBatch(const picojson::object& args, + picojson::object& out) { + LoggerD("enter"); + + if (!CalendarManager::GetInstance().IsConnected()) { + throw UnknownException("DB Connection failed."); + } + + auto& ids = FromJson(args, "ids"); + if (ids.empty()) { + throw InvalidValuesException("No items"); + } + + int type = CalendarRecord::TypeToInt(FromJson(args, "type")); + const char* view_uri = CalendarRecord::TypeToUri(type); + + auto batch_func = [=](const JsonValuePtr & response)->void { + picojson::object& response_obj = response->get(); + + try { + std::vector ids_to_remove; + int id; + for (int i = 0, size = ids.size(); i < size; i++) { + if (type == CALENDAR_BOOK_TYPE_EVENT) { + id = common::stol( + FromJson(ids.at(i).get(), "uid")); + } else { + id = common::stol(ids.at(i).get()); + } + + CalendarRecordPtr record_ptr = CalendarItem::GetById(id, view_uri); + + if (type == CALENDAR_BOOK_TYPE_EVENT) { + const std::string& rid = CalendarRecord::GetString( + record_ptr.get(), _calendar_event.recurrence_id); + if (rid.empty()) { + ids_to_remove.push_back(id); + } else { + // @todo handle recurrence_id + } + } else { + ids_to_remove.push_back(id); + } + } + + int ret; + if (ids_to_remove.size() > 0) { + ret = calendar_db_delete_records(view_uri, &ids_to_remove[0], + ids_to_remove.size()); + + if (CALENDAR_ERROR_NONE != ret) { + LoggerE("calendar_db_delete_records failed."); + if (CALENDAR_ERROR_INVALID_PARAMETER == ret) { + LoggerE("CALENDAR_ERROR_INVALID_PARAMETER"); + throw InvalidValuesException("Parameter is invalid"); + } else { + LoggerE("CALENDAR_ERROR_DB_FAILED"); + throw UnknownException("UnknownError"); + } + } + } + } + catch(...) { //(const BasePlatformException& e) { + } + }; + + int callback_handle;// = NativePlugin::GetAsyncCallbackHandle(args); + auto after_batch_func = [callback_handle](const JsonValuePtr& response) { + }; + + TaskQueue::GetInstance().Queue( + batch_func, after_batch_func, + JsonValuePtr(new picojson::value(picojson::object()))); + +} + +void Calendar::AddChangeListener(const picojson::object& args, picojson::object& out) { + LoggerD("enter"); + + if (!CalendarManager::GetInstance().IsConnected()) { + throw UnknownException("DB Connection failed."); + } + + const std::string& type = FromJson(args, "type"); + const std::string& listener_id = FromJson(args, "listenerId"); + + int ret; + if (listeners_registered_.find(type) == listeners_registered_.end()) { + const char* view_uri = CalendarRecord::TypeToUri(type); + ret = calendar_db_add_changed_cb(view_uri, ChangeCallback, nullptr); + if (CALENDAR_ERROR_NONE != ret) { + LoggerE("Add calendar change callback error for type %s", type.c_str()); + throw UnknownException("Add calendar change callback error"); + } + + ret = calendar_db_get_current_version(¤t_db_version_); + if (CALENDAR_ERROR_NONE != ret) { + current_db_version_ = 0; + LoggerE("Can't get calendar db version"); + throw UnknownException("Can't get calendar db version"); + } + + listeners_registered_[type] = listener_id; + } +} + +void Calendar::RemoveChangeListener(const picojson::object& args, + picojson::object& out) { + LoggerD("enter"); + + if (!CalendarManager::GetInstance().IsConnected()) { + throw UnknownException("DB Connection failed."); + } + + const std::string& type = FromJson(args, "type"); + + int ret; + if (listeners_registered_.find(type) != listeners_registered_.end()) { + const char* view_uri = CalendarRecord::TypeToUri(type); + ret = calendar_db_remove_changed_cb(view_uri, ChangeCallback, nullptr); + if (CALENDAR_ERROR_NONE != ret) { + LoggerE("Remove calendar change callback error for type %s", + type.c_str()); + throw UnknownException("Remove calendar change callback error"); + } + listeners_registered_.erase(type); + } + +} + +void Calendar::ChangeCallback(const char* view_uri, void*) { + LoggerD("enter"); + + calendar_list_h list = nullptr; + int ret, updated_version; + ret = calendar_db_get_changes_by_version(view_uri, CALENDAR_BOOK_FILTER_ALL, + current_db_version_, &list, + &updated_version); + if (CALENDAR_ERROR_NONE != ret) { + LoggerE("Can't get the changed item list"); + throw UnknownException("Can't get the changed item list"); + } + CalendarListPtr list_ptr = CalendarListPtr(list, CalendarRecord::ListDeleter); + + int count; + ret = calendar_list_get_count(list_ptr.get(), &count); + if (CALENDAR_ERROR_NONE != ret) { + LoggerE("Can't get the changed item count"); + throw UnknownException("Can't get the changed item count"); + } + LoggerD("Item count: %d", count); + + calendar_list_first(list_ptr.get()); + + int id, calendar_id, status; + calendar_record_h update_info = nullptr; + + int type = CalendarRecord::TypeToInt(view_uri); + + // prepare response object + picojson::value response = picojson::value(picojson::object()); + picojson::object& response_obj = response.get(); + + picojson::array& added = + response_obj.insert(std::make_pair("added", picojson::array())) + .first->second.get(); + picojson::array& updated = + response_obj.insert(std::make_pair("updated", picojson::array())) + .first->second.get(); + picojson::array& removed = + response_obj.insert(std::make_pair("removed", picojson::array())) + .first->second.get(); + + while (count-- > 0) { + ret = calendar_list_get_current_record_p(list, &update_info); + if (CALENDAR_ERROR_NONE != ret) { + LoggerE("Can't get current record"); + throw UnknownException("Can't get current record"); + } + + id = CalendarRecord::GetInt(update_info, _calendar_updated_info.id); + status = CalendarRecord::GetInt(update_info, + _calendar_updated_info.modified_status); + + if (status == CALENDAR_RECORD_MODIFIED_STATUS_DELETED) { + calendar_id = CalendarRecord::GetInt( + update_info, _calendar_updated_info.calendar_book_id); + + picojson::value removed_row = picojson::value(picojson::object()); + picojson::object& removed_obj = removed_row.get(); + removed_obj.insert(std::make_pair("id", picojson::value(std::to_string(id)))); + removed_obj.insert(std::make_pair( + "calendarId", picojson::value(std::to_string(calendar_id)))); + + removed.push_back(removed_row); + + calendar_list_next(list); + continue; + } + + try { + CalendarRecordPtr record_ptr = CalendarRecord::GetById(id, view_uri); + picojson::value record_obj = picojson::value(picojson::object()); + CalendarItem::ToJson(type, record_ptr.get(), + &record_obj.get()); + if (status == CALENDAR_RECORD_MODIFIED_STATUS_INSERTED) { + added.push_back(record_obj); + } else { + updated.push_back(record_obj); + } + } + catch(...) {//(BasePlatformException& ex) { + } + + calendar_list_next(list); + } + + if (added.empty()) { + response_obj.erase("added"); + } + if (updated.empty()) { + response_obj.erase("updated"); + } + if (removed.empty()) { + response_obj.erase("removed"); + } + + ret = calendar_db_get_current_version(&updated_version); + if (CALENDAR_ERROR_NONE != ret) { + LoggerE("Can't get new version"); + throw UnknownException("Can't get new version"); + } + current_db_version_ = updated_version; + +// wrt::common::NativeContext::GetInstance()->FireEvent( +// listeners_registered_[CalendarRecord::TypeToString(type)], +// response.serialize()); +} + +} // namespace calendar +} // namespace webapi diff --git a/src/calendar/calendar.cpp b/src/calendar/calendar.cpp deleted file mode 100644 index 9d9cfdb8..00000000 --- a/src/calendar/calendar.cpp +++ /dev/null @@ -1,750 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "calendar.h" - -#include - -#include "logger.h" -#include "converter.h" -#include "native-plugin.h" -#include "task-queue.h" -#include "calendar-manager.h" -#include "calendar-privilege.h" -#include "calendar-item.h" - -namespace webapi { -namespace calendar { - -using namespace webapi::common; - -int Calendar::current_db_version_ = 0; -std::map Calendar::listeners_registered_; - -Calendar& Calendar::GetInstance() { - static Calendar instance; - return instance; -} - -Calendar::~Calendar() { - int ret; - - if (listeners_registered_.find("EVENT") != listeners_registered_.end()) { - ret = calendar_db_remove_changed_cb(_calendar_event._uri, ChangeCallback, - nullptr); - if (CALENDAR_ERROR_NONE != ret) { - LoggerE("Remove calendar event change callback error"); - } - } - - if (listeners_registered_.find("TASK") != listeners_registered_.end()) { - ret = calendar_db_remove_changed_cb(_calendar_todo._uri, ChangeCallback, - nullptr); - if (CALENDAR_ERROR_NONE != ret) { - LoggerE("Remove calendar todo change callback error"); - } - } -} - -void Calendar::Get(const json::Object& args, json::Object& out) { - LoggerD("enter"); - - NativePlugin::CheckAccess(Privilege::kCalendarRead); - - if (!CalendarManager::GetInstance().IsConnected()) { - throw UnknownException("DB Connection failed."); - } - - int calendar_id = common::stol(FromJson(args, "calendarId")); - CalendarRecordPtr calendar_ptr = - CalendarRecord::GetById(calendar_id, _calendar_book._uri); - int type = - CalendarRecord::GetInt(calendar_ptr.get(), _calendar_book.store_type); - - int id; - if (type == CALENDAR_BOOK_TYPE_EVENT) { - id = common::stol(FromJson(args, "id", "uid")); - } else { - id = common::stol(FromJson(args, "id")); - } - - CalendarRecordPtr record_ptr = - CalendarRecord::GetById(id, CalendarRecord::TypeToUri(type)); - json::Value record_obj = json::Value(json::Object()); - CalendarItem::ToJson(type, record_ptr.get(), &record_obj.get()); - - NativePlugin::ReportSuccess(record_obj, out); -} - -void Calendar::Add(const json::Object& args, json::Object& out) { - LoggerD("enter"); - - NativePlugin::CheckAccess(Privilege::kCalendarWrite); - - if (!CalendarManager::GetInstance().IsConnected()) { - throw UnknownException("DB Connection failed."); - } - - const auto& item = FromJson(args, "item"); - int type = CalendarRecord::TypeToInt(FromJson(args, "type")); - - CalendarRecordPtr item_ptr = CalendarItem::Create(type); - CalendarItem::FromJson(type, item_ptr.get(), item); - int record_id = CalendarRecord::Insert(item_ptr.get()); - - json::Value result = json::Value(json::Object()); - json::Object& result_obj = result.get(); - result_obj.insert(std::make_pair("uid", std::to_string(record_id))); - - if (type == CALENDAR_BOOK_TYPE_EVENT) { - std::string rid = CalendarRecord::GetString(item_ptr.get(), - _calendar_event.recurrence_id); - if (!rid.empty()) { - result_obj["rid"] = json::Value(rid); - } else { - result_obj["rid"] = json::Value(); - } - } - - NativePlugin::ReportSuccess(result, out); -} - -void Calendar::AddBatch(const common::json::Object& args, - common::json::Object& out) { - LoggerD("enter"); - - NativePlugin::CheckAccess(Privilege::kCalendarWrite); - - if (!CalendarManager::GetInstance().IsConnected()) { - throw UnknownException("DB Connection failed."); - } - - auto& items = FromJson(args, "items"); - if (items.empty()) { - throw InvalidValuesException("No items"); - } - - int type = CalendarRecord::TypeToInt(FromJson(args, "type")); - const char* view_uri = CalendarRecord::TypeToUri(type); - - auto batch_func = [=](const JsonValuePtr & response)->void { - json::Object& response_obj = response->get(); - - try { - calendar_list_h list = NULL; - if (CALENDAR_ERROR_NONE != calendar_list_create(&list)) { - LoggerE("Could not create list for batch operation"); - throw UnknownException("Could not create list for batch operation"); - } - CalendarListPtr list_ptr = - CalendarListPtr(list, CalendarRecord::ListDeleter); - - int ret; - calendar_record_h record; - - for (auto& item : items) { - ret = calendar_record_create(view_uri, &record); - if (CALENDAR_ERROR_NONE != ret) { - LoggerW("Can't create platform record %d", ret); - throw UnknownException("Can't create platform record"); - } - CalendarItem::FromJson(type, record, item.get()); - - if (CALENDAR_ERROR_NONE != calendar_list_add(list_ptr.get(), record)) { - LoggerE("Could not add record to list events"); - throw InvalidValuesException("Could not add record to list"); - } - } - - int* ids; - int count; - ret = calendar_db_insert_records(list_ptr.get(), &ids, &count); - if (CALENDAR_ERROR_NONE != ret) { - LoggerE("calendar_db_insert_records failed."); - if (CALENDAR_ERROR_INVALID_PARAMETER == ret) { - LoggerE("CALENDAR_ERROR_INVALID_PARAMETER."); - throw InvalidValuesException("Parameter is invalid"); - } else { - LoggerE("CALENDAR_ERROR_DB_FAILED"); - throw UnknownException("CALENDAR_ERROR_DB_FAILED occurred"); - } - } - - json::Value result = json::Value(json::Array()); - json::Array& array = result.get(); - - for (int i = 0; i < count; i++) { - json::Value id = json::Value(json::Object()); - json::Object& id_obj = id.get(); - - id_obj.insert(std::make_pair("uid", std::to_string(ids[i]))); - - if (type == CALENDAR_BOOK_TYPE_EVENT) { - id_obj.insert(std::make_pair("rid", json::Value())); - } - - array.push_back(id); - } - free(ids); - - NativePlugin::ReportSuccess(result, response_obj); - } - catch (const BasePlatformException& e) { - NativePlugin::ReportError(e, response_obj); - } - }; - - int callback_handle = NativePlugin::GetAsyncCallbackHandle(args); - auto after_batch_func = [callback_handle](const JsonValuePtr& response) { - wrt::common::NativeContext::GetInstance()->InvokeCallback( - callback_handle, response->serialize()); - }; - - TaskQueue::GetInstance().Queue( - batch_func, after_batch_func, - JsonValuePtr(new json::Value(json::Object()))); - - NativePlugin::ReportSuccess(out); -} - -void Calendar::Update(const common::json::Object& args, - common::json::Object& /*out*/) { - LoggerD("enter"); - - NativePlugin::CheckAccess(Privilege::kCalendarWrite); - - if (!CalendarManager::GetInstance().IsConnected()) { - throw UnknownException("DB Connection failed."); - } - - const auto& item = FromJson(args, "item"); - int type = CalendarRecord::TypeToInt(FromJson(args, "type")); - - bool update_all = true; - - int id; - if (type == CALENDAR_BOOK_TYPE_EVENT) { - id = common::stol(FromJson(item, "id", "uid")); - if (!IsNull(args, "updateAllInstances")) { - update_all = FromJson(args, "updateAllInstances"); - } - } else { - id = common::stol(FromJson(item, "id")); - } - - CalendarRecordPtr record_ptr = - CalendarRecord::GetById(id, CalendarRecord::TypeToUri(type)); - CalendarItem::FromJson(type, record_ptr.get(), item); - - if (type == CALENDAR_BOOK_TYPE_TODO || update_all || - common::IsNull(item, "recurrenceRule")) { - if (CALENDAR_ERROR_NONE != calendar_db_update_record(record_ptr.get())) { - LoggerE("Can't update calendar item"); - throw UnknownException("Can't update calendar item"); - } - } else { - // first update the parent event - std::string exdate = CalendarItem::ExceptionsFromJson( - common::FromJson(item, "recurrenceRule", "exceptions")); - if (!common::IsNull(common::FromJson(item, "id"), "rid")) { - exdate.append(common::FromJson(item, "id", "rid")); - } - CalendarRecord::SetString(record_ptr.get(), _calendar_event.exdate, exdate); - - // don't set the recurrence id for the parent event - CalendarRecord::SetString(record_ptr.get(), _calendar_event.recurrence_id, - ""); - - if (CALENDAR_ERROR_NONE != calendar_db_update_record(record_ptr.get())) { - LoggerE("Can't update calendar item"); - throw UnknownException("Can't update calendar item"); - } - - // now add the detached child event - CalendarRecordPtr item_ptr = CalendarItem::Create(type); - CalendarItem::FromJson(type, item_ptr.get(), item); - CalendarRecord::Insert(item_ptr.get()); - } -} - -void Calendar::UpdateBatch(const common::json::Object& args, - common::json::Object& out) { - LoggerD("enter"); - - NativePlugin::CheckAccess(Privilege::kCalendarWrite); - - if (!CalendarManager::GetInstance().IsConnected()) { - throw UnknownException("DB Connection failed."); - } - - auto& items = FromJson(args, "items"); - if (items.empty()) { - throw InvalidValuesException("No items"); - } - - bool update_all = true; - if (!IsNull(args, "updateAllInstances")) { - update_all = FromJson(args, "updateAllInstances"); - } - - int type = CalendarRecord::TypeToInt(FromJson(args, "type")); - const char* view_uri = CalendarRecord::TypeToUri(type); - - auto batch_func = [=](const JsonValuePtr & response)->void { - json::Object& response_obj = response->get(); - - try { - calendar_list_h list = NULL; - if (CALENDAR_ERROR_NONE != calendar_list_create(&list)) { - LoggerE("Could not create list for batch operation"); - throw UnknownException("Could not create list for batch operation"); - } - CalendarListPtr list_ptr = - CalendarListPtr(list, CalendarRecord::ListDeleter); - - int ret, id; - calendar_record_h record; - - for (auto& item : items) { - const json::Object& item_obj = item.get(); - if (type == CALENDAR_BOOK_TYPE_EVENT) { - id = common::stol(FromJson(item_obj, "id", "uid")); - } else { - id = common::stol(FromJson(item_obj, "id")); - } - - ret = calendar_db_get_record(view_uri, id, &record); - if (CALENDAR_ERROR_NONE != ret) { - LoggerW("Can't get platform record %d", ret); - throw UnknownException("Can't get platform record"); - } - CalendarItem::FromJson(type, record, item.get()); - - if (CALENDAR_ERROR_NONE != calendar_list_add(list_ptr.get(), record)) { - LoggerE("Could not add record to list events"); - throw InvalidValuesException("Could not add record to list"); - } - } - - if (type == CALENDAR_BOOK_TYPE_TODO || update_all) { - if (CALENDAR_ERROR_NONE != calendar_db_update_records(list_ptr.get())) { - LoggerE("Can't update calendar items"); - throw UnknownException("Can't update calendar items"); - } - } else { - // @todo update the exdate for a recurring parent event and add a new - // child event - } - - NativePlugin::ReportSuccess(response_obj); - } - catch (const BasePlatformException& e) { - NativePlugin::ReportError(e, response_obj); - } - }; - - int callback_handle = NativePlugin::GetAsyncCallbackHandle(args); - auto after_batch_func = [callback_handle](const JsonValuePtr& response) { - wrt::common::NativeContext::GetInstance()->InvokeCallback( - callback_handle, response->serialize()); - }; - - TaskQueue::GetInstance().Queue( - batch_func, after_batch_func, - JsonValuePtr(new json::Value(json::Object()))); - - NativePlugin::ReportSuccess(out); -} - -void Calendar::Remove(const common::json::Object& args, - common::json::Object& out) { - LoggerD("enter"); - - NativePlugin::CheckAccess(Privilege::kCalendarWrite); - - if (!CalendarManager::GetInstance().IsConnected()) { - throw UnknownException("DB Connection failed."); - } - - int type = CalendarRecord::TypeToInt(FromJson(args, "type")); - - int id; - if (type == CALENDAR_BOOK_TYPE_EVENT) { - id = common::stol(FromJson(args, "id", "uid")); - } else { - id = common::stol(FromJson(args, "id")); - } - - CalendarItem::Remove(type, id); - - NativePlugin::ReportSuccess(out); -} - -void Calendar::Find(const json::Object& args, json::Object& out) { - LoggerD("enter"); - - NativePlugin::CheckAccess(Privilege::kCalendarWrite); - - if (!CalendarManager::GetInstance().IsConnected()) { - throw UnknownException("DB Connection failed."); - } - - // TODO implement calendar filter and sorting in native code. - int calendar_id = common::stol(FromJson(args, "calendarId")); - int callback_handle = NativePlugin::GetAsyncCallbackHandle(args); - - auto get = [calendar_id](const std::shared_ptr & response) - ->void { - LoggerD("Entered"); - try { - int error_code = 0; - CalendarRecordPtr calendar_ptr = - CalendarRecord::GetById(calendar_id, _calendar_book._uri); - int type = - CalendarRecord::GetInt(calendar_ptr.get(), _calendar_book.store_type); - calendar_query_h calendar_query = nullptr; - if (type == CALENDAR_BOOK_TYPE_EVENT) { - error_code = - calendar_query_create(_calendar_event._uri, &calendar_query); - } else { - error_code = - calendar_query_create(_calendar_todo._uri, &calendar_query); - } - if (CALENDAR_ERROR_NONE != error_code) { - throw UnknownException("calendar_query_create failed"); - } - - CalendarQueryPtr calendar_query_ptr(calendar_query, - CalendarRecord::QueryDeleter); - - calendar_list_h record_list = nullptr; - error_code = calendar_db_get_records_with_query(calendar_query, 0, 0, - &record_list); - if (CALENDAR_ERROR_NONE != error_code) { - throw UnknownException("calendar_db_get_records_with_query failed"); - } - CalendarListPtr record_list_ptr(record_list, CalendarRecord::ListDeleter); - - int record_count = 0; - error_code = calendar_list_get_count(record_list, &record_count); - if (CALENDAR_ERROR_NONE != error_code) { - throw UnknownException("calendar_list_get_count failed"); - } - error_code = calendar_list_first(record_list); - if (CALENDAR_ERROR_NONE != error_code) { - throw UnknownException("calendar_list_first failed"); - } - - json::Value result{json::Array{}}; - json::Array& calendarItems = result.get(); - calendarItems.reserve(record_count); - for (int i = 0; i < record_count; ++i) { - calendar_record_h current_record = NULL; - error_code = - calendar_list_get_current_record_p(record_list, ¤t_record); - if (CALENDAR_ERROR_NONE != error_code) { - throw UnknownException("calendar_list_get_current_record_p failed"); - } - json::Value record_obj = json::Value(json::Object()); - CalendarItem::ToJson(type, current_record, - &record_obj.get()); - calendarItems.push_back(record_obj); - - error_code = calendar_list_next(record_list); - if (CALENDAR_ERROR_NONE != error_code) { - LoggerE("calendar_list_next failed (%i/%i)", i, record_count); - break; - } - } - - NativePlugin::ReportSuccess(result, response->get()); - } - catch (const BasePlatformException& e) { - LoggerE("error: %s: %s", e.name().c_str(), e.message().c_str()); - NativePlugin::ReportError(e, response->get()); - } - }; - - auto get_response = [callback_handle](const std::shared_ptr & - response)->void { - wrt::common::NativeContext::GetInstance()->InvokeCallback( - callback_handle, response->serialize()); - }; - - TaskQueue::GetInstance().Queue( - get, get_response, - std::shared_ptr(new json::Value(json::Object()))); - - NativePlugin::ReportSuccess(out); -} - -void Calendar::RemoveBatch(const common::json::Object& args, - common::json::Object& out) { - LoggerD("enter"); - - NativePlugin::CheckAccess(Privilege::kCalendarWrite); - - if (!CalendarManager::GetInstance().IsConnected()) { - throw UnknownException("DB Connection failed."); - } - - auto& ids = FromJson(args, "ids"); - if (ids.empty()) { - throw InvalidValuesException("No items"); - } - - int type = CalendarRecord::TypeToInt(FromJson(args, "type")); - const char* view_uri = CalendarRecord::TypeToUri(type); - - auto batch_func = [=](const JsonValuePtr & response)->void { - json::Object& response_obj = response->get(); - - try { - std::vector ids_to_remove; - int id; - for (int i = 0, size = ids.size(); i < size; i++) { - if (type == CALENDAR_BOOK_TYPE_EVENT) { - id = common::stol( - FromJson(ids.at(i).get(), "uid")); - } else { - id = common::stol(ids.at(i).get()); - } - - CalendarRecordPtr record_ptr = CalendarItem::GetById(id, view_uri); - - if (type == CALENDAR_BOOK_TYPE_EVENT) { - const std::string& rid = CalendarRecord::GetString( - record_ptr.get(), _calendar_event.recurrence_id); - if (rid.empty()) { - ids_to_remove.push_back(id); - } else { - // @todo handle recurrence_id - } - } else { - ids_to_remove.push_back(id); - } - } - - int ret; - if (ids_to_remove.size() > 0) { - ret = calendar_db_delete_records(view_uri, &ids_to_remove[0], - ids_to_remove.size()); - - if (CALENDAR_ERROR_NONE != ret) { - LoggerE("calendar_db_delete_records failed."); - if (CALENDAR_ERROR_INVALID_PARAMETER == ret) { - LoggerE("CALENDAR_ERROR_INVALID_PARAMETER"); - throw InvalidValuesException("Parameter is invalid"); - } else { - LoggerE("CALENDAR_ERROR_DB_FAILED"); - throw UnknownException("UnknownError"); - } - } - } - - NativePlugin::ReportSuccess(response_obj); - } - catch (const BasePlatformException& e) { - NativePlugin::ReportError(e, response_obj); - } - }; - - int callback_handle = NativePlugin::GetAsyncCallbackHandle(args); - auto after_batch_func = [callback_handle](const JsonValuePtr& response) { - wrt::common::NativeContext::GetInstance()->InvokeCallback( - callback_handle, response->serialize()); - }; - - TaskQueue::GetInstance().Queue( - batch_func, after_batch_func, - JsonValuePtr(new json::Value(json::Object()))); - - NativePlugin::ReportSuccess(out); -} - -void Calendar::AddChangeListener(const json::Object& args, json::Object& out) { - LoggerD("enter"); - - NativePlugin::CheckAccess(Privilege::kCalendarRead); - - if (!CalendarManager::GetInstance().IsConnected()) { - throw UnknownException("DB Connection failed."); - } - - const std::string& type = FromJson(args, "type"); - const std::string& listener_id = FromJson(args, "listenerId"); - - int ret; - if (listeners_registered_.find(type) == listeners_registered_.end()) { - const char* view_uri = CalendarRecord::TypeToUri(type); - ret = calendar_db_add_changed_cb(view_uri, ChangeCallback, nullptr); - if (CALENDAR_ERROR_NONE != ret) { - LoggerE("Add calendar change callback error for type %s", type.c_str()); - throw UnknownException("Add calendar change callback error"); - } - - ret = calendar_db_get_current_version(¤t_db_version_); - if (CALENDAR_ERROR_NONE != ret) { - current_db_version_ = 0; - LoggerE("Can't get calendar db version"); - throw UnknownException("Can't get calendar db version"); - } - - listeners_registered_[type] = listener_id; - } - - NativePlugin::ReportSuccess(out); -} - -void Calendar::RemoveChangeListener(const json::Object& args, - json::Object& out) { - LoggerD("enter"); - - NativePlugin::CheckAccess(Privilege::kCalendarRead); - - if (!CalendarManager::GetInstance().IsConnected()) { - throw UnknownException("DB Connection failed."); - } - - const std::string& type = FromJson(args, "type"); - - int ret; - if (listeners_registered_.find(type) != listeners_registered_.end()) { - const char* view_uri = CalendarRecord::TypeToUri(type); - ret = calendar_db_remove_changed_cb(view_uri, ChangeCallback, nullptr); - if (CALENDAR_ERROR_NONE != ret) { - LoggerE("Remove calendar change callback error for type %s", - type.c_str()); - throw UnknownException("Remove calendar change callback error"); - } - listeners_registered_.erase(type); - } - - NativePlugin::ReportSuccess(out); -} - -void Calendar::ChangeCallback(const char* view_uri, void*) { - LoggerD("enter"); - - calendar_list_h list = nullptr; - int ret, updated_version; - ret = calendar_db_get_changes_by_version(view_uri, CALENDAR_BOOK_FILTER_ALL, - current_db_version_, &list, - &updated_version); - if (CALENDAR_ERROR_NONE != ret) { - LoggerE("Can't get the changed item list"); - throw UnknownException("Can't get the changed item list"); - } - CalendarListPtr list_ptr = CalendarListPtr(list, CalendarRecord::ListDeleter); - - int count; - ret = calendar_list_get_count(list_ptr.get(), &count); - if (CALENDAR_ERROR_NONE != ret) { - LoggerE("Can't get the changed item count"); - throw UnknownException("Can't get the changed item count"); - } - LoggerD("Item count: %d", count); - - calendar_list_first(list_ptr.get()); - - int id, calendar_id, status; - calendar_record_h update_info = nullptr; - - int type = CalendarRecord::TypeToInt(view_uri); - - // prepare response object - json::Value response = json::Value(json::Object()); - json::Object& response_obj = response.get(); - - json::Array& added = - response_obj.insert(std::make_pair("added", json::Array())) - .first->second.get(); - json::Array& updated = - response_obj.insert(std::make_pair("updated", json::Array())) - .first->second.get(); - json::Array& removed = - response_obj.insert(std::make_pair("removed", json::Array())) - .first->second.get(); - - while (count-- > 0) { - ret = calendar_list_get_current_record_p(list, &update_info); - if (CALENDAR_ERROR_NONE != ret) { - LoggerE("Can't get current record"); - throw UnknownException("Can't get current record"); - } - - id = CalendarRecord::GetInt(update_info, _calendar_updated_info.id); - status = CalendarRecord::GetInt(update_info, - _calendar_updated_info.modified_status); - - if (status == CALENDAR_RECORD_MODIFIED_STATUS_DELETED) { - calendar_id = CalendarRecord::GetInt( - update_info, _calendar_updated_info.calendar_book_id); - - json::Value removed_row = json::Value(json::Object()); - json::Object& removed_obj = removed_row.get(); - removed_obj.insert(std::make_pair("id", json::Value(std::to_string(id)))); - removed_obj.insert(std::make_pair( - "calendarId", json::Value(std::to_string(calendar_id)))); - - removed.push_back(removed_row); - - calendar_list_next(list); - continue; - } - - try { - CalendarRecordPtr record_ptr = CalendarRecord::GetById(id, view_uri); - json::Value record_obj = json::Value(json::Object()); - CalendarItem::ToJson(type, record_ptr.get(), - &record_obj.get()); - if (status == CALENDAR_RECORD_MODIFIED_STATUS_INSERTED) { - added.push_back(record_obj); - } else { - updated.push_back(record_obj); - } - } - catch (BasePlatformException& ex) { - LoggerD("Can't get changed calendar item: %s", ex.message().c_str()); - } - - calendar_list_next(list); - } - - if (added.empty()) { - response_obj.erase("added"); - } - if (updated.empty()) { - response_obj.erase("updated"); - } - if (removed.empty()) { - response_obj.erase("removed"); - } - - ret = calendar_db_get_current_version(&updated_version); - if (CALENDAR_ERROR_NONE != ret) { - LoggerE("Can't get new version"); - throw UnknownException("Can't get new version"); - } - current_db_version_ = updated_version; - - wrt::common::NativeContext::GetInstance()->FireEvent( - listeners_registered_[CalendarRecord::TypeToString(type)], - response.serialize()); -} - -} // namespace calendar -} // namespace webapi diff --git a/src/calendar/calendar.gyp b/src/calendar/calendar.gyp index 74556383..8f08efd3 100644 --- a/src/calendar/calendar.gyp +++ b/src/calendar/calendar.gyp @@ -11,15 +11,22 @@ 'calendar_extension.cc', 'calendar_extension.h', 'calendar_instance.cc', - 'calendar_instance.h' + 'calendar_instance.h', + 'calendar.cc', + 'calendar.h', + 'calendar_item.cc', + 'calendar_item.h', + 'calendar_manager.cc', + 'calendar_manager.h', + 'calendar_privilege.h', + 'calendar_record.cc', + 'calendar_record.h' ], 'conditions': [ ['tizen == 1', { 'variables': { 'packages': [ - 'glib-2.0', 'calendar-service2', - 'vconf', ] }, }], diff --git a/src/calendar/calendar.h b/src/calendar/calendar.h index f5ed009f..bcd713d4 100644 --- a/src/calendar/calendar.h +++ b/src/calendar/calendar.h @@ -14,17 +14,22 @@ * limitations under the License. */ -#ifndef WEBAPI_PLUGINS_CALENDAR_H_ -#define WEBAPI_PLUGINS_CALENDAR_H_ +#ifndef CALENDAR_CALENDAR_H_ +#define CALENDAR_CALENDAR_H_ #include -#include "json-parser.h" +#include "common/picojson.h" -namespace webapi { +namespace extension { namespace calendar { -typedef std::shared_ptr JsonValuePtr; +typedef picojson::value JsonValue; +typedef picojson::object JsonObject; +typedef picojson::array JsonArray; +typedef std::string JsonString; + +typedef std::shared_ptr JsonValuePtr; class Calendar { public: @@ -40,7 +45,7 @@ class Calendar { * {status: 'success', item: {}} * @endcode */ - void Get(const common::json::Object& args, common::json::Object& out); + void Get(const JsonObject& args, JsonObject& out); /** * Signature: @code void add(item); @endcode @@ -52,7 +57,7 @@ class Calendar { * {status: 'success'} * @endcode */ - void Add(const common::json::Object& args, common::json::Object& out); + void Add(const JsonObject& args, JsonObject& out); /** * Signature: @code void addBatch(items, successCallback, errorCallback); @@ -66,7 +71,7 @@ class Calendar { * {status: 'success', result: items} * @endcode */ - void AddBatch(const common::json::Object& args, common::json::Object& out); + void AddBatch(const JsonObject& args, JsonObject& out); /** * Signature: @code void update(item, updateAllInstances); @endcode @@ -79,7 +84,7 @@ class Calendar { * {status: 'success'} * @endcode */ - void Update(const common::json::Object& args, common::json::Object& out); + void Update(const JsonObject& args, JsonObject& out); /** * Signature: @code void updateBatch(items, successCallback, errorCallback, @@ -94,7 +99,7 @@ class Calendar { * {status: 'success'} * @endcode */ - void UpdateBatch(const common::json::Object& args, common::json::Object& out); + void UpdateBatch(const JsonObject& args, JsonObject& out); /** * Signature: @code void remove(item); @endcode @@ -106,7 +111,7 @@ class Calendar { * {status: 'success'} * @endcode */ - void Remove(const common::json::Object& args, common::json::Object& out); + void Remove(const JsonObject& args, JsonObject& out); /** * Signature: @code void removeBatch(items, successCallback, errorCallback); @@ -120,7 +125,7 @@ class Calendar { * {status: 'success'} * @endcode */ - void RemoveBatch(const common::json::Object& args, common::json::Object& out); + void RemoveBatch(const JsonObject& args, JsonObject& out); /** * Signature: @code void find(successCallback, errorCallback, filter, @@ -139,7 +144,7 @@ class Calendar { * {status: 'success', result: {calendarItemsArray}} * @endcode */ - void Find(const common::json::Object& args, common::json::Object& out); + void Find(const JsonObject& args, JsonObject& out); /** * Signature: @code void addChangeListener(successCallback); @endcode @@ -152,8 +157,8 @@ class Calendar { * {status: 'success'} * @endcode */ - void AddChangeListener(const common::json::Object& args, - common::json::Object& out); + void AddChangeListener(const JsonObject& args, + JsonObject& out); /** * Signature: @code void removeChangeListener(); @endcode @@ -166,8 +171,8 @@ class Calendar { * {status: 'success'} * @endcode */ - void RemoveChangeListener(const common::json::Object& args, - common::json::Object& out); + void RemoveChangeListener(const JsonObject& args, + JsonObject& out); static Calendar& GetInstance(); @@ -180,4 +185,4 @@ class Calendar { } // namespace calendar } // namespace webapi -#endif // WEBAPI_PLUGINS_CALENDAR_H_ +#endif // CALENDAR_CALENDAR_H_ diff --git a/src/calendar/calendar_extension.cc b/src/calendar/calendar_extension.cc index ab780816..2eec3847 100644 --- a/src/calendar/calendar_extension.cc +++ b/src/calendar/calendar_extension.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "calendar/calendar_extension.h" - #include "calendar/calendar_instance.h" // This will be generated from calendar_api.js @@ -33,5 +32,5 @@ CalendarExtension::CalendarExtension() { CalendarExtension::~CalendarExtension() {} common::Instance* CalendarExtension::CreateInstance() { -// return new CalendarInstance; + return new extension::calendar::CalendarInstance; } diff --git a/src/calendar/calendar_instance.cc b/src/calendar/calendar_instance.cc index f331da29..9ed1f415 100644 --- a/src/calendar/calendar_instance.cc +++ b/src/calendar/calendar_instance.cc @@ -4,22 +4,153 @@ #include "calendar/calendar_instance.h" -#include +#include "common/converter.h" -#include "common/picojson.h" -#include "common/logger.h" -#include "common/platform_exception.h" +#include "calendar/calendar_manager.h" +#include "calendar/calendar.h" namespace extension { namespace calendar { using namespace common; +using namespace extension::calendar; CalendarInstance::CalendarInstance() { + using namespace std::placeholders; +#define REGISTER_SYNC(c, x) \ + RegisterSyncHandler(c, std::bind(&CalendarInstance::x, this, _1, _2)); + + // Calendar + REGISTER_SYNC("Calendar_get", Calendar_get); + REGISTER_SYNC("Calendar_add", Calendar_add); + REGISTER_SYNC("Calendar_addBatch", Calendar_addBatch); + REGISTER_SYNC("Calendar_update", Calendar_update); + REGISTER_SYNC("Calendar_updateBatch", Calendar_updateBatch); + REGISTER_SYNC("Calendar_remove", Calendar_remove); + REGISTER_SYNC("Calendar_removeBatch", Calendar_removeBatch); + REGISTER_SYNC("Calendar_find", Calendar_find); + REGISTER_SYNC("Calendar_addChangeListener", Calendar_addChangeListener); + REGISTER_SYNC("Calendar_removeChangeListener", Calendar_removeChangeListener); + + // Calendar Manager + REGISTER_SYNC("CalendarManager_addCalendar", CalendarManager_addCalendar); + REGISTER_SYNC("CalendarManager_getCalendar", CalendarManager_getCalendar); + REGISTER_SYNC("CalendarManager_getCalendars", CalendarManager_getCalendars); + REGISTER_SYNC("CalendarManager_removeCalendar", + CalendarManager_removeCalendar); + +#undef REGISTER_SYNC +} + +CalendarInstance::~CalendarInstance() {} + +void CalendarInstance::Calendar_get(const JsonValue& args, JsonObject& out) { + JsonValue val{JsonObject{}}; + Calendar::GetInstance().Get(common::JsonCast(args), + val.get()); + ReportSuccess(val, out); +} + +void CalendarInstance::Calendar_add(const JsonValue& args, JsonObject& out) { + JsonValue val{JsonObject{}}; + Calendar::GetInstance().Add(common::JsonCast(args), + val.get()); + ReportSuccess(val, out); +} + +void CalendarInstance::Calendar_addBatch(const JsonValue& args, + JsonObject& out) { + JsonValue val{JsonObject{}}; + Calendar::GetInstance().AddBatch(common::JsonCast(args), + val.get()); + ReportSuccess(val, out); +} + +void CalendarInstance::Calendar_update(const JsonValue& args, JsonObject& out) { + JsonValue val{JsonObject{}}; + Calendar::GetInstance().Update(common::JsonCast(args), + val.get()); + ReportSuccess(val, out); +} + +void CalendarInstance::Calendar_updateBatch(const JsonValue& args, + JsonObject& out) { + JsonValue val{JsonObject{}}; + Calendar::GetInstance().UpdateBatch(common::JsonCast(args), + val.get()); + ReportSuccess(val, out); +} + +void CalendarInstance::Calendar_remove(const JsonValue& args, JsonObject& out) { + JsonValue val{JsonObject{}}; + Calendar::GetInstance().Remove(common::JsonCast(args), + val.get()); + ReportSuccess(out); +} + +void CalendarInstance::Calendar_removeBatch(const JsonValue& args, + JsonObject& out) { + JsonValue val{JsonObject{}}; + Calendar::GetInstance().RemoveBatch(common::JsonCast(args), + val.get()); + ReportSuccess(out); +} + +void CalendarInstance::Calendar_find(const JsonValue& args, JsonObject& out) { + JsonValue val{JsonObject{}}; + Calendar::GetInstance().Find(common::JsonCast(args), + val.get()); + ReportSuccess(out); +} + +void CalendarInstance::Calendar_addChangeListener(const JsonValue& args, + JsonObject& out) { + JsonValue val{JsonObject{}}; + Calendar::GetInstance().AddChangeListener(common::JsonCast(args), + val.get()); + ReportSuccess(out); +} + +void CalendarInstance::Calendar_removeChangeListener(const JsonValue& args, + JsonObject& out) { + JsonValue val{JsonObject{}}; + Calendar::GetInstance().RemoveChangeListener( + common::JsonCast(args), val.get()); + ReportSuccess(out); +} + +// CalendarManager +void CalendarInstance::CalendarManager_addCalendar(const JsonValue& args, + JsonObject& out) { + JsonValue val{JsonObject{}}; + CalendarManager::GetInstance().AddCalendar(common::JsonCast(args), + val.get()); + ReportSuccess(val, out); +} + +void CalendarInstance::CalendarManager_getCalendar(const JsonValue& args, + JsonObject& out) { + JsonValue val{JsonObject{}}; + CalendarManager::GetInstance().GetCalendar(common::JsonCast(args), + val.get()); + ReportSuccess(val, out); +} + +void CalendarInstance::CalendarManager_getCalendars(const JsonValue& args, + JsonObject& out) { + JsonValue val{JsonObject{}}; + CalendarManager::GetInstance().GetCalendars( + common::JsonCast(args), val.get()); + ReportSuccess(val, out); } -CalendarInstance::~CalendarInstance() { +void CalendarInstance::CalendarManager_removeCalendar(const JsonValue& args, + JsonObject& out) { + JsonValue val{JsonObject{}}; + CalendarManager::GetInstance().RemoveCalendar( + common::JsonCast(args), val.get()); + ReportSuccess(val, out); } -} // namespace calendar -} // namespace extension +} // namespace calendar +} // namespace extension diff --git a/src/calendar/calendar_instance.h b/src/calendar/calendar_instance.h index e7734171..93ab8ade 100644 --- a/src/calendar/calendar_instance.h +++ b/src/calendar/calendar_instance.h @@ -6,14 +6,33 @@ #define CALENDAR_CALENDAR_INSTANCE_H_ #include "common/extension.h" +#include "common/picojson.h" namespace extension { namespace calendar { -class CalendarInstance { +class CalendarInstance : public common::ParsedInstance { public: CalendarInstance(); virtual ~CalendarInstance(); + + private: + void Calendar_get(const picojson::value& args, picojson::object& out); + void Calendar_add(const picojson::value& args, picojson::object& out); + void Calendar_addBatch(const picojson::value& args, picojson::object& out); + void Calendar_update(const picojson::value& args, picojson::object& out); + void Calendar_updateBatch(const picojson::value& args, picojson::object& out); + void Calendar_remove(const picojson::value& args, picojson::object& out); + void Calendar_removeBatch(const picojson::value& args, picojson::object& out); + void Calendar_find(const picojson::value& args, picojson::object& out); + void Calendar_addChangeListener(const picojson::value& args, picojson::object& out); + void Calendar_removeChangeListener(const picojson::value& args, picojson::object& out); + + void CalendarManager_addCalendar(const picojson::value& args, picojson::object& out); + void CalendarManager_getCalendar(const picojson::value& args, picojson::object& out); + void CalendarManager_getCalendars(const picojson::value& args, picojson::object& out); + void CalendarManager_removeCalendar(const picojson::value& args, picojson::object& out); + }; } // namespace calendar diff --git a/src/calendar/calendar_item.cc b/src/calendar/calendar_item.cc new file mode 100644 index 00000000..df9dd355 --- /dev/null +++ b/src/calendar/calendar_item.cc @@ -0,0 +1,1162 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "calendar_item.h" + +#include +#include + +#include "common/logger.h" +#include "common/converter.h" +using namespace common; +namespace extension { +namespace calendar { + +namespace { +const std::string kTimeDurationUnitMilliseconds = "MSECS"; +const std::string kTimeDurationUnitSeconds = "SECS"; +const std::string kTimeDurationUnitMinutes = "MINS"; +const std::string kTimeDurationUnitHours = "HOURS"; +const std::string kTimeDurationUnitDays = "DAYS"; + +const std::string kDefaultEnumKey = "_DEFAULT"; +const std::string kItemVisibility = "ItemVisibility"; +const std::string kEventAvailability = "EventAvailability"; +const std::string kEventPriority = "EventPriority"; +const std::string kTaskPriority = "TaskPriority"; +const std::string kEventStatus = "EventStatus"; +const std::string kTaskStatus = "TaskStatus"; +const std::string kAttendeeRole = "AttendeeRole"; +const std::string kAttendeeStatus = "AttendeeStatus"; +const std::string kAttendeeType = "AttendeeType"; +const std::string kAlarmMethod = "AlarmMethod"; +const std::string kRecurrenceRuleFrequency = "RecurrenceRuleFrequency"; +} + +const PlatformPropertyMap CalendarItem::platform_property_map_ = { + {"id", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.id}, + {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.id}}}, + {"calendar_id", + {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.calendar_book_id}, + {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.calendar_book_id}}}, + {"description", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.description}, + {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.description}}}, + {"summary", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.summary}, + {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.summary}}}, + {"isAllDay", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.is_allday}, + {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.is_allday}}}, + {"startDate_time", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.start_time}, + {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.start_time}}}, + {"startDate_tzid", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.start_tzid}, + {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.start_tzid}}}, + {"location", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.location}, + {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.location}}}, + {"latitude", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.latitude}, + {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.latitude}}}, + {"longitude", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.longitude}, + {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.longitude}}}, + {"organizer", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.organizer_name}, + {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.organizer_name}}}, + {"visibility", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.sensitivity}, + {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.sensitivity}}}, + {"status", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.event_status}, + {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.todo_status}}}, + {"priority", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.priority}, + {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.priority}}}, + {"categories", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.categories}, + {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.categories}}}, + {"lastModificationDate", + {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.last_modified_time}, + {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.last_modified_time}}}, + + // event only + {"endDate_time", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.end_time}}}, + {"endDate_tzid", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.end_tzid}}}, + {"recurrence_id", + {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.recurrence_id}}}, + {"availability", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.busy_status}}}, + + // task only + {"dueDate_time", {{CALENDAR_BOOK_TYPE_TODO, _calendar_todo.due_time}}}, + {"dueDate_tzid", {{CALENDAR_BOOK_TYPE_TODO, _calendar_todo.due_tzid}}}, + {"completedDate", + {{CALENDAR_BOOK_TYPE_TODO, _calendar_todo.completed_time}}}, + {"progress", {{CALENDAR_BOOK_TYPE_TODO, _calendar_todo.progress}}}}; + +const PlatformEnumMap CalendarItem::platform_enum_map_ = { + {kItemVisibility, {{kDefaultEnumKey, CALENDAR_SENSITIVITY_PUBLIC}, + {"PUBLIC", CALENDAR_SENSITIVITY_PUBLIC}, + {"PRIVATE", CALENDAR_SENSITIVITY_PRIVATE}, + {"CONFIDENTIAL", CALENDAR_SENSITIVITY_CONFIDENTIAL}}}, + {kEventAvailability, + {{kDefaultEnumKey, CALENDAR_EVENT_BUSY_STATUS_BUSY}, + {"FREE", CALENDAR_EVENT_BUSY_STATUS_FREE}, + {"BUSY", CALENDAR_EVENT_BUSY_STATUS_BUSY}, + {"BUSY-UNAVAILABLE", CALENDAR_EVENT_BUSY_STATUS_UNAVAILABLE}, + {"BUSY-TENTATIVE", CALENDAR_EVENT_BUSY_STATUS_TENTATIVE}}}, + {kEventAvailability, + {{kDefaultEnumKey, CALENDAR_EVENT_BUSY_STATUS_BUSY}, + {"FREE", CALENDAR_EVENT_BUSY_STATUS_FREE}, + {"BUSY", CALENDAR_EVENT_BUSY_STATUS_BUSY}, + {"BUSY-UNAVAILABLE", CALENDAR_EVENT_BUSY_STATUS_UNAVAILABLE}, + {"BUSY-TENTATIVE", CALENDAR_EVENT_BUSY_STATUS_TENTATIVE}}}, + {kEventPriority, {{kDefaultEnumKey, CALENDAR_EVENT_PRIORITY_NORMAL}, + {"LOW", CALENDAR_EVENT_PRIORITY_LOW}, + {"MEDIUM", CALENDAR_EVENT_PRIORITY_NORMAL}, + {"HIGH", CALENDAR_EVENT_PRIORITY_HIGH}}}, + {kTaskPriority, {{kDefaultEnumKey, CALENDAR_TODO_PRIORITY_NORMAL}, + {"LOW", CALENDAR_TODO_PRIORITY_LOW}, + {"MEDIUM", CALENDAR_TODO_PRIORITY_NORMAL}, + {"HIGH", CALENDAR_TODO_PRIORITY_HIGH}}}, + {kEventStatus, {{kDefaultEnumKey, CALENDAR_EVENT_STATUS_NONE}, + {"TENTATIVE", CALENDAR_EVENT_STATUS_TENTATIVE}, + {"CONFIRMED", CALENDAR_EVENT_STATUS_CONFIRMED}, + {"CANCELLED", CALENDAR_EVENT_STATUS_CANCELLED}}}, + {kTaskStatus, {{kDefaultEnumKey, CALENDAR_TODO_STATUS_NONE}, + {"NEEDS_ACTION", CALENDAR_TODO_STATUS_NEEDS_ACTION}, + {"COMPLETED", CALENDAR_TODO_STATUS_COMPLETED}, + {"IN_PROCESS", CALENDAR_TODO_STATUS_IN_PROCESS}, + {"CANCELLED", CALENDAR_TODO_STATUS_CANCELED}}}, + {kAttendeeRole, + {{kDefaultEnumKey, CALENDAR_ATTENDEE_ROLE_CHAIR}, + {"REQ_PARTICIPANT", CALENDAR_ATTENDEE_ROLE_REQ_PARTICIPANT}, + {"OPT_PARTICIPANT", CALENDAR_ATTENDEE_ROLE_OPT_PARTICIPANT}, + {"NON_PARTICIPANT", CALENDAR_ATTENDEE_ROLE_NON_PARTICIPANT}, + {"CHAIR", CALENDAR_ATTENDEE_ROLE_CHAIR}}}, + {kAttendeeStatus, {{kDefaultEnumKey, CALENDAR_ATTENDEE_STATUS_PENDING}, + {"PENDING", CALENDAR_ATTENDEE_STATUS_PENDING}, + {"ACCEPTED", CALENDAR_ATTENDEE_STATUS_ACCEPTED}, + {"DECLINED", CALENDAR_ATTENDEE_STATUS_DECLINED}, + {"TENTATIVE", CALENDAR_ATTENDEE_STATUS_TENTATIVE}, + {"DELEGATED", CALENDAR_ATTENDEE_STATUS_DELEGATED}, + {"COMPLETED", CALENDAR_ATTENDEE_STATUS_COMPLETED}, + {"IN_PROCESS", CALENDAR_ATTENDEE_STATUS_IN_PROCESS}, }}, + {kAttendeeType, {{kDefaultEnumKey, CALENDAR_ATTENDEE_CUTYPE_INDIVIDUAL}, + {"INDIVIDUAL", CALENDAR_ATTENDEE_CUTYPE_INDIVIDUAL}, + {"GROUP", CALENDAR_ATTENDEE_CUTYPE_GROUP}, + {"RESOURCE", CALENDAR_ATTENDEE_CUTYPE_RESOURCE}, + {"ROOM", CALENDAR_ATTENDEE_CUTYPE_ROOM}, + {"UNKNOWN", CALENDAR_ATTENDEE_CUTYPE_UNKNOWN}}}, + {kAlarmMethod, {{kDefaultEnumKey, CALENDAR_ALARM_ACTION_AUDIO}, + {"SOUND", CALENDAR_ALARM_ACTION_AUDIO}, + {"DISPLAY", CALENDAR_ALARM_ACTION_DISPLAY}}}, + {kRecurrenceRuleFrequency, {{kDefaultEnumKey, CALENDAR_RECURRENCE_NONE}, + {"", CALENDAR_RECURRENCE_NONE}, + {"DAILY", CALENDAR_RECURRENCE_DAILY}, + {"WEEKLY", CALENDAR_RECURRENCE_WEEKLY}, + {"MONTHLY", CALENDAR_RECURRENCE_MONTHLY}, + {"YEARLY", CALENDAR_RECURRENCE_YEARLY}}}}; +PlatformEnumReverseMap CalendarItem::platform_enum_reverse_map_ = {}; + +CalendarRecordPtr CalendarItem::Create(int type) { + LoggerD("enter"); + + return CalendarRecord::Create(CalendarRecord::TypeToUri(type)); +} + +void CalendarItem::Remove(int type, int id) { + LoggerD("enter"); + + const char* view_uri = CalendarRecord::TypeToUri(type); + CalendarRecordPtr record = GetById(id, view_uri); + + if (type == CALENDAR_BOOK_TYPE_EVENT) { + const std::string& rid = GetString(type, record.get(), "recurrence_id"); + if (rid.length() > 0) { + // @todo remove all occurrences + return; + } + } + + if (CALENDAR_ERROR_NONE != calendar_db_delete_record(view_uri, id)) { + LOGE("Calendar record delete error"); + throw common:: UnknownException("Record deletion error"); + } +} + +unsigned int CalendarItem::GetPlatformProperty(int type, + const std::string& property) { + if (platform_property_map_.find(property) == platform_property_map_.end()) { + throw common::UnknownException(std::string("Undefined property ") + property); + } + + auto prop = platform_property_map_.at(property); + if (prop.find(type) == prop.end()) { + LoggerD("Property %s not defined for type %d", property.c_str(), type); + return -1u; + } + + return prop.at(type); +} + +int CalendarItem::StringToPlatformEnum(const std::string& field, + const std::string& value) { + auto iter = platform_enum_map_.find(field); + if (iter == platform_enum_map_.end()) { + throw common::UnknownException(std::string("Undefined platform enum type ") + + field); + } + + auto def = platform_enum_map_.at(field); + auto def_iter = def.find(value); + if (def_iter != def.end()) { + return def_iter->second; + } + + // default value - if any + def_iter = def.find("_DEFAULT"); + if (def_iter != def.end()) { + return def_iter->second; + } + + std::string message = + "Platform enum value " + value + " not found for " + field; + throw InvalidValuesException(message); +} + +std::string CalendarItem::PlatformEnumToString(const std::string& field, + int value) { + // @todo can be replaced by Boost.Bimap + if (platform_enum_reverse_map_.empty()) { + for (auto& def : platform_enum_map_) { + platform_enum_reverse_map_[def.first] = {}; + + for (auto& key : def.second) { + if (key.first != kDefaultEnumKey) { + platform_enum_reverse_map_[def.first][key.second] = key.first; + } + } + } + } + + auto iter = platform_enum_reverse_map_.find(field); + if (iter == platform_enum_reverse_map_.end()) { + throw common::UnknownException(std::string("Undefined platform enum type ") + + field); + } + + auto def = platform_enum_reverse_map_.at(field); + auto def_iter = def.find(value); + if (def_iter != def.end()) { + return def_iter->second; + } + + std::string message = "Platform enum value " + std::to_string(value) + + " not found for " + field; + throw InvalidValuesException(message); +} + +void CalendarItem::SetString(int type, calendar_record_h rec, + const std::string& property, + const picojson::object& in, bool optional) { + LoggerD("set: %s", property.c_str()); + + if (optional && IsNull(in, property.c_str())) { + return; + } + + const std::string& value = + common::FromJson(in, property.c_str()); + + SetString(type, rec, property, value); +} + +void CalendarItem::SetString(int type, calendar_record_h rec, + const std::string& property, + const std::string& value) { + LoggerD("set: %s", property.c_str()); + + unsigned int prop = GetPlatformProperty(type, property); + + if (prop != -1u) { + CalendarRecord::SetString(rec, prop, value); + } +} + +std::string CalendarItem::GetString(int type, calendar_record_h rec, + const std::string& property) { + LoggerD("get: %s", property.c_str()); + + return CalendarRecord::GetString(rec, GetPlatformProperty(type, property)); +} + +void CalendarItem::SetInt(int type, calendar_record_h rec, + const std::string& property, const picojson::object& in, + bool optional) { + LoggerD("set: %s", property.c_str()); + + if (optional && IsNull(in, property.c_str())) { + return; + } + + int value = common::FromJson(in, property.c_str()); + + SetInt(type, rec, property, value); +} + +void CalendarItem::SetInt(int type, calendar_record_h rec, + const std::string& property, int value) { + LoggerD("set: %s", property.c_str()); + + unsigned int prop = GetPlatformProperty(type, property); + + if (prop != -1u) { + CalendarRecord::SetInt(rec, prop, value); + } +} + +int CalendarItem::GetInt(int type, calendar_record_h rec, + const std::string& property) { + LoggerD("get: %s", property.c_str()); + + return CalendarRecord::GetInt(rec, GetPlatformProperty(type, property)); +} + +void CalendarItem::SetEnum(int type, calendar_record_h rec, + const std::string& property, const picojson::object& in, + const std::string& enum_name) { + std::string value = common::FromJson(in, property.c_str()); + SetInt(type, rec, property, StringToPlatformEnum(enum_name, value)); +} + +void CalendarItem::SetEnum(calendar_record_h rec, unsigned int property, + const std::string& enum_name, + const std::string& value) { + CalendarRecord::SetInt(rec, property, StringToPlatformEnum(enum_name, value)); +} + +std::string CalendarItem::GetEnum(int type, calendar_record_h rec, + const std::string& property, + const std::string& enum_name) { + return PlatformEnumToString(enum_name, GetInt(type, rec, property)); +} + +std::string CalendarItem::GetEnum(calendar_record_h rec, unsigned int property, + const std::string& enum_name) { + return PlatformEnumToString(enum_name, CalendarRecord::GetInt(rec, property)); +} + +void CalendarItem::SetDouble(int type, calendar_record_h rec, + const std::string& property, double value) { + LoggerD("set: %s", property.c_str()); + + unsigned int prop = GetPlatformProperty(type, property); + + if (prop != -1u) { + int ret = calendar_record_set_double(rec, prop, value); + + if (CALENDAR_ERROR_NONE != ret) { + LoggerW("Can't set double value to record: %d", ret); + throw common::UnknownException("Set double to record failed."); + } + } +} + +double CalendarItem::GetDouble(int type, calendar_record_h rec, + const std::string& property) { + LoggerD("get: %s", property.c_str()); + + double value; + int ret = calendar_record_get_double(rec, GetPlatformProperty(type, property), + &value); + if (CALENDAR_ERROR_NONE != ret) { + LoggerW("Can't get double value form record: %d", ret); + throw common::UnknownException("Get int from record failed."); + } + + return value; +} + +void CalendarItem::SetCaltime(int type, calendar_record_h rec, + const std::string& property, + calendar_time_s value, bool throw_on_error) { + LoggerD("enter"); + + unsigned int prop = GetPlatformProperty(type, property); + + if (prop != -1u) { + SetCaltime(rec, prop, value, throw_on_error); + } +} + +void CalendarItem::SetCaltime(calendar_record_h rec, unsigned int property, + calendar_time_s value, bool throw_on_error) { + int ret = calendar_record_set_caltime(rec, property, value); + + if (CALENDAR_ERROR_NONE != ret) { + LoggerW("Can't set caltime value to record: %d", ret); + + if (throw_on_error) { + throw common::UnknownException("Set caltime to record failed."); + } + } +} + +calendar_time_s CalendarItem::GetCaltime(int type, calendar_record_h rec, + const std::string& property, + bool throw_on_error) { + LoggerD("get: %s", property.c_str()); + + unsigned int prop = GetPlatformProperty(type, property); + + return GetCaltime(rec, prop, throw_on_error); +} + +calendar_time_s CalendarItem::GetCaltime(calendar_record_h rec, + unsigned int property, + bool throw_on_error) { + calendar_time_s cal; + + if (property != -1u) { + int ret = calendar_record_get_caltime(rec, property, &cal); + if (CALENDAR_ERROR_NONE != ret) { + LoggerW("Can't get calendar_time value form record: %d", ret); + if (throw_on_error) { + throw common::UnknownException( + "Can't get calendar_time value form record"); + } + } + } + + return cal; +} + +void CalendarItem::SetLli(calendar_record_h rec, unsigned int property, + long long int value, bool throw_on_error) { + + int ret = calendar_record_set_lli(rec, property, value); + + if (CALENDAR_ERROR_NONE != ret) { + LoggerW("Can't set long long int value to record: %d", ret); + + if (throw_on_error) { + throw common::UnknownException("Set long long int to record failed."); + } + } +} + +long long int CalendarItem::GetLli(int type, calendar_record_h rec, + const std::string& property) { + LoggerD("get: %s", property.c_str()); + + return GetLli(rec, GetPlatformProperty(type, property)); +} + +long long int CalendarItem::GetLli(calendar_record_h rec, unsigned int property, + bool throw_on_error) { + long long int value; + int ret = calendar_record_get_lli(rec, property, &value); + if (CALENDAR_ERROR_NONE != ret) { + LoggerW("Can't get lli value form record: %d", ret); + if (throw_on_error) { + throw common::UnknownException("Get lli from record failed."); + } + } + + return value; +} + +Date CalendarItem::DateFromJson(const picojson::object& in) { + LoggerD("json date %s", picojson::value(in).serialize().c_str()); + + Date date = {(long long int)common::FromJson(in, "UTCTimestamp"), + (int)common::FromJson(in, "year"), + (int)common::FromJson(in, "month"), + (int)common::FromJson(in, "day"), + common::FromJson(in, "timezone")}; + + return date; +} + +Date CalendarItem::DateFromJson(const picojson::object& in, const char* obj_name) { + return DateFromJson(common::FromJson(in, obj_name)); +} + +picojson::value CalendarItem::DateToJson(Date date) { + LoggerD("timestamp: %lld", date.utc_timestamp_); + + picojson::value date_val = picojson::value(picojson::object()); + picojson::object& date_obj = date_val.get(); + + date_obj["UTCTimestamp"] = + picojson::value(static_cast(date.utc_timestamp_)); + date_obj["year"] = picojson::value(static_cast(date.year_)); + date_obj["month"] = picojson::value(static_cast(date.month_)); + date_obj["day"] = picojson::value(static_cast(date.day_)); + date_obj["timezone"] = picojson::value(date.time_zone_); + + return date_val; +} + +void CalendarItem::CategoriesFromJson(int type, calendar_record_h rec, + const picojson::array& value) { + std::string categories = ""; + for (auto iter = value.begin(); iter != value.end(); ++iter) { + if (iter == value.begin()) { + categories.append(iter->get().c_str()); + } else { + categories.append("," + iter->get()); + } + } + + SetString(type, rec, "categories", categories); +} + +picojson::array CalendarItem::CategoriesToJson(int type, calendar_record_h rec) { + LoggerD("enter"); + + std::string categories = GetString(type, rec, "categories"); + + return StringToArray(categories); +} + +void CalendarItem::AttendeesFromJson(int type, calendar_record_h rec, + const picojson::array& value) { + LoggerD("enter"); + + // Remove the preset child attendees before adding new ones. + unsigned int property; + if (type == CALENDAR_BOOK_TYPE_EVENT) { + property = _calendar_event.calendar_attendee; + } else { + property = _calendar_todo.calendar_attendee; + } + RemoveChildRecords(rec, property); + + calendar_record_h attendee; + for (auto& item : value) { + const picojson::object& obj = JsonCast(item); + + int ret = calendar_record_create(_calendar_attendee._uri, &attendee); + if (CALENDAR_ERROR_NONE != ret) { + LoggerE("Fail to create attendee record, error code: %d", ret); + throw common::UnknownException("Fail to create attendee record"); + } + + CalendarRecord::SetString(attendee, _calendar_attendee.email, + common::FromJson(obj, "uri")); + + if (!IsNull(obj, "name")) { + CalendarRecord::SetString(attendee, _calendar_attendee.name, + common::FromJson(obj, "name")); + } + + SetEnum(attendee, _calendar_attendee.role, kAttendeeRole, + common::FromJson(obj, "role")); + + SetEnum(attendee, _calendar_attendee.status, kAttendeeStatus, + common::FromJson(obj, "status")); + + CalendarRecord::SetInt(attendee, _calendar_attendee.rsvp, + common::FromJson(obj, "RSVP")); + + SetEnum(attendee, _calendar_attendee.cutype, kAttendeeType, + common::FromJson(obj, "type")); + + if (!IsNull(obj, "group")) { + CalendarRecord::SetString(attendee, _calendar_attendee.group, + common::FromJson(obj, "group")); + } + if (!IsNull(obj, "delegatorURI")) { + CalendarRecord::SetString( + attendee, _calendar_attendee.delegator_uri, + common::FromJson(obj, "delegatorURI")); + } + if (!IsNull(obj, "delegateURI")) { + CalendarRecord::SetString( + attendee, _calendar_attendee.delegatee_uri, + common::FromJson(obj, "delegateURI")); + } + + if (!IsNull(obj, "contactRef")) { + CalendarRecord::SetString( + attendee, _calendar_attendee.uid, + common::FromJson(obj, "contactRef", "contactId")); + + const std::string& address_book = + common::FromJson(obj, "contactRef", "addressBookId"); + CalendarRecord::SetInt(attendee, _calendar_attendee.person_id, + common::stol(address_book)); + } else { + LoggerD("ContactRef not set"); + } + + AddChildRecord(rec, property, attendee); + } +} + +picojson::array CalendarItem::AttendeesToJson(int type, calendar_record_h rec) { + LoggerD("enter"); + + picojson::array out = picojson::array(); + + unsigned int property; + if (type == CALENDAR_BOOK_TYPE_EVENT) { + property = _calendar_event.calendar_attendee; + } else { + property = _calendar_todo.calendar_attendee; + } + + unsigned int count = 0; + if (!(count = GetChildRecordCount(rec, property))) { + LoggerD("No attendees to set."); + return out; + } + + calendar_list_h list; + if (CALENDAR_ERROR_NONE != + calendar_record_clone_child_record_list(rec, property, &list)) { + LoggerE("Can't get attendee list"); + return out; + } + CalendarListPtr(list, CalendarRecord::ListDeleter); + + calendar_record_h attendee; + for (unsigned int i = 0; i < count; ++i) { + LoggerD("Processing the attendee %d", i); + + if (!GetChildRecordAt(rec, property, &attendee, i, false)) { + LoggerW("Can't get attendee record"); + continue; + } + + picojson::value attendee_val = picojson::value(picojson::object()); + picojson::object& attendee_obj = attendee_val.get(); + + attendee_obj["uri"] = picojson::value( + CalendarRecord::GetString(attendee, _calendar_attendee.email, false)); + + attendee_obj["name"] = picojson::value( + CalendarRecord::GetString(attendee, _calendar_attendee.name, false)); + + attendee_obj["role"] = + picojson::value(GetEnum(attendee, _calendar_attendee.role, kAttendeeRole)); + + attendee_obj["status"] = picojson::value( + GetEnum(attendee, _calendar_attendee.status, kAttendeeStatus)); + + attendee_obj["RSVP"] = picojson::value( + (bool)CalendarRecord::GetInt(attendee, _calendar_attendee.rsvp, false)); + + attendee_obj["type"] = picojson::value( + GetEnum(attendee, _calendar_attendee.cutype, kAttendeeType)); + + attendee_obj["group"] = picojson::value( + CalendarRecord::GetString(attendee, _calendar_attendee.group, false)); + + attendee_obj["delegatorURI"] = picojson::value(CalendarRecord::GetString( + attendee, _calendar_attendee.delegator_uri, false)); + + attendee_obj["delegateURI"] = picojson::value(CalendarRecord::GetString( + attendee, _calendar_attendee.delegatee_uri, false)); + + // contactRef + const std::string& contact_id = + CalendarRecord::GetString(attendee, _calendar_attendee.uid, false); + int book_id = + CalendarRecord::GetInt(attendee, _calendar_attendee.person_id, false); + attendee_obj["contactRef"] = picojson::value( + picojson::object{{"contactId", picojson::value(contact_id)}, + {"addressBookId", picojson::value(std::to_string(book_id))}}); + + out.push_back(attendee_val); + } + + return out; +} + +void CalendarItem::AlarmsFromJson(int type, calendar_record_h rec, + const picojson::array& alarms) { + LoggerD("enter"); + + unsigned int property; + if (type == CALENDAR_BOOK_TYPE_EVENT) { + property = _calendar_event.calendar_alarm; + } else { + property = _calendar_todo.calendar_alarm; + } + RemoveChildRecords(rec, property); + + calendar_record_h alarm; + for (auto& item : alarms) { + LoggerD("alarm: %s", item.serialize().c_str()); + const picojson::object& obj = JsonCast(item); + + int ret = calendar_record_create(_calendar_alarm._uri, &alarm); + if (CALENDAR_ERROR_NONE != ret) { + LoggerE("Fail to create attendee record, error code: %d", ret); + throw common::UnknownException("Fail to create attendee record"); + } + + int tick_unit = CALENDAR_ALARM_TIME_UNIT_SPECIFIC; + if (!common::IsNull(obj, "absoluteDate")) { + Date absolute = DateFromJson(obj, "absoluteDate"); + calendar_time_s absolute_date = DateToPlatform(absolute, false); + // SetLli(alarm, _calendar_alarm.time, absolute_date.time.utime); + CalendarRecord::SetInt(alarm, _calendar_alarm.tick_unit, tick_unit); + } + + if (!common::IsNull(obj, "before")) { + long long length = common::FromJson(obj, "before", "length"); + const std::string& unit = + common::FromJson(obj, "before", "unit"); + long long tick = 0; + if (kTimeDurationUnitMilliseconds == unit) { + tick_unit = + CALENDAR_ALARM_TIME_UNIT_MINUTE; // minimum calendar time unit. + tick = length / 60000; + } else if (kTimeDurationUnitSeconds == unit) { + tick_unit = CALENDAR_ALARM_TIME_UNIT_MINUTE; + tick = length / 60; + } else if (kTimeDurationUnitMinutes == unit) { + tick_unit = CALENDAR_ALARM_TIME_UNIT_MINUTE; + tick = length; + } else if (kTimeDurationUnitHours == unit) { + tick_unit = CALENDAR_ALARM_TIME_UNIT_HOUR; + tick = length; + } else if (kTimeDurationUnitDays == unit) { + tick_unit = CALENDAR_ALARM_TIME_UNIT_DAY; + tick = length; + } else { + LoggerW("Wrong alarm time unit: %s", unit.c_str()); + } + + CalendarRecord::SetInt(alarm, _calendar_alarm.tick, tick); + CalendarRecord::SetInt(alarm, _calendar_alarm.tick_unit, tick_unit); + } + + SetEnum(alarm, _calendar_alarm.action, kAlarmMethod, + common::FromJson(obj, "method")); + + CalendarRecord::SetString( + alarm, _calendar_alarm.description, + common::FromJson(obj, "description")); + + AddChildRecord(rec, property, alarm); + } +} + +picojson::array CalendarItem::AlarmsToJson(int type, calendar_record_h rec) { + LoggerD("enter"); + + picojson::array out = picojson::array(); + + unsigned int property; + if (type == CALENDAR_BOOK_TYPE_EVENT) { + property = _calendar_event.calendar_alarm; + } else { + property = _calendar_todo.calendar_alarm; + } + + unsigned int count = 0; + if (!(count = GetChildRecordCount(rec, property))) { + LoggerD("No attendees to set."); + return out; + } + + calendar_list_h list; + if (CALENDAR_ERROR_NONE != + calendar_record_clone_child_record_list(rec, property, &list)) { + LoggerW("Can't get alarms list"); + return out; + } + CalendarListPtr(list, CalendarRecord::ListDeleter); + + int tick, tick_unit; + calendar_record_h alarm; + for (unsigned int i = 0; i < count; ++i) { + LoggerD("Processing the alarm %d", i); + + if (!GetChildRecordAt(rec, property, &alarm, i, false)) { + LoggerW("Can't get alarm record"); + continue; + } + + picojson::value alarm_val = picojson::value(picojson::object()); + picojson::object& alarm_obj = alarm_val.get(); + + tick_unit = CalendarRecord::GetInt(alarm, _calendar_alarm.tick_unit, false); + + if (tick_unit == CALENDAR_ALARM_TIME_UNIT_SPECIFIC) { + // long long int time = GetLli(alarm, _calendar_alarm.time, false); + // alarm_obj["absoluteDate"] = picojson::value(static_cast(time)); + } else { + // tick = CalendarRecord::GetInt(alarm, _calendar_alarm.tick, false); + + int length = 0; + std::string unit = kTimeDurationUnitSeconds; + if (CALENDAR_ALARM_TIME_UNIT_MINUTE == tick_unit) { + unit = kTimeDurationUnitMinutes; + length = tick; + } else if (CALENDAR_ALARM_TIME_UNIT_HOUR == tick_unit) { + unit = kTimeDurationUnitHours; + length = tick; + } else if (CALENDAR_ALARM_TIME_UNIT_DAY == tick_unit) { + unit = kTimeDurationUnitDays; + length = tick; + } else if (CALENDAR_ALARM_TIME_UNIT_WEEK == tick_unit) { + unit = kTimeDurationUnitDays; + length = tick * 7; + } else { + LoggerW("Wrong tick unit: %d", tick_unit); + } + + alarm_obj["before"] = picojson::value( + picojson::object{{"length", picojson::value(static_cast(length))}, + {"unit", picojson::value(unit)}}); + } + + alarm_obj["method"] = + picojson::value(GetEnum(alarm, _calendar_alarm.action, kAlarmMethod)); + + alarm_obj["description"] = picojson::value( + CalendarRecord::GetString(alarm, _calendar_alarm.description, false)); + + out.push_back(alarm_val); + } + + return out; +} + +void CalendarItem::RecurrenceRuleFromJson(calendar_record_h rec, + const picojson::object& rrule) { + LoggerD("enter"); + + const std::string& frequency = + common::FromJson(rrule, "frequency"); + SetEnum(rec, _calendar_event.freq, kRecurrenceRuleFrequency, frequency); + + const unsigned short interval = common::FromJson(rrule, "interval"); + CalendarRecord::SetInt(rec, _calendar_event.interval, interval); + + const long occurrence_count = + common::FromJson(rrule, "occurrenceCount"); + if (-1 != occurrence_count) { + CalendarRecord::SetInt(rec, _calendar_event.count, occurrence_count); + CalendarRecord::SetInt(rec, _calendar_event.range_type, + CALENDAR_RANGE_COUNT); + } + + if (!common::IsNull(rrule, "untilDate")) { + Date until = DateFromJson(rrule, "untilDate"); + SetCaltime(rec, _calendar_event.until_time, DateToPlatform(until, false)); + CalendarRecord::SetInt(rec, _calendar_event.range_type, + CALENDAR_RANGE_UNTIL); + } + + const picojson::array& byday_array = + common::FromJson(rrule, "daysOfTheWeek"); + std::string byday; + for (auto iter = byday_array.begin(); iter != byday_array.end(); ++iter) { + if (iter == byday_array.begin()) { + byday.append(iter->get()); + } else { + byday.append("," + iter->get()); + } + } + CalendarRecord::SetString(rec, _calendar_event.byday, byday); + + const picojson::array& bysetpos_array = + common::FromJson(rrule, "setPositions"); + std::string bysetpos; + for (auto iter = bysetpos_array.begin(); iter != bysetpos_array.end(); + ++iter) { + if (iter == bysetpos_array.begin()) { + bysetpos.append(std::to_string((int)iter->get())); + } else { + bysetpos.append("," + iter->get()); + } + } + CalendarRecord::SetString(rec, _calendar_event.bysetpos, bysetpos); + + CalendarRecord::SetString( + rec, _calendar_event.exdate, + ExceptionsFromJson(common::FromJson(rrule, "exceptions"))); +} + +std::string CalendarItem::ExceptionsFromJson(const picojson::array &exceptions) { + std::string result; + Date date; + for (auto iter = exceptions.begin(); iter != exceptions.end(); ++iter) { + date = DateFromJson(iter->get()); + calendar_time_s exception_date = DateToPlatform(date, false); + // std::stringstream ss; +// ss << exception_date.time.utime; + +// if (iter == exceptions.begin()) { +// result.append(ss.str()); +// } else { +// result.append("," + ss.str()); +// } + } + + return result; +} + +picojson::object CalendarItem::RecurrenceRuleToJson(calendar_record_h rec) { + LoggerD("enter"); + + picojson::object out = picojson::object(); + + out["frequency"] = + picojson::value(GetEnum(rec, _calendar_event.freq, kRecurrenceRuleFrequency)); + + int interval = CalendarRecord::GetInt(rec, _calendar_event.interval, false); + out["interval"] = picojson::value(static_cast(interval)); + + int occurrence_count = CalendarRecord::GetInt(rec, _calendar_event.count); + out["occurrenceCount"] = picojson::value(static_cast(occurrence_count)); + + calendar_time_s cal = {CALENDAR_TIME_UTIME, {0}}; + calendar_record_get_caltime(rec, _calendar_event.until_time, &cal); + if (cal.time.utime > 0 && CALENDAR_RECORD_NO_UNTIL != cal.time.utime) { + Date until = {cal.time.utime, 0, 0, 0, ""}; + out["untilDate"] = DateToJson(until); + } else { + out["untilDate"] = picojson::value(); + } + + out["daysOfTheWeek"] = picojson::value( + StringToArray(CalendarRecord::GetString(rec, _calendar_event.byday))); + + out["setPositions"] = picojson::value( + StringToArray(CalendarRecord::GetString(rec, _calendar_event.bysetpos))); + + const picojson::array& exceptions = + StringToArray(CalendarRecord::GetString(rec, _calendar_event.exdate)); + picojson::array dates = picojson::array(); + for (auto& exception : exceptions) { + Date date = {common::stol(exception.get()), 0, 0, 0, ""}; + dates.push_back(DateToJson(date)); + } + out["exceptions"] = picojson::value(dates); + + return out; +} + +calendar_time_s CalendarItem::DateToPlatform(const Date& date, + bool is_all_day) { + LoggerD("enter"); + + calendar_time_s cal; + + if (is_all_day) { + cal.type = CALENDAR_TIME_LOCALTIME; + cal.time.date = {date.year_, date.month_, date.day_}; + } else { + cal.type = CALENDAR_TIME_UTIME; + cal.time.utime = date.utc_timestamp_; + } + + return cal; +} + +Date CalendarItem::DateFromPlatform(int type, calendar_record_h rec, + const std::string& property) { + LoggerD("enter"); + + calendar_time_s cal = GetCaltime(type, rec, property + "_time"); + std::string tzid = GetString(type, rec, property + "_tzid"); + + Date date = {cal.time.utime, cal.time.date.year, cal.time.date.month, + cal.time.date.mday, tzid}; + + return date; +} + +Date CalendarItem::DateFromPlatform(calendar_record_h rec, + unsigned int property) { + LoggerD("enter"); + + calendar_time_s cal = GetCaltime(rec, property); + + Date date = {cal.time.utime, cal.time.date.year, cal.time.date.month, + cal.time.date.mday, ""}; + + return date; +} + +void CalendarItem::FromJson(int type, calendar_record_h rec, + const picojson::object& in) { + LoggerD("enter"); + + if (in.empty()) { + LoggerE("Empty CalendarItem object."); + throw InvalidValuesException("Empty Calendar object."); + } + + SetString(type, rec, "description", in, true); + SetString(type, rec, "summary", in, true); + SetString(type, rec, "location", in, true); + SetString(type, rec, "organizer", in, true); + + int is_all_day = common::FromJson(in, "isAllDay"); + + if (!common::IsNull(in, "startDate")) { + Date start = DateFromJson(in, "startDate"); + + SetCaltime(type, rec, "startDate_time", DateToPlatform(start, is_all_day)); + SetString(type, rec, "startDate_tzid", start.time_zone_); + } + + const std::string& endProperty = + (type == CALENDAR_BOOK_TYPE_EVENT) ? "endDate" : "dueDate"; + if (!common::IsNull(in, endProperty.c_str())) { + Date end = DateFromJson(in, endProperty.c_str()); + + SetCaltime(type, rec, endProperty + "_time", + DateToPlatform(end, is_all_day)); + SetString(type, rec, endProperty + "_tzid", end.time_zone_); + } + + SetEnum(type, rec, "visibility", in, kItemVisibility); + + if (!common::IsNull(in, "geolocation")) { + SetDouble(type, rec, "latitude", + common::FromJson(in, "geolocation", "latitude")); + SetDouble(type, rec, "longitude", + common::FromJson(in, "geolocation", "longitude")); + } + + CategoriesFromJson(type, rec, + common::FromJson(in, "categories")); + AttendeesFromJson(type, rec, common::FromJson(in, "attendees")); + AlarmsFromJson(type, rec, common::FromJson(in, "alarms")); + + if (type == CALENDAR_BOOK_TYPE_EVENT) { + SetEnum(type, rec, "priority", in, kEventPriority); + SetEnum(type, rec, "status", in, kEventStatus); + SetEnum(type, rec, "availability", in, kEventAvailability); + + if (!common::IsNull(in, "recurrenceRule")) { + RecurrenceRuleFromJson( + rec, common::FromJson(in, "recurrenceRule")); + } + + } else { + SetEnum(type, rec, "priority", in, kTaskPriority); + SetEnum(type, rec, "status", in, kTaskStatus); + + if (!common::IsNull(in, "completedDate")) { + SetLli(rec, _calendar_todo.completed_time, + DateFromJson(in, "completedDate").utc_timestamp_); + } + SetInt(type, rec, "progress", in); + } +} + +void CalendarItem::ToJson(int type, calendar_record_h rec, + picojson::object* out_ptr) { + LoggerD("enter"); + + if (NULL == rec) { + LoggerE("Calendar record is null"); + throw common::UnknownException("Calendar record is null"); + } + + picojson::object& out = *out_ptr; + + int id = GetInt(type, rec, "id"); + + picojson::value id_val; + if (type == CALENDAR_BOOK_TYPE_EVENT) { + id_val = picojson::value(picojson::object()); + picojson::object& id_obj = id_val.get(); + + id_obj["uid"] = picojson::value(std::to_string(id)); + const std::string& rid = GetString(type, rec, "recurrence_id"); + if (rid.length() > 0) { + id_obj["rid"] = picojson::value(rid); + } else { + id_obj["rid"] = picojson::value(); + } + } else { + id_val = picojson::value(std::to_string(id)); + } + + out["id"] = id_val; + + int calendar_id = GetInt(type, rec, "calendar_id"); + out["calendarId"] = picojson::value(std::to_string(calendar_id)); + + out["description"] = picojson::value(GetString(type, rec, "description")); + out["summary"] = picojson::value(GetString(type, rec, "summary")); + out["location"] = picojson::value(GetString(type, rec, "location")); + out["organizer"] = picojson::value(GetString(type, rec, "organizer")); + out["isAllDay"] = picojson::value((bool)GetInt(type, rec, "isAllDay")); + + // startDate + out["startDate"] = DateToJson(DateFromPlatform(type, rec, "startDate")); + + // endDate / dueDate + const std::string& endProperty = + (type == CALENDAR_BOOK_TYPE_EVENT) ? "endDate" : "dueDate"; + out[endProperty] = DateToJson(DateFromPlatform(type, rec, endProperty)); + + out["lastModificationDate"] = picojson::value( + static_cast(GetLli(type, rec, "lastModificationDate"))); + + out["geolocation"] = picojson::value(picojson::object( + {{"latitude", picojson::value(GetDouble(type, rec, "latitude"))}, + {"longitude", picojson::value(GetDouble(type, rec, "longitude"))}})); + + out["visibility"] = + picojson::value(GetEnum(type, rec, "visibility", kItemVisibility)); + + out["attendees"] = picojson::value(AttendeesToJson(type, rec)); + out["categories"] = picojson::value(CategoriesToJson(type, rec)); + out["alarms"] = picojson::value(AlarmsToJson(type, rec)); + + if (type == CALENDAR_BOOK_TYPE_EVENT) { + out["status"] = picojson::value(GetEnum(type, rec, "status", kEventStatus)); + out["priority"] = + picojson::value(GetEnum(type, rec, "priority", kEventPriority)); + out["availability"] = + picojson::value(GetEnum(type, rec, "availability", kEventAvailability)); + out["recurrenceRule"] = picojson::value(RecurrenceRuleToJson(rec)); + } else { + out["status"] = picojson::value(GetEnum(type, rec, "status", kTaskStatus)); + out["priority"] = + picojson::value(GetEnum(type, rec, "priority", kTaskPriority)); + + out["completedDate"] = picojson::value( + static_cast(GetLli(rec, _calendar_todo.completed_time))); + out["progress"] = + picojson::value(static_cast(GetInt(type, rec, "progress"))); + } +} + +picojson::array CalendarItem::StringToArray(const std::string& string) { + picojson::array out = picojson::array(); + + char* cstr = new char[string.length() + 1]; + strcpy(cstr, string.c_str()); + + char* saveptr = NULL; + char* pch = strtok_r(cstr, ",", &saveptr); + + while (NULL != pch) { + out.push_back(picojson::value(std::string(pch))); + pch = strtok_r(NULL, ",", &saveptr); + } + + delete[] cstr; + + return out; +} + +} // namespace calendar +} // namespace extension diff --git a/src/calendar/calendar_item.cpp b/src/calendar/calendar_item.cpp deleted file mode 100644 index 65d850c8..00000000 --- a/src/calendar/calendar_item.cpp +++ /dev/null @@ -1,1164 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "calendar_item.h" - -#include -#include - -#include "logger.h" -#include "converter.h" - -namespace webapi { -namespace calendar { - -namespace { -const std::string kTimeDurationUnitMilliseconds = "MSECS"; -const std::string kTimeDurationUnitSeconds = "SECS"; -const std::string kTimeDurationUnitMinutes = "MINS"; -const std::string kTimeDurationUnitHours = "HOURS"; -const std::string kTimeDurationUnitDays = "DAYS"; - -const std::string kDefaultEnumKey = "_DEFAULT"; -const std::string kItemVisibility = "ItemVisibility"; -const std::string kEventAvailability = "EventAvailability"; -const std::string kEventPriority = "EventPriority"; -const std::string kTaskPriority = "TaskPriority"; -const std::string kEventStatus = "EventStatus"; -const std::string kTaskStatus = "TaskStatus"; -const std::string kAttendeeRole = "AttendeeRole"; -const std::string kAttendeeStatus = "AttendeeStatus"; -const std::string kAttendeeType = "AttendeeType"; -const std::string kAlarmMethod = "AlarmMethod"; -const std::string kRecurrenceRuleFrequency = "RecurrenceRuleFrequency"; -} - -using namespace webapi::common; - -const PlatformPropertyMap CalendarItem::platform_property_map_ = { - {"id", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.id}, - {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.id}}}, - {"calendar_id", - {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.calendar_book_id}, - {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.calendar_book_id}}}, - {"description", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.description}, - {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.description}}}, - {"summary", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.summary}, - {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.summary}}}, - {"isAllDay", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.is_allday}, - {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.is_allday}}}, - {"startDate_time", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.start_time}, - {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.start_time}}}, - {"startDate_tzid", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.start_tzid}, - {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.start_tzid}}}, - {"location", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.location}, - {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.location}}}, - {"latitude", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.latitude}, - {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.latitude}}}, - {"longitude", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.longitude}, - {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.longitude}}}, - {"organizer", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.organizer_name}, - {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.organizer_name}}}, - {"visibility", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.sensitivity}, - {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.sensitivity}}}, - {"status", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.event_status}, - {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.todo_status}}}, - {"priority", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.priority}, - {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.priority}}}, - {"categories", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.categories}, - {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.categories}}}, - {"lastModificationDate", - {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.last_modified_time}, - {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.last_modified_time}}}, - - // event only - {"endDate_time", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.end_time}}}, - {"endDate_tzid", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.end_tzid}}}, - {"recurrence_id", - {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.recurrence_id}}}, - {"availability", {{CALENDAR_BOOK_TYPE_EVENT, _calendar_event.busy_status}}}, - - // task only - {"dueDate_time", {{CALENDAR_BOOK_TYPE_TODO, _calendar_todo.due_time}}}, - {"dueDate_tzid", {{CALENDAR_BOOK_TYPE_TODO, _calendar_todo.due_tzid}}}, - {"completedDate", - {{CALENDAR_BOOK_TYPE_TODO, _calendar_todo.completed_time}}}, - {"progress", {{CALENDAR_BOOK_TYPE_TODO, _calendar_todo.progress}}}}; - -const PlatformEnumMap CalendarItem::platform_enum_map_ = { - {kItemVisibility, {{kDefaultEnumKey, CALENDAR_SENSITIVITY_PUBLIC}, - {"PUBLIC", CALENDAR_SENSITIVITY_PUBLIC}, - {"PRIVATE", CALENDAR_SENSITIVITY_PRIVATE}, - {"CONFIDENTIAL", CALENDAR_SENSITIVITY_CONFIDENTIAL}}}, - {kEventAvailability, - {{kDefaultEnumKey, CALENDAR_EVENT_BUSY_STATUS_BUSY}, - {"FREE", CALENDAR_EVENT_BUSY_STATUS_FREE}, - {"BUSY", CALENDAR_EVENT_BUSY_STATUS_BUSY}, - {"BUSY-UNAVAILABLE", CALENDAR_EVENT_BUSY_STATUS_UNAVAILABLE}, - {"BUSY-TENTATIVE", CALENDAR_EVENT_BUSY_STATUS_TENTATIVE}}}, - {kEventAvailability, - {{kDefaultEnumKey, CALENDAR_EVENT_BUSY_STATUS_BUSY}, - {"FREE", CALENDAR_EVENT_BUSY_STATUS_FREE}, - {"BUSY", CALENDAR_EVENT_BUSY_STATUS_BUSY}, - {"BUSY-UNAVAILABLE", CALENDAR_EVENT_BUSY_STATUS_UNAVAILABLE}, - {"BUSY-TENTATIVE", CALENDAR_EVENT_BUSY_STATUS_TENTATIVE}}}, - {kEventPriority, {{kDefaultEnumKey, CALENDAR_EVENT_PRIORITY_NORMAL}, - {"LOW", CALENDAR_EVENT_PRIORITY_LOW}, - {"MEDIUM", CALENDAR_EVENT_PRIORITY_NORMAL}, - {"HIGH", CALENDAR_EVENT_PRIORITY_HIGH}}}, - {kTaskPriority, {{kDefaultEnumKey, CALENDAR_TODO_PRIORITY_NORMAL}, - {"LOW", CALENDAR_TODO_PRIORITY_LOW}, - {"MEDIUM", CALENDAR_TODO_PRIORITY_NORMAL}, - {"HIGH", CALENDAR_TODO_PRIORITY_HIGH}}}, - {kEventStatus, {{kDefaultEnumKey, CALENDAR_EVENT_STATUS_NONE}, - {"TENTATIVE", CALENDAR_EVENT_STATUS_TENTATIVE}, - {"CONFIRMED", CALENDAR_EVENT_STATUS_CONFIRMED}, - {"CANCELLED", CALENDAR_EVENT_STATUS_CANCELLED}}}, - {kTaskStatus, {{kDefaultEnumKey, CALENDAR_TODO_STATUS_NONE}, - {"NEEDS_ACTION", CALENDAR_TODO_STATUS_NEEDS_ACTION}, - {"COMPLETED", CALENDAR_TODO_STATUS_COMPLETED}, - {"IN_PROCESS", CALENDAR_TODO_STATUS_IN_PROCESS}, - {"CANCELLED", CALENDAR_TODO_STATUS_CANCELED}}}, - {kAttendeeRole, - {{kDefaultEnumKey, CALENDAR_ATTENDEE_ROLE_CHAIR}, - {"REQ_PARTICIPANT", CALENDAR_ATTENDEE_ROLE_REQ_PARTICIPANT}, - {"OPT_PARTICIPANT", CALENDAR_ATTENDEE_ROLE_OPT_PARTICIPANT}, - {"NON_PARTICIPANT", CALENDAR_ATTENDEE_ROLE_NON_PARTICIPANT}, - {"CHAIR", CALENDAR_ATTENDEE_ROLE_CHAIR}}}, - {kAttendeeStatus, {{kDefaultEnumKey, CALENDAR_ATTENDEE_STATUS_PENDING}, - {"PENDING", CALENDAR_ATTENDEE_STATUS_PENDING}, - {"ACCEPTED", CALENDAR_ATTENDEE_STATUS_ACCEPTED}, - {"DECLINED", CALENDAR_ATTENDEE_STATUS_DECLINED}, - {"TENTATIVE", CALENDAR_ATTENDEE_STATUS_TENTATIVE}, - {"DELEGATED", CALENDAR_ATTENDEE_STATUS_DELEGATED}, - {"COMPLETED", CALENDAR_ATTENDEE_STATUS_COMPLETED}, - {"IN_PROCESS", CALENDAR_ATTENDEE_STATUS_IN_PROCESS}, }}, - {kAttendeeType, {{kDefaultEnumKey, CALENDAR_ATTENDEE_CUTYPE_INDIVIDUAL}, - {"INDIVIDUAL", CALENDAR_ATTENDEE_CUTYPE_INDIVIDUAL}, - {"GROUP", CALENDAR_ATTENDEE_CUTYPE_GROUP}, - {"RESOURCE", CALENDAR_ATTENDEE_CUTYPE_RESOURCE}, - {"ROOM", CALENDAR_ATTENDEE_CUTYPE_ROOM}, - {"UNKNOWN", CALENDAR_ATTENDEE_CUTYPE_UNKNOWN}}}, - {kAlarmMethod, {{kDefaultEnumKey, CALENDAR_ALARM_ACTION_AUDIO}, - {"SOUND", CALENDAR_ALARM_ACTION_AUDIO}, - {"DISPLAY", CALENDAR_ALARM_ACTION_DISPLAY}}}, - {kRecurrenceRuleFrequency, {{kDefaultEnumKey, CALENDAR_RECURRENCE_NONE}, - {"", CALENDAR_RECURRENCE_NONE}, - {"DAILY", CALENDAR_RECURRENCE_DAILY}, - {"WEEKLY", CALENDAR_RECURRENCE_WEEKLY}, - {"MONTHLY", CALENDAR_RECURRENCE_MONTHLY}, - {"YEARLY", CALENDAR_RECURRENCE_YEARLY}}}}; -PlatformEnumReverseMap CalendarItem::platform_enum_reverse_map_ = {}; - -CalendarRecordPtr CalendarItem::Create(int type) { - LoggerD("enter"); - - return CalendarRecord::Create(CalendarRecord::TypeToUri(type)); -} - -void CalendarItem::Remove(int type, int id) { - LoggerD("enter"); - - const char* view_uri = CalendarRecord::TypeToUri(type); - CalendarRecordPtr record = GetById(id, view_uri); - - if (type == CALENDAR_BOOK_TYPE_EVENT) { - const std::string& rid = GetString(type, record.get(), "recurrence_id"); - if (rid.length() > 0) { - // @todo remove all occurrences - return; - } - } - - if (CALENDAR_ERROR_NONE != calendar_db_delete_record(view_uri, id)) { - LOGE("Calendar record delete error"); - throw UnknownException("Record deletion error"); - } -} - -unsigned int CalendarItem::GetPlatformProperty(int type, - const std::string& property) { - if (platform_property_map_.find(property) == platform_property_map_.end()) { - throw UnknownException(std::string("Undefined property ") + property); - } - - auto prop = platform_property_map_.at(property); - if (prop.find(type) == prop.end()) { - LoggerD("Property %s not defined for type %d", property.c_str(), type); - return -1u; - } - - return prop.at(type); -} - -int CalendarItem::StringToPlatformEnum(const std::string& field, - const std::string& value) { - auto iter = platform_enum_map_.find(field); - if (iter == platform_enum_map_.end()) { - throw UnknownException(std::string("Undefined platform enum type ") + - field); - } - - auto def = platform_enum_map_.at(field); - auto def_iter = def.find(value); - if (def_iter != def.end()) { - return def_iter->second; - } - - // default value - if any - def_iter = def.find("_DEFAULT"); - if (def_iter != def.end()) { - return def_iter->second; - } - - std::string message = - "Platform enum value " + value + " not found for " + field; - throw InvalidValuesException(message); -} - -std::string CalendarItem::PlatformEnumToString(const std::string& field, - int value) { - // @todo can be replaced by Boost.Bimap - if (platform_enum_reverse_map_.empty()) { - for (auto& def : platform_enum_map_) { - platform_enum_reverse_map_[def.first] = {}; - - for (auto& key : def.second) { - if (key.first != kDefaultEnumKey) { - platform_enum_reverse_map_[def.first][key.second] = key.first; - } - } - } - } - - auto iter = platform_enum_reverse_map_.find(field); - if (iter == platform_enum_reverse_map_.end()) { - throw UnknownException(std::string("Undefined platform enum type ") + - field); - } - - auto def = platform_enum_reverse_map_.at(field); - auto def_iter = def.find(value); - if (def_iter != def.end()) { - return def_iter->second; - } - - std::string message = "Platform enum value " + std::to_string(value) + - " not found for " + field; - throw InvalidValuesException(message); -} - -void CalendarItem::SetString(int type, calendar_record_h rec, - const std::string& property, - const json::Object& in, bool optional) { - LoggerD("set: %s", property.c_str()); - - if (optional && IsNull(in, property.c_str())) { - return; - } - - const std::string& value = - common::FromJson(in, property.c_str()); - - SetString(type, rec, property, value); -} - -void CalendarItem::SetString(int type, calendar_record_h rec, - const std::string& property, - const std::string& value) { - LoggerD("set: %s", property.c_str()); - - unsigned int prop = GetPlatformProperty(type, property); - - if (prop != -1u) { - CalendarRecord::SetString(rec, prop, value); - } -} - -std::string CalendarItem::GetString(int type, calendar_record_h rec, - const std::string& property) { - LoggerD("get: %s", property.c_str()); - - return CalendarRecord::GetString(rec, GetPlatformProperty(type, property)); -} - -void CalendarItem::SetInt(int type, calendar_record_h rec, - const std::string& property, const json::Object& in, - bool optional) { - LoggerD("set: %s", property.c_str()); - - if (optional && IsNull(in, property.c_str())) { - return; - } - - int value = common::FromJson(in, property.c_str()); - - SetInt(type, rec, property, value); -} - -void CalendarItem::SetInt(int type, calendar_record_h rec, - const std::string& property, int value) { - LoggerD("set: %s", property.c_str()); - - unsigned int prop = GetPlatformProperty(type, property); - - if (prop != -1u) { - CalendarRecord::SetInt(rec, prop, value); - } -} - -int CalendarItem::GetInt(int type, calendar_record_h rec, - const std::string& property) { - LoggerD("get: %s", property.c_str()); - - return CalendarRecord::GetInt(rec, GetPlatformProperty(type, property)); -} - -void CalendarItem::SetEnum(int type, calendar_record_h rec, - const std::string& property, const json::Object& in, - const std::string& enum_name) { - std::string value = common::FromJson(in, property.c_str()); - SetInt(type, rec, property, StringToPlatformEnum(enum_name, value)); -} - -void CalendarItem::SetEnum(calendar_record_h rec, unsigned int property, - const std::string& enum_name, - const std::string& value) { - CalendarRecord::SetInt(rec, property, StringToPlatformEnum(enum_name, value)); -} - -std::string CalendarItem::GetEnum(int type, calendar_record_h rec, - const std::string& property, - const std::string& enum_name) { - return PlatformEnumToString(enum_name, GetInt(type, rec, property)); -} - -std::string CalendarItem::GetEnum(calendar_record_h rec, unsigned int property, - const std::string& enum_name) { - return PlatformEnumToString(enum_name, CalendarRecord::GetInt(rec, property)); -} - -void CalendarItem::SetDouble(int type, calendar_record_h rec, - const std::string& property, double value) { - LoggerD("set: %s", property.c_str()); - - unsigned int prop = GetPlatformProperty(type, property); - - if (prop != -1u) { - int ret = calendar_record_set_double(rec, prop, value); - - if (CALENDAR_ERROR_NONE != ret) { - LoggerW("Can't set double value to record: %d", ret); - throw common::UnknownException("Set double to record failed."); - } - } -} - -double CalendarItem::GetDouble(int type, calendar_record_h rec, - const std::string& property) { - LoggerD("get: %s", property.c_str()); - - double value; - int ret = calendar_record_get_double(rec, GetPlatformProperty(type, property), - &value); - if (CALENDAR_ERROR_NONE != ret) { - LoggerW("Can't get double value form record: %d", ret); - throw common::UnknownException("Get int from record failed."); - } - - return value; -} - -void CalendarItem::SetCaltime(int type, calendar_record_h rec, - const std::string& property, - calendar_time_s value, bool throw_on_error) { - LoggerD("enter"); - - unsigned int prop = GetPlatformProperty(type, property); - - if (prop != -1u) { - SetCaltime(rec, prop, value, throw_on_error); - } -} - -void CalendarItem::SetCaltime(calendar_record_h rec, unsigned int property, - calendar_time_s value, bool throw_on_error) { - int ret = calendar_record_set_caltime(rec, property, value); - - if (CALENDAR_ERROR_NONE != ret) { - LoggerW("Can't set caltime value to record: %d", ret); - - if (throw_on_error) { - throw common::UnknownException("Set caltime to record failed."); - } - } -} - -calendar_time_s CalendarItem::GetCaltime(int type, calendar_record_h rec, - const std::string& property, - bool throw_on_error) { - LoggerD("get: %s", property.c_str()); - - unsigned int prop = GetPlatformProperty(type, property); - - return GetCaltime(rec, prop, throw_on_error); -} - -calendar_time_s CalendarItem::GetCaltime(calendar_record_h rec, - unsigned int property, - bool throw_on_error) { - calendar_time_s cal; - - if (property != -1u) { - int ret = calendar_record_get_caltime(rec, property, &cal); - if (CALENDAR_ERROR_NONE != ret) { - LoggerW("Can't get calendar_time value form record: %d", ret); - if (throw_on_error) { - throw common::UnknownException( - "Can't get calendar_time value form record"); - } - } - } - - return cal; -} - -void CalendarItem::SetLli(calendar_record_h rec, unsigned int property, - long long int value, bool throw_on_error) { - - int ret = calendar_record_set_lli(rec, property, value); - - if (CALENDAR_ERROR_NONE != ret) { - LoggerW("Can't set long long int value to record: %d", ret); - - if (throw_on_error) { - throw common::UnknownException("Set long long int to record failed."); - } - } -} - -long long int CalendarItem::GetLli(int type, calendar_record_h rec, - const std::string& property) { - LoggerD("get: %s", property.c_str()); - - return GetLli(rec, GetPlatformProperty(type, property)); -} - -long long int CalendarItem::GetLli(calendar_record_h rec, unsigned int property, - bool throw_on_error) { - long long int value; - int ret = calendar_record_get_lli(rec, property, &value); - if (CALENDAR_ERROR_NONE != ret) { - LoggerW("Can't get lli value form record: %d", ret); - if (throw_on_error) { - throw common::UnknownException("Get lli from record failed."); - } - } - - return value; -} - -Date CalendarItem::DateFromJson(const json::Object& in) { - LoggerD("json date %s", json::Value(in).serialize().c_str()); - - Date date = {(long long int)common::FromJson(in, "UTCTimestamp"), - (int)common::FromJson(in, "year"), - (int)common::FromJson(in, "month"), - (int)common::FromJson(in, "day"), - common::FromJson(in, "timezone")}; - - return date; -} - -Date CalendarItem::DateFromJson(const json::Object& in, const char* obj_name) { - return DateFromJson(common::FromJson(in, obj_name)); -} - -json::Value CalendarItem::DateToJson(Date date) { - LoggerD("timestamp: %lld", date.utc_timestamp_); - - json::Value date_val = json::Value(json::Object()); - json::Object& date_obj = date_val.get(); - - date_obj["UTCTimestamp"] = - json::Value(static_cast(date.utc_timestamp_)); - date_obj["year"] = json::Value(static_cast(date.year_)); - date_obj["month"] = json::Value(static_cast(date.month_)); - date_obj["day"] = json::Value(static_cast(date.day_)); - date_obj["timezone"] = json::Value(date.time_zone_); - - return date_val; -} - -void CalendarItem::CategoriesFromJson(int type, calendar_record_h rec, - const json::Array& value) { - std::string categories = ""; - for (auto iter = value.begin(); iter != value.end(); ++iter) { - if (iter == value.begin()) { - categories.append(iter->get().c_str()); - } else { - categories.append("," + iter->get()); - } - } - - SetString(type, rec, "categories", categories); -} - -json::Array CalendarItem::CategoriesToJson(int type, calendar_record_h rec) { - LoggerD("enter"); - - std::string categories = GetString(type, rec, "categories"); - - return StringToArray(categories); -} - -void CalendarItem::AttendeesFromJson(int type, calendar_record_h rec, - const json::Array& value) { - LoggerD("enter"); - - // Remove the preset child attendees before adding new ones. - unsigned int property; - if (type == CALENDAR_BOOK_TYPE_EVENT) { - property = _calendar_event.calendar_attendee; - } else { - property = _calendar_todo.calendar_attendee; - } - RemoveChildRecords(rec, property); - - calendar_record_h attendee; - for (auto& item : value) { - const json::Object& obj = JsonCast(item); - - int ret = calendar_record_create(_calendar_attendee._uri, &attendee); - if (CALENDAR_ERROR_NONE != ret) { - LoggerE("Fail to create attendee record, error code: %d", ret); - throw common::UnknownException("Fail to create attendee record"); - } - - CalendarRecord::SetString(attendee, _calendar_attendee.email, - common::FromJson(obj, "uri")); - - if (!IsNull(obj, "name")) { - CalendarRecord::SetString(attendee, _calendar_attendee.name, - common::FromJson(obj, "name")); - } - - SetEnum(attendee, _calendar_attendee.role, kAttendeeRole, - common::FromJson(obj, "role")); - - SetEnum(attendee, _calendar_attendee.status, kAttendeeStatus, - common::FromJson(obj, "status")); - - CalendarRecord::SetInt(attendee, _calendar_attendee.rsvp, - common::FromJson(obj, "RSVP")); - - SetEnum(attendee, _calendar_attendee.cutype, kAttendeeType, - common::FromJson(obj, "type")); - - if (!IsNull(obj, "group")) { - CalendarRecord::SetString(attendee, _calendar_attendee.group, - common::FromJson(obj, "group")); - } - if (!IsNull(obj, "delegatorURI")) { - CalendarRecord::SetString( - attendee, _calendar_attendee.delegator_uri, - common::FromJson(obj, "delegatorURI")); - } - if (!IsNull(obj, "delegateURI")) { - CalendarRecord::SetString( - attendee, _calendar_attendee.delegatee_uri, - common::FromJson(obj, "delegateURI")); - } - - if (!IsNull(obj, "contactRef")) { - CalendarRecord::SetString( - attendee, _calendar_attendee.uid, - common::FromJson(obj, "contactRef", "contactId")); - - const std::string& address_book = - common::FromJson(obj, "contactRef", "addressBookId"); - CalendarRecord::SetInt(attendee, _calendar_attendee.person_id, - common::stol(address_book)); - } else { - LoggerD("ContactRef not set"); - } - - AddChildRecord(rec, property, attendee); - } -} - -json::Array CalendarItem::AttendeesToJson(int type, calendar_record_h rec) { - LoggerD("enter"); - - json::Array out = json::Array(); - - unsigned int property; - if (type == CALENDAR_BOOK_TYPE_EVENT) { - property = _calendar_event.calendar_attendee; - } else { - property = _calendar_todo.calendar_attendee; - } - - unsigned int count = 0; - if (!(count = GetChildRecordCount(rec, property))) { - LoggerD("No attendees to set."); - return out; - } - - calendar_list_h list; - if (CALENDAR_ERROR_NONE != - calendar_record_clone_child_record_list(rec, property, &list)) { - LoggerE("Can't get attendee list"); - return out; - } - CalendarListPtr(list, CalendarRecord::ListDeleter); - - calendar_record_h attendee; - for (unsigned int i = 0; i < count; ++i) { - LoggerD("Processing the attendee %d", i); - - if (!GetChildRecordAt(rec, property, &attendee, i, false)) { - LoggerW("Can't get attendee record"); - continue; - } - - json::Value attendee_val = json::Value(json::Object()); - json::Object& attendee_obj = attendee_val.get(); - - attendee_obj["uri"] = json::Value( - CalendarRecord::GetString(attendee, _calendar_attendee.email, false)); - - attendee_obj["name"] = json::Value( - CalendarRecord::GetString(attendee, _calendar_attendee.name, false)); - - attendee_obj["role"] = - json::Value(GetEnum(attendee, _calendar_attendee.role, kAttendeeRole)); - - attendee_obj["status"] = json::Value( - GetEnum(attendee, _calendar_attendee.status, kAttendeeStatus)); - - attendee_obj["RSVP"] = json::Value( - (bool)CalendarRecord::GetInt(attendee, _calendar_attendee.rsvp, false)); - - attendee_obj["type"] = json::Value( - GetEnum(attendee, _calendar_attendee.cutype, kAttendeeType)); - - attendee_obj["group"] = json::Value( - CalendarRecord::GetString(attendee, _calendar_attendee.group, false)); - - attendee_obj["delegatorURI"] = json::Value(CalendarRecord::GetString( - attendee, _calendar_attendee.delegator_uri, false)); - - attendee_obj["delegateURI"] = json::Value(CalendarRecord::GetString( - attendee, _calendar_attendee.delegatee_uri, false)); - - // contactRef - const std::string& contact_id = - CalendarRecord::GetString(attendee, _calendar_attendee.uid, false); - int book_id = - CalendarRecord::GetInt(attendee, _calendar_attendee.person_id, false); - attendee_obj["contactRef"] = json::Value( - json::Object{{"contactId", json::Value(contact_id)}, - {"addressBookId", json::Value(std::to_string(book_id))}}); - - out.push_back(attendee_val); - } - - return out; -} - -void CalendarItem::AlarmsFromJson(int type, calendar_record_h rec, - const common::json::Array& alarms) { - LoggerD("enter"); - - unsigned int property; - if (type == CALENDAR_BOOK_TYPE_EVENT) { - property = _calendar_event.calendar_alarm; - } else { - property = _calendar_todo.calendar_alarm; - } - RemoveChildRecords(rec, property); - - calendar_record_h alarm; - for (auto& item : alarms) { - LoggerD("alarm: %s", item.serialize().c_str()); - const json::Object& obj = JsonCast(item); - - int ret = calendar_record_create(_calendar_alarm._uri, &alarm); - if (CALENDAR_ERROR_NONE != ret) { - LoggerE("Fail to create attendee record, error code: %d", ret); - throw common::UnknownException("Fail to create attendee record"); - } - - int tick_unit = CALENDAR_ALARM_TIME_UNIT_SPECIFIC; - if (!common::IsNull(obj, "absoluteDate")) { - Date absolute = DateFromJson(obj, "absoluteDate"); - calendar_time_s absolute_date = DateToPlatform(absolute, false); - SetLli(alarm, _calendar_alarm.time, absolute_date.time.utime); - CalendarRecord::SetInt(alarm, _calendar_alarm.tick_unit, tick_unit); - } - - if (!common::IsNull(obj, "before")) { - long long length = common::FromJson(obj, "before", "length"); - const std::string& unit = - common::FromJson(obj, "before", "unit"); - long long tick = 0; - if (kTimeDurationUnitMilliseconds == unit) { - tick_unit = - CALENDAR_ALARM_TIME_UNIT_MINUTE; // minimum calendar time unit. - tick = length / 60000; - } else if (kTimeDurationUnitSeconds == unit) { - tick_unit = CALENDAR_ALARM_TIME_UNIT_MINUTE; - tick = length / 60; - } else if (kTimeDurationUnitMinutes == unit) { - tick_unit = CALENDAR_ALARM_TIME_UNIT_MINUTE; - tick = length; - } else if (kTimeDurationUnitHours == unit) { - tick_unit = CALENDAR_ALARM_TIME_UNIT_HOUR; - tick = length; - } else if (kTimeDurationUnitDays == unit) { - tick_unit = CALENDAR_ALARM_TIME_UNIT_DAY; - tick = length; - } else { - LoggerW("Wrong alarm time unit: %s", unit.c_str()); - } - - CalendarRecord::SetInt(alarm, _calendar_alarm.tick, tick); - CalendarRecord::SetInt(alarm, _calendar_alarm.tick_unit, tick_unit); - } - - SetEnum(alarm, _calendar_alarm.action, kAlarmMethod, - common::FromJson(obj, "method")); - - CalendarRecord::SetString( - alarm, _calendar_alarm.description, - common::FromJson(obj, "description")); - - AddChildRecord(rec, property, alarm); - } -} - -json::Array CalendarItem::AlarmsToJson(int type, calendar_record_h rec) { - LoggerD("enter"); - - json::Array out = json::Array(); - - unsigned int property; - if (type == CALENDAR_BOOK_TYPE_EVENT) { - property = _calendar_event.calendar_alarm; - } else { - property = _calendar_todo.calendar_alarm; - } - - unsigned int count = 0; - if (!(count = GetChildRecordCount(rec, property))) { - LoggerD("No attendees to set."); - return out; - } - - calendar_list_h list; - if (CALENDAR_ERROR_NONE != - calendar_record_clone_child_record_list(rec, property, &list)) { - LoggerW("Can't get alarms list"); - return out; - } - CalendarListPtr(list, CalendarRecord::ListDeleter); - - int tick, tick_unit; - calendar_record_h alarm; - for (unsigned int i = 0; i < count; ++i) { - LoggerD("Processing the alarm %d", i); - - if (!GetChildRecordAt(rec, property, &alarm, i, false)) { - LoggerW("Can't get alarm record"); - continue; - } - - json::Value alarm_val = json::Value(json::Object()); - json::Object& alarm_obj = alarm_val.get(); - - tick_unit = CalendarRecord::GetInt(alarm, _calendar_alarm.tick_unit, false); - - if (tick_unit == CALENDAR_ALARM_TIME_UNIT_SPECIFIC) { - long long int time = GetLli(alarm, _calendar_alarm.time, false); - alarm_obj["absoluteDate"] = json::Value(static_cast(time)); - } else { - tick = CalendarRecord::GetInt(alarm, _calendar_alarm.tick, false); - - int length = 0; - std::string unit = kTimeDurationUnitSeconds; - if (CALENDAR_ALARM_TIME_UNIT_MINUTE == tick_unit) { - unit = kTimeDurationUnitMinutes; - length = tick; - } else if (CALENDAR_ALARM_TIME_UNIT_HOUR == tick_unit) { - unit = kTimeDurationUnitHours; - length = tick; - } else if (CALENDAR_ALARM_TIME_UNIT_DAY == tick_unit) { - unit = kTimeDurationUnitDays; - length = tick; - } else if (CALENDAR_ALARM_TIME_UNIT_WEEK == tick_unit) { - unit = kTimeDurationUnitDays; - length = tick * 7; - } else { - LoggerW("Wrong tick unit: %d", tick_unit); - } - - alarm_obj["before"] = json::Value( - json::Object{{"length", json::Value(static_cast(length))}, - {"unit", json::Value(unit)}}); - } - - alarm_obj["method"] = - json::Value(GetEnum(alarm, _calendar_alarm.action, kAlarmMethod)); - - alarm_obj["description"] = json::Value( - CalendarRecord::GetString(alarm, _calendar_alarm.description, false)); - - out.push_back(alarm_val); - } - - return out; -} - -void CalendarItem::RecurrenceRuleFromJson(calendar_record_h rec, - const json::Object& rrule) { - LoggerD("enter"); - - const std::string& frequency = - common::FromJson(rrule, "frequency"); - SetEnum(rec, _calendar_event.freq, kRecurrenceRuleFrequency, frequency); - - const unsigned short interval = common::FromJson(rrule, "interval"); - CalendarRecord::SetInt(rec, _calendar_event.interval, interval); - - const long occurrence_count = - common::FromJson(rrule, "occurrenceCount"); - if (-1 != occurrence_count) { - CalendarRecord::SetInt(rec, _calendar_event.count, occurrence_count); - CalendarRecord::SetInt(rec, _calendar_event.range_type, - CALENDAR_RANGE_COUNT); - } - - if (!common::IsNull(rrule, "untilDate")) { - Date until = DateFromJson(rrule, "untilDate"); - SetCaltime(rec, _calendar_event.until_time, DateToPlatform(until, false)); - CalendarRecord::SetInt(rec, _calendar_event.range_type, - CALENDAR_RANGE_UNTIL); - } - - const json::Array& byday_array = - common::FromJson(rrule, "daysOfTheWeek"); - std::string byday; - for (auto iter = byday_array.begin(); iter != byday_array.end(); ++iter) { - if (iter == byday_array.begin()) { - byday.append(iter->get()); - } else { - byday.append("," + iter->get()); - } - } - CalendarRecord::SetString(rec, _calendar_event.byday, byday); - - const json::Array& bysetpos_array = - common::FromJson(rrule, "setPositions"); - std::string bysetpos; - for (auto iter = bysetpos_array.begin(); iter != bysetpos_array.end(); - ++iter) { - if (iter == bysetpos_array.begin()) { - bysetpos.append(std::to_string((int)iter->get())); - } else { - bysetpos.append("," + iter->get()); - } - } - CalendarRecord::SetString(rec, _calendar_event.bysetpos, bysetpos); - - CalendarRecord::SetString( - rec, _calendar_event.exdate, - ExceptionsFromJson(common::FromJson(rrule, "exceptions"))); -} - -std::string CalendarItem::ExceptionsFromJson(const json::Array& exceptions) { - std::string result; - Date date; - for (auto iter = exceptions.begin(); iter != exceptions.end(); ++iter) { - date = DateFromJson(iter->get()); - calendar_time_s exception_date = DateToPlatform(date, false); - std::stringstream ss; - ss << exception_date.time.utime; - - if (iter == exceptions.begin()) { - result.append(ss.str()); - } else { - result.append("," + ss.str()); - } - } - - return result; -} - -json::Object CalendarItem::RecurrenceRuleToJson(calendar_record_h rec) { - LoggerD("enter"); - - json::Object out = json::Object(); - - out["frequency"] = - json::Value(GetEnum(rec, _calendar_event.freq, kRecurrenceRuleFrequency)); - - int interval = CalendarRecord::GetInt(rec, _calendar_event.interval, false); - out["interval"] = json::Value(static_cast(interval)); - - int occurrence_count = CalendarRecord::GetInt(rec, _calendar_event.count); - out["occurrenceCount"] = json::Value(static_cast(occurrence_count)); - - calendar_time_s cal = {CALENDAR_TIME_UTIME, {0}}; - calendar_record_get_caltime(rec, _calendar_event.until_time, &cal); - if (cal.time.utime > 0 && CALENDAR_RECORD_NO_UNTIL != cal.time.utime) { - Date until = {cal.time.utime, 0, 0, 0, ""}; - out["untilDate"] = DateToJson(until); - } else { - out["untilDate"] = json::Value(); - } - - out["daysOfTheWeek"] = json::Value( - StringToArray(CalendarRecord::GetString(rec, _calendar_event.byday))); - - out["setPositions"] = json::Value( - StringToArray(CalendarRecord::GetString(rec, _calendar_event.bysetpos))); - - const json::Array& exceptions = - StringToArray(CalendarRecord::GetString(rec, _calendar_event.exdate)); - json::Array dates = json::Array(); - for (auto& exception : exceptions) { - Date date = {common::stol(exception.get()), 0, 0, 0, ""}; - dates.push_back(DateToJson(date)); - } - out["exceptions"] = json::Value(dates); - - return out; -} - -calendar_time_s CalendarItem::DateToPlatform(const Date& date, - bool is_all_day) { - LoggerD("enter"); - - calendar_time_s cal; - - if (is_all_day) { - cal.type = CALENDAR_TIME_LOCALTIME; - cal.time.date = {date.year_, date.month_, date.day_}; - } else { - cal.type = CALENDAR_TIME_UTIME; - cal.time.utime = date.utc_timestamp_; - } - - return cal; -} - -Date CalendarItem::DateFromPlatform(int type, calendar_record_h rec, - const std::string& property) { - LoggerD("enter"); - - calendar_time_s cal = GetCaltime(type, rec, property + "_time"); - std::string tzid = GetString(type, rec, property + "_tzid"); - - Date date = {cal.time.utime, cal.time.date.year, cal.time.date.month, - cal.time.date.mday, tzid}; - - return date; -} - -Date CalendarItem::DateFromPlatform(calendar_record_h rec, - unsigned int property) { - LoggerD("enter"); - - calendar_time_s cal = GetCaltime(rec, property); - - Date date = {cal.time.utime, cal.time.date.year, cal.time.date.month, - cal.time.date.mday, ""}; - - return date; -} - -void CalendarItem::FromJson(int type, calendar_record_h rec, - const json::Object& in) { - LoggerD("enter"); - - if (in.empty()) { - LoggerE("Empty CalendarItem object."); - throw InvalidValuesException("Empty Calendar object."); - } - - SetString(type, rec, "description", in, true); - SetString(type, rec, "summary", in, true); - SetString(type, rec, "location", in, true); - SetString(type, rec, "organizer", in, true); - - int is_all_day = common::FromJson(in, "isAllDay"); - - if (!common::IsNull(in, "startDate")) { - Date start = DateFromJson(in, "startDate"); - - SetCaltime(type, rec, "startDate_time", DateToPlatform(start, is_all_day)); - SetString(type, rec, "startDate_tzid", start.time_zone_); - } - - const std::string& endProperty = - (type == CALENDAR_BOOK_TYPE_EVENT) ? "endDate" : "dueDate"; - if (!common::IsNull(in, endProperty.c_str())) { - Date end = DateFromJson(in, endProperty.c_str()); - - SetCaltime(type, rec, endProperty + "_time", - DateToPlatform(end, is_all_day)); - SetString(type, rec, endProperty + "_tzid", end.time_zone_); - } - - SetEnum(type, rec, "visibility", in, kItemVisibility); - - if (!common::IsNull(in, "geolocation")) { - SetDouble(type, rec, "latitude", - common::FromJson(in, "geolocation", "latitude")); - SetDouble(type, rec, "longitude", - common::FromJson(in, "geolocation", "longitude")); - } - - CategoriesFromJson(type, rec, - common::FromJson(in, "categories")); - AttendeesFromJson(type, rec, common::FromJson(in, "attendees")); - AlarmsFromJson(type, rec, common::FromJson(in, "alarms")); - - if (type == CALENDAR_BOOK_TYPE_EVENT) { - SetEnum(type, rec, "priority", in, kEventPriority); - SetEnum(type, rec, "status", in, kEventStatus); - SetEnum(type, rec, "availability", in, kEventAvailability); - - if (!common::IsNull(in, "recurrenceRule")) { - RecurrenceRuleFromJson( - rec, common::FromJson(in, "recurrenceRule")); - } - - } else { - SetEnum(type, rec, "priority", in, kTaskPriority); - SetEnum(type, rec, "status", in, kTaskStatus); - - if (!common::IsNull(in, "completedDate")) { - SetLli(rec, _calendar_todo.completed_time, - DateFromJson(in, "completedDate").utc_timestamp_); - } - SetInt(type, rec, "progress", in); - } -} - -void CalendarItem::ToJson(int type, calendar_record_h rec, - json::Object* out_ptr) { - LoggerD("enter"); - - if (NULL == rec) { - LoggerE("Calendar record is null"); - throw UnknownException("Calendar record is null"); - } - - json::Object& out = *out_ptr; - - int id = GetInt(type, rec, "id"); - - json::Value id_val; - if (type == CALENDAR_BOOK_TYPE_EVENT) { - id_val = json::Value(json::Object()); - json::Object& id_obj = id_val.get(); - - id_obj["uid"] = json::Value(std::to_string(id)); - const std::string& rid = GetString(type, rec, "recurrence_id"); - if (rid.length() > 0) { - id_obj["rid"] = json::Value(rid); - } else { - id_obj["rid"] = json::Value(); - } - } else { - id_val = json::Value(std::to_string(id)); - } - - out["id"] = id_val; - - int calendar_id = GetInt(type, rec, "calendar_id"); - out["calendarId"] = json::Value(std::to_string(calendar_id)); - - out["description"] = json::Value(GetString(type, rec, "description")); - out["summary"] = json::Value(GetString(type, rec, "summary")); - out["location"] = json::Value(GetString(type, rec, "location")); - out["organizer"] = json::Value(GetString(type, rec, "organizer")); - out["isAllDay"] = json::Value((bool)GetInt(type, rec, "isAllDay")); - - // startDate - out["startDate"] = DateToJson(DateFromPlatform(type, rec, "startDate")); - - // endDate / dueDate - const std::string& endProperty = - (type == CALENDAR_BOOK_TYPE_EVENT) ? "endDate" : "dueDate"; - out[endProperty] = DateToJson(DateFromPlatform(type, rec, endProperty)); - - out["lastModificationDate"] = json::Value( - static_cast(GetLli(type, rec, "lastModificationDate"))); - - out["geolocation"] = json::Value(json::Object( - {{"latitude", json::Value(GetDouble(type, rec, "latitude"))}, - {"longitude", json::Value(GetDouble(type, rec, "longitude"))}})); - - out["visibility"] = - json::Value(GetEnum(type, rec, "visibility", kItemVisibility)); - - out["attendees"] = json::Value(AttendeesToJson(type, rec)); - out["categories"] = json::Value(CategoriesToJson(type, rec)); - out["alarms"] = json::Value(AlarmsToJson(type, rec)); - - if (type == CALENDAR_BOOK_TYPE_EVENT) { - out["status"] = json::Value(GetEnum(type, rec, "status", kEventStatus)); - out["priority"] = - json::Value(GetEnum(type, rec, "priority", kEventPriority)); - out["availability"] = - json::Value(GetEnum(type, rec, "availability", kEventAvailability)); - out["recurrenceRule"] = json::Value(RecurrenceRuleToJson(rec)); - } else { - out["status"] = json::Value(GetEnum(type, rec, "status", kTaskStatus)); - out["priority"] = - json::Value(GetEnum(type, rec, "priority", kTaskPriority)); - - out["completedDate"] = json::Value( - static_cast(GetLli(rec, _calendar_todo.completed_time))); - out["progress"] = - json::Value(static_cast(GetInt(type, rec, "progress"))); - } -} - -json::Array CalendarItem::StringToArray(const std::string& string) { - json::Array out = json::Array(); - - char* cstr = new char[string.length() + 1]; - strcpy(cstr, string.c_str()); - - char* saveptr = NULL; - char* pch = strtok_r(cstr, ",", &saveptr); - - while (NULL != pch) { - out.push_back(json::Value(std::string(pch))); - pch = strtok_r(NULL, ",", &saveptr); - } - - delete[] cstr; - - return out; -} - -} // namespace calendar -} // namespace webapi diff --git a/src/calendar/calendar_item.h b/src/calendar/calendar_item.h index fc00620b..42b71fd9 100644 --- a/src/calendar/calendar_item.h +++ b/src/calendar/calendar_item.h @@ -14,17 +14,16 @@ * limitations under the License. */ -#ifndef WEBAPI_PLUGINS_CALENDAR_ITEM_H_ -#define WEBAPI_PLUGINS_CALENDAR_ITEM_H_ +#ifndef CALENDAR_CALENDAR_ITEM_H_ +#define CALENDAR_CALENDAR_ITEM_H_ #include #include "calendar_record.h" -#include "json-parser.h" +#include "common/picojson.h" -namespace webapi { +namespace extension { namespace calendar { - struct Date { long long int utc_timestamp_; int year_; @@ -52,7 +51,7 @@ class CalendarItem : public CalendarRecord { // string static void SetString(int type, calendar_record_h rec, const std::string& property, - const common::json::Object& in, bool optional = false); + const picojson::object& in, bool optional = false); static void SetString(int type, calendar_record_h rec, const std::string& property, const std::string& value); static std::string GetString(int type, calendar_record_h rec, @@ -61,7 +60,7 @@ class CalendarItem : public CalendarRecord { // int static void SetInt(int type, calendar_record_h rec, const std::string& property, - const common::json::Object& in, bool optional = false); + const picojson::object& in, bool optional = false); static void SetInt(int type, calendar_record_h rec, const std::string& property, int value); static int GetInt(int type, calendar_record_h rec, @@ -70,7 +69,7 @@ class CalendarItem : public CalendarRecord { // enum static void SetEnum(int type, calendar_record_h rec, const std::string& property, - const common::json::Object& in, + const picojson::object& in, const std::string& enum_name); static void SetEnum(calendar_record_h rec, unsigned int property, const std::string& enum_name, const std::string& value); @@ -109,40 +108,40 @@ class CalendarItem : public CalendarRecord { // conversions static void FromJson(int type, calendar_record_h record, - const common::json::Object& in); + const picojson::object& in); static void ToJson(int type, calendar_record_h record, - common::json::Object* out_ptr); + picojson::object* out_ptr); - static std::string ExceptionsFromJson(const common::json::Array& exceptions); + static std::string ExceptionsFromJson(const picojson::array& exceptions); private: // from JSON to platform - static Date DateFromJson(const common::json::Object& in); - static Date DateFromJson(const common::json::Object& in, + static Date DateFromJson(const picojson::object& in); + static Date DateFromJson(const picojson::object& in, const char* obj_name); static void CategoriesFromJson(int type, calendar_record_h rec, - const common::json::Array& value); + const picojson::array& value); static void AttendeesFromJson(int type, calendar_record_h rec, - const common::json::Array& value); + const picojson::array& value); static void AlarmsFromJson(int type, calendar_record_h rec, - const common::json::Array& alarms); + const picojson::array& alarms); static void RecurrenceRuleFromJson(calendar_record_h rec, - const common::json::Object& rrule); + const picojson::object& rrule); static calendar_time_s DateToPlatform(const Date& date, bool is_all_day); // from platform to JSON - static common::json::Value DateToJson(Date date); - static common::json::Array CategoriesToJson(int type, calendar_record_h rec); - static common::json::Array AttendeesToJson(int type, calendar_record_h rec); - static common::json::Array AlarmsToJson(int type, calendar_record_h rec); - static common::json::Object RecurrenceRuleToJson(calendar_record_h rec); + static picojson::value DateToJson(Date date); + static picojson::array CategoriesToJson(int type, calendar_record_h rec); + static picojson::array AttendeesToJson(int type, calendar_record_h rec); + static picojson::array AlarmsToJson(int type, calendar_record_h rec); + static picojson::object RecurrenceRuleToJson(calendar_record_h rec); static Date DateFromPlatform(int type, calendar_record_h rec, const std::string& property); static Date DateFromPlatform(calendar_record_h rec, unsigned int property); - static common::json::Array StringToArray(const std::string& string); + static picojson::array StringToArray(const std::string& string); static const PlatformPropertyMap platform_property_map_; static const PlatformEnumMap platform_enum_map_; @@ -153,4 +152,4 @@ class CalendarItem : public CalendarRecord { } // namespace calendar } // namespace webapi -#endif // WEBAPI_PLUGINS_CALENDAR_ITEM_H_ +#endif // CALENDAR_CALENDAR_ITEM_H_ diff --git a/src/calendar/calendar_manager.cc b/src/calendar/calendar_manager.cc new file mode 100644 index 00000000..b4651583 --- /dev/null +++ b/src/calendar/calendar_manager.cc @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "calendar_manager.h" +#include "calendar_record.h" +#include "calendar_privilege.h" + +#include +#include +#include +#include "calendar_record.h" + +#include "common/task-queue.h" +#include "common/converter.h" +#include "common/logger.h" + +namespace extension { +namespace calendar { + +namespace { +const int kUnifiedCalendardId = 0; +} + +using namespace common; + +inline void CheckReturn(int ret, const std::string& error_name) { + if (CALENDAR_ERROR_NONE != ret) { + LoggerE("%s : %d", error_name.c_str(), ret); + throw UnknownException(error_name); + } +} + +CalendarManager::CalendarManager() { + if (CALENDAR_ERROR_NONE == calendar_connect()) { + LoggerD("Calendar DB connected"); + is_connected_ = true; + } else { + LoggerE("Calendar DB connection failed"); + } +} + +CalendarManager::~CalendarManager() { + if (is_connected_) { + if (CALENDAR_ERROR_NONE == calendar_disconnect()) { + LoggerD("Calendar DB disconnected"); + } else { + LoggerE("Calendar DB disconnect failed"); + } + } +} + +CalendarManager& CalendarManager::GetInstance() { + static CalendarManager instance; + return instance; +} + +bool CalendarManager::IsConnected() { return is_connected_; } + +void CalendarManager::GetCalendars(const JsonObject& args, + JsonObject& out) { + LoggerD("enter"); + +// NativePlugin::CheckAccess(Privilege::kCalendarRead); + + if (!is_connected_) { + throw UnknownException("DB Connection failed."); + } + +// int callback_handle = NativePlugin::GetAsyncCallbackHandle(args); + + const std::string& type = FromJson(args, "type"); + + LoggerD("calendar type: %s", type.c_str()); + + auto get = [type](const std::shared_ptr & response)->void { + + JsonObject& response_obj = response->get(); + JsonValue result = JsonValue(JsonArray()); + JsonArray& array = result.get(); + + calendar_list_h list = NULL; + + try { + int ret = calendar_db_get_all_records(_calendar_book._uri, 0, 0, &list); + CheckReturn(ret, "Failed to get list"); + + int count = 0; + ret = calendar_list_get_count(list, &count); + CheckReturn(ret, "Failed to get list size"); + + LoggerD("Calendar list count: %d", count); + + ret = calendar_list_first(list); + CheckReturn(ret, "Failed to move list to the first position"); + + int current_calendar_type = CalendarRecord::TypeToInt(type); + calendar_record_h calendar = NULL; + int store_type; + + while (count-- > 0) { + ret = calendar_list_get_current_record_p(list, &calendar); + CheckReturn(ret, "Failed to get current record"); + + store_type = + CalendarRecord::GetInt(calendar, _calendar_book.store_type); + if (current_calendar_type != store_type) { + LoggerD("Different store type %d, requested: %d. Skipping...", + store_type, current_calendar_type); + calendar_list_next(list); + continue; + } + + array.push_back(JsonValue(JsonObject())); + + CalendarRecord::CalendarToJson(calendar, + &array.back().get()); + + calendar_list_next(list); + } + + if (list) { + calendar_list_destroy(list, true); + } + + // NativePlugin::ReportSuccess(result, response_obj); + } + catch (...) {//const BasePlatformException& e) { + if (list) { + calendar_list_destroy(list, false); + } + + // NativePlugin::ReportError(e, response_obj); + } + }; + +// auto get_response = [callback_handle](const std::shared_ptr & +// response)->void { +// wrt::common::NativeContext::GetInstance()->InvokeCallback( +// callback_handle, response->serialize()); +// }; + +// TaskQueue::GetInstance().Queue( +// get, get_response, +// std::shared_ptr(new JsonValue(JsonObject()))); + +// NativePlugin::ReportSuccess(out); +} + +void CalendarManager::GetCalendar(const JsonObject& args, JsonObject& out) { + LoggerD("enter"); + + // NativePlugin::CheckAccess(Privilege::kCalendarRead); + + if (!is_connected_) { + throw UnknownException("DB Connection failed."); + } + + int id = common::stol(FromJson(args, "id")); + + CalendarRecordPtr record_ptr = + CalendarRecord::GetById(id, _calendar_book._uri); + + int type = CalendarRecord::TypeToInt(FromJson(args, "type")); + int calendar_type = + CalendarRecord::GetInt(record_ptr.get(), _calendar_book.store_type); + if (type != calendar_type) { + LoggerD("Calendar type doesn't match requested type"); + throw NotFoundException("Calendar not found"); + } + + JsonValue result = JsonValue(JsonObject()); + + CalendarRecord::CalendarToJson(record_ptr.get(), &out); +// NativePlugin::ReportSuccess(result, out); +} + +void CalendarManager::AddCalendar(const JsonObject& args, JsonObject& out) { + LoggerD("enter"); + +// NativePlugin::CheckAccess(Privilege::kCalendarWrite); + + if (!is_connected_) { + throw UnknownException("DB Connection failed."); + } + + const JsonObject& calendar = FromJson(args, "calendar"); + + CalendarRecordPtr record_ptr = CalendarRecord::CreateCalendar(); + CalendarRecord::CalendarFromJson(record_ptr.get(), calendar); + + int ret, record_id; + ret = calendar_db_insert_record(record_ptr.get(), &record_id); + CheckReturn(ret, "Failed to insert calendar record into db"); + +// NativePlugin::ReportSuccess(JsonValue(static_cast(record_id)), out); +} + +void CalendarManager::RemoveCalendar(const JsonObject& args, + JsonObject& out) { + LoggerD("enter"); + +// NativePlugin::CheckAccess(Privilege::kCalendarWrite); + + if (!is_connected_) { + throw UnknownException("DB Connection failed."); + } + + int id = common::stol(FromJson(args, "id")); + + if (id == kUnifiedCalendardId) { + LoggerE("Unified calendar can not be deleted"); + throw InvalidValuesException("Unified calendar can not be deleted"); + } else if (id == DEFAULT_EVENT_CALENDAR_BOOK_ID) { + LoggerE("Default event calendar can not be deleted"); + throw InvalidValuesException("Default event calendar can not be deleted"); + } else if (id == DEFAULT_TODO_CALENDAR_BOOK_ID) { + LoggerE("Default todo calendar can not be deleted"); + throw InvalidValuesException("Default todo calendar can not be deleted"); + } + + int ret = calendar_db_delete_record(_calendar_book._uri, id); + CheckReturn(ret, "Failed to delete record from db"); + + // NativePlugin::ReportSuccess(out); +} +} +} diff --git a/src/calendar/calendar_manager.cpp b/src/calendar/calendar_manager.cpp deleted file mode 100644 index f79490ba..00000000 --- a/src/calendar/calendar_manager.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "calendar_manager.h" -#include "calendar_record.h" -#include "calendar_privilege.h" - -#include -#include -#include -#include - -#include "native-plugin.h" -#include "task-queue.h" -#include "converter.h" -#include "logger.h" - -namespace webapi { -namespace calendar { - -namespace { -const int kUnifiedCalendardId = 0; -} - -using namespace webapi::common; - -inline void CheckReturn(int ret, const std::string& error_name) { - if (CALENDAR_ERROR_NONE != ret) { - LoggerE("%s : %d", error_name.c_str(), ret); - throw UnknownException(error_name); - } -} - -CalendarManager::CalendarManager() { - if (CALENDAR_ERROR_NONE == calendar_connect()) { - LoggerD("Calendar DB connected"); - is_connected_ = true; - } else { - LoggerE("Calendar DB connection failed"); - } -} - -CalendarManager::~CalendarManager() { - if (is_connected_) { - if (CALENDAR_ERROR_NONE == calendar_disconnect()) { - LoggerD("Calendar DB disconnected"); - } else { - LoggerE("Calendar DB disconnect failed"); - } - } -} - -CalendarManager& CalendarManager::GetInstance() { - static CalendarManager instance; - return instance; -} - -bool CalendarManager::IsConnected() { return is_connected_; } - -void CalendarManager::GetCalendars(const json::Object& args, - json::Object& out) { - LoggerD("enter"); - - NativePlugin::CheckAccess(Privilege::kCalendarRead); - - if (!is_connected_) { - throw UnknownException("DB Connection failed."); - } - - int callback_handle = NativePlugin::GetAsyncCallbackHandle(args); - - const std::string& type = FromJson(args, "type"); - - LoggerD("calendar type: %s", type.c_str()); - - auto get = [type](const std::shared_ptr & response)->void { - - json::Object& response_obj = response->get(); - json::Value result = json::Value(json::Array()); - json::Array& array = result.get(); - - calendar_list_h list = NULL; - - try { - int ret = calendar_db_get_all_records(_calendar_book._uri, 0, 0, &list); - CheckReturn(ret, "Failed to get list"); - - int count = 0; - ret = calendar_list_get_count(list, &count); - CheckReturn(ret, "Failed to get list size"); - - LoggerD("Calendar list count: %d", count); - - ret = calendar_list_first(list); - CheckReturn(ret, "Failed to move list to the first position"); - - int current_calendar_type = CalendarRecord::TypeToInt(type); - calendar_record_h calendar = NULL; - int store_type; - - while (count-- > 0) { - ret = calendar_list_get_current_record_p(list, &calendar); - CheckReturn(ret, "Failed to get current record"); - - store_type = - CalendarRecord::GetInt(calendar, _calendar_book.store_type); - if (current_calendar_type != store_type) { - LoggerD("Different store type %d, requested: %d. Skipping...", - store_type, current_calendar_type); - calendar_list_next(list); - continue; - } - - array.push_back(json::Value(json::Object())); - - CalendarRecord::CalendarToJson(calendar, - &array.back().get()); - - calendar_list_next(list); - } - - if (list) { - calendar_list_destroy(list, true); - } - - NativePlugin::ReportSuccess(result, response_obj); - } - catch (const BasePlatformException& e) { - if (list) { - calendar_list_destroy(list, false); - } - - NativePlugin::ReportError(e, response_obj); - } - }; - - auto get_response = [callback_handle](const std::shared_ptr & - response)->void { - wrt::common::NativeContext::GetInstance()->InvokeCallback( - callback_handle, response->serialize()); - }; - - TaskQueue::GetInstance().Queue( - get, get_response, - std::shared_ptr(new json::Value(json::Object()))); - - NativePlugin::ReportSuccess(out); -} - -void CalendarManager::GetCalendar(const json::Object& args, json::Object& out) { - LoggerD("enter"); - - NativePlugin::CheckAccess(Privilege::kCalendarRead); - - if (!is_connected_) { - throw UnknownException("DB Connection failed."); - } - - int id = common::stol(FromJson(args, "id")); - - CalendarRecordPtr record_ptr = - CalendarRecord::GetById(id, _calendar_book._uri); - - int type = CalendarRecord::TypeToInt(FromJson(args, "type")); - int calendar_type = - CalendarRecord::GetInt(record_ptr.get(), _calendar_book.store_type); - if (type != calendar_type) { - LoggerD("Calendar type doesn't match requested type"); - throw NotFoundException("Calendar not found"); - } - - json::Value result = json::Value(json::Object()); - - CalendarRecord::CalendarToJson(record_ptr.get(), &result.get()); - - NativePlugin::ReportSuccess(result, out); -} - -void CalendarManager::AddCalendar(const json::Object& args, json::Object& out) { - LoggerD("enter"); - - NativePlugin::CheckAccess(Privilege::kCalendarWrite); - - if (!is_connected_) { - throw UnknownException("DB Connection failed."); - } - - const json::Object& calendar = FromJson(args, "calendar"); - - CalendarRecordPtr record_ptr = CalendarRecord::CreateCalendar(); - CalendarRecord::CalendarFromJson(record_ptr.get(), calendar); - - int ret, record_id; - ret = calendar_db_insert_record(record_ptr.get(), &record_id); - CheckReturn(ret, "Failed to insert calendar record into db"); - - NativePlugin::ReportSuccess(json::Value(static_cast(record_id)), out); -} - -void CalendarManager::RemoveCalendar(const json::Object& args, - json::Object& out) { - LoggerD("enter"); - - NativePlugin::CheckAccess(Privilege::kCalendarWrite); - - if (!is_connected_) { - throw UnknownException("DB Connection failed."); - } - - int id = common::stol(FromJson(args, "id")); - - if (id == kUnifiedCalendardId) { - LoggerE("Unified calendar can not be deleted"); - throw InvalidValuesException("Unified calendar can not be deleted"); - } else if (id == DEFAULT_EVENT_CALENDAR_BOOK_ID) { - LoggerE("Default event calendar can not be deleted"); - throw InvalidValuesException("Default event calendar can not be deleted"); - } else if (id == DEFAULT_TODO_CALENDAR_BOOK_ID) { - LoggerE("Default todo calendar can not be deleted"); - throw InvalidValuesException("Default todo calendar can not be deleted"); - } - - int ret = calendar_db_delete_record(_calendar_book._uri, id); - CheckReturn(ret, "Failed to delete record from db"); - - NativePlugin::ReportSuccess(out); -} -} -} diff --git a/src/calendar/calendar_manager.h b/src/calendar/calendar_manager.h index 20a9d6cc..26e7de02 100644 --- a/src/calendar/calendar_manager.h +++ b/src/calendar/calendar_manager.h @@ -14,14 +14,19 @@ * limitations under the License. */ -#ifndef WEBAPI_PLUGINS_CALENDAR_MANAGER_H_ -#define WEBAPI_PLUGINS_CALENDAR_MANAGER_H_ +#ifndef CALENDAR_CALENDAR_MANAGER_H_ +#define CALENDAR_CALENDAR_MANAGER_H_ -#include "json-parser.h" +#include "common/picojson.h" -namespace webapi { +namespace extension { namespace calendar { +typedef picojson::value JsonValue; +typedef picojson::object JsonObject; +typedef picojson::array JsonArray; +typedef std::string JsonString; + class CalendarManager { public: /** @@ -41,12 +46,12 @@ class CalendarManager { * {status: 'success', result: {calendarsArray}} * @endcode */ - void GetCalendars(const common::json::Object& args, - common::json::Object& out); - void GetCalendar(const common::json::Object& args, common::json::Object& out); - void AddCalendar(const common::json::Object& args, common::json::Object& out); - void RemoveCalendar(const common::json::Object& args, - common::json::Object& out); + void GetCalendars(const JsonObject& args, + JsonObject& out); + void GetCalendar(const JsonObject& args, JsonObject& out); + void AddCalendar(const JsonObject& args, JsonObject& out); + void RemoveCalendar(const JsonObject& args, + JsonObject& out); static CalendarManager& GetInstance(); virtual ~CalendarManager(); @@ -60,4 +65,4 @@ class CalendarManager { } // namespace calendar } // namespace webapi -#endif /* WEBAPI_PLUGINS_CALENDAR_MANAGER_H_ */ +#endif /* CALENDAR_CALENDAR_MANAGER_H_ */ diff --git a/src/calendar/calendar_plugin.cc b/src/calendar/calendar_plugin.cc new file mode 100644 index 00000000..14ee5e36 --- /dev/null +++ b/src/calendar/calendar_plugin.cc @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "native-plugin.h" +#include "calendar_manager.h" +#include "calendar.h" + +namespace webapi { +namespace calendar { + +using namespace webapi::common; + +class CalendarPlugin : public NativePlugin { + public: + CalendarPlugin(); + ~CalendarPlugin(); + virtual void OnLoad(); + + private: + CalendarManager* manager_; + Calendar* calendar_; +}; + +EXPORT_NATIVE_PLUGIN(webapi::calendar::CalendarPlugin); + +CalendarPlugin::CalendarPlugin() { + manager_ = &CalendarManager::GetInstance(); + calendar_ = &Calendar::GetInstance(); +} + +CalendarPlugin::~CalendarPlugin() { manager_ = nullptr; } + +void CalendarPlugin::OnLoad() { + using namespace std::placeholders; + + dispatcher_.AddFunction( + "CalendarManager_getCalendars", + std::bind(&CalendarManager::GetCalendars, manager_, _1, _2)); + + dispatcher_.AddFunction( + "CalendarManager_getCalendar", + std::bind(&CalendarManager::GetCalendar, manager_, _1, _2)); + + dispatcher_.AddFunction( + "CalendarManager_addCalendar", + std::bind(&CalendarManager::AddCalendar, manager_, _1, _2)); + + dispatcher_.AddFunction( + "CalendarManager_removeCalendar", + std::bind(&CalendarManager::RemoveCalendar, manager_, _1, _2)); + + dispatcher_.AddFunction("Calendar_get", + std::bind(&Calendar::Get, calendar_, _1, _2)); + + dispatcher_.AddFunction("Calendar_add", + std::bind(&Calendar::Add, calendar_, _1, _2)); + + dispatcher_.AddFunction("Calendar_addBatch", + std::bind(&Calendar::AddBatch, calendar_, _1, _2)); + + dispatcher_.AddFunction("Calendar_update", + std::bind(&Calendar::Update, calendar_, _1, _2)); + + dispatcher_.AddFunction("Calendar_updateBatch", + std::bind(&Calendar::UpdateBatch, calendar_, _1, _2)); + + dispatcher_.AddFunction("Calendar_remove", + std::bind(&Calendar::Remove, calendar_, _1, _2)); + + dispatcher_.AddFunction("Calendar_removeBatch", + std::bind(&Calendar::RemoveBatch, calendar_, _1, _2)); + + dispatcher_.AddFunction("Calendar_find", + std::bind(&Calendar::Find, calendar_, _1, _2)); + + dispatcher_.AddFunction( + "Calendar_addChangeListener", + std::bind(&Calendar::AddChangeListener, calendar_, _1, _2)); + + dispatcher_.AddFunction( + "Calendar_removeChangeListener", + std::bind(&Calendar::RemoveChangeListener, calendar_, _1, _2)); +} + +} // namespace calendar +} // namespace webapi diff --git a/src/calendar/calendar_plugin.cpp b/src/calendar/calendar_plugin.cpp deleted file mode 100644 index 14ee5e36..00000000 --- a/src/calendar/calendar_plugin.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "native-plugin.h" -#include "calendar_manager.h" -#include "calendar.h" - -namespace webapi { -namespace calendar { - -using namespace webapi::common; - -class CalendarPlugin : public NativePlugin { - public: - CalendarPlugin(); - ~CalendarPlugin(); - virtual void OnLoad(); - - private: - CalendarManager* manager_; - Calendar* calendar_; -}; - -EXPORT_NATIVE_PLUGIN(webapi::calendar::CalendarPlugin); - -CalendarPlugin::CalendarPlugin() { - manager_ = &CalendarManager::GetInstance(); - calendar_ = &Calendar::GetInstance(); -} - -CalendarPlugin::~CalendarPlugin() { manager_ = nullptr; } - -void CalendarPlugin::OnLoad() { - using namespace std::placeholders; - - dispatcher_.AddFunction( - "CalendarManager_getCalendars", - std::bind(&CalendarManager::GetCalendars, manager_, _1, _2)); - - dispatcher_.AddFunction( - "CalendarManager_getCalendar", - std::bind(&CalendarManager::GetCalendar, manager_, _1, _2)); - - dispatcher_.AddFunction( - "CalendarManager_addCalendar", - std::bind(&CalendarManager::AddCalendar, manager_, _1, _2)); - - dispatcher_.AddFunction( - "CalendarManager_removeCalendar", - std::bind(&CalendarManager::RemoveCalendar, manager_, _1, _2)); - - dispatcher_.AddFunction("Calendar_get", - std::bind(&Calendar::Get, calendar_, _1, _2)); - - dispatcher_.AddFunction("Calendar_add", - std::bind(&Calendar::Add, calendar_, _1, _2)); - - dispatcher_.AddFunction("Calendar_addBatch", - std::bind(&Calendar::AddBatch, calendar_, _1, _2)); - - dispatcher_.AddFunction("Calendar_update", - std::bind(&Calendar::Update, calendar_, _1, _2)); - - dispatcher_.AddFunction("Calendar_updateBatch", - std::bind(&Calendar::UpdateBatch, calendar_, _1, _2)); - - dispatcher_.AddFunction("Calendar_remove", - std::bind(&Calendar::Remove, calendar_, _1, _2)); - - dispatcher_.AddFunction("Calendar_removeBatch", - std::bind(&Calendar::RemoveBatch, calendar_, _1, _2)); - - dispatcher_.AddFunction("Calendar_find", - std::bind(&Calendar::Find, calendar_, _1, _2)); - - dispatcher_.AddFunction( - "Calendar_addChangeListener", - std::bind(&Calendar::AddChangeListener, calendar_, _1, _2)); - - dispatcher_.AddFunction( - "Calendar_removeChangeListener", - std::bind(&Calendar::RemoveChangeListener, calendar_, _1, _2)); -} - -} // namespace calendar -} // namespace webapi diff --git a/src/calendar/calendar_privilege.h b/src/calendar/calendar_privilege.h index 392da228..22d17bf9 100644 --- a/src/calendar/calendar_privilege.h +++ b/src/calendar/calendar_privilege.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef WEBAPI_PLUGINS_CALENDAR_PRIVILEGE_H__ -#define WEBAPI_PLUGINS_CALENDAR_PRIVILEGE_H__ +#ifndef CALENDAR_CALENDAR_PRIVILEGE_H__ +#define CALENDAR_CALENDAR_PRIVILEGE_H__ #include @@ -30,4 +30,4 @@ const std::string kCalendarWrite = "http://tizen.org/privilege/calendar.write"; } // namespace calendar } // namespace webapi -#endif // WEBAPI_PLUGINS_CALENDAR_PRIVILEGE_H__ +#endif // CALENDAR_CALENDAR_PRIVILEGE_H__ diff --git a/src/calendar/calendar_record.cc b/src/calendar/calendar_record.cc new file mode 100644 index 00000000..3a3cf4b0 --- /dev/null +++ b/src/calendar/calendar_record.cc @@ -0,0 +1,374 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "calendar_record.h" + +#include + +#include "common/logger.h" +//#include "common/platform-exception.h" +#include "common/converter.h" + +namespace extension { +namespace calendar { + +namespace { +const std::string kCalendarTypeEvent = "EVENT"; +const std::string kCalendarTypeTask = "TASK"; +} + +using namespace common; + +inline void CheckReturn(int ret, const std::string& error_name) { + if (CALENDAR_ERROR_NONE != ret) { + LoggerE("%s : %d", error_name.c_str(), ret); + throw UnknownException(error_name); + } +} + +void CalendarRecord::QueryDeleter(calendar_query_h handle) { + if (handle) { + if (CALENDAR_ERROR_NONE != calendar_query_destroy(handle)) { + LoggerW("calendar_query_destroy failed"); + } + } +} + +void CalendarRecord::Deleter(calendar_record_h handle) { + if (handle) { + if (CALENDAR_ERROR_NONE != calendar_record_destroy(handle, true)) { + LoggerW("calendar_record_destroy failed"); + } + } +} + +void CalendarRecord::ListDeleter(calendar_list_h handle) { + if (handle) { + if (CALENDAR_ERROR_NONE != calendar_list_destroy(handle, true)) { + LoggerW("calendar_list_destroy failed"); + } + } +} + +std::string CalendarRecord::GetString(calendar_record_h rec, + unsigned int property, + bool throw_on_error) { + char* value = NULL; + int ret = calendar_record_get_str(rec, property, &value); + if (CALENDAR_ERROR_NONE != ret) { + LoggerW("Can't get string value form record: %d", ret); + if (throw_on_error) { + throw UnknownException("Get string from record failed."); + } + } + + std::string str = ""; + if (value) { + str = std::string(value); + free(value); + } + + return str; +} + +void CalendarRecord::SetString(calendar_record_h record, unsigned int property, + const std::string& value, bool throw_on_error) { + LoggerD("enter"); + + int ret = calendar_record_set_str(record, property, + value.empty() ? NULL : value.c_str()); + + if (CALENDAR_ERROR_NONE != ret) { + LoggerW("Can't set string value to record: %d", ret); + + if (throw_on_error) { + throw UnknownException("Set string to record failed."); + } + } +} + +int CalendarRecord::GetInt(calendar_record_h rec, unsigned int property, + bool throw_on_error) { + int value; + int ret = calendar_record_get_int(rec, property, &value); + if (CALENDAR_ERROR_NONE != ret) { + LoggerW("Can't get int value form record: %d", ret); + if (throw_on_error) { + throw UnknownException("Get int from record failed."); + } + } + + return value; +} + +void CalendarRecord::SetInt(calendar_record_h record, unsigned int property, + int value, bool throw_on_error) { + LoggerD("enter"); + + int ret = calendar_record_set_int(record, property, value); + + if (CALENDAR_ERROR_NONE != ret) { + LoggerW("Can't set int value to record: %d", ret); + + if (throw_on_error) { + throw UnknownException("Set int to record failed."); + } + } +} + +std::string CalendarRecord::TypeToString(int type) { + if (CALENDAR_BOOK_TYPE_EVENT == type) { + return kCalendarTypeEvent; + } + + if (CALENDAR_BOOK_TYPE_TODO == type) { + return kCalendarTypeTask; + } + + return ""; +} + +std::string CalendarRecord::TypeToString(const char* view_uri) { + if (0 == strcmp(view_uri, _calendar_event._uri)) { + return kCalendarTypeEvent; + } + if (0 == strcmp(view_uri, _calendar_todo._uri)) { + return kCalendarTypeTask; + } + + return ""; +} + +int CalendarRecord::TypeToInt(const std::string& type) { + if (kCalendarTypeEvent == type) { + return CALENDAR_BOOK_TYPE_EVENT; + } + if (kCalendarTypeTask == type) { + return CALENDAR_BOOK_TYPE_TODO; + } + + return CALENDAR_BOOK_TYPE_NONE; +} + +int CalendarRecord::TypeToInt(const char* view_uri) { + if (0 == strcmp(view_uri, _calendar_event._uri)) { + return CALENDAR_BOOK_TYPE_EVENT; + } + if (0 == strcmp(view_uri, _calendar_todo._uri)) { + return CALENDAR_BOOK_TYPE_TODO; + } + + return CALENDAR_BOOK_TYPE_NONE; +} + +const char* CalendarRecord::TypeToUri(const std::string& type) { + if (kCalendarTypeEvent == type) { + return _calendar_event._uri; + } + if (kCalendarTypeTask == type) { + return _calendar_todo._uri; + } + + throw UnknownException("Undefined record type"); +} + +const char* CalendarRecord::TypeToUri(int type) { + if (CALENDAR_BOOK_TYPE_EVENT == type) { + return _calendar_event._uri; + } + + if (CALENDAR_BOOK_TYPE_TODO == type) { + return _calendar_todo._uri; + } + + throw UnknownException("Undefined record type"); +} + +CalendarRecordPtr CalendarRecord::Create(const char* view_uri) { + LoggerD("enter"); + + calendar_record_h handle = nullptr; + int ret = calendar_record_create(view_uri, &handle); + if (CALENDAR_ERROR_NONE != ret || nullptr == handle) { + LoggerE("Fail to create calendar record, error code: %d", ret); + throw NotFoundException("Fail to create calendar record"); + } + + return CalendarRecordPtr(handle, CalendarRecord::Deleter); +} + +CalendarRecordPtr CalendarRecord::CreateCalendar() { + LoggerD("enter"); + + return Create(_calendar_book._uri); +} + +CalendarRecordPtr CalendarRecord::GetById(int id, const char* view_uri) { + calendar_record_h handle = nullptr; + + int ret = calendar_db_get_record(view_uri, id, &handle); + if (CALENDAR_ERROR_NONE != ret || nullptr == handle) { + LoggerE("Fail to get calendar record %d for view %s, error code: %d", id, + view_uri, ret); + throw NotFoundException("Fail to get record with given id"); + } + + return CalendarRecordPtr(handle, CalendarRecord::Deleter); +} + +int CalendarRecord::Insert(calendar_record_h rec) { + LoggerD("enter"); + + int record_id; + int ret = calendar_db_insert_record(rec, &record_id); + + if (CALENDAR_ERROR_NONE != ret) { + LoggerE("Cannot insert record, error code: %d", ret); + throw NotFoundException("Cannot insert record"); + } + + return record_id; +} + +void CalendarRecord::AddChildRecord(calendar_record_h rec, + unsigned int property, + calendar_record_h child) { + LoggerD("enter"); + + int ret = calendar_record_add_child_record(rec, property, child); + if (CALENDAR_ERROR_NONE != ret) { + if (child) { + calendar_record_destroy(child, true); + } + LoggerE("Cannot add child record, error code: %d", ret); + throw NotFoundException("Cannot add child record"); + } +} + +void CalendarRecord::RemoveChildRecords(calendar_record_h rec, + unsigned int property_id) { + LoggerD("enter"); + + unsigned int count = 0; + + if (CALENDAR_ERROR_NONE != + calendar_record_get_child_record_count(rec, property_id, &count)) { + LoggerW("Can't get attendees count"); + } + + calendar_record_h attendee; + for (unsigned int i = 0; i < count; ++i) { + attendee = NULL; + // Be careful about the index. We always insert 0 cause the child + // list is updated every time we remove one= + + if (CALENDAR_ERROR_NONE != + calendar_record_get_child_record_at_p(rec, property_id, 0, &attendee)) { + LoggerW("Can't get the attendee"); + continue; + } + + if (CALENDAR_ERROR_NONE != + calendar_record_remove_child_record(rec, property_id, attendee)) { + LoggerW("Can't remove the attendee"); + continue; + } + } +} + +unsigned int CalendarRecord::GetChildRecordCount(calendar_record_h rec, + unsigned int property, + bool throw_on_error) { + unsigned int value; + int ret = calendar_record_get_child_record_count(rec, property, &value); + if (CALENDAR_ERROR_NONE != ret) { + LoggerW("Can't get child record count: %d", ret); + if (throw_on_error) { + throw UnknownException("Get child record count failed."); + } + } + + return value; +} + +bool CalendarRecord::GetChildRecordAt(calendar_record_h rec, + unsigned int property, + calendar_record_h* result, int index, + bool throw_on_error) { + int ret = calendar_record_get_child_record_at_p(rec, property, index, result); + if (CALENDAR_ERROR_NONE != ret) { + LoggerW("Can't get child record at: %d", ret); + if (throw_on_error) { + throw UnknownException("Get child record at failed."); + } + + return false; + } + + return true; +} + +void CalendarRecord::CalendarToJson(calendar_record_h rec, + picojson::object* out_ptr) { + picojson::object& out = *out_ptr; + + if (NULL == rec) { + LoggerE("Calendar record is null"); + throw UnknownException("Calendar record is null"); + } + + int id = GetInt(rec, _calendar_book.id); + int account_id = GetInt(rec, _calendar_book.account_id); + std::string name = GetString(rec, _calendar_book.name); + std::string type = TypeToString(GetInt(rec, _calendar_book.store_type)); + + out.insert(std::make_pair("id", picojson::value(std::to_string(id)))); + out.insert( + std::make_pair("accountId", picojson::value(std::to_string(account_id)))); + out.insert(std::make_pair("name", picojson::value(name))); + out.insert(std::make_pair("type", picojson::value(type))); +} + +void CalendarRecord::CalendarFromJson(calendar_record_h rec, + const picojson::object &in) { + if (in.empty()) { + LoggerE("Empty Calendar object."); + throw InvalidValuesException("Empty Calendar object."); + } + + const std::string& name = FromJson(in, "name"); + int account_id = static_cast(FromJson(in, "accountId")); + const std::string& type = FromJson(in, "type"); + + int store_type = 0; + if (kCalendarTypeEvent == type) { + store_type = CALENDAR_BOOK_TYPE_EVENT; + } else if (kCalendarTypeTask == type) { + store_type = CALENDAR_BOOK_TYPE_TODO; + } + + int ret = calendar_record_set_str(rec, _calendar_book.name, name.c_str()); + CheckReturn(ret, "Failed to set name"); + + ret = calendar_record_set_int(rec, _calendar_book.account_id, account_id); + CheckReturn(ret, "Failed to set account_id"); + + ret = calendar_record_set_int(rec, _calendar_book.store_type, store_type); + CheckReturn(ret, "Failed to set store_type"); +} + +} // namespace calendar +} // namespace webapi diff --git a/src/calendar/calendar_record.cpp b/src/calendar/calendar_record.cpp deleted file mode 100644 index f9a52c4b..00000000 --- a/src/calendar/calendar_record.cpp +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "calendar_record.h" - -#include - -#include "logger.h" -#include "platform-exception.h" -#include "converter.h" - -namespace webapi { -namespace calendar { - -namespace { -const std::string kCalendarTypeEvent = "EVENT"; -const std::string kCalendarTypeTask = "TASK"; -} - -using namespace webapi::common; - -inline void CheckReturn(int ret, const std::string& error_name) { - if (CALENDAR_ERROR_NONE != ret) { - LoggerE("%s : %d", error_name.c_str(), ret); - throw UnknownException(error_name); - } -} - -void CalendarRecord::QueryDeleter(calendar_query_h handle) { - if (handle) { - if (CALENDAR_ERROR_NONE != calendar_query_destroy(handle)) { - LoggerW("calendar_query_destroy failed"); - } - } -} - -void CalendarRecord::Deleter(calendar_record_h handle) { - if (handle) { - if (CALENDAR_ERROR_NONE != calendar_record_destroy(handle, true)) { - LoggerW("calendar_record_destroy failed"); - } - } -} - -void CalendarRecord::ListDeleter(calendar_list_h handle) { - if (handle) { - if (CALENDAR_ERROR_NONE != calendar_list_destroy(handle, true)) { - LoggerW("calendar_list_destroy failed"); - } - } -} - -std::string CalendarRecord::GetString(calendar_record_h rec, - unsigned int property, - bool throw_on_error) { - char* value = NULL; - int ret = calendar_record_get_str(rec, property, &value); - if (CALENDAR_ERROR_NONE != ret) { - LoggerW("Can't get string value form record: %d", ret); - if (throw_on_error) { - throw common::UnknownException("Get string from record failed."); - } - } - - std::string str = ""; - if (value) { - str = std::string(value); - free(value); - } - - return str; -} - -void CalendarRecord::SetString(calendar_record_h record, unsigned int property, - const std::string& value, bool throw_on_error) { - LoggerD("enter"); - - int ret = calendar_record_set_str(record, property, - value.empty() ? NULL : value.c_str()); - - if (CALENDAR_ERROR_NONE != ret) { - LoggerW("Can't set string value to record: %d", ret); - - if (throw_on_error) { - throw common::UnknownException("Set string to record failed."); - } - } -} - -int CalendarRecord::GetInt(calendar_record_h rec, unsigned int property, - bool throw_on_error) { - int value; - int ret = calendar_record_get_int(rec, property, &value); - if (CALENDAR_ERROR_NONE != ret) { - LoggerW("Can't get int value form record: %d", ret); - if (throw_on_error) { - throw common::UnknownException("Get int from record failed."); - } - } - - return value; -} - -void CalendarRecord::SetInt(calendar_record_h record, unsigned int property, - int value, bool throw_on_error) { - LoggerD("enter"); - - int ret = calendar_record_set_int(record, property, value); - - if (CALENDAR_ERROR_NONE != ret) { - LoggerW("Can't set int value to record: %d", ret); - - if (throw_on_error) { - throw common::UnknownException("Set int to record failed."); - } - } -} - -std::string CalendarRecord::TypeToString(int type) { - if (CALENDAR_BOOK_TYPE_EVENT == type) { - return kCalendarTypeEvent; - } - - if (CALENDAR_BOOK_TYPE_TODO == type) { - return kCalendarTypeTask; - } - - return ""; -} - -std::string CalendarRecord::TypeToString(const char* view_uri) { - if (0 == strcmp(view_uri, _calendar_event._uri)) { - return kCalendarTypeEvent; - } - if (0 == strcmp(view_uri, _calendar_todo._uri)) { - return kCalendarTypeTask; - } - - return ""; -} - -int CalendarRecord::TypeToInt(const std::string& type) { - if (kCalendarTypeEvent == type) { - return CALENDAR_BOOK_TYPE_EVENT; - } - if (kCalendarTypeTask == type) { - return CALENDAR_BOOK_TYPE_TODO; - } - - return CALENDAR_BOOK_TYPE_NONE; -} - -int CalendarRecord::TypeToInt(const char* view_uri) { - if (0 == strcmp(view_uri, _calendar_event._uri)) { - return CALENDAR_BOOK_TYPE_EVENT; - } - if (0 == strcmp(view_uri, _calendar_todo._uri)) { - return CALENDAR_BOOK_TYPE_TODO; - } - - return CALENDAR_BOOK_TYPE_NONE; -} - -const char* CalendarRecord::TypeToUri(const std::string& type) { - if (kCalendarTypeEvent == type) { - return _calendar_event._uri; - } - if (kCalendarTypeTask == type) { - return _calendar_todo._uri; - } - - throw common::UnknownException("Undefined record type"); -} - -const char* CalendarRecord::TypeToUri(int type) { - if (CALENDAR_BOOK_TYPE_EVENT == type) { - return _calendar_event._uri; - } - - if (CALENDAR_BOOK_TYPE_TODO == type) { - return _calendar_todo._uri; - } - - throw common::UnknownException("Undefined record type"); -} - -CalendarRecordPtr CalendarRecord::Create(const char* view_uri) { - LoggerD("enter"); - - calendar_record_h handle = nullptr; - int ret = calendar_record_create(view_uri, &handle); - if (CALENDAR_ERROR_NONE != ret || nullptr == handle) { - LoggerE("Fail to create calendar record, error code: %d", ret); - throw NotFoundException("Fail to create calendar record"); - } - - return CalendarRecordPtr(handle, CalendarRecord::Deleter); -} - -CalendarRecordPtr CalendarRecord::CreateCalendar() { - LoggerD("enter"); - - return Create(_calendar_book._uri); -} - -CalendarRecordPtr CalendarRecord::GetById(int id, const char* view_uri) { - calendar_record_h handle = nullptr; - - int ret = calendar_db_get_record(view_uri, id, &handle); - if (CALENDAR_ERROR_NONE != ret || nullptr == handle) { - LoggerE("Fail to get calendar record %d for view %s, error code: %d", id, - view_uri, ret); - throw NotFoundException("Fail to get record with given id"); - } - - return CalendarRecordPtr(handle, CalendarRecord::Deleter); -} - -int CalendarRecord::Insert(calendar_record_h rec) { - LoggerD("enter"); - - int record_id; - int ret = calendar_db_insert_record(rec, &record_id); - - if (CALENDAR_ERROR_NONE != ret) { - LoggerE("Cannot insert record, error code: %d", ret); - throw NotFoundException("Cannot insert record"); - } - - return record_id; -} - -void CalendarRecord::AddChildRecord(calendar_record_h rec, - unsigned int property, - calendar_record_h child) { - LoggerD("enter"); - - int ret = calendar_record_add_child_record(rec, property, child); - if (CALENDAR_ERROR_NONE != ret) { - if (child) { - calendar_record_destroy(child, true); - } - LoggerE("Cannot add child record, error code: %d", ret); - throw NotFoundException("Cannot add child record"); - } -} - -void CalendarRecord::RemoveChildRecords(calendar_record_h rec, - unsigned int property_id) { - LoggerD("enter"); - - unsigned int count = 0; - - if (CALENDAR_ERROR_NONE != - calendar_record_get_child_record_count(rec, property_id, &count)) { - LoggerW("Can't get attendees count"); - } - - calendar_record_h attendee; - for (unsigned int i = 0; i < count; ++i) { - attendee = NULL; - // Be careful about the index. We always insert 0 cause the child - // list is updated every time we remove one= - - if (CALENDAR_ERROR_NONE != - calendar_record_get_child_record_at_p(rec, property_id, 0, &attendee)) { - LoggerW("Can't get the attendee"); - continue; - } - - if (CALENDAR_ERROR_NONE != - calendar_record_remove_child_record(rec, property_id, attendee)) { - LoggerW("Can't remove the attendee"); - continue; - } - } -} - -unsigned int CalendarRecord::GetChildRecordCount(calendar_record_h rec, - unsigned int property, - bool throw_on_error) { - unsigned int value; - int ret = calendar_record_get_child_record_count(rec, property, &value); - if (CALENDAR_ERROR_NONE != ret) { - LoggerW("Can't get child record count: %d", ret); - if (throw_on_error) { - throw common::UnknownException("Get child record count failed."); - } - } - - return value; -} - -bool CalendarRecord::GetChildRecordAt(calendar_record_h rec, - unsigned int property, - calendar_record_h* result, int index, - bool throw_on_error) { - int ret = calendar_record_get_child_record_at_p(rec, property, index, result); - if (CALENDAR_ERROR_NONE != ret) { - LoggerW("Can't get child record at: %d", ret); - if (throw_on_error) { - throw common::UnknownException("Get child record at failed."); - } - - return false; - } - - return true; -} - -void CalendarRecord::CalendarToJson(calendar_record_h rec, - json::Object* out_ptr) { - json::Object& out = *out_ptr; - - if (NULL == rec) { - LoggerE("Calendar record is null"); - throw UnknownException("Calendar record is null"); - } - - int id = GetInt(rec, _calendar_book.id); - int account_id = GetInt(rec, _calendar_book.account_id); - std::string name = GetString(rec, _calendar_book.name); - std::string type = TypeToString(GetInt(rec, _calendar_book.store_type)); - - out.insert(std::make_pair("id", json::Value(std::to_string(id)))); - out.insert( - std::make_pair("accountId", json::Value(std::to_string(account_id)))); - out.insert(std::make_pair("name", json::Value(name))); - out.insert(std::make_pair("type", json::Value(type))); -} - -void CalendarRecord::CalendarFromJson(calendar_record_h rec, - const json::Object& in) { - if (in.empty()) { - LoggerE("Empty Calendar object."); - throw InvalidValuesException("Empty Calendar object."); - } - - const std::string& name = FromJson(in, "name"); - int account_id = static_cast(FromJson(in, "accountId")); - const std::string& type = FromJson(in, "type"); - - int store_type = 0; - if (kCalendarTypeEvent == type) { - store_type = CALENDAR_BOOK_TYPE_EVENT; - } else if (kCalendarTypeTask == type) { - store_type = CALENDAR_BOOK_TYPE_TODO; - } - - int ret = calendar_record_set_str(rec, _calendar_book.name, name.c_str()); - CheckReturn(ret, "Failed to set name"); - - ret = calendar_record_set_int(rec, _calendar_book.account_id, account_id); - CheckReturn(ret, "Failed to set account_id"); - - ret = calendar_record_set_int(rec, _calendar_book.store_type, store_type); - CheckReturn(ret, "Failed to set store_type"); -} - -} // namespace calendar -} // namespace webapi diff --git a/src/calendar/calendar_record.h b/src/calendar/calendar_record.h index 000246f4..c4809059 100644 --- a/src/calendar/calendar_record.h +++ b/src/calendar/calendar_record.h @@ -22,9 +22,8 @@ #include #include -#include "json-parser.h" - -namespace webapi { +#include "common/picojson.h" +namespace extension { namespace calendar { typedef std::unique_ptr::type, @@ -77,9 +76,9 @@ class CalendarRecord { static CalendarRecordPtr CreateCalendar(); static void CalendarToJson(calendar_record_h rec, - common::json::Object* out_ptr); + picojson::object* out_ptr); static void CalendarFromJson(calendar_record_h rec, - const common::json::Object& in); + const picojson::object& in); }; } // namespace calendar