From: Arkadiusz Pietraszek Date: Thu, 19 Apr 2018 11:10:50 +0000 (+0200) Subject: [Filesystem] Added filesystem methods to file_system_manager.js X-Git-Tag: submit/tizen/20180518.121229~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fd1d402573e83de459363986584debe84b5ff873;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Filesystem] Added filesystem methods to file_system_manager.js Change-Id: I5a6f55d9dc82a98ad0e1e4e6d062ccc93e40479d Signed-off-by: Szymon Jastrzebski Signed-off-by: Arkadiusz Pietraszek Signed-off-by: Jakub Skowron Signed-off-by: Pawel Wasowski --- diff --git a/src/filesystem/js/file_system_manager.js b/src/filesystem/js/file_system_manager.js old mode 100755 new mode 100644 index 622f38d4..b40df95b --- a/src/filesystem/js/file_system_manager.js +++ b/src/filesystem/js/file_system_manager.js @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + function FileSystemStorage(data) { Object.defineProperties(this, { label: {value: data.label, writable: false, enumerable: true}, @@ -22,33 +22,534 @@ function FileSystemStorage(data) { }); } -var PATH_MAX = 4096; + +var FileStreamManager = function() { + this.nextId = 0; +}; + +FileStreamManager.prototype.getNextFileHandleId = function() { + return ++this.nextId; +}; + +var fileStreamManager = new FileStreamManager(); function FileSystemManager() { + var limits = native_.getResultObject(native_.callSync('FileSystemManager_getLimits')); Object.defineProperties(this, { - maxPathLength: {value: PATH_MAX, writable: false, enumerable: true} + maxNameLength: {value: limits[0], writable: false, enumerable: true}, + maxPathLength: {value: limits[1], writable: false, enumerable: true} }); } +FileSystemManager.prototype.openFile = function() { + var args = validator_.validateArgs(arguments, [ + {name: 'path', type: types_.STRING}, + {name: 'openMode', type: types_.ENUM, values: type_.getValues(FileMode)}, + {name: 'makeParents', type: types_.BOOLEAN, optional: true} + ]); + + if (!args.has.makeParents) { + args.makeParents = true; + } + + var data = { + path: commonFS_.toRealPath(args.path), + openMode: args.openMode, + makeParents: args.makeParents, + id: fileStreamManager.getNextFileHandleId() + }; + + if (!data.path) { + throw new WebAPIException( + WebAPIException.NOT_FOUND_ERR, 'Invalid path: ' + args.path); + } + + var result = native_.callSync('FileSystemManager_openFile', data); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } else { + return new FileHandle(data.id, args.path, args.openMode); + } +}; + +FileSystemManager.prototype.createDirectory = function() { + var args = validator_.validateArgs(arguments, [ + {name: 'path', type: types_.STRING}, + {name: 'makeParents', type: types_.BOOLEAN, optional: true}, + {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true}, + {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true} + ]); + + if (!args.has.makeParents) { + args.makeParents = true; + } + + var data = {path: commonFS_.toRealPath(args.path), makeParents: args.makeParents}; + + if (!data.path) { + throw new WebAPIException( + WebAPIException.NOT_FOUND_ERR, 'Invalid path: ' + args.path); + } + + var callback = function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + } else { + native_.callIfPossible(args.successCallback); + } + }; + + var result = native_.call('FileSystemManager_createDirectory', data, callback); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } +}; + +FileSystemManager.prototype.deleteFile = function() { + var args = validator_.validateArgs(arguments, [ + {name: 'path', type: types_.STRING}, + {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true}, + {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true} + ]); + + var data = {path: commonFS_.toRealPath(args.path)}; + + if (!data.path) { + throw new WebAPIException( + WebAPIException.NOT_FOUND_ERR, 'Invalid path: ' + args.path); + } + + var callback = function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + } else { + native_.callIfPossible(args.successCallback); + } + }; + + var result = native_.call('FileSystemManager_deleteFile', data, callback); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } +}; + +FileSystemManager.prototype.deleteDirectory = function() { + var args = validator_.validateArgs(arguments, [ + {name: 'path', type: types_.STRING}, + {name: 'recursive', type: types_.BOOLEAN, optional: true}, + {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true}, + {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true} + ]); + + if (!args.has.recursive) { + args.recursive = true; + } + + var realPath = commonFS_.toRealPath(args.path); + if (!realPath) { + throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Invalid path.'); + } + + var data = {path: realPath, recursive: args.recursive}; + + var callback = function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + } else { + native_.callIfPossible(args.successCallback); + } + }; + + var result = native_.call('FileSystemManager_deleteDirectory', data, callback); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } +}; + +FileSystemManager.prototype.copyFile = function() { + var args = validator_.validateArgs(arguments, [ + {name: 'path', type: types_.STRING}, {name: 'destinationPath', type: types_.STRING}, + {name: 'overwrite', type: types_.BOOLEAN, optional: true}, + {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true}, + {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true} + ]); + + if (!args.has.overwrite) { + args.overwrite = false; + } + + var data = { + path: commonFS_.toRealPath(args.path), + destinationPath: commonFS_.toRealPath(args.destinationPath), + overwrite: args.overwrite + }; + + if (!data.path) { + throw new WebAPIException( + WebAPIException.INVALID_VALUES_ERR, 'Invalid path: ' + args.path); + } + if (!data.destinationPath) { + throw new WebAPIException( + WebAPIException.INVALID_VALUES_ERR, 'Invalid path: ' + args.destinationPath); + } + + var callback = function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + } else { + native_.callIfPossible(args.successCallback); + } + }; + + var result = native_.call('FileSystemManager_copyFile', data, callback); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } +}; + +FileSystemManager.prototype.copyDirectory = function() { + var args = validator_.validateArgs(arguments, [ + {name: 'path', type: types_.STRING}, + {name: 'destinationPath', type: types_.STRING}, + {name: 'overwrite', type: types_.BOOLEAN, optional: true}, + {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true}, + {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true} + ]); + + var realPath = commonFS_.toRealPath(args.path); + var realDestinationPath = commonFS_.toRealPath(args.destinationPath); + if (!realPath || !realDestinationPath) { + throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Invalid path.'); + } + + if (!args.has.overwrite) { + args.overwrite = false; + } + + var data = { + path: realPath, + destinationPath: realDestinationPath, + overwrite: args.overwrite + }; + + var callback = function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + } else { + native_.callIfPossible(args.successCallback); + } + }; + + var result = native_.call('FileSystemManager_copyDirectory', data, callback); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } +}; + +FileSystemManager.prototype.moveFile = function() { + var args = validator_.validateArgs(arguments, [ + {name: 'path', type: types_.STRING}, + {name: 'destinationPath', type: types_.STRING}, + {name: 'overwrite', type: types_.BOOLEAN, optional: true}, + {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true}, + {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true} + ]); + + var realPath = commonFS_.toRealPath(args.path); + var realDestinationPath = commonFS_.toRealPath(args.destinationPath); + if (!realPath || !realDestinationPath) { + throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Invalid path.'); + } + + if (!args.has.overwrite) { + args.overwrite = false; + } + + var data = { + path: realPath, + destinationPath: realDestinationPath, + overwrite: args.overwrite + }; + + var callback = function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + } else { + native_.callIfPossible(args.successCallback); + } + }; + + var result = native_.call('FileSystemManager_moveFile', data, callback); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } +}; + +FileSystemManager.prototype.moveDirectory = function() { + var args = validator_.validateArgs(arguments, [ + {name: 'path', type: types_.STRING}, + {name: 'destinationPath', type: types_.STRING}, + {name: 'overwrite', type: types_.BOOLEAN, optional: true}, + {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true}, + {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true} + ]); + + var realPath = commonFS_.toRealPath(args.path); + var realDestinationPath = commonFS_.toRealPath(args.destinationPath); + if (!realPath || !realDestinationPath) { + throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Invalid path.'); + } + + if (!args.has.overwrite) { + args.overwrite = false; + } + + var data = { + path: realPath, + destinationPath: realDestinationPath, + overwrite: args.overwrite + }; + + var callback = function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + } else { + native_.callIfPossible(args.successCallback); + } + }; + + var result = native_.call('FileSystemManager_moveDirectory', data, callback); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } +}; + +FileSystemManager.prototype.rename = function() { + var args = validator_.validateArgs(arguments, [ + {name: 'path', type: types_.STRING}, + {name: 'newName', type: types_.STRING}, + {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true}, + {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true} + ]); + + if ((-1 !== args.newName.indexOf('/')) || (-1 !== args.newName.indexOf('\x00'))) { + throw new WebAPIException( + WebAPIException.INVALID_VALUES_ERR, 'newName contains invalid character.'); + } + + var realPath = commonFS_.toRealPath(args.path); + if (!realPath) { + throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Invalid path.'); + } + + var data = {path: realPath, newName: args.newName}; + + var callback = function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + } else { + native_.callIfPossible(args.successCallback); + } + }; + + var result = native_.call('FileSystemManager_rename', data, callback); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } +}; + +function throwIfNotDate(argument, name) { + if (argument instanceof Date) { + return true; + } + throw new WebAPIException( + WebAPIException.TYPE_MISMATCH_ERR, + 'Argument "' + name + '" in a filter is not of type Date.'); +} + +FileSystemManager.prototype.listDirectory = function() { + var args = validator_.validateArgs(arguments, [ + {name: 'path', type: types_.STRING}, + {name: 'successCallback', type: types_.FUNCTION, optional: true}, + {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true}, + {name: 'filter', type: types_.DICTIONARY, optional: true, nullable: true} + ]); + + if (!args.has.filter) { + args.filter = {}; + } + + if (args.filter.hasOwnProperty('startModified')) { + throwIfNotDate(args.filter.endModified, 'endModified'); + args.filter.startModified = args.filter.startModified.getTime() / 1000; + } + if (args.filter.hasOwnProperty('endModified')) { + throwIfNotDate(args.filter.endModified, 'endModified'); + args.filter.endModified = args.filter.endModified.getTime() / 1000; + } + if (args.filter.hasOwnProperty('startCreated')) { + throwIfNotDate(args.filter.endModified, 'endModified'); + args.filter.startCreated = args.filter.startCreated.getTime() / 1000; + } + if (args.filter.hasOwnProperty('endCreated')) { + throwIfNotDate(args.filter.endModified, 'endModified'); + args.filter.endCreated = args.filter.endCreated.getTime() / 1000; + } + + var data = {path: commonFS_.toRealPath(args.path), filter: args.filter}; + + if (!data.path) { + throw new WebAPIException( + WebAPIException.INVALID_VALUES_ERR, 'Invalid path: ' + args.path); + } + + var callback = function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + } else { + var names = native_.getResultObject(result); + if (args.filter.hasOwnProperty('name')) { + var regex_name = stringToRegex(args.filter.name); + for (var i = names.length - 1; i >= 0; i--) { + if (!regex_name.test(names[i])) { + names.splice(i, 1); + } + } + } + native_.callIfPossible(args.successCallback, names); + } + }; + + var result = native_.call('FileSystemManager_listDirectory', data, callback); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } +}; + +FileSystemManager.prototype.toURI = function() { + var args = validator_.validateArgs(arguments, [{name: 'path', type: types_.STRING}]); + + // The toRealPath function will convert any string to absolute path, if possible. + // The function returns undefined for path, which starts with not-existing virtual root. + var realPath = commonFS_.toRealPath(args.path); + + if (!realPath) { + throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Invalid path.'); + } + + return 'file://' + realPath; +}; + +FileSystemManager.prototype.isFile = function() { + var args = validator_.validateArgs(arguments, [{name: 'path', type: types_.STRING}]); + + // The toRealPath function will convert any string to absolute path, if possible. + // The function returns undefined for path, which starts with not-existing virtual root. + var realPath = commonFS_.toRealPath(args.path); + + if (!realPath) { + throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Invalid path.'); + } + + var data = {path: realPath}; + + var result = native_.callSync('FileSystemManager_isFile', data); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } else { + return native_.getResultObject(result); + } +}; + +FileSystemManager.prototype.isDirectory = function() { + var args = validator_.validateArgs(arguments, [{name: 'path', type: types_.STRING}]); + + // The toRealPath function will convert any string to absolute path, if possible. + // The function returns undefined for path, which starts with not-existing virtual root. + var realPath = commonFS_.toRealPath(args.path); + + if (!realPath) { + throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Invalid path.'); + } + + var data = {path: realPath}; + + var result = native_.callSync('FileSystemManager_isDirectory', data); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } else { + return native_.getResultObject(result); + } +}; + +FileSystemManager.prototype.pathExists = function() { + var args = validator_.validateArgs(arguments, [{name: 'path', type: types_.STRING}]); + + // The toRealPath function will convert any string to absolute path, if possible. + // The function returns undefined for path, which starts with not-existing virtual root. + var realPath = commonFS_.toRealPath(args.path); + + if (!realPath) { + throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Invalid path.'); + } + var data = {path: realPath}; + + var result = native_.callSync('FileSystemManager_pathExists', data); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } else { + return native_.getResultObject(result); + } +}; + +FileSystemManager.prototype.getDirName = function() { + var args = validator_.validateArgs(arguments, [{name: 'path', type: types_.STRING}]); + var path = args.path; + + path = mergeMultipleSlashes(path); + if (path.startsWith('file://')) { + path = path.substring('file://'.length - 1, path.length - 1); + } + + if (path.startsWith('/') && + 0 === path.lastIndexOf('/')) { // handle the "/" and "/file.ext" + return '/'; + } else if (path.endsWith('/')) { // cut the last '/' + path = path.substring(0, path.length - 1); + } + + var index = path.lastIndexOf('/'); + if (-1 !== index) { + path = path.substring(0, index); // cut the directory/file the path points to + } + return path; +}; + function resolve() { var args = validator_.validateArgs(arguments, [ - {name: 'location', type: types_.STRING}, - {name: 'onsuccess', type: types_.FUNCTION}, - {name: 'onerror', type: types_.FUNCTION, optional: true, nullable: true}, - {name: 'mode', type: types_.ENUM, values: Object.keys(FileMode), optional: true, nullable: true} + {name: 'location', type: types_.STRING}, {name: 'onsuccess', type: types_.FUNCTION}, + {name: 'onerror', type: types_.FUNCTION, optional: true, nullable: true}, { + name: 'mode', + type: types_.ENUM, + values: Object.keys(FileMode), + optional: true, + nullable: true + } ]); if (!args.has.mode) { args.mode = 'rw'; + } else if ('rwo' == args.mode) { + throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'rwo mode was introduced in version 5.0 and is not supported in earlier version methods'); } // resolving a path on unmounted storage should result in exception var storage = commonFS_.getStorage(args.location.split('/')[0]); if (storage && FileSystemStorageState.MOUNTED !== storage.state) { setTimeout(function() { - native_.callIfPossible(args.onerror, - new WebAPIException(WebAPIException.NOT_FOUND_ERR, - 'Storage is not mounted.')); + native_.callIfPossible( + args.onerror, + new WebAPIException(WebAPIException.NOT_FOUND_ERR, 'Storage is not mounted.')); }, 0); return; } @@ -58,9 +559,10 @@ function resolve() { if (!result) { // path contains dots - it is not allowed - return InvalidValuesError setTimeout(function() { - native_.callIfPossible(args.onerror, - new WebAPIException(WebAPIException.INVALID_VALUES_ERR, - 'Path contains \'.\' or \'..\' - it is not allowed.')); + native_.callIfPossible( + args.onerror, new WebAPIException( + WebAPIException.INVALID_VALUES_ERR, + 'Path contains \'.\' or \'..\' - it is not allowed.')); }, 0); return; } @@ -70,9 +572,9 @@ function resolve() { if (!_realPath) { // invalid real path means that virtual root does not exist setTimeout(function() { - native_.callIfPossible(args.onerror, - new WebAPIException(WebAPIException.NOT_FOUND_ERR, - 'Specified virtual root does not exist.')); + native_.callIfPossible( + args.onerror, + new WebAPIException(WebAPIException.NOT_FOUND_ERR, 'Invalid path.')); }, 0); return; } @@ -81,16 +583,15 @@ function resolve() { if (args.mode !== 'r' && !_isLocationAllowed) { setTimeout(function() { - native_.callIfPossible(args.onerror, - new WebAPIException(WebAPIException.INVALID_VALUES_ERR, - 'Provided arguments are not valid.')); + native_.callIfPossible( + args.onerror, + new WebAPIException( + WebAPIException.INVALID_VALUES_ERR, 'Provided arguments are not valid.')); }, 0); return; } - var data = { - location: _realPath - }; + var data = {location: _realPath}; var callback = function(result) { if (native_.isFailure(result)) { @@ -101,7 +602,9 @@ function resolve() { var aStatObj = native_.getResultObject(result); var _result = commonFS_.getFileInfo(aStatObj, false, args.mode); if (_result.readOnly && args.mode !== 'r') { - native_.callIfPossible(args.onerror, new WebAPIException(WebAPIException.IO_ERR, 'File is read-only.')); + native_.callIfPossible( + args.onerror, + new WebAPIException(WebAPIException.IO_ERR, 'File is read-only.')); } else { native_.callIfPossible(args.onsuccess, new File(_result)); } @@ -109,9 +612,9 @@ function resolve() { var ret = native_.call('File_stat', data, callback); if (native_.isFailure(ret)) { - throw native_.getErrorObject(ret); + throw native_.getErrorObject(ret); } -}; +} FileSystemManager.prototype.resolve = function() { resolve.apply(this, arguments); @@ -120,8 +623,7 @@ FileSystemManager.prototype.resolve = function() { function getStorage() { xwalk.utils.checkPrivilegeAccess(xwalk.utils.privilege.FILESYSTEM_READ); var args = validator_.validateArgs(arguments, [ - {name: 'label', type: types_.STRING}, - {name: 'onsuccess', type: types_.FUNCTION}, + {name: 'label', type: types_.STRING}, {name: 'onsuccess', type: types_.FUNCTION}, {name: 'onerror', type: types_.FUNCTION, optional: true, nullable: true} ]); @@ -129,13 +631,14 @@ function getStorage() { var storage = commonFS_.getStorage(args.label); if (!storage) { - native_.callIfPossible(args.onerror, + native_.callIfPossible( + args.onerror, new WebAPIException(WebAPIException.NOT_FOUND_ERR, 'Storage not found.')); } else { native_.callIfPossible(args.onsuccess, new FileSystemStorage(storage)); } }, 0); -}; +} FileSystemManager.prototype.getStorage = function() { getStorage.apply(this, arguments); @@ -157,7 +660,7 @@ function listStorages() { native_.callIfPossible(args.onsuccess, storages); }, 0); -}; +} FileSystemManager.prototype.listStorages = function() { listStorages.apply(this, arguments); @@ -202,20 +705,17 @@ function addStorageStateChangeListener() { } return id; -}; +} FileSystemManager.prototype.addStorageStateChangeListener = function() { return addStorageStateChangeListener.apply(this, arguments); }; function removeStorageStateChangeListener() { - var args = validator_.validateArgs(arguments, [ - {name: 'watchId', type: types_.LONG} - ]); + var args = validator_.validateArgs(arguments, [{name: 'watchId', type: types_.LONG}]); if (!arguments.length) { - throw new WebAPIException(WebAPIException.TYPE_MISMATCH_ERR, - 'Missing watchId'); + throw new WebAPIException(WebAPIException.TYPE_MISMATCH_ERR, 'Missing watchId'); } var id = args.watchId; @@ -226,12 +726,13 @@ function removeStorageStateChangeListener() { delete callbacks[id]; if (type_.isEmptyObject(callbacks)) { - var result = native_.callSync('FileSystemManager_removeStorageStateChangeListener', {}); + var result = + native_.callSync('FileSystemManager_removeStorageStateChangeListener', {}); if (native_.isFailure(result)) { throw native_.getErrorObject(result); } } -}; +} FileSystemManager.prototype.removeStorageStateChangeListener = function() { removeStorageStateChangeListener.apply(this, arguments);