1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: Apache-2.0
7 #' ArvadosFile class represents a file inside Arvados collection.
10 #' \preformatted{file = ArvadosFile$new(name)}
12 #' @section Arguments:
14 #' \item{name}{Name of the file.}
19 #' \item{getName()}{Returns name of the file.}
20 #' \item{getRelativePath()}{Returns file path relative to the root.}
21 #' \item{read(contentType = "raw", offset = 0, length = 0)}{Read file content.}
22 #' \item{write(content, contentType = "text/html")}{Write to file (override current content of the file).}
23 #' \item{connection(rw)}{Get connection opened in "read" or "write" mode.}
24 #' \item{flush()}{Write connections content to a file (override current content of the file).}
25 #' \item{remove(name)}{Removes ArvadosFile or Subcollection specified by name from the subcollection.}
26 #' \item{getSizeInBytes()}{Returns file size in bytes.}
27 #' \item{move(destination)}{Moves file to a new location inside collection.}
28 #' \item{copy(destination)}{Copies file to a new location inside collection.}
34 #' myFile <- ArvadosFile$new("myFile")
36 #' myFile$write("This is new file content")
37 #' fileContent <- myFile$read()
38 #' fileContent <- myFile$read("text")
39 #' fileContent <- myFile$read("raw", offset = 8, length = 4)
42 #' arvConnection <- myFile$connection("w")
43 #' write.table(mytable, arvConnection)
44 #' arvadosFile$flush()
47 #' arvConnection <- myFile$connection("r")
48 #' mytable <- read.table(arvConnection)
50 #' myFile$move("newFolder/myFile")
51 #' myFile$copy("newFolder/myFile")
56 ArvadosFile <- R6::R6Class(
62 initialize = function(name)
70 getName = function() private$name,
72 getFileListing = function(fullpath = TRUE)
77 getSizeInBytes = function()
79 if(is.null(private$collection))
82 REST <- private$collection$getRESTService()
84 fileSize <- REST$getResourceSize(self$getRelativePath(),
85 private$collection$uuid)
89 get = function(fileLikeObjectName)
99 getCollection = function() private$collection,
101 setCollection = function(collection, setRecursively = TRUE)
103 private$collection <- collection
106 getRelativePath = function()
108 relativePath <- c(private$name)
109 parent <- private$parent
111 while(!is.null(parent))
113 relativePath <- c(parent$getName(), relativePath)
114 parent <- parent$getParent()
117 relativePath <- relativePath[relativePath != ""]
118 paste0(relativePath, collapse = "/")
121 getParent = function() private$parent,
123 setParent = function(newParent) private$parent <- newParent,
125 read = function(contentType = "raw", offset = 0, length = 0)
127 if(is.null(private$collection))
128 stop("ArvadosFile doesn't belong to any collection.")
130 if(offset < 0 || length < 0)
131 stop("Offset and length must be positive values.")
133 REST <- private$collection$getRESTService()
135 fileContent <- REST$read(self$getRelativePath(),
136 private$collection$uuid,
137 contentType, offset, length)
141 connection = function(rw)
143 if (rw == "r" || rw == "rb")
145 REST <- private$collection$getRESTService()
146 return(REST$getConnection(self$getRelativePath(),
147 private$collection$uuid,
152 private$buffer <- textConnection(NULL, "w")
154 return(private$buffer)
160 v <- textConnectionValue(private$buffer)
161 close(private$buffer)
162 self$write(paste(v, collapse='\n'))
165 write = function(content, contentType = "text/html")
167 if(is.null(private$collection))
168 stop("ArvadosFile doesn't belong to any collection.")
170 REST <- private$collection$getRESTService()
172 writeResult <- REST$write(self$getRelativePath(),
173 private$collection$uuid,
174 content, contentType)
178 move = function(destination)
180 if(is.null(private$collection))
181 stop("ArvadosFile doesn't belong to any collection.")
183 destination <- trimFromEnd(destination, "/")
184 nameAndPath <- splitToPathAndName(destination)
186 newParent <- private$collection$get(nameAndPath$path)
188 if(is.null(newParent))
189 stop("Unable to get destination subcollection.")
191 childWithSameName <- newParent$get(nameAndPath$name)
193 if(!is.null(childWithSameName))
194 stop("Destination already contains content with same name.")
196 REST <- private$collection$getRESTService()
197 REST$move(self$getRelativePath(),
198 paste0(newParent$getRelativePath(), "/", nameAndPath$name),
199 private$collection$uuid)
201 private$dettachFromCurrentParent()
202 private$attachToNewParent(self, newParent)
204 private$parent <- newParent
205 private$name <- nameAndPath$name
210 copy = function(destination)
212 if(is.null(private$collection))
213 stop("ArvadosFile doesn't belong to any collection.")
215 destination <- trimFromEnd(destination, "/")
216 nameAndPath <- splitToPathAndName(destination)
218 newParent <- private$collection$get(nameAndPath$path)
220 if(is.null(newParent))
221 stop("Unable to get destination subcollection.")
223 childWithSameName <- newParent$get(nameAndPath$name)
225 if(!is.null(childWithSameName))
226 stop("Destination already contains content with same name.")
228 REST <- private$collection$getRESTService()
229 REST$copy(self$getRelativePath(),
230 paste0(newParent$getRelativePath(), "/", nameAndPath$name),
231 private$collection$uuid)
233 newFile <- self$duplicate(nameAndPath$name)
234 newFile$setCollection(self$getCollection())
235 private$attachToNewParent(newFile, newParent)
236 newFile$setParent(newParent)
241 duplicate = function(newName = NULL)
243 name <- if(!is.null(newName)) newName else private$name
244 newFile <- ArvadosFile$new(name)
257 attachToNewParent = function(content, newParent)
259 # We temporary set parents collection to NULL. This will ensure that
260 # add method doesn't post this file on REST.
261 # We also need to set content's collection to NULL because
262 # add method throws exception if we try to add content that already
263 # belongs to a collection.
264 parentsCollection <- newParent$getCollection()
265 content$setCollection(NULL, setRecursively = FALSE)
266 newParent$setCollection(NULL, setRecursively = FALSE)
267 newParent$add(content)
268 content$setCollection(parentsCollection, setRecursively = FALSE)
269 newParent$setCollection(parentsCollection, setRecursively = FALSE)
272 dettachFromCurrentParent = function()
274 # We temporary set parents collection to NULL. This will ensure that
275 # remove method doesn't remove this file from REST.
276 parent <- private$parent
277 parentsCollection <- parent$getCollection()
278 parent$setCollection(NULL, setRecursively = FALSE)
279 parent$remove(private$name)
280 parent$setCollection(parentsCollection, setRecursively = FALSE)
289 #' Custom print function for ArvadosFile class
291 #' @param x Instance of ArvadosFile class
292 #' @param ... Optional arguments.
294 print.ArvadosFile = function(x, ...)
297 relativePath <- x$getRelativePath()
299 if(!is.null(x$getCollection()))
301 collection <- x$getCollection()$uuid
302 relativePath <- paste0("/", relativePath)
305 cat(paste0("Type: ", "\"", "ArvadosFile", "\""), sep = "\n")
306 cat(paste0("Name: ", "\"", x$getName(), "\""), sep = "\n")
307 cat(paste0("Relative path: ", "\"", relativePath, "\""), sep = "\n")
308 cat(paste0("Collection: ", "\"", collection, "\""), sep = "\n")