16827: Don't append '/' to requests with query params. Bump version
[arvados.git] / sdk / R / R / CollectionTree.R
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: Apache-2.0
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             treeBranches <- sapply(fileContent, function(filePath) self$createBranch(filePath))
15             root <- Subcollection$new("")
16             sapply(treeBranches, function(branch) self$addBranch(root, branch))
17             root$setCollection(collection)
18             private$tree <- root
19         },
20
21         createBranch = function(filePath)
22         {
23             splitPath <- unlist(strsplit(filePath, "/", fixed = TRUE))
24             branch <- NULL
25             lastElementIndex <- length(splitPath)
26
27             for(elementIndex in lastElementIndex:1)
28             {
29                 if(elementIndex == lastElementIndex)
30                 {
31                     branch <- ArvadosFile$new(splitPath[[elementIndex]])
32                 }
33                 else
34                 {
35                     newFolder <- Subcollection$new(splitPath[[elementIndex]])
36                     newFolder$add(branch)
37                     branch <- newFolder
38                 }
39             }
40
41             branch
42         },
43
44         addBranch = function(container, node)
45         {
46             child <- container$get(node$getName())
47
48             if(is.null(child))
49             {
50                 # Make sure we are don't make any REST call while adding child
51                 collection <- container$getCollection()
52                 container$setCollection(NULL, setRecursively = FALSE)
53                 container$add(node)
54                 container$setCollection(collection, setRecursively = FALSE)
55             }
56             else
57             {
58                 # Note: REST always returns folder name alone before other folder
59                 # content, so in first iteration we don't know if it's a file
60                 # or folder since its just a name, so we assume it's a file.
61                 # If we encounter that same name again we know
62                 # it's a folder so we need to replace ArvadosFile with Subcollection.
63                 if("ArvadosFile" %in% class(child))
64                     child = private$replaceFileWithSubcollection(child)
65
66                 self$addBranch(child, node$getFirst())
67             }
68         },
69
70         getElement = function(relativePath)
71         {
72             relativePath <- trimFromStart(relativePath, "./")
73             relativePath <- trimFromEnd(relativePath, "/")
74
75             if(endsWith(relativePath, "/"))
76                 relativePath <- substr(relativePath, 0, nchar(relativePath) - 1)
77
78             splitPath <- unlist(strsplit(relativePath, "/", fixed = TRUE))
79             returnElement <- private$tree
80
81             for(pathFragment in splitPath)
82             {
83                 returnElement <- returnElement$get(pathFragment)
84
85                 if(is.null(returnElement))
86                     return(NULL)
87             }
88
89             returnElement
90         },
91
92         getTree = function() private$tree
93     ),
94
95     private = list(
96
97         tree = NULL,
98
99         replaceFileWithSubcollection = function(arvadosFile)
100         {
101             subcollection <- Subcollection$new(arvadosFile$getName())
102             fileParent <- arvadosFile$getParent()
103             fileParent$remove(arvadosFile$getName())
104             fileParent$add(subcollection)
105
106             arvadosFile$setParent(NULL)
107
108             subcollection
109         }
110     )
111 )