Created in-memory representation of collection file structure.
[arvados.git] / sdk / R / R / Collection.R
1 source("./R/Arvados.R")
2 source("./R/HttpParser.R")
3 source("./R/Subcollection.R")
4 source("./R/ArvadosFile.R")
5
6 #' Collection Class
7 #' 
8 #' @details 
9 #' Todo: Update description
10 #' Collection
11 #' 
12 #' @param uuid Object ID
13 #' @param etag Object version
14 #' @param owner_uuid No description
15 #' @param created_at No description
16 #' @param modified_by_client_uuid No description
17 #' @param modified_by_user_uuid No description
18 #' @param modified_at No description
19 #' @param portable_data_hash No description
20 #' @param replication_desired No description
21 #' @param replication_confirmed_at No description
22 #' @param replication_confirmed No description
23 #' @param updated_at No description
24 #' @param manifest_text No description
25 #' @param name No description
26 #' @param description No description
27 #' @param properties No description
28 #' @param delete_at No description
29 #' @param file_names No description
30 #' @param trash_at No description
31 #' @param is_trashed No description
32 #' 
33 #' @export Collection
34
35 #' @exportClass Collection
36 Collection <- setRefClass(
37
38     "Collection",
39
40     fields = list(uuid                     = "ANY",
41                   items                    = "ANY",
42                   etag                     = "ANY",
43                   owner_uuid               = "ANY",
44                   created_at               = "ANY",
45                   modified_by_client_uuid  = "ANY",
46                   modified_by_user_uuid    = "ANY",
47                   modified_at              = "ANY",
48                   portable_data_hash       = "ANY",
49                   replication_desired      = "ANY",
50                   replication_confirmed_at = "ANY",
51                   replication_confirmed    = "ANY",
52                   updated_at               = "ANY",
53                   manifest_text            = "ANY",
54                   name                     = "ANY",
55                   description              = "ANY",
56                   properties               = "ANY",
57                   delete_at                = "ANY",
58                   file_names               = "ANY",
59                   trash_at                 = "ANY",
60                   is_trashed               = "ANY",
61
62                   getCollectionContent = "function"
63     ),
64
65     methods = list(
66
67         initialize = function(api, uuid) 
68         {
69             result <- api$collection_get(uuid)
70             
71             # Private members
72             uuid                     <<- result$uuid                               
73             etag                     <<- result$etag                               
74             owner_uuid               <<- result$owner_uuid                         
75             created_at               <<- result$created_at                         
76             modified_by_client_uuid  <<- result$modified_by_client_uuid            
77             modified_by_user_uuid    <<- result$modified_by_user_uuid              
78             modified_at              <<- result$modified_at                        
79             portable_data_hash       <<- result$portable_data_hash                 
80             replication_desired      <<- result$replication_desired                
81             replication_confirmed_at <<- result$replication_confirmed_at           
82             replication_confirmed    <<- result$replication_confirmed              
83             updated_at               <<- result$updated_at                         
84             manifest_text            <<- result$manifest_text                      
85             name                     <<- result$name                               
86             description              <<- result$description                        
87             properties               <<- result$properties                         
88             delete_at                <<- result$delete_at                          
89             file_names               <<- result$file_names                         
90             trash_at                 <<- result$trash_at                           
91             is_trashed               <<- result$is_trashed                         
92
93             # Private methods
94             getCollectionContent <<- function()
95             {
96                 #TODO(Fudo): Use proper URL here.
97                 uri <- URLencode(api$getWebDavHostName())
98
99                 # fetch directory listing via curl and parse XML response
100                 h <- curl::new_handle()
101                 curl::handle_setopt(h, customrequest = "PROPFIND")
102
103                 #TODO(Fudo): Use proper token here.
104                 curl::handle_setheaders(h, "Authorization" = paste("OAuth2", api$getWebDavToken()))
105                 response <- curl::curl_fetch_memory(uri, h)
106
107                 HttpParser()$parseWebDAVResponse(response, uri)
108             }
109
110             createCollectionContentTree <- function(fileStructure)
111             {
112                 #Todo(Fudo): Refactor this.
113                 treeBranches <- sapply(fileStructure, function(filePath) 
114                 {
115                     fileWithPath <- unlist(stringr::str_split(filePath, "/"))
116
117                     file <- fileWithPath[length(fileWithPath), drop = T]
118                     file <- ArvadosFile(file)
119
120                     folders <- fileWithPath[-length(fileWithPath)]
121
122                     subcollections <- sapply(folders, function(folder)
123                     {
124                         folder <- Subcollection(folder)
125                     })
126
127                     if(length(subcollections) > 0)
128                     {
129                         bottomFolder <- subcollections[[length(subcollections)]]
130                         bottomFolder$add(file)
131
132                         if(length(subcollections) == 1)
133                         {
134                             return(bottomFolder)
135                         }
136                         else
137                         {
138                             # Link folders in hierarchy. At the bottom will always be a file.
139                             for(subcollectionIndex in 1:(length(subcollections) - 1))
140                             {
141                                 subcollections[[subcollectionIndex]]$add(subcollections[[subcollectionIndex + 1]])
142                             }
143
144                             subcollections[[1]]
145                         }
146                     }
147                     else
148                     {
149                         file
150                     }
151                 })
152
153                 root <- Subcollection(".")
154
155                 addIfExists <- function(firstNode, secondNode)
156                 {
157                     firstNodeContent <- sapply(firstNode$content, function(node) {node$name})
158                     if(length(firstNodeContent) == 0)
159                     {
160                         firstNode$add(secondNode)
161                         return()
162                     }
163
164                     matchPosition <- match(secondNode$name, firstNodeContent, -1)
165                     if(matchPosition != -1)
166                     {
167                         addIfExists(firstNode$content[[matchPosition]], secondNode$content[[1]])
168                     }
169                     else
170                     {
171                         firstNode$add(secondNode)
172                     }
173                 }
174
175                 sapply(treeBranches, function(branch)
176                 {
177                     addIfExists(root, branch)
178                 })
179
180                 root
181             }
182
183             #Todo(Fudo): This is dummy data. Real content will come from WebDAV server.
184             testFileStructure <- c("math.h", "main.cpp",
185                                    "java/render.java", "java/test/observer.java",
186                                    "java/test/observable.java",
187                                    "csharp/this.cs", "csharp/is.cs",
188                                    "csharp/dummy.cs", "csharp/file.cs")
189             #items  <<- getCollectionContent()
190             items  <<- createCollectionContentTree(testFileStructure)
191         }
192     )
193 )