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