Mercurial > hg > orthanc
comparison OrthancServer/Sources/ServerContext.cpp @ 5568:b0b5546f1b9f find-refactoring
find refactor: re-use existing code. /studies?expand is almost fully implemented with new code
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Thu, 25 Apr 2024 09:22:07 +0200 |
parents | acdb8d78bf99 |
children | 77570cce8855 |
comparison
equal
deleted
inserted
replaced
5567:f3562c1a150d | 5568:b0b5546f1b9f |
---|---|
2123 | 2123 |
2124 | 2124 |
2125 static void SerializeExpandedResource(Json::Value& target, | 2125 static void SerializeExpandedResource(Json::Value& target, |
2126 const ExpandedResource& resource, | 2126 const ExpandedResource& resource, |
2127 DicomToJsonFormat format, | 2127 DicomToJsonFormat format, |
2128 const std::set<DicomTag>& requestedTags) | 2128 const std::set<DicomTag>& requestedTags, |
2129 ExpandResourceFlags expandFlags) | |
2129 { | 2130 { |
2130 target = Json::objectValue; | 2131 target = Json::objectValue; |
2131 | 2132 |
2132 target["Type"] = GetResourceTypeText(resource.GetLevel(), false, true); | 2133 target["Type"] = GetResourceTypeText(resource.GetLevel(), false, true); |
2133 target["ID"] = resource.GetPublicId(); | 2134 target["ID"] = resource.GetPublicId(); |
2134 | 2135 |
2135 switch (resource.GetLevel()) | 2136 if (!resource.parentId_.empty()) |
2136 { | 2137 { |
2137 case ResourceType_Patient: | 2138 switch (resource.GetLevel()) |
2138 break; | 2139 { |
2139 | 2140 case ResourceType_Patient: |
2140 case ResourceType_Study: | 2141 break; |
2141 target["ParentPatient"] = resource.parentId_; | 2142 |
2142 break; | 2143 case ResourceType_Study: |
2143 | 2144 target["ParentPatient"] = resource.parentId_; |
2144 case ResourceType_Series: | 2145 break; |
2145 target["ParentStudy"] = resource.parentId_; | 2146 |
2146 break; | 2147 case ResourceType_Series: |
2147 | 2148 target["ParentStudy"] = resource.parentId_; |
2148 case ResourceType_Instance: | 2149 break; |
2149 target["ParentSeries"] = resource.parentId_; | 2150 |
2150 break; | 2151 case ResourceType_Instance: |
2151 | 2152 target["ParentSeries"] = resource.parentId_; |
2152 default: | 2153 break; |
2153 throw OrthancException(ErrorCode_InternalError); | 2154 |
2154 } | 2155 default: |
2155 | 2156 throw OrthancException(ErrorCode_InternalError); |
2156 switch (resource.GetLevel()) | 2157 } |
2157 { | 2158 } |
2158 case ResourceType_Patient: | 2159 |
2159 case ResourceType_Study: | 2160 if ((expandFlags & ExpandResourceFlags_IncludeChildren) != 0) |
2160 case ResourceType_Series: | 2161 { |
2161 { | 2162 switch (resource.GetLevel()) |
2162 Json::Value c = Json::arrayValue; | 2163 { |
2163 | 2164 case ResourceType_Patient: |
2164 for (std::list<std::string>::const_iterator | 2165 case ResourceType_Study: |
2165 it = resource.childrenIds_.begin(); it != resource.childrenIds_.end(); ++it) | 2166 case ResourceType_Series: |
2166 { | 2167 { |
2167 c.append(*it); | 2168 Json::Value c = Json::arrayValue; |
2168 } | 2169 |
2169 | 2170 for (std::list<std::string>::const_iterator |
2170 if (resource.GetLevel() == ResourceType_Patient) | 2171 it = resource.childrenIds_.begin(); it != resource.childrenIds_.end(); ++it) |
2171 { | 2172 { |
2172 target["Studies"] = c; | 2173 c.append(*it); |
2173 } | 2174 } |
2174 else if (resource.GetLevel() == ResourceType_Study) | 2175 |
2175 { | 2176 if (resource.GetLevel() == ResourceType_Patient) |
2176 target["Series"] = c; | 2177 { |
2177 } | 2178 target["Studies"] = c; |
2178 else | 2179 } |
2179 { | 2180 else if (resource.GetLevel() == ResourceType_Study) |
2180 target["Instances"] = c; | 2181 { |
2181 } | 2182 target["Series"] = c; |
2182 break; | 2183 } |
2183 } | 2184 else |
2184 | 2185 { |
2185 case ResourceType_Instance: | 2186 target["Instances"] = c; |
2186 break; | 2187 } |
2187 | 2188 break; |
2188 default: | 2189 } |
2189 throw OrthancException(ErrorCode_InternalError); | 2190 |
2190 } | 2191 case ResourceType_Instance: |
2191 | 2192 break; |
2192 switch (resource.GetLevel()) | 2193 |
2193 { | 2194 default: |
2194 case ResourceType_Patient: | 2195 throw OrthancException(ErrorCode_InternalError); |
2195 case ResourceType_Study: | 2196 } |
2196 break; | 2197 } |
2197 | 2198 |
2198 case ResourceType_Series: | 2199 if ((expandFlags & ExpandResourceFlags_IncludeMetadata) != 0) |
2199 if (resource.expectedNumberOfInstances_ < 0) | 2200 { |
2200 { | 2201 switch (resource.GetLevel()) |
2201 target["ExpectedNumberOfInstances"] = Json::nullValue; | 2202 { |
2202 } | 2203 case ResourceType_Patient: |
2203 else | 2204 case ResourceType_Study: |
2204 { | 2205 break; |
2205 target["ExpectedNumberOfInstances"] = resource.expectedNumberOfInstances_; | 2206 |
2206 } | 2207 case ResourceType_Series: |
2207 target["Status"] = resource.status_; | 2208 if (resource.expectedNumberOfInstances_ < 0) |
2208 break; | 2209 { |
2209 | 2210 target["ExpectedNumberOfInstances"] = Json::nullValue; |
2210 case ResourceType_Instance: | 2211 } |
2211 { | 2212 else |
2212 target["FileSize"] = static_cast<unsigned int>(resource.fileSize_); | 2213 { |
2213 target["FileUuid"] = resource.fileUuid_; | 2214 target["ExpectedNumberOfInstances"] = resource.expectedNumberOfInstances_; |
2214 | 2215 } |
2215 if (resource.indexInSeries_ < 0) | 2216 target["Status"] = resource.status_; |
2216 { | 2217 break; |
2217 target["IndexInSeries"] = Json::nullValue; | 2218 |
2218 } | 2219 case ResourceType_Instance: |
2219 else | 2220 { |
2220 { | 2221 target["FileSize"] = static_cast<unsigned int>(resource.fileSize_); |
2221 target["IndexInSeries"] = resource.indexInSeries_; | 2222 target["FileUuid"] = resource.fileUuid_; |
2222 } | 2223 |
2223 | 2224 if (resource.indexInSeries_ < 0) |
2224 break; | 2225 { |
2225 } | 2226 target["IndexInSeries"] = Json::nullValue; |
2226 | 2227 } |
2227 default: | 2228 else |
2228 throw OrthancException(ErrorCode_InternalError); | 2229 { |
2229 } | 2230 target["IndexInSeries"] = resource.indexInSeries_; |
2230 | 2231 } |
2231 if (!resource.anonymizedFrom_.empty()) | 2232 |
2232 { | 2233 break; |
2233 target["AnonymizedFrom"] = resource.anonymizedFrom_; | 2234 } |
2234 } | 2235 |
2236 default: | |
2237 throw OrthancException(ErrorCode_InternalError); | |
2238 } | |
2235 | 2239 |
2236 if (!resource.modifiedFrom_.empty()) | 2240 if (!resource.anonymizedFrom_.empty()) |
2237 { | 2241 { |
2238 target["ModifiedFrom"] = resource.modifiedFrom_; | 2242 target["AnonymizedFrom"] = resource.anonymizedFrom_; |
2243 } | |
2244 | |
2245 if (!resource.modifiedFrom_.empty()) | |
2246 { | |
2247 target["ModifiedFrom"] = resource.modifiedFrom_; | |
2248 } | |
2239 } | 2249 } |
2240 | 2250 |
2241 if (resource.GetLevel() == ResourceType_Patient || | 2251 if (resource.GetLevel() == ResourceType_Patient || |
2242 resource.GetLevel() == ResourceType_Study || | 2252 resource.GetLevel() == ResourceType_Study || |
2243 resource.GetLevel() == ResourceType_Series) | 2253 resource.GetLevel() == ResourceType_Series) |
2244 { | 2254 { |
2245 target["IsStable"] = resource.isStable_; | 2255 if ((expandFlags & ExpandResourceFlags_IncludeIsStable) != 0) |
2256 { | |
2257 target["IsStable"] = resource.isStable_; | |
2258 } | |
2246 | 2259 |
2247 if (!resource.lastUpdate_.empty()) | 2260 if (!resource.lastUpdate_.empty()) |
2248 { | 2261 { |
2249 target["LastUpdate"] = resource.lastUpdate_; | 2262 target["LastUpdate"] = resource.lastUpdate_; |
2250 } | 2263 } |
2251 } | 2264 } |
2252 | 2265 |
2253 // serialize tags | 2266 if ((expandFlags & ExpandResourceFlags_IncludeMainDicomTags) != 0) |
2254 | 2267 { |
2255 static const char* const MAIN_DICOM_TAGS = "MainDicomTags"; | 2268 // serialize tags |
2256 static const char* const PATIENT_MAIN_DICOM_TAGS = "PatientMainDicomTags"; | 2269 |
2257 | 2270 static const char* const MAIN_DICOM_TAGS = "MainDicomTags"; |
2258 DicomMap mainDicomTags; | 2271 static const char* const PATIENT_MAIN_DICOM_TAGS = "PatientMainDicomTags"; |
2259 resource.GetMainDicomTags().ExtractResourceInformation(mainDicomTags, resource.GetLevel()); | 2272 |
2260 | 2273 DicomMap mainDicomTags; |
2261 target[MAIN_DICOM_TAGS] = Json::objectValue; | 2274 resource.GetMainDicomTags().ExtractResourceInformation(mainDicomTags, resource.GetLevel()); |
2262 FromDcmtkBridge::ToJson(target[MAIN_DICOM_TAGS], mainDicomTags, format); | 2275 |
2263 | 2276 target[MAIN_DICOM_TAGS] = Json::objectValue; |
2264 if (resource.GetLevel() == ResourceType_Study) | 2277 FromDcmtkBridge::ToJson(target[MAIN_DICOM_TAGS], mainDicomTags, format); |
2265 { | 2278 |
2266 DicomMap patientMainDicomTags; | 2279 if (resource.GetLevel() == ResourceType_Study) |
2267 resource.GetMainDicomTags().ExtractPatientInformation(patientMainDicomTags); | 2280 { |
2268 | 2281 DicomMap patientMainDicomTags; |
2269 target[PATIENT_MAIN_DICOM_TAGS] = Json::objectValue; | 2282 resource.GetMainDicomTags().ExtractPatientInformation(patientMainDicomTags); |
2270 FromDcmtkBridge::ToJson(target[PATIENT_MAIN_DICOM_TAGS], patientMainDicomTags, format); | 2283 |
2271 } | 2284 target[PATIENT_MAIN_DICOM_TAGS] = Json::objectValue; |
2272 | 2285 FromDcmtkBridge::ToJson(target[PATIENT_MAIN_DICOM_TAGS], patientMainDicomTags, format); |
2273 if (requestedTags.size() > 0) | 2286 } |
2274 { | 2287 |
2275 static const char* const REQUESTED_TAGS = "RequestedTags"; | 2288 if (requestedTags.size() > 0) |
2276 | 2289 { |
2277 DicomMap tags; | 2290 static const char* const REQUESTED_TAGS = "RequestedTags"; |
2278 resource.GetMainDicomTags().ExtractTags(tags, requestedTags); | 2291 |
2279 | 2292 DicomMap tags; |
2280 target[REQUESTED_TAGS] = Json::objectValue; | 2293 resource.GetMainDicomTags().ExtractTags(tags, requestedTags); |
2281 FromDcmtkBridge::ToJson(target[REQUESTED_TAGS], tags, format); | 2294 |
2282 | 2295 target[REQUESTED_TAGS] = Json::objectValue; |
2283 } | 2296 FromDcmtkBridge::ToJson(target[REQUESTED_TAGS], tags, format); |
2284 | 2297 |
2298 } | |
2299 } | |
2300 | |
2301 if ((expandFlags & ExpandResourceFlags_IncludeLabels) != 0) | |
2285 { | 2302 { |
2286 Json::Value labels = Json::arrayValue; | 2303 Json::Value labels = Json::arrayValue; |
2287 | 2304 |
2288 for (std::set<std::string>::const_iterator it = resource.labels_.begin(); it != resource.labels_.end(); ++it) | 2305 for (std::set<std::string>::const_iterator it = resource.labels_.begin(); it != resource.labels_.end(); ++it) |
2289 { | 2306 { |
2290 labels.append(*it); | 2307 labels.append(*it); |
2291 } | 2308 } |
2292 | 2309 |
2293 target["Labels"] = labels; | 2310 target["Labels"] = labels; |
2311 } | |
2312 | |
2313 // new in Orthanc 1.12.4 | |
2314 if ((expandFlags & ExpandResourceFlags_IncludeAllMetadata) != 0) | |
2315 { | |
2316 Json::Value metadata = Json::objectValue; | |
2317 | |
2318 for (std::map<MetadataType, std::string>::const_iterator it = resource.metadata_.begin(); it != resource.metadata_.end(); ++it) | |
2319 { | |
2320 metadata[EnumerationToString(it->first)] = it->second; | |
2321 } | |
2322 | |
2323 target["Metadata"] = metadata; | |
2294 } | 2324 } |
2295 } | 2325 } |
2296 | 2326 |
2297 | 2327 |
2298 static void ComputeInstanceTags(ExpandedResource& resource, | 2328 static void ComputeInstanceTags(ExpandedResource& resource, |
2535 const std::set<DicomTag>& requestedTags, | 2565 const std::set<DicomTag>& requestedTags, |
2536 bool allowStorageAccess) | 2566 bool allowStorageAccess) |
2537 { | 2567 { |
2538 ExpandedResource resource; | 2568 ExpandedResource resource; |
2539 | 2569 |
2540 if (ExpandResource(resource, publicId, mainDicomTags, instanceId, dicomAsJson, level, requestedTags, ExpandResourceFlags_Default, allowStorageAccess)) | 2570 if (ExpandResource(resource, publicId, mainDicomTags, instanceId, dicomAsJson, level, requestedTags, ExpandResourceFlags_DefaultExtract, allowStorageAccess)) |
2541 { | 2571 { |
2542 SerializeExpandedResource(target, resource, format, requestedTags); | 2572 SerializeExpandedResource(target, resource, format, requestedTags, ExpandResourceFlags_DefaultOutput); |
2543 return true; | 2573 return true; |
2544 } | 2574 } |
2545 | 2575 |
2546 return false; | 2576 return false; |
2547 } | 2577 } |
2685 boost::posix_time::time_duration elapsed = nowUtc - serverStartTimeUtc_; | 2715 boost::posix_time::time_duration elapsed = nowUtc - serverStartTimeUtc_; |
2686 | 2716 |
2687 return elapsed.total_seconds(); | 2717 return elapsed.total_seconds(); |
2688 } | 2718 } |
2689 | 2719 |
2720 void ServerContext::AppendFindResponse(Json::Value& target, | |
2721 const FindResponse::Item& item, | |
2722 DicomToJsonFormat format, | |
2723 const std::set<DicomTag>& requestedTags, | |
2724 bool allowStorageAccess) | |
2725 { | |
2726 // convert to ExpandedResource to re-use the serialization code TODO-FIND: check if this is the right way to do. shouldn't we copy the code and finally get rid of ExpandedResource ? | |
2727 ExpandedResource resource(item); | |
2728 | |
2729 ExpandResourceFlags expandFlags = ExpandResourceFlags_None; | |
2730 if (item.HasResponseContent(FindRequest::ResponseContent_Children)) | |
2731 { | |
2732 expandFlags = static_cast<ExpandResourceFlags>(expandFlags | ExpandResourceFlags_IncludeChildren); | |
2733 } | |
2734 if (item.HasResponseContent(FindRequest::ResponseContent_Metadata)) | |
2735 { | |
2736 expandFlags = static_cast<ExpandResourceFlags>(expandFlags | ExpandResourceFlags_IncludeAllMetadata | ExpandResourceFlags_IncludeMetadata ); | |
2737 } | |
2738 if (item.HasResponseContent(FindRequest::ResponseContent_MainDicomTags)) | |
2739 { | |
2740 expandFlags = static_cast<ExpandResourceFlags>(expandFlags | ExpandResourceFlags_IncludeMainDicomTags); | |
2741 } | |
2742 if (item.HasResponseContent(FindRequest::ResponseContent_IsStable)) | |
2743 { | |
2744 expandFlags = static_cast<ExpandResourceFlags>(expandFlags | ExpandResourceFlags_IncludeIsStable); | |
2745 } | |
2746 if (item.HasResponseContent(FindRequest::ResponseContent_Labels)) | |
2747 { | |
2748 expandFlags = static_cast<ExpandResourceFlags>(expandFlags | ExpandResourceFlags_IncludeLabels); | |
2749 } | |
2750 | |
2751 Json::Value jsonItem; | |
2752 SerializeExpandedResource(jsonItem, resource, format, requestedTags, expandFlags); | |
2753 target.append(jsonItem); | |
2754 } | |
2755 | |
2756 | |
2690 } | 2757 } |