2411: add copyright headers to our R files.
[arvados.git] / sdk / R / R / Collection.R
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: Apache-2.0
4
5 source("./R/Subcollection.R")
6 source("./R/ArvadosFile.R")
7 source("./R/RESTService.R")
8 source("./R/util.R")
9
10 #' Collection
11 #' 
12 #' Collection class provides interface for working with Arvados collections.
13 #' 
14 #' @section Usage:
15 #' \preformatted{collection = Collection$new(arv, uuid)}
16 #'
17 #' @section Arguments:
18 #' \describe{
19 #'   \item{arv}{Arvados object.}
20 #'   \item{uuid}{UUID of a collection.}
21 #' }
22 #' 
23 #' @section Methods:
24 #' \describe{
25 #'   \item{add(content)}{Adds ArvadosFile or Subcollection specified by content to the collection.}
26 #'   \item{create(fileNames, relativePath = "")}{Creates one or more ArvadosFiles and adds them to the collection at specified path.}
27 #'   \item{remove(fileNames)}{Remove one or more files from the collection.}
28 #'   \item{move(content, newLocation)}{Moves ArvadosFile or Subcollection to another location in the collection.}
29 #'   \item{getFileListing()}{Returns collections file content as character vector.}
30 #'   \item{get(relativePath)}{If relativePath is valid, returns ArvadosFile or Subcollection specified by relativePath, else returns NULL.}
31 #' }
32 #'
33 #' @name Collection
34 #' @examples
35 #' \dontrun{
36 #' arv <- Arvados$new("your Arvados token", "example.arvadosapi.com")
37 #' collection <- Collection$new(arv, "uuid")
38 #'
39 #' newFile <- ArvadosFile$new("myFile")
40 #' collection$add(newFile, "myFolder")
41 #'
42 #' createdFiles <- collection$create(c("main.cpp", lib.dll), "cpp/src/")
43 #'
44 #' collection$remove("location/to/my/file.cpp")
45 #'
46 #' collection$move("folder/file.cpp", "file.cpp")
47 #'
48 #' arvadosFile <- collection$get("location/to/my/file.cpp")
49 #' arvadosSubcollection <- collection$get("location/to/my/directory/")
50 #' }
51 NULL
52
53 #' @export
54 Collection <- R6::R6Class(
55
56     "Collection",
57
58     public = list(
59
60                 uuid = NULL,
61         # api  = NULL,
62
63                 initialize = function(api, uuid) 
64         {
65             # self$api <- api
66             private$REST <- api$getRESTService()
67
68             self$uuid <- uuid
69
70             private$fileContent <- private$REST$getCollectionContent(uuid)
71             private$tree <- CollectionTree$new(private$fileContent, self)
72         },
73
74         add = function(content, relativePath = "")
75         {
76             if(is.null(private$tree))
77                 private$genereateCollectionTreeStructure()
78
79             if(relativePath == ""  ||
80                relativePath == "." ||
81                relativePath == "./")
82             {
83                 subcollection <- private$tree$getTree()
84             }
85             else
86             {
87                 relativePath <- trimFromEnd(relativePath, "/")
88                 subcollection <- self$get(relativePath)
89             }
90
91             if(is.null(subcollection))
92                 stop(paste("Subcollection", relativePath, "doesn't exist."))
93
94             if("ArvadosFile"   %in% class(content) ||
95                "Subcollection" %in% class(content))
96             {
97                 if(content$getName() == "")
98                     stop("Content has invalid name.")
99
100                 subcollection$add(content)
101                 content
102             }
103             else
104             {
105                 stop(paste0("Expected AravodsFile or Subcollection object, got ",
106                             paste0("(", paste0(class(content), collapse = ", "), ")"),
107                             "."))
108             }
109         },
110
111         create = function(fileNames, relativePath = "")
112         {
113             if(is.null(private$tree))
114                 private$genereateCollectionTreeStructure()
115
116             if(relativePath == ""  ||
117                relativePath == "." ||
118                relativePath == "./")
119             {
120                 subcollection <- private$tree$getTree()
121             }
122             else
123             {
124                 relativePath  <- trimFromEnd(relativePath, "/") 
125                 subcollection <- self$get(relativePath)
126             }
127
128             if(is.null(subcollection))
129                 stop(paste("Subcollection", relativePath, "doesn't exist."))
130
131             if(is.character(fileNames))
132             {
133                 arvadosFiles <- NULL
134                 sapply(fileNames, function(fileName)
135                 {
136                     childWithSameName <- subcollection$get(fileName)
137                     if(!is.null(childWithSameName))
138                         stop("Destination already contains file with same name.")
139
140                     newFile <- ArvadosFile$new(fileName)
141                     subcollection$add(newFile)
142
143                     arvadosFiles <<- c(arvadosFiles, newFile)
144                 })
145
146                 if(length(arvadosFiles) == 1)
147                     return(arvadosFiles[[1]])
148                 else
149                     return(arvadosFiles)
150             }
151             else 
152             {
153                 stop(paste0("Expected character vector, got ",
154                             paste0("(", paste0(class(fileNames), collapse = ", "), ")"),
155                             "."))
156             }
157         },
158
159         remove = function(paths)
160         {
161             if(is.null(private$tree))
162                 private$genereateCollectionTreeStructure()
163
164             if(is.character(paths))
165             {
166                 sapply(paths, function(filePath)
167                 {
168                     filePath <- trimFromEnd(filePath, "/")
169                     file <- self$get(filePath)
170
171                     if(is.null(file))
172                         stop(paste("File", filePath, "doesn't exist."))
173
174                     parent <- file$getParent()
175
176                     if(is.null(parent))
177                         stop("You can't delete root folder.")
178
179                     parent$remove(file$getName())
180                 })
181
182                 "Content removed"
183             }
184             else 
185             {
186                 stop(paste0("Expected character vector, got ",
187                             paste0("(", paste0(class(paths), collapse = ", "), ")"),
188                             "."))
189             }
190         },
191
192         move = function(content, newLocation)
193         {
194             if(is.null(private$tree))
195                 private$genereateCollectionTreeStructure()
196
197             content <- trimFromEnd(content, "/")
198
199             elementToMove <- self$get(content)
200
201             if(is.null(elementToMove))
202                 stop("Content you want to move doesn't exist in the collection.")
203
204             elementToMove$move(newLocation)
205         },
206
207         getFileListing = function()
208         {
209             if(is.null(private$tree))
210                 private$genereateCollectionTreeStructure()
211
212             content <- private$REST$getCollectionContent(self$uuid)
213             content[order(tolower(content))]
214         },
215
216         get = function(relativePath)
217         {
218             if(is.null(private$tree))
219                 private$genereateCollectionTreeStructure()
220
221             private$tree$getElement(relativePath)
222         },
223
224                 toJSON = function() 
225         {
226                         fields <- sapply(private$classFields, function(field)
227                         {
228                                 self[[field]]
229                         }, USE.NAMES = TRUE)
230                         
231                         jsonlite::toJSON(list("collection" = 
232                      Filter(Negate(is.null), fields)), auto_unbox = TRUE)
233                 },
234
235                 isEmpty = function() {
236                         fields <- sapply(private$classFields,
237                                          function(field) self[[field]])
238
239                         if(any(sapply(fields, function(field) !is.null(field) && field != "")))
240                                 FALSE
241                         else
242                                 TRUE
243                 },
244
245         getRESTService = function() private$REST,
246         setRESTService = function(newRESTService) private$REST <- newRESTService
247     ),
248
249     private = list(
250
251         REST        = NULL,
252         tree        = NULL,
253         fileContent = NULL,
254         classFields = NULL,
255
256         genereateCollectionTreeStructure = function()
257         {
258             if(is.null(self$uuid))
259                 stop("Collection uuid is not defined.")
260
261             if(is.null(private$REST))
262                 stop("REST service is not defined.")
263
264             private$fileContent <- private$REST$getCollectionContent(self$uuid)
265             private$tree <- CollectionTree$new(private$fileContent, self)
266         }
267     ),
268
269     cloneable = FALSE
270 )
271
272 #' print.Collection
273 #'
274 #' Custom print function for Collection class
275 #'
276 #' @param x Instance of Collection class
277 #' @param ... Optional arguments.
278 #' @export 
279 print.Collection = function(x, ...)
280 {
281     cat(paste0("Type: ", "\"", "Arvados Collection", "\""), sep = "\n")
282     cat(paste0("uuid: ", "\"", x$uuid,               "\""), sep = "\n")
283 }