Fix loading canonical resources so that duplicates with different versions is OK

This commit is contained in:
Grahame Grieve 2022-08-09 20:18:52 +10:00
parent a16034106a
commit 21b6fb5e7c
3 changed files with 57 additions and 17 deletions

View File

@ -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.TerminologyServiceErrorClass;
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
import org.hl7.fhir.r5.terminologies.ValueSetExpanderSimple; 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.ToolingExtensions;
import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier; import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier;
import org.hl7.fhir.utilities.OIDUtils; 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.VersionUtilities;
import org.hl7.fhir.utilities.i18n.I18nBase; import org.hl7.fhir.utilities.i18n.I18nBase;
import org.hl7.fhir.utilities.i18n.I18nConstants; 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.IssueSeverity;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
import org.hl7.fhir.utilities.validation.ValidationOptions; 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 { public void registerResourceFromPackage(CanonicalResourceProxy r, PackageVersion packageInfo) throws FHIRException {
PackageHackerR5.fixLoadedResource(r, packageInfo);
synchronized (lock) { synchronized (lock) {
if (r.getId() != null) { if (r.getId() != null) {
@ -326,13 +329,14 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
} }
String url = r.getUrl(); 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 // spcial workaround for known problems with existing packages
if (Utilities.existsInList(url, "http://hl7.org/fhir/SearchParameter/example")) { if (Utilities.existsInList(url, "http://hl7.org/fhir/SearchParameter/example")) {
return; return;
} }
throw new DefinitionException(formatMessage(I18nConstants.DUPLICATE_RESOURCE_, url, CanonicalResource ex = fetchResourceWithException(r.getType(), url);
fetchResourceWithException(r.getType(), url).fhirType())); throw new DefinitionException(formatMessage(I18nConstants.DUPLICATE_RESOURCE_, url, r.getVersion(), ex.getVersion(),
ex.fhirType()));
} }
switch(r.getType()) { switch(r.getType()) {
case "StructureDefinition": case "StructureDefinition":
@ -413,8 +417,9 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
if (Utilities.existsInList(url, "http://hl7.org/fhir/SearchParameter/example")) { if (Utilities.existsInList(url, "http://hl7.org/fhir/SearchParameter/example")) {
return; return;
} }
throw new DefinitionException(formatMessage(I18nConstants.DUPLICATE_RESOURCE_, url, CanonicalResource ex = (CanonicalResource) fetchResourceWithException(r.getClass(), url);
fetchResourceWithException(r.getClass(), url).fhirType())); throw new DefinitionException(formatMessage(I18nConstants.DUPLICATE_RESOURCE_, url, ((CanonicalResource) r).getVersion(), ex.getVersion(),
ex.fhirType()));
} }
if (r instanceof StructureDefinition) { if (r instanceof StructureDefinition) {
StructureDefinition sd = (StructureDefinition) m; StructureDefinition sd = (StructureDefinition) m;
@ -1364,15 +1369,15 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
} }
public <T extends Resource> T fetchResourceWithException(String cls, String uri) throws FHIRException { public <T extends Resource> T fetchResourceWithException(String cls, String uri) throws FHIRException {
return fetchResourceWithException(cls, uri, null); return fetchResourceWithExceptionByVersion(cls, uri, null, null);
} }
public <T extends Resource> T fetchResourceWithException(Class<T> class_, String uri, CanonicalResource source) throws FHIRException { public <T extends Resource> T fetchResourceWithException(Class<T> class_, String uri, CanonicalResource source) throws FHIRException {
return fetchResourceWithException(class_, uri, null, source); return fetchResourceWithExceptionByVersion(class_, uri, null, source);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends Resource> T fetchResourceWithException(Class<T> class_, String uri, String version, CanonicalResource source) throws FHIRException { public <T extends Resource> T fetchResourceWithExceptionByVersion(Class<T> class_, String uri, String version, CanonicalResource source) throws FHIRException {
if (uri == null) { if (uri == null) {
return null; return null;
} }
@ -1382,10 +1387,14 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
} }
synchronized (lock) { synchronized (lock) {
if (version == null) {
if (uri.contains("|")) { if (uri.contains("|")) {
version = uri.substring(uri.lastIndexOf("|")+1); version = uri.substring(uri.lastIndexOf("|")+1);
uri = uri.substring(0, uri.lastIndexOf("|")); uri = uri.substring(0, uri.lastIndexOf("|"));
} }
} else {
assert !uri.contains("|");
}
if (uri.contains("#")) { if (uri.contains("#")) {
uri = uri.substring(0, uri.indexOf("#")); uri = uri.substring(0, uri.indexOf("#"));
} }
@ -1556,7 +1565,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends Resource> T fetchResourceWithException(String cls, String uri, CanonicalResource source) throws FHIRException { public <T extends Resource> T fetchResourceWithExceptionByVersion(String cls, String uri, String version, CanonicalResource source) throws FHIRException {
if (uri == null) { if (uri == null) {
return null; return null;
} }
@ -1566,11 +1575,15 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
} }
synchronized (lock) { synchronized (lock) {
String version = null; if (version == null) {
if (uri.contains("|")) { if (uri.contains("|")) {
version = uri.substring(uri.lastIndexOf("|")+1); version = uri.substring(uri.lastIndexOf("|")+1);
uri = uri.substring(0, uri.lastIndexOf("|")); uri = uri.substring(0, uri.lastIndexOf("|"));
} }
} else {
boolean b = !uri.contains("|");
assert b;
}
if (uri.contains("#")) { if (uri.contains("#")) {
uri = uri.substring(0, uri.indexOf("#")); uri = uri.substring(0, uri.indexOf("#"));
} }
@ -1728,7 +1741,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
public <T extends Resource> T fetchResource(Class<T> class_, String uri, String version) { public <T extends Resource> T fetchResource(Class<T> class_, String uri, String version) {
try { try {
return fetchResourceWithException(class_, uri, version, null); return fetchResourceWithExceptionByVersion(class_, uri, version, null);
} catch (FHIRException e) { } catch (FHIRException e) {
throw new Error(e); throw new Error(e);
} }
@ -1751,6 +1764,22 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
} }
} }
public <T extends Resource> boolean hasResourceVersion(Class<T> class_, String uri, String version) {
try {
return fetchResourceWithExceptionByVersion(class_, uri, version, null) != null;
} catch (Exception e) {
return false;
}
}
public <T extends Resource> boolean hasResourceVersion(String cls, String uri, String version) {
try {
return fetchResourceWithExceptionByVersion(cls, uri, version, null) != null;
} catch (Exception e) {
return false;
}
}
public TranslationServices translator() { public TranslationServices translator() {
return translator; return translator;

View File

@ -87,6 +87,13 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
public String toString() { public String toString() {
return type+"/"+id+": "+url+"|"+version; return type+"/"+id+": "+url+"|"+version;
} }
public void hack(String url, String version) {
this.url = url;
this.version = version;
getResource().setUrl(url).setVersion(version);
}
} }
public class CanonicalListSorter implements Comparator<CanonicalResource> { public class CanonicalListSorter implements Comparator<CanonicalResource> {

View File

@ -193,6 +193,10 @@ public interface IWorkerContext {
public Date getDate() { public Date getDate() {
return date; return date;
} }
public boolean isHTO() {
boolean b = id.startsWith("hl7.terminology.r");
return b;
}
} }