Adjust handling of slicing min issues

This commit is contained in:
Grahame Grieve 2023-05-23 17:37:11 +10:00
parent ba45c863db
commit 8a5c9c7ca6
2 changed files with 30 additions and 23 deletions

View File

@ -174,17 +174,13 @@ public class ProfilePathProcessor {
// in the simple case, source is not sliced. // in the simple case, source is not sliced.
if (!currentBase.hasSlicing() || currentBasePath.equals(getSlicing().getPath())) if (!currentBase.hasSlicing() || currentBasePath.equals(getSlicing().getPath()))
{ {
ElementDefinition currentRes = processSimplePath(currentBase, currentBasePath, diffMatches, typeList, ElementDefinition currentRes = processSimplePath(currentBase, currentBasePath, diffMatches, typeList, cursors);
cursors
);
if (res == null) { if (res == null) {
res = currentRes; res = currentRes;
} }
} }
else { else {
processPathWithSlicedBase(currentBase, currentBasePath, diffMatches, typeList, processPathWithSlicedBase(currentBase, currentBasePath, diffMatches, typeList, cursors);
cursors
);
} }
} }

View File

@ -135,6 +135,7 @@ public class ProfileUtilities extends TranslatingUtilities {
public class ElementDefinitionCounter { public class ElementDefinitionCounter {
int count = 0; int count = 0;
ElementDefinition focus; ElementDefinition focus;
Set<String> names = new HashSet<>();
public ElementDefinitionCounter(ElementDefinition ed) { public ElementDefinitionCounter(ElementDefinition ed) {
focus = ed; focus = ed;
@ -142,15 +143,16 @@ public class ProfileUtilities extends TranslatingUtilities {
public int update() { public int update() {
if (count > focus.getMin()) { if (count > focus.getMin()) {
int was = focus.getMin(); return count;
focus.setMin(count);
return was;
} }
return -1; return -1;
} }
public void count(ElementDefinition ed) { public boolean count(ElementDefinition ed, String name) {
count = count + ed.getMin(); count = count + ed.getMin();
boolean ok = !names.contains(name);
names.add(name);
return ok;
} }
public ElementDefinition getFocus() { public ElementDefinition getFocus() {
@ -725,13 +727,13 @@ public class ProfileUtilities extends TranslatingUtilities {
if (tn.contains("/")) { if (tn.contains("/")) {
tn = tn.substring(tn.lastIndexOf("/")+1); tn = tn.substring(tn.lastIndexOf("/")+1);
} }
System.out.println("Check slicing for "+derived.getVersionedUrl()); // System.out.println("Check slicing for "+derived.getVersionedUrl());
Map<String, ElementDefinitionCounter> slices = new HashMap<>(); Map<String, ElementDefinitionCounter> slices = new HashMap<>();
int i = 0; int i = 0;
for (ElementDefinition ed : derived.getSnapshot().getElement()) { for (ElementDefinition ed : derived.getSnapshot().getElement()) {
if (ed.hasSlicing()) { if (ed.hasSlicing()) {
slices.put(ed.getPath(), new ElementDefinitionCounter(ed)); slices.put(ed.getPath(), new ElementDefinitionCounter(ed));
System.out.println("Entering slicing for "+ed.getPath()+" ["+i+"]"); // System.out.println("Entering slicing for "+ed.getPath()+" ["+i+"]");
} else { } else {
Set<String> toRemove = new HashSet<>(); Set<String> toRemove = new HashSet<>();
for (String s : slices.keySet()) { for (String s : slices.keySet()) {
@ -740,13 +742,14 @@ public class ProfileUtilities extends TranslatingUtilities {
} }
} }
for (String s : toRemove) { for (String s : toRemove) {
int was = slices.get(s).update(); int count = slices.get(s).update();
if (was > -1) { if (count > -1) {
String msg = "The slice definition for "+slices.get(s).getFocus().getId()+" had a minimum of "+was+" but the slices added up to a minimum of "+slices.get(s).getFocus().getMin()+" so the value has been adjusted in the snapshot"; String msg = "The slice definition for "+slices.get(s).getFocus().getId()+" has a minimum of "+slices.get(s).getFocus().getMin()+" but the slices add up to a minimum of "+count;
System.out.println(msg); //+" so the value has been adjusted in the snapshot"; we don't adjust it because of downstream effects. But if it's for publication, they better get it right.
// System.out.println(msg);
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), msg, forPublication ? ValidationMessage.IssueSeverity.ERROR : ValidationMessage.IssueSeverity.INFORMATION)); messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), msg, forPublication ? ValidationMessage.IssueSeverity.ERROR : ValidationMessage.IssueSeverity.INFORMATION));
} }
System.out.println("Exiting slicing for "+s+" at "+ed.getPath()+" ["+i+"]"); // System.out.println("Exiting slicing for "+s+" at "+ed.getPath()+" ["+i+"]");
slices.remove(s); slices.remove(s);
} }
} }
@ -758,7 +761,10 @@ public class ProfileUtilities extends TranslatingUtilities {
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), msg, ValidationMessage.IssueSeverity.ERROR)); messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), msg, ValidationMessage.IssueSeverity.ERROR));
} }
if (ed.hasSliceName() && slices.containsKey(ed.getPath())) { if (ed.hasSliceName() && slices.containsKey(ed.getPath())) {
slices.get(ed.getPath()).count(ed); if (!slices.get(ed.getPath()).count(ed, ed.getSliceName())) {
String msg = "Duplicate slice name "+ed.getSliceName()+" on "+ed.getId()+" (["+i+"])";
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), msg, ValidationMessage.IssueSeverity.ERROR));
}
} }
i++; i++;
} }
@ -2043,10 +2049,15 @@ public class ProfileUtilities extends TranslatingUtilities {
} }
// Before applying changes, apply them to what's in the profile // Before applying changes, apply them to what's in the profile
StructureDefinition profile = null; StructureDefinition profile = null;
if (base.hasSliceName()) if (base.hasSliceName()) {
profile = base.getType().size() == 1 && base.getTypeFirstRep().hasProfile() ? context.fetchResource(StructureDefinition.class, base.getTypeFirstRep().getProfile().get(0).getValue(), srcSD) : null; profile = base.getType().size() == 1 && base.getTypeFirstRep().hasProfile() ? context.fetchResource(StructureDefinition.class, base.getTypeFirstRep().getProfile().get(0).getValue(), srcSD) : null;
if (profile==null) }
if (profile==null) {
profile = source.getType().size() == 1 && source.getTypeFirstRep().hasProfile() ? context.fetchResource(StructureDefinition.class, source.getTypeFirstRep().getProfile().get(0).getValue(), derivedSrc) : null; profile = source.getType().size() == 1 && source.getTypeFirstRep().hasProfile() ? context.fetchResource(StructureDefinition.class, source.getTypeFirstRep().getProfile().get(0).getValue(), derivedSrc) : null;
if (profile != null && !"Extension".equals(profile.getType())) {
profile = null;
}
}
if (profile != null) { if (profile != null) {
ElementDefinition e = profile.getSnapshot().getElement().get(0); ElementDefinition e = profile.getSnapshot().getElement().get(0);
String webroot = profile.getUserString("webroot"); String webroot = profile.getUserString("webroot");
@ -2157,7 +2168,7 @@ public class ProfileUtilities extends TranslatingUtilities {
if (derived.hasMinElement()) { if (derived.hasMinElement()) {
if (!Base.compareDeep(derived.getMinElement(), base.getMinElement(), false)) { if (!Base.compareDeep(derived.getMinElement(), base.getMinElement(), false)) {
if (derived.getMin() < base.getMin() && !derived.hasSliceName()) // in a slice, minimum cardinality rules do not apply if (derived.getMin() < base.getMin() && !derived.hasSliceName()) // in a slice, minimum cardinality rules do not apply
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+source.getPath(), "Element "+base.getPath()+": derived min ("+Integer.toString(derived.getMin())+") cannot be less than base min ("+Integer.toString(base.getMin())+")", ValidationMessage.IssueSeverity.ERROR)); messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+source.getPath(), "Element "+base.getPath()+": derived min ("+Integer.toString(derived.getMin())+") cannot be less than the base min ("+Integer.toString(base.getMin())+") in "+srcSD.getVersionedUrl(), ValidationMessage.IssueSeverity.ERROR));
base.setMinElement(derived.getMinElement().copy()); base.setMinElement(derived.getMinElement().copy());
} else if (trimDifferential) } else if (trimDifferential)
derived.setMinElement(null); derived.setMinElement(null);
@ -2168,7 +2179,7 @@ public class ProfileUtilities extends TranslatingUtilities {
if (derived.hasMaxElement()) { if (derived.hasMaxElement()) {
if (!Base.compareDeep(derived.getMaxElement(), base.getMaxElement(), false)) { if (!Base.compareDeep(derived.getMaxElement(), base.getMaxElement(), false)) {
if (isLargerMax(derived.getMax(), base.getMax())) if (isLargerMax(derived.getMax(), base.getMax()))
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+source.getPath(), "Element "+base.getPath()+": derived max ("+derived.getMax()+") cannot be greater than base max ("+base.getMax()+")", ValidationMessage.IssueSeverity.ERROR)); messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+source.getPath(), "Element "+base.getPath()+": derived max ("+derived.getMax()+") cannot be greater than the base max ("+base.getMax()+")", ValidationMessage.IssueSeverity.ERROR));
base.setMaxElement(derived.getMaxElement().copy()); base.setMaxElement(derived.getMaxElement().copy());
} else if (trimDifferential) } else if (trimDifferential)
derived.setMaxElement(null); derived.setMaxElement(null);