2411: add copyright headers to our R files.
[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 source("./R/util.R")
6
7 #' ArvadosFile
8 #' 
9 #' ArvadosFile class represents a file inside Arvados collection.
10 #' 
11 #' @section Usage:
12 #' \preformatted{file = ArvadosFile$new(name)}
13 #'
14 #' @section Arguments:
15 #' \describe{
16 #'   \item{name}{Name of the file.}
17 #' }
18 #' 
19 #' @section Methods:
20 #' \describe{
21 #'   \item{getName()}{Returns name of the file.}
22 #'   \item{getRelativePath()}{Returns file path relative to the root.}
23 #'   \item{read(contentType = "raw", offset = 0, length = 0)}{Read file content.}
24 #'   \item{write(content, contentType = "text/html")}{Write to file (override current content of the file).}
25 #'   \item{connection(rw)}{Get connection opened in "read" or "write" mode.}
26 #'   \item{flush()}{Write connections content to a file (override current content of the file).}
27 #'   \item{remove(name)}{Removes ArvadosFile or Subcollection specified by name from the subcollection.}
28 #'   \item{getSizeInBytes()}{Returns file size in bytes.}
29 #'   \item{move(newLocation)}{Moves file to a new location inside collection.}
30 #' }
31 #'
32 #' @name ArvadosFile
33 #' @examples
34 #' \dontrun{
35 #' myFile <- ArvadosFile$new("myFile")
36 #'
37 #' myFile$write("This is new file content")
38 #' fileContent <- myFile$read()
39 #' fileContent <- myFile$read("text")
40 #' fileContent <- myFile$read("raw", offset = 8, length = 4) 
41 #'
42 #' #Write a table:
43 #' arvConnection <- myFile$connection("w")
44 #' write.table(mytable, arvConnection)
45 #' arvadosFile$flush()
46 #'
47 #' #Read a table:
48 #' arvConnection <- myFile$connection("r")
49 #' mytable <- read.table(arvConnection)
50 #'
51 #' myFile$move("newFolder/myFile")
52 #' }
53 NULL
54
55 #' @export
56 ArvadosFile <- R6::R6Class(
57
58     "ArvadosFile",
59
60     public = list(
61
62         initialize = function(name)
63         {
64             if(name == "")
65                 stop("Invalid name.")
66
67             private$name <- name
68         },
69
70         getName = function() private$name,
71
72         getFileListing = function(fullpath = TRUE)
73         {
74             self$getName()
75         },
76
77         getSizeInBytes = function()
78         {
79             if(is.null(private$collection))
80                 return(0)
81
82             REST <- private$collection$getRESTService()
83
84             fileSize <- REST$getResourceSize(self$getRelativePath(),
85                                              private$collection$uuid)
86
87             fileSize
88         },
89
90         get = function(fileLikeObjectName)
91         {
92             return(NULL)
93         },
94
95         getFirst = function()
96         {
97             return(NULL)
98         },
99
100         getCollection = function() private$collection,
101
102         setCollection = function(collection)
103         {
104             private$collection <- collection
105         },
106
107         getRelativePath = function()
108         {
109             relativePath <- c(private$name)
110             parent <- private$parent
111
112             while(!is.null(parent))
113             {
114                 relativePath <- c(parent$getName(), relativePath)
115                 parent <- parent$getParent()
116             }
117
118             relativePath <- relativePath[relativePath != ""]
119             paste0(relativePath, collapse = "/")
120         },
121
122         getParent = function() private$parent,
123
124         setParent = function(newParent) private$parent <- newParent,
125
126         read = function(contentType = "raw", offset = 0, length = 0)
127         {
128             if(is.null(private$collection))
129                 stop("ArvadosFile doesn't belong to any collection.")
130
131             if(offset < 0 || length < 0)
132                 stop("Offset and length must be positive values.")
133
134             REST <- private$collection$getRESTService()
135
136             fileContent <- REST$read(self$getRelativePath(),
137                                      private$collection$uuid,
138                                      contentType, offset, length)
139             fileContent
140         },
141
142         connection = function(rw)
143         {
144             if (rw == "r" || rw == "rb") 
145             {
146                 REST <- private$collection$getRESTService()
147                 return(REST$getConnection(private$collection$uuid,
148                                           self$getRelativePath(),
149                                           rw))
150             }
151             else if (rw == "w") 
152             {
153                 private$buffer <- textConnection(NULL, "w")
154
155                 return(private$buffer)
156             }
157         },
158
159         flush = function() 
160         {
161             v <- textConnectionValue(private$buffer)
162             close(private$buffer)
163             self$write(paste(v, collapse='\n'))
164         },
165
166         write = function(content, contentType = "text/html")
167         {
168             if(is.null(private$collection))
169                 stop("ArvadosFile doesn't belong to any collection.")
170
171             REST <- private$collection$getRESTService()
172
173             writeResult <- REST$write(self$getRelativePath(),
174                                       private$collection$uuid,
175                                       content, contentType)
176             writeResult
177         },
178
179         move = function(newLocation)
180         {
181             if(is.null(private$collection))
182                 stop("ArvadosFile doesn't belong to any collection")
183
184             newLocation <- trimFromEnd(newLocation, "/")
185             nameAndPath <- splitToPathAndName(newLocation)
186
187             newParent <- private$collection$get(nameAndPath$path)
188
189             if(is.null(newParent))
190             {
191                 stop("Unable to get destination subcollection")
192             }
193
194             childWithSameName <- newParent$get(nameAndPath$name)
195
196             if(!is.null(childWithSameName))
197                 stop("Destination already contains content with same name.")
198
199             REST <- private$collection$getRESTService()
200             REST$move(self$getRelativePath(),
201                       paste0(newParent$getRelativePath(), "/", nameAndPath$name),
202                       private$collection$uuid)
203
204             private$dettachFromCurrentParent()
205             private$attachToNewParent(newParent)
206
207             private$name <- nameAndPath$name
208
209             "Content moved successfully."
210         }
211     ),
212
213     private = list(
214
215         name       = NULL,
216         size       = NULL,
217         parent     = NULL,
218         collection = NULL,
219         buffer     = NULL,
220
221         attachToNewParent = function(newParent)
222         {
223             #Note: We temporary set parents collection to NULL. This will ensure that
224             #      add method doesn't post file on REST.
225             parentsCollection <- newParent$getCollection()
226             newParent$setCollection(NULL, setRecursively = FALSE)
227
228             newParent$add(self)
229
230             newParent$setCollection(parentsCollection, setRecursively = FALSE)
231
232             private$parent <- newParent
233         },
234
235         dettachFromCurrentParent = function()
236         {
237             #Note: We temporary set parents collection to NULL. This will ensure that
238             #      remove method doesn't remove this subcollection from REST.
239             parent <- private$parent
240             parentsCollection <- parent$getCollection()
241             parent$setCollection(NULL, setRecursively = FALSE)
242
243             parent$remove(private$name)
244
245             parent$setCollection(parentsCollection, setRecursively = FALSE)
246         }
247     ),
248
249     cloneable = FALSE
250 )
251
252 #' print.ArvadosFile
253 #'
254 #' Custom print function for ArvadosFile class
255 #'
256 #' @param x Instance of ArvadosFile class
257 #' @param ... Optional arguments.
258 #' @export 
259 print.ArvadosFile = function(x, ...)
260 {
261     collection   <- NULL
262     relativePath <- x$getRelativePath()
263
264     if(!is.null(x$getCollection()))
265     {
266         collection <- x$getCollection()$uuid
267         relativePath <- paste0("/", relativePath)
268     }
269
270     cat(paste0("Type:          ", "\"", "ArvadosFile",         "\""), sep = "\n")
271     cat(paste0("Name:          ", "\"", x$getName(),           "\""), sep = "\n")
272     cat(paste0("Relative path: ", "\"", relativePath,          "\""), sep = "\n")
273     cat(paste0("Collection:    ", "\"", collection,            "\""), sep = "\n")
274 }