2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @file JSPreferences.cpp
19 * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
23 #include "JSPreferences.h"
26 #include <dpl/assert.h>
27 #include <dpl/log/log.h>
28 #include <dpl/optional.h>
29 #include <CommonsJavaScript/Converter.h>
30 #include <CommonsJavaScript/JSDOMExceptionFactory.h>
31 #include <StorageEvent/StorageEventMgr.h>
32 #include <StorageEvent/IStorageEvent.h>
33 #include "IFrameSupport.h"
34 #include "AddEventListenerSupport.h"
37 using namespace WrtDeviceApis;
38 using namespace WrtDeviceApis::Commons;
39 using namespace WrtDeviceApis::CommonsJavaScript;
40 using namespace WrtDeviceApis::LocalStorage::Api;
41 using namespace WrtDeviceApis::StorageEvent::Api;
43 #define PREFERENCES_PLUGIN_NAME "preferences"
44 #define LOCAL_STORAGE_PROPERTY_LENGTH "length"
46 #define CATCH_EXCEPTION_NO_MODIFABLE \
47 Catch(Commons::LocalStorageValueNoModifableException) {\
48 LogError("The item is read only");\
49 return JSDOMExceptionFactory::\
50 NoModificationAllowedException.make(context, exception);\
53 #define CATCH_EXCEPTION_CONVERSION \
54 Catch(Commons::ConversionException) {\
55 LogError("Error on conversion");\
56 return JSDOMExceptionFactory::\
57 UnknownException.make(context, exception);\
60 #define CATCH_EXCEPTION_NULL_PTR \
61 Catch(Commons::NullPointerException) {\
62 LogError("Error on pointer, null value");\
63 return JSDOMExceptionFactory::\
64 UnknownException.make(context, exception);\
67 #define CATCH_EXCEPTION_PLATFORM_ERROR \
68 Catch(Commons::PlatformException){\
69 LogError("PlatformException occured");\
70 return JSDOMExceptionFactory::\
71 UnknownException.make(context, exception);\
74 #define CATCH_EXCEPTION_SECURITY \
75 Catch(Commons::SecurityException){\
76 LogError("Security exception occured");\
77 return JSDOMExceptionFactory::\
78 SecurityException.make(context, exception);\
81 #define CATCH_EXCEPTION_OUT_OF_RANGE \
82 Catch(Commons::OutOfRangeException) {\
83 LogError("OutOfRangeException");\
84 return JSDOMExceptionFactory::\
85 QuotaExceededException.make(context, exception);\
88 #define CATCH_EXCEPTION_INVALID_ARG \
89 Catch(Commons::InvalidArgumentException) {\
90 LogError("Pair for given key doesnt exist");\
91 return JSValueMakeNull(context);\
94 namespace WrtPlugins {
98 ILocalStoragePtr getIStorage(JSObjectRef arg)
100 LogWarning("get localstorage object");
102 LocalStoragePrivateData* priv =
103 static_cast<LocalStoragePrivateData*>(JSObjectGetPrivate(arg));
106 LogError("Private object not initialized");
107 ThrowMsg(Commons::NullPointerException,
108 "Private object not initialized");
111 return priv->istorage;
114 JSObjectRef getWidgetObject(JSObjectRef arg)
116 LogWarning("get widget object");
118 LocalStoragePrivateData* priv =
119 static_cast<LocalStoragePrivateData*>(JSObjectGetPrivate(arg));
122 LogError("Private object not initialized");
123 ThrowMsg(Commons::NullPointerException,
124 "Private object not initialized");
127 return priv->widgetObject;
131 enum class ModificationType{
136 //this function may throw exceptions
137 IStorageEventPtr modifyItemAndCreateEvent(ModificationType type,
138 JSObjectRef thisObject,
140 const string& value = std::string())
142 DPL::Optional<std::string> oldValue =
143 getIStorage(thisObject)->getValue(key);
145 if (ModificationType::SetItem == type)
147 getIStorage(thisObject)->setItem(key, value, false);
149 else if (ModificationType::RemoveItem == type)
151 getIStorage(thisObject)->removeItem(key);
155 Assert(0 && "Wrong Modification type");
158 DPL::Optional<std::string> newValue =
159 getIStorage(thisObject)->getValue(key);
161 //create event object
162 IStorageEventPtr storageEvent = getStorageEvent();
165 storageEvent->setKey(key);
167 if (!!oldValue) { storageEvent->setOldValue(*oldValue); }
169 if(!!newValue){ storageEvent->setNewValue(*newValue); }
175 JSClassDefinition JSPreferences::m_classInfo =
178 kJSClassAttributeNone,
179 PREFERENCES_PLUGIN_NAME,
188 NULL,//DeleteProperty,
189 NULL,//GetPropertyNames,
190 NULL,//CallAsFunction,
191 NULL,//CallAsConstructor,
193 NULL,//ConvertToType,
196 JSStaticFunction JSPreferences::m_function[] = {
197 { "setItem", JSPreferences::setItem, kJSPropertyAttributeNone },
198 { "removeItem", JSPreferences::removeItem, kJSPropertyAttributeNone },
199 { "getItem", JSPreferences::getItem, kJSPropertyAttributeNone },
200 { "clear", JSPreferences::clear, kJSPropertyAttributeNone },
201 { "key", JSPreferences::key, kJSPropertyAttributeNone },
205 JSStaticValue JSPreferences::m_property[] =
207 {LOCAL_STORAGE_PROPERTY_LENGTH,
208 JSPreferences::getLength,
210 kJSPropertyAttributeReadOnly},
214 const JSClassRef JSPreferences::getClassRef()
217 m_jsClassRef = JSClassCreate(&m_classInfo);
222 const JSClassDefinition* JSPreferences::getClassInfo()
227 JSClassRef JSPreferences::m_jsClassRef =
228 JSClassCreate(JSPreferences::getClassInfo());
230 void JSPreferences::initialize(JSContextRef context,
235 if( !AddEventListenerSupport::isInitialized())
237 AddEventListenerSupport::initializeContext(context);
240 LocalStoragePrivateData* priv =
241 static_cast<LocalStoragePrivateData*>(JSObjectGetPrivate(object));
243 Assert(priv && "private object of preferences is NULL");
246 void JSPreferences::finalize(JSObjectRef object)
249 LocalStoragePrivateData* priv =
250 static_cast<LocalStoragePrivateData*>(JSObjectGetPrivate(object));
253 LogDebug("private object is realised");
256 JSValueRef JSPreferences::removeItem(JSContextRef context,
258 JSObjectRef thisObject,
259 size_t argumentCount,
260 const JSValueRef arguments[],
261 JSValueRef* exception)
266 Converter converter(context);
268 std::string key = converter.toString(arguments[0]);
270 auto event = modifyItemAndCreateEvent(ModificationType::RemoveItem,
274 auto iframe = IFrameSupport::
275 getIFrameObjectForWidget(getWidgetObject(thisObject));
277 Assert(iframe && "Iframe is NULL");
279 AddEventListenerSupport::
280 CallListenersFromDifferentIFrames(iframe, event);
283 return JSValueMakeNull(context);
285 CATCH_EXCEPTION_NO_MODIFABLE
286 CATCH_EXCEPTION_CONVERSION
287 CATCH_EXCEPTION_NULL_PTR
288 CATCH_EXCEPTION_PLATFORM_ERROR
289 CATCH_EXCEPTION_SECURITY
292 JSValueRef JSPreferences::setItem(JSContextRef context,
294 JSObjectRef thisObject,
295 size_t argumentCount,
296 const JSValueRef arguments[],
297 JSValueRef* exception)
300 LogDebug("This: " << thisObject);
301 LogDebug("Object: " << object);
304 Converter converter(context);
306 std::string key = converter.toString(arguments[0]);
307 std::string value = converter.tryString(arguments[1]);
309 auto event = modifyItemAndCreateEvent(ModificationType::SetItem,
314 auto iframe = IFrameSupport::
315 getIFrameObjectForWidget(getWidgetObject(thisObject));
316 Assert(iframe && "Iframe is NULL");
318 AddEventListenerSupport::
319 CallListenersFromDifferentIFrames(iframe, event);
323 return JSValueMakeUndefined(context);
325 CATCH_EXCEPTION_NO_MODIFABLE
326 CATCH_EXCEPTION_CONVERSION
327 CATCH_EXCEPTION_NULL_PTR
328 CATCH_EXCEPTION_PLATFORM_ERROR
329 CATCH_EXCEPTION_SECURITY
330 CATCH_EXCEPTION_OUT_OF_RANGE
334 JSValueRef JSPreferences::clear(JSContextRef context,
336 JSObjectRef thisObject,
337 size_t argumentCount,
338 const JSValueRef arguments[],
339 JSValueRef* exception)
344 getIStorage(thisObject)->clear(false);
347 auto iframe = IFrameSupport::
348 getIFrameObjectForWidget(getWidgetObject(thisObject));
350 Assert(iframe && "Iframe is NULL");
352 //create event object
353 IStorageEventPtr storageEvent = getStorageEvent();
355 AddEventListenerSupport::
356 CallListenersFromDifferentIFrames(iframe, storageEvent);
360 return JSValueMakeNull(context);
362 CATCH_EXCEPTION_NULL_PTR
363 CATCH_EXCEPTION_PLATFORM_ERROR
364 CATCH_EXCEPTION_SECURITY
367 JSValueRef JSPreferences::getItem(JSContextRef context,
369 JSObjectRef thisObject,
370 size_t argumentCount,
371 const JSValueRef arguments[],
372 JSValueRef* exception)
377 Converter converter(context);
379 std::string key = converter.tryString(arguments[0]);
381 LogDebug("Getting item for key " << key);
383 DPL::Optional<std::string> value =
384 getIStorage(thisObject)->getValue(key);
387 return JSValueMakeNull(context);
389 return converter.toJSValueRef(*value);
391 CATCH_EXCEPTION_INVALID_ARG
392 CATCH_EXCEPTION_CONVERSION
393 CATCH_EXCEPTION_NULL_PTR
394 CATCH_EXCEPTION_PLATFORM_ERROR
395 CATCH_EXCEPTION_SECURITY
398 JSValueRef JSPreferences::key(JSContextRef context,
400 JSObjectRef thisObject,
401 size_t argumentCount,
402 const JSValueRef arguments[],
403 JSValueRef* exception)
408 if (argumentCount<1) {
409 LogError("No argument found");
410 Throw(Commons::InvalidArgumentException);
413 Converter converter(context);
415 size_t n = converter.toSizeT(arguments[0]);
417 std::string value = getIStorage(thisObject)->getValueByIndex(n);
421 return converter.toJSValueRef(value);
423 CATCH_EXCEPTION_CONVERSION
424 CATCH_EXCEPTION_NULL_PTR
425 CATCH_EXCEPTION_PLATFORM_ERROR
426 CATCH_EXCEPTION_SECURITY
427 CATCH_EXCEPTION_INVALID_ARG
430 JSValueRef JSPreferences::getLength(JSContextRef context,
432 JSStringRef propertyName,
433 JSValueRef* exception)
439 Converter converter(context);
441 size_t value = getIStorage(object)->getStorageSize();
442 return converter.toJSValueRef(value);
444 CATCH_EXCEPTION_CONVERSION
445 CATCH_EXCEPTION_NULL_PTR
446 CATCH_EXCEPTION_PLATFORM_ERROR
447 CATCH_EXCEPTION_SECURITY
448 CATCH_EXCEPTION_INVALID_ARG
451 bool JSPreferences::hasProperty(JSContextRef context,
453 JSStringRef propertyName)
458 Converter converter(context);
460 std::string key = converter.toString(propertyName);
462 if(!getIStorage(object)->getValue(key)) {
469 Catch(Commons::InvalidArgumentException) {
470 LogDebug("Pair for given key doesnt exist");
473 Catch(Commons::ConversionException) {
474 LogError("Error on conversion");
477 Catch(Commons::NullPointerException) {
478 LogError("Error on pointer, null value");
481 Catch(Commons::PlatformException){
482 LogError("PlatformException occured");
487 JSValueRef JSPreferences::getProperty(JSContextRef context,
489 JSStringRef propertyName,
490 JSValueRef* exception)
495 Converter converter(context);
497 std::string key = converter.toString(propertyName);
499 DPL::Optional<std::string> value =
500 getIStorage(object)->getValue(key);
505 return JSValueMakeNull(context);
507 return converter.toJSValueRef(*value);
510 CATCH_EXCEPTION_CONVERSION
511 CATCH_EXCEPTION_NULL_PTR
512 CATCH_EXCEPTION_PLATFORM_ERROR
513 CATCH_EXCEPTION_INVALID_ARG
516 bool JSPreferences::setProperty(JSContextRef context,
518 JSStringRef propertyName,
520 JSValueRef* exception)
525 Converter converter(context);
527 std::string key = converter.toString(propertyName);
528 std::string value = converter.toString(jvalue);
530 auto event = modifyItemAndCreateEvent(ModificationType::SetItem,
535 auto iframe = IFrameSupport::
536 getIFrameObjectForWidget(getWidgetObject(object));
537 Assert(iframe && "Iframe is NULL");
539 AddEventListenerSupport::
540 CallListenersFromDifferentIFrames(iframe, event);
546 CATCH_EXCEPTION_NO_MODIFABLE
547 CATCH_EXCEPTION_OUT_OF_RANGE
548 CATCH_EXCEPTION_INVALID_ARG
549 CATCH_EXCEPTION_CONVERSION
550 CATCH_EXCEPTION_NULL_PTR
551 CATCH_EXCEPTION_PLATFORM_ERROR
552 CATCH_EXCEPTION_SECURITY
557 #undef CATCH_EXCEPTION_NO_MODIFABLE
558 #undef CATCH_EXCEPTION_CONVERSION
559 #undef CATCH_EXCEPTION_NULL_PTR
560 #undef CATCH_EXCEPTION_PLATFORM_ERROR
561 #undef CATCH_EXCEPTION_SECURITY
562 #undef CATCH_EXCEPTION_OUT_OF_RANGE
563 #undef CATCH_EXCEPTION_INVALID_ARG