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