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);
266 std::string oldValueStr = "";
267 std::string newValueStr = "";
269 if (!!oldValue) { oldValueStr = *oldValue; }
270 if (!!newValue) { newValueStr = *newValue; }
272 DispatchEventSupport::dispatchStorageEvent(g_context, key, oldValueStr, newValueStr, "");
275 return JSValueMakeNull(context);
277 CATCH_EXCEPTION_NO_MODIFABLE
278 CATCH_EXCEPTION_CONVERSION
279 CATCH_EXCEPTION_NULL_PTR
280 CATCH_EXCEPTION_PLATFORM_ERROR
281 CATCH_EXCEPTION_SECURITY
284 JSValueRef JSPreferences::setItem(JSContextRef context,
286 JSObjectRef thisObject,
287 size_t /*argumentCount*/,
288 const JSValueRef arguments[],
289 JSValueRef* exception)
292 LogDebug("This: " << thisObject);
293 LogDebug("Object: " << object);
296 Converter converter(context);
298 std::string key = converter.toString(arguments[0]);
299 std::string value = converter.tryString(arguments[1]);
301 DPL::Optional<std::string> oldValue = getIStorage(thisObject)->getValue(key);
302 getIStorage(thisObject)->setItem(key, value, false);
303 DPL::Optional<std::string> newValue = getIStorage(thisObject)->getValue(key);
305 JSContextRef g_context = JSContextGetGlobalContext(context);
306 std::string oldValueStr = "";
307 std::string newValueStr = "";
309 if (!!oldValue) { oldValueStr = *oldValue; }
310 if (!!newValue) { newValueStr = *newValue; }
312 DispatchEventSupport::dispatchStorageEvent(g_context, key, oldValueStr, newValueStr, "");
316 return JSValueMakeUndefined(context);
318 CATCH_EXCEPTION_NO_MODIFABLE
319 CATCH_EXCEPTION_CONVERSION
320 CATCH_EXCEPTION_NULL_PTR
321 CATCH_EXCEPTION_PLATFORM_ERROR
322 CATCH_EXCEPTION_SECURITY
323 CATCH_EXCEPTION_OUT_OF_RANGE
326 JSValueRef JSPreferences::clear(JSContextRef context,
327 JSObjectRef /*object*/,
328 JSObjectRef thisObject,
329 size_t /*argumentCount*/,
330 const JSValueRef /*arguments*/[],
331 JSValueRef* exception)
336 getIStorage(thisObject)->clear(false);
338 JSContextRef g_context = JSContextGetGlobalContext(context);
340 DispatchEventSupport::dispatchStorageEvent(g_context, "", "", "", "");
344 return JSValueMakeNull(context);
346 CATCH_EXCEPTION_NULL_PTR
347 CATCH_EXCEPTION_PLATFORM_ERROR
348 CATCH_EXCEPTION_SECURITY
351 JSValueRef JSPreferences::getItem(JSContextRef context,
352 JSObjectRef /*object*/,
353 JSObjectRef thisObject,
354 size_t /*argumentCount*/,
355 const JSValueRef arguments[],
356 JSValueRef* exception)
361 Converter converter(context);
363 std::string key = converter.tryString(arguments[0]);
365 LogDebug("Getting item for key " << key);
367 DPL::Optional<std::string> value =
368 getIStorage(thisObject)->getValue(key);
371 return JSValueMakeNull(context);
373 return converter.toJSValueRef(*value);
376 CATCH_EXCEPTION_INVALID_ARG
377 CATCH_EXCEPTION_CONVERSION
378 CATCH_EXCEPTION_NULL_PTR
379 CATCH_EXCEPTION_PLATFORM_ERROR
380 CATCH_EXCEPTION_SECURITY
383 JSValueRef JSPreferences::key(JSContextRef context,
384 JSObjectRef /*object*/,
385 JSObjectRef thisObject,
386 size_t argumentCount,
387 const JSValueRef arguments[],
388 JSValueRef* exception)
393 if (argumentCount < 1) {
394 LogError("No argument found");
395 Throw(Commons::InvalidArgumentException);
398 Converter converter(context);
400 size_t n = converter.toSizeT(arguments[0]);
402 std::string value = getIStorage(thisObject)->getKeyByIndex(n);
406 return converter.toJSValueRef(value);
408 CATCH_EXCEPTION_CONVERSION
409 CATCH_EXCEPTION_NULL_PTR
410 CATCH_EXCEPTION_PLATFORM_ERROR
411 CATCH_EXCEPTION_SECURITY
412 CATCH_EXCEPTION_INVALID_ARG
415 JSValueRef JSPreferences::getLength(JSContextRef context,
417 JSStringRef /*propertyName*/,
418 JSValueRef* exception)
424 Converter converter(context);
426 size_t value = getIStorage(object)->getStorageSize();
427 return converter.toJSValueRef(value);
429 CATCH_EXCEPTION_CONVERSION
430 CATCH_EXCEPTION_NULL_PTR
431 CATCH_EXCEPTION_PLATFORM_ERROR
432 CATCH_EXCEPTION_SECURITY
433 CATCH_EXCEPTION_INVALID_ARG
436 bool JSPreferences::hasProperty(JSContextRef context,
438 JSStringRef propertyName)
443 Converter converter(context);
445 std::string key = converter.toString(propertyName);
447 if (!getIStorage(object)->getValue(key)) {
454 Catch(Commons::InvalidArgumentException) {
455 LogDebug("Pair for given key doesnt exist");
458 Catch(Commons::ConversionException) {
459 LogError("Error on conversion");
462 Catch(Commons::NullPointerException) {
463 LogError("Error on pointer, null value");
466 Catch(Commons::PlatformException){
467 LogError("PlatformException occured");
472 JSValueRef JSPreferences::getProperty(JSContextRef context,
474 JSStringRef propertyName,
475 JSValueRef* exception)
480 Converter converter(context);
482 std::string key = converter.toString(propertyName);
484 DPL::Optional<std::string> value =
485 getIStorage(object)->getValue(key);
490 return JSValueMakeNull(context);
492 return converter.toJSValueRef(*value);
496 CATCH_EXCEPTION_CONVERSION
497 CATCH_EXCEPTION_NULL_PTR
498 CATCH_EXCEPTION_PLATFORM_ERROR
499 CATCH_EXCEPTION_INVALID_ARG
502 bool JSPreferences::setProperty(JSContextRef context,
504 JSStringRef propertyName,
506 JSValueRef* exception)
511 Converter converter(context);
513 std::string key = converter.toString(propertyName);
514 std::string value = converter.toString(jvalue);
516 DPL::Optional<std::string> oldValue = getIStorage(object)->getValue(key);
517 getIStorage(object)->setItem(key, value, false);
518 DPL::Optional<std::string> newValue = getIStorage(object)->getValue(key);
520 JSContextRef g_context = JSContextGetGlobalContext(context);
521 std::string oldValueStr = "";
522 std::string newValueStr = "";
524 if (!!oldValue) { oldValueStr = *oldValue; }
525 if (!!newValue) { newValueStr = *newValue; }
527 DispatchEventSupport::dispatchStorageEvent(g_context, key, oldValueStr, newValueStr, "");
533 CATCH_EXCEPTION_NO_MODIFABLE
534 CATCH_EXCEPTION_OUT_OF_RANGE
535 CATCH_EXCEPTION_INVALID_ARG
536 CATCH_EXCEPTION_CONVERSION
537 CATCH_EXCEPTION_NULL_PTR
538 CATCH_EXCEPTION_PLATFORM_ERROR
539 CATCH_EXCEPTION_SECURITY
544 #undef CATCH_EXCEPTION_NO_MODIFABLE
545 #undef CATCH_EXCEPTION_CONVERSION
546 #undef CATCH_EXCEPTION_NULL_PTR
547 #undef CATCH_EXCEPTION_PLATFORM_ERROR
548 #undef CATCH_EXCEPTION_SECURITY
549 #undef CATCH_EXCEPTION_OUT_OF_RANGE
550 #undef CATCH_EXCEPTION_INVALID_ARG