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