Refactor to support all new tests
This commit is contained in:
parent
78271a2931
commit
ac7c684437
|
@ -33,17 +33,20 @@ import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||||
import ca.uhn.fhir.jpa.model.cross.IResourceLookup;
|
import ca.uhn.fhir.jpa.model.cross.IResourceLookup;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.searchparam.extractor.IResourceLinkResolver;
|
import ca.uhn.fhir.jpa.searchparam.extractor.IResourceLinkResolver;
|
||||||
|
import ca.uhn.fhir.mdm.util.CanonicalIdentifier;
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
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;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||||
import ca.uhn.fhir.util.HapiExtensions;
|
import ca.uhn.fhir.util.HapiExtensions;
|
||||||
|
import ca.uhn.fhir.util.TerserUtil;
|
||||||
import org.hl7.fhir.instance.model.api.IBase;
|
import org.hl7.fhir.instance.model.api.IBase;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseExtension;
|
import org.hl7.fhir.instance.model.api.IBaseExtension;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
|
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseReference;
|
import org.hl7.fhir.instance.model.api.IBaseReference;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
@ -122,11 +125,7 @@ public class DaoResourceLinkResolver implements IResourceLinkResolver {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
T newResource = (T) missingResourceDef.newInstance();
|
T newResource = (T) missingResourceDef.newInstance();
|
||||||
|
|
||||||
if (newResource instanceof IBaseHasExtensions) {
|
tryToAddPlaceholderExtensionToResource(newResource);
|
||||||
IBaseExtension<?, ?> extension = ((IBaseHasExtensions) newResource).addExtension();
|
|
||||||
extension.setUrl(HapiExtensions.EXT_RESOURCE_PLACEHOLDER);
|
|
||||||
extension.setValue(myContext.getPrimitiveBoolean(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
IFhirResourceDao<T> placeholderResourceDao = myDaoRegistry.getResourceDao(theType);
|
IFhirResourceDao<T> placeholderResourceDao = myDaoRegistry.getResourceDao(theType);
|
||||||
ourLog.debug("Automatically creating empty placeholder resource: {}", newResource.getIdElement().getValue());
|
ourLog.debug("Automatically creating empty placeholder resource: {}", newResource.getIdElement().getValue());
|
||||||
|
@ -146,26 +145,98 @@ public class DaoResourceLinkResolver implements IResourceLinkResolver {
|
||||||
return Optional.ofNullable(valueOf);
|
return Optional.ofNullable(valueOf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T extends IBaseResource> void tryToAddPlaceholderExtensionToResource(T newResource) {
|
||||||
|
if (newResource instanceof IBaseHasExtensions) {
|
||||||
|
IBaseExtension<?, ?> extension = ((IBaseHasExtensions) newResource).addExtension();
|
||||||
|
extension.setUrl(HapiExtensions.EXT_RESOURCE_PLACEHOLDER);
|
||||||
|
extension.setValue(myContext.getPrimitiveBoolean(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private <T extends IBaseResource> void tryToCopyIdentifierFromReferenceToTargetResource(IBaseReference theSourceReference, RuntimeResourceDefinition theTargetResourceDef, T theTargetResource) {
|
private <T extends IBaseResource> void tryToCopyIdentifierFromReferenceToTargetResource(IBaseReference theSourceReference, RuntimeResourceDefinition theTargetResourceDef, T theTargetResource) {
|
||||||
boolean referenceHasIdentifier = theSourceReference.hasIdentifier();
|
// boolean referenceHasIdentifier = theSourceReference.hasIdentifier();
|
||||||
if (referenceHasIdentifier) {
|
CanonicalIdentifier referenceMatchUrlIdentifier = extractIdentifierFromUrl(theSourceReference.getReferenceElement().getValue());
|
||||||
BaseRuntimeChildDefinition targetIdentifier = theTargetResourceDef.getChildByName("identifier");
|
CanonicalIdentifier referenceIdentifier = extractIdentifierReference(theSourceReference);
|
||||||
if (targetIdentifier != null) {
|
|
||||||
BaseRuntimeElementDefinition<?> identifierElement = targetIdentifier.getChildByName("identifier");
|
|
||||||
String identifierElementName = identifierElement.getName();
|
|
||||||
boolean targetHasIdentifierElement = identifierElementName.equals("Identifier");
|
|
||||||
if (targetHasIdentifierElement) {
|
|
||||||
|
|
||||||
BaseRuntimeElementCompositeDefinition<?> referenceElement = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(theSourceReference.getClass());
|
if (referenceIdentifier == null && referenceMatchUrlIdentifier != null) {
|
||||||
BaseRuntimeChildDefinition referenceIdentifierChild = referenceElement.getChildByName("identifier");
|
addMatchUrlIdentifierToTargetResource(theTargetResourceDef, theTargetResource, referenceMatchUrlIdentifier);
|
||||||
Optional<IBase> identifierOpt = referenceIdentifierChild.getAccessor().getFirstValueOrNull(theSourceReference);
|
} else if (referenceIdentifier!= null && referenceMatchUrlIdentifier == null) {
|
||||||
identifierOpt.ifPresent(theIBase -> targetIdentifier.getMutator().addValue(theTargetResource, theIBase));
|
addSubjectIdentifierToTargetResource(theSourceReference, theTargetResourceDef, theTargetResource);
|
||||||
|
} else if (referenceIdentifier != null && referenceMatchUrlIdentifier != null) {
|
||||||
}
|
if (referenceIdentifier.equals(referenceMatchUrlIdentifier)) {
|
||||||
|
addSubjectIdentifierToTargetResource(theSourceReference, theTargetResourceDef, theTargetResource);
|
||||||
|
} else {
|
||||||
|
addSubjectIdentifierToTargetResource(theSourceReference, theTargetResourceDef, theTargetResource);
|
||||||
|
addMatchUrlIdentifierToTargetResource(theTargetResourceDef, theTargetResource, referenceMatchUrlIdentifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T extends IBaseResource> void addSubjectIdentifierToTargetResource(IBaseReference theSourceReference, RuntimeResourceDefinition theTargetResourceDef, T theTargetResource) {
|
||||||
|
BaseRuntimeChildDefinition targetIdentifier = theTargetResourceDef.getChildByName("identifier");
|
||||||
|
if (targetIdentifier != null) {
|
||||||
|
BaseRuntimeElementDefinition<?> identifierElement = targetIdentifier.getChildByName("identifier");
|
||||||
|
String identifierElementName = identifierElement.getName();
|
||||||
|
boolean targetHasIdentifierElement = identifierElementName.equals("Identifier");
|
||||||
|
if (targetHasIdentifierElement) {
|
||||||
|
|
||||||
|
BaseRuntimeElementCompositeDefinition<?> referenceElement = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(theSourceReference.getClass());
|
||||||
|
BaseRuntimeChildDefinition referenceIdentifierChild = referenceElement.getChildByName("identifier");
|
||||||
|
Optional<IBase> identifierOpt = referenceIdentifierChild.getAccessor().getFirstValueOrNull(theSourceReference);
|
||||||
|
identifierOpt.ifPresent(theIBase -> targetIdentifier.getMutator().addValue(theTargetResource, theIBase));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends IBaseResource> void addMatchUrlIdentifierToTargetResource(RuntimeResourceDefinition theTargetResourceDef, T theTargetResource, CanonicalIdentifier referenceMatchUrlIdentifier) {
|
||||||
|
BaseRuntimeChildDefinition identifierDefinition = theTargetResourceDef.getChildByName("identifier");
|
||||||
|
IBase identifierIBase = identifierDefinition.getChildByName("identifier").newInstance(identifierDefinition.getInstanceConstructorArguments());
|
||||||
|
IBase systemIBase = TerserUtil.newElement(myContext, "uri", referenceMatchUrlIdentifier.getSystemElement().getValueAsString());
|
||||||
|
IBase valueIBase = TerserUtil.newElement(myContext, "string", referenceMatchUrlIdentifier.getValueElement().getValueAsString());
|
||||||
|
//Set system in the IBase Identifier
|
||||||
|
|
||||||
|
BaseRuntimeElementDefinition<?> elementDefinition = myContext.getElementDefinition(identifierIBase.getClass());
|
||||||
|
|
||||||
|
BaseRuntimeChildDefinition systemDefinition = elementDefinition.getChildByName("system");
|
||||||
|
systemDefinition.getMutator().setValue(identifierIBase, systemIBase);
|
||||||
|
|
||||||
|
BaseRuntimeChildDefinition valueDefinition = elementDefinition.getChildByName("value");
|
||||||
|
valueDefinition.getMutator().setValue(identifierIBase, valueIBase);
|
||||||
|
|
||||||
|
//Set Value in the IBase identifier
|
||||||
|
identifierDefinition.getMutator().addValue(theTargetResource, identifierIBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CanonicalIdentifier extractIdentifierReference(IBaseReference theSourceReference) {
|
||||||
|
Optional<IBase> identifier = myContext.newFhirPath().evaluateFirst(theSourceReference, "identifier", IBase.class);
|
||||||
|
if (!identifier.isPresent()) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
CanonicalIdentifier canonicalIdentifier = new CanonicalIdentifier();
|
||||||
|
Optional<IPrimitiveType> system = myContext.newFhirPath().evaluateFirst(identifier.get(), "system", IPrimitiveType.class);
|
||||||
|
Optional<IPrimitiveType> value = myContext.newFhirPath().evaluateFirst(identifier.get(), "value", IPrimitiveType.class);
|
||||||
|
|
||||||
|
system.ifPresent(theIPrimitiveType -> canonicalIdentifier.setSystem(theIPrimitiveType.getValueAsString()));
|
||||||
|
value.ifPresent(theIPrimitiveType -> canonicalIdentifier.setValue(theIPrimitiveType.getValueAsString()));
|
||||||
|
return canonicalIdentifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CanonicalIdentifier extractIdentifierFromUrl(String theValue) {
|
||||||
|
if (!theValue.contains("identifier=")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
CanonicalIdentifier identifier = new CanonicalIdentifier();
|
||||||
|
String identifierString = theValue.substring(theValue.indexOf("=") + 1);
|
||||||
|
String[] split = identifierString.split("\\|");
|
||||||
|
if (split.length != 2) {
|
||||||
|
throw new IllegalArgumentException("Can't create a placeholder reference with identifier " + theValue + ". It is not a valid identifier");
|
||||||
|
}
|
||||||
|
identifier.setSystem(split[0]);
|
||||||
|
identifier.setValue(split[1]);
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validateTypeOrThrowException(Class<? extends IBaseResource> theType) {
|
public void validateTypeOrThrowException(Class<? extends IBaseResource> theType) {
|
||||||
myDaoRegistry.getDaoOrThrowException(theType);
|
myDaoRegistry.getDaoOrThrowException(theType);
|
||||||
|
|
|
@ -276,6 +276,7 @@ public class SearchParamWithInlineReferencesExtractor {
|
||||||
throw new InvalidRequestException(msg);
|
throw new InvalidRequestException(msg);
|
||||||
}
|
}
|
||||||
Class<? extends IBaseResource> matchResourceType = matchResourceDef.getImplementingClass();
|
Class<? extends IBaseResource> matchResourceType = matchResourceDef.getImplementingClass();
|
||||||
|
//Attempt to find the target reference before creating a placeholder
|
||||||
Set<ResourcePersistentId> matches = myMatchResourceUrlService.processMatchUrl(nextIdText, matchResourceType, theRequest);
|
Set<ResourcePersistentId> matches = myMatchResourceUrlService.processMatchUrl(nextIdText, matchResourceType, theRequest);
|
||||||
|
|
||||||
ResourcePersistentId match;
|
ResourcePersistentId match;
|
||||||
|
|
|
@ -423,13 +423,13 @@ public class FhirResourceDaoCreatePlaceholdersR4Test extends BaseJpaR4Test {
|
||||||
List<Identifier> identifiers = placeholderPat.getIdentifier();
|
List<Identifier> identifiers = placeholderPat.getIdentifier();
|
||||||
|
|
||||||
//inline match-url identifier
|
//inline match-url identifier
|
||||||
assertThat(identifiers.get(0).getSystem(), is(equalTo("http://foo")));
|
|
||||||
assertThat(identifiers.get(0).getValue(), is(equalTo("123")));
|
|
||||||
|
|
||||||
//subject identifier
|
|
||||||
assertThat(identifiers.get(1).getSystem(), is(equalTo("http://foo")));
|
assertThat(identifiers.get(1).getSystem(), is(equalTo("http://foo")));
|
||||||
assertThat(identifiers.get(1).getValue(), is(equalTo("123")));
|
assertThat(identifiers.get(1).getValue(), is(equalTo("123")));
|
||||||
|
|
||||||
|
//subject identifier
|
||||||
|
assertThat(identifiers.get(0).getSystem(), is(equalTo("http://bar")));
|
||||||
|
assertThat(identifiers.get(0).getValue(), is(equalTo("321")));
|
||||||
|
|
||||||
|
|
||||||
// Conditionally update a Patient with the same identifier
|
// Conditionally update a Patient with the same identifier
|
||||||
Patient patToConditionalUpdate = new Patient();
|
Patient patToConditionalUpdate = new Patient();
|
||||||
|
|
|
@ -49,6 +49,8 @@ public final class IdentifierUtil {
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves appropriate FHIR Identifier model instance based on the context version
|
* Retrieves appropriate FHIR Identifier model instance based on the context version
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue