Mercurial > hg > orthanc
comparison Core/RestApi/RestApiHierarchy.cpp @ 978:ce3106e5843f
refactoring
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 30 Jun 2014 16:04:58 +0200 |
parents | c550e99c452b |
children | f1ff2a2f06cd |
comparison
equal
deleted
inserted
replaced
975:c550e99c452b | 978:ce3106e5843f |
---|---|
36 | 36 |
37 #include <cassert> | 37 #include <cassert> |
38 | 38 |
39 namespace Orthanc | 39 namespace Orthanc |
40 { | 40 { |
41 RestApiHierarchy::Handlers::Handlers() : | 41 RestApiHierarchy::Resource::Resource() : |
42 getHandler_(NULL), | 42 getHandler_(NULL), |
43 postHandler_(NULL), | 43 postHandler_(NULL), |
44 putHandler_(NULL), | 44 putHandler_(NULL), |
45 deleteHandler_(NULL) | 45 deleteHandler_(NULL) |
46 { | 46 { |
47 } | 47 } |
48 | 48 |
49 | 49 |
50 bool RestApiHierarchy::Handlers::HasHandler(HttpMethod method) const | 50 bool RestApiHierarchy::Resource::HasHandler(HttpMethod method) const |
51 { | 51 { |
52 switch (method) | 52 switch (method) |
53 { | 53 { |
54 case HttpMethod_Get: | 54 case HttpMethod_Get: |
55 return getHandler_ != NULL; | 55 return getHandler_ != NULL; |
67 throw OrthancException(ErrorCode_ParameterOutOfRange); | 67 throw OrthancException(ErrorCode_ParameterOutOfRange); |
68 } | 68 } |
69 } | 69 } |
70 | 70 |
71 | 71 |
72 bool RestApiHierarchy::Handlers::IsEmpty() const | 72 bool RestApiHierarchy::Resource::IsEmpty() const |
73 { | 73 { |
74 return (getHandler_ == NULL && | 74 return (getHandler_ == NULL && |
75 postHandler_ == NULL && | 75 postHandler_ == NULL && |
76 putHandler_ == NULL && | 76 putHandler_ == NULL && |
77 deleteHandler_ == NULL); | 77 deleteHandler_ == NULL); |
78 } | 78 } |
79 | 79 |
80 | 80 |
81 RestApiGetCall::Handler RestApiHierarchy::Handlers::GetGetHandler() const | |
82 { | |
83 assert(getHandler_ != NULL); | |
84 return getHandler_; | |
85 } | |
86 | |
87 RestApiPutCall::Handler RestApiHierarchy::Handlers::GetPutHandler() const | |
88 { | |
89 assert(putHandler_ != NULL); | |
90 return putHandler_; | |
91 } | |
92 | |
93 RestApiPostCall::Handler RestApiHierarchy::Handlers::GetPostHandler() const | |
94 { | |
95 assert(postHandler_ != NULL); | |
96 return postHandler_; | |
97 } | |
98 | |
99 RestApiDeleteCall::Handler RestApiHierarchy::Handlers::GetDeleteHandler() const | |
100 { | |
101 assert(deleteHandler_ != NULL); | |
102 return deleteHandler_; | |
103 } | |
104 | |
105 | |
106 RestApiHierarchy& RestApiHierarchy::AddChild(Children& children, | 81 RestApiHierarchy& RestApiHierarchy::AddChild(Children& children, |
107 const std::string& name) | 82 const std::string& name) |
108 { | 83 { |
109 Children::iterator it = children.find(name); | 84 Children::iterator it = children.find(name); |
110 | 85 |
120 return *it->second; | 95 return *it->second; |
121 } | 96 } |
122 } | 97 } |
123 | 98 |
124 | 99 |
100 | |
101 bool RestApiHierarchy::Resource::Handle(RestApiGetCall& call) const | |
102 { | |
103 if (getHandler_ != NULL) | |
104 { | |
105 getHandler_(call); | |
106 return true; | |
107 } | |
108 else | |
109 { | |
110 return false; | |
111 } | |
112 } | |
113 | |
114 | |
115 bool RestApiHierarchy::Resource::Handle(RestApiPutCall& call) const | |
116 { | |
117 if (putHandler_ != NULL) | |
118 { | |
119 putHandler_(call); | |
120 return true; | |
121 } | |
122 else | |
123 { | |
124 return false; | |
125 } | |
126 } | |
127 | |
128 | |
129 bool RestApiHierarchy::Resource::Handle(RestApiPostCall& call) const | |
130 { | |
131 if (postHandler_ != NULL) | |
132 { | |
133 postHandler_(call); | |
134 return true; | |
135 } | |
136 else | |
137 { | |
138 return false; | |
139 } | |
140 } | |
141 | |
142 | |
143 bool RestApiHierarchy::Resource::Handle(RestApiDeleteCall& call) const | |
144 { | |
145 if (deleteHandler_ != NULL) | |
146 { | |
147 deleteHandler_(call); | |
148 return true; | |
149 } | |
150 else | |
151 { | |
152 return false; | |
153 } | |
154 } | |
155 | |
156 | |
157 | |
125 void RestApiHierarchy::DeleteChildren(Children& children) | 158 void RestApiHierarchy::DeleteChildren(Children& children) |
126 { | 159 { |
127 for (Children::iterator it = children.begin(); | 160 for (Children::iterator it = children.begin(); |
128 it != children.end(); it++) | 161 it != children.end(); it++) |
129 { | 162 { |
163 child->RegisterInternal(path, handler, level + 1); | 196 child->RegisterInternal(path, handler, level + 1); |
164 } | 197 } |
165 } | 198 } |
166 | 199 |
167 | 200 |
168 bool RestApiHierarchy::LookupHandler(HttpHandler::Arguments& components, | 201 bool RestApiHierarchy::LookupResource(HttpHandler::Arguments& components, |
169 const UriComponents& uri, | 202 const UriComponents& uri, |
170 ResourceCallback callback, | 203 IVisitor& visitor, |
171 size_t level, | 204 size_t level) |
172 void* call) | |
173 { | 205 { |
174 assert(uri.size() >= level); | 206 assert(uri.size() >= level); |
175 UriComponents trailing; | 207 UriComponents trailing; |
176 | 208 |
177 // Look for an exact match on the resource of interest | 209 // Look for an exact match on the resource of interest |
178 if (uri.size() == level) | 210 if (uri.size() == level) |
179 { | 211 { |
180 if (!handlers_.IsEmpty() && | 212 if (!handlers_.IsEmpty() && |
181 callback(handlers_, uri, components, trailing, call)) | 213 visitor.Visit(handlers_, uri, components, trailing)) |
182 { | 214 { |
183 return true; | 215 return true; |
184 } | 216 } |
185 } | 217 } |
186 | 218 |
187 | 219 |
188 // Try and go down in the hierarchy, using an exact match for the child | 220 // Try and go down in the hierarchy, using an exact match for the child |
189 Children::const_iterator child = children_.find(uri[level]); | 221 Children::const_iterator child = children_.find(uri[level]); |
190 if (child != children_.end()) | 222 if (child != children_.end()) |
191 { | 223 { |
192 if (child->second->LookupHandler(components, uri, callback, level + 1, call)) | 224 if (child->second->LookupResource(components, uri, visitor, level + 1)) |
193 { | 225 { |
194 return true; | 226 return true; |
195 } | 227 } |
196 } | 228 } |
197 | 229 |
201 child != wildcardChildren_.end(); child++) | 233 child != wildcardChildren_.end(); child++) |
202 { | 234 { |
203 HttpHandler::Arguments subComponents = components; | 235 HttpHandler::Arguments subComponents = components; |
204 subComponents[child->first] = uri[level]; | 236 subComponents[child->first] = uri[level]; |
205 | 237 |
206 if (child->second->LookupHandler(components, uri, callback, level + 1, call)) | 238 if (child->second->LookupResource(components, uri, visitor, level + 1)) |
207 { | 239 { |
208 return true; | 240 return true; |
209 } | 241 } |
210 } | 242 } |
211 | 243 |
220 trailing[pos] = uri[i]; | 252 trailing[pos] = uri[i]; |
221 } | 253 } |
222 | 254 |
223 assert(pos == trailing.size()); | 255 assert(pos == trailing.size()); |
224 | 256 |
225 if (callback(universalHandlers_, uri, components, trailing, call)) | 257 if (visitor.Visit(universalHandlers_, uri, components, trailing)) |
226 { | 258 { |
227 return true; | 259 return true; |
228 } | 260 } |
229 } | 261 } |
230 | 262 |
231 return false; | 263 return false; |
264 } | |
265 | |
266 | |
267 bool RestApiHierarchy::CanGenerateDirectory() const | |
268 { | |
269 return (!handlers_.HasHandler(HttpMethod_Get) && | |
270 universalHandlers_.IsEmpty() && | |
271 wildcardChildren_.size() == 0); | |
232 } | 272 } |
233 | 273 |
234 | 274 |
235 bool RestApiHierarchy::GetDirectory(Json::Value& result, | 275 bool RestApiHierarchy::GetDirectory(Json::Value& result, |
236 const UriComponents& uri, | 276 const UriComponents& uri, |
237 size_t level) | 277 size_t level) |
238 { | 278 { |
239 if (uri.size() == level) | 279 if (uri.size() == level) |
240 { | 280 { |
241 if (!handlers_.HasHandler(HttpMethod_Get) && | 281 if (CanGenerateDirectory()) |
242 universalHandlers_.IsEmpty() && | |
243 wildcardChildren_.size() == 0) | |
244 { | 282 { |
245 result = Json::arrayValue; | 283 result = Json::arrayValue; |
246 | 284 |
247 for (Children::const_iterator it = children_.begin(); | 285 for (Children::const_iterator it = children_.begin(); |
248 it != children_.end(); it++) | 286 it != children_.end(); it++) |
278 | 316 |
279 return false; | 317 return false; |
280 } | 318 } |
281 | 319 |
282 | 320 |
283 bool RestApiHierarchy::GetCallback(Handlers& handlers, | |
284 const UriComponents& uri, | |
285 const HttpHandler::Arguments& components, | |
286 const UriComponents& trailing, | |
287 void* call) | |
288 { | |
289 if (handlers.HasHandler(HttpMethod_Get)) | |
290 { | |
291 handlers.GetGetHandler() (*reinterpret_cast<RestApiGetCall*>(call)); | |
292 return true; | |
293 } | |
294 else | |
295 { | |
296 return false; | |
297 } | |
298 } | |
299 | |
300 | |
301 bool RestApiHierarchy::PostCallback(Handlers& handlers, | |
302 const UriComponents& uri, | |
303 const HttpHandler::Arguments& components, | |
304 const UriComponents& trailing, | |
305 void* call) | |
306 { | |
307 if (handlers.HasHandler(HttpMethod_Post)) | |
308 { | |
309 handlers.GetPostHandler() (*reinterpret_cast<RestApiPostCall*>(call)); | |
310 return true; | |
311 } | |
312 else | |
313 { | |
314 return false; | |
315 } | |
316 } | |
317 | |
318 | |
319 bool RestApiHierarchy::PutCallback(Handlers& handlers, | |
320 const UriComponents& uri, | |
321 const HttpHandler::Arguments& components, | |
322 const UriComponents& trailing, | |
323 void* call) | |
324 { | |
325 if (handlers.HasHandler(HttpMethod_Put)) | |
326 { | |
327 handlers.GetPutHandler() (*reinterpret_cast<RestApiPutCall*>(call)); | |
328 return true; | |
329 } | |
330 else | |
331 { | |
332 return false; | |
333 } | |
334 } | |
335 | |
336 | |
337 bool RestApiHierarchy::DeleteCallback(Handlers& handlers, | |
338 const UriComponents& uri, | |
339 const HttpHandler::Arguments& components, | |
340 const UriComponents& trailing, | |
341 void* call) | |
342 { | |
343 if (handlers.HasHandler(HttpMethod_Delete)) | |
344 { | |
345 handlers.GetDeleteHandler() (*reinterpret_cast<RestApiDeleteCall*>(call)); | |
346 return true; | |
347 } | |
348 else | |
349 { | |
350 return false; | |
351 } | |
352 } | |
353 | |
354 | |
355 RestApiHierarchy::~RestApiHierarchy() | 321 RestApiHierarchy::~RestApiHierarchy() |
356 { | 322 { |
357 DeleteChildren(children_); | 323 DeleteChildren(children_); |
358 DeleteChildren(wildcardChildren_); | 324 DeleteChildren(wildcardChildren_); |
359 } | 325 } |
388 | 354 |
389 void RestApiHierarchy::CreateSiteMap(Json::Value& target) const | 355 void RestApiHierarchy::CreateSiteMap(Json::Value& target) const |
390 { | 356 { |
391 if (children_.size() == 0) | 357 if (children_.size() == 0) |
392 { | 358 { |
393 std::string s = " "; | 359 /*std::string s = " "; |
394 if (handlers_.HasHandler(HttpMethod_Get)) | 360 if (handlers_.HasHandler(HttpMethod_Get)) |
395 { | 361 { |
396 s += "GET "; | 362 s += "GET "; |
397 } | 363 } |
398 | 364 |
409 if (handlers_.HasHandler(HttpMethod_Delete)) | 375 if (handlers_.HasHandler(HttpMethod_Delete)) |
410 { | 376 { |
411 s += "DELETE "; | 377 s += "DELETE "; |
412 } | 378 } |
413 | 379 |
414 target = s; | 380 target = s;*/ |
381 | |
382 target = Json::objectValue; | |
415 } | 383 } |
416 else | 384 else |
417 { | 385 { |
418 target = Json::objectValue; | 386 target = Json::objectValue; |
419 | 387 |
429 { | 397 { |
430 it->second->CreateSiteMap(target["* (" + it->first + ")"]); | 398 it->second->CreateSiteMap(target["* (" + it->first + ")"]); |
431 }*/ | 399 }*/ |
432 } | 400 } |
433 | 401 |
434 bool RestApiHierarchy::Handle(RestApiGetCall& call, | 402 |
435 const UriComponents& uri) | 403 bool RestApiHierarchy::LookupResource(const UriComponents& uri, |
404 IVisitor& visitor) | |
436 { | 405 { |
437 HttpHandler::Arguments components; | 406 HttpHandler::Arguments components; |
438 return LookupHandler(components, uri, GetCallback, 0, &call); | 407 return LookupResource(components, uri, visitor, 0); |
439 } | 408 } |
440 | 409 |
441 bool RestApiHierarchy::Handle(RestApiPutCall& call, | 410 |
442 const UriComponents& uri) | 411 |
412 namespace | |
413 { | |
414 // Anonymous namespace to avoid clashes between compilation modules | |
415 | |
416 class AcceptedMethodsVisitor : public RestApiHierarchy::IVisitor | |
417 { | |
418 private: | |
419 std::set<HttpMethod>& methods_; | |
420 | |
421 public: | |
422 AcceptedMethodsVisitor(std::set<HttpMethod>& methods) : methods_(methods) | |
423 { | |
424 } | |
425 | |
426 virtual bool Visit(const RestApiHierarchy::Resource& resource, | |
427 const UriComponents& uri, | |
428 const HttpHandler::Arguments& components, | |
429 const UriComponents& trailing) | |
430 { | |
431 if (trailing.size() == 0) // Ignore universal handlers | |
432 { | |
433 if (resource.HasHandler(HttpMethod_Get)) | |
434 { | |
435 methods_.insert(HttpMethod_Get); | |
436 } | |
437 | |
438 if (resource.HasHandler(HttpMethod_Post)) | |
439 { | |
440 methods_.insert(HttpMethod_Post); | |
441 } | |
442 | |
443 if (resource.HasHandler(HttpMethod_Put)) | |
444 { | |
445 methods_.insert(HttpMethod_Put); | |
446 } | |
447 | |
448 if (resource.HasHandler(HttpMethod_Delete)) | |
449 { | |
450 methods_.insert(HttpMethod_Delete); | |
451 } | |
452 } | |
453 | |
454 return false; // Continue to check all the possible ways to access this URI | |
455 } | |
456 }; | |
457 } | |
458 | |
459 void RestApiHierarchy::GetAcceptedMethods(std::set<HttpMethod>& methods, | |
460 const UriComponents& uri) | |
443 { | 461 { |
444 HttpHandler::Arguments components; | 462 HttpHandler::Arguments components; |
445 return LookupHandler(components, uri, PutCallback, 0, &call); | 463 AcceptedMethodsVisitor visitor(methods); |
446 } | 464 LookupResource(components, uri, visitor, 0); |
447 | 465 |
448 bool RestApiHierarchy::Handle(RestApiPostCall& call, | 466 Json::Value d; |
449 const UriComponents& uri) | 467 if (GetDirectory(d, uri)) |
450 { | 468 { |
451 HttpHandler::Arguments components; | 469 methods.insert(HttpMethod_Get); |
452 return LookupHandler(components, uri, PostCallback, 0, &call); | 470 } |
453 } | 471 } |
454 | |
455 bool RestApiHierarchy::Handle(RestApiDeleteCall& call, | |
456 const UriComponents& uri) | |
457 { | |
458 HttpHandler::Arguments components; | |
459 return LookupHandler(components, uri, DeleteCallback, 0, &call); | |
460 } | |
461 | |
462 } | 472 } |