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 e86086ac1..25106f617 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 @@ -408,55 +408,60 @@ public class ProfileUtilities extends TranslatingUtilities { derived.setSnapshot(new StructureDefinitionSnapshotComponent()); - - // so we have two lists - the base list, and the differential list - // the differential list is only allowed to include things that are in the base list, but - // is allowed to include them multiple times - thereby slicing them + try { + // so we have two lists - the base list, and the differential list + // the differential list is only allowed to include things that are in the base list, but + // is allowed to include them multiple times - thereby slicing them - // our approach is to walk through the base list, and see whether the differential - // says anything about them. - int baseCursor = 0; - int diffCursor = 0; // we need a diff cursor because we can only look ahead, in the bound scoped by longer paths + // our approach is to walk through the base list, and see whether the differential + // says anything about them. + int baseCursor = 0; + int diffCursor = 0; // we need a diff cursor because we can only look ahead, in the bound scoped by longer paths - if (derived.hasDifferential() && !derived.getDifferential().getElementFirstRep().getPath().contains(".") && !derived.getDifferential().getElementFirstRep().getType().isEmpty()) - throw new Error("type on first differential element!"); + if (derived.hasDifferential() && !derived.getDifferential().getElementFirstRep().getPath().contains(".") && !derived.getDifferential().getElementFirstRep().getType().isEmpty()) + throw new Error("type on first differential element!"); - for (ElementDefinition e : derived.getDifferential().getElement()) - e.clearUserData(GENERATED_IN_SNAPSHOT); - - // we actually delegate the work to a subroutine so we can re-enter it with a different cursors + for (ElementDefinition e : derived.getDifferential().getElement()) + e.clearUserData(GENERATED_IN_SNAPSHOT); - processPaths("", derived.getSnapshot(), base.getSnapshot(), derived.getDifferential(), baseCursor, diffCursor, base.getSnapshot().getElement().size()-1, - derived.getDifferential().hasElement() ? derived.getDifferential().getElement().size()-1 : -1, url, webUrl, derived.getId(), null, null, false, base.getUrl(), null, false, new ArrayList()); - if (!derived.getSnapshot().getElementFirstRep().getType().isEmpty()) - throw new Error("type on first snapshot element for "+derived.getSnapshot().getElementFirstRep().getPath()+" in "+derived.getUrl()+" from "+base.getUrl()); - updateMaps(base, derived); - setIds(derived, false); - - if (DEBUG) { - System.out.println("Differential: "); - for (ElementDefinition ed : derived.getDifferential().getElement()) - System.out.println(" "+ed.getPath()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" id = "+ed.getId()+" "+constraintSummary(ed)); - System.out.println("Snapshot: "); - for (ElementDefinition ed : derived.getSnapshot().getElement()) - System.out.println(" "+ed.getPath()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" id = "+ed.getId()+" "+constraintSummary(ed)); - } - //Check that all differential elements have a corresponding snapshot element - for (ElementDefinition e : derived.getDifferential().getElement()) { - if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) { - System.out.println("Error in snapshot generation: Differential for "+derived.getUrl()+" with id: " + e.getId()+" has an element that is not marked with a snapshot match"); - if (exception) - throw new DefinitionException("Snapshot for "+derived.getUrl()+" does not contain an element that matches an existing differential element that has id: " + e.getId()); - else - messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url, "Snapshot for "+derived.getUrl()+" does not contain an element that matches an existing differential element that has id: " + e.getId(), ValidationMessage.IssueSeverity.ERROR)); + // we actually delegate the work to a subroutine so we can re-enter it with a different cursors + + processPaths("", derived.getSnapshot(), base.getSnapshot(), derived.getDifferential(), baseCursor, diffCursor, base.getSnapshot().getElement().size()-1, + derived.getDifferential().hasElement() ? derived.getDifferential().getElement().size()-1 : -1, url, webUrl, derived.getId(), null, null, false, base.getUrl(), null, false, new ArrayList()); + if (!derived.getSnapshot().getElementFirstRep().getType().isEmpty()) + throw new Error("type on first snapshot element for "+derived.getSnapshot().getElementFirstRep().getPath()+" in "+derived.getUrl()+" from "+base.getUrl()); + updateMaps(base, derived); + setIds(derived, false); + + if (DEBUG) { + System.out.println("Differential: "); + for (ElementDefinition ed : derived.getDifferential().getElement()) + System.out.println(" "+ed.getPath()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" id = "+ed.getId()+" "+constraintSummary(ed)); + System.out.println("Snapshot: "); + for (ElementDefinition ed : derived.getSnapshot().getElement()) + System.out.println(" "+ed.getPath()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" id = "+ed.getId()+" "+constraintSummary(ed)); } - } - if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) { - for (ElementDefinition ed : derived.getSnapshot().getElement()) { - if (!ed.hasBase()) { - ed.getBase().setPath(ed.getPath()).setMin(ed.getMin()).setMax(ed.getMax()); + //Check that all differential elements have a corresponding snapshot element + for (ElementDefinition e : derived.getDifferential().getElement()) { + if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) { + System.out.println("Error in snapshot generation: Differential for "+derived.getUrl()+" with id: " + e.getId()+" has an element that is not marked with a snapshot match"); + if (exception) + throw new DefinitionException("Snapshot for "+derived.getUrl()+" does not contain an element that matches an existing differential element that has id: " + e.getId()); + else + messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url, "Snapshot for "+derived.getUrl()+" does not contain an element that matches an existing differential element that has id: " + e.getId(), ValidationMessage.IssueSeverity.ERROR)); } } + if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) { + for (ElementDefinition ed : derived.getSnapshot().getElement()) { + if (!ed.hasBase()) { + ed.getBase().setPath(ed.getPath()).setMin(ed.getMin()).setMax(ed.getMax()); + } + } + } + } catch (Exception e) { + // if we had an exception generating the snapshot, make sure we don't leave any half generated snapshot behind + derived.setSnapshot(null); + throw e; } }