Merge branch 'master' of git.curoverse.com:arvados into 11876-r-sdk
[arvados.git] / sdk / R / R / Subcollection.R
1 source("./R/util.R")
2
3 #' Arvados SubCollection Object
4 #'
5 #' Update description
6 #'
7 #' @export Subcollection
8 Subcollection <- R6::R6Class(
9
10     "Subcollection",
11
12     public = list(
13
14         initialize = function(name)
15         {
16             private$name       <- name
17         },
18
19         getName = function() private$name,
20         
21         getRelativePath = function()
22         {
23             relativePath <- c(private$name)
24             parent <- private$parent
25
26             while(!is.null(parent))
27             {
28                 relativePath <- c(parent$getName(), relativePath)
29                 parent <- parent$getParent()
30             }
31
32             relativePath <- relativePath[relativePath != ""]
33             paste0(relativePath, collapse = "/")
34         },
35
36         add = function(content)
37         {
38             if("ArvadosFile"   %in% class(content) ||
39                "Subcollection" %in% class(content))
40             {
41                 childWithSameName <- self$get(content$getName())
42                 if(!is.null(childWithSameName))
43                     stop(paste("Subcollection already contains ArvadosFile",
44                                "or Subcollection with same name."))
45
46                 if(!is.null(private$collection))
47                 {       
48                     if(self$getRelativePath() != "")
49                         contentPath <- paste0(self$getRelativePath(),
50                                               "/", content$getFileListing())
51                     else
52                         contentPath <- content$getFileListing()
53
54                     REST <- private$collection$getRESTService()
55                     REST$create(contentPath, private$collection$uuid)
56                     content$setCollection(private$collection)
57                 }
58
59                 private$children <- c(private$children, content)
60                 content$setParent(self)
61
62                 "Content added successfully."
63             }
64             else
65             {
66                 stop(paste0("Expected AravodsFile or Subcollection object, got ",
67                             paste0("(", paste0(class(content), collapse = ", "), ")"),
68                             "."))
69             }
70         },
71
72         remove = function(name)
73         {
74             if(is.character(name))
75             {
76                 child <- self$get(name)
77
78                 if(is.null(child))
79                     stop(paste("Subcollection doesn't contains ArvadosFile",
80                                "or Subcollection with specified name."))
81
82                 if(!is.null(private$collection))
83                 {
84                     REST <- private$collection$getRESTService()
85                     REST$delete(child$getRelativePath(), private$collection$uuid)
86                     child$setCollection(NULL)
87                 }
88
89                 private$removeChild(name)
90                 child$setParent(NULL)
91
92                 "Content removed"
93             }
94             else
95             {
96                 stop(paste0("Expected character, got ",
97                             paste0("(", paste0(class(name), collapse = ", "), ")"),
98                             "."))
99             }
100         },
101
102         getFileListing = function(fullPath = TRUE)
103         {
104             content <- NULL
105
106             if(fullPath)
107             {
108                 for(child in private$children)
109                     content <- c(content, child$getFileListing())
110
111                 if(private$name != "")
112                     content <- unlist(paste0(private$name, "/", content))
113             }
114             else
115             {
116                 for(child in private$children)
117                     content <- c(content, child$getName())
118             }
119
120             content
121         },
122
123         getSizeInBytes = function()
124         {
125             if(is.null(private$collection))
126                 return(0)
127
128             REST <- private$collection$getRESTService()
129
130             fileSizes <- REST$getResourceSize(paste0(self$getRelativePath(), "/"),
131                                               private$collection$uuid)
132             return(sum(fileSizes))
133         },
134
135         move = function(newLocation)
136         {
137             if(is.null(private$collection))
138                 stop("Subcollection doesn't belong to any collection")
139
140             newLocation <- trimFromEnd(newLocation, "/")
141             nameAndPath <- splitToPathAndName(newLocation)
142
143             newParent <- private$collection$get(nameAndPath$path)
144
145             if(is.null(newParent))
146             {
147                 stop("Unable to get destination subcollection")
148             }
149
150             childWithSameName <- newParent$get(nameAndPath$name)
151
152             if(!is.null(childWithSameName))
153                 stop("Destination already contains content with same name.")
154
155             REST <- private$collection$getRESTService()
156             REST$move(self$getRelativePath(),
157                       paste0(newParent$getRelativePath(), "/", nameAndPath$name),
158                       private$collection$uuid)
159
160             private$dettachFromCurrentParent()
161             private$attachToNewParent(newParent)
162
163             private$name <- nameAndPath$name
164
165             "Content moved successfully."
166         },
167
168         get = function(name)
169         {
170             for(child in private$children)
171             {
172                 if(child$getName() == name)
173                     return(child)
174             }
175
176             return(NULL)
177         },
178
179         getFirst = function()
180         {
181             if(length(private$children) == 0)
182                return(NULL)
183
184             private$children[[1]]
185         },
186
187         setCollection = function(collection, setRecursively = TRUE)
188         {
189             private$collection = collection
190
191             if(setRecursively)
192             {
193                 for(child in private$children)
194                     child$setCollection(collection)
195             }
196         },
197
198         getCollection = function() private$collection,
199
200         getParent = function() private$parent,
201
202         setParent = function(newParent) private$parent <- newParent
203     ),
204
205     private = list(
206
207         name       = NULL,
208         children   = NULL,
209         parent     = NULL,
210         collection = NULL,
211
212         removeChild = function(name)
213         {
214             numberOfChildren = length(private$children)
215             if(numberOfChildren > 0)
216             {
217                 for(childIndex in 1:numberOfChildren)
218                 {
219                     if(private$children[[childIndex]]$getName() == name)
220                     {
221                         private$children = private$children[-childIndex]
222                         return()
223                     }
224                 }
225             }
226         },
227
228         attachToNewParent = function(newParent)
229         {
230             #Note: We temporary set parents collection to NULL. This will ensure that
231             #      add method doesn't post file on REST.
232             parentsCollection <- newParent$getCollection()
233             newParent$setCollection(NULL, setRecursively = FALSE)
234
235             newParent$add(self)
236
237             newParent$setCollection(parentsCollection, setRecursively = FALSE)
238
239             private$parent <- newParent
240         },
241
242         dettachFromCurrentParent = function()
243         {
244             #Note: We temporary set parents collection to NULL. This will ensure that
245             #      remove method doesn't remove this subcollection from REST.
246             parent <- private$parent
247             parentsCollection <- parent$getCollection()
248             parent$setCollection(NULL, setRecursively = FALSE)
249
250             parent$remove(private$name)
251
252             parent$setCollection(parentsCollection, setRecursively = FALSE)
253         }
254     ),
255     
256     cloneable = FALSE
257 )