diff --git a/FileSystem/file_system.d.ts b/FileSystem/file_system.d.ts index e4956e6d3..886105e0b 100644 --- a/FileSystem/file_system.d.ts +++ b/FileSystem/file_system.d.ts @@ -3,22 +3,27 @@ * Gets the Date object specifying the last time this entity was modified. */ public lastModified: Date; + /** * Gets the name of the entity. */ public name: string; + /** * Gets the fully-qualified path (including the extension for a File) of the entity. */ public path: string; + /** * Gets the Folder object representing the parent of this entity. Will be null for a root folder like Documents or Temporary. */ public getParent(onError?: (error: any) => any): Folder; + /** - * Deletes the current Entity from the file system. + * Removes (deletes) the current Entity from the file system. */ - public delete(onSuccess?: () => any, onError?: (error: any) => any); + public remove(onSuccess?: () => any, onError?: (error: any) => any); + /** * Renames the current entity using the specified name. */ @@ -26,26 +31,31 @@ } export declare class File extends FileSystemEntity { + /** + * Checks whether a File with the specified path already exists. + */ + public static exists(path: string): boolean; + /** * Gets the extension of the file. */ public extension: string; + /** * Gets a value indicating whether the file is currently locked, meaning a background operation associated with this file is running. */ public isLocked: boolean; + /** * Gets or creates a File entity at the specified path. */ public static fromPath(path: string, onError?: (error: any) => any): File; - /** - * Checks whether a File with the specified path already exists. - */ - public static exists(path: string): boolean; + /** * Creates a FileReader object over this file and locks the file until the reader is released. */ public openRead(): FileReader; + /** * Creates a FileWriter object over this file and locks the file until the writer is released. */ @@ -69,19 +79,15 @@ export declare class Folder extends FileSystemEntity { public static exists(path: string): boolean; /** - * Checks whether this Folder contains a file with the specified name. + Checks whether this Folder contains an Entity with the specified name. + The path of the folder is added to the name to resolve the complete path to check for. */ - public containsFile(name: string): boolean; - - /** - * Checks whether this Folder contains a Folder with the specified name. - */ - public containsFolder(name: string): boolean; + public contains(name: string): boolean; /** * Deletes all the files and folders (recursively), contained within this Folder. */ - public empty(onSuccess?: () => any, onError?: (error: any) => any); + public clear(onSuccess?: () => any, onError?: (error: any) => any); /** * Gets or creates a File entity with the specified name within this Folder. @@ -89,15 +95,22 @@ export declare class Folder extends FileSystemEntity { public getFile(name: string, onError?: (error: any) => any): File; /** - * Gets or creates a Folder entity with the specified name within this Folder. - */ + * Gets or creates a Folder entity with the specified name within this Folder. + */ public getFolder(name: string, onError?: (error: any) => any): Folder; /** - * Gets all the top-level FileSystem entities residing within this Folder. + * Gets all the top-level entities residing within this folder. */ - public enumEntities(onSuccess: (entities: Array) => any, onError?: (error: any) => any); -} + public getEntities(onSuccess: (entities: Array) => any, onError?: (error) => any); + + /** + Enumerates all the top-level FileSystem entities residing within this folder. + The first parameter is a callback that receives the current entity. + If the callback returns false this will mean for the iteration to stop. + */ + public eachEntity(onEntity: (entity: FileSystemEntity) => boolean, onError?: (error: any) => any); + } /** * Provides access to the top-level Folders instances that are accessible from the application. Use these as entry points to access the FileSystem. diff --git a/FileSystem/file_system.ts b/FileSystem/file_system.ts index 99ac71829..7374ea7df 100644 --- a/FileSystem/file_system.ts +++ b/FileSystem/file_system.ts @@ -64,9 +64,9 @@ export class FileSystemEntity { } /** - * Deletes the current entity from the file system. + * Removes the current entity from the file system. */ - public delete(onSuccess?: () => any, onError?: (error: any) => any) { + public remove(onSuccess?: () => any, onError?: (error: any) => any) { if (this instanceof File) { getFileAccess().deleteFile(this.path, onSuccess, onError); } else if (this instanceof Folder) { @@ -233,25 +233,21 @@ export class Folder extends FileSystemEntity { /** * Checks whether this Folder contains a file with the specified name. */ - public containsFile(name: string): boolean { + public contains(name: string): boolean { var fileAccess = getFileAccess(); var path = fileAccess.concatPath(this.path, name); - return fileAccess.fileExists(path); - } - /** - * Checks whether this Folder contains a Folder with the specified name. - */ - public containsFolder(name: string): boolean { - var fileAccess = getFileAccess(); - var path = fileAccess.concatPath(this.path, name); + if (fileAccess.fileExists(path)) { + return true; + } + return fileAccess.folderExists(path); } /** - * Deletes all the files and folders (recursively), contained within this Folder. + * Removes all the files and folders (recursively), contained within this Folder. */ - public empty(onSuccess?: () => any, onError?: (error: any) => any) { + public clear(onSuccess?: () => any, onError?: (error: any) => any) { getFileAccess().emptyFolder(this.path, onSuccess, onError); } @@ -295,7 +291,7 @@ export class Folder extends FileSystemEntity { /** * Gets all the top-level FileSystem entities residing within this Folder. */ - public enumEntities(onSuccess: (files: Array) => any, onError?: (error: any) => any) { + public getEntities(onSuccess: (files: Array) => any, onError?: (error: any) => any) { var localSuccess = function (fileInfos: Array<{ path: string; name: string; extension: string }>) { if (onSuccess) { var entities = new Array(); @@ -314,7 +310,30 @@ export class Folder extends FileSystemEntity { onSuccess(entities); } } - getFileAccess().enumFiles(this.path, localSuccess, onError); + getFileAccess().getEntities(this.path, localSuccess, onError); + } + + /** + Enumerates all the top-level FileSystem entities residing within this folder. + The first parameter is a callback that receives the current entity. + If the callback returns false this will mean for the iteration to stop. + */ + public eachEntity(onEntity: (entity: FileSystemEntity) => boolean, onError?: (error: any) => any) { + if (!onEntity) { + return; + } + + var localSuccess = function (fileInfo: { path: string; name: string; extension: string }): boolean { + var entity; + if (fileInfo.extension) { + entity = createFile(fileInfo); + } else { + entity = createFolder(fileInfo); + } + + return onEntity(entity); + } + getFileAccess().eachEntity(this.path, localSuccess, onError); } } diff --git a/FileSystem/file_system_access.android.ts b/FileSystem/file_system_access.android.ts index 8a90124b2..710a609f1 100644 --- a/FileSystem/file_system_access.android.ts +++ b/FileSystem/file_system_access.android.ts @@ -40,48 +40,38 @@ export class FileSystemAccess { return { path: dirInfo.path, name: dirInfo.name }; } - public enumFiles(path: string, onSuccess: (files: Array<{ path: string; name: string; extension: string }>) => any, onError?: (error: any) => any) { - try { - var javaFile = new java.io.File(path); - if (!javaFile.getCanonicalFile().isDirectory()) { - if (onError) { - onError("There is no folder existing at path " + path); - } + public eachEntity(path: string, onEntity: (file: { path: string; name: string; extension: string }) => boolean, onError?: (error: any) => any) { + if (!onEntity) { + return; + } - return; - } + this.enumEntities(path, onEntity, onError); + } - var filesList: any = javaFile.listFiles(); - var fileInfos = new Array<{ path: string; name: string; extension: string }>(); + public getEntities(path: string, onSuccess: (files: Array<{ path: string; name: string; extension: string }>) => any, onError?: (error: any) => any) { + if (!onSuccess) { + return; + } - var length = filesList.length, - i, - filePath, - info; + var fileInfos = new Array<{ path: string; name: string; extension: string }>(); + var onEntity = function (entity: { path: string; name: string; extension: string }): boolean { + fileInfos.push(entity); + return true; + } - for (i = 0; i < length; i++) { - javaFile = filesList[i]; - - info = { - path: javaFile.getAbsolutePath(), - name: javaFile.getName() - }; - - if (javaFile.isFile()) { - info.extension = this.getFileExtension(info.path); - } - - fileInfos.push(info); - } - - if (onSuccess) { - onSuccess(fileInfos); - } - - } catch (exception) { + var errorOccurred; + var localError = function (error: any) { if (onError) { - onError(exception); + onError(error); } + + errorOccurred = true; + } + + this.enumEntities(path, onEntity, localError); + + if (!errorOccurred) { + onSuccess(fileInfos); } } @@ -346,13 +336,56 @@ export class FileSystemAccess { } } + // TODO: This method is the same as in the iOS implementation. + // Make it in a separate file / module so it can be reused from both implementations. private getFileExtension(path: string): string { var dotIndex = path.lastIndexOf("."); if (dotIndex && dotIndex >= 0 && dotIndex < path.length) { - // return the extension without the "." (like in iOS) - return path.substring(dotIndex + 1); + return path.substring(dotIndex); } - return undefined; + return ""; + } + + private enumEntities(path: string, callback: (entity: { path: string; name: string; extension: string }) => boolean, onError?: (error) => any) { + try { + var javaFile = new java.io.File(path); + if (!javaFile.getCanonicalFile().isDirectory()) { + if (onError) { + onError("There is no folder existing at path " + path); + } + + return; + } + + var filesList = javaFile.listFiles(); + var length = filesList.length, + i, + filePath, + info, + retVal; + + for (i = 0; i < length; i++) { + javaFile = filesList[i]; + + info = { + path: javaFile.getAbsolutePath(), + name: javaFile.getName() + }; + + if (javaFile.isFile()) { + info.extension = this.getFileExtension(info.path); + } + + retVal = callback(info); + if (retVal != undefined && !retVal) { + break; + } + } + } catch (exception) { + if (onError) { + onError(exception); + } + } } } \ No newline at end of file diff --git a/FileSystem/file_system_access.d.ts b/FileSystem/file_system_access.d.ts index 4b7db87ba..093dfb0e0 100644 --- a/FileSystem/file_system_access.d.ts +++ b/FileSystem/file_system_access.d.ts @@ -7,7 +7,10 @@ export declare class FileSystemAccess { getParent(path: string, onError?: (error: any) => any): { path: string; name: string }; getFile(path: string, onError?: (error: any) => any): { path: string; name: string; extension: string }; getFolder(path: string, onError?: (error: any) => any): { path: string; name: string }; - enumFiles(path: string, onSuccess: (files: Array<{ path: string; name: string; extension: string }>) => any, onError?: (error: any) => any); + + getEntities(path: string, onSuccess: (files: Array<{ path: string; name: string; extension: string }>) => any, onError?: (error: any) => any); + eachEntity(path: string, onSuccess: (entity: { path: string; name: string; extension: string }) => boolean, onError?: (error: any) => any); + fileExists(path: string): boolean; folderExists(path: string): boolean; concatPath(left: string, right: string): string; diff --git a/FileSystem/file_system_access.ios.ts b/FileSystem/file_system_access.ios.ts index ffcf27496..c00196065 100644 --- a/FileSystem/file_system_access.ios.ts +++ b/FileSystem/file_system_access.ios.ts @@ -114,48 +114,38 @@ export class FileSystemAccess { } } - public enumFiles(path: string, onSuccess: (files: Array<{ path: string; name: string; extension: string }>) => any, onError?: (error: any) => any) { - try { - var fileManager = Foundation.NSFileManager.defaultManager(); - var files = fileManager.contentsOfDirectoryAtPathError(path, null); - - if (!files) { - if (onError) { - onError(new Error("Failed to enum files for forlder '" + path + "'")); - } - - return; - } - - var fileInfos = new Array<{ path: string; name: string; extension: string }>(); - var file, - i, - info; - - - for (i = 0; i < files.count(); i++) { - file = files.objectAtIndex(i); - - info = { - path: this.concatPath(path, file), - name: file - }; - - if (!this.folderExists(file)) { - info.extension = this.getFileExtension(info.path); - } - - fileInfos.push(info); - } - - if (onSuccess) { - onSuccess(fileInfos); - } + public eachEntity(path: string, onEntity: (file: { path: string; name: string; extension: string }) => any, onError?: (error: any) => any) { + if (!onEntity) { + return; } - catch (ex) { + + this.enumEntities(path, onEntity, onError); + } + + public getEntities(path: string, onSuccess: (files: Array<{ path: string; name: string; extension: string }>) => any, onError?: (error: any) => any) { + if (!onSuccess) { + return; + } + + var fileInfos = new Array<{ path: string; name: string; extension: string }>(); + var onEntity = function (entity: { path: string; name: string; extension: string }): boolean { + fileInfos.push(entity); + return true; + } + + var errorOccurred; + var localError = function (error: any) { if (onError) { - onError(ex); + onError(error); } + + errorOccurred = true; + } + + this.enumEntities(path, onEntity, onError); + + if (!errorOccurred) { + onSuccess(fileInfos); } } @@ -213,7 +203,7 @@ export class FileSystemAccess { } } - this.enumFiles(path, filesEnum, onError); + this.getEntities(path, filesEnum, onError); } public rename(path: string, newPath: string, onSuccess?: () => any, onError?: (error: any) => any) { @@ -267,9 +257,24 @@ export class FileSystemAccess { return url.path(); } + // TODO: This method is the same as in the iOS implementation. + // Make it in a separate file / module so it can be reused from both implementations. private getFileExtension(path: string): string { - var url = Foundation.NSURL.fileURLWithPathIsDirectory(path, false); - return url.pathExtension(); + // TODO [For Panata]: The definitions currently specify "any" as a return value of this method + //var nsString = Foundation.NSString.stringWithString(path); + //var extension = nsString.pathExtension(); + + //if (extension && extension.length > 0) { + // extension = extension.concat(".", extension); + //} + + //return extension; + var dotIndex = path.lastIndexOf("."); + if (dotIndex && dotIndex >= 0 && dotIndex < path.length) { + return path.substring(dotIndex); + } + + return ""; } private deleteEntity(path: string, onSuccess?: () => any, onError?: (error: any) => any) { @@ -284,4 +289,50 @@ export class FileSystemAccess { } } } + + private enumEntities(path: string, callback: (entity: { path: string; name: string; extension: string }) => boolean, onError?: (error) => any) { + try { + var fileManager = Foundation.NSFileManager.defaultManager(); + var files = fileManager.contentsOfDirectoryAtPathError(path, null); + + if (!files) { + if (onError) { + onError(new Error("Failed to enum files for forlder '" + path + "'")); + } + + return; + } + + var fileInfos = new Array<{ path: string; name: string; extension: string }>(); + var file, + i, + info, + retVal; + + + for (i = 0; i < files.count(); i++) { + file = files.objectAtIndex(i); + + info = { + path: this.concatPath(path, file), + name: file + }; + + if (!this.folderExists(file)) { + info.extension = this.getFileExtension(info.path); + } + + retVal = callback(info); + if (retVal != undefined && !retVal) { + // the callback returned false meaning we should stop the iteration + break; + } + } + } + catch (ex) { + if (onError) { + onError(ex); + } + } + } } \ No newline at end of file