1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: Apache-2.0
5 #' R6 Class Representing a Subcollection
8 #' Subcollection class represents a folder inside Arvados collection.
9 #' It is essentially a composite of arvadosFiles and other subcollections.
12 Subcollection <- R6::R6Class(
19 #' Initialize new enviroment.
20 #' @param name Name of the new enviroment.
21 #' @return A new `Subcollection` object.
22 initialize = function(name)
28 #' Returns name of the file.
29 getName = function() private$name,
32 #' Returns Subcollection's path relative to the root.
33 getRelativePath = function()
35 relativePath <- c(private$name)
36 parent <- private$parent
38 while(!is.null(parent))
40 relativePath <- c(parent$getName(), relativePath)
41 parent <- parent$getParent()
44 relativePath <- relativePath[relativePath != ""]
45 paste0(relativePath, collapse = "/")
49 #' Adds ArvadosFile or Subcollection specified by content to the Subcollection.
50 #' @param content Content to be added.
51 add = function(content)
53 if("ArvadosFile" %in% class(content) ||
54 "Subcollection" %in% class(content))
56 if(!is.null(content$getCollection()))
57 stop("Content already belongs to a collection.")
59 if(content$getName() == "")
60 stop("Content has invalid name.")
62 childWithSameName <- self$get(content$getName())
64 if(!is.null(childWithSameName))
65 stop(paste("Subcollection already contains ArvadosFile",
66 "or Subcollection with same name."))
68 if(!is.null(private$collection))
70 if(self$getRelativePath() != "")
71 contentPath <- paste0(self$getRelativePath(),
72 "/", content$getFileListing())
74 contentPath <- content$getFileListing()
76 REST <- private$collection$getRESTService()
77 REST$create(contentPath, private$collection$uuid)
78 content$setCollection(private$collection)
81 private$children <- c(private$children, content)
82 content$setParent(self)
84 "Content added successfully."
88 stop(paste0("Expected AravodsFile or Subcollection object, got ",
89 paste0("(", paste0(class(content), collapse = ", "), ")"),
95 #' Removes ArvadosFile or Subcollection specified by name from the Subcollection.
96 #' @param name Name of the file to be removed.
97 remove = function(name)
99 if(is.character(name))
101 child <- self$get(name)
104 stop(paste("Subcollection doesn't contains ArvadosFile",
105 "or Subcollection with specified name."))
107 if(!is.null(private$collection))
109 REST <- private$collection$getRESTService()
110 REST$delete(child$getRelativePath(), private$collection$uuid)
112 child$setCollection(NULL)
115 private$removeChild(name)
116 child$setParent(NULL)
122 stop(paste0("Expected character, got ",
123 paste0("(", paste0(class(name), collapse = ", "), ")"),
129 #' Returns Subcollections file content as character vector.
130 #' @param fullPath Checking if the path to file exists.
131 getFileListing = function(fullPath = TRUE)
133 content <- private$getContentAsCharVector(fullPath)
134 content[order(tolower(content))]
138 #' Returns subcollections content size in bytes.
139 getSizeInBytes = function()
141 if(is.null(private$collection))
144 REST <- private$collection$getRESTService()
146 fileSizes <- REST$getResourceSize(paste0(self$getRelativePath(), "/"),
147 private$collection$uuid)
148 return(sum(fileSizes))
152 #' Moves Subcollection to a new location inside collection.
153 #' @param destination Path to move the file.
154 move = function(destination)
156 if(is.null(private$collection))
157 stop("Subcollection doesn't belong to any collection.")
159 destination <- trimFromEnd(destination, "/")
160 nameAndPath <- splitToPathAndName(destination)
162 newParent <- private$collection$get(nameAndPath$path)
164 if(is.null(newParent))
165 stop("Unable to get destination subcollection.")
167 childWithSameName <- newParent$get(nameAndPath$name)
169 if(!is.null(childWithSameName))
170 stop("Destination already contains content with same name.")
172 REST <- private$collection$getRESTService()
173 REST$move(self$getRelativePath(),
174 paste0(newParent$getRelativePath(), "/", nameAndPath$name),
175 private$collection$uuid)
177 private$dettachFromCurrentParent()
178 private$attachToNewParent(self, newParent)
180 private$parent <- newParent
181 private$name <- nameAndPath$name
187 #' Copies Subcollection to a new location inside collection.
188 #' @param destination Path to copy the file.
189 copy = function(destination)
191 if(is.null(private$collection))
192 stop("Subcollection doesn't belong to any collection.")
194 destination <- trimFromEnd(destination, "/")
195 nameAndPath <- splitToPathAndName(destination)
197 newParent <- private$collection$get(nameAndPath$path)
199 if(is.null(newParent) || !("Subcollection" %in% class(newParent)))
200 stop("Unable to get destination subcollection.")
202 childWithSameName <- newParent$get(nameAndPath$name)
204 if(!is.null(childWithSameName))
205 stop("Destination already contains content with same name.")
207 REST <- private$collection$getRESTService()
208 REST$copy(self$getRelativePath(),
209 paste0(newParent$getRelativePath(), "/", nameAndPath$name),
210 private$collection$uuid)
212 newContent <- self$duplicate(nameAndPath$name)
213 newContent$setCollection(self$getCollection(), setRecursively = TRUE)
214 newContent$setParent(newParent)
215 private$attachToNewParent(newContent, newParent)
221 #' Duplicate Subcollection and gives it a new name.
222 #' @param newName New name for duplicated file.
223 duplicate = function(newName = NULL)
225 name <- if(!is.null(newName)) newName else private$name
226 root <- Subcollection$new(name)
227 for(child in private$children)
228 root$add(child$duplicate())
234 #' If name is valid, returns ArvadosFile or Subcollection specified by relativePath, else returns NULL.
235 #' @param name Name of the file.
238 for(child in private$children)
240 if(child$getName() == name)
248 #' Returns files in Subcollection.
249 getFirst = function()
251 if(length(private$children) == 0)
254 private$children[[1]]
258 #' Sets Collection by its UUID.
259 setCollection = function(collection, setRecursively = TRUE)
261 private$collection = collection
265 for(child in private$children)
266 child$setCollection(collection)
271 #' Returns Collection of Subcollection.
272 getCollection = function() private$collection,
275 #' Returns Collection UUID.
276 getParent = function() private$parent,
279 #' Sets new Collection.
280 setParent = function(newParent) private$parent <- newParent
290 removeChild = function(name)
292 numberOfChildren = length(private$children)
293 if(numberOfChildren > 0)
295 for(childIndex in 1:numberOfChildren)
297 if(private$children[[childIndex]]$getName() == name)
299 private$children = private$children[-childIndex]
306 attachToNewParent = function(content, newParent)
308 # We temporary set parents collection to NULL. This will ensure that
309 # add method doesn't post this subcollection to REST.
310 # We also need to set content's collection to NULL because
311 # add method throws exception if we try to add content that already
312 # belongs to a collection.
313 parentsCollection <- newParent$getCollection()
314 content$setCollection(NULL, setRecursively = FALSE)
315 newParent$setCollection(NULL, setRecursively = FALSE)
316 newParent$add(content)
317 content$setCollection(parentsCollection, setRecursively = FALSE)
318 newParent$setCollection(parentsCollection, setRecursively = FALSE)
321 dettachFromCurrentParent = function()
323 # We temporary set parents collection to NULL. This will ensure that
324 # remove method doesn't remove this subcollection from REST.
325 parent <- private$parent
326 parentsCollection <- parent$getCollection()
327 parent$setCollection(NULL, setRecursively = FALSE)
328 parent$remove(private$name)
329 parent$setCollection(parentsCollection, setRecursively = FALSE)
332 getContentAsCharVector = function(fullPath = TRUE)
338 for(child in private$children)
339 content <- c(content, child$getFileListing())
341 if(private$name != "")
342 content <- unlist(paste0(private$name, "/", content))
346 for(child in private$children)
347 content <- c(content, child$getName())
357 #' print.Subcollection
359 #' Custom print function for Subcollection class
361 #' @param x Instance of Subcollection class
362 #' @param ... Optional arguments.
364 print.Subcollection = function(x, ...)
367 relativePath <- x$getRelativePath()
369 if(!is.null(x$getCollection()))
371 collection <- x$getCollection()$uuid
373 if(!x$getName() == "")
374 relativePath <- paste0("/", relativePath)
377 cat(paste0("Type: ", "\"", "Arvados Subcollection", "\""), sep = "\n")
378 cat(paste0("Name: ", "\"", x$getName(), "\""), sep = "\n")
379 cat(paste0("Relative path: ", "\"", relativePath, "\""), sep = "\n")
380 cat(paste0("Collection: ", "\"", collection, "\""), sep = "\n")