18874: Merge commit '6f8dcb2b13f3058db656908fb26b09e23b527f08' into 18874-merge-wb2
[arvados.git] / sdk / R / R / ArvadosFile.R
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: Apache-2.0
4
5 #' R6 Class Representing a ArvadosFile
6 #'
7 #' @description
8 #' ArvadosFile class represents a file inside Arvados collection.
9
10 #' @export
11 ArvadosFile <- R6::R6Class(
12
13     "ArvadosFile",
14
15     public = list(
16
17         #' @description
18         #' Initialize new enviroment.
19         #' @param name Name of the new enviroment.
20         #' @return A new `ArvadosFile` object.
21         #' @examples
22         #' \dontrun{
23         #' myFile   <- ArvadosFile$new("myFile")
24         #' }
25         initialize = function(name)
26         {
27             if(name == "")
28                 stop("Invalid name.")
29
30             private$name <- name
31         },
32
33         #' @description
34         #' Returns name of the file.
35         #' @examples
36         #' \dontrun{
37         #' arvadosFile$getName()
38         #' }
39         getName = function() private$name,
40
41         #' @description
42         #' Returns collections file content as character vector.
43         #' @param fullPath Checking if TRUE.
44         #' @examples
45         #' \dontrun{
46         #' arvadosFile$getFileListing()
47         #' }
48         getFileListing = function(fullpath = TRUE)
49         {
50             self$getName()
51         },
52
53         #' @description
54         #' Returns collections content size in bytes.
55         #' @examples
56         #' \dontrun{
57         #' arvadosFile$getSizeInBytes()
58         #' }
59         getSizeInBytes = function()
60         {
61             if(is.null(private$collection))
62                 return(0)
63
64             REST <- private$collection$getRESTService()
65
66             fileSize <- REST$getResourceSize(self$getRelativePath(),
67                                              private$collection$uuid)
68             fileSize
69         },
70
71         get = function(fileLikeObjectName)
72         {
73             return(NULL)
74         },
75
76         getFirst = function()
77         {
78             return(NULL)
79         },
80
81         #' @description
82         #' Returns collection UUID.
83         getCollection = function() private$collection,
84
85         #' @description
86         #' Sets new collection.
87         setCollection = function(collection, setRecursively = TRUE)
88         {
89             private$collection <- collection
90         },
91
92         #' @description
93         #' Returns file path relative to the root.
94         getRelativePath = function()
95         {
96             relativePath <- c(private$name)
97             parent <- private$parent
98
99             while(!is.null(parent))
100             {
101                 relativePath <- c(parent$getName(), relativePath)
102                 parent <- parent$getParent()
103             }
104
105             relativePath <- relativePath[relativePath != ""]
106             paste0(relativePath, collapse = "/")
107         },
108
109         #' @description
110         #' Returns project UUID.
111         getParent = function() private$parent,
112
113         #' @description
114         #' Sets project collection.
115         setParent = function(newParent) private$parent <- newParent,
116
117         #' @description
118         #' Read file content.
119         #' @param contentType Type of content. Possible is "text", "raw".
120         #' @param offset Describes the location of a piece of data compared to another location
121         #' @param length Length of content
122         #' @examples
123         #' \dontrun{
124         #' collection <- Collection$new(arv, collectionUUID)
125         #' arvadosFile <- collection$get(fileName)
126         #' fileContent <- arvadosFile$read("text")
127         #' }
128         read = function(contentType = "raw", offset = 0, length = 0)
129         {
130             if(is.null(private$collection))
131                 stop("ArvadosFile doesn't belong to any collection.")
132
133             if(offset < 0 || length < 0)
134                 stop("Offset and length must be positive values.")
135
136             REST <- private$collection$getRESTService()
137
138             fileContent <- REST$read(self$getRelativePath(),
139                                      private$collection$uuid,
140                                      contentType, offset, length)
141             fileContent
142         },
143
144         #' @description
145         #' Get connection opened in "read" or "write" mode.
146         #' @param rw Type of connection.
147         #' @examples
148         #' \dontrun{
149         #' collection <- Collection$new(arv, collectionUUID)
150         #' arvadosFile <- collection$get(fileName)
151         #' arvConnection <- arvadosFile$connection("w")
152         #' }
153         connection = function(rw)
154         {
155             if (rw == "r" || rw == "rb")
156             {
157                 REST <- private$collection$getRESTService()
158                 return(REST$getConnection(self$getRelativePath(),
159                                           private$collection$uuid,
160                                           rw))
161             }
162             else if (rw == "w")
163             {
164                 private$buffer <- textConnection(NULL, "w")
165
166                 return(private$buffer)
167             }
168         },
169
170         #' @description
171         #' Write connections content to a file or override current content of the file.
172         #' @examples
173         #' \dontrun{
174         #' collection <- Collection$new(arv, collectionUUID)
175         #' arvadosFile <- collection$get(fileName)
176         #' myFile$write("This is new file content")
177         #' arvadosFile$flush()
178         #' }
179         flush = function()
180         {
181             v <- textConnectionValue(private$buffer)
182             close(private$buffer)
183             self$write(paste(v, collapse='\n'))
184         },
185
186         #' @description
187         #' Write to file or override current content of the file.
188         #' @param content File to write.
189         #' @param contentType Type of content. Possible is "text", "raw".
190         #' @examples
191         #' \dontrun{
192         #' collection <- Collection$new(arv, collectionUUID)
193         #' arvadosFile <- collection$get(fileName)
194         #' myFile$write("This is new file content")
195         #' }
196         write = function(content, contentType = "text/html")
197         {
198             if(is.null(private$collection))
199                 stop("ArvadosFile doesn't belong to any collection.")
200
201             REST <- private$collection$getRESTService()
202
203             writeResult <- REST$write(self$getRelativePath(),
204                                       private$collection$uuid,
205                                       content, contentType)
206             writeResult
207         },
208
209         #' @description
210         #' Moves file to a new location inside collection.
211         #' @param destination Path to new folder.
212         #' @examples
213         #' \dontrun{
214         #' arvadosFile$move(newPath)
215         #' }
216         move = function(destination)
217         {
218             if(is.null(private$collection))
219                 stop("ArvadosFile doesn't belong to any collection.")
220
221             destination <- trimFromEnd(destination, "/")
222             nameAndPath <- splitToPathAndName(destination)
223
224             newParent <- private$collection$get(nameAndPath$path)
225
226             if(is.null(newParent))
227                 stop("Unable to get destination subcollection.")
228
229             childWithSameName <- newParent$get(nameAndPath$name)
230
231             if(!is.null(childWithSameName))
232                 stop("Destination already contains content with same name.")
233
234             REST <- private$collection$getRESTService()
235             REST$move(self$getRelativePath(),
236                       paste0(newParent$getRelativePath(), "/", nameAndPath$name),
237                       private$collection$uuid)
238
239             private$dettachFromCurrentParent()
240             private$attachToNewParent(self, newParent)
241
242             private$parent <- newParent
243             private$name <- nameAndPath$name
244
245             self
246         },
247
248         #' @description
249         #' Copies file to a new location inside collection.
250         #' @param destination Path to new folder.
251         #' @examples
252         #' \dontrun{
253         #' arvadosFile$copy("NewName.format")
254         #' }
255         copy = function(destination)
256         {
257             if(is.null(private$collection))
258                 stop("ArvadosFile doesn't belong to any collection.")
259
260             destination <- trimFromEnd(destination, "/")
261             nameAndPath <- splitToPathAndName(destination)
262
263             newParent <- private$collection$get(nameAndPath$path)
264
265             if(is.null(newParent))
266                 stop("Unable to get destination subcollection.")
267
268             childWithSameName <- newParent$get(nameAndPath$name)
269
270             if(!is.null(childWithSameName))
271                 stop("Destination already contains content with same name.")
272
273             REST <- private$collection$getRESTService()
274             REST$copy(self$getRelativePath(),
275                       paste0(newParent$getRelativePath(), "/", nameAndPath$name),
276                       private$collection$uuid)
277
278             newFile <- self$duplicate(nameAndPath$name)
279             newFile$setCollection(self$getCollection())
280             private$attachToNewParent(newFile, newParent)
281             newFile$setParent(newParent)
282
283             newFile
284         },
285
286         #' @description
287         #' Duplicate file and gives it a new name.
288         #' @param newName New name for duplicated file.
289         duplicate = function(newName = NULL)
290         {
291             name <- if(!is.null(newName)) newName else private$name
292             newFile <- ArvadosFile$new(name)
293             newFile
294         }
295     ),
296
297     private = list(
298
299         name       = NULL,
300         size       = NULL,
301         parent     = NULL,
302         collection = NULL,
303         buffer     = NULL,
304
305         attachToNewParent = function(content, newParent)
306         {
307             # We temporary set parents collection to NULL. This will ensure that
308             # add method doesn't post this file on REST.
309             # We also need to set content's collection to NULL because
310             # add method throws exception if we try to add content that already
311             # belongs to a collection.
312
313             parentsCollection <- newParent$getCollection()
314             #parent$.__enclos_env__$private$children <- c(parent$.__enclos_env__$private$children, self)
315             #private$parent <- parent
316             content$setCollection(NULL, setRecursively = FALSE)
317             newParent$setCollection(NULL, setRecursively = FALSE)
318             newParent$add(content)
319             content$setCollection(parentsCollection, setRecursively = FALSE)
320             newParent$setCollection(parentsCollection, setRecursively = FALSE)
321         },
322
323         dettachFromCurrentParent = function()
324         {
325             # We temporary set parents collection to NULL. This will ensure that
326             # remove method doesn't remove this file from REST.
327
328             #private$parent$.__enclos_env__$private$removeChild(private$name)
329             #private$parent <- NULL
330             parent <- private$parent
331             parentsCollection <- parent$getCollection()
332             parent$setCollection(NULL, setRecursively = FALSE)
333             parent$remove(private$name)
334             parent$setCollection(parentsCollection, setRecursively = FALSE)
335         }
336     ),
337
338     cloneable = FALSE
339 )
340
341 #' print.ArvadosFile
342 #'
343 #' Custom print function for ArvadosFile class
344 #'
345 #' @param x Instance of ArvadosFile class
346 #' @param ... Optional arguments.
347 #' @export
348 print.ArvadosFile = function(x, ...)
349 {
350     collection   <- NULL
351     relativePath <- x$getRelativePath()
352
353     if(!is.null(x$getCollection()))
354     {
355         collection <- x$getCollection()$uuid
356         relativePath <- paste0("/", relativePath)
357     }
358
359     cat(paste0("Type:          ", "\"", "ArvadosFile", "\""), sep = "\n")
360     cat(paste0("Name:          ", "\"", x$getName(),   "\""), sep = "\n")
361     cat(paste0("Relative path: ", "\"", relativePath,  "\""), sep = "\n")
362     cat(paste0("Collection:    ", "\"", collection,    "\""), sep = "\n")
363 }