fix for new test case about profiles restricting types (#261)

* fix for new test case about profiles restricting types

* update release notes

* fix NPEs doing ProfileComparison

* fix non-translated messages in InstanceValidator
This commit is contained in:
Grahame Grieve 2020-06-27 04:46:54 +10:00 committed by GitHub
parent c8957fa921
commit 03a4224424
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 72 additions and 13 deletions

View File

@ -0,0 +1,3 @@
* Add extra validation for value sets (check concept codes are valid)
* Add extra code to check derivation consisteny for SearchParameter resources
* More Improvements to Questionnaire Rendering

View File

@ -138,7 +138,7 @@ public class ComparisonRenderer implements IEvaluationContext {
private void renderProfile(String id, ProfileComparison comp) throws IOException {
String template = templates.get("Profile");
Map<String, Base> vars = new HashMap<>();
ProfileComparer cs = new ProfileComparer(session, new ProfileUtilities(session.getContext(), null, null));
ProfileComparer cs = new ProfileComparer(session, new ProfileUtilities(session.getContext(), null, session.getPkp()));
vars.put("left", new StringType(comp.getLeft().present()));
vars.put("right", new StringType(comp.getRight().present()));
vars.put("leftId", new StringType(comp.getLeft().getId()));

View File

@ -13,6 +13,7 @@ import org.hl7.fhir.r5.comparison.ProfileComparer.ProfileComparison;
import org.hl7.fhir.r5.comparison.ResourceComparer.ResourceComparison;
import org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison;
import org.hl7.fhir.r5.conformance.ProfileUtilities;
import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.CodeSystem;
@ -29,12 +30,14 @@ public class ComparisonSession {
private int count;
private boolean debug;
private String title;
private ProfileKnowledgeProvider pkp;
public ComparisonSession(IWorkerContext context, String title) {
public ComparisonSession(IWorkerContext context, String title, ProfileKnowledgeProvider pkp) {
super();
this.context = context;
this.sessiondId = UUID.randomUUID().toString().toLowerCase();
this.title = title;
this.pkp = pkp;
// debug = true;
}
@ -77,7 +80,7 @@ public class ComparisonSession {
compares.put(key, csc);
return csc;
} else if (left instanceof StructureDefinition && right instanceof StructureDefinition) {
ProfileComparer cs = new ProfileComparer(this, new ProfileUtilities(context, null, null));
ProfileComparer cs = new ProfileComparer(this, new ProfileUtilities(context, null, pkp));
ProfileComparison csc = cs.compare((StructureDefinition) left, (StructureDefinition) right);
compares.put(key, csc);
return csc;
@ -111,4 +114,8 @@ public class ComparisonSession {
public Map<String, ResourceComparison> getCompares() {
return compares;
}
public ProfileKnowledgeProvider getPkp() {
return pkp;
}
}

View File

@ -3975,7 +3975,7 @@ public class ProfileUtilities extends TranslatingUtilities {
}
}
for (ElementDefinitionConstraintComponent inv : definition.getConstraint()) {
if (!inv.hasSource() || inv.getSource().equals(profile.getUrl()) || allInvariants) {
if (!inv.hasSource() || profile == null || inv.getSource().equals(profile.getUrl()) || allInvariants) {
if (!c.getPieces().isEmpty())
c.addPiece(gen.new Piece("br"));
c.getPieces().add(checkForNoChange(inv, gen.new Piece(null, inv.getKey()+": ", null).addStyle("font-weight:bold")));

View File

@ -47,6 +47,7 @@ import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@ -1285,6 +1286,19 @@ public class Utilities {
}
return false;
}
public static boolean startsWithInList(String s, Collection<String> list) {
if (s == null) {
return false;
}
for (String l : list) {
if (s.startsWith(l)) {
return true;
}
}
return false;
}
}

View File

@ -103,6 +103,7 @@ public class I18nConstants {
public static final String EXTENSION_EXT_SIMPLE = "Extension_EXT_Simple";
public static final String EXTENSION_EXT_SUBEXTENSION_INVALID = "Extension_EXT_SubExtension_Invalid";
public static final String EXTENSION_EXT_TYPE = "Extension_EXT_Type";
public static final String EXTENSION_PROF_TYPE = "Extension_PROF_Type";
public static final String EXTENSION_EXT_UNKNOWN = "Extension_EXT_Unknown";
public static final String EXTENSION_EXT_UNKNOWN_NOTHERE = "Extension_EXT_Unknown_NotHere";
public static final String EXTENSION_EXT_URL_ABSOLUTE = "Extension_EXT_URL_Absolute";
@ -125,6 +126,7 @@ public class I18nConstants {
public static final String ILLEGAL_PATH__IN_DIFFERENTIAL_IN__NAME_PORTION_MISING_ = "Illegal_path__in_differential_in__name_portion_mising_";
public static final String ILLEGAL_PATH__IN_DIFFERENTIAL_IN__NO_UNICODE_WHITESPACE = "Illegal_path__in_differential_in__no_unicode_whitespace";
public static final String INTERNAL_ERROR___TYPE_NOT_KNOWN_ = "Internal_error___type_not_known_";
public static final String INTERNAL_ERROR = "Internal_error";
public static final String INTERNAL_INT_BAD_TYPE = "Internal_INT_Bad_Type";
public static final String INTERNAL_RECURSION_DETECTION_FIND_LOOP_PATH_RECURSION____CHECK_PATHS_ARE_VALID_FOR_PATH_ = "Internal_recursion_detection_find_loop_path_recursion____check_paths_are_valid_for_path_";
public static final String INVALID_SLICING__THERE_IS_MORE_THAN_ONE_TYPE_SLICE_AT__BUT_ONE_OF_THEM__HAS_MIN__1_SO_THE_OTHER_SLICES_CANNOT_EXIST = "Invalid_slicing__there_is_more_than_one_type_slice_at__but_one_of_them__has_min__1_so_the_other_slices_cannot_exist";
@ -511,4 +513,8 @@ public class I18nConstants {
public static final String VALUESET_UNC_SYSTEM_WARNING_VER = "VALUESET_UNC_SYSTEM_WARNING_VER";
public static final String VALUESET_INCLUDE_INVALID_CONCEPT_CODE = "VALUESET_INCLUDE_INVALID_CONCEPT_CODE";
public static final String VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER = "VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER";
public static final String TYPE_CHECKS_PATTERN_CC = "TYPE_CHECKS_PATTERN_CC";
public static final String TYPE_CHECKS_PATTERN_CC_US = "TYPE_CHECKS_PATTERN_CC_US";
public static final String TYPE_CHECKS_FIXED_CC = "TYPE_CHECKS_FIXED_CC";
public static final String TYPE_CHECKS_FIXED_CC_US = "TYPE_CHECKS_FIXED_CC_US";
}

View File

@ -512,3 +512,9 @@ VALUESET_INCLUDE_INVALID_CONCEPT_CODE = The code {1} is not valid in the system
VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER = The code {2} is not valid in the system {0} version {1}
VALUESET_UNC_SYSTEM_WARNING = Unknown System specified, so Concepts and Filters can't be checked
VALUESET_UNC_SYSTEM_WARNING_VER = Unknown System/Version specified, so Concepts and Filters can't be checked
Extension_PROF_Type = The Profile "{0}" definition allows for the type {1} but found type {2}
TYPE_CHECKS_PATTERN_CC = The pattern [system {0}, code {1}, and display "{2}"] defined in the profile {3} not found. Issues: {4}
TYPE_CHECKS_PATTERN_CC_US = The pattern [system {0}, code {1}, display "{2}" and userSelected {5}] defined in the profile {3} not found. Issues: {4}
TYPE_CHECKS_FIXED_CC = The pattern [system {0}, code {1}, and display "{2}"] defined in the profile {3} not found. Issues: {4}
TYPE_CHECKS_FIXED_CC_US = The pattern [system {0}, code {1}, display "{2}" and userSelected {5}] defined in the profile {3} not found. Issues: {4}
Internal_error = Internal error: {0}

View File

@ -841,15 +841,29 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if (!found) {
// The argonaut DSTU2 labs profile requires userSelected=false on the category.coding and this
// needs to produce an understandable error message
String message = "Expected CodeableConcept " + (pattern ? "pattern" : "fixed value") + " not found for" +
" system: " + fixedCoding.getSystemElement().asStringValue() +
" code: " + fixedCoding.getCodeElement().asStringValue() +
" display: " + fixedCoding.getDisplayElement().asStringValue();
// String message = "Expected CodeableConcept " + (pattern ? "pattern" : "fixed value") + " not found for" +
// " system: " + fixedCoding.getSystemElement().asStringValue() +
// " code: " + fixedCoding.getCodeElement().asStringValue() +
// " display: " + fixedCoding.getDisplayElement().asStringValue();
// if (fixedCoding.hasUserSelected()) {
// message += " userSelected: " + fixedCoding.getUserSelected();
// }
// message += " - Issues: " + allErrorsFixed;
// TYPE_CHECKS_PATTERN_CC = The pattern [system {0}, code {1}, and display "{2}"] defined in the profile {3} not found. Issues: {4}
// TYPE_CHECKS_PATTERN_CC_US = The pattern [system {0}, code {1}, display "{2}" and userSelected {5}] defined in the profile {3} not found. Issues: {4}
// TYPE_CHECKS_FIXED_CC = The pattern [system {0}, code {1}, and display "{2}"] defined in the profile {3} not found. Issues: {4}
// TYPE_CHECKS_FIXED_CC_US = The pattern [system {0}, code {1}, display "{2}" and userSelected {5}] defined in the profile {3} not found. Issues: {4}
if (fixedCoding.hasUserSelected()) {
message += " userSelected: " + fixedCoding.getUserSelected();
rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, false, pattern ? I18nConstants.TYPE_CHECKS_PATTERN_CC_US : I18nConstants.TYPE_CHECKS_FIXED_CC_US,
fixedCoding.getSystemElement().asStringValue(), fixedCoding.getCodeElement().asStringValue(), fixedCoding.getDisplayElement().asStringValue(),
fixedSource, allErrorsFixed, fixedCoding.getUserSelected());
} else {
rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, false, pattern ? I18nConstants.TYPE_CHECKS_PATTERN_CC : I18nConstants.TYPE_CHECKS_FIXED_CC,
fixedCoding.getSystemElement().asStringValue(), fixedCoding.getCodeElement().asStringValue(), fixedCoding.getDisplayElement().asStringValue(),
fixedSource, allErrorsFixed);
}
message += " - Issues: " + allErrorsFixed;
rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, false, message);
}
}
}
@ -3723,6 +3737,15 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if (ei.definition.getType().size() == 1 && !"*".equals(ei.definition.getType().get(0).getWorkingCode()) && !"Element".equals(ei.definition.getType().get(0).getWorkingCode())
&& !"BackboneElement".equals(ei.definition.getType().get(0).getWorkingCode())) {
type = ei.definition.getType().get(0).getWorkingCode();
String stype = ei.getElement().fhirType();
if (ei.definition.isChoice() && !stype.equals(type)) {
if ("Extension".equals(profile.getType())) {
// error will be raised elsewhere
} else {
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), false, I18nConstants.EXTENSION_PROF_TYPE, profile.getUrl(), type, stype);
}
}
//
// Excluding reference is a kludge to get around versioning issues
if (ei.definition.getType().get(0).hasProfile()) {
for (CanonicalType p : ei.definition.getType().get(0).getProfile()) {
@ -4171,7 +4194,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
ei.additionalSlice = true;
}
} catch (FHIRException e) {
rule(errors, IssueType.PROCESSING, ei.line(), ei.col(), ei.getPath(), false, e.getMessage());
rule(errors, IssueType.PROCESSING, ei.line(), ei.col(), ei.getPath(), false, I18nConstants.INTERNAL_ERROR, e.getMessage());
unsupportedSlicing = true;
childUnsupportedSlicing = true;
}

View File

@ -116,7 +116,7 @@ public class ComparisonTests {
CanonicalResource left = load("left");
CanonicalResource right = load("right");
ComparisonSession session = new ComparisonSession(context, "Comparison Tests");
ComparisonSession session = new ComparisonSession(context, "Comparison Tests", null);
if (left instanceof CodeSystem && right instanceof CodeSystem) {
CodeSystemComparer cs = new CodeSystemComparer(session);