Beta merge 2
[profile/ivi/wrt-plugins-tizen.git] / src / standards / Tizen / Contact / JSContactAddressArray.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * @file        JSContactAddressArray.cpp
19  * @author      Kisub Song (kisubs.song@samsung.com)
20  * @version     0.1
21  * @brief
22  */
23
24 #include <algorithm>
25 #include <dpl/log/log.h>
26 #include <Tizen/Common/JSTizenExceptionFactory.h>
27 #include <Tizen/Common/JSTizenException.h>
28 #include "ContactConverter.h"
29 #include "JSContactAddressArray.h"
30
31 #define FUNCTION_CONCAT "concat"
32 #define FUNCTION_JOIN "join"
33 #define FUNCTION_POP "pop"
34 #define FUNCTION_PUSH "push"
35 #define FUNCTION_REVERSE "reverse"
36 #define FUNCTION_SHIFT "shift"
37 #define FUNCTION_SLICE "slice"
38 #define FUNCTION_SORT "sort"
39 #define FUNCTION_SPLICE "splice"
40 #define FUNCTION_TOSTRING "toString"
41 #define FUNCTION_UNSHIFT "unshift"
42 #define FUNCTION_VALUEOF "valueOf"
43 #define ARRAY "Array"
44 #define ATTRIBUTE_LENGTH "length"
45
46 namespace TizenApis {
47 namespace Tizen1_0 {
48 namespace Contact {
49
50 using namespace TizenApis::Commons;
51 using namespace TizenApis::Api::Contact;
52
53 JSClassDefinition JSContactAddressArray::m_classInfo = {
54         0,
55         kJSClassAttributeNone,
56         ARRAY,
57         0,
58         m_property,
59         m_function,
60         initialize,
61         finalize,
62         hasProperty,
63         getProperty,
64         setProperty,
65         NULL, //deleteProperty,
66         NULL, //getPropertyNames,
67         NULL, //callAsFunction,
68         NULL, //callAsConstructor,
69         NULL, //hasInstance,
70         NULL, //convertToType,
71 };
72
73 JSStaticValue JSContactAddressArray::m_property[] = {
74         { ATTRIBUTE_LENGTH, getLength, NULL, kJSPropertyAttributeReadOnly },
75         { 0, 0, 0, 0 }
76 };
77
78 JSStaticFunction JSContactAddressArray::m_function[] = {
79         { FUNCTION_CONCAT, concat, kJSPropertyAttributeNone },
80         { FUNCTION_JOIN, join, kJSPropertyAttributeNone },
81         { FUNCTION_POP, pop, kJSPropertyAttributeNone },
82         { FUNCTION_PUSH, push, kJSPropertyAttributeNone },
83         { FUNCTION_REVERSE, reverse, kJSPropertyAttributeNone },
84         { FUNCTION_SHIFT, shift, kJSPropertyAttributeNone },
85         { FUNCTION_SLICE, slice, kJSPropertyAttributeNone },
86         { FUNCTION_SORT, sort, kJSPropertyAttributeNone },
87         { FUNCTION_SPLICE, splice, kJSPropertyAttributeNone },
88         { FUNCTION_TOSTRING, toString, kJSPropertyAttributeNone },
89         { FUNCTION_UNSHIFT, unshift, kJSPropertyAttributeNone },
90         { FUNCTION_VALUEOF, valueOf, kJSPropertyAttributeNone },
91         { 0, 0, 0 }
92 };
93
94 JSClassRef JSContactAddressArray::m_jsClassRef = JSClassCreate(
95                 JSContactAddressArray::getClassInfo());
96
97 JSValueRef JSContactAddressArray::getLength(JSContextRef context,
98                 JSObjectRef object,
99                 JSStringRef propertyName,
100                 JSValueRef* exception)
101 {
102         //LogDebug("enter");
103         Try
104         {
105                 JSContactAddressArrayPriv* priv =
106                         static_cast<JSContactAddressArrayPriv*>(JSObjectGetPrivate(object));
107                 if (!priv) {
108                         Throw(WrtDeviceApis::Commons::NullPointerException);
109                 }
110                 ContactAddressArrayPtr contactAddresses = priv->getObject();
111                 if (contactAddresses) {
112                         ContactConverterFactory::ConverterType converter =
113                                         ContactConverterFactory::getConverter(context);
114                         return converter->toJSValueRef(contactAddresses->size());
115                 }
116         }
117         Catch(WrtDeviceApis::Commons::Exception)
118         {
119                 LogError("invalid conversion");
120         }
121         return JSValueMakeUndefined(context);
122 }
123
124 JSObjectRef JSContactAddressArray::createArray(JSContextRef context,
125                 const ContactAddressArrayPtr &contactAddresses)
126 {
127         JSContactAddressArrayPriv *priv = new JSContactAddressArrayPriv(context, contactAddresses);
128         return JSObjectMake(context, getClassRef(), priv);
129 }
130
131 const JSClassDefinition* JSContactAddressArray::getClassInfo()
132 {
133         return &(m_classInfo);
134 }
135
136 JSClassRef JSContactAddressArray::getClassRef()
137 {
138         if (!m_jsClassRef) {
139                 m_jsClassRef = JSClassCreate(&m_classInfo);
140         }
141         return m_jsClassRef;
142 }
143
144 bool JSContactAddressArray::isObjectOfClass(JSContextRef context, JSValueRef value)
145 {
146         return JSValueIsObjectOfClass(context, value, getClassRef());
147 }
148
149 ContactAddressArrayPtr JSContactAddressArray::getContactAddressArray(JSContextRef context, JSValueRef value)
150 {
151         if (!isObjectOfClass(context, value)) {
152                 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
153         }
154         JSObjectRef object = JSValueToObject(context, value, NULL);
155         if (!object) {
156                 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
157         }
158         JSContactAddressArrayPriv *priv = static_cast<JSContactAddressArrayPriv*>(JSObjectGetPrivate(object));
159         if (!priv) {
160                 Throw(WrtDeviceApis::Commons::NullPointerException);
161         }
162         return priv->getObject();
163 }
164
165 void JSContactAddressArray::initialize(JSContextRef context,
166                 JSObjectRef object)
167 {
168         //LogDebug("enter");
169 }
170
171 void JSContactAddressArray::finalize(JSObjectRef object)
172 {
173         //LogDebug("enter");
174         JSContactAddressArrayPriv* priv =
175                 static_cast<JSContactAddressArrayPriv*>(JSObjectGetPrivate(object));
176         delete priv;
177         JSObjectSetPrivate(object, NULL);
178 }
179
180 bool JSContactAddressArray::hasProperty(JSContextRef context,
181                 JSObjectRef object,
182                 JSStringRef propertyName)
183 {
184         //LogDebug("enter");
185         ContactConverterFactory::ConverterType converter =
186                         ContactConverterFactory::getConverter(context);
187         Try
188         {
189                 size_t index = converter->toSizeT(propertyName);
190                 JSContactAddressArrayPriv* priv =
191                         static_cast<JSContactAddressArrayPriv*>(JSObjectGetPrivate(object));
192                 if (!priv) {
193                         Throw(WrtDeviceApis::Commons::NullPointerException);
194                 }
195                 ContactAddressArrayPtr contactAddresses = priv->getObject();
196                 if (index < contactAddresses->size()) {
197                         return true;
198                 }
199         }
200         Catch(WrtDeviceApis::Commons::Exception)
201         {
202                 //not reporting error is intended
203         }
204         return false;
205 }
206
207 JSValueRef JSContactAddressArray::getProperty(JSContextRef context,
208                 JSObjectRef object,
209                 JSStringRef propertyName,
210                 JSValueRef* exception)
211 {
212         //LogDebug("enter");
213         ContactConverterFactory::ConverterType converter =
214                         ContactConverterFactory::getConverter(context);
215         Try
216         {
217                 size_t index = converter->toSizeT(propertyName);
218                 JSContactAddressArrayPriv* priv =
219                         static_cast<JSContactAddressArrayPriv*>(JSObjectGetPrivate(object));
220                 if (!priv) {
221                         Throw(WrtDeviceApis::Commons::NullPointerException);
222                 }
223                 ContactAddressArrayPtr contactAddresses = priv->getObject();
224                 if (index < contactAddresses->size()) {
225                         ContactAddressPtr result = contactAddresses->at(index);
226                         if (result) {
227                                 return converter->toJSValueRef(result);
228                         }
229                 }
230         }
231         Catch(WrtDeviceApis::Commons::Exception)
232         {
233                 LogError("invalid property");
234         }
235         return JSValueMakeUndefined(context);
236 }
237
238 bool JSContactAddressArray::setProperty(JSContextRef context,
239                 JSObjectRef object,
240                 JSStringRef propertyName,
241                 JSValueRef value,
242                 JSValueRef* exception)
243 {
244         //LogDebug("enter");
245         ContactConverterFactory::ConverterType converter =
246                         ContactConverterFactory::getConverter(context);
247         Try
248         {
249                 size_t index = converter->toSizeT(propertyName);
250                 ContactAddressPtr contactAddress;
251                 if (!JSValueIsUndefined(context, value)) {
252                         contactAddress = converter->toContactAddress(value);
253                 }
254                 JSContactAddressArrayPriv* priv =
255                         static_cast<JSContactAddressArrayPriv*>(JSObjectGetPrivate(object));
256                 if (!priv) {
257                         Throw(WrtDeviceApis::Commons::NullPointerException);
258                 }
259                 ContactAddressArrayPtr contactAddresses = priv->getObject();
260                 if (!contactAddresses) {
261                         Throw(WrtDeviceApis::Commons::NullPointerException);
262                 }
263                 if (contactAddresses->size() <= index) {
264                         contactAddresses->resize(index + 1);
265                 }
266                 (*contactAddresses)[index] = contactAddress;
267                 return true;
268         }
269         Catch(WrtDeviceApis::Commons::Exception)
270         {
271                 LogError("error occured");
272                 JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
273         }
274         return false;
275 }
276
277 JSValueRef JSContactAddressArray::concat(JSContextRef context,
278                 JSObjectRef function,
279                 JSObjectRef thisObject,
280                 size_t argumentCount,
281                 const JSValueRef arguments[],
282                 JSValueRef* exception)
283 {
284         //LogDebug("enter");
285         Try
286         {
287                 ContactAddressArrayPtr contactAddresses = ContactAddressArrayPtr(new ContactAddressArray());
288                 JSContactAddressArrayPriv *newPrivateObject = new JSContactAddressArrayPriv(context, contactAddresses);
289                 JSValueRef result = JSObjectMake(context, getClassRef(), newPrivateObject);
290
291                 //copy current contactAddresses
292                 JSContactAddressArrayPriv* priv =
293                         static_cast<JSContactAddressArrayPriv*>(JSObjectGetPrivate(thisObject));
294                 ContactAddressArrayPtr currentContactAddresses = priv->getObject();
295                 for (size_t i = 0; i < currentContactAddresses->size(); ++i) {
296                         contactAddresses->push_back(currentContactAddresses->at(i));
297                 }
298
299                 //copy submitted arrays
300                 ContactConverterFactory::ConverterType converter =
301                                 ContactConverterFactory::getConverter(context);
302                 for (size_t i = 0; i < argumentCount; ++i) {
303                         if (!JSIsArrayValue(context, arguments[i])) {
304                                 Throw(WrtDeviceApis::Commons::ConversionException);
305                         }
306                         // process array of strings
307                         JSObjectRef arrayObj = converter->toJSObjectRef(arguments[i]);
308                         unsigned int len = JSGetArrayLength(context, arrayObj);
309                         for (unsigned int e = 0; e < len; ++e) {
310                                 JSValueRef att = JSGetArrayElement(context, arrayObj, e);
311                                 contactAddresses->push_back(converter->toContactAddress(att));
312                         }
313                 }
314                 return result;
315         }
316         Catch(WrtDeviceApis::Commons::Exception)
317         {
318                 LogError("error occured");
319         }
320         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
321 }
322
323 JSValueRef JSContactAddressArray::join(JSContextRef context,
324                 JSObjectRef function,
325                 JSObjectRef thisObject,
326                 size_t argumentCount,
327                 const JSValueRef arguments[],
328                 JSValueRef* exception)
329 {
330         //LogDebug("entered");
331         Try
332         {
333                 std::string result;
334                 std::string separator(",");
335                 ContactConverterFactory::ConverterType converter =
336                                 ContactConverterFactory::getConverter(context);
337                 JSContactAddressArrayPriv* priv =
338                         static_cast<JSContactAddressArrayPriv*>(JSObjectGetPrivate(thisObject));
339                 ContactAddressArrayPtr currentContactAddresses = priv->getObject();
340                 if (argumentCount > 0 && JSValueIsString(context, arguments[0])) {
341                         separator = converter->toString(arguments[0]);
342                 }
343                 for (size_t i = 0; i < currentContactAddresses->size(); ++i) {
344                         if (i != 0) {
345                                 result += separator;
346                         }
347                         //FIXME : to be changed to support join
348                         //result += currentContactAddresses->at(i);
349                 }
350                 return converter->toJSValueRef(result);
351         }
352         Catch(WrtDeviceApis::Commons::Exception)
353         {
354                 LogError("error occured");
355         }
356         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
357 }
358
359 JSValueRef JSContactAddressArray::pop(JSContextRef context,
360                 JSObjectRef function,
361                 JSObjectRef thisObject,
362                 size_t argumentCount,
363                 const JSValueRef arguments[],
364                 JSValueRef* exception)
365 {
366         //LogDebug("entered");
367         Try
368         {
369                 ContactConverterFactory::ConverterType converter =
370                                 ContactConverterFactory::getConverter(context);
371                 JSContactAddressArrayPriv* priv =
372                         static_cast<JSContactAddressArrayPriv*>(JSObjectGetPrivate(thisObject));
373                 ContactAddressArrayPtr currentContactAddresses = priv->getObject();
374                 if (currentContactAddresses->size() > 0) {
375                         ContactAddressPtr result = currentContactAddresses->at(
376                                         currentContactAddresses->size() - 1);
377                         currentContactAddresses->pop_back();
378                         return converter->toJSValueRef(result);
379                 }
380         }
381         Catch(WrtDeviceApis::Commons::Exception)
382         {
383                 LogError("error occured");
384         }
385         return JSValueMakeUndefined(context);
386 }
387
388 JSValueRef JSContactAddressArray::push(JSContextRef context,
389                 JSObjectRef function,
390                 JSObjectRef thisObject,
391                 size_t argumentCount,
392                 const JSValueRef arguments[],
393                 JSValueRef* exception)
394 {
395         //LogDebug("entered");
396         Try
397         {
398                 ContactConverterFactory::ConverterType converter =
399                                 ContactConverterFactory::getConverter(context);
400                 JSContactAddressArrayPriv* priv =
401                         static_cast<JSContactAddressArrayPriv*>(JSObjectGetPrivate(thisObject));
402                 ContactAddressArrayPtr currentContactAddresses = priv->getObject();
403                 for (size_t i = 0; i < argumentCount; ++i) {
404                         currentContactAddresses->push_back(converter->toContactAddress(arguments[i]));
405                 }
406                 return converter->toJSValueRef(currentContactAddresses->size());
407         }
408         Catch(WrtDeviceApis::Commons::Exception)
409         {
410                 LogError("error occured");
411         }
412         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
413 }
414
415 JSValueRef JSContactAddressArray::reverse(JSContextRef context,
416                 JSObjectRef function,
417                 JSObjectRef thisObject,
418                 size_t argumentCount,
419                 const JSValueRef arguments[],
420                 JSValueRef* exception)
421 {
422         //LogDebug("entered");
423         Try
424         {
425                 ContactConverterFactory::ConverterType converter =
426                                 ContactConverterFactory::getConverter(context);
427                 JSContactAddressArrayPriv* priv =
428                         static_cast<JSContactAddressArrayPriv*>(JSObjectGetPrivate(thisObject));
429                 ContactAddressArrayPtr currentContactAddresses = priv->getObject();
430                 std::reverse(currentContactAddresses->begin(), currentContactAddresses->end());
431                 return thisObject;
432         }
433         Catch(WrtDeviceApis::Commons::Exception)
434         {
435                 LogError("error occured");
436         }
437         return JSValueMakeUndefined(context);
438 }
439
440 JSValueRef JSContactAddressArray::shift(JSContextRef context,
441                 JSObjectRef function,
442                 JSObjectRef thisObject,
443                 size_t argumentCount,
444                 const JSValueRef arguments[],
445                 JSValueRef* exception)
446 {
447         //LogDebug("entered");
448         Try
449         {
450                 ContactConverterFactory::ConverterType converter =
451                                 ContactConverterFactory::getConverter(context);
452                 JSContactAddressArrayPriv* priv =
453                         static_cast<JSContactAddressArrayPriv*>(JSObjectGetPrivate(thisObject));
454                 ContactAddressArrayPtr currentContactAddresses = priv->getObject();
455                 if (currentContactAddresses->size() > 0) {
456                         ContactAddressPtr result = currentContactAddresses->at(0);
457                         currentContactAddresses->erase(currentContactAddresses->begin());
458                         return converter->toJSValueRef(result);
459                 }
460         }
461         Catch(WrtDeviceApis::Commons::Exception)
462         {
463                 LogError("error occured");
464         }
465         return JSValueMakeUndefined(context);
466 }
467
468 JSValueRef JSContactAddressArray::slice(JSContextRef context,
469                 JSObjectRef function,
470                 JSObjectRef thisObject,
471                 size_t argumentCount,
472                 const JSValueRef arguments[],
473                 JSValueRef* exception)
474 {
475         //LogDebug("enter");
476         Try
477         {
478                 if (argumentCount < 1) {
479                         return JSValueMakeUndefined(context);
480                 }
481                 ContactConverterFactory::ConverterType converter =
482                                 ContactConverterFactory::getConverter(context);
483                 ContactAddressArrayPtr contactAddresses = ContactAddressArrayPtr(new ContactAddressArray());
484                 JSContactAddressArrayPriv *newPrivateObject = new JSContactAddressArrayPriv(
485                                 context,
486                                 contactAddresses);
487                 JSValueRef result = JSObjectMake(context,
488                                                                                  getClassRef(), newPrivateObject);
489
490                 //copy current contactAddresses
491                 JSContactAddressArrayPriv* priv =
492                         static_cast<JSContactAddressArrayPriv*>(JSObjectGetPrivate(thisObject));
493                 ContactAddressArrayPtr currentContactAddresses = priv->getObject();
494                 std::size_t first = converter->toSizeT(arguments[0]);
495                 std::size_t last = currentContactAddresses->size() - 1;
496                 if (argumentCount > 1) {
497                         last = converter->toSizeT(arguments[1]);
498                         if (last >= currentContactAddresses->size()) {
499                                 last = currentContactAddresses->size() - 1;
500                         }
501                 }
502                 if (first < 0) {
503                         first = 0;
504                 }
505                 for (size_t i = first; i <= last; ++i) {
506                         contactAddresses->push_back(currentContactAddresses->at(i));
507                 }
508
509                 return result;
510         }
511         Catch(WrtDeviceApis::Commons::Exception)
512         {
513                 LogError("error occured");
514         }
515         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
516 }
517
518 JSValueRef JSContactAddressArray::sort(JSContextRef context,
519                 JSObjectRef function,
520                 JSObjectRef thisObject,
521                 size_t argumentCount,
522                 const JSValueRef arguments[],
523                 JSValueRef* exception)
524 {
525         //LogDebug("entered");
526         Try
527         {
528                 ContactConverterFactory::ConverterType converter =
529                                 ContactConverterFactory::getConverter(context);
530                 JSContactAddressArrayPriv* priv =
531                         static_cast<JSContactAddressArrayPriv*>(JSObjectGetPrivate(thisObject));
532                 ContactAddressArrayPtr currentContactAddresses = priv->getObject();
533                 std::sort(currentContactAddresses->begin(), currentContactAddresses->end());
534                 return thisObject;
535         }
536         Catch(WrtDeviceApis::Commons::Exception)
537         {
538                 LogError("error occured");
539         }
540         return JSValueMakeUndefined(context);
541 }
542
543 JSValueRef JSContactAddressArray::splice(JSContextRef context,
544                 JSObjectRef function,
545                 JSObjectRef thisObject,
546                 size_t argumentCount,
547                 const JSValueRef arguments[],
548                 JSValueRef* exception)
549 {
550         //LogDebug("entered");
551         return JSValueMakeUndefined(context);
552 }
553
554 JSValueRef JSContactAddressArray::toString(JSContextRef context,
555                 JSObjectRef function,
556                 JSObjectRef thisObject,
557                 size_t argumentCount,
558                 const JSValueRef arguments[],
559                 JSValueRef* exception)
560 {
561         //LogDebug("entered");
562         return join(context, function, thisObject, 0, arguments, exception);
563 }
564
565 JSValueRef JSContactAddressArray::unshift(JSContextRef context,
566                 JSObjectRef function,
567                 JSObjectRef thisObject,
568                 size_t argumentCount,
569                 const JSValueRef arguments[],
570                 JSValueRef* exception)
571 {
572         //LogDebug("entered");
573         return JSValueMakeUndefined(context);
574 }
575
576 JSValueRef JSContactAddressArray::valueOf(JSContextRef context,
577                 JSObjectRef function,
578                 JSObjectRef thisObject,
579                 size_t argumentCount,
580                 const JSValueRef arguments[],
581                 JSValueRef* exception)
582 {
583         //LogDebug("entered");
584         return JSValueMakeUndefined(context);
585 }
586
587 } // Contact
588 } // Tizen1_0
589 } // TizenApis