1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: Apache-2.0
9 #' Subcollection class represents a folder inside Arvados collection.
10 #' It is essentially a composite of arvadosFiles and other subcollections.
13 #' \preformatted{subcollection = Subcollection$new(name)}
15 #' @section Arguments:
17 #' \item{name}{Name of the subcollection.}
22 #' \item{getName()}{Returns name of the subcollection.}
23 #' \item{getRelativePath()}{Returns subcollection path relative to the root.}
24 #' \item{add(content)}{Adds ArvadosFile or Subcollection specified by content to the subcollection.}
25 #' \item{remove(name)}{Removes ArvadosFile or Subcollection specified by name from the subcollection.}
26 #' \item{get(relativePath)}{If relativePath is valid, returns ArvadosFile or Subcollection specified by relativePath, else returns NULL.}
27 #' \item{getFileListing()}{Returns subcollections file content as character vector.}
28 #' \item{getSizeInBytes()}{Returns subcollections content size in bytes.}
29 #' \item{move(newLocation)}{Moves subcollection to a new location inside collection.}
32 #' @name Subcollection
35 #' myFolder <- Subcollection$new("myFolder")
36 #' myFile <- ArvadosFile$new("myFile")
38 #' myFolder$add(myFile)
39 #' myFolder$get("myFile")
40 #' myFolder$remove("myFile")
42 #' myFolder$move("newLocation/myFolder")
47 Subcollection <- R6::R6Class(
53 initialize = function(name)
58 getName = function() private$name,
60 getRelativePath = function()
62 relativePath <- c(private$name)
63 parent <- private$parent
65 while(!is.null(parent))
67 relativePath <- c(parent$getName(), relativePath)
68 parent <- parent$getParent()
71 relativePath <- relativePath[relativePath != ""]
72 paste0(relativePath, collapse = "/")
75 add = function(content)
77 if("ArvadosFile" %in% class(content) ||
78 "Subcollection" %in% class(content))
80 if(content$getName() == "")
81 stop("Content has invalid name.")
83 childWithSameName <- self$get(content$getName())
85 if(!is.null(childWithSameName))
86 stop(paste("Subcollection already contains ArvadosFile",
87 "or Subcollection with same name."))
89 if(!is.null(private$collection))
91 if(self$getRelativePath() != "")
92 contentPath <- paste0(self$getRelativePath(),
93 "/", content$getFileListing())
95 contentPath <- content$getFileListing()
97 REST <- private$collection$getRESTService()
98 REST$create(contentPath, private$collection$uuid)
99 content$setCollection(private$collection)
102 private$children <- c(private$children, content)
103 content$setParent(self)
105 "Content added successfully."
109 stop(paste0("Expected AravodsFile or Subcollection object, got ",
110 paste0("(", paste0(class(content), collapse = ", "), ")"),
115 remove = function(name)
117 if(is.character(name))
119 child <- self$get(name)
122 stop(paste("Subcollection doesn't contains ArvadosFile",
123 "or Subcollection with specified name."))
125 if(!is.null(private$collection))
127 REST <- private$collection$getRESTService()
128 REST$delete(child$getRelativePath(), private$collection$uuid)
130 child$setCollection(NULL)
133 private$removeChild(name)
134 child$setParent(NULL)
140 stop(paste0("Expected character, got ",
141 paste0("(", paste0(class(name), collapse = ", "), ")"),
146 getFileListing = function(fullPath = TRUE)
148 content <- private$getContentAsCharVector(fullPath)
149 content[order(tolower(content))]
152 getSizeInBytes = function()
154 if(is.null(private$collection))
157 REST <- private$collection$getRESTService()
159 fileSizes <- REST$getResourceSize(paste0(self$getRelativePath(), "/"),
160 private$collection$uuid)
161 return(sum(fileSizes))
164 move = function(newLocation)
166 if(is.null(private$collection))
167 stop("Subcollection doesn't belong to any collection")
169 newLocation <- trimFromEnd(newLocation, "/")
170 nameAndPath <- splitToPathAndName(newLocation)
172 newParent <- private$collection$get(nameAndPath$path)
174 if(is.null(newParent))
176 stop("Unable to get destination subcollection")
179 childWithSameName <- newParent$get(nameAndPath$name)
181 if(!is.null(childWithSameName))
182 stop("Destination already contains content with same name.")
184 REST <- private$collection$getRESTService()
185 REST$move(self$getRelativePath(),
186 paste0(newParent$getRelativePath(), "/", nameAndPath$name),
187 private$collection$uuid)
189 private$dettachFromCurrentParent()
190 private$attachToNewParent(newParent)
192 private$name <- nameAndPath$name
194 "Content moved successfully."
199 for(child in private$children)
201 if(child$getName() == name)
208 getFirst = function()
210 if(length(private$children) == 0)
213 private$children[[1]]
216 setCollection = function(collection, setRecursively = TRUE)
218 private$collection = collection
222 for(child in private$children)
223 child$setCollection(collection)
227 getCollection = function() private$collection,
229 getParent = function() private$parent,
231 setParent = function(newParent) private$parent <- newParent
241 removeChild = function(name)
243 numberOfChildren = length(private$children)
244 if(numberOfChildren > 0)
246 for(childIndex in 1:numberOfChildren)
248 if(private$children[[childIndex]]$getName() == name)
250 private$children = private$children[-childIndex]
257 attachToNewParent = function(newParent)
259 #Note: We temporary set parents collection to NULL. This will ensure that
260 # add method doesn't post file on REST.
261 parentsCollection <- newParent$getCollection()
262 newParent$setCollection(NULL, setRecursively = FALSE)
266 newParent$setCollection(parentsCollection, setRecursively = FALSE)
268 private$parent <- newParent
271 dettachFromCurrentParent = function()
273 #Note: We temporary set parents collection to NULL. This will ensure that
274 # remove method doesn't remove this subcollection from REST.
275 parent <- private$parent
276 parentsCollection <- parent$getCollection()
277 parent$setCollection(NULL, setRecursively = FALSE)
279 parent$remove(private$name)
281 parent$setCollection(parentsCollection, setRecursively = FALSE)
284 getContentAsCharVector = function(fullPath = TRUE)
290 for(child in private$children)
291 content <- c(content, child$getFileListing())
293 if(private$name != "")
294 content <- unlist(paste0(private$name, "/", content))
298 for(child in private$children)
299 content <- c(content, child$getName())
309 #' print.Subcollection
311 #' Custom print function for Subcollection class
313 #' @param x Instance of Subcollection class
314 #' @param ... Optional arguments.
316 print.Subcollection = function(x, ...)
319 relativePath <- x$getRelativePath()
321 if(!is.null(x$getCollection()))
323 collection <- x$getCollection()$uuid
325 if(!x$getName() == "")
326 relativePath <- paste0("/", relativePath)
329 cat(paste0("Type: ", "\"", "Arvados Subcollection", "\""), sep = "\n")
330 cat(paste0("Name: ", "\"", x$getName(), "\""), sep = "\n")
331 cat(paste0("Relative path: ", "\"", relativePath, "\""), sep = "\n")
332 cat(paste0("Collection: ", "\"", collection, "\""), sep = "\n")