tizen 2.3 release
[framework/web/wearable/wrt-plugins-tizen.git] / src / Common / JSWebAPIException.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include "JSWebAPIException.h"
19 #include <string>
20 #include <map>
21 #include "JSUtil.h"
22 #include "JSStringRefWrapper.h"
23 #include "Logger.h"
24
25 namespace DeviceAPI {
26 namespace Common {
27
28 namespace {
29 const char* CLASS_NAME = "WebAPIException";
30
31 const char* PROPERTY_CODE = "code";
32 const char* PROPERTY_NAME ="name";
33 const char* PROPERTY_TYPE ="type";
34 const char* PROPERTY_MESSAGE ="message";
35
36 const char* PROPERTY_INDEX_SIZE_ERR = "INDEX_SIZE_ERR";
37 const char* PROPERTY_DOMSTRING_SIZE_ERR = "DOMSTRING_SIZE_ERR";
38 const char* PROPERTY_HIERARCHY_REQUEST_ERR = "HIERARCHY_REQUEST_ERR";
39 const char* PROPERTY_WRONG_DOCUMENT_ERR = "WRONG_DOCUMENT_ERR";
40 const char* PROPERTY_INVALID_CHARACTER_ERR = "INVALID_CHARACTER_ERR";
41 const char* PROPERTY_NO_DATA_ALLOWED_ERR = "NO_DATA_ALLOWED_ERR";
42 const char* PROPERTY_NO_MODIFICATION_ALLOWED_ERR = "NO_MODIFICATION_ALLOWED_ERR";
43 const char* PROPERTY_NOT_FOUND_ERR = "NOT_FOUND_ERR";
44 const char* PROPERTY_NOT_SUPPORTED_ERR = "NOT_SUPPORTED_ERR";
45 const char* PROPERTY_INUSE_ATTRIBUTE_ERR = "INUSE_ATTRIBUTE_ERR";
46 const char* PROPERTY_INVALID_STATE_ERR = "INVALID_STATE_ERR";
47 const char* PROPERTY_SYNTAX_ERR = "SYNTAX_ERR";
48 const char* PROPERTY_INVALID_MODIFICATION_ERR = "INVALID_MODIFICATION_ERR";
49 const char* PROPERTY_NAMESPACE_ERR = "NAMESPACE_ERR";
50 const char* PROPERTY_INVALID_ACCESS_ERR = "INVALID_ACCESS_ERR";
51 const char* PROPERTY_VALIDATION_ERR = "VALIDATION_ERR";
52 const char* PROPERTY_TYPE_MISMATCH_ERR = "TYPE_MISMATCH_ERR";
53 const char* PROPERTY_SECURITY_ERR = "SECURITY_ERR";
54 const char* PROPERTY_NETWORK_ERR = "NETWORK_ERR";
55 const char* PROPERTY_ABORT_ERR = "ABORT_ERR";
56 const char* PROPERTY_URL_MISMATCH_ERR = "URL_MISMATCH_ERR";
57 const char* PROPERTY_QUOTA_EXCEEDED_ERR = "QUOTA_EXCEEDED_ERR";
58 const char* PROPERTY_TIMEOUT_ERR = "TIMEOUT_ERR";
59 const char* PROPERTY_INVALID_NODE_TYPE_ERR = "INVALID_NODE_TYPE_ERR";
60 const char* PROPERTY_DATA_CLONE_ERR = "DATA_CLONE_ERR";
61
62 const char* FUNCTION_TO_STRING = "toString";
63 }
64
65 typedef std::map<std::string, int> DeviceAPIErrorCodeMap;
66
67 static DeviceAPIErrorCodeMap errorCodes = {
68         { PROPERTY_INDEX_SIZE_ERR, 1 },
69         { PROPERTY_DOMSTRING_SIZE_ERR, 2 },
70         { PROPERTY_HIERARCHY_REQUEST_ERR, 3 },
71         { PROPERTY_WRONG_DOCUMENT_ERR, 4 },
72         { PROPERTY_INVALID_CHARACTER_ERR, 5 },
73         { PROPERTY_NO_DATA_ALLOWED_ERR, 6 },
74         { PROPERTY_NO_MODIFICATION_ALLOWED_ERR, 7 },
75         { PROPERTY_NOT_FOUND_ERR, 8 },
76         { PROPERTY_NOT_SUPPORTED_ERR, 9 },
77         { PROPERTY_INUSE_ATTRIBUTE_ERR, 10 },
78         { PROPERTY_INVALID_STATE_ERR, 11 },
79         { PROPERTY_SYNTAX_ERR, 12 },
80         { PROPERTY_INVALID_MODIFICATION_ERR, 13 },
81         { PROPERTY_NAMESPACE_ERR, 14 },
82         { PROPERTY_INVALID_ACCESS_ERR, 15 },
83         { PROPERTY_VALIDATION_ERR, 16 },
84         { PROPERTY_TYPE_MISMATCH_ERR, 17 },
85         { PROPERTY_SECURITY_ERR, 18 },
86         { PROPERTY_NETWORK_ERR, 19 },
87         { PROPERTY_ABORT_ERR, 20 },
88         { PROPERTY_URL_MISMATCH_ERR, 21 },
89         { PROPERTY_QUOTA_EXCEEDED_ERR, 22 },
90         { PROPERTY_TIMEOUT_ERR, 23 },
91         { PROPERTY_INVALID_NODE_TYPE_ERR, 24 },
92         { PROPERTY_DATA_CLONE_ERR, 25 } };
93
94 JSClassRef JSWebAPIException::m_classRef = NULL;
95
96 JSClassDefinition JSWebAPIException::m_classInfo = {
97         0,
98         kJSClassAttributeNone,
99         CLASS_NAME,
100         0,
101         m_properties,
102         m_function,
103         initialize,
104         finalize,
105         NULL, // hasProperty,
106         NULL, // getProperty,
107         NULL, // setProperty,
108         NULL, // deleteProperty,
109         NULL, // getPropertyNames,
110         NULL, // callAsFunction,
111         NULL, // callAsConstructor,
112         NULL, // hasInstance,
113         NULL, // convertToType,
114 };
115
116 JSStaticFunction JSWebAPIException::m_function[] = {
117         { FUNCTION_TO_STRING, toString, kJSPropertyAttributeNone },
118         { 0, 0, 0 }
119 };
120
121 JSStaticValue JSWebAPIException::m_properties[] = {
122         { PROPERTY_CODE, getProperty, NULL, kJSPropertyAttributeReadOnly },
123         { PROPERTY_NAME, getProperty, NULL, kJSPropertyAttributeReadOnly },
124         { PROPERTY_TYPE, getProperty, NULL, kJSPropertyAttributeReadOnly },
125         { PROPERTY_MESSAGE, getProperty, NULL, kJSPropertyAttributeReadOnly },
126         { PROPERTY_INDEX_SIZE_ERR, getStaticProperty, NULL,
127                 kJSPropertyAttributeReadOnly },
128         { PROPERTY_DOMSTRING_SIZE_ERR, getStaticProperty, NULL,
129                 kJSPropertyAttributeReadOnly },
130         { PROPERTY_HIERARCHY_REQUEST_ERR, getStaticProperty, NULL,
131                 kJSPropertyAttributeReadOnly },
132         { PROPERTY_WRONG_DOCUMENT_ERR, getStaticProperty, NULL,
133                 kJSPropertyAttributeReadOnly },
134         { PROPERTY_INVALID_CHARACTER_ERR, getStaticProperty, NULL,
135                 kJSPropertyAttributeReadOnly },
136         { PROPERTY_NO_DATA_ALLOWED_ERR, getStaticProperty, NULL,
137                 kJSPropertyAttributeReadOnly },
138         { PROPERTY_NO_MODIFICATION_ALLOWED_ERR, getStaticProperty, NULL,
139                 kJSPropertyAttributeReadOnly },
140         { PROPERTY_NOT_FOUND_ERR, getStaticProperty, NULL,
141                 kJSPropertyAttributeReadOnly },
142         { PROPERTY_NOT_SUPPORTED_ERR, getStaticProperty, NULL,
143                 kJSPropertyAttributeReadOnly },
144         { PROPERTY_INUSE_ATTRIBUTE_ERR, getStaticProperty, NULL,
145                 kJSPropertyAttributeReadOnly },
146         { PROPERTY_INVALID_STATE_ERR, getStaticProperty, NULL,
147                 kJSPropertyAttributeReadOnly },
148         { PROPERTY_SYNTAX_ERR, getStaticProperty, NULL,
149                 kJSPropertyAttributeReadOnly },
150         { PROPERTY_INVALID_MODIFICATION_ERR, getStaticProperty, NULL,
151                 kJSPropertyAttributeReadOnly },
152         { PROPERTY_NAMESPACE_ERR, getStaticProperty, NULL,
153                 kJSPropertyAttributeReadOnly },
154         { PROPERTY_INVALID_ACCESS_ERR, getStaticProperty, NULL,
155                 kJSPropertyAttributeReadOnly },
156         { PROPERTY_VALIDATION_ERR, getStaticProperty, NULL,
157                 kJSPropertyAttributeReadOnly },
158         { PROPERTY_TYPE_MISMATCH_ERR, getStaticProperty, NULL,
159                 kJSPropertyAttributeReadOnly },
160         { PROPERTY_SECURITY_ERR, getStaticProperty, NULL,
161                 kJSPropertyAttributeReadOnly },
162         { PROPERTY_NETWORK_ERR, getStaticProperty, NULL,
163                 kJSPropertyAttributeReadOnly },
164         { PROPERTY_ABORT_ERR, getStaticProperty, NULL,
165                 kJSPropertyAttributeReadOnly },
166         { PROPERTY_URL_MISMATCH_ERR, getStaticProperty, NULL,
167                 kJSPropertyAttributeReadOnly },
168         { PROPERTY_QUOTA_EXCEEDED_ERR, getStaticProperty, NULL,
169                 kJSPropertyAttributeReadOnly },
170         { PROPERTY_TIMEOUT_ERR, getStaticProperty, NULL,
171                 kJSPropertyAttributeReadOnly },
172         { PROPERTY_INVALID_NODE_TYPE_ERR, getStaticProperty, NULL,
173                 kJSPropertyAttributeReadOnly },
174         { PROPERTY_DATA_CLONE_ERR, getStaticProperty, NULL,
175                 kJSPropertyAttributeReadOnly },
176         { 0, 0, 0, 0 }
177 };
178
179 const JSClassDefinition* JSWebAPIException::getClassInfo()
180 {
181     return &m_classInfo;
182 }
183
184 JSClassRef JSWebAPIException::getClassRef()
185 {
186     if (!m_classRef) {
187         m_classRef = JSClassCreate(&m_classInfo);
188     }
189     return m_classRef;
190 }
191
192 bool JSWebAPIException::isObjectOfClass(JSContextRef context, JSValueRef value)
193 {
194     return JSValueIsObjectOfClass(context, value, getClassRef());
195 }
196
197 JSObjectRef JSWebAPIException::createJSObject(JSContextRef context,
198         WebAPIError* webapiError)
199 {
200     JSObjectRef jsObjectRef = JSObjectMake(context, getClassRef(),
201             static_cast<void*>(webapiError));
202     if (NULL == jsObjectRef) {
203         LOGE("object creation error");
204         return NULL;
205     }
206     return jsObjectRef;
207 }
208
209 WebAPIError* JSWebAPIException::getPriv(JSContextRef context,
210         JSObjectRef object)
211 {
212     if (!JSValueIsObjectOfClass(context, object, getClassRef())) {
213         return NULL;
214     }
215
216     return static_cast<WebAPIError*>(JSObjectGetPrivate(object));
217 }
218
219 JSObjectRef JSWebAPIException::constructor(JSContextRef context,
220         JSObjectRef constructor,
221         size_t argumentCount,
222         const JSValueRef arguments[],
223         JSValueRef* exception)
224 {
225     return JSWebAPIErrorFactory::postException(context, exception,
226             JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Illegal constructor");
227 }
228
229 void JSWebAPIException::initializeConstructor(JSContextRef context,
230         JSObjectRef constructor)
231 {
232     for (DeviceAPIErrorCodeMap::iterator iter = errorCodes.begin();
233             iter != errorCodes.end(); iter++) {
234         JSStringRefWrapper name(iter->first);
235         JSValueRef value = JSValueMakeNumber(context,
236                 static_cast<double>(iter->second));
237         JSObjectSetProperty(context, constructor, name.get(), value,
238                 kJSPropertyAttributeReadOnly, NULL);
239     }
240 }
241
242 void JSWebAPIException::initialize(JSContextRef /*context*/,
243         JSObjectRef /*object*/)
244 {
245 }
246
247 void JSWebAPIException::finalize(JSObjectRef /*object*/)
248 {
249 }
250
251 JSValueRef JSWebAPIException::getProperty(JSContextRef context,
252         JSObjectRef object,
253         JSStringRef propertyName,
254         JSValueRef* /*exception*/)
255 {
256     WebAPIError* webapiErrObj = getPriv(context, object);
257     if (!webapiErrObj) {
258         LOGE("Private object is not set.");
259         return JSValueMakeUndefined(context);
260     }
261
262     try {
263         std::string propertyNameStr = JSUtil::JSStringToString(context,
264                 propertyName);
265
266         if (PROPERTY_CODE == propertyNameStr) {
267             return JSUtil::toJSValueRef(context,
268                     static_cast<long>(webapiErrObj->getCode()));
269         }
270         else if (PROPERTY_NAME == propertyNameStr) {
271             return JSUtil::toJSValueRef(context, webapiErrObj->getName());
272         }
273         else if (PROPERTY_TYPE == propertyNameStr) {
274             return JSUtil::toJSValueRef(context, webapiErrObj->getName());
275         }
276         else if (PROPERTY_MESSAGE == propertyNameStr) {
277             return JSUtil::toJSValueRef(context, webapiErrObj->getMessage());
278         }
279     }
280     catch (const BasePlatformException & err) {
281         LOGE("Exception: %s", err.getMessage().c_str());
282     }
283
284     return JSValueMakeUndefined(context);
285 }
286
287 JSValueRef JSWebAPIException::getStaticProperty(JSContextRef context,
288         JSObjectRef object,
289         JSStringRef propertyName,
290         JSValueRef* /*exception*/)
291 {
292     try {
293         std::string propertyNameStr = JSUtil::JSStringToString(context,
294                 propertyName);
295
296         DeviceAPIErrorCodeMap::iterator iter = errorCodes.find(propertyNameStr);
297         if (iter != errorCodes.end()) {
298             return JSUtil::toJSValueRef(context, static_cast<long>(iter->second));
299         }
300     }
301     catch (const BasePlatformException & err) {
302         LOGE("Exception: %s", err.getMessage().c_str());
303     }
304
305     return JSValueMakeUndefined(context);
306 }
307
308 JSValueRef JSWebAPIException::toString(JSContextRef context,
309         JSObjectRef object,
310         JSObjectRef thisObject,
311         size_t argumentCount,
312         const JSValueRef arguments[],
313         JSValueRef* exception)
314 {
315     WebAPIError* webapiErrObj = getPriv(context, thisObject);
316     if (!webapiErrObj) {
317         LOGE("Private object is not set.");
318         return NULL;
319     }
320
321     std::string name = webapiErrObj->getName();
322     std::string message = webapiErrObj->getMessage();
323
324     std::string result = name + ": " + message;
325
326     return JSUtil::toJSValueRef(context, result);
327 }
328
329 } // Common
330 } // DeviceAPI