Fixed update instance
[framework/osp/social.git] / src / FScl_RecurrenceImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 /**
18  * @file                FScl_RecurrenceImpl.cpp
19  * @brief               This is the implementation for _RecurrenceImpl class.
20  *
21  * This file contains definitions of @e _RecurrenceImpl class.
22  */
23
24 #include <new>
25 #include <FBaseColIList.h>
26 #include <FBaseColArrayList.h>
27 #include <FBaseDateTime.h>
28 #include <FSclRecurrence.h>
29 #include <FBaseSysLog.h>
30 #include <FApp_AppInfo.h>
31 #include "FScl_RecurrenceImpl.h"
32 #include "FScl_CalendarbookImpl.h"
33 #include "FScl_CalendarbookUtil.h"
34
35 using namespace Tizen::Base;
36 using namespace Tizen::Base::Collection;
37 using namespace Tizen::App;
38
39 namespace Tizen { namespace Social
40 {
41
42 static const RecurFrequency _DEFAULT_RECURRENCE_TYPE = FREQ_DAILY;
43 static const int _DEFAULT_INTERVAL = 1;
44 static const int _DEFAULT_COUNT = 1;
45 static const CalDayOfWeek _DEFAULT_WEEK_START = CAL_MONDAY;
46 static const int _WEEK_ONE = 1;
47 static const int _WEEK_FIVE = 5;
48 static const int _MONTH_ONE = 1;
49 static const int _MONTH_TWELVE = 12;
50 static const int _DAY_ONE = 1;
51 static const int _DAY_THIRTY_ONE = 31;
52 static const int _MIN_RECURRENCE_INTERVAL = 1;
53 static const int _MAX_DAY_OF_WEEK = 0x7F;
54
55 _RecurrenceImpl::_RecurrenceImpl(void)
56         : __type(_DEFAULT_RECURRENCE_TYPE)
57         , __interval(_DEFAULT_INTERVAL)
58         , __pUntil(null)
59         , __count(_DEFAULT_COUNT)
60         , __weekStart(_DEFAULT_WEEK_START)
61         , __dayOfWeek(0)
62         , __dayOfMonth(0)
63         , __weekOfMonth(0)
64         , __monthOfYear(0)
65 {
66         std::unique_ptr<ArrayList, AllElementsDeleter> pExceptionDates(new (std::nothrow) ArrayList());
67         SysTryReturnVoidResult(NID_SCL, pExceptionDates, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
68
69         result r = pExceptionDates->Construct();
70         SysTryReturnVoidResult(NID_SCL, !IsFailed(r), r, "[%s] Propagating.", GetErrorMessage(r));
71
72         __pExceptionDates = std::move(pExceptionDates);
73 }
74
75 _RecurrenceImpl::_RecurrenceImpl(const _RecurrenceImpl& rhs)
76         : __type(rhs.__type)
77         , __interval(rhs.__interval)
78         , __pUntil(null)
79         , __count(rhs.__count)
80         , __weekStart(rhs.__weekStart)
81         , __dayOfWeek(rhs.__dayOfWeek)
82         , __dayOfMonth(rhs.__dayOfMonth)
83         , __weekOfMonth(rhs.__weekOfMonth)
84         , __monthOfYear(rhs.__monthOfYear)
85         , __pExceptionDates(null)
86 {
87         std::unique_ptr<Tizen::Base::DateTime> pUntil;
88
89         if (rhs.__pUntil != null)
90         {
91                 pUntil = std::unique_ptr<Tizen::Base::DateTime>(new (std::nothrow) DateTime(*rhs.__pUntil));
92                 SysTryReturnVoidResult(NID_SCL, pUntil != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
93         }
94
95         std::unique_ptr<ArrayList, AllElementsDeleter> pExceptionDates(new (std::nothrow) ArrayList());
96         SysTryReturnVoidResult(NID_SCL, pExceptionDates, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
97
98         result r = pExceptionDates->Construct();
99         SysTryReturnVoidResult(NID_SCL, !IsFailed(r), r, "[%s] Propagating.", GetErrorMessage(r));
100
101         if (rhs.__pExceptionDates != null)
102         {
103                 DateTime* pTmpExDate = null;
104                 std::unique_ptr<IEnumerator> pEnum(rhs.__pExceptionDates->GetEnumeratorN());
105                 while (pEnum->MoveNext() == E_SUCCESS)
106                 {
107                         pTmpExDate = static_cast<DateTime*>(pEnum->GetCurrent());
108                         pExceptionDates->Add(*(new (std::nothrow) DateTime(*pTmpExDate)));
109                 }
110         }
111
112         __pExceptionDates = std::move(pExceptionDates);
113         __pUntil = std::move(pUntil);
114 }
115
116 _RecurrenceImpl::~_RecurrenceImpl(void)
117 {
118 }
119
120 _RecurrenceImpl&
121 _RecurrenceImpl::operator =(const _RecurrenceImpl& rhs)
122 {
123         if (this == &rhs)
124         {
125                 return *this;
126         }
127
128         std::unique_ptr<Tizen::Base::DateTime> pUntil;
129
130         __type = rhs.__type;
131         __interval = rhs.__interval;
132         __count = rhs.__count;
133         __weekStart = rhs.__weekStart;
134         __dayOfWeek = rhs.__dayOfWeek;
135         __dayOfMonth = rhs.__dayOfMonth;
136         __weekOfMonth = rhs.__weekOfMonth;
137         __monthOfYear = rhs.__monthOfYear;
138
139         if (rhs.__pUntil != null)
140         {
141                 pUntil.reset(new (std::nothrow) DateTime(*(rhs.__pUntil)));
142                 SysTryReturn(NID_SCL, pUntil != null, *this, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
143         }
144
145         if (__pExceptionDates != null && rhs.__pExceptionDates != null)
146         {
147                 __pExceptionDates->RemoveAll(true);
148
149                 DateTime* pTmpExDate = null;
150                 std::unique_ptr<IEnumerator> pEnum(rhs.__pExceptionDates->GetEnumeratorN());
151                 while (pEnum->MoveNext() == E_SUCCESS)
152                 {
153                         pTmpExDate = static_cast<DateTime*>(pEnum->GetCurrent());
154                         __pExceptionDates->Add(*(new (std::nothrow) DateTime(*pTmpExDate)));
155                 }
156         }
157
158         __pUntil = std::move(pUntil);
159
160         return *this;
161 }
162
163 bool
164 _RecurrenceImpl::Equals(const Object& rhs) const
165 {
166         const _RecurrenceImpl* pRecurrenceImpl = dynamic_cast<const _RecurrenceImpl*>(&rhs);
167
168         if (pRecurrenceImpl == null)
169         {
170                 return false;
171         }
172
173         return (__type == pRecurrenceImpl->__type && __interval == pRecurrenceImpl->__interval
174                         && __count == pRecurrenceImpl->__count && __weekStart == pRecurrenceImpl->__weekStart
175                         && __dayOfWeek == pRecurrenceImpl->__dayOfWeek && __dayOfMonth == pRecurrenceImpl->__dayOfMonth
176                         && __weekOfMonth == pRecurrenceImpl->__weekOfMonth && __monthOfYear == pRecurrenceImpl->__monthOfYear);
177 }
178
179 int
180 _RecurrenceImpl::GetHashCode(void) const
181 {
182         int hashCode = 17;
183
184         hashCode = ( hashCode << 4 ) ^ ( hashCode >> 28 ) ^ __type;
185         hashCode = ( hashCode << 4 ) ^ ( hashCode >> 28 ) ^ __interval;
186         hashCode = ( hashCode << 4 ) ^ ( hashCode >> 28 ) ^ __count;
187         hashCode = ( hashCode << 4 ) ^ ( hashCode >> 28 ) ^ __weekStart;
188         hashCode = ( hashCode << 4 ) ^ ( hashCode >> 28 ) ^ __dayOfWeek;
189         hashCode = ( hashCode << 4 ) ^ ( hashCode >> 28 ) ^ __dayOfMonth;
190         hashCode = ( hashCode << 4 ) ^ ( hashCode >> 28 ) ^ __weekOfMonth;
191         hashCode = ( hashCode << 4 ) ^ ( hashCode >> 28 ) ^ __monthOfYear;
192
193         DateTime* pTmpExDate = null;
194         std::unique_ptr<IEnumerator> pEnum(__pExceptionDates->GetEnumeratorN());
195         while (pEnum->MoveNext() == E_SUCCESS)
196         {
197                 pTmpExDate = static_cast<DateTime*>(pEnum->GetCurrent());
198                 hashCode = ( hashCode << 4 ) ^ ( hashCode >> 28 ) ^ pTmpExDate->GetHashCode();
199         }
200
201         return hashCode;
202 }
203
204 RecurFrequency
205 _RecurrenceImpl::GetFrequency(void) const
206 {
207         return __type;
208 }
209
210 int
211 _RecurrenceImpl::GetInterval(void) const
212 {
213         return __interval;
214 }
215
216 const DateTime*
217 _RecurrenceImpl::GetUntil(void) const
218 {
219         return __pUntil.get();
220 }
221
222 int
223 _RecurrenceImpl::GetCounts(void) const
224 {
225         return __count;
226 }
227
228 CalDayOfWeek
229 _RecurrenceImpl::GetWeekStart(void) const
230 {
231         return __weekStart;
232 }
233
234 int
235 _RecurrenceImpl::GetDayOfWeek(void) const
236 {
237         return __dayOfWeek;
238 }
239
240 int
241 _RecurrenceImpl::GetDayOfMonth(void) const
242 {
243         return __dayOfMonth;
244 }
245
246 int
247 _RecurrenceImpl::GetWeekOfMonth(void) const
248 {
249         return __weekOfMonth;
250 }
251
252 int
253 _RecurrenceImpl::GetMonthOfYear(void)const
254 {
255         return __monthOfYear;
256 }
257
258 void
259 _RecurrenceImpl::SetFrequency(RecurFrequency type)
260 {
261         __type = type;
262
263         // reset all properties
264         if (__pUntil != null)
265         {
266                 __pUntil.release();
267         }
268
269         __dayOfWeek = 0;
270         __dayOfMonth = 0;
271         __weekOfMonth = 0;
272         __monthOfYear = 0;
273         __interval = _DEFAULT_INTERVAL;
274         __count = _DEFAULT_COUNT;
275         __weekStart = _DEFAULT_WEEK_START;
276
277         __pExceptionDates->RemoveAll(true);
278 }
279
280 result
281 _RecurrenceImpl::SetInterval(int interval)
282 {
283         SysTryReturnResult(NID_SCL, interval >= _MIN_RECURRENCE_INTERVAL, E_INVALID_ARG, "Invalid argument is used. The interval is less than 1");
284
285         if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
286         {
287                 SysTryReturnResult(NID_SCL, interval <= MAX_RECURRENCE_INTERVAL_VALUE, E_INVALID_ARG
288                                 , "The inverval exceeds MAX_RECURRENCE_INTERVAL_VALUE");
289         }
290
291         __interval = interval;
292
293         // reset exception dates
294         __pExceptionDates->RemoveAll(true);
295
296         return E_SUCCESS;
297 }
298
299 result
300 _RecurrenceImpl::SetUntil(const DateTime* pUntil)
301 {
302         if (pUntil != null)
303         {
304                 SysTryReturnResult(NID_SCL, (_CalendarbookUtil::CheckValidDateTime(*pUntil) == true) || (*pUntil == DateTime::GetMaxValue()), E_INVALID_ARG, "Invalid argument is used. The until date is invalid.");
305
306                 __pUntil.reset(new (std::nothrow) DateTime(*pUntil));
307                 if (__pUntil == null)
308                 {
309                         SysLogException(NID_SCL, E_OUT_OF_MEMORY, "Memory allocation failed.");
310                         return E_OUT_OF_MEMORY;
311                 }
312
313                 // reset count
314                 __count = 0;
315         }
316         else
317         {
318                 __pUntil.release();
319                 __count = _DEFAULT_COUNT;
320         }
321
322         // reset exception dates
323         __pExceptionDates->RemoveAll(true);
324
325         return E_SUCCESS;
326 }
327
328 result
329 _RecurrenceImpl::SetCounts(int count)
330 {
331         SysTryReturnResult(NID_SCL, count >= 0, E_INVALID_ARG, "Invalid argument is used. The count is less than 0");
332
333         __count = count;
334
335         // reset until
336         if (__pUntil != null)
337         {
338                 __pUntil.release();
339         }
340
341         // reset exception dates
342         __pExceptionDates->RemoveAll(true);
343
344         return E_SUCCESS;
345 }
346
347 result
348 _RecurrenceImpl::SetWeekStart(CalDayOfWeek weekStart)
349 {
350         SysTryReturnResult(NID_SCL, weekStart == CAL_SUNDAY || weekStart == CAL_MONDAY, E_INVALID_ARG,
351                         "Invalid argument is used. weekStart = %d", weekStart);
352
353         __weekStart = weekStart;
354
355         // reset exception dates
356         __pExceptionDates->RemoveAll(true);
357
358         return E_SUCCESS;
359 }
360
361 result
362 _RecurrenceImpl::SetDayOfWeek(int day)
363 {
364         SysTryReturnResult(NID_SCL, __type != FREQ_DAILY, E_TYPE_MISMATCH,
365                                 "The frequency type is daily. It should be WEEKLY ,MOTHLY or YEARLY");
366         SysTryReturnResult(NID_SCL, day >= CAL_SUNDAY, E_INVALID_ARG, "Invalid argument is used. The day(%d) is less than min value.", day);
367         SysTryReturnResult(NID_SCL, day <= _MAX_DAY_OF_WEEK, E_INVALID_ARG, "Invalid argument is used. The day(%d) exceeds max value.", day);
368
369         __dayOfWeek = day;
370
371         // reset day of month
372         __dayOfMonth = 0;
373
374         // reset exception dates
375         __pExceptionDates->RemoveAll(true);
376
377         return E_SUCCESS;
378 }
379
380 result
381 _RecurrenceImpl::SetDayOfMonth(int day)
382 {
383         SysTryReturnResult(NID_SCL, __type != FREQ_DAILY, E_TYPE_MISMATCH, "The frequency is daily.");
384         SysTryReturnResult(NID_SCL, __type != FREQ_WEEKLY, E_TYPE_MISMATCH, "The frequency is weekly.");
385         SysTryReturnResult(NID_SCL, day >= _DAY_ONE, E_INVALID_ARG, "Invalid argument is used. The day is less than 1");
386         SysTryReturnResult(NID_SCL, day <= _DAY_THIRTY_ONE, E_INVALID_ARG, "Invalid argument is used. The day is greater than 31");
387
388         __dayOfMonth = day;
389
390         // reset day of week and week of month
391         __dayOfWeek = 0;
392         __weekOfMonth = 0;
393
394         // reset exception dates
395         __pExceptionDates->RemoveAll(true);
396
397         return E_SUCCESS;
398 }
399
400 result
401 _RecurrenceImpl::SetWeekOfMonth(int week)
402 {
403         SysTryReturnResult(NID_SCL, __type != FREQ_DAILY, E_TYPE_MISMATCH, "The frequency is daily.");
404         SysTryReturnResult(NID_SCL, __type != FREQ_WEEKLY, E_TYPE_MISMATCH, "The frequency is weekly.");
405         SysTryReturnResult(NID_SCL, week >= _WEEK_ONE, E_INVALID_ARG, "Invalid argument is used. The week (%d) is less than 1.", week);
406         SysTryReturnResult(NID_SCL, week <= _WEEK_FIVE, E_INVALID_ARG, "Invalid argument is used. The week (%d) is greater than 5.", week);
407
408         __weekOfMonth = week;
409
410         // reset day of month
411         __dayOfMonth = 0;
412
413         // reset exception dates
414         __pExceptionDates->RemoveAll(true);
415
416         return E_SUCCESS;
417 }
418
419
420 result
421 _RecurrenceImpl::SetMonthOfYear(int month)
422 {
423         SysTryReturnResult(NID_SCL, __type != FREQ_DAILY, E_TYPE_MISMATCH, "The frequency is daily.");
424         SysTryReturnResult(NID_SCL, __type != FREQ_WEEKLY, E_TYPE_MISMATCH, "The frequency is weekly.");
425         SysTryReturnResult(NID_SCL, __type != FREQ_MONTHLY, E_TYPE_MISMATCH, "The frequency is monthly.");
426         SysTryReturnResult(NID_SCL, month >= _MONTH_ONE, E_INVALID_ARG, "Invalid argument is used. The month (%d) is less than 1 ", month);
427         SysTryReturnResult(NID_SCL, month <= _MONTH_TWELVE, E_INVALID_ARG, "Invalid argument is used. The month (%d) is greater than 12", month);
428
429         __monthOfYear = month;
430
431         // reset exception dates
432         __pExceptionDates->RemoveAll(true);
433
434         return E_SUCCESS;
435 }
436
437 result
438 _RecurrenceImpl::AddExceptionDate(const DateTime& exceptionDate)
439 {
440         SysTryReturnResult(NID_SCL, exceptionDate >= _CalendarbookImpl::GetMinDateTime() &&
441                         exceptionDate <= _CalendarbookImpl::GetMaxDateTime(), E_INVALID_ARG, "Invalid argument is used. exceptionDate = %S", exceptionDate.ToString().GetPointer());
442
443         bool alreadyExist = false;
444
445         DateTime* pTmpExDate = null;
446         std::unique_ptr<IEnumerator> pEnum(__pExceptionDates->GetEnumeratorN());
447         while (pEnum->MoveNext() == E_SUCCESS)
448         {
449                 pTmpExDate = static_cast<DateTime*>(pEnum->GetCurrent());
450                 if (*pTmpExDate == exceptionDate)
451                 {
452                         alreadyExist = true;
453                         break;
454                 }
455         }
456
457         SysTryReturnResult(NID_SCL, !alreadyExist, E_OBJ_ALREADY_EXIST, "The exceptionDate already exists");
458
459         DateTime* pExDate = new (std::nothrow) DateTime(exceptionDate);
460         SysTryReturnResult(NID_SCL, pExDate != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
461
462         __pExceptionDates->Add(*pExDate);
463
464         return E_SUCCESS;
465 }
466
467 IList*
468 _RecurrenceImpl::GetExceptionDatesN(void) const
469 {
470         ClearLastResult();
471         result r = E_SUCCESS;
472
473         std::unique_ptr<Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter> pList(new (std::nothrow) ArrayList());
474         SysTryReturn(NID_SCL, pList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
475         r = pList->Construct();
476         SysTryReturn(NID_SCL, r == E_SUCCESS, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
477
478         DateTime* pExDate = null;
479         DateTime* pTmpExDate = null;
480         std::unique_ptr<IEnumerator> pEnum(__pExceptionDates->GetEnumeratorN());
481         while (pEnum->MoveNext() == E_SUCCESS)
482         {
483                 pExDate = static_cast<DateTime*>(pEnum->GetCurrent());
484                 if (pExDate)
485                 {
486                         pTmpExDate = new (std::nothrow) DateTime(*pExDate);
487                         SysTryReturn(NID_SCL, pTmpExDate != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
488                         pList->Add(*pTmpExDate);
489                 }
490         }
491
492         return pList.release();
493 }
494
495 _RecurrenceImpl*
496 _RecurrenceImpl::GetInstance(Recurrence& recurrence)
497 {
498         return recurrence.__pRecurrenceImpl;
499 }
500
501 const _RecurrenceImpl*
502 _RecurrenceImpl::GetInstance(const Recurrence& recurrence)
503 {
504         return recurrence.__pRecurrenceImpl;
505 }
506
507 }}      // Tizen::Social