Made Subcollection and ArvadosFile more flexible.
[arvados.git] / sdk / R / R / Collection.R
index 49a1e81d0767c7b33513a290ecad208f0a7fd216..94141d97f4437d4e5f095a193853fe10d770a283 100644 (file)
@@ -1,6 +1,5 @@
 source("./R/Subcollection.R")
 source("./R/ArvadosFile.R")
-source("./R/FileTree.R")
 source("./R/HttpRequest.R")
 source("./R/HttpParser.R")
 
@@ -9,225 +8,162 @@ source("./R/HttpParser.R")
 #' Update description
 #'
 #' @examples arv = Collection$new(api, uuid)
-#' @export Collection
-Collection <- R6::R6Class(
-
-    "Collection",
-
+#' @export CTest
+CTest <- R6::R6Class(
+    "CTest",
     public = list(
 
-        #Todo(Fudo): Encapsulate this?
-        uuid                     = NULL,
-        etag                     = NULL,
-        owner_uuid               = NULL,
-        created_at               = NULL,
-        modified_by_client_uuid  = NULL,
-        modified_by_user_uuid    = NULL,
-        modified_at              = NULL,
-        portable_data_hash       = NULL,
-        replication_desired      = NULL,
-        replication_confirmed_at = NULL,
-        replication_confirmed    = NULL,
-        updated_at               = NULL,
-        manifest_text            = NULL,
-        name                     = NULL,
-        description              = NULL,
-        properties               = NULL,
-        delete_at                = NULL,
-        file_names               = NULL,
-        trash_at                 = NULL,
-        is_trashed               = NULL,
+        api  = NULL,
+        uuid = NULL,
 
         initialize = function(api, uuid)
         {
-            private$api <- api
-            result <- private$api$getCollection(uuid)
-
-            self$uuid                     <- result$uuid                               
-            self$etag                     <- result$etag                               
-            self$owner_uuid               <- result$owner_uuid                         
-            self$created_at               <- result$created_at                         
-            self$modified_by_client_uuid  <- result$modified_by_client_uuid            
-            self$modified_by_user_uuid    <- result$modified_by_user_uuid              
-            self$modified_at              <- result$modified_at                        
-            self$portable_data_hash       <- result$portable_data_hash                 
-            self$replication_desired      <- result$replication_desired                
-            self$replication_confirmed_at <- result$replication_confirmed_at           
-            self$replication_confirmed    <- result$replication_confirmed              
-            self$updated_at               <- result$updated_at                         
-            self$manifest_text            <- result$manifest_text                      
-            self$name                     <- result$name                               
-            self$description              <- result$description                        
-            self$properties               <- result$properties                         
-            self$delete_at                <- result$delete_at                          
-            self$file_names               <- result$file_names                         
-            self$trash_at                 <- result$trash_at                           
-            self$is_trashed               <- result$is_trashed                         
-
+            self$api <- api
             private$http <- HttpRequest$new()
             private$httpParser <- HttpParser$new()
 
-            private$fileItems <- private$getCollectionContent()
-            private$fileTree <- FileTree$new(private$fileItems)
-
-        },
+            self$uuid <- uuid
+            collection <- self$api$getCollection(uuid)
 
-        printFileContent = function()
-        {
-            private$fileTree$printContent(private$fileTree$getRoot(), 0)
+            private$fileContent <- private$getCollectionContent()
+            private$tree <- CollectionTree$new(private$fileContent, self)
         },
 
-        getFileContent = function()
+        add = function(content, relativePath = "")
         {
-            sapply(private$fileItems, function(file)
+            if(relativePath == "" ||
+               relativePath == "." ||
+               relativePath == "./")
             {
-                file$name
-            })
-        },
-
-        get = function(relativePath)
-        {
-            treeNode <- private$fileTree$traverseInOrder(private$fileTree$getRoot(), function(node)
+                subcollection <- private$tree$.__enclos_env__$private$tree
+            }
+            else
             {
-                if(node$relativePath == relativePath)
-                    return(node)
-                else
-                    return(NULL)
-            })
+                if(endsWith(relativePath, "/") && nchar(relativePath) > 0)
+                    relativePath <- substr(relativePath, 1, nchar(relativePath) - 1)
+
+                subcollection <- self$get(relativePath)
+            }
+
+            if(is.null(subcollection))
+                stop(paste("Subcollection", relativePath, "doesn't exist."))
 
-            if(!is.null(treeNode))
+            if(is.character(content))
             {
-                return(private$createSubcollectionTree(treeNode))
+                sapply(content, function(fileName)
+                {
+                    subcollection$add(ArvadosFile$new(fileName))
+                })
             }
-            else
+            else if("ArvadosFile"   %in% class(content) ||
+                    "Subcollection" %in% class(content))
             {
-                return(NULL)
+                subcollection$add(content)
             }
         },
 
-        createNewFile = function(relativePath, content, contentType)
+        remove = function(content)
         {
-            fileURL <- paste0(private$api$getWebDavHostName(), "c=", self$uuid, "/", relativePath);
-            headers <- list(Authorization = paste("OAuth2", private$api$getToken()), 
-                            "Content-Type" = contentType)
-            body <- content
+            if(is.character(content))
+            {
+                sapply(content, function(filePath)
+                {
+                    if(endsWith(filePath, "/") && nchar(filePath) > 0)
+                        filePath <- substr(filePath, 1, nchar(filePath) - 1)
 
-            serverResponse <- private$http$PUT(fileURL, headers, body)
+                    file <- self$get(filePath)
 
-            if(serverResponse$status_code != 201)
-                stop(paste("Server code:", serverResponse$status_code))
+                    if(is.null(file))
+                        stop(paste("File", filePath, "doesn't exist."))
 
-            fileSize = private$getNewFileSize(relativePath)
-            private$fileTree$addNode(relativePath, fileSize)
+                    file$removeFromCollection()
+                })
+            }
+            else if("ArvadosFile"   %in% class(content) ||
+                    "Subcollection" %in% class(content))
+            {
+                if(is.null(content$.__enclos_env__$private$collection) || 
+                   content$.__enclos_env__$private$collection$uuid != self$uuid)
+                    stop("Subcollection doesn't belong to this collection.")
 
-            paste0("File created (size = ", fileSize , ")")
+                content$removeFromCollection()
+            }
         },
 
-        removeFile = function(relativePath)
-        {
-            node <- private$fileTree$getNode(relativePath)
-
-            if(is.null(node))
-                stop("File doesn't exists.")
-
-            fileURL <- paste0(private$api$getWebDavHostName(), "c=", self$uuid, "/", relativePath);
-            headers <- list(Authorization = paste("OAuth2", private$api$getToken())) 
-
-            serverResponse <- private$http$DELETE(fileURL, headers)
+        getTree = function() private$tree,
 
-            if(serverResponse$status_code != 204)
-                stop(paste("Server code:", serverResponse$status_code))
-
-            "File deleted"
-        },
+        getFileContent = function() private$getCollectionContent(),
 
-        update = function(subcollection, event)
+        get = function(relativePath)
         {
-            #Todo(Fudo): Add some king of check here later on.
-            if(event == "File size changed")
-            {
-                private$handleFileSizeChange(subcollection$getRelativePath(),
-                                             subcollection$getSizeInBytes())
-            }
+            private$tree$getElement(relativePath)
         }
     ),
 
-    active = list(
-        items = function(value)
-        {
-            if(missing(value))
-                return(private$fileItems)
-            else
-                print("Value is read-only.")
-
-            return(NULL)
-        }
-    ),
-    
     private = list(
 
-        fileItems  = NULL,
-        api        = NULL,
-        fileTree   = NULL,
         http       = NULL,
         httpParser = NULL,
+        tree       = NULL,
 
-        handleFileSizeChange = function(filePath, newSize)
+        fileContent = NULL,
+
+        getCollectionContent = function()
         {
-            node <- private$fileTree$getNode(filePath)
+            collectionURL <- URLencode(paste0(self$api$getWebDavHostName(), "c=", self$uuid))
 
-            if(is.null(node))
-                stop("File doesn't exits")
+            headers = list("Authorization" = paste("OAuth2", self$api$getToken()))
 
-            node$size <- newSize
+            response <- private$http$PROPFIND(collectionURL, headers)
+
+            parsedResponse <- private$httpParser$parseWebDAVResponse(response, collectionURL)
+            parsedResponse[-1]
         },
 
-        createSubcollectionTree = function(treeNode)
+        createFilesOnREST = function(files)
         {
-            if(treeNode$hasChildren())
+            sapply(files, function(filePath)
             {
-                children = NULL
-
-                for(child in treeNode$children)
-                {
-                    child <- private$createSubcollectionTree(child)
-                    children <- c(children, child)                   
-                }
-
-                return(Subcollection$new(treeNode$name, treeNode$relativePath, children))
-            }
-            else
+                private$createNewFile(filePath, NULL, "text/html")
+            })
+        },
+        
+        generateTree = function(content)
+        {
+            treeBranches <- sapply(collectionContent, function(filePath)
             {
-                if(treeNode$type == "file")
-                    return(ArvadosFile$new(treeNode$name, treeNode$relativePath, treeNode$size, private$api, self))
-                else 
-                    return(Subcollection$new(treeNode$name, treeNode$relativePath, NULL))
-            }
+                splitPath <- unlist(strsplit(filePath$name, "/", fixed = TRUE))
+
+                branch = private$createBranch(splitPath, filePath$fileSize)      
+            })
         },
 
-        getCollectionContent = function()
+        createNewFile = function(relativePath, content, contentType)
         {
-            collectionURL <- URLencode(paste0(private$api$getWebDavHostName(), "c=", self$uuid))
+            fileURL <- paste0(self$api$getWebDavHostName(), "c=", self$uuid, "/", relativePath);
+            headers <- list(Authorization = paste("OAuth2", self$api$getToken()), 
+                            "Content-Type" = contentType)
+            body <- content
 
-            headers = list("Authorization" = paste("OAuth2", private$api$getToken()))
+            serverResponse <- private$http$PUT(fileURL, headers, body)
 
-            response <- private$http$PROPFIND(collectionURL, headers)
+            if(serverResponse$status_code != 201)
+                stop(paste("Server code:", serverResponse$status_code))
 
-            parsedResponse <- private$httpParser$parseWebDAVResponse(response, collectionURL)
-            parsedResponse[-1]
+            print(paste("File created:", relativePath))
         },
-
-        getNewFileSize = function(relativePath)
+        
+        deleteFromREST = function(relativePath)
         {
-            collectionURL <- URLencode(paste0(private$api$getWebDavHostName(), "c=", self$uuid))
-            fileURL = paste0(collectionURL, "/", relativePath);
-            headers = list("Authorization" = paste("OAuth2", private$api$getToken()))
+            fileURL <- paste0(self$api$getWebDavHostName(), "c=", self$uuid, "/", relativePath);
+            headers <- list(Authorization = paste("OAuth2", self$api$getToken())) 
 
-            propfindResponse <- private$http$PROPFIND(fileURL, headers)
+            serverResponse <- private$http$DELETE(fileURL, headers)
 
-            fileInfo <- private$httpParser$parseWebDAVResponse(propfindResponse, collectionURL)
+            if(serverResponse$status_code != 204)
+                stop(paste("Server code:", serverResponse$status_code))
 
-            fileInfo[[1]]$fileSize
+            print(paste("File deleted", relativePath))
         }
     ),