Collection classes no longer use each others private state.
[arvados.git] / sdk / R / R / ArvadosFile.R
1 #' ArvadosFile Object
2 #'
3 #' Update description
4 #'
5 #' @export ArvadosFile
6 ArvadosFile <- R6::R6Class(
7
8     "ArvadosFile",
9
10     public = list(
11
12         initialize = function(name)
13         {
14             private$name             <- name
15             private$http             <- HttpRequest$new()
16             private$httpParser       <- HttpParser$new()
17         },
18
19         getName = function() private$name,
20
21         getFileListing = function(fullpath = TRUE)
22         {
23             self$getName()
24         },
25
26         getSizeInBytes = function()
27         {
28             collectionURL <- URLencode(paste0(private$collection$api$getWebDavHostName(),
29                                               "c=", private$collection$uuid))
30             fileURL <- paste0(collectionURL, "/", self$getRelativePath());
31
32             headers = list("Authorization" = paste("OAuth2", private$collection$api$getToken()))
33
34             propfindResponse <- private$http$PROPFIND(fileURL, headers)
35
36             sizes <- private$httpParser$extractFileSizeFromWebDAVResponse(propfindResponse, collectionURL)
37             as.numeric(sizes)
38         },
39
40         get = function(fileLikeObjectName)
41         {
42             return(NULL)
43         },
44
45         getFirst = function()
46         {
47             return(NULL)
48         },
49
50         getCollection = function() private$collection,
51
52         setCollection = function(collection)
53         {
54             private$collection <- collection
55         },
56
57         getRelativePath = function()
58         {
59             relativePath <- c(private$name)
60             parent <- private$parent
61
62             while(!is.null(parent))
63             {
64                 relativePath <- c(parent$getName(), relativePath)
65                 parent <- parent$getParent()
66             }
67
68             relativePath <- relativePath[relativePath != ""]
69             paste0(relativePath, collapse = "/")
70         },
71
72         getParent = function() private$parent,
73
74         setParent = function(newParent) private$parent <- newParent,
75
76         read = function(contentType = "raw", offset = 0, length = 0)
77         {
78             if(is.null(private$collection))
79                 stop("ArvadosFile doesn't belong to any collection.")
80
81             if(offset < 0 || length < 0)
82                 stop("Offset and length must be positive values.")
83
84             if(!(contentType %in% private$http$validContentTypes))
85                 stop("Invalid contentType. Please use text or raw.")
86
87             range = paste0("bytes=", offset, "-")
88
89             if(length > 0)
90                 range = paste0(range, offset + length - 1)
91             
92             fileURL = paste0(private$collection$api$getWebDavHostName(),
93                              "c=", private$collection$uuid, "/", self$getRelativePath());
94
95             if(offset == 0 && length == 0)
96             {
97                 headers <- list(Authorization = paste("OAuth2",
98                                                       private$collection$api$getToken())) 
99             }
100             else
101             {
102                 headers <- list(Authorization = paste("OAuth2", private$collection$api$getToken()), 
103                                 Range = range)
104             }
105
106             serverResponse <- private$http$GET(fileURL, headers)
107
108             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
109                 stop(paste("Server code:", serverResponse$status_code))
110
111             parsedServerResponse <- httr::content(serverResponse, contentType)
112             parsedServerResponse
113         },
114         
115         write = function(content, contentType = "text/html")
116         {
117             if(is.null(private$collection))
118                 stop("ArvadosFile doesn't belong to any collection.")
119
120             fileURL = paste0(private$collection$api$getWebDavHostName(), 
121                              "c=", private$collection$uuid, "/", self$getRelativePath());
122             headers <- list(Authorization = paste("OAuth2", private$collection$api$getToken()), 
123                             "Content-Type" = contentType)
124             body <- content
125
126             serverResponse <- private$http$PUT(fileURL, headers, body)
127
128             if(serverResponse$status_code < 200 || serverResponse$status_code >= 300)
129                 stop(paste("Server code:", serverResponse$status_code))
130
131             parsedServerResponse <- httr::content(serverResponse, "text")
132             parsedServerResponse
133         },
134
135         move = function(newLocation)
136         {
137             #todo test if file can be moved
138
139             if(is.null(private$collection))
140                 stop("ArvadosFile doesn't belong to any collection.")
141
142             if(endsWith(newLocation, paste0(private$name, "/")))
143             {
144                 newLocation <- substr(newLocation, 0,
145                                       nchar(newLocation)
146                                       - nchar(paste0(private$name, "/")))
147             }
148             else if(endsWith(newLocation, private$name))
149             {
150                 newLocation <- substr(newLocation, 0,
151                                       nchar(newLocation) - nchar(private$name))
152             }
153             else
154             {
155                 stop("Destination path is not valid.")
156             }
157
158             newParent <- private$collection$get(newLocation)
159
160             if(is.null(newParent))
161             {
162                 stop("Unable to get destination subcollection.")
163             }
164
165             childWithSameName <- newParent$get(private$name)
166
167             if(!is.null(childWithSameName))
168                 stop("Destination already contains file with same name.")
169
170             status <- private$collection$moveOnREST(self$getRelativePath(),
171                                                     paste0(newParent$getRelativePath(),
172                                                            "/", self$getName()))
173
174             #Note: We temporary set parents collection to NULL. This will ensure that
175             #      add method doesn't post file on REST server.
176             parentsCollection <- newParent$getCollection()
177             newParent$setCollection(NULL, setRecursively = FALSE)
178
179             newParent$add(self)
180
181             newParent$setCollection(parentsCollection, setRecursively = FALSE)
182
183             private$parent <- newParent
184
185             "Content moved successfully."
186         }
187     ),
188
189     private = list(
190
191         name       = NULL,
192         size       = NULL,
193         parent     = NULL,
194         collection = NULL,
195         http       = NULL,
196         httpParser = NULL
197     ),
198     
199     cloneable = FALSE
200 )