Skip to content

Commit

Permalink
#2 Add support for Remove Metadata (ITI-62)
Browse files Browse the repository at this point in the history
* Fix validation handling for RPLC associations
  • Loading branch information
Thopap committed Apr 1, 2024
1 parent e1a2738 commit 3508c42
Showing 1 changed file with 35 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,42 +48,27 @@ public Response remove(RemoveMetadata metadataToRemove) {

var docBundleResult = client.search().forResource(DocumentReference.class)
.withProfile(MappingSupport.MHD_COMPREHENSIVE_PROFILE)
.include(DocumentReference.INCLUDE_RELATESTO)
.include(DocumentReference.INCLUDE_RELATED)
.revInclude(ListResource.INCLUDE_ITEM)
.revInclude(DocumentReference.INCLUDE_RELATED)
.revInclude(DocumentReference.INCLUDE_RELATESTO)
.where(DocumentReference.IDENTIFIER.exactly().systemAndValues(URI_URN,uuidsToDelete))
.returnBundle(Bundle.class)
.execute();

// collect all List Resources (SubmissionSet, Folder) without duplicates (hapi domain objects do not implement equal / hashcode)
var uniqueResults = new TreeSet<ListResource>((a, b) -> Comparator.comparing(IAnyResource::getId).compare(a, b));

var docResult = new PagingFhirResultIterator<DocumentReference>(docBundleResult, DocumentReference.class, client);
var docResult = BundleUtil.toListOfResourcesOfType(client.getFhirContext(), docBundleResult, DocumentReference.class);
uniqueResults.addAll(BundleUtil.toListOfResourcesOfType(client.getFhirContext(), docBundleResult, ListResource.class));
docResult.forEachRemaining(doc -> {

docResult.forEach(doc -> {
processAssociations(doc, doc.getRelatesTo(), uuidsToDelete, builder);
if (addToDeleteTransaction(doc, uuidsToDelete, builder)) {
validateNoReferencesExists(doc, docResult, unmodifiedUuidsToDelete, errorInfo);
}
});

var reverseSearchCriteria = Collections.singletonMap("item:identifier", Collections.singletonList(
uuidsToDelete.stream().map(MappingSupport::toUrnCoded).map(urnCoded -> URI_URN + "|" + urnCoded).collect(Collectors.joining(","))));
var referenceQuery = client.search().forResource(ListResource.class)
.whereMap(reverseSearchCriteria)
.revInclude(ListResource.INCLUDE_ITEM)
.returnBundle(Bundle.class);

var listQuery = client.search().forResource(ListResource.class)
.where(ListResource.IDENTIFIER.exactly().systemAndValues(URI_URN,uuidsToDelete))
.revInclude(ListResource.INCLUDE_ITEM)
.returnBundle(Bundle.class);

new PagingFhirResultIterator<ListResource>(referenceQuery.execute(), ListResource.class, client)
.forEachRemaining(uniqueResults::add);

new PagingFhirResultIterator<ListResource>(listQuery.execute(), ListResource.class, client)
.forEachRemaining(uniqueResults::add);
uniqueResults.addAll(fetchFolderAndSubmissionSets(uuidsToDelete));

uniqueResults.forEach(ref -> {
processAssociations(ref, ref.getEntry(), uuidsToDelete, builder);
Expand Down Expand Up @@ -117,22 +102,47 @@ public Response remove(RemoveMetadata metadataToRemove) {
return response;
}

private List<ListResource> fetchFolderAndSubmissionSets(List<String> uuidsToDelete) {
var result = new ArrayList<ListResource>();
var reverseSearchCriteria = Collections.singletonMap("item:identifier", Collections.singletonList(
uuidsToDelete.stream().map(MappingSupport::toUrnCoded).map(urnCoded -> URI_URN + "|" + urnCoded).collect(Collectors.joining(","))));
var referenceQuery = client.search().forResource(ListResource.class)
.whereMap(reverseSearchCriteria)
.revInclude(ListResource.INCLUDE_ITEM)
.returnBundle(Bundle.class);

var listQuery = client.search().forResource(ListResource.class)
.where(ListResource.IDENTIFIER.exactly().systemAndValues(URI_URN,uuidsToDelete))
.revInclude(ListResource.INCLUDE_ITEM)
.returnBundle(Bundle.class);

new PagingFhirResultIterator<ListResource>(referenceQuery.execute(), ListResource.class, client)
.forEachRemaining(result::add);

new PagingFhirResultIterator<ListResource>(listQuery.execute(), ListResource.class, client)
.forEachRemaining(result::add);
return result;
}

private void validateNoReferencesExists(DocumentReference doc,
PagingFhirResultIterator<DocumentReference> docResult, ArrayList<String> uuidsToDelete, List<ErrorInfo> errorInfo) {
List<DocumentReference> docResult, List<String> uuidsToDelete, List<ErrorInfo> errorInfo) {
var listOfRelations = new ArrayList<DocumentReferenceRelatesToComponent>();
docResult.forEachRemaining(aDoc -> {
docResult.forEach(aDoc -> {
var entryUuid = StoredQueryMapper.entryUuidFrom(aDoc);
if (!uuidsToDelete.contains(entryUuid) && aDoc != doc)
listOfRelations.addAll(aDoc.getRelatesTo());
});
doc.getRelatesTo().stream().filter(docRel -> docRel.getCode().equals(DocumentRelationshipType.REPLACES)).forEach(relDoc -> {
doc.getRelatesTo().stream().filter(docRel -> DocumentRelationshipType.REPLACES.equals(docRel.getCode())).forEach(relDoc -> {
var entryUuid = StoredQueryMapper.entryUuidFrom(relDoc.getTarget().getResource());
if (!uuidsToDelete.contains(entryUuid)){
errorInfo.add(new ErrorInfo(ErrorCode.REFERENCE_EXISTS_EXCEPTION, "Some references still exists to " + entryUuid,
Severity.ERROR, null, null));
}
});
listOfRelations.stream().map(DocumentReferenceRelatesToComponent::getTarget).filter(Objects::nonNull)
listOfRelations.stream()
.filter(rel -> !uuidsToDelete.contains(rel.getId()))
.map(DocumentReferenceRelatesToComponent::getTarget)
.filter(Objects::nonNull)
.map(Reference::getResource).filter(DocumentReference.class::isInstance)
.map(DocumentReference.class::cast)
.filter(docRef -> docRef.equalsDeep(doc))
Expand Down

0 comments on commit 3508c42

Please sign in to comment.