Fixed some bugs and improved error handling.
[arvados.git] / sdk / R / R / Collection.R
1 source("./R/Subcollection.R")
2 source("./R/ArvadosFile.R")
3 source("./R/HttpRequest.R")
4 source("./R/HttpParser.R")
5
6 #' Arvados Collection Object
7 #'
8 #' Update description
9 #'
10 #' @examples arv = Collection$new(api, uuid)
11 #' @export Collection
12 Collection <- R6::R6Class(
13
14     "Collection",
15
16     public = list(
17
18         api  = NULL,
19         uuid = NULL,
20
21         initialize = function(api, uuid)
22         {
23             self$api <- api
24             private$http <- HttpRequest$new()
25             private$httpParser <- HttpParser$new()
26
27             self$uuid <- uuid
28             collection <- self$api$getCollection(uuid)
29
30             private$fileContent <- private$getCollectionContent()
31             private$tree <- CollectionTree$new(private$fileContent, self)
32         },
33
34         add = function(content, relativePath = "")
35         {
36             if(relativePath == "" ||
37                relativePath == "." ||
38                relativePath == "./")
39             {
40                 subcollection <- private$tree$.__enclos_env__$private$tree
41             }
42             else
43             {
44                 if(endsWith(relativePath, "/") && nchar(relativePath) > 0)
45                     relativePath <- substr(relativePath, 1, nchar(relativePath) - 1)
46
47                 subcollection <- self$get(relativePath)
48             }
49
50             if(is.null(subcollection))
51                 stop(paste("Subcollection", relativePath, "doesn't exist."))
52
53             if(is.character(content))
54             {
55                 sapply(content, function(fileName)
56                 {
57                     subcollection$add(ArvadosFile$new(fileName))
58                 })
59             }
60             else if("ArvadosFile"   %in% class(content) ||
61                     "Subcollection" %in% class(content))
62             {
63                 subcollection$add(content)
64             }
65         },
66
67         remove = function(content)
68         {
69             if(is.character(content))
70             {
71                 sapply(content, function(filePath)
72                 {
73                     if(endsWith(filePath, "/") && nchar(filePath) > 0)
74                         filePath <- substr(filePath, 1, nchar(filePath) - 1)
75
76                     file <- self$get(filePath)
77
78                     if(is.null(file))
79                         stop(paste("File", filePath, "doesn't exist."))
80
81                     file$removeFromCollection()
82                 })
83             }
84             else if("ArvadosFile"   %in% class(content) ||
85                     "Subcollection" %in% class(content))
86             {
87                 if(is.null(content$.__enclos_env__$private$collection) || 
88                    content$.__enclos_env__$private$collection$uuid != self$uuid)
89                     stop("Subcollection doesn't belong to this collection.")
90
91                 content$removeFromCollection()
92             }
93         },
94
95         move = function(content, newLocation)
96         {
97             if(endsWith(content, "/"))
98                 content <- substr(content, 0, nchar(content) - 1)
99
100             elementToMove <- self$get(content)
101
102             if(is.null(elementToMove))
103                 stop("Element you want to move doesn't exist in the collection.")
104
105             elementToMove$move(newLocation)
106         },
107
108         getFileContent = function() private$getCollectionContent(),
109
110         get = function(relativePath)
111         {
112             private$tree$getElement(relativePath)
113         }
114     ),
115
116     private = list(
117
118         http       = NULL,
119         httpParser = NULL,
120         tree       = NULL,
121
122         fileContent = NULL,
123
124         getCollectionContent = function()
125         {
126             collectionURL <- URLencode(paste0(self$api$getWebDavHostName(), "c=", self$uuid))
127
128             headers = list("Authorization" = paste("OAuth2", self$api$getToken()))
129
130             response <- private$http$PROPFIND(collectionURL, headers)
131
132             parsedResponse <- private$httpParser$parseWebDAVResponse(response, collectionURL)
133             parsedResponse[-1]
134         },
135
136         createFilesOnREST = function(files)
137         {
138             sapply(files, function(filePath)
139             {
140                 private$createNewFile(filePath, NULL, "text/html")
141             })
142         },
143         
144         generateTree = function(content)
145         {
146             treeBranches <- sapply(collectionContent, function(filePath)
147             {
148                 splitPath <- unlist(strsplit(filePath$name, "/", fixed = TRUE))
149
150                 branch = private$createBranch(splitPath, filePath$fileSize)      
151             })
152         },
153
154         createNewFile = function(relativePath, content, contentType)
155         {
156             fileURL <- paste0(self$api$getWebDavHostName(), "c=", self$uuid, "/", relativePath);
157             headers <- list(Authorization = paste("OAuth2", self$api$getToken()), 
158                             "Content-Type" = contentType)
159             body <- content
160
161             serverResponse <- private$http$PUT(fileURL, headers, body)
162
163             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
164                 stop(paste("Server code:", serverResponse$status_code))
165
166             print(paste("File created:", relativePath))
167         },
168         
169         deleteFromREST = function(relativePath)
170         {
171             fileURL <- paste0(self$api$getWebDavHostName(), "c=", self$uuid, "/", relativePath);
172             headers <- list(Authorization = paste("OAuth2", self$api$getToken())) 
173
174             serverResponse <- private$http$DELETE(fileURL, headers)
175
176             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
177                 stop(paste("Server code:", serverResponse$status_code))
178
179             print(paste("File deleted:", relativePath))
180         },
181
182         moveOnREST = function(from, to)
183         {
184             collectionURL <- URLencode(paste0(self$api$getWebDavHostName(), "c=", self$uuid, "/"))
185             fromURL <- paste0(collectionURL, from)
186             toURL <- paste0(collectionURL, to)
187
188             headers = list("Authorization" = paste("OAuth2", self$api$getToken()),
189                            "Destination" = toURL)
190
191             serverResponse <- private$http$MOVE(fromURL, headers)
192
193             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
194                 stop(paste("Server code:", serverResponse$status_code))
195
196             serverResponse
197         }
198     ),
199
200     cloneable = FALSE
201 )