R4B quality fixes

This commit is contained in:
Grahame Grieve 2022-04-22 07:36:28 +10:00
parent 5fef79c08d
commit 10f2325e19
7 changed files with 140 additions and 21 deletions

View File

@ -146,6 +146,11 @@ public class SpecDifferenceEvaluator {
for (String n : names)
// note reverse of order
renames.put(ini.getStringProperty("r5-renames", n), n);
names = ini.getPropertyNames("r4b-renames");
if (names != null)
for (String n : names)
// note reverse of order
renames.put(ini.getStringProperty("r4b-renames", n), n);
}
public SpecPackage getOriginal() {
@ -311,9 +316,9 @@ public class SpecDifferenceEvaluator {
if (orig == null)
orig = original.getTypes().get(checkRename(rev.getName()));
if (orig == null)
return "<p>This " + rev.getKind().toCode() + " did not exist in Release 2</p>";
return "<p>This " + rev.getKind().toCode() + " did not exist in Release 3</p>";
else {
start();
start();
compare(orig, rev);
return new XhtmlComposer(false, true).compose(tbl) + "\r\n<p>See the <a href=\"diff.html\">Full Difference</a> for further information</p>\r\n";
}
@ -646,8 +651,9 @@ public class SpecDifferenceEvaluator {
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder("\r\n");
if (rev.getStrength() != orig.getStrength())
b.append("Change binding strength from " + orig.getStrength().toCode() + " to " + rev.getStrength().toCode());
if (!Base.compareDeep(rev.getValueSet(), orig.getValueSet(), false))
if (!canonicalsMatch(rev.getValueSet(), orig.getValueSet())) {
b.append("Change value set from " + describeReference(orig.getValueSet()) + " to " + describeReference(rev.getValueSet()));
}
if (!maxValueSetsMatch(rev, orig))
b.append("Change max value set from " + describeMax(orig) + " to " + describeMax(rev));
if (rev.getStrength() == BindingStrength.REQUIRED && orig.getStrength() == BindingStrength.REQUIRED) {
@ -691,6 +697,20 @@ public class SpecDifferenceEvaluator {
return b.toString();
}
private boolean canonicalsMatch(String url1, String url2) {
String rvs = VersionUtilities.removeVersionFromCanonical(url1);
String ovs = VersionUtilities.removeVersionFromCanonical(url2);
if (rvs == null && ovs == null) {
return true;
} else if (rvs == null) {
return false;
} else {
return rvs.equals(ovs);
}
}
private String describeMax(ElementDefinitionBindingComponent orig) {
if (!orig.hasExtension(ToolingExtensions.EXT_MAX_VALUESET))
return "n/a";
@ -870,8 +890,18 @@ public class SpecDifferenceEvaluator {
private boolean hasType(List<TypeRefComponent> types, TypeRefComponent tr) {
for (TypeRefComponent t : types) {
if (t.getWorkingCode().equals(tr.getWorkingCode())) {
if (((!t.hasProfile() && !tr.hasProfile()) || (t.getProfile().equals(tr.getProfile()))))
if ((!t.hasProfile() && !tr.hasProfile())) {
return true;
}
boolean found = true;
for (CanonicalType t1 : tr.getProfile()) {
boolean ok = false;
for (CanonicalType t2 : t.getProfile()) {
ok = ok || t2.getValue().equals(t1.getValue());
}
found = found && ok;
}
return found;
}
}
return false;
@ -910,7 +940,7 @@ public class SpecDifferenceEvaluator {
if (tr.getProfile().size() > 0) {
b.append("(");
boolean first = true;
for (UriType u : tr.getTargetProfile()) {
for (UriType u : tr.getProfile()) {
if (first)
first = false;
else

View File

@ -7603,9 +7603,9 @@ When pattern[x] is used to constrain a complex object, it means that each proper
public String typeSummary() {
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
for (TypeRefComponent tr : type) {
for (TypeRefComponent tr : getType()) {
if (tr.hasCode())
b.append(tr.getCode());
b.append(tr.getWorkingCode());
}
return b.toString();
}

View File

@ -1,6 +1,7 @@
package org.hl7.fhir.r4.utils;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@ -11,8 +12,10 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r4.formats.JsonParser;
import org.hl7.fhir.r4.model.CodeType;
import org.hl7.fhir.r4.model.ElementDefinition;
import org.hl7.fhir.r4.model.SearchParameter;
import org.hl7.fhir.r4.model.StructureDefinition;
import org.hl7.fhir.r4.model.StructureDefinition.TypeDerivationRule;
@ -100,10 +103,46 @@ public class IntegrityChecker {
}
private void check() throws IOException {
checkSD();
checkSP();
dumpSD(new FileWriter("/Users/grahamegrieve/temp/r4-dump.txt"));
// checkSD();
// checkSP();
}
private void dumpSD(FileWriter w) throws FHIRFormatError, IOException {
Map<String, StructureDefinition> map = new HashMap<>();
for (String sdn : npm.listResources("StructureDefinition")) {
InputStream s = npm.load(sdn);
StructureDefinition sd = (StructureDefinition) new JsonParser().parse(s);
map.put(sd.getUrl(), sd);
}
msg("Loaded "+map.size()+" Structures");
List<String> structures = new ArrayList<>();
for (StructureDefinition sd : map.values()) {
structures.add(sd.getUrl());
}
Collections.sort(structures);
for (String sdn : structures) {
dumpSD(map.get(sdn), map, w);
}
}
private void dumpSD(StructureDefinition sd, Map<String, StructureDefinition> map, FileWriter w) throws IOException {
if (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
StructureDefinition base = sd.hasBaseDefinition() ? map.get(sd.getBaseDefinition()) : null;
System.out.println(sd.getType()+(base == null ? "" : " : "+base.getType()));
w.append(sd.getType()+(base == null ? "" : " : "+base.getType())+"\r\n");
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
w.append(" "+Utilities.padLeft("", ' ', Utilities.charCount(ed.getPath(), '.'))+tail(ed.getPath())+" : "+ed.typeSummary()+" ["+ed.getMin()+".."+ed.getMax()+"]"+"\r\n");
}
}
}
private String tail(String path) {
return path.contains(".") ? path.substring(path.lastIndexOf('.')+1) : path;
}
private void checkSP() throws IOException {
List<SearchParameter> list = new ArrayList<>();

View File

@ -4,6 +4,8 @@ import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@ -23,6 +25,8 @@ import org.hl7.fhir.r4b.utils.IntegrityChecker.SearchParameterNode;
import org.hl7.fhir.r4b.utils.IntegrityChecker.SearchParameterNodeSorter;
import org.hl7.fhir.r4b.utils.IntegrityChecker.SearchParameterParamNode;
import org.hl7.fhir.r4b.utils.IntegrityChecker.SearchParameterParamNodeSorter;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r4b.model.ElementDefinition;
import org.hl7.fhir.r4b.formats.JsonParser;
import org.hl7.fhir.r4b.formats.XmlParser;
import org.hl7.fhir.r4b.model.StructureDefinition;
@ -107,12 +111,49 @@ public class IntegrityChecker {
}
private void check(String dst) throws IOException {
checkSD();
checkSP();
checkExamplesXml(dst);
checkExamplesJson(dst);
dumpSD(new FileWriter("/Users/grahamegrieve/temp/r4b-dump.txt"));
// checkSD();
// checkSP();
// checkExamplesXml(dst);
// checkExamplesJson(dst);
}
private void dumpSD(FileWriter w) throws FHIRFormatError, IOException {
Map<String, StructureDefinition> map = new HashMap<>();
for (String sdn : npm.listResources("StructureDefinition")) {
InputStream s = npm.load(sdn);
StructureDefinition sd = (StructureDefinition) new JsonParser().parse(s);
map.put(sd.getUrl(), sd);
}
msg("Loaded "+map.size()+" Structures");
List<String> structures = new ArrayList<>();
for (StructureDefinition sd : map.values()) {
structures.add(sd.getUrl());
}
Collections.sort(structures);
for (String sdn : structures) {
dumpSD(map.get(sdn), map, w);
}
}
private void dumpSD(StructureDefinition sd, Map<String, StructureDefinition> map, FileWriter w) throws IOException {
if (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
StructureDefinition base = sd.hasBaseDefinition() ? map.get(sd.getBaseDefinition()) : null;
System.out.println(sd.getType()+(base == null ? "" : " : "+base.getType()));
w.append(sd.getType()+(base == null ? "" : " : "+base.getType())+"\r\n");
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
w.append(" "+Utilities.padLeft("", ' ', Utilities.charCount(ed.getPath(), '.'))+tail(ed.getPath())+" : "+ed.typeSummary()+" ["+ed.getMin()+".."+ed.getMax()+"]"+"\r\n");
}
}
}
private String tail(String path) {
return path.contains(".") ? path.substring(path.lastIndexOf('.')+1) : path;
}
private Map<String, byte[]> loadZip(InputStream stream) throws IOException {
Map<String, byte[]> res = new HashMap<String, byte[]>();
ZipInputStream zip = new ZipInputStream(stream);

View File

@ -592,7 +592,7 @@ public class ShExGenerator {
return simpleElement(sd, ed, ref);
}
} else if (typ.getWorkingCode().startsWith(Constants.NS_SYSTEM_TYPE)) {
} else if (typ.getCode().startsWith(Constants.NS_SYSTEM_TYPE)) {
String xt = typ.getWorkingCode();
// TODO: Remove the next line when the type of token gets switched to string
// TODO: Add a rdf-type entry for valueInteger to xsd:integer (instead of int)

View File

@ -132,9 +132,7 @@ public class TypesUtilities {
res.add(new WildcardInformation("Annotation", TypeClassification.DATATYPE));
res.add(new WildcardInformation("Attachment", TypeClassification.DATATYPE));
res.add(new WildcardInformation("CodeableConcept", TypeClassification.DATATYPE));
if (!VersionUtilities.isR4BVer(version)) {
res.add(new WildcardInformation("CodeableReference", TypeClassification.DATATYPE));
}
res.add(new WildcardInformation("CodeableReference", TypeClassification.DATATYPE));
res.add(new WildcardInformation("Coding", TypeClassification.DATATYPE));
res.add(new WildcardInformation("ContactPoint", TypeClassification.DATATYPE));
res.add(new WildcardInformation("Count", TypeClassification.DATATYPE));
@ -147,9 +145,7 @@ public class TypesUtilities {
res.add(new WildcardInformation("Quantity", TypeClassification.DATATYPE));
res.add(new WildcardInformation("Range", TypeClassification.DATATYPE));
res.add(new WildcardInformation("Ratio", TypeClassification.DATATYPE));
if (!VersionUtilities.isR4BVer(version)) {
res.add(new WildcardInformation("RatioRange", TypeClassification.DATATYPE));
}
res.add(new WildcardInformation("RatioRange", TypeClassification.DATATYPE));
res.add(new WildcardInformation("Reference", " - a reference to another resource", TypeClassification.DATATYPE));
res.add(new WildcardInformation("SampledData", TypeClassification.DATATYPE));
res.add(new WildcardInformation("Signature", TypeClassification.DATATYPE));
@ -167,7 +163,9 @@ public class TypesUtilities {
// special cases
res.add(new WildcardInformation("Dosage", TypeClassification.SPECIAL));
res.add(new WildcardInformation("Meta", TypeClassification.SPECIAL));
if (!VersionUtilities.isR4BVer(version)) {
res.add(new WildcardInformation("Meta", TypeClassification.SPECIAL));
}
return res;
}

View File

@ -543,5 +543,16 @@ public class VersionUtilities {
return v.compareTo("4.5") >= 0;
}
public static String removeVersionFromCanonical(String url) {
if (url == null) {
return null;
}
if (url.contains("|")) {
return url.substring(0, url.indexOf("|"));
} else {
return url;
}
}
}