18870: Need to declare NODES as array
[arvados.git] / sdk / R / R / Collection.R
index 47d88ac0bc9fd3980f75d6a2b662c36d19495cbe..9ed758c0a474767e67e529afac94aef5c22d2a79 100644 (file)
@@ -1,36 +1,68 @@
-source("./R/Subcollection.R")
-source("./R/ArvadosFile.R")
-source("./R/RESTService.R")
-source("./R/util.R")
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
 
-#' Arvados Collection Object
+#' Collection
 #'
-#' Update description
+#' Collection class provides interface for working with Arvados collections.
 #'
-#' @examples arv = Collection$new(api, uuid)
-#' @export Collection
+#' @section Usage:
+#' \preformatted{collection = Collection$new(arv, uuid)}
+#'
+#' @section Arguments:
+#' \describe{
+#'   \item{arv}{Arvados object.}
+#'   \item{uuid}{UUID of a collection.}
+#' }
+#'
+#' @section Methods:
+#' \describe{
+#'   \item{add(content)}{Adds ArvadosFile or Subcollection specified by content to the collection.}
+#'   \item{create(files)}{Creates one or more ArvadosFiles and adds them to the collection at specified path.}
+#'   \item{remove(fileNames)}{Remove one or more files from the collection.}
+#'   \item{move(content, destination)}{Moves ArvadosFile or Subcollection to another location in the collection.}
+#'   \item{copy(content, destination)}{Copies ArvadosFile or Subcollection to another location in the collection.}
+#'   \item{getFileListing()}{Returns collections file content as character vector.}
+#'   \item{get(relativePath)}{If relativePath is valid, returns ArvadosFile or Subcollection specified by relativePath, else returns NULL.}
+#' }
+#'
+#' @name Collection
+#' @examples
+#' \dontrun{
+#' arv <- Arvados$new("your Arvados token", "example.arvadosapi.com")
+#' collection <- Collection$new(arv, "uuid")
+#'
+#' createdFiles <- collection$create(c("main.cpp", lib.dll), "cpp/src/")
+#'
+#' collection$remove("location/to/my/file.cpp")
+#'
+#' collection$move("folder/file.cpp", "file.cpp")
+#'
+#' arvadosFile <- collection$get("location/to/my/file.cpp")
+#' arvadosSubcollection <- collection$get("location/to/my/directory/")
+#' }
+NULL
+
+#' @export
 Collection <- R6::R6Class(
 
     "Collection",
 
     public = list(
 
-        api  = NULL,
-        uuid = NULL,
+               uuid = NULL,
 
-        initialize = function(api, uuid)
+               initialize = function(api, uuid)
         {
-            self$api <- api
             private$REST <- api$getRESTService()
-
             self$uuid <- uuid
-
-            private$fileContent <- private$REST$getCollectionContent(uuid)
-            private$tree <- CollectionTree$new(private$fileContent, self)
         },
 
         add = function(content, relativePath = "")
         {
+            if(is.null(private$tree))
+                private$generateCollectionTreeStructure()
+
             if(relativePath == ""  ||
                relativePath == "." ||
                relativePath == "./")
@@ -49,6 +81,8 @@ Collection <- R6::R6Class(
             if("ArvadosFile"   %in% class(content) ||
                "Subcollection" %in% class(content))
             {
+                if(!is.null(content$getCollection()))
+                    stop("Content already belongs to a collection.")
 
                 if(content$getName() == "")
                     stop("Content has invalid name.")
@@ -64,53 +98,40 @@ Collection <- R6::R6Class(
             }
         },
 
-        create = function(fileNames, relativePath = "")
+        create = function(files)
         {
-            if(relativePath == ""  ||
-               relativePath == "." ||
-               relativePath == "./")
-            {
-                subcollection <- private$tree$getTree()
-            }
-            else
-            {
-                relativePath  <- trimFromEnd(relativePath, "/") 
-                subcollection <- self$get(relativePath)
-            }
-
-            if(is.null(subcollection))
-                stop(paste("Subcollection", relativePath, "doesn't exist."))
+            if(is.null(private$tree))
+                private$generateCollectionTreeStructure()
 
-            if(is.character(fileNames))
+            if(is.character(files))
             {
-                arvadosFiles <- NULL
-                sapply(fileNames, function(fileName)
+                sapply(files, function(file)
                 {
-                    childWithSameName <- subcollection$get(fileName)
+                    childWithSameName <- self$get(file)
                     if(!is.null(childWithSameName))
                         stop("Destination already contains file with same name.")
 
-                    newFile <- ArvadosFile$new(fileName)
-                    subcollection$add(newFile)
+                    newTreeBranch <- private$tree$createBranch(file)
+                    private$tree$addBranch(private$tree$getTree(), newTreeBranch)
 
-                    arvadosFiles <<- c(arvadosFiles, newFile)
+                    private$REST$create(file, self$uuid)
+                    newTreeBranch$setCollection(self)
+                   newTreeBranch
                 })
-
-                if(length(arvadosFiles) == 1)
-                    return(arvadosFiles[[1]])
-                else
-                    return(arvadosFiles)
             }
-            else 
+            else
             {
                 stop(paste0("Expected character vector, got ",
-                            paste0("(", paste0(class(fileNames), collapse = ", "), ")"),
+                            paste0("(", paste0(class(files), collapse = ", "), ")"),
                             "."))
             }
         },
 
         remove = function(paths)
         {
+            if(is.null(private$tree))
+                private$generateCollectionTreeStructure()
+
             if(is.character(paths))
             {
                 sapply(paths, function(filePath)
@@ -131,7 +152,7 @@ Collection <- R6::R6Class(
 
                 "Content removed"
             }
-            else 
+            else
             {
                 stop(paste0("Expected character vector, got ",
                             paste0("(", paste0(class(paths), collapse = ", "), ")"),
@@ -139,8 +160,11 @@ Collection <- R6::R6Class(
             }
         },
 
-        move = function(content, newLocation)
+        move = function(content, destination)
         {
+            if(is.null(private$tree))
+                private$generateCollectionTreeStructure()
+
             content <- trimFromEnd(content, "/")
 
             elementToMove <- self$get(content)
@@ -148,17 +172,47 @@ Collection <- R6::R6Class(
             if(is.null(elementToMove))
                 stop("Content you want to move doesn't exist in the collection.")
 
-            elementToMove$move(newLocation)
+            elementToMove$move(destination)
+        },
+
+        copy = function(content, destination)
+        {
+            if(is.null(private$tree))
+                private$generateCollectionTreeStructure()
+
+            content <- trimFromEnd(content, "/")
+
+            elementToCopy <- self$get(content)
+
+            if(is.null(elementToCopy))
+                stop("Content you want to copy doesn't exist in the collection.")
+
+            elementToCopy$copy(destination)
+        },
+
+        refresh = function()
+        {
+            if(!is.null(private$tree))
+            {
+                private$tree$getTree()$setCollection(NULL, setRecursively = TRUE)
+                private$tree <- NULL
+            }
         },
 
         getFileListing = function()
         {
+            if(is.null(private$tree))
+                private$generateCollectionTreeStructure()
+
             content <- private$REST$getCollectionContent(self$uuid)
             content[order(tolower(content))]
         },
 
         get = function(relativePath)
         {
+            if(is.null(private$tree))
+                private$generateCollectionTreeStructure()
+
             private$tree$getElement(relativePath)
         },
 
@@ -170,15 +224,33 @@ Collection <- R6::R6Class(
 
         REST        = NULL,
         tree        = NULL,
-        fileContent = NULL
+        fileContent = NULL,
+
+        generateCollectionTreeStructure = function()
+        {
+            if(is.null(self$uuid))
+                stop("Collection uuid is not defined.")
+
+            if(is.null(private$REST))
+                stop("REST service is not defined.")
+
+            private$fileContent <- private$REST$getCollectionContent(self$uuid)
+            private$tree <- CollectionTree$new(private$fileContent, self)
+        }
     ),
 
     cloneable = FALSE
 )
 
-#' @export print.Collection
-print.Collection = function(collection)
+#' print.Collection
+#'
+#' Custom print function for Collection class
+#'
+#' @param x Instance of Collection class
+#' @param ... Optional arguments.
+#' @export
+print.Collection = function(x, ...)
 {
     cat(paste0("Type: ", "\"", "Arvados Collection", "\""), sep = "\n")
-    cat(paste0("uuid: ", "\"", collection$uuid,      "\""), sep = "\n")
+    cat(paste0("uuid: ", "\"", x$uuid,               "\""), sep = "\n")
 }