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 }