mirror of
https://github.com/hapifhir/org.hl7.fhir.core.git
synced 2025-02-09 06:14:45 +00:00
more validation for canonical URLs
This commit is contained in:
parent
e21a9830b8
commit
4cdead6f80
@ -1093,6 +1093,8 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
||||
err = TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED;
|
||||
} else if (it == IssueType.NOTSUPPORTED) {
|
||||
err = TerminologyServiceErrorClass.VALUESET_UNSUPPORTED;
|
||||
} else {
|
||||
err = null;
|
||||
}
|
||||
} catch (FHIRException e) {
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
public class Utilities {
|
||||
|
||||
private static final String UUID_REGEX = "[0-9a-f]{8}\\-[0-9a-f]{4}\\-[0-9a-f]{4}\\-[0-9a-f]{4}\\-[0-9a-f]{12}";
|
||||
private static final String OID_REGEX = "[0-2](\\.(0|[1-9][0-9]*))+";
|
||||
|
||||
/**
|
||||
@ -1476,7 +1477,7 @@ public class Utilities {
|
||||
}
|
||||
|
||||
final static int[] illegalChars = {34, 60, 62, 124, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 58, 42, 63, 92, 47};
|
||||
|
||||
|
||||
static {
|
||||
Arrays.sort(illegalChars);
|
||||
}
|
||||
@ -1493,5 +1494,13 @@ public class Utilities {
|
||||
return cleanName.toString();
|
||||
}
|
||||
|
||||
public static boolean isValidUUID(String uuid) {
|
||||
return uuid.matches(UUID_REGEX);
|
||||
}
|
||||
|
||||
public static boolean isValidOID(String oid) {
|
||||
return oid.matches(OID_REGEX);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -461,6 +461,7 @@ public class I18nConstants {
|
||||
public static final String TYPE_ON_FIRST_DIFFERENTIAL_ELEMENT = "type_on_first_differential_element";
|
||||
public static final String TYPE_ON_FIRST_SNAPSHOT_ELEMENT_FOR__IN__FROM_ = "type_on_first_snapshot_element_for__in__from_";
|
||||
public static final String TYPE_SPECIFIC_CHECKS_CANONICAL_ABSOLUTE = "TYPE_SPECIFIC_CHECKS_CANONICAL_ABSOLUTE";
|
||||
public static final String TYPE_SPECIFIC_CHECKS_CANONICAL_CONTAINED = "TYPE_SPECIFIC_CHECKS_CANONICAL_CONTAINED";
|
||||
public static final String TYPE_SPECIFIC_CHECKS_DT_ATT_NO_CONTENT = "TYPE_SPECIFIC_CHECKS_DT_ATT_NO_CONTENT";
|
||||
public static final String TYPE_SPECIFIC_CHECKS_DT_ATT_NO_FETCHER = "TYPE_SPECIFIC_CHECKS_DT_ATT_NO_FETCHER";
|
||||
public static final String TYPE_SPECIFIC_CHECKS_DT_ATT_SIZE_CORRECT = "TYPE_SPECIFIC_CHECKS_DT_ATT_SIZE_CORRECT";
|
||||
|
@ -208,7 +208,7 @@ Type_Specific_Checks_DT_URI_UUID = URI values cannot start with uuid:
|
||||
Type_Specific_Checks_DT_URI_WS = URI values cannot have whitespace(''{0}'')
|
||||
Type_Specific_Checks_DT_URL_Resolve = URL value ''{0}'' does not resolve
|
||||
Type_Specific_Checks_DT_UUID_Strat = UUIDs must start with urn:uuid:
|
||||
Type_Specific_Checks_DT_UUID_Vaid = UUIDs must be valid ({0})
|
||||
Type_Specific_Checks_DT_UUID_Vaid = UUIDs must be valid
|
||||
Validation_BUNDLE_Message = The first entry in a message must be a MessageHeader
|
||||
Validation_VAL_Content_Unknown = Unrecognised Content {0}
|
||||
Validation_VAL_NoType = Unknown type {0}
|
||||
@ -469,7 +469,8 @@ MEASURE_M_GROUP_POP_NO_CODE = A measure group population should have a code when
|
||||
MEASURE_M_GROUP_STRATA_NO_CODE = A measure group stratifier should have a code when there is more than one population
|
||||
MEASURE_M_GROUP_STRATA_COMP_NO_CODE = A measure group stratifier component should have a code when there is more than one population
|
||||
MEASURE_M_LIB_UNKNOWN = The Library {0} could not be resolved, so expression validation may not be correct
|
||||
TYPE_SPECIFIC_CHECKS_CANONICAL_ABSOLUTE = Canonical URLs must be absolute URLs if they are not fragment references ({0})
|
||||
TYPE_SPECIFIC_CHECKS_CANONICAL_ABSOLUTE = Canonical URLs must be absolute URLs if they are not fragment references ({0})
|
||||
TYPE_SPECIFIC_CHECKS_CANONICAL_CONTAINED = Canonical URLs in contained resources must be absolute URLs if present ({0})
|
||||
MEASURE_MR_SCORE_PROHIBITED_RT = No measureScore when the type of the report is ''data-collection''
|
||||
MEASURE_MR_SCORE_PROHIBITED_MS = No measureScore when the scoring of the mesage is ''cohort''
|
||||
MEASURE_MR_SCORE_REQUIRED = A measureScore is required when the Measure.scoring={0}
|
||||
|
@ -2025,23 +2025,27 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||
rule(errors, IssueType.INVALID, e.line(), e.col(), path, !context.hasMaxLength() || context.getMaxLength() == 0 || e.primitiveValue().length() <= context.getMaxLength(), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_PRIMITIVE_LENGTH, context.getMaxLength());
|
||||
|
||||
if (type.equals("oid")) {
|
||||
if (rule(errors, IssueType.INVALID, e.line(), e.col(), path, url.startsWith("urn:oid:"), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_OID_START))
|
||||
rule(errors, IssueType.INVALID, e.line(), e.col(), path, Utilities.isOid(url.substring(8)), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_OID_VALID);
|
||||
rule(errors, IssueType.INVALID, e.line(), e.col(), path, url.startsWith("urn:oid:"), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_OID_START);
|
||||
}
|
||||
if (type.equals("uuid")) {
|
||||
rule(errors, IssueType.INVALID, e.line(), e.col(), path, url.startsWith("urn:uuid:"), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_UUID_STRAT);
|
||||
try {
|
||||
UUID.fromString(url.substring(8));
|
||||
} catch (Exception ex) {
|
||||
rule(errors, IssueType.INVALID, e.line(), e.col(), path, false, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_UUID_VAID, ex.getMessage());
|
||||
}
|
||||
}
|
||||
if (type.equals("canonical")) {
|
||||
rule(errors, IssueType.INVALID, e.line(), e.col(), path, url.startsWith("#") || Utilities.isAbsoluteUrl(url), I18nConstants.TYPE_SPECIFIC_CHECKS_CANONICAL_ABSOLUTE, url);
|
||||
}
|
||||
|
||||
if (url != null && url.startsWith("urn:uuid:")) {
|
||||
rule(errors, IssueType.INVALID, e.line(), e.col(), path, Utilities.isValidUUID(url.substring(9)), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_UUID_VAID);
|
||||
}
|
||||
if (url != null && url.startsWith("urn:oid:")) {
|
||||
rule(errors, IssueType.INVALID, e.line(), e.col(), path, Utilities.isOid(url.substring(8)), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_OID_VALID);
|
||||
}
|
||||
|
||||
if (isCanonicalURLElement(e)) {
|
||||
// for now, no validation. Need to think about authority.
|
||||
// we get to here if this is a defining canonical URL (e.g. CodeSystem.url)
|
||||
// the URL must be an IRI if present
|
||||
rule(errors, IssueType.INVALID, e.line(), e.col(), path, Utilities.isAbsoluteUrl(url),
|
||||
node.isContained() ? I18nConstants.TYPE_SPECIFIC_CHECKS_CANONICAL_CONTAINED : I18nConstants.TYPE_SPECIFIC_CHECKS_CANONICAL_ABSOLUTE, url);
|
||||
} else {
|
||||
// now, do we check the URI target?
|
||||
if (fetcher != null && !type.equals("uuid")) {
|
||||
@ -4317,6 +4321,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||
idstatus = IdStatus.OPTIONAL;
|
||||
break;
|
||||
case CONTAINED:
|
||||
stack.setContained(true);
|
||||
idstatus = IdStatus.REQUIRED;
|
||||
break;
|
||||
case PARAMETER:
|
||||
@ -5372,6 +5377,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||
if ("probability is decimal implies (probability as decimal) <= 100".equals(expr)) {
|
||||
return "probablility.empty() or ((probability is decimal) implies ((probability as decimal) <= 100))";
|
||||
}
|
||||
|
||||
if ("enableWhen.count() > 2 implies enableBehavior.exists()".equals(expr)) {
|
||||
return "enableWhen.count() >= 2 implies enableBehavior.exists()";
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ public class NodeStack {
|
||||
private String workingLang;
|
||||
private Map<String, Element> ids;
|
||||
private boolean resetPoint = false;
|
||||
private boolean contained = false;
|
||||
|
||||
public NodeStack(IWorkerContext context) {
|
||||
this.context = context;
|
||||
@ -101,6 +102,7 @@ public class NodeStack {
|
||||
res.workingLang = this.workingLang;
|
||||
res.element = element;
|
||||
res.definition = definition;
|
||||
res.contained = contained;
|
||||
res.literalPath = getLiteralPath() + sep + element.getName();
|
||||
if (count > -1)
|
||||
res.literalPath = res.literalPath + "[" + Integer.toString(count) + "]";
|
||||
@ -195,5 +197,13 @@ public class NodeStack {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isContained() {
|
||||
return contained;
|
||||
}
|
||||
|
||||
public void setContained(boolean contained) {
|
||||
this.contained = contained;
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user