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/secure_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 _E("The item is read only"); \
51 return JSDOMExceptionFactory:: \
52 NoModificationAllowedException.make(context, exception); \
55 #define CATCH_EXCEPTION_CONVERSION \
56 Catch(Commons::ConversionException) { \
57 _E("Error on conversion"); \
58 return JSDOMExceptionFactory:: \
59 UnknownException.make(context, exception); \
62 #define CATCH_EXCEPTION_NULL_PTR \
63 Catch(Commons::NullPointerException) { \
64 _E("Error on pointer, null value"); \
65 return JSDOMExceptionFactory:: \
66 UnknownException.make(context, exception); \
69 #define CATCH_EXCEPTION_PLATFORM_ERROR \
70 Catch(Commons::PlatformException){ \
71 _E("PlatformException occured"); \
72 return JSDOMExceptionFactory:: \
73 UnknownException.make(context, exception); \
76 #define CATCH_EXCEPTION_SECURITY \
77 Catch(Commons::SecurityException){ \
78 _E("Security exception occured"); \
79 return JSDOMExceptionFactory:: \
80 SecurityException.make(context, exception); \
83 #define CATCH_EXCEPTION_OUT_OF_RANGE \
84 Catch(Commons::OutOfRangeException) { \
85 _E("OutOfRangeException"); \
86 return JSDOMExceptionFactory:: \
87 QuotaExceededException.make(context, exception); \
90 #define CATCH_EXCEPTION_INVALID_ARG \
91 Catch(Commons::InvalidArgumentException) { \
92 _E("Pair for given key doesnt exist"); \
93 return JSValueMakeNull(context); \
96 namespace WrtPlugins {
98 ILocalStoragePtr getIStorage(JSObjectRef arg)
100 _D("get localstorage object");
101 LocalStoragePrivateData* priv =
102 static_cast<LocalStoragePrivateData*>(JSObjectGetPrivate(arg));
105 _E("Private object not initialized");
106 ThrowMsg(Commons::NullPointerException,
107 "Private object not initialized");
110 return priv->istorage;
113 JSObjectRef getWidgetObject(JSObjectRef arg)
115 _D("get widget object");
116 LocalStoragePrivateData* priv =
117 static_cast<LocalStoragePrivateData*>(JSObjectGetPrivate(arg));
120 _E("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 _D("entered. Context: %p", 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));
244 JSValueRef JSPreferences::removeItem(JSContextRef context,
245 JSObjectRef /*object*/,
246 JSObjectRef thisObject,
247 size_t /*argumentCount*/,
248 const JSValueRef arguments[],
249 JSValueRef* exception)
254 Converter converter(context);
256 std::string key = converter.toString(arguments[0]);
258 DPL::Optional<std::string> oldValue = getIStorage(thisObject)->getValue(key);
259 getIStorage(thisObject)->removeItem(key);
260 DPL::Optional<std::string> newValue = getIStorage(thisObject)->getValue(key);
262 JSContextRef g_context = JSContextGetGlobalContext(context);
264 DispatchEventSupport::dispatchStorageEvent(g_context, key, oldValue, newValue, "");
266 return JSValueMakeNull(context);
268 CATCH_EXCEPTION_NO_MODIFABLE
269 CATCH_EXCEPTION_CONVERSION
270 CATCH_EXCEPTION_NULL_PTR
271 CATCH_EXCEPTION_PLATFORM_ERROR
272 CATCH_EXCEPTION_SECURITY
275 JSValueRef JSPreferences::setItem(JSContextRef context,
276 JSObjectRef /*object*/,
277 JSObjectRef thisObject,
278 size_t /*argumentCount*/,
279 const JSValueRef arguments[],
280 JSValueRef* exception)
285 Converter converter(context);
287 std::string key = converter.toString(arguments[0]);
288 std::string value = converter.tryString(arguments[1]);
290 DPL::Optional<std::string> oldValue = getIStorage(thisObject)->getValue(key);
291 getIStorage(thisObject)->setItem(key, value, false);
292 DPL::Optional<std::string> newValue = getIStorage(thisObject)->getValue(key);
294 JSContextRef g_context = JSContextGetGlobalContext(context);
296 DispatchEventSupport::dispatchStorageEvent(g_context, key, oldValue, newValue, "");
298 return JSValueMakeUndefined(context);
300 CATCH_EXCEPTION_NO_MODIFABLE
301 CATCH_EXCEPTION_CONVERSION
302 CATCH_EXCEPTION_NULL_PTR
303 CATCH_EXCEPTION_PLATFORM_ERROR
304 CATCH_EXCEPTION_SECURITY
305 CATCH_EXCEPTION_OUT_OF_RANGE
308 JSValueRef JSPreferences::clear(JSContextRef context,
309 JSObjectRef /*object*/,
310 JSObjectRef thisObject,
311 size_t /*argumentCount*/,
312 const JSValueRef /*arguments*/[],
313 JSValueRef* exception)
318 getIStorage(thisObject)->clear(false);
320 JSContextRef g_context = JSContextGetGlobalContext(context);
322 const auto& null = DPL::Optional<std::string>::Null;
324 DispatchEventSupport::dispatchStorageEvent(g_context, null, null, null, "");
326 return JSValueMakeNull(context);
328 CATCH_EXCEPTION_NULL_PTR
329 CATCH_EXCEPTION_PLATFORM_ERROR
330 CATCH_EXCEPTION_SECURITY
333 JSValueRef JSPreferences::getItem(JSContextRef context,
334 JSObjectRef /*object*/,
335 JSObjectRef thisObject,
336 size_t /*argumentCount*/,
337 const JSValueRef arguments[],
338 JSValueRef* exception)
343 Converter converter(context);
345 std::string key = converter.tryString(arguments[0]);
347 _D("Getting item for key %s", key.c_str());
349 DPL::Optional<std::string> value =
350 getIStorage(thisObject)->getValue(key);
353 return JSValueMakeNull(context);
355 return converter.toJSValueRef(*value);
358 CATCH_EXCEPTION_INVALID_ARG
359 CATCH_EXCEPTION_CONVERSION
360 CATCH_EXCEPTION_NULL_PTR
361 CATCH_EXCEPTION_PLATFORM_ERROR
362 CATCH_EXCEPTION_SECURITY
365 JSValueRef JSPreferences::key(JSContextRef context,
366 JSObjectRef /*object*/,
367 JSObjectRef thisObject,
368 size_t argumentCount,
369 const JSValueRef arguments[],
370 JSValueRef* exception)
375 if (argumentCount < 1) {
376 _E("No argument found");
377 Throw(Commons::InvalidArgumentException);
380 Converter converter(context);
382 size_t n = converter.toSizeT(arguments[0]);
384 std::string value = getIStorage(thisObject)->getKeyByIndex(n);
386 return converter.toJSValueRef(value);
388 CATCH_EXCEPTION_CONVERSION
389 CATCH_EXCEPTION_NULL_PTR
390 CATCH_EXCEPTION_PLATFORM_ERROR
391 CATCH_EXCEPTION_SECURITY
392 CATCH_EXCEPTION_INVALID_ARG
395 JSValueRef JSPreferences::getLength(JSContextRef context,
397 JSStringRef /*propertyName*/,
398 JSValueRef* exception)
404 Converter converter(context);
406 size_t value = getIStorage(object)->getStorageSize();
407 return converter.toJSValueRef(value);
409 CATCH_EXCEPTION_CONVERSION
410 CATCH_EXCEPTION_NULL_PTR
411 CATCH_EXCEPTION_PLATFORM_ERROR
412 CATCH_EXCEPTION_SECURITY
413 CATCH_EXCEPTION_INVALID_ARG
416 bool JSPreferences::hasProperty(JSContextRef context,
418 JSStringRef propertyName)
423 Converter converter(context);
425 std::string key = converter.toString(propertyName);
427 if (!getIStorage(object)->getValue(key)) {
434 Catch(Commons::InvalidArgumentException) {
435 _E("Pair for given key doesnt exist");
438 Catch(Commons::ConversionException) {
439 _E("Error on conversion");
442 Catch(Commons::NullPointerException) {
443 _E("Error on pointer, null value");
446 Catch(Commons::PlatformException){
447 _E("PlatformException occured");
452 JSValueRef JSPreferences::getProperty(JSContextRef context,
454 JSStringRef propertyName,
455 JSValueRef* exception)
460 Converter converter(context);
462 std::string key = converter.toString(propertyName);
464 DPL::Optional<std::string> value =
465 getIStorage(object)->getValue(key);
468 return JSValueMakeNull(context);
470 return converter.toJSValueRef(*value);
474 CATCH_EXCEPTION_CONVERSION
475 CATCH_EXCEPTION_NULL_PTR
476 CATCH_EXCEPTION_PLATFORM_ERROR
477 CATCH_EXCEPTION_INVALID_ARG
480 bool JSPreferences::setProperty(JSContextRef context,
482 JSStringRef propertyName,
484 JSValueRef* exception)
489 Converter converter(context);
491 std::string key = converter.toString(propertyName);
492 std::string value = converter.toString(jvalue);
494 DPL::Optional<std::string> oldValue = getIStorage(object)->getValue(key);
495 getIStorage(object)->setItem(key, value, false);
496 DPL::Optional<std::string> newValue = getIStorage(object)->getValue(key);
498 JSContextRef g_context = JSContextGetGlobalContext(context);
499 std::string oldValueStr = "";
500 std::string newValueStr = "";
502 if (!!oldValue) { oldValueStr = *oldValue; }
503 if (!!newValue) { newValueStr = *newValue; }
505 DispatchEventSupport::dispatchStorageEvent(g_context, key, oldValueStr, newValueStr, "");
509 CATCH_EXCEPTION_NO_MODIFABLE
510 CATCH_EXCEPTION_OUT_OF_RANGE
511 CATCH_EXCEPTION_INVALID_ARG
512 CATCH_EXCEPTION_CONVERSION
513 CATCH_EXCEPTION_NULL_PTR
514 CATCH_EXCEPTION_PLATFORM_ERROR
515 CATCH_EXCEPTION_SECURITY
520 #undef CATCH_EXCEPTION_NO_MODIFABLE
521 #undef CATCH_EXCEPTION_CONVERSION
522 #undef CATCH_EXCEPTION_NULL_PTR
523 #undef CATCH_EXCEPTION_PLATFORM_ERROR
524 #undef CATCH_EXCEPTION_SECURITY
525 #undef CATCH_EXCEPTION_OUT_OF_RANGE
526 #undef CATCH_EXCEPTION_INVALID_ARG