void SimplifyTags(Json::Value& target, const Json::Value& source, DicomToJsonFormat format) { assert(source.isObject()); target = Json::objectValue; Json::Value::Members members = source.getMemberNames(); for (size_t i = 0; i < members.size(); i++) { const Json::Value& v = source[members[i]]; const std::string& type = v["Type"].asString(); std::string name; switch (format) { case DicomToJsonFormat_Human: name = v["Name"].asString(); break; case DicomToJsonFormat_Short: name = members[i]; break; default: throw OrthancException(ErrorCode_ParameterOutOfRange); } if (type == "String") { target[name] = v["Value"].asString(); } else if (type == "TooLong" || type == "Null") { target[name] = Json::nullValue; } else if (type == "Sequence") { const Json::Value& array = v["Value"]; assert(array.isArray()); Json::Value children = Json::arrayValue; for (Json::Value::ArrayIndex i = 0; i < array.size(); i++) { Json::Value c; SimplifyTags(c, array[i], format); children.append(c); } target[name] = children; } else { assert(0); } } }
void SimplifyTags(Json::Value& target, const Json::Value& source) { assert(source.isObject()); target = Json::objectValue; Json::Value::Members members = source.getMemberNames(); for (size_t i = 0; i < members.size(); i++) { const Json::Value& v = source[members[i]]; const std::string& name = v["Name"].asString(); const std::string& type = v["Type"].asString(); if (type == "String") { target[name] = v["Value"].asString(); } else if (type == "TooLong" || type == "Null") { target[name] = Json::nullValue; } else if (type == "Sequence") { const Json::Value& array = v["Value"]; assert(array.isArray()); Json::Value children = Json::arrayValue; for (Json::Value::ArrayIndex i = 0; i < array.size(); i++) { Json::Value c; SimplifyTags(c, array[i]); children.append(c); } target[name] = children; } else { assert(0); } } }
StoreStatus ServerContext::Store(const char* dicomInstance, size_t dicomSize, const DicomMap& dicomSummary, const Json::Value& dicomJson, const std::string& remoteAet) { // Test if the instance must be filtered out if (lua_.IsExistingFunction(RECEIVED_INSTANCE_FILTER)) { Json::Value simplified; SimplifyTags(simplified, dicomJson); LuaFunctionCall call(lua_, RECEIVED_INSTANCE_FILTER); call.PushJSON(simplified); call.PushString(remoteAet); if (!call.ExecutePredicate()) { LOG(INFO) << "An incoming instance has been discarded by the filter"; return StoreStatus_FilteredOut; } } if (compressionEnabled_) { accessor_.SetCompressionForNextOperations(CompressionType_Zlib); } else { accessor_.SetCompressionForNextOperations(CompressionType_None); } FileInfo dicomInfo = accessor_.Write(dicomInstance, dicomSize, FileContentType_Dicom); FileInfo jsonInfo = accessor_.Write(dicomJson.toStyledString(), FileContentType_Json); ServerIndex::Attachments attachments; attachments.push_back(dicomInfo); attachments.push_back(jsonInfo); StoreStatus status = index_.Store(dicomSummary, attachments, remoteAet); if (status != StoreStatus_Success) { storage_.Remove(dicomInfo.GetUuid()); storage_.Remove(jsonInfo.GetUuid()); } switch (status) { case StoreStatus_Success: LOG(INFO) << "New instance stored"; break; case StoreStatus_AlreadyStored: LOG(INFO) << "Already stored"; break; case StoreStatus_Failure: LOG(ERROR) << "Store failure"; break; default: // This should never happen break; } return status; }
StoreStatus ServerContext::Store(std::string& resultPublicId, DicomInstanceToStore& dicom) { try { DicomInstanceHasher hasher(dicom.GetSummary()); resultPublicId = hasher.HashInstance(); Json::Value simplified; SimplifyTags(simplified, dicom.GetJson()); // Test if the instance must be filtered out bool accepted = true; { boost::recursive_mutex::scoped_lock lock(listenersMutex_); for (ServerListeners::iterator it = listeners_.begin(); it != listeners_.end(); ++it) { try { if (!it->GetListener().FilterIncomingInstance(simplified, dicom.GetRemoteAet())) { accepted = false; break; } } catch (OrthancException& e) { LOG(ERROR) << "Error in the " << it->GetDescription() << " callback while receiving an instance: " << e.What(); throw; } } } if (!accepted) { LOG(INFO) << "An incoming instance has been discarded by the filter"; return StoreStatus_FilteredOut; } if (compressionEnabled_) { accessor_.SetCompressionForNextOperations(CompressionType_Zlib); } else { accessor_.SetCompressionForNextOperations(CompressionType_None); } FileInfo dicomInfo = accessor_.Write(dicom.GetBufferData(), dicom.GetBufferSize(), FileContentType_Dicom); FileInfo jsonInfo = accessor_.Write(dicom.GetJson().toStyledString(), FileContentType_DicomAsJson); ServerIndex::Attachments attachments; attachments.push_back(dicomInfo); attachments.push_back(jsonInfo); typedef std::map<MetadataType, std::string> InstanceMetadata; InstanceMetadata instanceMetadata; StoreStatus status = index_.Store(instanceMetadata, dicom.GetSummary(), attachments, dicom.GetRemoteAet(), dicom.GetMetadata()); // Only keep the metadata for the "instance" level dicom.GetMetadata().clear(); for (InstanceMetadata::const_iterator it = instanceMetadata.begin(); it != instanceMetadata.end(); ++it) { dicom.GetMetadata().insert(std::make_pair(std::make_pair(ResourceType_Instance, it->first), it->second)); } if (status != StoreStatus_Success) { accessor_.Remove(dicomInfo.GetUuid(), FileContentType_Dicom); accessor_.Remove(jsonInfo.GetUuid(), FileContentType_DicomAsJson); } switch (status) { case StoreStatus_Success: LOG(INFO) << "New instance stored"; break; case StoreStatus_AlreadyStored: LOG(INFO) << "Already stored"; break; case StoreStatus_Failure: LOG(ERROR) << "Store failure"; break; default: // This should never happen break; } if (status == StoreStatus_Success || status == StoreStatus_AlreadyStored) { boost::recursive_mutex::scoped_lock lock(listenersMutex_); for (ServerListeners::iterator it = listeners_.begin(); it != listeners_.end(); ++it) { try { it->GetListener().SignalStoredInstance(resultPublicId, dicom, simplified); } catch (OrthancException& e) { LOG(ERROR) << "Error in the " << it->GetDescription() << " callback while receiving an instance: " << e.What(); } } } return status; } catch (OrthancException& e) { if (e.GetErrorCode() == ErrorCode_InexistentTag) { LogMissingRequiredTag(dicom.GetSummary()); } throw; } }