001/*- 002 * #%L 003 * Smile CDR - CDR 004 * %% 005 * Copyright (C) 2016 - 2026 Smile CDR, Inc. 006 * %% 007 * All rights reserved. 008 * #L% 009 */ 010package ca.cdr.api.fhirgw.model; 011 012import org.hl7.fhir.instance.model.api.IBaseResource; 013import org.slf4j.Logger; 014import org.slf4j.LoggerFactory; 015 016import java.util.Collection; 017import java.util.Collections; 018import java.util.HashMap; 019import java.util.List; 020import java.util.Map; 021 022import static java.util.Collections.emptyList; 023import static java.util.Objects.nonNull; 024import static org.apache.commons.lang3.ObjectUtils.getIfNull; 025 026public class OperationResponsesAccumulator implements IResultsAccumulator<OperationResponse> { 027 028 private static final Logger ourLog = LoggerFactory.getLogger(OperationResponsesAccumulator.class); 029 030 private final int myMaxResponsesCount; 031 032 private final Map<String, OperationResponse> myTargetIdToResponseMap = Collections.synchronizedMap(new HashMap<>()); 033 034 public OperationResponsesAccumulator() { 035 this(Integer.MAX_VALUE); 036 } 037 038 public OperationResponsesAccumulator(int theMaxResponsesCount) { 039 myMaxResponsesCount = theMaxResponsesCount; 040 } 041 042 public boolean isAcceptingMoreOperationResponses() { 043 return getResults().size() < myMaxResponsesCount; 044 } 045 046 public Collection<OperationResponse> getResults() { 047 return myTargetIdToResponseMap.values(); 048 } 049 050 /** 051 * Accumulates a list of resources that was originally obtained from the RESPONSE 052 * and processed by interceptors if applicable. 053 * 054 * @param theResults the list of resources processed by interceptors to accumulate 055 * @param theResponse the original response from which a list of resources was obtained and submitted to interceptors 056 * @param theTargetId the id of the target that returned the RESPONSE 057 */ 058 @Override 059 public void accumulate(List<IBaseResource> theResults, OperationResponse theResponse, String theTargetId) { 060 // at this point, theResults is a list of resources (originally obtained from theResponse) that was processed 061 // by interceptors. if applicable, we need to: 062 // 1- sanitize the list; 063 // 2- store it in theResponse; 064 // 3- accumulate theResponse; 065 066 if (!isAcceptingMoreOperationResponses()) { 067 return; 068 } 069 070 List<IBaseResource> nonNullResultList = getIfNull(theResults, emptyList()); 071 List<IBaseResource> sanitizedResultList = nonNullResultList.stream() 072 .filter(theIBaseResource -> nonNull(theIBaseResource)) 073 .toList(); 074 075 // the target response for an operation is one IBaseResource or nothing if there was an exception thrown by 076 // the invocation. if we have anything to return, it will be at the first index. 077 IBaseResource resourceToReturn = sanitizedResultList.isEmpty() ? null : sanitizedResultList.get(0); 078 079 theResponse.setResponse(resourceToReturn); 080 081 myTargetIdToResponseMap.put(theTargetId, theResponse); 082 } 083 084 @Override 085 public void addResults(String theTargetId, List<IBaseResource> theResults, int theTotal) { 086 ourLog.debug("Can't add {} Resources to targetId {}. Operation not supported", theResults.size(), theTargetId); 087 } 088 089 @Override 090 public List<IBaseResource> getResults(String theTargetId) { 091 ourLog.debug("Can't provide a list of Resources for targetId {}. Operation not supported", theTargetId); 092 return emptyList(); 093 } 094 095 @Override 096 public List<IBaseResource> getMatchedResults(String theTargetId) { 097 ourLog.debug("Can't provide matched results for targetId {}. Operation not supported", theTargetId); 098 return emptyList(); 099 } 100 101 @Override 102 public List<IBaseResource> getPageableResults(String theTargetId) { 103 ourLog.debug("Can't provide pageable results for targetId {}. Operation not supported", theTargetId); 104 return emptyList(); 105 } 106 107 @Override 108 public List<IBaseResource> getIncludeResults(String theTargetId) { 109 ourLog.debug("Can't provide a list of included results targetId {}. Operation not supported", theTargetId); 110 return emptyList(); 111 } 112 113 @Override 114 public List<IBaseResource> getOutcomeResults(String theTargetId) { 115 ourLog.debug("Can't provide a list of outcome results targetId {}. Operation not supported", theTargetId); 116 return emptyList(); 117 } 118 119 @Override 120 public List<IBaseResource> getUncategorizedResults(String theTargetId) { 121 ourLog.debug( 122 "Can't provide a list of uncategorized included results targetId {}. Operation not supported", 123 theTargetId); 124 return emptyList(); 125 } 126 127 @Override 128 public void removeResults(String theTargetId, List<IBaseResource> theResultsToBeRemoved) { 129 ourLog.debug("Can't remove results for targetId {}. Operation not supported", theTargetId); 130 } 131 132 @Override 133 public int getTotal() { 134 ourLog.debug("Can't provide a total count. A placeholder value of 0 is returned. Operation not supported"); 135 return 0; 136 } 137 138 @Override 139 public boolean getTotalOmitted() { 140 ourLog.debug( 141 "Can't provide a total omitted count. A placeholder value of false is returned. Operation not supported"); 142 return false; 143 } 144 145 @Override 146 public void setTotalOmitted(boolean theTotalOmitted) { 147 ourLog.debug("Can't set the total omitted count to {}. Operation not supported", theTotalOmitted); 148 } 149}