comparison OrthancServer/Sources/ServerEnumerations.cpp @ 4044:d25f4c0fa160 framework

splitting code into OrthancFramework and OrthancServer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 10 Jun 2020 20:30:34 +0200
parents OrthancServer/ServerEnumerations.cpp@5d2348b39392
children 05b8fd21089c
comparison
equal deleted inserted replaced
4043:6c6239aec462 4044:d25f4c0fa160
1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
11 *
12 * In addition, as a special exception, the copyright holders of this
13 * program give permission to link the code of its release with the
14 * OpenSSL project's "OpenSSL" library (or with modified versions of it
15 * that use the same license as the "OpenSSL" library), and distribute
16 * the linked executables. You must obey the GNU General Public License
17 * in all respects for all of the code used other than "OpenSSL". If you
18 * modify file(s) with this exception, you may extend this exception to
19 * your version of the file(s), but you are not obligated to do so. If
20 * you do not wish to do so, delete this exception statement from your
21 * version. If you delete this exception statement from all source files
22 * in the program, then also delete it here.
23 *
24 * This program is distributed in the hope that it will be useful, but
25 * WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31 **/
32
33
34 #include "PrecompiledHeadersServer.h"
35 #include "ServerEnumerations.h"
36
37 #include "../Core/OrthancException.h"
38 #include "../Core/EnumerationDictionary.h"
39 #include "../Core/Logging.h"
40 #include "../Core/Toolbox.h"
41
42 #include <boost/thread.hpp>
43
44 namespace Orthanc
45 {
46 typedef std::map<FileContentType, std::string> MimeTypes;
47
48 static boost::mutex enumerationsMutex_;
49 static EnumerationDictionary<MetadataType> dictMetadataType_;
50 static EnumerationDictionary<FileContentType> dictContentType_;
51 static MimeTypes mimeTypes_;
52
53 void InitializeServerEnumerations()
54 {
55 boost::mutex::scoped_lock lock(enumerationsMutex_);
56
57 dictMetadataType_.Clear();
58 dictContentType_.Clear();
59
60 dictMetadataType_.Add(MetadataType_Instance_IndexInSeries, "IndexInSeries");
61 dictMetadataType_.Add(MetadataType_Instance_ReceptionDate, "ReceptionDate");
62 dictMetadataType_.Add(MetadataType_Instance_RemoteAet, "RemoteAET");
63 dictMetadataType_.Add(MetadataType_Series_ExpectedNumberOfInstances, "ExpectedNumberOfInstances");
64 dictMetadataType_.Add(MetadataType_ModifiedFrom, "ModifiedFrom");
65 dictMetadataType_.Add(MetadataType_AnonymizedFrom, "AnonymizedFrom");
66 dictMetadataType_.Add(MetadataType_LastUpdate, "LastUpdate");
67 dictMetadataType_.Add(MetadataType_Instance_Origin, "Origin");
68 dictMetadataType_.Add(MetadataType_Instance_TransferSyntax, "TransferSyntax");
69 dictMetadataType_.Add(MetadataType_Instance_SopClassUid, "SopClassUid");
70 dictMetadataType_.Add(MetadataType_Instance_RemoteIp, "RemoteIP");
71 dictMetadataType_.Add(MetadataType_Instance_CalledAet, "CalledAET");
72 dictMetadataType_.Add(MetadataType_Instance_HttpUsername, "HttpUsername");
73
74 dictContentType_.Add(FileContentType_Dicom, "dicom");
75 dictContentType_.Add(FileContentType_DicomAsJson, "dicom-as-json");
76 }
77
78 void RegisterUserMetadata(int metadata,
79 const std::string& name)
80 {
81 boost::mutex::scoped_lock lock(enumerationsMutex_);
82
83 MetadataType type = static_cast<MetadataType>(metadata);
84
85 if (metadata < 0 ||
86 !IsUserMetadata(type))
87 {
88 LOG(ERROR) << "A user content type must have index between "
89 << static_cast<int>(MetadataType_StartUser) << " and "
90 << static_cast<int>(MetadataType_EndUser) << ", but \""
91 << name << "\" has index " << metadata;
92
93 throw OrthancException(ErrorCode_ParameterOutOfRange);
94 }
95
96 if (dictMetadataType_.Contains(type))
97 {
98 LOG(ERROR) << "Cannot associate user content type \""
99 << name << "\" with index " << metadata
100 << ", as this index is already used";
101
102 throw OrthancException(ErrorCode_ParameterOutOfRange);
103 }
104
105 dictMetadataType_.Add(type, name);
106 }
107
108 std::string EnumerationToString(MetadataType type)
109 {
110 // This function MUST return a "std::string" and not "const
111 // char*", as the result is not a static string
112 boost::mutex::scoped_lock lock(enumerationsMutex_);
113 return dictMetadataType_.Translate(type);
114 }
115
116 MetadataType StringToMetadata(const std::string& str)
117 {
118 boost::mutex::scoped_lock lock(enumerationsMutex_);
119 return dictMetadataType_.Translate(str);
120 }
121
122 void RegisterUserContentType(int contentType,
123 const std::string& name,
124 const std::string& mime)
125 {
126 boost::mutex::scoped_lock lock(enumerationsMutex_);
127
128 FileContentType type = static_cast<FileContentType>(contentType);
129
130 if (contentType < 0 ||
131 !IsUserContentType(type))
132 {
133 LOG(ERROR) << "A user content type must have index between "
134 << static_cast<int>(FileContentType_StartUser) << " and "
135 << static_cast<int>(FileContentType_EndUser) << ", but \""
136 << name << "\" has index " << contentType;
137
138 throw OrthancException(ErrorCode_ParameterOutOfRange);
139 }
140
141 if (dictContentType_.Contains(type))
142 {
143 LOG(ERROR) << "Cannot associate user content type \""
144 << name << "\" with index " << contentType
145 << ", as this index is already used";
146
147 throw OrthancException(ErrorCode_ParameterOutOfRange);
148 }
149
150 dictContentType_.Add(type, name);
151 mimeTypes_[type] = mime;
152 }
153
154 std::string EnumerationToString(FileContentType type)
155 {
156 // This function MUST return a "std::string" and not "const
157 // char*", as the result is not a static string
158 boost::mutex::scoped_lock lock(enumerationsMutex_);
159 return dictContentType_.Translate(type);
160 }
161
162 std::string GetFileContentMime(FileContentType type)
163 {
164 if (type >= FileContentType_StartUser &&
165 type <= FileContentType_EndUser)
166 {
167 boost::mutex::scoped_lock lock(enumerationsMutex_);
168
169 MimeTypes::const_iterator it = mimeTypes_.find(type);
170 if (it != mimeTypes_.end())
171 {
172 return it->second;
173 }
174 }
175
176 switch (type)
177 {
178 case FileContentType_Dicom:
179 return EnumerationToString(MimeType_Dicom);
180
181 case FileContentType_DicomAsJson:
182 return MIME_JSON_UTF8;
183
184 default:
185 return EnumerationToString(MimeType_Binary);
186 }
187 }
188
189 FileContentType StringToContentType(const std::string& str)
190 {
191 boost::mutex::scoped_lock lock(enumerationsMutex_);
192 return dictContentType_.Translate(str);
193 }
194
195
196 FindStorageAccessMode StringToFindStorageAccessMode(const std::string& value)
197 {
198 if (value == "Always")
199 {
200 return FindStorageAccessMode_DiskOnLookupAndAnswer;
201 }
202 else if (value == "Never")
203 {
204 return FindStorageAccessMode_DatabaseOnly;
205 }
206 else if (value == "Answers")
207 {
208 return FindStorageAccessMode_DiskOnAnswer;
209 }
210 else
211 {
212 throw OrthancException(ErrorCode_ParameterOutOfRange,
213 "Configuration option \"StorageAccessOnFind\" "
214 "should be \"Always\", \"Never\" or \"Answers\": " + value);
215 }
216 }
217
218
219 BuiltinDecoderTranscoderOrder StringToBuiltinDecoderTranscoderOrder(const std::string& value)
220 {
221 if (value == "Before")
222 {
223 return BuiltinDecoderTranscoderOrder_Before;
224 }
225 else if (value == "After")
226 {
227 return BuiltinDecoderTranscoderOrder_After;
228 }
229 else if (value == "Disabled")
230 {
231 return BuiltinDecoderTranscoderOrder_Disabled;
232 }
233 else
234 {
235 throw OrthancException(ErrorCode_ParameterOutOfRange,
236 "Configuration option \"BuiltinDecoderTranscoderOrder\" "
237 "should be \"After\", \"Before\" or \"Disabled\": " + value);
238 }
239 }
240
241
242 std::string GetBasePath(ResourceType type,
243 const std::string& publicId)
244 {
245 switch (type)
246 {
247 case ResourceType_Patient:
248 return "/patients/" + publicId;
249
250 case ResourceType_Study:
251 return "/studies/" + publicId;
252
253 case ResourceType_Series:
254 return "/series/" + publicId;
255
256 case ResourceType_Instance:
257 return "/instances/" + publicId;
258
259 default:
260 throw OrthancException(ErrorCode_ParameterOutOfRange);
261 }
262 }
263
264 const char* EnumerationToString(SeriesStatus status)
265 {
266 switch (status)
267 {
268 case SeriesStatus_Complete:
269 return "Complete";
270
271 case SeriesStatus_Missing:
272 return "Missing";
273
274 case SeriesStatus_Inconsistent:
275 return "Inconsistent";
276
277 case SeriesStatus_Unknown:
278 return "Unknown";
279
280 default:
281 throw OrthancException(ErrorCode_ParameterOutOfRange);
282 }
283 }
284
285 const char* EnumerationToString(StoreStatus status)
286 {
287 switch (status)
288 {
289 case StoreStatus_Success:
290 return "Success";
291
292 case StoreStatus_AlreadyStored:
293 return "AlreadyStored";
294
295 case StoreStatus_Failure:
296 return "Failure";
297
298 case StoreStatus_FilteredOut:
299 return "FilteredOut";
300
301 default:
302 throw OrthancException(ErrorCode_ParameterOutOfRange);
303 }
304 }
305
306
307 const char* EnumerationToString(ChangeType type)
308 {
309 switch (type)
310 {
311 case ChangeType_CompletedSeries:
312 return "CompletedSeries";
313
314 case ChangeType_NewInstance:
315 return "NewInstance";
316
317 case ChangeType_NewPatient:
318 return "NewPatient";
319
320 case ChangeType_NewSeries:
321 return "NewSeries";
322
323 case ChangeType_NewStudy:
324 return "NewStudy";
325
326 case ChangeType_AnonymizedStudy:
327 return "AnonymizedStudy";
328
329 case ChangeType_AnonymizedSeries:
330 return "AnonymizedSeries";
331
332 case ChangeType_ModifiedStudy:
333 return "ModifiedStudy";
334
335 case ChangeType_ModifiedSeries:
336 return "ModifiedSeries";
337
338 case ChangeType_AnonymizedPatient:
339 return "AnonymizedPatient";
340
341 case ChangeType_ModifiedPatient:
342 return "ModifiedPatient";
343
344 case ChangeType_StablePatient:
345 return "StablePatient";
346
347 case ChangeType_StableStudy:
348 return "StableStudy";
349
350 case ChangeType_StableSeries:
351 return "StableSeries";
352
353 case ChangeType_Deleted:
354 return "Deleted";
355
356 case ChangeType_NewChildInstance:
357 return "NewChildInstance";
358
359 case ChangeType_UpdatedAttachment:
360 return "UpdatedAttachment";
361
362 case ChangeType_UpdatedMetadata:
363 return "UpdatedMetadata";
364
365 default:
366 throw OrthancException(ErrorCode_ParameterOutOfRange);
367 }
368 }
369
370
371 bool IsUserMetadata(MetadataType metadata)
372 {
373 return (metadata >= MetadataType_StartUser &&
374 metadata <= MetadataType_EndUser);
375 }
376 }