Merge branch 'master' of github.com:jamesagnew/hapi-fhir

This commit is contained in:
James 2017-04-22 06:34:36 -04:00
commit 405ac50351
10 changed files with 227 additions and 233 deletions

View File

@ -146,6 +146,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
*/ */
static final Map<String, Class<? extends IQueryParameterType>> RESOURCE_META_PARAMS; static final Map<String, Class<? extends IQueryParameterType>> RESOURCE_META_PARAMS;
public static final String UCUM_NS = "http://unitsofmeasure.org"; public static final String UCUM_NS = "http://unitsofmeasure.org";
private static final Set<String> EXCLUDE_ELEMENTS_IN_ENCODED;
static { static {
Map<String, Class<? extends IQueryParameterType>> resourceMetaParams = new HashMap<String, Class<? extends IQueryParameterType>>(); Map<String, Class<? extends IQueryParameterType>> resourceMetaParams = new HashMap<String, Class<? extends IQueryParameterType>>();
@ -162,6 +163,11 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
resourceMetaAndParams.put(Constants.PARAM_SECURITY, TokenAndListParam.class); resourceMetaAndParams.put(Constants.PARAM_SECURITY, TokenAndListParam.class);
RESOURCE_META_PARAMS = Collections.unmodifiableMap(resourceMetaParams); RESOURCE_META_PARAMS = Collections.unmodifiableMap(resourceMetaParams);
RESOURCE_META_AND_PARAMS = Collections.unmodifiableMap(resourceMetaAndParams); RESOURCE_META_AND_PARAMS = Collections.unmodifiableMap(resourceMetaAndParams);
HashSet<String> excludeElementsInEncoded = new HashSet<String>();
excludeElementsInEncoded.add("*.id");
excludeElementsInEncoded.add("*.meta");
EXCLUDE_ELEMENTS_IN_ENCODED = Collections.unmodifiableSet(excludeElementsInEncoded);
} }
@Autowired(required = true) @Autowired(required = true)
@ -834,8 +840,12 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
} }
} }
String encoded = myConfig.getResourceEncoding().newParser(myContext).encodeResourceToString(theResource);
ResourceEncodingEnum encoding = myConfig.getResourceEncoding(); ResourceEncodingEnum encoding = myConfig.getResourceEncoding();
IParser parser = encoding.newParser(myContext);
parser.setDontEncodeElements(EXCLUDE_ELEMENTS_IN_ENCODED);
String encoded = parser.encodeResourceToString(theResource);
theEntity.setEncoding(encoding); theEntity.setEncoding(encoding);
theEntity.setFhirVersion(myContext.getVersion().getVersion()); theEntity.setFhirVersion(myContext.getVersion().getVersion());
switch (encoding) { switch (encoding) {
@ -1057,7 +1067,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
} }
IFhirResourceDao<R> dao = getDao(theResourceType); IFhirResourceDao<R> dao = getDao(theResourceType);
Set<Long> ids = dao.searchForIdsWithAndOr(paramMap); Set<Long> ids = dao.searchForIds(paramMap);
return ids; return ids;
} }
@ -1582,12 +1592,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
return updateEntity(theResource, entity, theDeletedTimestampOrNull, true, true, theUpdateTime); return updateEntity(theResource, entity, theDeletedTimestampOrNull, true, true, theUpdateTime);
} }
private void updateSearchParamPresent(Map<String, Boolean> presentSearchParams, Set<? extends BaseResourceIndexedSearchParam> params) {
for (BaseResourceIndexedSearchParam nextSearchParam : params) {
presentSearchParams.put(nextSearchParam.getParamName(), Boolean.TRUE);
}
}
private void validateChildReferences(IBase theElement, String thePath) { private void validateChildReferences(IBase theElement, String thePath) {
if (theElement == null) { if (theElement == null) {
return; return;

View File

@ -883,22 +883,10 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
} }
@Override
public Set<Long> searchForIds(Map<String, IQueryParameterType> theParams) {
SearchParameterMap map = new SearchParameterMap();
for (Entry<String, IQueryParameterType> nextEntry : theParams.entrySet()) {
map.add(nextEntry.getKey(), (nextEntry.getValue()));
}
return searchForIdsWithAndOr(map);
}
@Override @Override
public Set<Long> searchForIds(String theParameterName, IQueryParameterType theValue) { public Set<Long> searchForIds(SearchParameterMap theParams) {
return searchForIds(Collections.singletonMap(theParameterName, theValue));
}
@Override
public Set<Long> searchForIdsWithAndOr(SearchParameterMap theParams) {
SearchBuilder builder = newSearchBuilder(); SearchBuilder builder = newSearchBuilder();
builder.setType(getResourceType(), getResourceName()); builder.setType(getResourceType(), getResourceName());
@ -1090,6 +1078,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
"Invalid resource ID[" + entity.getIdDt().toUnqualifiedVersionless() + "] of type[" + entity.getResourceType() + "] - Does not match expected [" + getResourceName() + "]"); "Invalid resource ID[" + entity.getIdDt().toUnqualifiedVersionless() + "] of type[" + entity.getResourceType() + "] - Does not match expected [" + getResourceName() + "]");
} }
// entity.get
// Notify interceptors // Notify interceptors
ActionRequestDetails requestDetails = null; ActionRequestDetails requestDetails = null;
if (theRequestDetails != null) { if (theRequestDetails != null) {

View File

@ -10,7 +10,7 @@ package ca.uhn.fhir.jpa.dao;
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@ -56,25 +56,42 @@ import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet> implements IFhirResourceDaoValueSet<ValueSet, CodingDt, CodeableConceptDt>, IFhirResourceDaoCodeSystem<ValueSet, CodingDt, CodeableConceptDt> { public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
implements IFhirResourceDaoValueSet<ValueSet, CodingDt, CodeableConceptDt>, IFhirResourceDaoCodeSystem<ValueSet, CodingDt, CodeableConceptDt> {
private DefaultProfileValidationSupport myDefaultProfileValidationSupport;
@Autowired @Autowired
private IJpaValidationSupportDstu2 myJpaValidationSupport; private IJpaValidationSupportDstu2 myJpaValidationSupport;
private ValidationSupportChain myValidationSupport;
@Autowired @Autowired
@Qualifier("myFhirContextDstu2Hl7Org") @Qualifier("myFhirContextDstu2Hl7Org")
private FhirContext myRiCtx; private FhirContext myRiCtx;
private DefaultProfileValidationSupport myDefaultProfileValidationSupport; private ValidationSupportChain myValidationSupport;
@Override private void addCompose(String theFilter, ValueSet theValueSetToPopulate, ValueSet theSourceValueSet, CodeSystemConcept theConcept) {
@PostConstruct if (isBlank(theFilter)) {
public void postConstruct() { addCompose(theValueSetToPopulate, theSourceValueSet.getCodeSystem().getSystem(), theConcept.getCode(), theConcept.getDisplay());
super.postConstruct(); } else {
myDefaultProfileValidationSupport = new DefaultProfileValidationSupport(); String filter = theFilter.toLowerCase();
myValidationSupport = new ValidationSupportChain(myDefaultProfileValidationSupport, myJpaValidationSupport); if (theConcept.getDisplay().toLowerCase().contains(filter) || theConcept.getCode().toLowerCase().contains(filter)) {
addCompose(theValueSetToPopulate, theSourceValueSet.getCodeSystem().getSystem(), theConcept.getCode(), theConcept.getDisplay());
}
}
for (CodeSystemConcept nextChild : theConcept.getConcept()) {
addCompose(theFilter, theValueSetToPopulate, theSourceValueSet, nextChild);
}
}
private void addCompose(ValueSet retVal, String theSystem, String theCode, String theDisplay) {
if (isBlank(theCode)) {
return;
}
ExpansionContains contains = retVal.getExpansion().addContains();
contains.setSystem(theSystem);
contains.setCode(theCode);
contains.setDisplay(theDisplay);
} }
@Override @Override
@ -84,46 +101,6 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
} }
private ValueSet loadValueSetForExpansion(IIdType theId) {
if (theId.getValue().startsWith("http://hl7.org/fhir/")) {
org.hl7.fhir.instance.model.ValueSet valueSet = myValidationSupport.fetchResource(myRiCtx, org.hl7.fhir.instance.model.ValueSet.class, theId.getValue());
if (valueSet != null) {
return getContext().newJsonParser().parseResource(ValueSet.class, myRiCtx.newJsonParser().encodeResourceToString(valueSet));
}
}
BaseHasResource sourceEntity = readEntity(theId);
if (sourceEntity == null) {
throw new ResourceNotFoundException(theId);
}
ValueSet source = (ValueSet) toResource(sourceEntity, false);
return source;
}
@Override
public ValueSet expandByIdentifier(String theUri, String theFilter) {
if (isBlank(theUri)) {
throw new InvalidRequestException("URI must not be blank or missing");
}
ValueSet source;
org.hl7.fhir.instance.model.ValueSet defaultValueSet = myDefaultProfileValidationSupport.fetchResource(myRiCtx, org.hl7.fhir.instance.model.ValueSet.class, theUri);
if (defaultValueSet != null) {
source = getContext().newJsonParser().parseResource(ValueSet.class, myRiCtx.newJsonParser().encodeResourceToString(defaultValueSet));
} else {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ValueSet.SP_URL, new UriParam(theUri));
IBundleProvider ids = search(params);
if (ids.size() == 0) {
throw new InvalidRequestException("Unknown ValueSet URI: " + theUri);
}
source = (ValueSet) ids.getResources(0, 1).get(0);
}
return expand(source, theFilter);
}
@Override @Override
public ValueSet expand(ValueSet source, String theFilter) { public ValueSet expand(ValueSet source, String theFilter) {
ValueSet retVal = new ValueSet(); ValueSet retVal = new ValueSet();
@ -157,88 +134,39 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
return retVal; return retVal;
} }
private void addCompose(String theFilter, ValueSet theValueSetToPopulate, ValueSet theSourceValueSet, CodeSystemConcept theConcept) {
if (isBlank(theFilter)) {
addCompose(theValueSetToPopulate, theSourceValueSet.getCodeSystem().getSystem(), theConcept.getCode(), theConcept.getDisplay());
} else {
String filter = theFilter.toLowerCase();
if (theConcept.getDisplay().toLowerCase().contains(filter) || theConcept.getCode().toLowerCase().contains(filter)) {
addCompose(theValueSetToPopulate, theSourceValueSet.getCodeSystem().getSystem(), theConcept.getCode(), theConcept.getDisplay());
}
}
for (CodeSystemConcept nextChild : theConcept.getConcept()) {
addCompose(theFilter, theValueSetToPopulate, theSourceValueSet, nextChild);
}
}
private void addCompose(ValueSet retVal, String theSystem, String theCode, String theDisplay) {
if (isBlank(theCode)) {
return;
}
ExpansionContains contains = retVal.getExpansion().addContains();
contains.setSystem(theSystem);
contains.setCode(theCode);
contains.setDisplay(theDisplay);
}
@Override @Override
public ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult validateCode(IPrimitiveType<String> theValueSetIdentifier, IIdType theId, IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, IPrimitiveType<String> theDisplay, CodingDt theCoding, CodeableConceptDt theCodeableConcept, RequestDetails theRequestDetails) { public ValueSet expandByIdentifier(String theUri, String theFilter) {
List<IIdType> valueSetIds; if (isBlank(theUri)) {
throw new InvalidRequestException("URI must not be blank or missing");
boolean haveCodeableConcept = theCodeableConcept != null && theCodeableConcept.getCoding().size() > 0;
boolean haveCoding = theCoding != null && theCoding.isEmpty() == false;
boolean haveCode = theCode != null && theCode.isEmpty() == false;
if (!haveCodeableConcept && !haveCoding && !haveCode) {
throw new InvalidRequestException("No code, coding, or codeableConcept provided to validate");
}
if (!multiXor(haveCodeableConcept, haveCoding, haveCode)) {
throw new InvalidRequestException("$validate-code can only validate (system AND code) OR (coding) OR (codeableConcept)");
} }
ValueSet source;
boolean haveIdentifierParam = theValueSetIdentifier != null && theValueSetIdentifier.isEmpty() == false; org.hl7.fhir.instance.model.ValueSet defaultValueSet = myDefaultProfileValidationSupport.fetchResource(myRiCtx, org.hl7.fhir.instance.model.ValueSet.class, theUri);
if (theId != null) { if (defaultValueSet != null) {
valueSetIds = Collections.singletonList(theId); source = getContext().newJsonParser().parseResource(ValueSet.class, myRiCtx.newJsonParser().encodeResourceToString(defaultValueSet));
} else if (haveIdentifierParam) {
Set<Long> ids = searchForIds(ValueSet.SP_IDENTIFIER, new TokenParam(null, theValueSetIdentifier.getValue()));
valueSetIds = new ArrayList<IIdType>();
for (Long next : ids) {
valueSetIds.add(new IdDt("ValueSet", next));
}
} else { } else {
if (theCode == null || theCode.isEmpty()) { SearchParameterMap params = new SearchParameterMap();
throw new InvalidRequestException("Either ValueSet ID or ValueSet identifier or system and code must be provided. Unable to validate."); params.setLoadSynchronousUpTo(1);
params.add(ValueSet.SP_URL, new UriParam(theUri));
IBundleProvider ids = search(params);
if (ids.size() == 0) {
throw new InvalidRequestException("Unknown ValueSet URI: " + theUri);
} }
String code = theCode.getValue(); source = (ValueSet) ids.getResources(0, 1).get(0);
String system = toStringOrNull(theSystem);
valueSetIds = findCodeSystemIdsContainingSystemAndCode(code, system);
} }
for (IIdType nextId : valueSetIds) { return expand(source, theFilter);
ValueSet expansion = expand(nextId, null, theRequestDetails);
List<ExpansionContains> contains = expansion.getExpansion().getContains();
ValidateCodeResult result = validateCodeIsInContains(contains, toStringOrNull(theSystem), toStringOrNull(theCode), theCoding, theCodeableConcept);
if (result != null) {
if (theDisplay != null && isNotBlank(theDisplay.getValue()) && isNotBlank(result.getDisplay())) {
if (!theDisplay.getValue().equals(result.getDisplay())) {
return new ValidateCodeResult(false, "Display for code does not match", result.getDisplay());
}
}
return result;
}
}
return new ValidateCodeResult(false, "Code not found", null);
} }
@Override @Override
public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem) { public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem) {
if (theSystem != null && theSystem.startsWith("http://hl7.org/fhir/")) { if (theSystem != null && theSystem.startsWith("http://hl7.org/fhir/")) {
return Collections.singletonList((IIdType)new IdDt(theSystem)); return Collections.singletonList((IIdType) new IdDt(theSystem));
} }
List<IIdType> valueSetIds; List<IIdType> valueSetIds;
Set<Long> ids = searchForIds(ValueSet.SP_CODE, new TokenParam(theSystem, theCode)); Set<Long> ids = searchForIds(new SearchParameterMap(ValueSet.SP_CODE, new TokenParam(theSystem, theCode)));
valueSetIds = new ArrayList<IIdType>(); valueSetIds = new ArrayList<IIdType>();
for (Long next : ids) { for (Long next : ids) {
valueSetIds.add(new IdDt("ValueSet", next)); valueSetIds.add(new IdDt("ValueSet", next));
@ -246,45 +174,38 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
return valueSetIds; return valueSetIds;
} }
private static boolean multiXor(boolean... theValues) { private ValueSet loadValueSetForExpansion(IIdType theId) {
int count = 0; if (theId.getValue().startsWith("http://hl7.org/fhir/")) {
for (int i = 0; i < theValues.length; i++) { org.hl7.fhir.instance.model.ValueSet valueSet = myValidationSupport.fetchResource(myRiCtx, org.hl7.fhir.instance.model.ValueSet.class, theId.getValue());
if (theValues[i]) { if (valueSet != null) {
count++; return getContext().newJsonParser().parseResource(ValueSet.class, myRiCtx.newJsonParser().encodeResourceToString(valueSet));
} }
} }
return count == 1; BaseHasResource sourceEntity = readEntity(theId);
if (sourceEntity == null) {
throw new ResourceNotFoundException(theId);
}
ValueSet source = (ValueSet) toResource(sourceEntity, false);
return source;
} }
private String toStringOrNull(IPrimitiveType<String> thePrimitive) { private LookupCodeResult lookup(List<ExpansionContains> theContains, String theSystem, String theCode) {
return thePrimitive != null ? thePrimitive.getValue() : null; for (ExpansionContains nextCode : theContains) {
}
private ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult validateCodeIsInContains(List<ExpansionContains> contains, String theSystem, String theCode, CodingDt theCoding,
CodeableConceptDt theCodeableConcept) {
for (ExpansionContains nextCode : contains) {
ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult result = validateCodeIsInContains(nextCode.getContains(), theSystem, theCode, theCoding, theCodeableConcept);
if (result != null) {
return result;
}
String system = nextCode.getSystem(); String system = nextCode.getSystem();
String code = nextCode.getCode(); String code = nextCode.getCode();
if (theSystem.equals(system) && theCode.equals(code)) {
if (isNotBlank(theCode)) { LookupCodeResult retVal = new LookupCodeResult();
if (theCode.equals(code) && (isBlank(theSystem) || theSystem.equals(system))) { retVal.setSearchedForCode(code);
return new ValidateCodeResult(true, "Validation succeeded", nextCode.getDisplay()); retVal.setSearchedForSystem(system);
} retVal.setFound(true);
} else if (theCoding != null) { if (nextCode.getAbstract() != null) {
if (StringUtils.equals(system, theCoding.getSystem()) && StringUtils.equals(code, theCoding.getCode())) { retVal.setCodeIsAbstract(nextCode.getAbstract().booleanValue());
return new ValidateCodeResult(true, "Validation succeeded", nextCode.getDisplay());
}
} else {
for (CodingDt next : theCodeableConcept.getCoding()) {
if (StringUtils.equals(system, next.getSystem()) && StringUtils.equals(code, next.getCode())) {
return new ValidateCodeResult(true, "Validation succeeded", nextCode.getDisplay());
}
} }
retVal.setCodeDisplay(nextCode.getDisplay());
retVal.setCodeSystemVersion(nextCode.getVersion());
retVal.setCodeSystemDisplayName("Unknown"); // TODO: implement
return retVal;
} }
} }
@ -332,28 +253,12 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
return retVal; return retVal;
} }
private LookupCodeResult lookup(List<ExpansionContains> theContains, String theSystem, String theCode) { @Override
for (ExpansionContains nextCode : theContains) { @PostConstruct
public void postConstruct() {
String system = nextCode.getSystem(); super.postConstruct();
String code = nextCode.getCode(); myDefaultProfileValidationSupport = new DefaultProfileValidationSupport();
if (theSystem.equals(system) && theCode.equals(code)) { myValidationSupport = new ValidationSupportChain(myDefaultProfileValidationSupport, myJpaValidationSupport);
LookupCodeResult retVal = new LookupCodeResult();
retVal.setSearchedForCode(code);
retVal.setSearchedForSystem(system);
retVal.setFound(true);
if (nextCode.getAbstract() != null) {
retVal.setCodeIsAbstract(nextCode.getAbstract().booleanValue());
}
retVal.setCodeDisplay(nextCode.getDisplay());
retVal.setCodeSystemVersion(nextCode.getVersion());
retVal.setCodeSystemDisplayName("Unknown"); // TODO: implement
return retVal;
}
}
return null;
} }
@Override @Override
@ -361,5 +266,101 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
// nothing // nothing
} }
private String toStringOrNull(IPrimitiveType<String> thePrimitive) {
return thePrimitive != null ? thePrimitive.getValue() : null;
}
@Override
public ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult validateCode(IPrimitiveType<String> theValueSetIdentifier, IIdType theId, IPrimitiveType<String> theCode,
IPrimitiveType<String> theSystem, IPrimitiveType<String> theDisplay, CodingDt theCoding, CodeableConceptDt theCodeableConcept, RequestDetails theRequestDetails) {
List<IIdType> valueSetIds;
boolean haveCodeableConcept = theCodeableConcept != null && theCodeableConcept.getCoding().size() > 0;
boolean haveCoding = theCoding != null && theCoding.isEmpty() == false;
boolean haveCode = theCode != null && theCode.isEmpty() == false;
if (!haveCodeableConcept && !haveCoding && !haveCode) {
throw new InvalidRequestException("No code, coding, or codeableConcept provided to validate");
}
if (!multiXor(haveCodeableConcept, haveCoding, haveCode)) {
throw new InvalidRequestException("$validate-code can only validate (system AND code) OR (coding) OR (codeableConcept)");
}
boolean haveIdentifierParam = theValueSetIdentifier != null && theValueSetIdentifier.isEmpty() == false;
if (theId != null) {
valueSetIds = Collections.singletonList(theId);
} else if (haveIdentifierParam) {
Set<Long> ids = searchForIds(new SearchParameterMap(ValueSet.SP_IDENTIFIER, new TokenParam(null, theValueSetIdentifier.getValue())));
valueSetIds = new ArrayList<IIdType>();
for (Long next : ids) {
valueSetIds.add(new IdDt("ValueSet", next));
}
} else {
if (theCode == null || theCode.isEmpty()) {
throw new InvalidRequestException("Either ValueSet ID or ValueSet identifier or system and code must be provided. Unable to validate.");
}
String code = theCode.getValue();
String system = toStringOrNull(theSystem);
valueSetIds = findCodeSystemIdsContainingSystemAndCode(code, system);
}
for (IIdType nextId : valueSetIds) {
ValueSet expansion = expand(nextId, null, theRequestDetails);
List<ExpansionContains> contains = expansion.getExpansion().getContains();
ValidateCodeResult result = validateCodeIsInContains(contains, toStringOrNull(theSystem), toStringOrNull(theCode), theCoding, theCodeableConcept);
if (result != null) {
if (theDisplay != null && isNotBlank(theDisplay.getValue()) && isNotBlank(result.getDisplay())) {
if (!theDisplay.getValue().equals(result.getDisplay())) {
return new ValidateCodeResult(false, "Display for code does not match", result.getDisplay());
}
}
return result;
}
}
return new ValidateCodeResult(false, "Code not found", null);
}
private ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult validateCodeIsInContains(List<ExpansionContains> contains, String theSystem, String theCode, CodingDt theCoding,
CodeableConceptDt theCodeableConcept) {
for (ExpansionContains nextCode : contains) {
ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult result = validateCodeIsInContains(nextCode.getContains(), theSystem, theCode, theCoding, theCodeableConcept);
if (result != null) {
return result;
}
String system = nextCode.getSystem();
String code = nextCode.getCode();
if (isNotBlank(theCode)) {
if (theCode.equals(code) && (isBlank(theSystem) || theSystem.equals(system))) {
return new ValidateCodeResult(true, "Validation succeeded", nextCode.getDisplay());
}
} else if (theCoding != null) {
if (StringUtils.equals(system, theCoding.getSystem()) && StringUtils.equals(code, theCoding.getCode())) {
return new ValidateCodeResult(true, "Validation succeeded", nextCode.getDisplay());
}
} else {
for (CodingDt next : theCodeableConcept.getCoding()) {
if (StringUtils.equals(system, next.getSystem()) && StringUtils.equals(code, next.getCode())) {
return new ValidateCodeResult(true, "Validation succeeded", nextCode.getDisplay());
}
}
}
}
return null;
}
private static boolean multiXor(boolean... theValues) {
int count = 0;
for (int i = 0; i < theValues.length; i++) {
if (theValues[i]) {
count++;
}
}
return count == 1;
}
} }

View File

@ -178,11 +178,7 @@ public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
IBundleProvider search(SearchParameterMap theParams, RequestDetails theRequestDetails); IBundleProvider search(SearchParameterMap theParams, RequestDetails theRequestDetails);
Set<Long> searchForIds(Map<String, IQueryParameterType> theParams); Set<Long> searchForIds(SearchParameterMap theParams);
Set<Long> searchForIds(String theParameterName, IQueryParameterType theValue);
Set<Long> searchForIdsWithAndOr(SearchParameterMap theParams);
/** /**
* Takes a map of incoming raw search parameters and translates/parses them into * Takes a map of incoming raw search parameters and translates/parses them into

View File

@ -41,6 +41,7 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem; import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao; import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
import ca.uhn.fhir.jpa.entity.ResourceTable; import ca.uhn.fhir.jpa.entity.ResourceTable;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion; import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
@ -65,7 +66,7 @@ public class FhirResourceDaoCodeSystemDstu3 extends FhirResourceDaoDstu3<CodeSys
@Override @Override
public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem) { public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem) {
List<IIdType> valueSetIds; List<IIdType> valueSetIds;
Set<Long> ids = searchForIds(CodeSystem.SP_CODE, new TokenParam(theSystem, theCode)); Set<Long> ids = searchForIds(new SearchParameterMap(CodeSystem.SP_CODE, new TokenParam(theSystem, theCode)));
valueSetIds = new ArrayList<IIdType>(); valueSetIds = new ArrayList<IIdType>();
for (Long next : ids) { for (Long next : ids) {
valueSetIds.add(new IdType("CodeSystem", next)); valueSetIds.add(new IdType("CodeSystem", next));

View File

@ -1590,7 +1590,7 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test {
QuantityParam param; QuantityParam param;
Set<Long> found; Set<Long> found;
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, null); param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, null);
found = myObservationDao.searchForIds("value-quantity", param); found = myObservationDao.searchForIds(new SearchParameterMap("value-quantity", param));
int initialSize = found.size(); int initialSize = found.size();
Observation o = new Observation(); Observation o = new Observation();
@ -1601,19 +1601,19 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test {
myObservationDao.create(o, mySrd); myObservationDao.create(o, mySrd);
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, null); param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, null);
found = myObservationDao.searchForIds("value-quantity", param); found = myObservationDao.searchForIds(new SearchParameterMap("value-quantity", param));
assertEquals(1 + initialSize, found.size()); assertEquals(1 + initialSize, found.size());
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, methodName + "units"); param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, methodName + "units");
found = myObservationDao.searchForIds("value-quantity", param); found = myObservationDao.searchForIds(new SearchParameterMap("value-quantity", param));
assertEquals(1, found.size()); assertEquals(1, found.size());
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), "urn:bar:" + methodName, null); param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), "urn:bar:" + methodName, null);
found = myObservationDao.searchForIds("value-quantity", param); found = myObservationDao.searchForIds(new SearchParameterMap("value-quantity", param));
assertEquals(1, found.size()); assertEquals(1, found.size());
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), "urn:bar:" + methodName, methodName + "units"); param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), "urn:bar:" + methodName, methodName + "units");
found = myObservationDao.searchForIds("value-quantity", param); found = myObservationDao.searchForIds(new SearchParameterMap("value-quantity", param));
assertEquals(1, found.size()); assertEquals(1, found.size());
} }

View File

@ -237,7 +237,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
assertThat(toUnqualifiedVersionlessIdValues(found), hasItem(id2.getValue())); assertThat(toUnqualifiedVersionlessIdValues(found), hasItem(id2.getValue()));
} }
{ {
Set<Long> found = myObservationDao.searchForIds(Observation.SP_DATE, new DateParam(">2016-01-02")); Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2016-01-02")));
assertThat(found, not(hasItem(id2.getIdPartAsLong()))); assertThat(found, not(hasItem(id2.getIdPartAsLong())));
} }
} }
@ -1624,13 +1624,13 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
"}\n"; "}\n";
//@formatter:on //@formatter:on
Set<Long> val = myOrganizationDao.searchForIds("name", new StringParam("P")); Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
int initial = val.size(); int initial = val.size();
Organization org = myFhirCtx.newJsonParser().parseResource(Organization.class, inputStr); Organization org = myFhirCtx.newJsonParser().parseResource(Organization.class, inputStr);
myOrganizationDao.create(org, mySrd); myOrganizationDao.create(org, mySrd);
val = myOrganizationDao.searchForIds("name", new StringParam("P")); val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
assertEquals(initial + 1, val.size()); assertEquals(initial + 1, val.size());
} }
@ -2783,19 +2783,19 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
assertThat(str.length(), greaterThan(ResourceIndexedSearchParamString.MAX_LENGTH)); assertThat(str.length(), greaterThan(ResourceIndexedSearchParamString.MAX_LENGTH));
Set<Long> val = myOrganizationDao.searchForIds("name", new StringParam("P")); Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
int initial = val.size(); int initial = val.size();
myOrganizationDao.create(org, mySrd); myOrganizationDao.create(org, mySrd);
val = myOrganizationDao.searchForIds("name", new StringParam("P")); val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
assertEquals(initial + 0, val.size()); assertEquals(initial + 0, val.size());
val = myOrganizationDao.searchForIds("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH))); val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH))));
assertEquals(initial + 1, val.size()); assertEquals(initial + 1, val.size());
try { try {
myOrganizationDao.searchForIds("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH + 1))); myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH + 1))));
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
// ok // ok
@ -2931,23 +2931,23 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
String subStr1 = longStr1.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); String subStr1 = longStr1.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
String subStr2 = longStr2.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); String subStr2 = longStr2.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
Set<Long> val = myOrganizationDao.searchForIds("type", new IdentifierDt(subStr1, subStr2)); Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new IdentifierDt(subStr1, subStr2)));
int initial = val.size(); int initial = val.size();
myOrganizationDao.create(org, mySrd); myOrganizationDao.create(org, mySrd);
val = myOrganizationDao.searchForIds("type", new IdentifierDt(subStr1, subStr2)); val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new IdentifierDt(subStr1, subStr2)));
assertEquals(initial + 1, val.size()); assertEquals(initial + 1, val.size());
try { try {
myOrganizationDao.searchForIds("type", new IdentifierDt(longStr1, subStr2)); myOrganizationDao.searchForIds(new SearchParameterMap("type", new IdentifierDt(longStr1, subStr2)));
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
// ok // ok
} }
try { try {
myOrganizationDao.searchForIds("type", new IdentifierDt(subStr1, longStr2)); myOrganizationDao.searchForIds(new SearchParameterMap("type", new IdentifierDt(subStr1, longStr2)));
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
// ok // ok

View File

@ -28,6 +28,7 @@ import org.junit.AfterClass;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.Tag; import ca.uhn.fhir.model.api.Tag;
@ -245,7 +246,7 @@ public class FhirResourceDaoDstu2UpdateTest extends BaseJpaDstu2Test {
p2.addName().addFamily("Tester").addGiven("testUpdateMaintainsSearchParamsDstu2BBB"); p2.addName().addFamily("Tester").addGiven("testUpdateMaintainsSearchParamsDstu2BBB");
myPatientDao.create(p2, mySrd).getId(); myPatientDao.create(p2, mySrd).getId();
Set<Long> ids = myPatientDao.searchForIds(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2AAA")); Set<Long> ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2AAA")));
assertEquals(1, ids.size()); assertEquals(1, ids.size());
assertThat(ids, contains(p1id.getIdPartAsLong())); assertThat(ids, contains(p1id.getIdPartAsLong()));
@ -254,10 +255,10 @@ public class FhirResourceDaoDstu2UpdateTest extends BaseJpaDstu2Test {
MethodOutcome update2 = myPatientDao.update(p1, mySrd); MethodOutcome update2 = myPatientDao.update(p1, mySrd);
IIdType p1id2 = update2.getId(); IIdType p1id2 = update2.getId();
ids = myPatientDao.searchForIds(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2AAA")); ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2AAA")));
assertEquals(0, ids.size()); assertEquals(0, ids.size());
ids = myPatientDao.searchForIds(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2BBB")); ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2BBB")));
assertEquals(2, ids.size()); assertEquals(2, ids.size());
// Make sure vreads work // Make sure vreads work

View File

@ -230,11 +230,11 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
IIdType id2 = myObservationDao.create(o2, mySrd).getId(); IIdType id2 = myObservationDao.create(o2, mySrd).getId();
{ {
Set<Long> found = myObservationDao.searchForIds(Observation.SP_DATE, new DateParam(">2001-01-02")); Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2001-01-02")));
assertThat(found, hasItem(id2.getIdPartAsLong())); assertThat(found, hasItem(id2.getIdPartAsLong()));
} }
{ {
Set<Long> found = myObservationDao.searchForIds(Observation.SP_DATE, new DateParam(">2016-01-02")); Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2016-01-02")));
assertThat(found, not(hasItem(id2.getIdPartAsLong()))); assertThat(found, not(hasItem(id2.getIdPartAsLong())));
} }
} }
@ -2016,13 +2016,13 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
"}\n"; "}\n";
//@formatter:on //@formatter:on
Set<Long> val = myOrganizationDao.searchForIds("name", new StringParam("P")); Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
int initial = val.size(); int initial = val.size();
Organization org = myFhirCtx.newJsonParser().parseResource(Organization.class, inputStr); Organization org = myFhirCtx.newJsonParser().parseResource(Organization.class, inputStr);
myOrganizationDao.create(org, mySrd); myOrganizationDao.create(org, mySrd);
val = myOrganizationDao.searchForIds("name", new StringParam("P")); val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
assertEquals(initial + 1, val.size()); assertEquals(initial + 1, val.size());
} }
@ -3237,19 +3237,19 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
assertThat(str.length(), greaterThan(ResourceIndexedSearchParamString.MAX_LENGTH)); assertThat(str.length(), greaterThan(ResourceIndexedSearchParamString.MAX_LENGTH));
Set<Long> val = myOrganizationDao.searchForIds("name", new StringParam("P")); Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
int initial = val.size(); int initial = val.size();
myOrganizationDao.create(org, mySrd); myOrganizationDao.create(org, mySrd);
val = myOrganizationDao.searchForIds("name", new StringParam("P")); val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
assertEquals(initial + 0, val.size()); assertEquals(initial + 0, val.size());
val = myOrganizationDao.searchForIds("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH))); val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH))));
assertEquals(initial + 1, val.size()); assertEquals(initial + 1, val.size());
try { try {
myOrganizationDao.searchForIds("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH + 1))); myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH + 1))));
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
// ok // ok
@ -3416,23 +3416,23 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
String subStr1 = longStr1.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); String subStr1 = longStr1.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
String subStr2 = longStr2.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); String subStr2 = longStr2.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
Set<Long> val = myOrganizationDao.searchForIds("type", new TokenParam(subStr1, subStr2)); Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, subStr2)));
int initial = val.size(); int initial = val.size();
myOrganizationDao.create(org, mySrd); myOrganizationDao.create(org, mySrd);
val = myOrganizationDao.searchForIds("type", new TokenParam(subStr1, subStr2)); val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, subStr2)));
assertEquals(initial + 1, val.size()); assertEquals(initial + 1, val.size());
try { try {
myOrganizationDao.searchForIds("type", new TokenParam(longStr1, subStr2)); myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(longStr1, subStr2)));
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
// ok // ok
} }
try { try {
myOrganizationDao.searchForIds("type", new TokenParam(subStr1, longStr2)); myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, longStr2)));
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
// ok // ok

View File

@ -37,6 +37,7 @@ import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
@ -352,7 +353,7 @@ public class FhirResourceDaoDstu3UpdateTest extends BaseJpaDstu3Test {
p2.addName().setFamily("Tester").addGiven("testUpdateMaintainsSearchParamsDstu2BBB"); p2.addName().setFamily("Tester").addGiven("testUpdateMaintainsSearchParamsDstu2BBB");
myPatientDao.create(p2, mySrd).getId(); myPatientDao.create(p2, mySrd).getId();
Set<Long> ids = myPatientDao.searchForIds(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2AAA")); Set<Long> ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2AAA")));
assertEquals(1, ids.size()); assertEquals(1, ids.size());
assertThat(ids, contains(p1id.getIdPartAsLong())); assertThat(ids, contains(p1id.getIdPartAsLong()));
@ -361,10 +362,10 @@ public class FhirResourceDaoDstu3UpdateTest extends BaseJpaDstu3Test {
MethodOutcome update2 = myPatientDao.update(p1, mySrd); MethodOutcome update2 = myPatientDao.update(p1, mySrd);
IIdType p1id2 = update2.getId(); IIdType p1id2 = update2.getId();
ids = myPatientDao.searchForIds(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2AAA")); ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2AAA")));
assertEquals(0, ids.size()); assertEquals(0, ids.size());
ids = myPatientDao.searchForIds(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2BBB")); ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2BBB")));
assertEquals(2, ids.size()); assertEquals(2, ids.size());
// Make sure vreads work // Make sure vreads work