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.
19 * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
25 #include <CommonsJavaScript/Converter.h>
26 #include <dpl/log/log.h>
27 #include <dpl/assert.h>
28 #include <Widget/WidgetFactory.h>
29 #include <CommonsJavaScript/JSDOMExceptionFactory.h>
30 #include "JSPreferences.h"
31 #include <Widget/IWidget.h>
32 #include <LocalStorage/LocalStorageMgr.h>
33 #include <Commons/WrtAccess/WrtAccess.h>
35 #define CATCH_EXCEPTION_NO_MODIFABLE \
36 Catch(Commons::LocalStorageValueNoModifableException) { \
37 LogError("The item is read only"); \
38 return JSDOMExceptionFactory:: \
39 NoModificationAllowedException.make(context, exception); \
42 #define CATCH_EXCEPTION_CONVERSION \
43 Catch(Commons::ConversionException) { \
44 LogError("Error on conversion"); \
45 return JSDOMExceptionFactory:: \
46 UnknownException.make(context, exception); \
49 #define CATCH_EXCEPTION_NULL_PTR \
50 Catch(Commons::NullPointerException) { \
51 LogError("Error on pointer, null value"); \
52 return JSDOMExceptionFactory:: \
53 UnknownException.make(context, exception); \
56 #define CATCH_EXCEPTION_PLATFORM_ERROR \
57 Catch(Commons::PlatformException){ \
58 LogError("PlatformException occured"); \
59 return JSDOMExceptionFactory:: \
60 UnknownException.make(context, exception); \
63 #define CATCH_EXCEPTION_SECURITY \
64 Catch(Commons::SecurityException){ \
65 LogError("Security exception occured"); \
66 return JSDOMExceptionFactory:: \
67 SecurityException.make(context, exception); \
70 #define CATCH_EXCEPTION_OUT_OF_RANGE \
71 Catch(Commons::OutOfRangeException) { \
72 LogError("OutOfRangeException"); \
73 return JSDOMExceptionFactory:: \
74 QuotaExceededException.make(context, exception); \
77 #define CATCH_EXCEPTION_INVALID_ARG \
78 Catch(Commons::InvalidArgumentException) { \
79 LogError("Pair for given key doesnt exist"); \
80 return JSValueMakeNull(context); \
83 #define WIDGET_PLUGIN_NAME "Widget"
85 #define WRT_WIDGET_PROPERTY_AUTHOR "author"
86 #define WRT_WIDGET_PROPERTY_AUTHOR_EMAIL "authorEmail"
87 #define WRT_WIDGET_PROPERTY_AUTHOR_HREF "authorHref"
88 #define WRT_WIDGET_PROPERTY_DESCRIPTION "description"
89 #define WRT_WIDGET_PROPERTY_ID "id"
90 #define WRT_WIDGET_PROPERTY_NAME "name"
91 #define WRT_WIDGET_PROPERTY_SHORT_NAME "shortName"
92 #define WRT_WIDGET_PROPERTY_VERSION "version"
93 #define WRT_WIDGET_PROPERTY_HEIGHT "height"
94 #define WRT_WIDGET_PROPERTY_WIDTH "width"
96 namespace WrtPlugins {
98 using namespace WrtDeviceApis;
99 using namespace WrtDeviceApis::Commons;
100 using namespace WrtDeviceApis::CommonsJavaScript;
101 using namespace WrtDeviceApis::Widget;
103 struct WidgetPrivateObject
105 Widget::Api::IWidgetPtr iwidget;
106 JSObjectRef preferencesObject;
108 //int widgetId // TODO: check is it necessary (g.rynkowski)
109 JSObjectRef widgetObject;
111 typedef std::shared_ptr<WidgetPrivateObject> WidgetPrivateObjectPtr;
113 typedef WrtDeviceApis::CommonsJavaScript::PrivateObjectT
114 <WidgetPrivateObjectPtr>::Type JSWidgetPrivateObject;
116 WrtDeviceApis::Widget::Api::IWidgetPtr getIWidget(JSObjectRef arg)
118 JSWidgetPrivateObject* priv =
119 static_cast<JSWidgetPrivateObject*>(JSObjectGetPrivate(arg));
122 LogError("Private object not initialized");
123 ThrowMsg(Commons::NullPointerException,
124 "Private object not initialized");
127 return priv->getObject()->iwidget;
130 LocalStorage::Api::ILocalStoragePtr getLocalStorage(int widgetId)
132 LocalStorage::Api::ILocalStoragePtr storage(
133 LocalStorage::Api::getLocalStorage(widgetId));
138 JSObjectRef getPreferences(JSObjectRef arg)
140 JSWidgetPrivateObject* priv =
141 static_cast<JSWidgetPrivateObject*>(JSObjectGetPrivate(arg));
144 LogError("Private object not initialized");
148 return priv->getObject()->preferencesObject;
151 JSObjectRef createPreferencesObject(JSContextRef context,
152 JSObjectRef widgetObject,
155 Assert(widgetObject && "Widget Object can'n be null");
156 //delete is invoked in JSPreferences::finalize
157 LocalStoragePrivateData* priv = new LocalStoragePrivateData;
158 Assert(priv && "Private data is null");
159 priv->istorage = getLocalStorage(widgetId);
160 priv->widgetObject = widgetObject;
162 JSObjectRef preferences = JSObjectMake(context,
163 JSPreferences::getClassRef(),
167 LogError("Preferences object is null");
170 //Unprotect is called in JSWidget::finalize
171 JSValueProtect(context, preferences);
176 JSClassDefinition JSWidget::m_classInfo = {
178 kJSClassAttributeNone,
188 NULL, //DeleteProperty,
189 NULL, //GetPropertyNames,
190 NULL, //CallAsFunction,
193 NULL, //ConvertToType,
196 JSStaticValue JSWidget::m_property[] = {
197 { WRT_WIDGET_PROPERTY_AUTHOR, JSWidget::getAuthor,
198 0, kJSPropertyAttributeReadOnly },
199 { WRT_WIDGET_PROPERTY_AUTHOR_EMAIL, JSWidget::getAuthorEmail,
200 0, kJSPropertyAttributeReadOnly },
201 { WRT_WIDGET_PROPERTY_AUTHOR_HREF, JSWidget::getAuthorHref,
202 0, kJSPropertyAttributeReadOnly },
203 { WRT_WIDGET_PROPERTY_DESCRIPTION, JSWidget::getDescription,
204 0, kJSPropertyAttributeReadOnly },
205 { WRT_WIDGET_PROPERTY_ID, JSWidget::getId,
206 0, kJSPropertyAttributeReadOnly },
207 { WRT_WIDGET_PROPERTY_NAME, JSWidget::getName,
208 0, kJSPropertyAttributeReadOnly },
209 { WRT_WIDGET_PROPERTY_SHORT_NAME, JSWidget::getShortName,
210 0, kJSPropertyAttributeReadOnly },
211 { WRT_WIDGET_PROPERTY_VERSION, JSWidget::getVersion,
212 0, kJSPropertyAttributeReadOnly },
213 { WRT_WIDGET_PROPERTY_HEIGHT, JSWidget::getHeight,
214 0, kJSPropertyAttributeReadOnly },
215 { WRT_WIDGET_PROPERTY_WIDTH, JSWidget::getWidth,
216 0, kJSPropertyAttributeReadOnly },
220 JSClassRef JSWidget::getClassRef()
223 m_jsClassRef = JSClassCreate(&m_classInfo);
228 const JSClassDefinition* JSWidget::getClassInfo()
233 JSClassRef JSWidget::m_jsClassRef = JSClassCreate(JSWidget::getClassInfo());
235 JSContextRef JSWidget::m_globalContext = NULL;
237 void JSWidget::initialize(JSContextRef context,
240 LogDebug("entered. Context : " << context << ", Object: " << object);
242 JSWidgetPrivateObject* priv =
243 static_cast<JSWidgetPrivateObject*>(JSObjectGetPrivate(object));
246 LogDebug("creation private object");
249 using namespace WrtDeviceApis::Commons;
251 Widget::Api::IWidgetPtr widget =
252 Api::WidgetFactory::createWidget();
253 int widgetId = WrtAccessSingleton::Instance().getWidgetId();
254 JSObjectRef preferences =
255 createPreferencesObject(context,
259 LogError("Failed to create preferences object");
262 WidgetPrivateObjectPtr widgetPriv(new WidgetPrivateObject);
263 widgetPriv->iwidget = widget;
264 widgetPriv->preferencesObject = preferences;
266 priv = new JSWidgetPrivateObject(context, widgetPriv);
267 JSObjectSetPrivate(object, priv);
269 Catch(Commons::InvalidArgumentException){
270 LogError("You should register widget id in ON_WIDGET_START");
273 Catch(DPL::Exception) {
274 LogError("Failed to create private object for JSWidget");
280 void JSWidget::finalize(JSObjectRef object)
283 LogDebug("Object: " << object);
284 JSWidgetPrivateObject* priv =
285 static_cast<JSWidgetPrivateObject*>(JSObjectGetPrivate(object));
288 JSValueUnprotect(priv->getContext(),
289 priv->getObject()->preferencesObject);
292 LogDebug("private object is released");
294 LogDebug("private object wasn't created");
298 void JSWidget::acquireGlobalContext(java_script_context_t global_context,
299 js_object_instance_t /*iframe*/,
300 js_object_instance_t /*object*/)
302 if (!m_globalContext) {
303 m_globalContext = static_cast<JSContextRef>(global_context);
304 LogInfo("Global context acquired.");
306 LogInfo("Global context already set.");
310 JSValueRef JSWidget::getAuthor(JSContextRef context,
312 JSStringRef /*propertyName*/,
313 JSValueRef* exception)
318 Converter converter(context);
319 return converter.toJSValueRef(getIWidget(object)->getAuthor());
321 CATCH_EXCEPTION_CONVERSION
322 CATCH_EXCEPTION_NULL_PTR
323 CATCH_EXCEPTION_PLATFORM_ERROR
326 JSValueRef JSWidget::getAuthorEmail(JSContextRef context,
328 JSStringRef /*propertyName*/,
329 JSValueRef* exception)
332 Converter converter(context);
333 return converter.toJSValueRef(getIWidget(object)->getAuthorEmail());
335 CATCH_EXCEPTION_CONVERSION
336 CATCH_EXCEPTION_NULL_PTR
337 CATCH_EXCEPTION_PLATFORM_ERROR
340 JSValueRef JSWidget::getAuthorHref(JSContextRef context,
342 JSStringRef /*propertyName*/,
343 JSValueRef* exception)
346 Converter converter(context);
347 return converter.toJSValueRef(getIWidget(object)->getAuthorHref());
349 CATCH_EXCEPTION_CONVERSION
350 CATCH_EXCEPTION_NULL_PTR
351 CATCH_EXCEPTION_PLATFORM_ERROR
354 JSValueRef JSWidget::getDescription(JSContextRef context,
356 JSStringRef /*propertyName*/,
357 JSValueRef* exception)
360 Converter converter(context);
361 return converter.toJSValueRef(getIWidget(object)->getDescription());
363 CATCH_EXCEPTION_CONVERSION
364 CATCH_EXCEPTION_NULL_PTR
365 CATCH_EXCEPTION_PLATFORM_ERROR
368 JSValueRef JSWidget::getId(JSContextRef context,
370 JSStringRef /*propertyName*/,
371 JSValueRef* exception)
374 Converter converter(context);
375 return converter.toJSValueRef(getIWidget(object)->getId());
377 CATCH_EXCEPTION_CONVERSION
378 CATCH_EXCEPTION_NULL_PTR
379 CATCH_EXCEPTION_PLATFORM_ERROR
382 JSValueRef JSWidget::getName(JSContextRef context,
384 JSStringRef /*propertyName*/,
385 JSValueRef* exception)
388 Converter converter(context);
389 return converter.toJSValueRef(getIWidget(object)->getName());
391 CATCH_EXCEPTION_CONVERSION
392 CATCH_EXCEPTION_NULL_PTR
393 CATCH_EXCEPTION_PLATFORM_ERROR
396 JSValueRef JSWidget::getShortName(JSContextRef context,
398 JSStringRef /*propertyName*/,
399 JSValueRef* exception)
402 Converter converter(context);
403 return converter.toJSValueRef(getIWidget(object)->getShortName());
405 CATCH_EXCEPTION_CONVERSION
406 CATCH_EXCEPTION_NULL_PTR
407 CATCH_EXCEPTION_PLATFORM_ERROR
410 JSValueRef JSWidget::getVersion(JSContextRef context,
412 JSStringRef /*propertyName*/,
413 JSValueRef* exception)
416 Converter converter(context);
417 return converter.toJSValueRef(getIWidget(object)->getVersion());
419 CATCH_EXCEPTION_CONVERSION
420 CATCH_EXCEPTION_NULL_PTR
421 CATCH_EXCEPTION_PLATFORM_ERROR
424 JSValueRef JSWidget::getHeight(JSContextRef context,
426 JSStringRef /*propertyName*/,
427 JSValueRef* exception)
430 Converter converter(context);
431 unsigned int height = getIWidget(object)->getHeight();
435 return converter.toJSValueRef(height);
437 CATCH_EXCEPTION_CONVERSION
438 CATCH_EXCEPTION_NULL_PTR
439 CATCH_EXCEPTION_PLATFORM_ERROR
442 JSValueRef JSWidget::getWidth(JSContextRef context,
444 JSStringRef /*propertyName*/,
445 JSValueRef* exception)
448 Converter converter(context);
449 unsigned int width = getIWidget(object)->getWidth();
453 return converter.toJSValueRef(width);
455 CATCH_EXCEPTION_CONVERSION
456 CATCH_EXCEPTION_NULL_PTR
457 CATCH_EXCEPTION_PLATFORM_ERROR
460 bool JSWidget::hasProperty(JSContextRef context,
461 JSObjectRef /*object*/,
462 JSStringRef propertyName)
467 Converter converter(context);
469 std::string key = converter.toString(propertyName);
470 if (key == "preferences") {
474 Catch(Commons::InvalidArgumentException) {
475 LogDebug("Pair for given key doesnt exist");
478 Catch(Commons::ConversionException) {
479 LogError("Error on conversion");
482 Catch(Commons::NullPointerException) {
483 LogError("Error on pointer, null value");
486 Catch(Commons::PlatformException){
487 LogError("PlatformException occured");
492 JSValueRef JSWidget::getProperty(JSContextRef context,
494 JSStringRef propertyName,
495 JSValueRef* exception)
497 LogDebug("Object: " << object);
500 Converter converter(context);
502 std::string key = converter.toString(propertyName);
504 if (key == "preferences") {
505 Converter converter(context);
506 JSObjectRef pref = getPreferences(object);
508 LogError("Preferences object is NULL");
509 return JSValueMakeUndefined(context);
513 LogError("Property NOT supported: " << propertyName);
514 return JSValueMakeUndefined(context);
517 CATCH_EXCEPTION_CONVERSION
518 CATCH_EXCEPTION_NULL_PTR
519 CATCH_EXCEPTION_INVALID_ARG
522 bool JSWidget::setProperty(JSContextRef context,
523 JSObjectRef /*object*/,
524 JSStringRef propertyName,
525 JSValueRef /*jvalue*/,
526 JSValueRef* exception)
531 Converter converter(context);
533 std::string key = converter.toString(propertyName);
534 if (key == "preferences") {
535 LogError("Object is read only");
539 CATCH_EXCEPTION_INVALID_ARG
540 CATCH_EXCEPTION_CONVERSION
541 CATCH_EXCEPTION_NULL_PTR
546 JSObjectRef JSWidget::callAsConstructor(JSContextRef context,
547 JSObjectRef /*constructor*/,
548 size_t /*argumentCount*/,
549 const JSValueRef /*arguments*/[],
550 JSValueRef* /*exception*/)
552 LogDebug("widget constructor");
553 if (!m_globalContext) {
554 LogError("Global context not set. Creating 'widget' object with "
556 return JSObjectMake(context, JSWidget::getClassRef(), NULL);
558 return JSObjectMake(m_globalContext, JSWidget::getClassRef(), NULL);
561 #undef CATCH_EXCEPTION_NO_MODIFABLE
562 #undef CATCH_EXCEPTION_CONVERSION
563 #undef CATCH_EXCEPTION_NULL_PTR
564 #undef CATCH_EXCEPTION_PLATFORM_ERROR
565 #undef CATCH_EXCEPTION_SECURITY
566 #undef CATCH_EXCEPTION_OUT_OF_RANGE
567 #undef CATCH_EXCEPTION_INVALID_ARG