From 21b6fb5e7c673231e40ddbea7504d2f0b775def3 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Tue, 9 Aug 2022 20:18:52 +1000 Subject: [PATCH] Fix loading canonical resources so that duplicates with different versions is OK --- .../fhir/r5/context/BaseWorkerContext.java | 63 ++++++++++++++----- .../r5/context/CanonicalResourceManager.java | 7 +++ .../hl7/fhir/r5/context/IWorkerContext.java | 4 ++ 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java index ec56f847f..a407664a0 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java @@ -111,6 +111,7 @@ import org.hl7.fhir.r5.terminologies.ValueSetCheckerSimple; import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass; import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; import org.hl7.fhir.r5.terminologies.ValueSetExpanderSimple; +import org.hl7.fhir.r5.utils.PackageHackerR5; import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier; import org.hl7.fhir.utilities.OIDUtils; @@ -121,6 +122,7 @@ import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.i18n.I18nBase; import org.hl7.fhir.utilities.i18n.I18nConstants; +import org.hl7.fhir.utilities.npm.PackageHacker; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; import org.hl7.fhir.utilities.validation.ValidationOptions; @@ -312,6 +314,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte public void registerResourceFromPackage(CanonicalResourceProxy r, PackageVersion packageInfo) throws FHIRException { + PackageHackerR5.fixLoadedResource(r, packageInfo); synchronized (lock) { if (r.getId() != null) { @@ -326,13 +329,14 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte } String url = r.getUrl(); - if (!allowLoadingDuplicates && hasResource(r.getType(), url)) { + if (!allowLoadingDuplicates && hasResourceVersion(r.getType(), url, r.getVersion()) && !packageInfo.isHTO()) { // spcial workaround for known problems with existing packages if (Utilities.existsInList(url, "http://hl7.org/fhir/SearchParameter/example")) { return; } - throw new DefinitionException(formatMessage(I18nConstants.DUPLICATE_RESOURCE_, url, - fetchResourceWithException(r.getType(), url).fhirType())); + CanonicalResource ex = fetchResourceWithException(r.getType(), url); + throw new DefinitionException(formatMessage(I18nConstants.DUPLICATE_RESOURCE_, url, r.getVersion(), ex.getVersion(), + ex.fhirType())); } switch(r.getType()) { case "StructureDefinition": @@ -413,8 +417,9 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte if (Utilities.existsInList(url, "http://hl7.org/fhir/SearchParameter/example")) { return; } - throw new DefinitionException(formatMessage(I18nConstants.DUPLICATE_RESOURCE_, url, - fetchResourceWithException(r.getClass(), url).fhirType())); + CanonicalResource ex = (CanonicalResource) fetchResourceWithException(r.getClass(), url); + throw new DefinitionException(formatMessage(I18nConstants.DUPLICATE_RESOURCE_, url, ((CanonicalResource) r).getVersion(), ex.getVersion(), + ex.fhirType())); } if (r instanceof StructureDefinition) { StructureDefinition sd = (StructureDefinition) m; @@ -1364,15 +1369,15 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte } public T fetchResourceWithException(String cls, String uri) throws FHIRException { - return fetchResourceWithException(cls, uri, null); + return fetchResourceWithExceptionByVersion(cls, uri, null, null); } public T fetchResourceWithException(Class class_, String uri, CanonicalResource source) throws FHIRException { - return fetchResourceWithException(class_, uri, null, source); + return fetchResourceWithExceptionByVersion(class_, uri, null, source); } @SuppressWarnings("unchecked") - public T fetchResourceWithException(Class class_, String uri, String version, CanonicalResource source) throws FHIRException { + public T fetchResourceWithExceptionByVersion(Class class_, String uri, String version, CanonicalResource source) throws FHIRException { if (uri == null) { return null; } @@ -1382,9 +1387,13 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte } synchronized (lock) { - if (uri.contains("|")) { - version = uri.substring(uri.lastIndexOf("|")+1); - uri = uri.substring(0, uri.lastIndexOf("|")); + if (version == null) { + if (uri.contains("|")) { + version = uri.substring(uri.lastIndexOf("|")+1); + uri = uri.substring(0, uri.lastIndexOf("|")); + } + } else { + assert !uri.contains("|"); } if (uri.contains("#")) { uri = uri.substring(0, uri.indexOf("#")); @@ -1556,7 +1565,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte } @SuppressWarnings("unchecked") - public T fetchResourceWithException(String cls, String uri, CanonicalResource source) throws FHIRException { + public T fetchResourceWithExceptionByVersion(String cls, String uri, String version, CanonicalResource source) throws FHIRException { if (uri == null) { return null; } @@ -1566,10 +1575,14 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte } synchronized (lock) { - String version = null; - if (uri.contains("|")) { - version = uri.substring(uri.lastIndexOf("|")+1); - uri = uri.substring(0, uri.lastIndexOf("|")); + if (version == null) { + if (uri.contains("|")) { + version = uri.substring(uri.lastIndexOf("|")+1); + uri = uri.substring(0, uri.lastIndexOf("|")); + } + } else { + boolean b = !uri.contains("|"); + assert b; } if (uri.contains("#")) { uri = uri.substring(0, uri.indexOf("#")); @@ -1728,7 +1741,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte public T fetchResource(Class class_, String uri, String version) { try { - return fetchResourceWithException(class_, uri, version, null); + return fetchResourceWithExceptionByVersion(class_, uri, version, null); } catch (FHIRException e) { throw new Error(e); } @@ -1751,6 +1764,22 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte } } + public boolean hasResourceVersion(Class class_, String uri, String version) { + try { + return fetchResourceWithExceptionByVersion(class_, uri, version, null) != null; + } catch (Exception e) { + return false; + } + } + + public boolean hasResourceVersion(String cls, String uri, String version) { + try { + return fetchResourceWithExceptionByVersion(cls, uri, version, null) != null; + } catch (Exception e) { + return false; + } + } + public TranslationServices translator() { return translator; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/CanonicalResourceManager.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/CanonicalResourceManager.java index 0ad221c62..6ab1b474c 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/CanonicalResourceManager.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/CanonicalResourceManager.java @@ -86,6 +86,13 @@ public class CanonicalResourceManager { @Override public String toString() { return type+"/"+id+": "+url+"|"+version; + } + + public void hack(String url, String version) { + this.url = url; + this.version = version; + getResource().setUrl(url).setVersion(version); + } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/IWorkerContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/IWorkerContext.java index 3521f353d..40f3dedbd 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/IWorkerContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/IWorkerContext.java @@ -193,6 +193,10 @@ public interface IWorkerContext { public Date getDate() { return date; } + public boolean isHTO() { + boolean b = id.startsWith("hl7.terminology.r"); + return b; + } }