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