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 <dispatch-event/dispatch_event_support.h>
35 // import temporarily from JSContextRefPrivate.h
36 extern "C" JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx);
39 using namespace WrtDeviceApis;
40 using namespace WrtDeviceApis::Commons;
41 using namespace WrtDeviceApis::CommonsJavaScript;
42 using namespace WrtDeviceApis::LocalStorage::Api;
43 using namespace WrtDeviceApis::StorageEvent::Api;
45 #define PREFERENCES_PLUGIN_NAME "preferences"
46 #define LOCAL_STORAGE_PROPERTY_LENGTH "length"
48 #define CATCH_EXCEPTION_NO_MODIFABLE \
49 Catch(Commons::LocalStorageValueNoModifableException) { \
50 LogError("The item is read only"); \
51 return JSDOMExceptionFactory:: \
52 NoModificationAllowedException.make(context, exception); \
55 #define CATCH_EXCEPTION_CONVERSION \
56 Catch(Commons::ConversionException) { \
57 LogError("Error on conversion"); \
58 return JSDOMExceptionFactory:: \
59 UnknownException.make(context, exception); \
62 #define CATCH_EXCEPTION_NULL_PTR \
63 Catch(Commons::NullPointerException) { \
64 LogError("Error on pointer, null value"); \
65 return JSDOMExceptionFactory:: \
66 UnknownException.make(context, exception); \
69 #define CATCH_EXCEPTION_PLATFORM_ERROR \
70 Catch(Commons::PlatformException){ \
71 LogError("PlatformException occured"); \
72 return JSDOMExceptionFactory:: \
73 UnknownException.make(context, exception); \
76 #define CATCH_EXCEPTION_SECURITY \
77 Catch(Commons::SecurityException){ \
78 LogError("Security exception occured"); \
79 return JSDOMExceptionFactory:: \
80 SecurityException.make(context, exception); \
83 #define CATCH_EXCEPTION_OUT_OF_RANGE \
84 Catch(Commons::OutOfRangeException) { \
85 LogError("OutOfRangeException"); \
86 return JSDOMExceptionFactory:: \
87 QuotaExceededException.make(context, exception); \
90 #define CATCH_EXCEPTION_INVALID_ARG \
91 Catch(Commons::InvalidArgumentException) { \
92 LogError("Pair for given key doesnt exist"); \
93 return JSValueMakeNull(context); \
96 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;
130 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) {
146 getIStorage(thisObject)->setItem(key, value, false);
147 } else if (ModificationType::RemoveItem == type) {
148 getIStorage(thisObject)->removeItem(key);
150 Assert(0 && "Wrong Modification type");
153 DPL::Optional<std::string> newValue =
154 getIStorage(thisObject)->getValue(key);
156 //create event object
157 IStorageEventPtr storageEvent = getStorageEvent();
160 storageEvent->setKey(key);
163 storageEvent->setOldValue(*oldValue);
167 storageEvent->setNewValue(*newValue);
173 JSClassDefinition JSPreferences::m_classInfo = {
175 kJSClassAttributeNone,
176 PREFERENCES_PLUGIN_NAME,
185 NULL, //DeleteProperty,
186 NULL, //GetPropertyNames,
187 NULL, //CallAsFunction,
188 NULL, //CallAsConstructor,
190 NULL, //ConvertToType,
193 JSStaticFunction JSPreferences::m_function[] = {
194 { "setItem", JSPreferences::setItem, kJSPropertyAttributeNone },
195 { "removeItem", JSPreferences::removeItem, kJSPropertyAttributeNone },
196 { "getItem", JSPreferences::getItem, kJSPropertyAttributeNone },
197 { "clear", JSPreferences::clear, kJSPropertyAttributeNone },
198 { "key", JSPreferences::key, kJSPropertyAttributeNone },
202 JSStaticValue JSPreferences::m_property[] = {
203 { LOCAL_STORAGE_PROPERTY_LENGTH,
204 JSPreferences::getLength,
206 kJSPropertyAttributeReadOnly },
210 JSClassRef JSPreferences::getClassRef()
213 m_jsClassRef = JSClassCreate(&m_classInfo);
218 const JSClassDefinition* JSPreferences::getClassInfo()
223 JSClassRef JSPreferences::m_jsClassRef =
224 JSClassCreate(JSPreferences::getClassInfo());
226 void JSPreferences::initialize(JSContextRef context,
229 LogDebug("entered. Context: " << context);
231 LocalStoragePrivateData* priv =
232 static_cast<LocalStoragePrivateData*>(JSObjectGetPrivate(object));
234 Assert(priv && "private object of preferences is NULL");
237 void JSPreferences::finalize(JSObjectRef object)
240 LocalStoragePrivateData* priv =
241 static_cast<LocalStoragePrivateData*>(JSObjectGetPrivate(object));
244 LogDebug("private object is realised");
247 JSValueRef JSPreferences::removeItem(JSContextRef context,
248 JSObjectRef /*object*/,
249 JSObjectRef thisObject,
250 size_t /*argumentCount*/,
251 const JSValueRef arguments[],
252 JSValueRef* exception)
257 Converter converter(context);
259 std::string key = converter.toString(arguments[0]);
261 DPL::Optional<std::string> oldValue = getIStorage(thisObject)->getValue(key);
262 getIStorage(thisObject)->removeItem(key);
263 DPL::Optional<std::string> newValue = getIStorage(thisObject)->getValue(key);
265 JSContextRef g_context = JSContextGetGlobalContext(context);
267 DispatchEventSupport::dispatchStorageEvent(g_context, key, oldValue, newValue, "");
270 return JSValueMakeNull(context);
272 CATCH_EXCEPTION_NO_MODIFABLE
273 CATCH_EXCEPTION_CONVERSION
274 CATCH_EXCEPTION_NULL_PTR
275 CATCH_EXCEPTION_PLATFORM_ERROR
276 CATCH_EXCEPTION_SECURITY
279 JSValueRef JSPreferences::setItem(JSContextRef context,
281 JSObjectRef thisObject,
282 size_t /*argumentCount*/,
283 const JSValueRef arguments[],
284 JSValueRef* exception)
287 LogDebug("This: " << thisObject);
288 LogDebug("Object: " << object);
291 Converter converter(context);
293 std::string key = converter.toString(arguments[0]);
294 std::string value = converter.tryString(arguments[1]);
296 DPL::Optional<std::string> oldValue = getIStorage(thisObject)->getValue(key);
297 getIStorage(thisObject)->setItem(key, value, false);
298 DPL::Optional<std::string> newValue = getIStorage(thisObject)->getValue(key);
300 JSContextRef g_context = JSContextGetGlobalContext(context);
302 DispatchEventSupport::dispatchStorageEvent(g_context, key, oldValue, newValue, "");
306 return JSValueMakeUndefined(context);
308 CATCH_EXCEPTION_NO_MODIFABLE
309 CATCH_EXCEPTION_CONVERSION
310 CATCH_EXCEPTION_NULL_PTR
311 CATCH_EXCEPTION_PLATFORM_ERROR
312 CATCH_EXCEPTION_SECURITY
313 CATCH_EXCEPTION_OUT_OF_RANGE
316 JSValueRef JSPreferences::clear(JSContextRef context,
317 JSObjectRef /*object*/,
318 JSObjectRef thisObject,
319 size_t /*argumentCount*/,
320 const JSValueRef /*arguments*/[],
321 JSValueRef* exception)
326 getIStorage(thisObject)->clear(false);
328 JSContextRef g_context = JSContextGetGlobalContext(context);
330 const auto& null = DPL::Optional<std::string>::Null;
332 DispatchEventSupport::dispatchStorageEvent(g_context, null, null, null, "");
336 return JSValueMakeNull(context);
338 CATCH_EXCEPTION_NULL_PTR
339 CATCH_EXCEPTION_PLATFORM_ERROR
340 CATCH_EXCEPTION_SECURITY
343 JSValueRef JSPreferences::getItem(JSContextRef context,
344 JSObjectRef /*object*/,
345 JSObjectRef thisObject,
346 size_t /*argumentCount*/,
347 const JSValueRef arguments[],
348 JSValueRef* exception)
353 Converter converter(context);
355 std::string key = converter.tryString(arguments[0]);
357 LogDebug("Getting item for key " << key);
359 DPL::Optional<std::string> value =
360 getIStorage(thisObject)->getValue(key);
363 return JSValueMakeNull(context);
365 return converter.toJSValueRef(*value);
368 CATCH_EXCEPTION_INVALID_ARG
369 CATCH_EXCEPTION_CONVERSION
370 CATCH_EXCEPTION_NULL_PTR
371 CATCH_EXCEPTION_PLATFORM_ERROR
372 CATCH_EXCEPTION_SECURITY
375 JSValueRef JSPreferences::key(JSContextRef context,
376 JSObjectRef /*object*/,
377 JSObjectRef thisObject,
378 size_t argumentCount,
379 const JSValueRef arguments[],
380 JSValueRef* exception)
385 if (argumentCount < 1) {
386 LogError("No argument found");
387 Throw(Commons::InvalidArgumentException);
390 Converter converter(context);
392 size_t n = converter.toSizeT(arguments[0]);
394 std::string value = getIStorage(thisObject)->getKeyByIndex(n);
398 return converter.toJSValueRef(value);
400 CATCH_EXCEPTION_CONVERSION
401 CATCH_EXCEPTION_NULL_PTR
402 CATCH_EXCEPTION_PLATFORM_ERROR
403 CATCH_EXCEPTION_SECURITY
404 CATCH_EXCEPTION_INVALID_ARG
407 JSValueRef JSPreferences::getLength(JSContextRef context,
409 JSStringRef /*propertyName*/,
410 JSValueRef* exception)
416 Converter converter(context);
418 size_t value = getIStorage(object)->getStorageSize();
419 return converter.toJSValueRef(value);
421 CATCH_EXCEPTION_CONVERSION
422 CATCH_EXCEPTION_NULL_PTR
423 CATCH_EXCEPTION_PLATFORM_ERROR
424 CATCH_EXCEPTION_SECURITY
425 CATCH_EXCEPTION_INVALID_ARG
428 bool JSPreferences::hasProperty(JSContextRef context,
430 JSStringRef propertyName)
435 Converter converter(context);
437 std::string key = converter.toString(propertyName);
439 if (!getIStorage(object)->getValue(key)) {
446 Catch(Commons::InvalidArgumentException) {
447 LogDebug("Pair for given key doesnt exist");
450 Catch(Commons::ConversionException) {
451 LogError("Error on conversion");
454 Catch(Commons::NullPointerException) {
455 LogError("Error on pointer, null value");
458 Catch(Commons::PlatformException){
459 LogError("PlatformException occured");
464 JSValueRef JSPreferences::getProperty(JSContextRef context,
466 JSStringRef propertyName,
467 JSValueRef* exception)
472 Converter converter(context);
474 std::string key = converter.toString(propertyName);
476 DPL::Optional<std::string> value =
477 getIStorage(object)->getValue(key);
482 return JSValueMakeNull(context);
484 return converter.toJSValueRef(*value);
488 CATCH_EXCEPTION_CONVERSION
489 CATCH_EXCEPTION_NULL_PTR
490 CATCH_EXCEPTION_PLATFORM_ERROR
491 CATCH_EXCEPTION_INVALID_ARG
494 bool JSPreferences::setProperty(JSContextRef context,
496 JSStringRef propertyName,
498 JSValueRef* exception)
503 Converter converter(context);
505 std::string key = converter.toString(propertyName);
506 std::string value = converter.toString(jvalue);
508 DPL::Optional<std::string> oldValue = getIStorage(object)->getValue(key);
509 getIStorage(object)->setItem(key, value, false);
510 DPL::Optional<std::string> newValue = getIStorage(object)->getValue(key);
512 JSContextRef g_context = JSContextGetGlobalContext(context);
513 std::string oldValueStr = "";
514 std::string newValueStr = "";
516 if (!!oldValue) { oldValueStr = *oldValue; }
517 if (!!newValue) { newValueStr = *newValue; }
519 DispatchEventSupport::dispatchStorageEvent(g_context, key, oldValueStr, newValueStr, "");
525 CATCH_EXCEPTION_NO_MODIFABLE
526 CATCH_EXCEPTION_OUT_OF_RANGE
527 CATCH_EXCEPTION_INVALID_ARG
528 CATCH_EXCEPTION_CONVERSION
529 CATCH_EXCEPTION_NULL_PTR
530 CATCH_EXCEPTION_PLATFORM_ERROR
531 CATCH_EXCEPTION_SECURITY
536 #undef CATCH_EXCEPTION_NO_MODIFABLE
537 #undef CATCH_EXCEPTION_CONVERSION
538 #undef CATCH_EXCEPTION_NULL_PTR
539 #undef CATCH_EXCEPTION_PLATFORM_ERROR
540 #undef CATCH_EXCEPTION_SECURITY
541 #undef CATCH_EXCEPTION_OUT_OF_RANGE
542 #undef CATCH_EXCEPTION_INVALID_ARG