getFileListing now returns sorted list
[arvados.git] / sdk / R / R / CollectionTree.R
1 source("./R/Subcollection.R")
2 source("./R/ArvadosFile.R")
3 source("./R/util.R")
4
5 #' Arvados Collection Object
6 #'
7 #' Update description
8 #'
9 #' @examples arv = Collection$new(api, uuid)
10 #' @export CollectionTree
11 CollectionTree <- R6::R6Class(
12     "CollectionTree",
13     public = list(
14
15         pathsList = NULL,
16
17         initialize = function(fileContent, collection)
18         {
19             self$pathsList <- fileContent
20
21             treeBranches <- sapply(fileContent, function(filePath)
22             {
23                 splitPath <- unlist(strsplit(filePath, "/", fixed = TRUE))
24                 branch <- private$createBranch(splitPath)      
25             })
26
27             root <- Subcollection$new("")
28
29             sapply(treeBranches, function(branch)
30             {
31                 private$addBranch(root, branch)
32             })
33
34             root$setCollection(collection)
35             private$tree <- root
36         },
37
38         getElement = function(relativePath)
39         {
40             relativePath <- trimFromStart(relativePath, "./")
41             relativePath <- trimFromEnd(relativePath, "/")
42
43             if(endsWith(relativePath, "/"))
44                 relativePath <- substr(relativePath, 0, nchar(relativePath) - 1)
45
46             splitPath <- unlist(strsplit(relativePath, "/", fixed = TRUE))
47             returnElement <- private$tree
48
49             for(pathFragment in splitPath)
50             {
51                 returnElement <- returnElement$get(pathFragment)
52
53                 if(is.null(returnElement))
54                     return(NULL)
55             }
56
57             returnElement
58         },
59
60         getTree = function() private$tree
61     ),
62
63     private = list(
64
65         tree = NULL,
66
67         createBranch = function(splitPath)
68         {
69             branch <- NULL
70             lastElementIndex <- length(splitPath)
71
72             for(elementIndex in lastElementIndex:1)
73             {
74                 if(elementIndex == lastElementIndex)
75                 {
76                     branch <- ArvadosFile$new(splitPath[[elementIndex]])
77                 }
78                 else
79                 {
80                     newFolder <- Subcollection$new(splitPath[[elementIndex]])
81                     newFolder$add(branch)
82                     branch <- newFolder
83                 }
84             }
85             
86             branch
87         },
88
89         addBranch = function(container, node)
90         {
91             child <- container$get(node$getName())
92
93             if(is.null(child))
94             {
95                 container$add(node)
96             }
97             else
98             {
99                 # Note: REST always returns folder name alone before other folder content
100                 # (for some reason), so in first iteration we don't know if it's a file
101                 # or folder since its just a name, so we assume it's a file. 
102                 # If we encounter that same name again we know 
103                 # it's a folder so we need to replace ArvadosFile with Subcollection.
104                 if("ArvadosFile" %in% class(child))
105                 {
106                     child = private$replaceFileWithSubcollection(child)
107                 }
108
109                 private$addBranch(child, node$getFirst())
110             }
111         },
112
113         replaceFileWithSubcollection = function(arvadosFile)
114         {
115             subcollection <- Subcollection$new(arvadosFile$getName())
116             fileParent <- arvadosFile$getParent()
117             fileParent$remove(arvadosFile$getName())
118             fileParent$add(subcollection)
119
120             arvadosFile$setParent(NULL)
121
122             subcollection
123         }
124     )
125 )