comparison OrthancServer/Sources/OrthancWebDav.cpp @ 5706:1404a80dd461 find-refactoring-clean

integration find-refactoring->find-refactoring-clean
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 12 Jul 2024 17:54:29 +0200
parents 0c2f0d72d143 eb56ee3c5d63
children c8d21a09aae6
comparison
equal deleted inserted replaced
5704:0c2f0d72d143 5706:1404a80dd461
176 } 176 }
177 } 177 }
178 }; 178 };
179 179
180 180
181 class OrthancWebDav::DicomFileVisitor : public ServerContext::ILookupVisitor 181 class OrthancWebDav::DicomFileVisitorV2 : public ResourceFinder::IVisitor
182 { 182 {
183 private: 183 private:
184 ServerContext& context_; 184 ServerContext& context_;
185 bool success_; 185 bool success_;
186 std::string& target_; 186 std::string& target_;
187 boost::posix_time::ptime& time_; 187 boost::posix_time::ptime& time_;
188 188
189 public: 189 public:
190 DicomFileVisitor(ServerContext& context, 190 DicomFileVisitorV2(ServerContext& context,
191 std::string& target, 191 std::string& target,
192 boost::posix_time::ptime& time) : 192 boost::posix_time::ptime& time) :
193 context_(context), 193 context_(context),
194 success_(false), 194 success_(false),
195 target_(target), 195 target_(target),
196 time_(time) 196 time_(time)
197 { 197 {
200 bool IsSuccess() const 200 bool IsSuccess() const
201 { 201 {
202 return success_; 202 return success_;
203 } 203 }
204 204
205 virtual bool IsDicomAsJsonNeeded() const ORTHANC_OVERRIDE
206 {
207 return false; // (*)
208 }
209
210 virtual void MarkAsComplete() ORTHANC_OVERRIDE 205 virtual void MarkAsComplete() ORTHANC_OVERRIDE
211 { 206 {
212 } 207 }
213 208
214 virtual void Visit(const std::string& publicId, 209 virtual void Apply(const FindResponse::Resource& resource,
215 const std::string& instanceId /* unused */, 210 const DicomMap& requestedTags) ORTHANC_OVERRIDE
216 const DicomMap& mainDicomTags,
217 const Json::Value* dicomAsJson /* unused (*) */) ORTHANC_OVERRIDE
218 { 211 {
219 if (success_) 212 if (success_)
220 { 213 {
221 success_ = false; // Two matches => Error 214 success_ = false; // Two matches => Error
222 } 215 }
223 else 216 else
224 { 217 {
225 LookupTime(time_, context_, publicId, ResourceType_Instance, MetadataType_Instance_ReceptionDate); 218 std::string s;
226 context_.ReadDicom(target_, publicId); 219 if (resource.LookupMetadata(s, ResourceType_Instance, MetadataType_Instance_ReceptionDate))
220 {
221 ParseTime(time_, s);
222 }
223 else
224 {
225 time_ = GetNow();
226 }
227
228 context_.ReadDicom(target_, resource.GetIdentifier());
227 success_ = true; 229 success_ = true;
228 } 230 }
229 } 231 }
230 }; 232 };
231 233
232 234
233 class OrthancWebDav::OrthancJsonVisitor : public ServerContext::ILookupVisitor 235 class OrthancWebDav::OrthancJsonVisitor : public ServerContext::ILookupVisitor
234 { 236 {
235 private: 237 private:
236 ServerContext& context_; 238 ServerContext& context_;
962 { 964 {
963 private: 965 private:
964 std::string year_; 966 std::string year_;
965 std::string month_; 967 std::string month_;
966 968
967 class Visitor : public ServerContext::ILookupVisitor 969 class Visitor : public ResourceFinder::IVisitor
968 { 970 {
969 private: 971 private:
970 std::list<std::string>& resources_; 972 std::list<std::string>& resources_;
971 973
972 public: 974 public:
973 explicit Visitor(std::list<std::string>& resources) : 975 explicit Visitor(std::list<std::string>& resources) :
974 resources_(resources) 976 resources_(resources)
975 { 977 {
976 } 978 }
977 979
978 virtual bool IsDicomAsJsonNeeded() const ORTHANC_OVERRIDE
979 {
980 return false; // (*)
981 }
982
983 virtual void MarkAsComplete() ORTHANC_OVERRIDE 980 virtual void MarkAsComplete() ORTHANC_OVERRIDE
984 { 981 {
985 } 982 }
986 983
987 virtual void Visit(const std::string& publicId, 984 virtual void Apply(const FindResponse::Resource& resource,
988 const std::string& instanceId /* unused */, 985 const DicomMap& requestedTags) ORTHANC_OVERRIDE
989 const DicomMap& mainDicomTags, 986 {
990 const Json::Value* dicomAsJson /* unused (*) */) ORTHANC_OVERRIDE 987 resources_.push_back(resource.GetIdentifier());
991 {
992 resources_.push_back(publicId);
993 } 988 }
994 }; 989 };
995 990
996 protected: 991 protected:
997 virtual void GetCurrentResources(std::list<std::string>& resources) ORTHANC_OVERRIDE 992 virtual void GetCurrentResources(std::list<std::string>& resources) ORTHANC_OVERRIDE
999 DatabaseLookup query; 994 DatabaseLookup query;
1000 query.AddRestConstraint(DICOM_TAG_STUDY_DATE, year_ + month_ + "01-" + year_ + month_ + "31", 995 query.AddRestConstraint(DICOM_TAG_STUDY_DATE, year_ + month_ + "01-" + year_ + month_ + "31",
1001 true /* case sensitive */, true /* mandatory tag */); 996 true /* case sensitive */, true /* mandatory tag */);
1002 997
1003 Visitor visitor(resources); 998 Visitor visitor(resources);
1004 GetContext().Apply(visitor, query, ResourceType_Study, 0 /* since */, 0 /* no limit */); 999
1000 ResourceFinder finder(ResourceType_Study, false /* no expand */);
1001 finder.SetDatabaseLookup(query);
1002 finder.Execute(visitor, GetContext());
1005 } 1003 }
1006 1004
1007 virtual INode* CreateResourceNode(const std::string& resource) ORTHANC_OVERRIDE 1005 virtual INode* CreateResourceNode(const std::string& resource) ORTHANC_OVERRIDE
1008 { 1006 {
1009 return new SingleDicomResource(GetContext(), ResourceType_Series, resource, GetTemplates()); 1007 return new SingleDicomResource(GetContext(), ResourceType_Series, resource, GetTemplates());
1032 private: 1030 private:
1033 ServerContext& context_; 1031 ServerContext& context_;
1034 std::string year_; 1032 std::string year_;
1035 const Templates& templates_; 1033 const Templates& templates_;
1036 1034
1037 class Visitor : public ServerContext::ILookupVisitor 1035 class Visitor : public ResourceFinder::IVisitor
1038 { 1036 {
1039 private: 1037 private:
1040 std::set<std::string> months_; 1038 std::set<std::string> months_;
1041 1039
1042 public: 1040 public:
1043 const std::set<std::string>& GetMonths() const 1041 const std::set<std::string>& GetMonths() const
1044 { 1042 {
1045 return months_; 1043 return months_;
1046 } 1044 }
1047 1045
1048 virtual bool IsDicomAsJsonNeeded() const ORTHANC_OVERRIDE
1049 {
1050 return false; // (*)
1051 }
1052
1053 virtual void MarkAsComplete() ORTHANC_OVERRIDE 1046 virtual void MarkAsComplete() ORTHANC_OVERRIDE
1054 { 1047 {
1055 } 1048 }
1056 1049
1057 virtual void Visit(const std::string& publicId, 1050 virtual void Apply(const FindResponse::Resource& resource,
1058 const std::string& instanceId /* unused */, 1051 const DicomMap& requestedTags) ORTHANC_OVERRIDE
1059 const DicomMap& mainDicomTags, 1052 {
1060 const Json::Value* dicomAsJson /* unused (*) */) ORTHANC_OVERRIDE 1053 DicomMap mainDicomTags;
1061 { 1054 resource.GetMainDicomTags(mainDicomTags, ResourceType_Study);
1055
1062 std::string s; 1056 std::string s;
1063 if (mainDicomTags.LookupStringValue(s, DICOM_TAG_STUDY_DATE, false) && 1057 if (mainDicomTags.LookupStringValue(s, DICOM_TAG_STUDY_DATE, false) &&
1064 s.size() == 8) 1058 s.size() == 8)
1065 { 1059 {
1066 months_.insert(s.substr(4, 2)); // Get the month from "YYYYMMDD" 1060 months_.insert(s.substr(4, 2)); // Get the month from "YYYYMMDD"
1078 DatabaseLookup query; 1072 DatabaseLookup query;
1079 query.AddRestConstraint(DICOM_TAG_STUDY_DATE, year_ + "0101-" + year_ + "1231", 1073 query.AddRestConstraint(DICOM_TAG_STUDY_DATE, year_ + "0101-" + year_ + "1231",
1080 true /* case sensitive */, true /* mandatory tag */); 1074 true /* case sensitive */, true /* mandatory tag */);
1081 1075
1082 Visitor visitor; 1076 Visitor visitor;
1083 context_.Apply(visitor, query, ResourceType_Study, 0 /* since */, 0 /* no limit */); 1077
1078 ResourceFinder finder(ResourceType_Study, false /* no expand */);
1079 finder.SetDatabaseLookup(query);
1080 finder.Execute(visitor, context_);
1084 1081
1085 for (std::set<std::string>::const_iterator it = visitor.GetMonths().begin(); 1082 for (std::set<std::string>::const_iterator it = visitor.GetMonths().begin();
1086 it != visitor.GetMonths().end(); ++it) 1083 it != visitor.GetMonths().end(); ++it)
1087 { 1084 {
1088 target.AddResource(new IWebDavBucket::Folder(year_ + "-" + *it)); 1085 target.AddResource(new IWebDavBucket::Folder(year_ + "-" + *it));
1172 { 1169 {
1173 } 1170 }
1174 }; 1171 };
1175 1172
1176 1173
1177 class OrthancWebDav::DicomDeleteVisitor : public ServerContext::ILookupVisitor 1174 class OrthancWebDav::DicomDeleteVisitor : public ResourceFinder::IVisitor
1178 { 1175 {
1179 private: 1176 private:
1180 ServerContext& context_; 1177 ServerContext& context_;
1181 ResourceType level_; 1178 ResourceType level_;
1182 1179
1186 context_(context), 1183 context_(context),
1187 level_(level) 1184 level_(level)
1188 { 1185 {
1189 } 1186 }
1190 1187
1191 virtual bool IsDicomAsJsonNeeded() const ORTHANC_OVERRIDE
1192 {
1193 return false; // (*)
1194 }
1195
1196 virtual void MarkAsComplete() ORTHANC_OVERRIDE 1188 virtual void MarkAsComplete() ORTHANC_OVERRIDE
1197 { 1189 {
1198 } 1190 }
1199 1191
1200 virtual void Visit(const std::string& publicId, 1192 virtual void Apply(const FindResponse::Resource& resource,
1201 const std::string& instanceId /* unused */, 1193 const DicomMap& requestedTags) ORTHANC_OVERRIDE
1202 const DicomMap& mainDicomTags /* unused */,
1203 const Json::Value* dicomAsJson /* unused (*) */) ORTHANC_OVERRIDE
1204 { 1194 {
1205 Json::Value info; 1195 Json::Value info;
1206 context_.DeleteResource(info, publicId, level_); 1196 context_.DeleteResource(info, resource.GetIdentifier(), level_);
1207 } 1197 }
1208 }; 1198 };
1209 1199
1210 1200
1211 void OrthancWebDav::AddVirtualFile(Collection& collection, 1201 void OrthancWebDav::AddVirtualFile(Collection& collection,
1507 return false; 1497 return false;
1508 } 1498 }
1509 } 1499 }
1510 1500
1511 1501
1502 static bool GetOrthancJson(std::string& target,
1503 ServerContext& context,
1504 ResourceType level,
1505 const DatabaseLookup& query)
1506 {
1507 ResourceFinder finder(level, true /* expand */);
1508 finder.SetDatabaseLookup(query);
1509
1510 Json::Value expanded;
1511 finder.Execute(expanded, context);
1512
1513 if (expanded.size() != 1)
1514 {
1515 return false;
1516 }
1517 else
1518 {
1519 target = expanded[0].toStyledString();
1520
1521 // Replace UNIX newlines with DOS newlines
1522 boost::replace_all(target, "\n", "\r\n");
1523
1524 return true;
1525 }
1526 }
1527
1528
1512 bool OrthancWebDav::GetFileContent(MimeType& mime, 1529 bool OrthancWebDav::GetFileContent(MimeType& mime,
1513 std::string& content, 1530 std::string& content,
1514 boost::posix_time::ptime& modificationTime, 1531 boost::posix_time::ptime& modificationTime,
1515 const UriComponents& path) 1532 const UriComponents& path)
1516 { 1533 {
1524 path[2] == STUDY_INFO) 1541 path[2] == STUDY_INFO)
1525 { 1542 {
1526 DatabaseLookup query; 1543 DatabaseLookup query;
1527 query.AddRestConstraint(DICOM_TAG_STUDY_INSTANCE_UID, path[1], 1544 query.AddRestConstraint(DICOM_TAG_STUDY_INSTANCE_UID, path[1],
1528 true /* case sensitive */, true /* mandatory tag */); 1545 true /* case sensitive */, true /* mandatory tag */);
1529
1530 OrthancJsonVisitor visitor(context_, content, ResourceType_Study);
1531 context_.Apply(visitor, query, ResourceType_Study, 0 /* since */, 0 /* no limit */);
1532 1546
1533 mime = MimeType_Json; 1547 mime = MimeType_Json;
1534 return visitor.IsSuccess(); 1548 return GetOrthancJson(content, context_, ResourceType_Study, query);
1535 } 1549 }
1536 else if (path.size() == 4 && 1550 else if (path.size() == 4 &&
1537 path[3] == SERIES_INFO) 1551 path[3] == SERIES_INFO)
1538 { 1552 {
1539 DatabaseLookup query; 1553 DatabaseLookup query;
1540 query.AddRestConstraint(DICOM_TAG_STUDY_INSTANCE_UID, path[1], 1554 query.AddRestConstraint(DICOM_TAG_STUDY_INSTANCE_UID, path[1],
1541 true /* case sensitive */, true /* mandatory tag */); 1555 true /* case sensitive */, true /* mandatory tag */);
1542 query.AddRestConstraint(DICOM_TAG_SERIES_INSTANCE_UID, path[2], 1556 query.AddRestConstraint(DICOM_TAG_SERIES_INSTANCE_UID, path[2],
1543 true /* case sensitive */, true /* mandatory tag */); 1557 true /* case sensitive */, true /* mandatory tag */);
1544 1558
1545 OrthancJsonVisitor visitor(context_, content, ResourceType_Series);
1546 context_.Apply(visitor, query, ResourceType_Series, 0 /* since */, 0 /* no limit */);
1547
1548 mime = MimeType_Json; 1559 mime = MimeType_Json;
1549 return visitor.IsSuccess(); 1560 return GetOrthancJson(content, context_, ResourceType_Series, query);
1550 } 1561 }
1551 else if (path.size() == 4 && 1562 else if (path.size() == 4 &&
1552 boost::ends_with(path[3], ".dcm")) 1563 boost::ends_with(path[3], ".dcm"))
1553 { 1564 {
1554 const std::string sopInstanceUid = path[3].substr(0, path[3].size() - 4); 1565 const std::string sopInstanceUid = path[3].substr(0, path[3].size() - 4);
1559 query.AddRestConstraint(DICOM_TAG_SERIES_INSTANCE_UID, path[2], 1570 query.AddRestConstraint(DICOM_TAG_SERIES_INSTANCE_UID, path[2],
1560 true /* case sensitive */, true /* mandatory tag */); 1571 true /* case sensitive */, true /* mandatory tag */);
1561 query.AddRestConstraint(DICOM_TAG_SOP_INSTANCE_UID, sopInstanceUid, 1572 query.AddRestConstraint(DICOM_TAG_SOP_INSTANCE_UID, sopInstanceUid,
1562 true /* case sensitive */, true /* mandatory tag */); 1573 true /* case sensitive */, true /* mandatory tag */);
1563 1574
1564 DicomFileVisitor visitor(context_, content, modificationTime);
1565 context_.Apply(visitor, query, ResourceType_Instance, 0 /* since */, 0 /* no limit */);
1566
1567 mime = MimeType_Dicom; 1575 mime = MimeType_Dicom;
1576
1577 ResourceFinder finder(ResourceType_Instance, false /* no expand */);
1578 finder.SetDatabaseLookup(query);
1579 finder.SetRetrieveMetadata(true);
1580 finder.SetRetrieveAttachments(true);
1581
1582 DicomFileVisitorV2 visitor(context_, content, modificationTime);
1583 finder.Execute(visitor, context_);
1584
1568 return visitor.IsSuccess(); 1585 return visitor.IsSuccess();
1569 } 1586 }
1570 else 1587 else
1571 { 1588 {
1572 return false; 1589 return false;
1684 return false; 1701 return false;
1685 } 1702 }
1686 } 1703 }
1687 1704
1688 DicomDeleteVisitor visitor(context_, level); 1705 DicomDeleteVisitor visitor(context_, level);
1689 context_.Apply(visitor, query, level, 0 /* since */, 0 /* no limit */); 1706
1707 ResourceFinder finder(level, false /* no expand */);
1708 finder.SetDatabaseLookup(query);
1709 finder.Execute(visitor, context_);
1690 return true; 1710 return true;
1691 } 1711 }
1692 else 1712 else
1693 { 1713 {
1694 return false; // read-only 1714 return false; // read-only