From 4d99bcb0c63dd0b16c84373dc8fd782546514c5d Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 12 Feb 2020 18:07:21 +1100 Subject: [PATCH] better handling of circular dependencies in snap shot generator --- .../fhir/r5/conformance/ProfileUtilities.java | 16 ++++++++++++++-- .../org/hl7/fhir/r5/context/IWorkerContext.java | 3 ++- .../hl7/fhir/r5/context/SimpleWorkerContext.java | 6 ++++++ .../org/hl7/fhir/r5/test/PackageClientTests.java | 10 ++++++++++ 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java index 130946780..c80cc3877 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java @@ -463,6 +463,9 @@ public class ProfileUtilities extends TranslatingUtilities { if (derived == null) { throw new DefinitionException("no derived structure provided"); } + checkNotGenerating(base, "Base for generating a snapshot for the profile "+derived.getUrl()); + checkNotGenerating(derived, "Focus for generating a snapshot"); + derived.setUserData("profileutils.snapshot.generating", true); if (!base.hasType()) { throw new DefinitionException("Base profile "+base.getUrl()+" has no type"); @@ -622,6 +625,7 @@ public class ProfileUtilities extends TranslatingUtilities { derived.setSnapshot(null); throw e; } + derived.clearUserData("profileutils.snapshot.generating"); } private void checkDifferential(List elements, String type, String url) { @@ -853,10 +857,12 @@ public class ProfileUtilities extends TranslatingUtilities { CanonicalType p = diffMatches.get(0).getType().get(0).getProfile().get(0); StructureDefinition sd = context.fetchResource(StructureDefinition.class, p.getValue()); if (sd != null) { + checkNotGenerating(sd, "an extension definition"); if (!sd.hasSnapshot()) { StructureDefinition sdb = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition()); if (sdb == null) throw new DefinitionException("Unable to find base "+sd.getBaseDefinition()+" for "+sd.getUrl()); + checkNotGenerating(sdb, "an extension base"); generateSnapshot(sdb, sd, sd.getUrl(), (sdb.hasUserData("path")) ? Utilities.extractBaseUrl(sdb.getUserString("path")) : webUrl, sd.getName()); } ElementDefinition src; @@ -1424,7 +1430,7 @@ public class ProfileUtilities extends TranslatingUtilities { outcome.setSlicing(null); if (!outcome.getPath().startsWith(resultPathBase)) throw new DefinitionException("Adding wrong path"); - if (diffpos < diffMatches.size() && diffMatches.get(diffpos).getSliceName().equals(outcome.getSliceName())) { + if (diffpos < diffMatches.size() && diffMatches.get(diffpos).hasSliceName() && diffMatches.get(diffpos).getSliceName().equals(outcome.getSliceName())) { // if there's a diff, we update the outcome with diff // no? updateFromDefinition(outcome, diffMatches.get(diffpos), profileName, closed, url); //then process any children @@ -1540,6 +1546,12 @@ public class ProfileUtilities extends TranslatingUtilities { } + private void checkNotGenerating(StructureDefinition sd, String role) { + if (sd.hasUserData("profileutils.snapshot.generating")) { + throw new FHIRException("Attempt to use a snapshot on profile '"+sd.getUrl()+"' as "+role+" before it is generated"); + } + } + private boolean isBaseResource(List types) { if (types.isEmpty()) return false; @@ -2566,7 +2578,7 @@ public class ProfileUtilities extends TranslatingUtilities { String url = u.getValue(); boolean tgtOk = !td.hasTargetProfile() || td.hasTargetProfile(url); while (url != null && !tgtOk) { - StructureDefinition sd = context.fetchResource(StructureDefinition.class, url); + StructureDefinition sd = context.fetchRawProfile(url); if (sd == null) { if (messages != null) { messages.add(new ValidationMessage(Source.InstanceValidator, IssueType.BUSINESSRULE, purl+"#"+derived.getPath(), "Connect check whether the target profile "+url+" is valid constraint on the base because it is not known", IssueSeverity.WARNING)); 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 19d69ca45..11c4a94cf 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 @@ -539,7 +539,8 @@ public interface IWorkerContext { public void setOverrideVersionNs(String value); public StructureDefinition fetchTypeDefinition(String typeName); - + public StructureDefinition fetchRawProfile(String url); + public void setUcumService(UcumService ucumService); public String getLinkForUrl(String corePath, String s); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java index a5838a0e4..455dc659f 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java @@ -640,6 +640,12 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon return r; } + @Override + public StructureDefinition fetchRawProfile(String uri) { + StructureDefinition r = super.fetchResource(StructureDefinition.class, uri); + return r; + } + @Override public void generateSnapshot(StructureDefinition p) throws DefinitionException, FHIRException { generateSnapshot(p, false); diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/PackageClientTests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/PackageClientTests.java index 8c1e3b0a5..6376b2425 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/PackageClientTests.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/PackageClientTests.java @@ -87,6 +87,16 @@ public class PackageClientTests { for (PackageInfo pi : matches) { System.out.println(pi.toString()); } + Assert.assertTrue(matches.size() == 0); + } + + @Test + public void testVersions2A() throws IOException { + PackageClient client = new PackageClient("http://local.fhir.org:960/packages"); + List matches = client.getVersions("hl7.fhir.us.core"); + for (PackageInfo pi : matches) { + System.out.println(pi.toString()); + } Assert.assertTrue(matches.size() > 0); }