Mercurial > hg > orthanc
annotate OrthancFramework/Sources/RestApi/RestApiHierarchy.cpp @ 4844:55e8fb8e8028
tagging a pre-release of the Orthanc framework for WSI 1.1
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 07 Dec 2021 14:01:17 +0100 |
parents | 7053502fbf97 |
children | 43e613a7756b |
rev | line source |
---|---|
969 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
1900 | 3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics |
1288
6e7e5ed91c2d
upgrade to year 2015
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1063
diff
changeset
|
4 * Department, University Hospital of Liege, Belgium |
4437
d9473bd5ed43
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4401
diff
changeset
|
5 * Copyright (C) 2017-2021 Osimis S.A., Belgium |
4831
7053502fbf97
added copyright UCLouvain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
6 * Copyright (C) 2021-2021 Sebastien Jodogne, ICTEAM UCLouvain, Belgium |
969 | 7 * |
8 * This program is free software: you can redistribute it and/or | |
4119
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
9 * modify it under the terms of the GNU Lesser General Public License |
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
10 * as published by the Free Software Foundation, either version 3 of |
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
11 * the License, or (at your option) any later version. |
969 | 12 * |
13 * This program is distributed in the hope that it will be useful, but | |
14 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
4119
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
16 * Lesser General Public License for more details. |
969 | 17 * |
4119
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
18 * You should have received a copy of the GNU Lesser General Public |
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
19 * License along with this program. If not, see |
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
20 * <http://www.gnu.org/licenses/>. |
969 | 21 **/ |
22 | |
23 | |
1624
0a2ad4a6858f
fix missing precompiled headers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1444
diff
changeset
|
24 #include "../PrecompiledHeaders.h" |
969 | 25 #include "RestApiHierarchy.h" |
26 | |
975 | 27 #include "../OrthancException.h" |
28 | |
969 | 29 #include <cassert> |
1063
0332e6e8c679
Fix automated generation of the list of resource children in the REST API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
980
diff
changeset
|
30 #include <stdio.h> |
969 | 31 |
32 namespace Orthanc | |
33 { | |
978 | 34 RestApiHierarchy::Resource::Resource() : |
972 | 35 getHandler_(NULL), |
36 postHandler_(NULL), | |
37 putHandler_(NULL), | |
38 deleteHandler_(NULL) | |
39 { | |
40 } | |
41 | |
42 | |
4400 | 43 bool RestApiHierarchy::Resource::HasHandler(HttpMethod method) const |
972 | 44 { |
45 switch (method) | |
46 { | |
47 case HttpMethod_Get: | |
48 return getHandler_ != NULL; | |
49 | |
50 case HttpMethod_Post: | |
51 return postHandler_ != NULL; | |
52 | |
53 case HttpMethod_Put: | |
54 return putHandler_ != NULL; | |
55 | |
56 case HttpMethod_Delete: | |
57 return deleteHandler_ != NULL; | |
58 | |
59 default: | |
60 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
61 } | |
62 } | |
63 | |
64 | |
4300 | 65 void RestApiHierarchy::Resource::Register(RestApiGetCall::Handler handler) |
66 { | |
67 getHandler_ = handler; | |
68 } | |
69 | |
70 void RestApiHierarchy::Resource::Register(RestApiPutCall::Handler handler) | |
71 { | |
72 putHandler_ = handler; | |
73 } | |
74 | |
75 void RestApiHierarchy::Resource::Register(RestApiPostCall::Handler handler) | |
76 { | |
77 postHandler_ = handler; | |
78 } | |
79 | |
80 void RestApiHierarchy::Resource::Register(RestApiDeleteCall::Handler handler) | |
81 { | |
82 deleteHandler_ = handler; | |
83 } | |
84 | |
85 | |
978 | 86 bool RestApiHierarchy::Resource::IsEmpty() const |
969 | 87 { |
972 | 88 return (getHandler_ == NULL && |
89 postHandler_ == NULL && | |
90 putHandler_ == NULL && | |
91 deleteHandler_ == NULL); | |
92 } | |
93 | |
94 | |
969 | 95 RestApiHierarchy& RestApiHierarchy::AddChild(Children& children, |
96 const std::string& name) | |
97 { | |
98 Children::iterator it = children.find(name); | |
99 | |
100 if (it == children.end()) | |
101 { | |
102 // Create new child | |
103 RestApiHierarchy *child = new RestApiHierarchy; | |
104 children[name] = child; | |
105 return *child; | |
106 } | |
107 else | |
108 { | |
109 return *it->second; | |
110 } | |
111 } | |
112 | |
113 | |
978 | 114 |
115 bool RestApiHierarchy::Resource::Handle(RestApiGetCall& call) const | |
116 { | |
117 if (getHandler_ != NULL) | |
118 { | |
119 getHandler_(call); | |
120 return true; | |
121 } | |
122 else | |
123 { | |
124 return false; | |
125 } | |
126 } | |
127 | |
128 | |
129 bool RestApiHierarchy::Resource::Handle(RestApiPutCall& call) const | |
130 { | |
131 if (putHandler_ != NULL) | |
132 { | |
133 putHandler_(call); | |
134 return true; | |
135 } | |
136 else | |
137 { | |
138 return false; | |
139 } | |
140 } | |
141 | |
142 | |
143 bool RestApiHierarchy::Resource::Handle(RestApiPostCall& call) const | |
144 { | |
145 if (postHandler_ != NULL) | |
146 { | |
147 postHandler_(call); | |
148 return true; | |
149 } | |
150 else | |
151 { | |
152 return false; | |
153 } | |
154 } | |
155 | |
156 | |
157 bool RestApiHierarchy::Resource::Handle(RestApiDeleteCall& call) const | |
158 { | |
159 if (deleteHandler_ != NULL) | |
160 { | |
161 deleteHandler_(call); | |
162 return true; | |
163 } | |
164 else | |
165 { | |
166 return false; | |
167 } | |
168 } | |
169 | |
170 | |
969 | 171 void RestApiHierarchy::DeleteChildren(Children& children) |
172 { | |
173 for (Children::iterator it = children.begin(); | |
1303 | 174 it != children.end(); ++it) |
969 | 175 { |
176 delete it->second; | |
177 } | |
178 } | |
179 | |
180 | |
181 template <typename Handler> | |
182 void RestApiHierarchy::RegisterInternal(const RestApiPath& path, | |
183 Handler handler, | |
184 size_t level) | |
185 { | |
186 if (path.GetLevelCount() == level) | |
187 { | |
188 if (path.IsUniversalTrailing()) | |
189 { | |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
190 handlersWithTrailing_.Register(handler); |
969 | 191 } |
192 else | |
193 { | |
194 handlers_.Register(handler); | |
195 } | |
196 } | |
197 else | |
198 { | |
199 RestApiHierarchy* child; | |
200 if (path.IsWildcardLevel(level)) | |
201 { | |
202 child = &AddChild(wildcardChildren_, path.GetWildcardName(level)); | |
203 } | |
204 else | |
205 { | |
206 child = &AddChild(children_, path.GetLevelName(level)); | |
207 } | |
208 | |
209 child->RegisterInternal(path, handler, level + 1); | |
210 } | |
211 } | |
212 | |
213 | |
4330
a01b1c9cbef4
moving generic type definitions from IHttpHandler to HttpToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4303
diff
changeset
|
214 bool RestApiHierarchy::LookupResource(HttpToolbox::Arguments& components, |
a01b1c9cbef4
moving generic type definitions from IHttpHandler to HttpToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4303
diff
changeset
|
215 const UriComponents& uri, |
a01b1c9cbef4
moving generic type definitions from IHttpHandler to HttpToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4303
diff
changeset
|
216 IVisitor& visitor, |
a01b1c9cbef4
moving generic type definitions from IHttpHandler to HttpToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4303
diff
changeset
|
217 size_t level) |
969 | 218 { |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
219 if (uri.size() != 0 && |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
220 level > uri.size()) |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
221 { |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
222 return false; |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
223 } |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
224 |
969 | 225 // Look for an exact match on the resource of interest |
4330
a01b1c9cbef4
moving generic type definitions from IHttpHandler to HttpToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4303
diff
changeset
|
226 if (uri.size() == 0 || |
a01b1c9cbef4
moving generic type definitions from IHttpHandler to HttpToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4303
diff
changeset
|
227 level == uri.size()) |
969 | 228 { |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
229 UriComponents noTrailing; |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
230 |
969 | 231 if (!handlers_.IsEmpty() && |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
232 visitor.Visit(handlers_, uri, false, components, noTrailing)) |
969 | 233 { |
234 return true; | |
235 } | |
236 } | |
237 | |
238 | |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
239 if (level < uri.size()) // A recursive call is possible |
969 | 240 { |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
241 // Try and go down in the hierarchy, using an exact match for the child |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
242 Children::const_iterator child = children_.find(uri[level]); |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
243 if (child != children_.end()) |
969 | 244 { |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
245 if (child->second->LookupResource(components, uri, visitor, level + 1)) |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
246 { |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
247 return true; |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
248 } |
969 | 249 } |
250 | |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
251 // Try and go down in the hierarchy, using wildcard rules for children |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
252 for (child = wildcardChildren_.begin(); |
1303 | 253 child != wildcardChildren_.end(); ++child) |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
254 { |
4330
a01b1c9cbef4
moving generic type definitions from IHttpHandler to HttpToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4303
diff
changeset
|
255 HttpToolbox::Arguments subComponents = components; |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
256 subComponents[child->first] = uri[level]; |
969 | 257 |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
258 if (child->second->LookupResource(subComponents, uri, visitor, level + 1)) |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
259 { |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
260 return true; |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
261 } |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
262 } |
969 | 263 } |
264 | |
265 | |
266 // As a last resort, call the universal handlers, if any | |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
267 if (!handlersWithTrailing_.IsEmpty()) |
969 | 268 { |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
269 UriComponents trailing; |
969 | 270 trailing.resize(uri.size() - level); |
271 size_t pos = 0; | |
272 for (size_t i = level; i < uri.size(); i++, pos++) | |
273 { | |
274 trailing[pos] = uri[i]; | |
275 } | |
276 | |
277 assert(pos == trailing.size()); | |
278 | |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
279 if (visitor.Visit(handlersWithTrailing_, uri, true, components, trailing)) |
969 | 280 { |
281 return true; | |
282 } | |
283 } | |
284 | |
285 return false; | |
286 } | |
287 | |
288 | |
978 | 289 bool RestApiHierarchy::CanGenerateDirectory() const |
290 { | |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
291 return (handlersWithTrailing_.IsEmpty() && |
1303 | 292 wildcardChildren_.empty()); |
978 | 293 } |
294 | |
295 | |
969 | 296 bool RestApiHierarchy::GetDirectory(Json::Value& result, |
297 const UriComponents& uri, | |
298 size_t level) | |
299 { | |
300 if (uri.size() == level) | |
301 { | |
978 | 302 if (CanGenerateDirectory()) |
969 | 303 { |
304 result = Json::arrayValue; | |
305 | |
306 for (Children::const_iterator it = children_.begin(); | |
1303 | 307 it != children_.end(); ++it) |
969 | 308 { |
309 result.append(it->first); | |
310 } | |
311 | |
312 return true; | |
313 } | |
314 else | |
315 { | |
316 return false; | |
317 } | |
318 } | |
319 | |
320 Children::const_iterator child = children_.find(uri[level]); | |
321 if (child != children_.end()) | |
322 { | |
323 if (child->second->GetDirectory(result, uri, level + 1)) | |
324 { | |
325 return true; | |
326 } | |
327 } | |
328 | |
329 for (child = wildcardChildren_.begin(); | |
1303 | 330 child != wildcardChildren_.end(); ++child) |
969 | 331 { |
332 if (child->second->GetDirectory(result, uri, level + 1)) | |
333 { | |
334 return true; | |
335 } | |
336 } | |
337 | |
338 return false; | |
339 } | |
340 | |
341 | |
342 RestApiHierarchy::~RestApiHierarchy() | |
343 { | |
344 DeleteChildren(children_); | |
345 DeleteChildren(wildcardChildren_); | |
346 } | |
347 | |
970 | 348 void RestApiHierarchy::Register(const std::string& uri, |
974 | 349 RestApiGetCall::Handler handler) |
969 | 350 { |
970 | 351 RestApiPath path(uri); |
969 | 352 RegisterInternal(path, handler, 0); |
353 } | |
354 | |
970 | 355 void RestApiHierarchy::Register(const std::string& uri, |
974 | 356 RestApiPutCall::Handler handler) |
969 | 357 { |
970 | 358 RestApiPath path(uri); |
969 | 359 RegisterInternal(path, handler, 0); |
360 } | |
361 | |
970 | 362 void RestApiHierarchy::Register(const std::string& uri, |
974 | 363 RestApiPostCall::Handler handler) |
969 | 364 { |
970 | 365 RestApiPath path(uri); |
969 | 366 RegisterInternal(path, handler, 0); |
367 } | |
368 | |
970 | 369 void RestApiHierarchy::Register(const std::string& uri, |
974 | 370 RestApiDeleteCall::Handler handler) |
969 | 371 { |
970 | 372 RestApiPath path(uri); |
969 | 373 RegisterInternal(path, handler, 0); |
374 } | |
375 | |
376 void RestApiHierarchy::CreateSiteMap(Json::Value& target) const | |
377 { | |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
378 target = Json::objectValue; |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
379 |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
380 /*std::string s = " "; |
4400 | 381 if (handlers_.HasHandler(HttpMethod_Get)) |
969 | 382 { |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
383 s += "GET "; |
969 | 384 } |
385 | |
4400 | 386 if (handlers_.HasHandler(HttpMethod_Post)) |
969 | 387 { |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
388 s += "POST "; |
969 | 389 } |
390 | |
4400 | 391 if (handlers_.HasHandler(HttpMethod_Put)) |
969 | 392 { |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
393 s += "PUT "; |
969 | 394 } |
395 | |
4400 | 396 if (handlers_.HasHandler(HttpMethod_Delete)) |
969 | 397 { |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
398 s += "DELETE "; |
969 | 399 } |
400 | |
978 | 401 target = s;*/ |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
402 |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
403 for (Children::const_iterator it = children_.begin(); |
1303 | 404 it != children_.end(); ++it) |
969 | 405 { |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
406 it->second->CreateSiteMap(target[it->first]); |
969 | 407 } |
408 | |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
409 for (Children::const_iterator it = wildcardChildren_.begin(); |
1303 | 410 it != wildcardChildren_.end(); ++it) |
980
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
411 { |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
412 it->second->CreateSiteMap(target["<" + it->first + ">"]); |
f1ff2a2f06cd
use RestApiHierarchy inside RestApi
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
978
diff
changeset
|
413 } |
969 | 414 } |
415 | |
4300 | 416 bool RestApiHierarchy::GetDirectory(Json::Value &result, const UriComponents &uri) |
417 { | |
418 return GetDirectory(result, uri, 0); | |
419 } | |
420 | |
978 | 421 |
422 bool RestApiHierarchy::LookupResource(const UriComponents& uri, | |
423 IVisitor& visitor) | |
969 | 424 { |
4330
a01b1c9cbef4
moving generic type definitions from IHttpHandler to HttpToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4303
diff
changeset
|
425 HttpToolbox::Arguments components; |
978 | 426 return LookupResource(components, uri, visitor, 0); |
969 | 427 } |
428 | |
978 | 429 |
430 | |
431 namespace | |
432 { | |
433 // Anonymous namespace to avoid clashes between compilation modules | |
434 | |
435 class AcceptedMethodsVisitor : public RestApiHierarchy::IVisitor | |
436 { | |
437 private: | |
438 std::set<HttpMethod>& methods_; | |
439 | |
440 public: | |
4203
4d42408da117
improving const-correctness in ParsedDicomFile
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4119
diff
changeset
|
441 explicit AcceptedMethodsVisitor(std::set<HttpMethod>& methods) : |
4d42408da117
improving const-correctness in ParsedDicomFile
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4119
diff
changeset
|
442 methods_(methods) |
978 | 443 { |
444 } | |
445 | |
446 virtual bool Visit(const RestApiHierarchy::Resource& resource, | |
447 const UriComponents& uri, | |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
448 bool hasTrailing, |
4330
a01b1c9cbef4
moving generic type definitions from IHttpHandler to HttpToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4303
diff
changeset
|
449 const HttpToolbox::Arguments& components, |
978 | 450 const UriComponents& trailing) |
451 { | |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
452 if (!hasTrailing) // Ignore universal handlers |
978 | 453 { |
4400 | 454 if (resource.HasHandler(HttpMethod_Get)) |
978 | 455 { |
456 methods_.insert(HttpMethod_Get); | |
457 } | |
458 | |
4400 | 459 if (resource.HasHandler(HttpMethod_Post)) |
978 | 460 { |
461 methods_.insert(HttpMethod_Post); | |
462 } | |
463 | |
4400 | 464 if (resource.HasHandler(HttpMethod_Put)) |
978 | 465 { |
466 methods_.insert(HttpMethod_Put); | |
467 } | |
468 | |
4400 | 469 if (resource.HasHandler(HttpMethod_Delete)) |
978 | 470 { |
471 methods_.insert(HttpMethod_Delete); | |
472 } | |
473 } | |
474 | |
475 return false; // Continue to check all the possible ways to access this URI | |
476 } | |
477 }; | |
478 } | |
479 | |
480 void RestApiHierarchy::GetAcceptedMethods(std::set<HttpMethod>& methods, | |
481 const UriComponents& uri) | |
969 | 482 { |
4330
a01b1c9cbef4
moving generic type definitions from IHttpHandler to HttpToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4303
diff
changeset
|
483 HttpToolbox::Arguments components; |
978 | 484 AcceptedMethodsVisitor visitor(methods); |
1444
b2b09a3dbd8e
refactoring: OrthancHttpHandler inside OrthancServer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1441
diff
changeset
|
485 if (LookupResource(components, uri, visitor, 0)) |
978 | 486 { |
1444
b2b09a3dbd8e
refactoring: OrthancHttpHandler inside OrthancServer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1441
diff
changeset
|
487 Json::Value d; |
b2b09a3dbd8e
refactoring: OrthancHttpHandler inside OrthancServer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1441
diff
changeset
|
488 if (GetDirectory(d, uri)) |
b2b09a3dbd8e
refactoring: OrthancHttpHandler inside OrthancServer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1441
diff
changeset
|
489 { |
b2b09a3dbd8e
refactoring: OrthancHttpHandler inside OrthancServer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1441
diff
changeset
|
490 methods.insert(HttpMethod_Get); |
b2b09a3dbd8e
refactoring: OrthancHttpHandler inside OrthancServer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1441
diff
changeset
|
491 } |
978 | 492 } |
493 } | |
4300 | 494 |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
495 void RestApiHierarchy::ExploreAllResources(IVisitor& visitor, |
4401
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
496 const UriComponents& path, |
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
497 const std::set<std::string>& uriArguments) const |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
498 { |
4401
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
499 HttpToolbox::Arguments args; |
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
500 |
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
501 for (std::set<std::string>::const_iterator it = uriArguments.begin(); it != uriArguments.end(); ++it) |
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
502 { |
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
503 args[*it] = ""; |
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
504 } |
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
505 |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
506 if (!handlers_.IsEmpty()) |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
507 { |
4401
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
508 visitor.Visit(handlers_, path, false, args, UriComponents()); |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
509 } |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
510 |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
511 if (!handlersWithTrailing_.IsEmpty()) |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
512 { |
4401
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
513 visitor.Visit(handlersWithTrailing_, path, true, args, UriComponents()); |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
514 } |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
515 |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
516 for (Children::const_iterator |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
517 it = children_.begin(); it != children_.end(); ++it) |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
518 { |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
519 assert(it->second != NULL); |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
520 UriComponents c = path; |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
521 c.push_back(it->first); |
4401
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
522 it->second->ExploreAllResources(visitor, c, uriArguments); |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
523 } |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
524 |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
525 for (Children::const_iterator |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
526 it = wildcardChildren_.begin(); it != wildcardChildren_.end(); ++it) |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
527 { |
4401
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
528 if (uriArguments.find(it->first) != uriArguments.end()) |
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
529 { |
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
530 throw OrthancException(ErrorCode_InternalError, "Twice the same URI argument in a path: " + it->first); |
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
531 } |
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
532 |
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
533 std::set<std::string> d = uriArguments; |
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
534 d.insert(it->first); |
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
535 |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
536 assert(it->second != NULL); |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
537 UriComponents c = path; |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
538 c.push_back("{" + it->first + "}"); |
4401
354ea95b294a
documenting system calls
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4400
diff
changeset
|
539 it->second->ExploreAllResources(visitor, c, d); |
4399
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
540 } |
80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4330
diff
changeset
|
541 } |
969 | 542 } |