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 <js-overlay/js_iframe_support.h>
34 #include <js-overlay/js_overlay_addEventListener.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,
233 LogDebug("entered. Context: " << context);
235 LocalStoragePrivateData* priv =
236 static_cast<LocalStoragePrivateData*>(JSObjectGetPrivate(object));
238 Assert(priv && "private object of preferences is NULL");
241 void JSPreferences::finalize(JSObjectRef object)
244 LocalStoragePrivateData* priv =
245 static_cast<LocalStoragePrivateData*>(JSObjectGetPrivate(object));
248 LogDebug("private object is realised");
251 JSValueRef JSPreferences::removeItem(JSContextRef context,
253 JSObjectRef thisObject,
254 size_t argumentCount,
255 const JSValueRef arguments[],
256 JSValueRef* exception)
261 Converter converter(context);
263 std::string key = converter.toString(arguments[0]);
265 auto event = modifyItemAndCreateEvent(ModificationType::RemoveItem,
269 auto iframe = IFrameSupport::
270 getIFrameObjectForWidget(getWidgetObject(thisObject));
272 Assert(iframe && "Iframe is NULL");
274 AddEventListenerSupport::
275 CallStorageListenersFromDifferentIFrames(iframe, event);
278 return JSValueMakeNull(context);
280 CATCH_EXCEPTION_NO_MODIFABLE
281 CATCH_EXCEPTION_CONVERSION
282 CATCH_EXCEPTION_NULL_PTR
283 CATCH_EXCEPTION_PLATFORM_ERROR
284 CATCH_EXCEPTION_SECURITY
287 JSValueRef JSPreferences::setItem(JSContextRef context,
289 JSObjectRef thisObject,
290 size_t argumentCount,
291 const JSValueRef arguments[],
292 JSValueRef* exception)
295 LogDebug("This: " << thisObject);
296 LogDebug("Object: " << object);
299 Converter converter(context);
301 std::string key = converter.toString(arguments[0]);
302 std::string value = converter.tryString(arguments[1]);
304 auto event = modifyItemAndCreateEvent(ModificationType::SetItem,
309 auto iframe = IFrameSupport::
310 getIFrameObjectForWidget(getWidgetObject(thisObject));
311 Assert(iframe && "Iframe is NULL");
313 AddEventListenerSupport::
314 CallStorageListenersFromDifferentIFrames(iframe, event);
318 return JSValueMakeUndefined(context);
320 CATCH_EXCEPTION_NO_MODIFABLE
321 CATCH_EXCEPTION_CONVERSION
322 CATCH_EXCEPTION_NULL_PTR
323 CATCH_EXCEPTION_PLATFORM_ERROR
324 CATCH_EXCEPTION_SECURITY
325 CATCH_EXCEPTION_OUT_OF_RANGE
329 JSValueRef JSPreferences::clear(JSContextRef context,
331 JSObjectRef thisObject,
332 size_t argumentCount,
333 const JSValueRef arguments[],
334 JSValueRef* exception)
339 getIStorage(thisObject)->clear(false);
342 auto iframe = IFrameSupport::
343 getIFrameObjectForWidget(getWidgetObject(thisObject));
345 Assert(iframe && "Iframe is NULL");
347 //create event object
348 IStorageEventPtr storageEvent = getStorageEvent();
350 AddEventListenerSupport::
351 CallStorageListenersFromDifferentIFrames(iframe, storageEvent);
355 return JSValueMakeNull(context);
357 CATCH_EXCEPTION_NULL_PTR
358 CATCH_EXCEPTION_PLATFORM_ERROR
359 CATCH_EXCEPTION_SECURITY
362 JSValueRef JSPreferences::getItem(JSContextRef context,
364 JSObjectRef thisObject,
365 size_t argumentCount,
366 const JSValueRef arguments[],
367 JSValueRef* exception)
372 Converter converter(context);
374 std::string key = converter.tryString(arguments[0]);
376 LogDebug("Getting item for key " << key);
378 DPL::Optional<std::string> value =
379 getIStorage(thisObject)->getValue(key);
382 return JSValueMakeNull(context);
384 return converter.toJSValueRef(*value);
386 CATCH_EXCEPTION_INVALID_ARG
387 CATCH_EXCEPTION_CONVERSION
388 CATCH_EXCEPTION_NULL_PTR
389 CATCH_EXCEPTION_PLATFORM_ERROR
390 CATCH_EXCEPTION_SECURITY
393 JSValueRef JSPreferences::key(JSContextRef context,
395 JSObjectRef thisObject,
396 size_t argumentCount,
397 const JSValueRef arguments[],
398 JSValueRef* exception)
403 if (argumentCount<1) {
404 LogError("No argument found");
405 Throw(Commons::InvalidArgumentException);
408 Converter converter(context);
410 size_t n = converter.toSizeT(arguments[0]);
412 std::string value = getIStorage(thisObject)->getKeyByIndex(n);
416 return converter.toJSValueRef(value);
418 CATCH_EXCEPTION_CONVERSION
419 CATCH_EXCEPTION_NULL_PTR
420 CATCH_EXCEPTION_PLATFORM_ERROR
421 CATCH_EXCEPTION_SECURITY
422 CATCH_EXCEPTION_INVALID_ARG
425 JSValueRef JSPreferences::getLength(JSContextRef context,
427 JSStringRef propertyName,
428 JSValueRef* exception)
434 Converter converter(context);
436 size_t value = getIStorage(object)->getStorageSize();
437 return converter.toJSValueRef(value);
439 CATCH_EXCEPTION_CONVERSION
440 CATCH_EXCEPTION_NULL_PTR
441 CATCH_EXCEPTION_PLATFORM_ERROR
442 CATCH_EXCEPTION_SECURITY
443 CATCH_EXCEPTION_INVALID_ARG
446 bool JSPreferences::hasProperty(JSContextRef context,
448 JSStringRef propertyName)
453 Converter converter(context);
455 std::string key = converter.toString(propertyName);
457 if(!getIStorage(object)->getValue(key)) {
464 Catch(Commons::InvalidArgumentException) {
465 LogDebug("Pair for given key doesnt exist");
468 Catch(Commons::ConversionException) {
469 LogError("Error on conversion");
472 Catch(Commons::NullPointerException) {
473 LogError("Error on pointer, null value");
476 Catch(Commons::PlatformException){
477 LogError("PlatformException occured");
482 JSValueRef JSPreferences::getProperty(JSContextRef context,
484 JSStringRef propertyName,
485 JSValueRef* exception)
490 Converter converter(context);
492 std::string key = converter.toString(propertyName);
494 DPL::Optional<std::string> value =
495 getIStorage(object)->getValue(key);
500 return JSValueMakeNull(context);
502 return converter.toJSValueRef(*value);
505 CATCH_EXCEPTION_CONVERSION
506 CATCH_EXCEPTION_NULL_PTR
507 CATCH_EXCEPTION_PLATFORM_ERROR
508 CATCH_EXCEPTION_INVALID_ARG
511 bool JSPreferences::setProperty(JSContextRef context,
513 JSStringRef propertyName,
515 JSValueRef* exception)
520 Converter converter(context);
522 std::string key = converter.toString(propertyName);
523 std::string value = converter.toString(jvalue);
525 auto event = modifyItemAndCreateEvent(ModificationType::SetItem,
530 auto iframe = IFrameSupport::
531 getIFrameObjectForWidget(getWidgetObject(object));
532 Assert(iframe && "Iframe is NULL");
534 AddEventListenerSupport::
535 CallStorageListenersFromDifferentIFrames(iframe, event);
541 CATCH_EXCEPTION_NO_MODIFABLE
542 CATCH_EXCEPTION_OUT_OF_RANGE
543 CATCH_EXCEPTION_INVALID_ARG
544 CATCH_EXCEPTION_CONVERSION
545 CATCH_EXCEPTION_NULL_PTR
546 CATCH_EXCEPTION_PLATFORM_ERROR
547 CATCH_EXCEPTION_SECURITY
552 #undef CATCH_EXCEPTION_NO_MODIFABLE
553 #undef CATCH_EXCEPTION_CONVERSION
554 #undef CATCH_EXCEPTION_NULL_PTR
555 #undef CATCH_EXCEPTION_PLATFORM_ERROR
556 #undef CATCH_EXCEPTION_SECURITY
557 #undef CATCH_EXCEPTION_OUT_OF_RANGE
558 #undef CATCH_EXCEPTION_INVALID_ARG