-source("./R/Subcollection.R")
-source("./R/ArvadosFile.R")
-source("./R/HttpRequest.R")
-source("./R/HttpParser.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$http <- HttpRequest$new()
- private$httpParser <- HttpParser$new()
-
+ private$REST <- api$getRESTService()
self$uuid <- uuid
- collection <- self$api$getCollection(uuid)
-
- private$fileContent <- private$getCollectionContent()
- private$tree <- CollectionTree$new(private$fileContent, self)
},
add = function(content, relativePath = "")
{
- if(relativePath == "" ||
+ if(is.null(private$tree))
+ private$generateCollectionTreeStructure()
+
+ if(relativePath == "" ||
relativePath == "." ||
relativePath == "./")
{
}
else
{
- if(endsWith(relativePath, "/") && nchar(relativePath) > 0)
- relativePath <- substr(relativePath, 1, nchar(relativePath) - 1)
-
+ relativePath <- trimFromEnd(relativePath, "/")
subcollection <- self$get(relativePath)
}
if("ArvadosFile" %in% class(content) ||
"Subcollection" %in% class(content))
{
- subcollection$add(content)
+ if(!is.null(content$getCollection()))
+ stop("Content already belongs to a collection.")
+
+ if(content$getName() == "")
+ stop("Content has invalid name.")
+ subcollection$add(content)
content
}
else
{
- contentClass <- paste(class(content), collapse = ", ")
- stop(paste("Expected AravodsFile or Subcollection object, got",
- paste0("(", contentClass, ")"), "."))
+ stop(paste0("Expected AravodsFile or Subcollection object, got ",
+ paste0("(", paste0(class(content), collapse = ", "), ")"),
+ "."))
}
},
- create = function(fileNames, relativePath = "")
+ create = function(files)
{
- if(relativePath == "" ||
- relativePath == "." ||
- relativePath == "./")
- {
- subcollection <- private$tree$getTree()
- }
- else
- {
- if(endsWith(relativePath, "/") && nchar(relativePath) > 0)
- relativePath <- substr(relativePath, 1, nchar(relativePath) - 1)
-
- subcollection <- self$get(relativePath)
- }
+ if(is.null(private$tree))
+ private$generateCollectionTreeStructure()
- if(is.null(subcollection))
- stop(paste("Subcollection", relativePath, "doesn't exist."))
-
- 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)
})
- if(length(arvadosFiles) == 1)
- return(arvadosFiles[[1]])
- else
- return(arvadosFiles)
+ "Created"
}
- else
+ else
{
- contentClass <- paste(class(fileNames), collapse = ", ")
- stop(paste("Expected character vector, got",
- paste0("(", contentClass, ")"), "."))
+ stop(paste0("Expected character vector, got ",
+ paste0("(", paste0(class(files), collapse = ", "), ")"),
+ "."))
}
},
- remove = function(content)
+ remove = function(paths)
{
- if(is.character(content))
+ if(is.null(private$tree))
+ private$generateCollectionTreeStructure()
+
+ if(is.character(paths))
{
- sapply(content, function(filePath)
+ sapply(paths, function(filePath)
{
- if(endsWith(filePath, "/") && nchar(filePath) > 0)
- filePath <- substr(filePath, 1, nchar(filePath) - 1)
-
+ filePath <- trimFromEnd(filePath, "/")
file <- self$get(filePath)
if(is.null(file))
stop(paste("File", filePath, "doesn't exist."))
parent <- file$getParent()
- parent$remove(filePath)
+
+ if(is.null(parent))
+ stop("You can't delete root folder.")
+
+ parent$remove(file$getName())
})
+
+ "Content removed"
}
- else if("ArvadosFile" %in% class(content) ||
- "Subcollection" %in% class(content))
+ else
{
- if(is.null(content$getCollection()) ||
- content$getCollection()$uuid != self$uuid)
- stop("Subcollection doesn't belong to this collection.")
-
- content$removeFromCollection()
+ stop(paste0("Expected character vector, got ",
+ paste0("(", paste0(class(paths), collapse = ", "), ")"),
+ "."))
}
},
- move = function(content, newLocation)
+ move = function(content, destination)
{
- if(endsWith(content, "/"))
- content <- substr(content, 0, nchar(content) - 1)
+ if(is.null(private$tree))
+ private$generateCollectionTreeStructure()
+
+ content <- trimFromEnd(content, "/")
elementToMove <- self$get(content)
if(is.null(elementToMove))
- stop("Element you want to move doesn't exist in the collection.")
+ stop("Content you want to move doesn't exist in the collection.")
- elementToMove$move(newLocation)
+ elementToMove$move(destination)
},
- getFileListing = function() private$getCollectionContent(),
-
- get = function(relativePath)
- {
- private$tree$getElement(relativePath)
- },
-
- #Todo: Move these methods to another class.
- createFilesOnREST = function(files)
+ copy = function(content, destination)
{
- sapply(files, function(filePath)
- {
- self$createNewFile(filePath, NULL, "text/html")
- })
- },
+ if(is.null(private$tree))
+ private$generateCollectionTreeStructure()
- createNewFile = function(relativePath, content, contentType)
- {
- fileURL <- paste0(self$api$getWebDavHostName(), "c=", self$uuid, "/", relativePath);
- headers <- list(Authorization = paste("OAuth2", self$api$getToken()),
- "Content-Type" = contentType)
- body <- content
+ content <- trimFromEnd(content, "/")
- serverResponse <- private$http$PUT(fileURL, headers, body)
+ elementToCopy <- self$get(content)
- if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
- stop(paste("Server code:", serverResponse$status_code))
+ if(is.null(elementToCopy))
+ stop("Content you want to copy doesn't exist in the collection.")
- print(paste("File created:", relativePath))
+ elementToCopy$copy(destination)
},
- deleteFromREST = function(relativePath)
+ refresh = function()
{
- fileURL <- paste0(self$api$getWebDavHostName(), "c=", self$uuid, "/", relativePath);
- headers <- list(Authorization = paste("OAuth2", self$api$getToken()))
-
- serverResponse <- private$http$DELETE(fileURL, headers)
-
- if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
- stop(paste("Server code:", serverResponse$status_code))
-
- print(paste("File deleted:", relativePath))
+ if(!is.null(private$tree))
+ {
+ private$tree$getTree()$setCollection(NULL, setRecursively = TRUE)
+ private$tree <- NULL
+ }
},
- moveOnREST = function(from, to)
+ getFileListing = function()
{
- collectionURL <- URLencode(paste0(self$api$getWebDavHostName(), "c=", self$uuid, "/"))
- fromURL <- paste0(collectionURL, from)
- toURL <- paste0(collectionURL, to)
+ if(is.null(private$tree))
+ private$generateCollectionTreeStructure()
- headers = list("Authorization" = paste("OAuth2", self$api$getToken()),
- "Destination" = toURL)
+ content <- private$REST$getCollectionContent(self$uuid)
+ content[order(tolower(content))]
+ },
- serverResponse <- private$http$MOVE(fromURL, headers)
+ get = function(relativePath)
+ {
+ if(is.null(private$tree))
+ private$generateCollectionTreeStructure()
- if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
- stop(paste("Server code:", serverResponse$status_code))
+ private$tree$getElement(relativePath)
+ },
- serverResponse
- }
+ getRESTService = function() private$REST,
+ setRESTService = function(newRESTService) private$REST <- newRESTService
),
private = list(
- http = NULL,
- httpParser = NULL,
- tree = NULL,
-
+ REST = NULL,
+ tree = NULL,
fileContent = NULL,
- getCollectionContent = function()
+ generateCollectionTreeStructure = function()
{
- collectionURL <- URLencode(paste0(self$api$getWebDavHostName(), "c=", self$uuid))
+ if(is.null(self$uuid))
+ stop("Collection uuid is not defined.")
- headers = list("Authorization" = paste("OAuth2", self$api$getToken()))
+ if(is.null(private$REST))
+ stop("REST service is not defined.")
- response <- private$http$PROPFIND(collectionURL, headers)
-
- parsedResponse <- private$httpParser$parseWebDAVResponse(response, collectionURL)
- parsedResponse[-1]
- },
-
- generateTree = function(content)
- {
- treeBranches <- sapply(collectionContent, function(filePath)
- {
- splitPath <- unlist(strsplit(filePath$name, "/", fixed = TRUE))
-
- branch = private$createBranch(splitPath, filePath$fileSize)
- })
+ private$fileContent <- private$REST$getCollectionContent(self$uuid)
+ private$tree <- CollectionTree$new(private$fileContent, self)
}
),
cloneable = FALSE
)
+
+#' 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: ", "\"", x$uuid, "\""), sep = "\n")
+}