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