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