tizen 2.3 release
[framework/web/wearable/wrt-plugins-tizen.git] / src / Filesystem / JSFile.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 /**
19  * @file        JSFile.cpp
20  */
21
22 #include "JSFile.h"
23
24 #include <string>
25 #include <ctime>
26 #include <Logger.h>
27
28 #include <Commons/FunctionDeclaration.h>
29 #include <Commons/Exception.h>
30 #include <Commons/WrtAccess/WrtAccess.h>
31 #include <CommonsJavaScript/JSCallbackManager.h>
32 #include <CommonsJavaScript/Validator.h>
33 #include <CommonsJavaScript/JSUtils.h>
34 #include <JSWebAPIErrorFactory.h>
35 #include <SecurityExceptions.h>
36 #include <ArgumentValidator.h>
37 #include <GlobalContextManager.h>
38 #include <JSUtil.h>
39 #include <Export.h>
40 #include <TimeTracer.h>
41
42 #include "Enums.h"
43 #include "Manager.h"
44 #include "EventCopy.h"
45 #include "EventMove.h"
46 #include "EventListNodes.h"
47 #include "EventOpen.h"
48 #include "EventReadText.h"
49 #include "Converter.h"
50 #include "plugin_config.h"
51 #include "Encodings.h"
52 #include "JSFilestream.h"
53 #include "JSErrors.h"
54 #include "FilesystemUtils.h"
55 #include "FilesystemPathUtils.h"
56 #include <SecurityAccessor.h>
57
58 using namespace WrtDeviceApis::Commons;
59 using namespace WrtDeviceApis::CommonsJavaScript;
60
61 namespace {
62 #define PLUGIN_NAME  "File"
63 #define PROPERTY_PARENT  "parent"
64 #define PROPERTY_READ_ONLY  "readOnly"
65 #define PROPERTY_IS_FILE  "isFile"
66 #define PROPERTY_IS_DIRECTORY "isDirectory"
67 #define PROPERTY_CREATED  "created"
68 #define PROPERTY_MODIFIED  "modified"
69 #define PROPERTY_PATH  "path"
70 #define PROPERTY_NAME  "name"
71 #define PROPERTY_FULL_PATH  "fullPath"
72 #define PROPERTY_FILE_SIZE  "fileSize"
73 #define PROPERTY_LENGTH "length"
74
75 const std::string TIME_TRACER_FILE_RESOLVE = "JSFile::resolve";
76 }    //namespace
77
78 JSValueRef getFunctionOrNull(JSContextRef ctx, JSValueRef arg)
79 {
80     if (Validator(ctx).isCallback(arg)) {
81         return arg;
82     } else if (!JSValueIsNull(ctx, arg) && !JSValueIsUndefined(ctx, arg)) {
83         LOGW("throw DeviceAPI::Common::TypeMismatchException");
84         throw DeviceAPI::Common::TypeMismatchException(
85                 "Not a function nor JS null.");
86     }
87     return NULL;
88 }
89
90 JSValueRef getFunction(JSContextRef ctx, JSValueRef arg)
91 {
92     if (Validator(ctx).isCallback(arg)) {
93         return arg;
94     } else{
95         LOGW("throw DeviceAPI::Common::TypeMismatchException");
96         throw DeviceAPI::Common::TypeMismatchException(
97                 "Not a function nor JS null.");
98     }
99 }
100
101 namespace DeviceAPI {
102 namespace Filesystem {
103
104 using namespace DeviceAPI::Common;
105
106 namespace {
107 template <class EventPtr>
108 bool verifyPath(EventPtr callback,
109                 PathPtr aPath,
110                 JSContextRef localContext,
111                 NodeType aType)
112 {
113
114     EventResolvePtr eventResolve(new EventResolve(localContext));
115     eventResolve->setPath(aPath);
116     eventResolve->setForSynchronousCall();
117
118     Manager::getInstance().getNode(eventResolve);
119     if (!eventResolve->getResult() || !eventResolve->getExceptionName().empty())
120     {
121         LOGW("Exception name %s", eventResolve->getExceptionName().c_str());
122         if ("NotFoundError" == eventResolve->getExceptionName())
123         {
124             LOGW("throw NotFoundException");
125             throw DeviceAPI::Common::NotFoundException(
126                     "Not found error");
127         }
128         LOGD("POST IO ERROR");
129         Utils::MainLoop<EventPtr>::passErrorLater(
130                 JSWebAPIErrorFactory::IO_ERROR,
131                 "IO error",
132                 JSValueMakeUndefined(localContext),
133                 callback);
134         return true;
135     }
136     if (eventResolve->getResult()->getType() != aType) {
137         LOGW("throw InvalidValuesException");
138         throw DeviceAPI::Common::InvalidValuesException(
139                 "Invalid directory");
140     }
141     return false;
142 }
143 } //Anonymous namespace
144
145 JSClassRef JSFile::m_classRef = 0;
146
147 JSClassDefinition JSFile::m_classInfo = {
148     0,
149     kJSClassAttributeNone,
150     PLUGIN_NAME,
151     0,
152     m_properties,
153     m_functions,
154     initialize,
155     finalize,
156     NULL,
157     NULL,
158     NULL,
159     NULL,
160     getPropertyNames,
161     NULL,
162     NULL,
163     hasInstance,
164     NULL
165 };
166
167 JSStaticValue JSFile::m_properties[] = {
168     { PROPERTY_PARENT, getProperty, NULL, kJSPropertyAttributeReadOnly },
169     { PROPERTY_READ_ONLY, getProperty, NULL, kJSPropertyAttributeReadOnly },
170     { PROPERTY_IS_FILE, getProperty, NULL, kJSPropertyAttributeReadOnly },
171     { PROPERTY_IS_DIRECTORY, getProperty, NULL, kJSPropertyAttributeReadOnly },
172     { PROPERTY_CREATED, getProperty, NULL, kJSPropertyAttributeReadOnly },
173     { PROPERTY_MODIFIED, getProperty, NULL, kJSPropertyAttributeReadOnly },
174     { PROPERTY_PATH, getProperty, NULL, kJSPropertyAttributeReadOnly },
175     { PROPERTY_NAME, getProperty, NULL, kJSPropertyAttributeReadOnly },
176     { PROPERTY_FULL_PATH, getProperty, NULL, kJSPropertyAttributeReadOnly },
177     { PROPERTY_FILE_SIZE, getProperty, NULL, kJSPropertyAttributeReadOnly },
178     { PROPERTY_LENGTH, getProperty, NULL, kJSPropertyAttributeReadOnly },
179     { 0, 0, 0, 0 }
180 };
181
182 JSStaticFunction JSFile::m_functions[] = {
183     { "toURI", toUri, kJSPropertyAttributeNone },
184     { "listFiles", listFiles, kJSPropertyAttributeNone },
185     { "openStream", openStream, kJSPropertyAttributeNone },
186     { "readAsText", readAsText, kJSPropertyAttributeNone },
187     { "copyTo", copyTo, kJSPropertyAttributeNone },
188     { "moveTo", moveTo, kJSPropertyAttributeNone },
189     { "createDirectory", createDirectory, kJSPropertyAttributeNone },
190     { "createFile", createFile, kJSPropertyAttributeNone },
191     { "resolve", resolve, kJSPropertyAttributeNone },
192     { "deleteDirectory", deleteDirectory, kJSPropertyAttributeNone },
193     { "deleteFile", deleteFile, kJSPropertyAttributeNone },
194     { 0, 0, 0 }
195 };
196
197 void JSFile::initialize(JSContextRef context,
198         JSObjectRef object)
199 {
200 }
201
202 void JSFile::finalize(JSObjectRef object)
203 {
204     FileHolder* priv = static_cast<FileHolder*>(JSObjectGetPrivate(object));
205     if (priv) {
206         JSObjectSetPrivate(object, NULL);
207         delete priv;
208     }
209 }
210
211 const JSClassRef DLL_EXPORT JSFile::getClassRef()
212 {
213     if (!m_classRef) {
214         m_classRef = JSClassCreate(&m_classInfo);
215     }
216     return m_classRef;
217 }
218
219 const JSClassDefinition* JSFile::getClassInfo()
220 {
221     return &m_classInfo;
222 }
223
224 FilePtr DLL_EXPORT JSFile::getPrivateObject(JSContextRef context,
225         JSValueRef value)
226 {
227     if (!JSValueIsObjectOfClass(context, value, getClassRef())) {
228         LOGE("Object type do not match");
229         throw TypeMismatchException("Object type is not JSFile");
230     }
231
232     JSObjectRef object = JSUtil::JSValueToObject(context, value);
233     FileHolder* priv = static_cast<FileHolder*>(JSObjectGetPrivate(object));
234     if (!priv) {
235         LOGE("NULL private data");
236         throw UnknownException("Private data holder is null");
237     }
238     if (!(priv->ptr)) {
239         LOGE("NULL shared pointer in private data");
240         throw UnknownException("Private data is null");
241     }
242
243     return priv->ptr;
244 }
245
246 void JSFile::setPrivateObject(JSObjectRef object, FilePtr data)
247 {
248     if (!data) {
249         LOGE("NULL shared pointer given to set as private data");
250         throw UnknownException("NULL private data given");
251     }
252
253     FileHolder* priv = static_cast<FileHolder*>(JSObjectGetPrivate(object));
254     if (priv) {
255         priv->ptr = data;
256     }
257     else {
258         priv = new FileHolder();
259         priv->ptr = data;
260
261         if(!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
262             delete priv;
263             priv = NULL;
264             LOGE("Failed to set JSFile private datae");
265             throw UnknownException("Failed to set JSFile private data");
266         }
267     }
268 }
269
270 JSObjectRef DLL_EXPORT JSFile::makeJSObject(JSContextRef context, FilePtr ptr,
271         Common::SecurityAccessor* srcSecurityAccessor)
272 {
273     if (!ptr) {
274         LOGE("NULL pointer to File given");
275         throw UnknownException("NULL pointer to File given");
276     }
277
278     FileHolder* priv = new FileHolder();
279     priv->ptr = ptr;
280
281     JSObjectRef obj = JSObjectMake(context, getClassRef(), NULL);
282     if(!JSObjectSetPrivate(obj, static_cast<void*>(priv))) {
283         delete priv;
284         LOGE("Failed to set private in JSFile");
285         throw UnknownException("Private data not set");
286     }
287
288     ptr->setContext(context);
289
290     if(srcSecurityAccessor) {
291         ptr->copyAceCheckAccessFunction(srcSecurityAccessor);
292     }
293     else {
294         LOGW("Source SecurityAccessor is not available!");
295     }
296
297     return obj;
298 }
299
300 JSValueRef JSFile::getProperty(JSContextRef context,
301         JSObjectRef object,
302         JSStringRef propertyName,
303         JSValueRef* exception)
304 {
305     LOGD("Entered");
306
307     try {
308         FilePtr priv = JSFile::getPrivateObject(context, object);
309         if (!priv) {
310             LOGE("Private object is not set.");
311             return JSValueMakeUndefined(context);
312         }
313
314         JSContextRef globalContext = priv->getContext();
315         Converter converter(globalContext);
316
317         auto node = priv->getNode();
318         if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_PARENT))
319         {
320             NodePtr parent(node->getParent());
321             File::PermissionList perms = priv->getParentPermissions();
322             if (parent && !perms.empty())
323             {
324                 parent->setPermissions(perms.back());
325                 perms.pop_back();
326
327                 FilePtr parentPriv = FilePtr(new File(parent, perms));
328                 return JSFile::makeJSObject(priv->getContext(),parentPriv, priv.get());
329             }
330             return JSValueMakeNull(context);
331         }
332         else if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_READ_ONLY))
333         {
334             bool readOnly = ((node->getMode() & PM_USER_WRITE) == 0);
335             return converter.toJSValueRef(readOnly);
336         }
337         else if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_IS_FILE))
338         {
339             bool isFile = (node->getType() == NT_FILE);
340             return converter.toJSValueRef(isFile);
341         }
342         else if (JSStringIsEqualToUTF8CString(propertyName,
343                   PROPERTY_IS_DIRECTORY))
344         {
345             bool isDirectory = (node->getType() == NT_DIRECTORY);
346             return converter.toJSValueRef(isDirectory);
347         }
348         else if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_CREATED))
349         {
350             std::time_t created = node->getCreated();
351             return converter.toJSValueRef(created);
352         }
353         else if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_MODIFIED))
354         {
355             std::time_t modified = node->getModified();
356             return converter.toJSValueRef(modified);
357         }
358         else if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_PATH))
359         {
360             std::string fpath = node->getPath()->getFullPath();
361             std::string vpath = Utils::toVirtualPath(globalContext, fpath);
362             std::string::size_type pos = vpath.rfind(Path::getSeparator());
363             std::string path;
364             if (std::string::npos != pos)
365             {
366                 path = vpath.substr(0, pos + 1);
367             }
368             else
369             {
370                 path = vpath;
371             }
372             return converter.toJSValueRef(path);
373         }
374         else if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_NAME))
375         {
376             std::string fpath = node->getPath()->getFullPath();
377             std::string vpath = Utils::toVirtualPath(globalContext, fpath);
378             std::string name;
379             std::string::size_type pos = vpath.rfind(Path::getSeparator());
380
381             if (std::string::npos != pos) {
382                 name = vpath.substr(pos + 1);
383             }
384             return converter.toJSValueRef(name);
385         }
386         else if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_FULL_PATH))
387         {
388             std::string path = priv->getOriginalFullPath();
389             LOGD("path = originalFullPath: %s", path.c_str());
390
391             if(path.empty()) {
392                 path = node->getPath()->getFullPath();
393                 LOGD("path =  %s (originalFullPath is not set)", path.c_str());
394             }
395
396             return converter.toJSValueRef(Utils::toVirtualPath(globalContext,
397                                                                path));
398         }
399         else if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_FILE_SIZE))
400         {
401             if (node->getType() == NT_DIRECTORY)
402             {
403                 return JSValueMakeUndefined(context);
404             }
405             return converter.toJSValueRef(node->getSize());
406         }
407         else if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_LENGTH))
408         {
409             if (node->getType() == NT_FILE) {
410                 return JSValueMakeUndefined(context);
411             }
412             // TODO: think about more efficent solution!
413             NodeList children = node->getChildNodes();
414             return converter.toJSValueRef(children.size());
415         }
416     } catch (const WrtDeviceApis::Commons::Exception& ex) {
417         LOGW("Exception caught: %s", ex.GetMessage().c_str());
418     } catch (const DeviceAPI::Common::BasePlatformException& ex) {
419         LOGW("Exception caught: %s", ex.getMessage().c_str());
420     } catch(...) {
421         LOGW("Unknown exception cought");
422     }
423
424     return JSValueMakeUndefined(context);
425 }
426
427 void JSFile::getPropertyNames(JSContextRef context,
428         JSObjectRef object,
429         JSPropertyNameAccumulatorRef propertyNames)
430 {
431 }
432
433 bool JSFile::hasInstance(JSContextRef context,
434         JSObjectRef constructor,
435         JSValueRef possibleInstance,
436         JSValueRef* exception)
437 {
438     return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
439 }
440
441 JSValueRef JSFile::toUri(JSContextRef context,
442         JSObjectRef object,
443         JSObjectRef thisObject,
444         size_t argc,
445         const JSValueRef argv[],
446         JSValueRef* exception)
447 {
448     SET_TIME_TRACER_ITEM(0);
449     LOGD("Entered");
450
451     try {
452         FilePtr priv = JSFile::getPrivateObject(context, thisObject);
453
454         Converter converter(context);
455         TIZEN_CHECK_ACCESS(context, exception, priv.get(), FILESYSTEM_FUNCTION_API_TO_URI);
456
457         std::string uri = priv->getOriginalURI();
458         LOGD("uri = originalURI: %s", uri.c_str());
459
460         if(uri.empty()) {
461             int widgetId = WrtAccessSingleton::Instance().getWidgetId();
462             uri = priv->getNode()->toUri(widgetId);
463             LOGD("uri = %s(originalURI is not set)", uri.c_str());
464         }
465
466         return converter.toJSValueRef(uri);
467     } catch(const DeviceAPI::Common::BasePlatformException& err) {
468         LOGW("WrtDeviceAPI::Common::BasePlatformException exception caught");
469         return JSWebAPIErrorFactory::postException(context, exception, err);
470     } catch (...) {
471         LOGW("Unexpected exception caught");
472         DeviceAPI::Common::UnknownException err(
473                 "Unknown Error");
474         return JSWebAPIErrorFactory::postException(context, exception, err);
475     }
476 }
477
478 JSValueRef JSFile::listFiles(JSContextRef context,
479         JSObjectRef object,
480         JSObjectRef thisObject,
481         size_t argc,
482         const JSValueRef argv[],
483         JSValueRef* exception)
484 {
485     SET_TIME_TRACER_ITEM(0);
486     LOGD("Entered");
487
488     EventListNodesPtr callback;
489
490     try {
491         FilePtr priv = JSFile::getPrivateObject(context, thisObject);
492
493         TIZEN_CHECK_ACCESS(context, exception, priv.get(),
494                 FILESYSTEM_FUNCTION_API_LIST_FILES);
495
496         ArgumentValidator validator(context, argc, argv);
497         validator.toFunction(0, false);
498         validator.toFunction(1, true);
499         validator.toObject(2, true);
500
501         JSContextRef globalContext = priv->getContext();
502         size_t index = 0;
503         JSValueRef reserveArguments[3];
504         JSCallbackManagerPtr cbm = JSCallbackManager::createObject(globalContext);
505
506         auto globalContextManager = GlobalContextManager::getInstance();
507         auto listContext = globalContextManager->getGlobalContext(context);
508         callback = EventListNodesPtr(new EventListNodes(listContext));
509
510         for (index = 0; index < 3; index++)
511         {
512             if (index < argc) {
513                 reserveArguments[index] = argv[index];
514             } else {
515                 reserveArguments[index] = JSValueMakeUndefined(context);
516             }
517         }
518
519         JSValueRef onSuccess = getFunction(globalContext, reserveArguments[0]);
520         JSValueRef onError = NULL;
521
522
523         if (argc > 1) {
524             onError = getFunctionOrNull(globalContext, reserveArguments[1]);
525         }
526
527         callback->setSuccessCallback(onSuccess);
528         callback->setErrorCallback(onError);
529
530         Converter converter(globalContext);
531
532         if (argc > 2) {
533             if (JSValueIsNull(context, reserveArguments[2]) == false &&
534                 JSValueIsUndefined(context, reserveArguments[2]) == false) {
535                     callback->setFilter(converter.toNodeFilter(reserveArguments[2]));
536                 }
537         }
538         auto myNode = priv->getNode();
539         File::PermissionList perms = priv->getParentPermissions();
540         perms.push_back(myNode->getPermissions());
541
542         callback->setParentPermissions(perms);
543         callback->setNode(myNode);
544
545         Node::getChildNodes(callback);
546
547     } catch(const DeviceAPI::Common::BasePlatformException& err) {
548         LOGD("WrtDeviceAPI::Common::BasePlatformException exception caught");
549         if (!checkReportAsyncAPI(err.getName(),
550                               err.getMessage(),
551                               callback,
552                               context)) {
553             LOGD("Synchronous error report for [%s]", err.getName().c_str());
554             return JSWebAPIErrorFactory::postException(context,
555                                                        exception,
556                                                        err);
557         }
558     } catch(const WrtDeviceApis::Commons::Exception& err) {
559         LOGD("WrtDeviceApis::Commons::Exception Exception caught");
560         if (!checkReportAsyncAPI(translateApi2APIErrors(err.GetClassName()),
561                               err.GetMessage(),
562                               callback,
563                               context)) {
564             return JSWebAPIErrorFactory::postException(
565                     context,
566                     exception,
567                     translateApi2APIErrors(std::string(err.GetClassName())),
568                     std::string(err.GetMessage()));
569         }
570     } catch (...) {
571         LOGD("Unexpected exception caught");
572         DeviceAPI::Common::UnknownException err(
573                 "Unknown Error");
574         return JSWebAPIErrorFactory::postException(context, exception, err);
575     }
576     return JSValueMakeUndefined(context);
577 }
578
579 JSValueRef JSFile::openStream(JSContextRef context,
580         JSObjectRef object,
581         JSObjectRef thisObject,
582         size_t argumentCount,
583         const JSValueRef arguments[],
584         JSValueRef* exception)
585 {
586     SET_TIME_TRACER_ITEM(0);
587     LOGD("Entered");
588
589     EventOpenPtr callback;
590     try {
591         FilePtr priv = JSFile::getPrivateObject(context, thisObject);
592         TIZEN_CHECK_ACCESS(context, exception, priv.get(),
593                 FILESYSTEM_FUNCTION_API_OPEN_STREAM);
594
595         auto globalCtx = GlobalContextManager::getInstance()->getGlobalContext(context);
596         callback = EventOpenPtr(new EventOpen(globalCtx));
597         ArgumentValidator validator(context, argumentCount, arguments);
598         AccessMode mode =
599                 Converter(globalCtx).toAccessMode(validator.toJSValueRef(0, false));
600         callback->setSuccessCallback(validator.toFunction(1 ,false));
601         callback->setErrorCallback(validator.toFunction(2 ,true));
602         std::string encoding = validator.toString(3, true, Encodings::UTF8);
603
604         auto node = priv->getNode();
605         if ((AM_READ != mode) && (PERM_READ == node->getPermissions())) {
606             LOGE("Permission denied");
607             return Utils::MainLoop<EventOpenPtr>::passErrorLater(
608                     JSWebAPIErrorFactory::INVALID_VALUES_ERROR,
609                     "permission denied error",
610                     JSValueMakeUndefined(context),
611                     callback);
612         }
613
614         if (!(encoding == Encodings::UTF8 || encoding == Encodings::ISO88591
615                 || encoding == Encodings::SJIS)) {
616             LOGE("Type mismath");
617             throw DeviceAPI::Common::TypeMismatchException("Type mismatch");
618         }
619         callback->setCharSet(encoding);
620         callback->setNode(priv->getNode());
621         callback->setMode(mode);
622         Node::open(callback);
623
624     } catch(const DeviceAPI::Common::BasePlatformException& err) {
625         LOGD("WrtDeviceAPI::Common::BasePlatformException exception caught");
626         if (!checkReportAsyncAPI(err.getName(),
627                                  err.getMessage(),
628                                  callback,
629                                  context)) {
630             LOGD("Synchronous error report for [%s]", err.getName().c_str());
631             return JSWebAPIErrorFactory::postException(context,
632                                                        exception,
633                                                        err);
634         }
635     } catch(const WrtDeviceApis::Commons::Exception& err) {
636         LOGD("WrtDeviceApis::Commons::Exception Exception caught");
637         if (!checkReportAsyncAPI(translateApi2APIErrors(err.GetClassName()),
638                               err.GetMessage(),
639                               callback,
640                               context)) {
641             return JSWebAPIErrorFactory::postException(
642                     context,
643                     exception,
644                     translateApi2APIErrors(std::string(err.GetClassName())),
645                     std::string(err.GetMessage()));
646         }
647     } catch (...) {
648         LOGD("Unexpected exception caught");
649         DeviceAPI::Common::UnknownException err(
650                 "Unknown Error");
651         return JSWebAPIErrorFactory::postException(context, exception, err);
652     }
653
654     return JSValueMakeUndefined(context);
655 }
656
657 JSValueRef JSFile::readAsText(
658         JSContextRef localContext,
659         JSObjectRef object,
660         JSObjectRef thisObject,
661         size_t argc,
662         const JSValueRef argv[],
663         JSValueRef* exception)
664 {
665     SET_TIME_TRACER_ITEM(0);
666     LOGD("Entered");
667
668     EventReadTextPtr callback;
669
670     try {
671         FilePtr priv = JSFile::getPrivateObject(localContext, thisObject);
672         TIZEN_CHECK_ACCESS(localContext, exception, priv.get(),
673                 FILESYSTEM_FUNCTION_API_READ_AS_TEXT);
674
675         callback = EventReadTextPtr(new EventReadText(
676                 GlobalContextManager::getInstance()->getGlobalContext(localContext)));
677
678         ArgumentValidator validator(localContext, argc, argv);
679         callback->setSuccessCallback(validator.toFunction(0,false));
680         callback->setErrorCallback(validator.toFunction(1,true));
681
682         std::string encoding = validator.toString(2,true,Encodings::UTF8);
683
684         if (!(encoding == Encodings::UTF8 || encoding == Encodings::ISO88591
685                 || encoding == Encodings::SJIS)) {
686             LOGE("Type mismath");
687             throw DeviceAPI::Common::TypeMismatchException("Type mismatch");
688         }
689
690         if (NT_FILE != priv->getNode()->getType()) {
691             LOGE("JSFile is not file.");
692             return Utils::MainLoop<EventReadTextPtr>::passErrorLater(
693                     JSWebAPIErrorFactory::IO_ERROR,
694                     "IO error",
695                     JSValueMakeUndefined(localContext),
696                     callback);
697         }
698
699         callback->setCharSet(encoding);
700         callback->setNode(priv->getNode());
701
702         Node::readAsText(callback);
703
704     } catch(const DeviceAPI::Common::BasePlatformException& err) {
705         LOGD("WrtDeviceAPI::Common::BasePlatformException exception caught");
706         if (!checkReportAsyncAPI(err.getName(),
707                                  err.getMessage(),
708                                  callback,
709                                  localContext)) {
710             LOGD("Synchronous error report for [%s]", err.getName().c_str());
711             return JSWebAPIErrorFactory::postException(localContext,
712                                                        exception,
713                                                        err);
714         }
715     } catch(const WrtDeviceApis::Commons::Exception& err) {
716         LOGD("WrtDeviceApis::Commons::Exception Exception caught");
717         if (!checkReportAsyncAPI(translateApi2APIErrors(err.GetClassName()),
718                               err.GetMessage(),
719                               callback,
720                               localContext)) {
721             return JSWebAPIErrorFactory::postException(
722                     localContext,
723                     exception,
724                     translateApi2APIErrors(std::string(err.GetClassName())),
725                     std::string(err.GetMessage()));
726         }
727     } catch (...) {
728         LOGD("Unexpected exception caught");
729         DeviceAPI::Common::UnknownException err(
730                 "Unknown Error");
731         return JSWebAPIErrorFactory::postException(localContext, exception, err);
732     }
733
734     return JSValueMakeUndefined(localContext);
735 }
736
737 JSValueRef JSFile::copyTo(JSContextRef localContext,
738         JSObjectRef /*object*/,
739         JSObjectRef thisObject,
740         size_t argc,
741         const JSValueRef argv[],
742         JSValueRef* exception)
743 {
744     SET_TIME_TRACER_ITEM(0);
745     LOGD("Entered");
746
747     JSContextRef globalContext = NULL;
748     EventCopyPtr callback;
749
750     try {
751         FilePtr priv = JSFile::getPrivateObject(localContext, thisObject);
752
753         TIZEN_CHECK_ACCESS(localContext, exception, priv.get(),
754                 FILESYSTEM_FUNCTION_API_COPY_TO);
755
756         JSContextRef privateContext = priv->getContext();
757         size_t index = 0;
758         JSValueRef reserveArguments[5];
759         auto globalContextManager = GlobalContextManager::getInstance();
760         globalContext = globalContextManager->getGlobalContext(localContext);
761         callback = EventCopyPtr(new EventCopy(globalContext));
762
763         ArgumentValidator validator(localContext, argc, argv);
764         validator.toFunction(3, true);
765         validator.toFunction(4, true);
766
767         for (index = 0; index < 5; index++)
768         {
769             if (index < argc) {
770                 reserveArguments[index] = argv[index];
771             } else {
772                  reserveArguments[index] = JSValueMakeUndefined(localContext);
773             }
774         }
775
776         Converter converter(privateContext);
777         JSValueRef onSuccess = NULL;
778         JSValueRef onError = NULL;
779
780         onSuccess = getFunctionOrNull(privateContext, reserveArguments[3]);
781         onError = getFunctionOrNull(privateContext, reserveArguments[4]);
782
783         callback->setSuccessCallback(onSuccess);
784         callback->setErrorCallback(onError);
785
786         //TODO add check validation for src, dest string.
787         PathPtr src = Utils::fromVirtualPath(
788                 privateContext,
789                 converter.toString(reserveArguments[0]));
790         PathPtr dest = Utils::fromVirtualPath(
791                 privateContext,
792                 converter.toString(reserveArguments[1]));
793         bool overwrite = converter.toBool(reserveArguments[2]);;
794
795         auto dirNode = priv->getNode();
796         LOGD("copyTo executed from dir:[%s] src path:[%s] dest path:[%s]",
797                 dirNode->getPath()->getFullPath().c_str(),
798                 src->getFullPath().c_str(),
799                 dest->getFullPath().c_str());
800         if (NT_DIRECTORY != dirNode->getType()) {
801             LOGW("This node is not directory");
802             return Utils::MainLoop<EventCopyPtr>::passErrorLater(
803                     JSWebAPIErrorFactory::IO_ERROR,
804                     "IO error",
805                     JSValueMakeUndefined(localContext),
806                     callback);
807         }
808
809         // Filesystem spec:
810         // The file or directory to be copied MUST be under the Directory
811         // from which the method is invoked, otherwise the operation
812         // MUST NOT be performed.
813         //
814         // ringtones: the location for ringtones (read-only location)
815         // wgt-package: the widget package location (read-only location)
816         //
817
818         const bool isSubPath = dirNode->isSubPath(src);
819         const bool destIsAllowed = isDestinationAllowed(dest);
820         if (!isSubPath || !destIsAllowed)
821         {
822             LOGE("isSubPath:%d destIsAllowed:%d", isSubPath, destIsAllowed);
823             return Utils::MainLoop<EventCopyPtr>::passErrorLater(
824                     JSWebAPIErrorFactory::INVALID_VALUES_ERROR,
825                     "Invalid Values",
826                     JSValueMakeUndefined(localContext),
827                     callback);
828         }
829
830         callback->setSource(src);
831         callback->setDestination(dest);
832
833         if (overwrite) {
834             callback->setOptions(OPT_OVERWRITE);
835         }
836
837         Manager::getInstance().copy(callback);
838     } catch(const DeviceAPI::Common::BasePlatformException& err) {
839         LOGD("WrtDeviceAPI::Common::BasePlatformException exception caught");
840         if (!checkReportAsyncAPI(err.getName(),
841                                  err.getMessage(),
842                                  callback,
843                                  globalContext))
844         {
845             LOGD("Synchronous error report for [%s]", err.getName().c_str());
846             return JSWebAPIErrorFactory::postException(localContext,
847                                                        exception,
848                                                        err);
849         }
850     } catch(const WrtDeviceApis::Commons::Exception& err) {
851         LOGD("WrtDeviceApis::Commons::Exception Exception caught");
852         if (!checkReportAsyncAPI(translateApi2APIErrors(err.GetClassName()),
853                                  err.GetMessage(),
854                                  callback,
855                                  globalContext))
856         {
857             return JSWebAPIErrorFactory::postException(
858                     localContext,
859                     exception,
860                     translateApi2APIErrors(std::string(err.GetClassName())),
861                     std::string(err.GetMessage()));
862         }
863     } catch (...) {
864         LOGD("Unexpected exception caught");
865         DeviceAPI::Common::UnknownException err("Unknown Error");
866         return JSWebAPIErrorFactory::postException(localContext, exception, err);
867     }
868
869     return JSValueMakeUndefined(localContext);
870 }
871
872 bool JSFile::isDestinationAllowed(PathPtr aDestination)
873 {
874     static auto ringtones =
875         Utils::fromVirtualPath(NULL, "ringtones")->getFullPath();
876     static auto wgtPackage =
877         Utils::fromVirtualPath(NULL, "wgt-package")->getFullPath();
878     LOGD("Check allowed destinations ringtones [%s] wgt-package [%s] "
879          "destination [%s]",
880          ringtones.c_str(),
881          wgtPackage.c_str(),
882          aDestination->getFullPath().c_str());
883     return !Node::isSubPath(ringtones, aDestination) &&
884            !Node::isSubPath(wgtPackage, aDestination);
885
886 }
887
888 JSValueRef JSFile::moveTo(JSContextRef localContext,
889         JSObjectRef object,
890         JSObjectRef thisObject,
891         size_t argc,
892         const JSValueRef argv[],
893         JSValueRef* exception)
894 {
895     SET_TIME_TRACER_ITEM(0);
896     LOGD("Entered");
897
898     EventMovePtr callback;
899
900     try {
901         FilePtr priv = JSFile::getPrivateObject(localContext, thisObject);
902
903         TIZEN_CHECK_ACCESS(localContext, exception, priv.get(),
904                 FILESYSTEM_FUNCTION_API_MOVE_TO);
905
906         ArgumentValidator validator(localContext, argc, argv);
907         auto globalManager = GlobalContextManager::getInstance();
908         JSContextRef globalContext = globalManager->getGlobalContext(localContext);
909         callback = EventMovePtr(new EventMove(globalContext));
910
911         std::string srcPath = validator.toString(0);
912         std::string destPath = validator.toString(1);
913         bool overwrite = validator.toBool(2);
914
915         JSValueRef onSuccess = validator.toFunction(3, true);
916         JSValueRef onError = validator.toFunction(4, true);
917
918         callback->setSuccessCallback(onSuccess);
919         callback->setErrorCallback(onError);
920         auto node = priv->getNode();
921
922         if (NT_DIRECTORY != node->getType()) {
923             return Utils::MainLoop<EventMovePtr>::passErrorLater(
924                     JSWebAPIErrorFactory::IO_ERROR,
925                     "io error",
926                     JSValueMakeUndefined(localContext),
927                     callback);
928         }
929         auto dirNode = priv->getNode();
930
931         PathPtr src = Utils::fromVirtualPath(
932                 globalContext,
933                 srcPath);
934         PathPtr dest = Utils::fromVirtualPath(
935                 globalContext,
936                 destPath);
937
938         // Filesystem spec:
939         // The file or directory to be moved MUST be under the Directory
940         // from which the method is invoked, otherwise the operation
941         // MUST NOT be performed.
942         //
943         // ringtones: the location for ringtones (read-only location)
944         // wgt-package: the widget package location (read-only location)
945         //
946         if (!dirNode->isSubPath(src) || !isDestinationAllowed(dest))
947         {
948             return Utils::MainLoop<EventMovePtr>::passErrorLater(
949                     JSWebAPIErrorFactory::INVALID_VALUES_ERROR,
950                     "Invalid Values",
951                     JSValueMakeUndefined(localContext),
952                     callback);
953         }
954         if ((node->getPermissions() & PERM_WRITE) == 0)
955         {
956             return Utils::MainLoop<EventMovePtr>::passErrorLater(
957                     JSWebAPIErrorFactory::INVALID_VALUES_ERROR,
958                     "permission denied error",
959                     JSValueMakeUndefined(localContext),
960                     callback);
961         }
962
963         callback->setSource(src);
964         callback->setDestination(dest);
965
966         if (overwrite)
967         {
968             callback->setOptions(OPT_OVERWRITE);
969         }
970
971         Manager::getInstance().move(callback);
972
973     } catch(const DeviceAPI::Common::BasePlatformException& err) {
974         LOGD("WrtDeviceAPI::Common::BasePlatformException exception caught");
975         if (!checkReportAsyncAPI(err.getName(),
976                                  err.getMessage(),
977                                  callback,
978                                  localContext))
979         {
980             LOGD("Synchronous error report for [%s]", err.getName().c_str());
981             return JSWebAPIErrorFactory::postException(localContext,
982                                                        exception,
983                                                        err);
984         }
985     } catch(const WrtDeviceApis::Commons::Exception& err) {
986         LOGD("WrtDeviceApis::Commons::Exception Exception caught");
987         if (!checkReportAsyncAPI(translateApi2APIErrors(err.GetClassName()),
988                                                         err.GetMessage(),
989                                                         callback,
990                                                         localContext))
991         {
992             return JSWebAPIErrorFactory::postException(
993                     localContext,
994                     exception,
995                     translateApi2APIErrors(std::string(err.GetClassName())),
996                     std::string(err.GetMessage()));
997         }
998     } catch (...) {
999         LOGD("Unexpected exception caught");
1000         DeviceAPI::Common::UnknownException err(
1001                 "Unknown Error");
1002         return JSWebAPIErrorFactory::postException(localContext, exception, err);
1003     }
1004
1005     return JSValueMakeUndefined(localContext);
1006 }
1007
1008 JSValueRef JSFile::createDirectory(JSContextRef context,
1009         JSObjectRef object,
1010         JSObjectRef thisObject,
1011         size_t argc,
1012         const JSValueRef argv[],
1013         JSValueRef* exception)
1014 {
1015     SET_TIME_TRACER_ITEM(0);
1016     LOGD("Entered");
1017
1018     try {
1019         FilePtr priv = JSFile::getPrivateObject(context, thisObject);
1020
1021         TIZEN_CHECK_ACCESS(context, exception, priv.get(),
1022                     FILESYSTEM_FUNCTION_API_CREATE_DIR);
1023
1024         Converter converter(context);
1025
1026         if (argc < 1) {
1027             LOGW("throw InvalidValuesException");
1028             throw DeviceAPI::Common::InvalidValuesException(
1029                     "Invalid path name");
1030         }
1031         auto dirNode = priv->getNode();
1032         if ((dirNode->getPermissions() & PERM_WRITE) == 0)
1033         {
1034             LOGW("throw SecurityException");
1035             throw DeviceAPI::Common::InvalidValuesException(
1036                     "Permission denied error");
1037         }
1038
1039         PathPtr path = converter.toPath(argv[0]);
1040         NodePtr node(dirNode->createChild(path, NT_DIRECTORY, OPT_RECURSIVE));
1041         node->setPermissions(dirNode->getPermissions());
1042
1043         FilePtr newDirPriv = FilePtr(new File(node, priv->getParentPermissions()));
1044         newDirPriv->pushParentPermissions(dirNode->getPermissions());
1045         return JSFile::makeJSObject(priv->getContext(), newDirPriv, priv.get());
1046     } catch(const DeviceAPI::Common::BasePlatformException& err) {
1047         LOGD("WrtDeviceAPI::Common::BasePlatformException exception caught");
1048         return JSWebAPIErrorFactory::postException(context, exception, err);
1049     } catch (...) {
1050         LOGD("Unexpected exception caught");
1051         DeviceAPI::Common::UnknownException err(
1052                 "Unknown Error");
1053         return JSWebAPIErrorFactory::postException(context, exception, err);
1054     }
1055 }
1056
1057 JSValueRef JSFile::createFile(JSContextRef context,
1058         JSObjectRef object,
1059         JSObjectRef thisObject,
1060         size_t argc,
1061         const JSValueRef argv[],
1062         JSValueRef* exception)
1063 {
1064     SET_TIME_TRACER_ITEM(0);
1065     LOGD("Entered");
1066
1067     try {
1068         FilePtr priv = JSFile::getPrivateObject(context, thisObject);
1069
1070         TIZEN_CHECK_ACCESS(context, exception, priv.get(),
1071                 FILESYSTEM_FUNCTION_API_CREATE_FILE);
1072
1073         Converter converter(context);
1074
1075         if (argc < 1) {
1076             LOGW("throw InvalidValuesException");
1077             throw DeviceAPI::Common::InvalidValuesException(
1078                     "Invalid path name");
1079         }
1080         auto dirNode = priv->getNode();
1081         if ((dirNode->getPermissions() & PERM_WRITE) == 0)
1082         {
1083             LOGW("throw SecurityException");
1084             throw DeviceAPI::Common::InvalidValuesException("Permission denied error");
1085         }
1086
1087         PathPtr path = converter.toPath(argv[0]);
1088         NodePtr node = dirNode->createChild(path, NT_FILE);
1089
1090         FilePtr newFilePriv = FilePtr(new File(node, priv->getParentPermissions()));
1091         newFilePriv->pushParentPermissions(dirNode->getPermissions());
1092         return JSFile::makeJSObject(priv->getContext(), newFilePriv, priv.get());
1093     } catch(const DeviceAPI::Common::BasePlatformException& err) {
1094         LOGD("WrtDeviceAPI::Common::BasePlatformException exception caught - %s: %s",
1095             err.getName().c_str(), err.getMessage().c_str());
1096         return JSWebAPIErrorFactory::postException(context, exception, err);
1097     } catch (...) {
1098         LOGD("Unexpected exception caught");
1099         DeviceAPI::Common::UnknownException err(
1100                 "Unknown Error");
1101         return JSWebAPIErrorFactory::postException(context, exception, err);
1102     }
1103 }
1104
1105 JSValueRef JSFile::resolve(JSContextRef context,
1106         JSObjectRef object,
1107         JSObjectRef thisObject,
1108         size_t argc,
1109         const JSValueRef argv[],
1110         JSValueRef* exception)
1111 {
1112     SET_TIME_TRACER_ITEM(0);
1113     LOGD("Entered");
1114
1115     try {
1116         FilePtr priv = JSFile::getPrivateObject(context, thisObject);
1117
1118         TIZEN_CHECK_ACCESS(context, exception, priv.get(),
1119                 FILESYSTEM_FUNCTION_API_RESOLVE);
1120
1121         if (priv->getNode()->getType() != NT_DIRECTORY) {
1122             LOGE("JSFile object is not directory.");
1123             return JSWebAPIErrorFactory::postException(
1124                     context,
1125                     exception,
1126                     JSWebAPIErrorFactory::IO_ERROR,
1127                     "IO error");
1128         }
1129
1130         Converter converter(context);
1131
1132         if (argc < 1) {
1133             LOGW("throw InvalidValuesException");
1134             throw DeviceAPI::Common::InvalidValuesException(
1135                     "Invalid path name");
1136         }
1137         auto dirNode = priv->getNode();
1138         PathPtr path = converter.toPath(argv[0]);
1139         NodePtr node = dirNode->getChild(path);
1140         node->setPermissions(dirNode->getPermissions());
1141
1142         FilePtr resolvedPriv = FilePtr(new File(node, priv->getParentPermissions()));
1143         resolvedPriv->pushParentPermissions(dirNode->getPermissions());
1144         return JSFile::makeJSObject(priv->getContext(), resolvedPriv, priv.get());
1145     } catch(const DeviceAPI::Common::BasePlatformException& err) {
1146         LOGD("WrtDeviceAPI::Common::BasePlatformException exception caught");
1147         return JSWebAPIErrorFactory::postException(context, exception, err);
1148     } catch (...) {
1149         LOGD("Unexpected exception caught");
1150         DeviceAPI::Common::UnknownException err(
1151                 "Unknown Error");
1152         return JSWebAPIErrorFactory::postException(context, exception, err);
1153     }
1154 }
1155
1156 JSValueRef JSFile::deleteDirectory(JSContextRef localContext,
1157         JSObjectRef object,
1158         JSObjectRef thisObject,
1159         size_t argc,
1160         const JSValueRef argv[],
1161         JSValueRef* exception)
1162 {
1163     SET_TIME_TRACER_ITEM(0);
1164     LOGD("Entered");
1165
1166     EventRemovePtr callback;
1167
1168     try {
1169         FilePtr priv = JSFile::getPrivateObject(localContext, thisObject);
1170
1171         TIZEN_CHECK_ACCESS(localContext, exception, priv.get(),
1172                 FILESYSTEM_FUNCTION_API_DELETE_DIR);
1173
1174         auto fileNode = priv->getNode();
1175
1176         if (argc < 2) {
1177             return JSWebAPIErrorFactory::postException(
1178                     localContext,
1179                     exception,
1180                     JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR,
1181                     "Type missmatch error");
1182         }
1183
1184         ArgumentValidator validator(localContext, argc, argv);
1185         validator.toFunction(2, true);
1186
1187         size_t index = 0;
1188         JSValueRef reserveArguments[4];
1189
1190         auto global = GlobalContextManager::getInstance();
1191         JSContextRef globalContext = global->getGlobalContext(localContext);
1192         callback = EventRemovePtr(new EventRemove(globalContext));
1193
1194         for (index = 0; index < 4; index++) {
1195         if (index < argc)
1196             reserveArguments[index] = argv[index];
1197         else
1198             reserveArguments[index] = JSValueMakeUndefined(localContext);
1199         }
1200
1201
1202         JSValueRef onSuccess = NULL;
1203         JSValueRef onError = NULL;
1204
1205         onSuccess = getFunctionOrNull(globalContext, reserveArguments[2]);
1206         onError = getFunctionOrNull(globalContext, reserveArguments[3]);
1207
1208         callback->setSuccessCallback(onSuccess);
1209         callback->setErrorCallback(onError);
1210
1211
1212         if ((fileNode->getPermissions() & PERM_WRITE) == 0)
1213         {
1214             return Utils::MainLoop<EventRemovePtr>::passErrorLater(
1215                     JSWebAPIErrorFactory::INVALID_VALUES_ERROR,
1216                     "permission denied error",
1217                     JSValueMakeUndefined(localContext),
1218                     callback);
1219         }
1220
1221         if (fileNode->getType() != NT_DIRECTORY) {
1222             return Utils::MainLoop<EventRemovePtr>::passErrorLater(
1223                     JSWebAPIErrorFactory::IO_ERROR,
1224                     "IO error",
1225                     JSValueMakeUndefined(localContext),
1226                     callback);
1227         }
1228
1229         Converter converter(localContext);
1230         PathPtr path = Utils::fromVirtualPath(
1231                 globalContext,
1232                 converter.toString(reserveArguments[0]));
1233         bool recursive = converter.toBool(reserveArguments[1]);
1234
1235         if (fileNode->getPath()->getFullPath() != path->getPath()) {
1236             return Utils::MainLoop<EventRemovePtr>::passErrorLater(
1237                     JSWebAPIErrorFactory::NOT_FOUND_ERROR,
1238                     "not found error in current directory",
1239                     JSValueMakeUndefined(localContext),
1240                     callback);
1241         }
1242
1243         if (verifyPath(callback, path, localContext, NT_DIRECTORY))
1244         {
1245             return JSValueMakeUndefined(localContext);
1246         }
1247         if (recursive) {
1248             callback->setOptions(OPT_RECURSIVE);
1249         }
1250
1251         callback->setPath(path);
1252
1253         Manager::getInstance().remove(callback);
1254     } catch(const DeviceAPI::Common::BasePlatformException& err) {
1255         LOGD("WrtDeviceAPI::Common::BasePlatformException exception caught");
1256         if (!checkReportAsyncAPI(err.getName(),
1257                                  err.getMessage(),
1258                                  callback,
1259                                  localContext)) {
1260             LOGD("Synchronous error report for [%s]", err.getName().c_str());
1261             return JSWebAPIErrorFactory::postException(localContext,
1262                                                        exception,
1263                                                        err);
1264         }
1265     } catch(const WrtDeviceApis::Commons::Exception& err) {
1266         LOGD("WrtDeviceApis::Commons::Exception Exception caught");
1267         if (!checkReportAsyncAPI(translateApi2APIErrors(err.GetClassName()),
1268                               err.GetMessage(),
1269                               callback,
1270                               localContext)) {
1271             return JSWebAPIErrorFactory::postException(
1272                     localContext,
1273                     exception,
1274                     translateApi2APIErrors(std::string(err.GetClassName())),
1275                     std::string(err.GetMessage()));
1276         }
1277     } catch (...) {
1278         LOGD("Unexpected exception caught");
1279         DeviceAPI::Common::UnknownException err(
1280                 "Unknown Error");
1281         return JSWebAPIErrorFactory::postException(localContext, exception, err);
1282     }
1283
1284     return JSValueMakeUndefined(localContext);
1285 }
1286
1287 JSValueRef JSFile::deleteFile(JSContextRef context,
1288         JSObjectRef object,
1289         JSObjectRef thisObject,
1290         size_t argc,
1291         const JSValueRef argv[],
1292         JSValueRef* exception)
1293 {
1294     SET_TIME_TRACER_ITEM(0);
1295     LOGD("Entered");
1296
1297     EventRemovePtr callback;
1298
1299     try {
1300         FilePtr priv = JSFile::getPrivateObject(context, thisObject);
1301
1302         TIZEN_CHECK_ACCESS(context, exception, priv.get(),
1303                 FILESYSTEM_FUNCTION_API_DELETE_FILE);
1304
1305         ArgumentValidator validator(context, argc, argv);
1306         validator.toFunction(1, true);
1307         validator.toFunction(2, true);
1308
1309         size_t index = 0;
1310         JSValueRef reserveArguments[3];
1311         auto contextManager = GlobalContextManager::getInstance();
1312         JSContextRef globalContext = contextManager->getGlobalContext(context);
1313         callback = EventRemovePtr(new EventRemove(globalContext));
1314
1315         for (index = 0; index < 3; index++) {
1316             if (index < argc) {
1317                 reserveArguments[index] = argv[index];
1318             } else {
1319                 reserveArguments[index] = JSValueMakeUndefined(context);
1320             }
1321         }
1322
1323         JSValueRef onSuccess = NULL;
1324         JSValueRef onError = NULL;
1325
1326         onSuccess = getFunctionOrNull(globalContext, reserveArguments[1]);
1327         onError = getFunctionOrNull(globalContext, reserveArguments[2]);
1328
1329         callback->setSuccessCallback(onSuccess);
1330         callback->setErrorCallback(onError);
1331
1332         auto node = priv->getNode();
1333         if ((node->getPermissions() & PERM_WRITE) == 0)
1334         {
1335             return Utils::MainLoop<EventRemovePtr>::passErrorLater(
1336                     JSWebAPIErrorFactory::INVALID_VALUES_ERROR,
1337                     "permission denied error",
1338                     JSValueMakeUndefined(context),
1339                     callback);
1340         }
1341
1342         if (node->getType() != NT_DIRECTORY) {
1343             return Utils::MainLoop<EventRemovePtr>::passErrorLater(
1344                     JSWebAPIErrorFactory::IO_ERROR,
1345                     "IO error",
1346                     JSValueMakeUndefined(context),
1347                     callback);
1348         }
1349
1350
1351         Converter converter(context);
1352         PathPtr path = Utils::fromVirtualPath(
1353                 globalContext,
1354                 converter.toString(reserveArguments[0]));
1355
1356         if (*node->getPath() != path->getPath()) {
1357             return Utils::MainLoop<EventRemovePtr>::passErrorLater(
1358                     JSWebAPIErrorFactory::NOT_FOUND_ERROR,
1359                     "not found error in current directory",
1360                     JSValueMakeUndefined(context),
1361                     callback);
1362         }
1363         if (verifyPath(callback, path, context, NT_FILE))
1364         {
1365             return JSValueMakeUndefined(context);
1366         }
1367
1368         LOGD("try to call async event");
1369         callback->setPath(path);
1370         Manager::getInstance().remove(callback);
1371     } catch(const DeviceAPI::Common::BasePlatformException& err) {
1372         LOGD("WrtDeviceAPI::Common::BasePlatformException exception caught");
1373         if (!checkReportAsyncAPI(err.getName(),
1374                                  err.getMessage(),
1375                                  callback,
1376                                  context)) {
1377             LOGD("Synchronous error report for [%s]", err.getName().c_str());
1378             return JSWebAPIErrorFactory::postException(context,
1379                                                        exception,
1380                                                        err);
1381         }
1382     } catch(const WrtDeviceApis::Commons::Exception& err) {
1383         LOGD("WrtDeviceApis::Commons::Exception Exception caught");
1384         if (!checkReportAsyncAPI(translateApi2APIErrors(err.GetClassName()),
1385                                  err.GetMessage(),
1386                                  callback,
1387                                  context)) {
1388             return JSWebAPIErrorFactory::postException(
1389                     context,
1390                     exception,
1391                     translateApi2APIErrors(std::string(err.GetClassName())),
1392                     std::string(err.GetMessage()));
1393         }
1394     } catch (...) {
1395         LOGD("Unexpected exception caught");
1396         DeviceAPI::Common::UnknownException err(
1397                 "Unknown Error");
1398         return JSWebAPIErrorFactory::postException(context, exception, err);
1399     }
1400
1401     return JSValueMakeUndefined(context);
1402 }
1403
1404 } //namespace DeviceAPI
1405 } //namespace Filesystem