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 {
96 ILocalStoragePtr getIStorage(JSObjectRef arg)
98 LogWarning("get localstorage object");
100 LocalStoragePrivateData* priv =
101 static_cast<LocalStoragePrivateData*>(JSObjectGetPrivate(arg));
104 LogError("Private object not initialized");
105 ThrowMsg(Commons::NullPointerException,
106 "Private object not initialized");
109 return priv->istorage;
112 JSObjectRef getWidgetObject(JSObjectRef arg)
114 LogWarning("get widget object");
116 LocalStoragePrivateData* priv =
117 static_cast<LocalStoragePrivateData*>(JSObjectGetPrivate(arg));
120 LogError("Private object not initialized");
121 ThrowMsg(Commons::NullPointerException,
122 "Private object not initialized");
125 return priv->widgetObject;
128 enum class ModificationType
134 //this function may throw exceptions
135 IStorageEventPtr modifyItemAndCreateEvent(ModificationType type,
136 JSObjectRef thisObject,
138 const string& value = std::string())
140 DPL::Optional<std::string> oldValue =
141 getIStorage(thisObject)->getValue(key);
143 if (ModificationType::SetItem == type) {
144 getIStorage(thisObject)->setItem(key, value, false);
145 } else if (ModificationType::RemoveItem == type) {
146 getIStorage(thisObject)->removeItem(key);
148 Assert(0 && "Wrong Modification type");
151 DPL::Optional<std::string> newValue =
152 getIStorage(thisObject)->getValue(key);
154 //create event object
155 IStorageEventPtr storageEvent = getStorageEvent();
158 storageEvent->setKey(key);
161 storageEvent->setOldValue(*oldValue);
165 storageEvent->setNewValue(*newValue);
171 JSClassDefinition JSPreferences::m_classInfo = {
173 kJSClassAttributeNone,
174 PREFERENCES_PLUGIN_NAME,
183 NULL, //DeleteProperty,
184 NULL, //GetPropertyNames,
185 NULL, //CallAsFunction,
186 NULL, //CallAsConstructor,
188 NULL, //ConvertToType,
191 JSStaticFunction JSPreferences::m_function[] = {
192 { "setItem", JSPreferences::setItem, kJSPropertyAttributeNone },
193 { "removeItem", JSPreferences::removeItem, kJSPropertyAttributeNone },
194 { "getItem", JSPreferences::getItem, kJSPropertyAttributeNone },
195 { "clear", JSPreferences::clear, kJSPropertyAttributeNone },
196 { "key", JSPreferences::key, kJSPropertyAttributeNone },
200 JSStaticValue JSPreferences::m_property[] = {
201 { LOCAL_STORAGE_PROPERTY_LENGTH,
202 JSPreferences::getLength,
204 kJSPropertyAttributeReadOnly },
208 JSClassRef JSPreferences::getClassRef()
211 m_jsClassRef = JSClassCreate(&m_classInfo);
216 const JSClassDefinition* JSPreferences::getClassInfo()
221 JSClassRef JSPreferences::m_jsClassRef =
222 JSClassCreate(JSPreferences::getClassInfo());
224 void JSPreferences::initialize(JSContextRef context,
227 LogDebug("entered. Context: " << context);
229 LocalStoragePrivateData* priv =
230 static_cast<LocalStoragePrivateData*>(JSObjectGetPrivate(object));
232 Assert(priv && "private object of preferences is NULL");
235 void JSPreferences::finalize(JSObjectRef object)
238 LocalStoragePrivateData* priv =
239 static_cast<LocalStoragePrivateData*>(JSObjectGetPrivate(object));
242 LogDebug("private object is realised");
245 JSValueRef JSPreferences::removeItem(JSContextRef context,
246 JSObjectRef /*object*/,
247 JSObjectRef thisObject,
248 size_t /*argumentCount*/,
249 const JSValueRef arguments[],
250 JSValueRef* exception)
255 Converter converter(context);
257 std::string key = converter.toString(arguments[0]);
259 auto event = modifyItemAndCreateEvent(ModificationType::RemoveItem,
263 auto iframe = IFrameSupport::
264 getIFrameObjectForWidget(getWidgetObject(thisObject));
266 Assert(iframe && "Iframe is NULL");
268 AddEventListenerSupport::
269 CallStorageListenersFromDifferentIFrames(iframe, event);
272 return JSValueMakeNull(context);
274 CATCH_EXCEPTION_NO_MODIFABLE
275 CATCH_EXCEPTION_CONVERSION
276 CATCH_EXCEPTION_NULL_PTR
277 CATCH_EXCEPTION_PLATFORM_ERROR
278 CATCH_EXCEPTION_SECURITY
281 JSValueRef JSPreferences::setItem(JSContextRef context,
283 JSObjectRef thisObject,
284 size_t /*argumentCount*/,
285 const JSValueRef arguments[],
286 JSValueRef* exception)
289 LogDebug("This: " << thisObject);
290 LogDebug("Object: " << object);
293 Converter converter(context);
295 std::string key = converter.toString(arguments[0]);
296 std::string value = converter.tryString(arguments[1]);
298 auto event = modifyItemAndCreateEvent(ModificationType::SetItem,
303 auto iframe = IFrameSupport::
304 getIFrameObjectForWidget(getWidgetObject(thisObject));
305 Assert(iframe && "Iframe is NULL");
307 AddEventListenerSupport::
308 CallStorageListenersFromDifferentIFrames(iframe, event);
312 return JSValueMakeUndefined(context);
314 CATCH_EXCEPTION_NO_MODIFABLE
315 CATCH_EXCEPTION_CONVERSION
316 CATCH_EXCEPTION_NULL_PTR
317 CATCH_EXCEPTION_PLATFORM_ERROR
318 CATCH_EXCEPTION_SECURITY
319 CATCH_EXCEPTION_OUT_OF_RANGE
322 JSValueRef JSPreferences::clear(JSContextRef context,
323 JSObjectRef /*object*/,
324 JSObjectRef thisObject,
325 size_t /*argumentCount*/,
326 const JSValueRef /*arguments*/[],
327 JSValueRef* exception)
332 getIStorage(thisObject)->clear(false);
334 auto iframe = IFrameSupport::
335 getIFrameObjectForWidget(getWidgetObject(thisObject));
337 Assert(iframe && "Iframe is NULL");
339 //create event object
340 IStorageEventPtr storageEvent = getStorageEvent();
342 AddEventListenerSupport::
343 CallStorageListenersFromDifferentIFrames(iframe, storageEvent);
347 return JSValueMakeNull(context);
349 CATCH_EXCEPTION_NULL_PTR
350 CATCH_EXCEPTION_PLATFORM_ERROR
351 CATCH_EXCEPTION_SECURITY
354 JSValueRef JSPreferences::getItem(JSContextRef context,
355 JSObjectRef /*object*/,
356 JSObjectRef thisObject,
357 size_t /*argumentCount*/,
358 const JSValueRef arguments[],
359 JSValueRef* exception)
364 Converter converter(context);
366 std::string key = converter.tryString(arguments[0]);
368 LogDebug("Getting item for key " << key);
370 DPL::Optional<std::string> value =
371 getIStorage(thisObject)->getValue(key);
374 return JSValueMakeNull(context);
376 return converter.toJSValueRef(*value);
379 CATCH_EXCEPTION_INVALID_ARG
380 CATCH_EXCEPTION_CONVERSION
381 CATCH_EXCEPTION_NULL_PTR
382 CATCH_EXCEPTION_PLATFORM_ERROR
383 CATCH_EXCEPTION_SECURITY
386 JSValueRef JSPreferences::key(JSContextRef context,
387 JSObjectRef /*object*/,
388 JSObjectRef thisObject,
389 size_t argumentCount,
390 const JSValueRef arguments[],
391 JSValueRef* exception)
396 if (argumentCount < 1) {
397 LogError("No argument found");
398 Throw(Commons::InvalidArgumentException);
401 Converter converter(context);
403 size_t n = converter.toSizeT(arguments[0]);
405 std::string value = getIStorage(thisObject)->getKeyByIndex(n);
409 return converter.toJSValueRef(value);
411 CATCH_EXCEPTION_CONVERSION
412 CATCH_EXCEPTION_NULL_PTR
413 CATCH_EXCEPTION_PLATFORM_ERROR
414 CATCH_EXCEPTION_SECURITY
415 CATCH_EXCEPTION_INVALID_ARG
418 JSValueRef JSPreferences::getLength(JSContextRef context,
420 JSStringRef /*propertyName*/,
421 JSValueRef* exception)
427 Converter converter(context);
429 size_t value = getIStorage(object)->getStorageSize();
430 return converter.toJSValueRef(value);
432 CATCH_EXCEPTION_CONVERSION
433 CATCH_EXCEPTION_NULL_PTR
434 CATCH_EXCEPTION_PLATFORM_ERROR
435 CATCH_EXCEPTION_SECURITY
436 CATCH_EXCEPTION_INVALID_ARG
439 bool JSPreferences::hasProperty(JSContextRef context,
441 JSStringRef propertyName)
446 Converter converter(context);
448 std::string key = converter.toString(propertyName);
450 if (!getIStorage(object)->getValue(key)) {
457 Catch(Commons::InvalidArgumentException) {
458 LogDebug("Pair for given key doesnt exist");
461 Catch(Commons::ConversionException) {
462 LogError("Error on conversion");
465 Catch(Commons::NullPointerException) {
466 LogError("Error on pointer, null value");
469 Catch(Commons::PlatformException){
470 LogError("PlatformException occured");
475 JSValueRef JSPreferences::getProperty(JSContextRef context,
477 JSStringRef propertyName,
478 JSValueRef* exception)
483 Converter converter(context);
485 std::string key = converter.toString(propertyName);
487 DPL::Optional<std::string> value =
488 getIStorage(object)->getValue(key);
493 return JSValueMakeNull(context);
495 return converter.toJSValueRef(*value);
499 CATCH_EXCEPTION_CONVERSION
500 CATCH_EXCEPTION_NULL_PTR
501 CATCH_EXCEPTION_PLATFORM_ERROR
502 CATCH_EXCEPTION_INVALID_ARG
505 bool JSPreferences::setProperty(JSContextRef context,
507 JSStringRef propertyName,
509 JSValueRef* exception)
514 Converter converter(context);
516 std::string key = converter.toString(propertyName);
517 std::string value = converter.toString(jvalue);
519 auto event = modifyItemAndCreateEvent(ModificationType::SetItem,
524 auto iframe = IFrameSupport::
525 getIFrameObjectForWidget(getWidgetObject(object));
526 Assert(iframe && "Iframe is NULL");
528 AddEventListenerSupport::
529 CallStorageListenersFromDifferentIFrames(iframe, event);
535 CATCH_EXCEPTION_NO_MODIFABLE
536 CATCH_EXCEPTION_OUT_OF_RANGE
537 CATCH_EXCEPTION_INVALID_ARG
538 CATCH_EXCEPTION_CONVERSION
539 CATCH_EXCEPTION_NULL_PTR
540 CATCH_EXCEPTION_PLATFORM_ERROR
541 CATCH_EXCEPTION_SECURITY
546 #undef CATCH_EXCEPTION_NO_MODIFABLE
547 #undef CATCH_EXCEPTION_CONVERSION
548 #undef CATCH_EXCEPTION_NULL_PTR
549 #undef CATCH_EXCEPTION_PLATFORM_ERROR
550 #undef CATCH_EXCEPTION_SECURITY
551 #undef CATCH_EXCEPTION_OUT_OF_RANGE
552 #undef CATCH_EXCEPTION_INVALID_ARG