Add support for Attachment validation + max size and max decimal places validation
This commit is contained in:
parent
5f1889765d
commit
130caef348
|
@ -33,6 +33,7 @@ package org.hl7.fhir.r5.utils;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
|
@ -81,6 +82,8 @@ public interface IResourceValidator {
|
|||
ReferenceValidationPolicy validationPolicy(Object appContext, String path, String url);
|
||||
boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException;
|
||||
|
||||
byte[] fetchRaw(String url) throws MalformedURLException, IOException; // for attachment checking
|
||||
|
||||
void setLocale(Locale locale);
|
||||
}
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ import org.hl7.fhir.r5.model.CodeType;
|
|||
import org.hl7.fhir.r5.model.CodeableConcept;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
import org.hl7.fhir.r5.model.DataType;
|
||||
import org.hl7.fhir.r5.model.DecimalType;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Element;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
|
@ -83,6 +84,7 @@ import org.hl7.fhir.r5.model.Extension;
|
|||
import org.hl7.fhir.r5.model.ExtensionHelper;
|
||||
import org.hl7.fhir.r5.model.Factory;
|
||||
import org.hl7.fhir.r5.model.Identifier;
|
||||
import org.hl7.fhir.r5.model.Integer64Type;
|
||||
import org.hl7.fhir.r5.model.IntegerType;
|
||||
import org.hl7.fhir.r5.model.MarkdownType;
|
||||
import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
|
||||
|
@ -327,6 +329,10 @@ public class ToolingExtensions {
|
|||
return ((CodeType) ex.getValue()).getValue();
|
||||
if (ex.getValue() instanceof IntegerType)
|
||||
return ((IntegerType) ex.getValue()).asStringValue();
|
||||
if (ex.getValue() instanceof Integer64Type)
|
||||
return ((Integer64Type) ex.getValue()).asStringValue();
|
||||
if (ex.getValue() instanceof DecimalType)
|
||||
return ((DecimalType) ex.getValue()).asStringValue();
|
||||
if ((ex.getValue() instanceof MarkdownType))
|
||||
return ((MarkdownType) ex.getValue()).getValue();
|
||||
if (!(ex.getValue() instanceof StringType))
|
||||
|
@ -346,6 +352,10 @@ public class ToolingExtensions {
|
|||
return ((CodeType) ex.getValue()).getValue();
|
||||
if (ex.getValue() instanceof IntegerType)
|
||||
return ((IntegerType) ex.getValue()).asStringValue();
|
||||
if (ex.getValue() instanceof Integer64Type)
|
||||
return ((Integer64Type) ex.getValue()).asStringValue();
|
||||
if (ex.getValue() instanceof DecimalType)
|
||||
return ((DecimalType) ex.getValue()).asStringValue();
|
||||
if ((ex.getValue() instanceof MarkdownType))
|
||||
return ((MarkdownType) ex.getValue()).getValue();
|
||||
return null;
|
||||
|
|
|
@ -171,6 +171,7 @@ public class I18nConstants {
|
|||
public final static String TERMINOLOGY_TX_VALUESET_NOTFOUND = "Terminology_TX_ValueSet_NotFound";
|
||||
public final static String TERMINOLOGY_TX_VALUESET_NOTFOUND2 = "Terminology_TX_ValueSet_NotFound2";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_BASE64_VALID = "Type_Specific_Checks_DT_Base64_Valid";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_BASE64_TOO_LONG = "TYPE_SPECIFIC_CHECKS_DT_BASE64_TOO_LONG";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_BOOLEAN_VALUE = "Type_Specific_Checks_DT_Boolean_Value";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_CODE_WS = "Type_Specific_Checks_DT_Code_WS";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_DATETIME_REASONABLE = "Type_Specific_Checks_DT_DateTime_Reasonable";
|
||||
|
@ -180,6 +181,7 @@ public class I18nConstants {
|
|||
public final static String TYPE_SPECIFIC_CHECKS_DT_DATE_VALID = "Type_Specific_Checks_DT_Date_Valid";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_DECIMAL_RANGE = "Type_Specific_Checks_DT_Decimal_Range";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_DECIMAL_VALID = "Type_Specific_Checks_DT_Decimal_Valid";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_DECIMAL_CHARS = "TYPE_SPECIFIC_CHECKS_DT_DECIMAL_CHARS";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_IDENTIFIER_SYSTEM = "Type_Specific_Checks_DT_Identifier_System";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_IDENTIFIER_IETF_SYSTEM_VALUE = "TYPE_SPECIFIC_CHECKS_DT_IDENTIFIER_IETF_SYSTEM_VALUE";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_ID_VALID = "Type_Specific_Checks_DT_ID_Valid";
|
||||
|
@ -206,6 +208,13 @@ public class I18nConstants {
|
|||
public final static String TYPE_SPECIFIC_CHECKS_DT_URL_RESOLVE = "Type_Specific_Checks_DT_URL_Resolve";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_UUID_STRAT = "Type_Specific_Checks_DT_UUID_Strat";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_UUID_VAID = "Type_Specific_Checks_DT_UUID_Vaid";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_ATT_SIZE_CORRECT = "TYPE_SPECIFIC_CHECKS_DT_ATT_SIZE_CORRECT";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_ATT_SIZE_INVALID = "TYPE_SPECIFIC_CHECKS_DT_ATT_SIZE_INVALID";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_ATT_NO_FETCHER = "TYPE_SPECIFIC_CHECKS_DT_ATT_NO_FETCHER";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_ATT_UNKNOWN_URL_SCHEME = "TYPE_SPECIFIC_CHECKS_DT_ATT_UNKNOWN_URL_SCHEME";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_ATT_URL_ERROR = "TYPE_SPECIFIC_CHECKS_DT_ATT_URL_ERROR";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_ATT_TOO_LONG = "TYPE_SPECIFIC_CHECKS_DT_ATT_TOO_LONG";
|
||||
public final static String TYPE_SPECIFIC_CHECKS_DT_ATT_NO_CONTENT = "TYPE_SPECIFIC_CHECKS_DT_ATT_NO_CONTENT";
|
||||
public final static String VALIDATION_BUNDLE_MESSAGE = "Validation_BUNDLE_Message";
|
||||
public final static String VALIDATION_VAL_CONTENT_UNKNOWN = "Validation_VAL_Content_Unknown";
|
||||
public final static String VALIDATION_VAL_NOTYPE = "Validation_VAL_NoType";
|
||||
|
|
|
@ -485,4 +485,13 @@ XHTML_URL_EMPTY = URL is empty
|
|||
XHTML_URL_INVALID_CHARS = URL contains Invalid Characters ({0})
|
||||
TERMINOLOGY_TX_SYSTEM_HTTPS = The system URL ''{0}'' wrongly starts with https: not http:
|
||||
CODESYSTEM_CS_NO_VS_NOTCOMPLETE = Review the All Codes Value Set - incomplete CodeSystems generally should not have an all codes value set specified
|
||||
TYPE_SPECIFIC_CHECKS_DT_IDENTIFIER_IETF_SYSTEM_VALUE = if identifier.system is ''urn:ietf:rfc:3986'', then the identifier.value must be a full URI (e.g. start with a scheme)
|
||||
TYPE_SPECIFIC_CHECKS_DT_IDENTIFIER_IETF_SYSTEM_VALUE = if identifier.system is ''urn:ietf:rfc:3986'', then the identifier.value must be a full URI (e.g. start with a scheme)
|
||||
TYPE_SPECIFIC_CHECKS_DT_ATT_SIZE_INVALID = Stated Attachment Size {0} is not valid
|
||||
TYPE_SPECIFIC_CHECKS_DT_ATT_SIZE_CORRECT = Stated Attachment Size {0} does not match actual attachment size {1}
|
||||
TYPE_SPECIFIC_CHECKS_DT_ATT_NO_FETCHER = Attachment size cannot be checked because the validator has not been set up to access the network (url = {0})
|
||||
TYPE_SPECIFIC_CHECKS_DT_ATT_UNKNOWN_URL_SCHEME = Attachment size cannot be checked because the validator doesn't understand how to access {0}
|
||||
TYPE_SPECIFIC_CHECKS_DT_ATT_URL_ERROR = Attachment size cannot be checked because there was an error accesssing {0}: {1}
|
||||
TYPE_SPECIFIC_CHECKS_DT_ATT_TOO_LONG = Attachment size is {0} bytes which exceeds the stated limit of {1} bytes
|
||||
TYPE_SPECIFIC_CHECKS_DT_ATT_NO_CONTENT = Attachments have data and/or url, or else must have either contentType and/oor language
|
||||
TYPE_SPECIFIC_CHECKS_DT_BASE64_TOO_LONG = Base64 size is {0} bytes which exceeds the stated limit of {1} bytes
|
||||
TYPE_SPECIFIC_CHECKS_DT_DECIMAL_CHARS = Found {0} decimal places which exceeds the stated limit of {1} digits
|
||||
|
|
|
@ -42,8 +42,11 @@ import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
|
|||
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
@ -2068,5 +2071,12 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
|||
throw new Exception("Target Version not supported yet: "+targetVer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] fetchRaw(String source) throws IOException {
|
||||
URL url = new URL(source);
|
||||
URLConnection c = url.openConnection();
|
||||
return TextFile.streamToBytes(c.getInputStream());
|
||||
}
|
||||
|
||||
}
|
|
@ -34,10 +34,12 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
|
|||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
|
@ -1232,7 +1234,6 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
|
||||
private void checkMaxValueSet(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, String maxVSUrl, CodeableConcept cc, NodeStack stack) {
|
||||
// TODO Auto-generated method stub
|
||||
ValueSet valueset = resolveBindingReference(profile, maxVSUrl, profile.getUrl());
|
||||
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND, describeReference(maxVSUrl))) {
|
||||
try {
|
||||
|
@ -1252,7 +1253,6 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
|
||||
private void checkMaxValueSet(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, String maxVSUrl, Coding c, NodeStack stack) {
|
||||
// TODO Auto-generated method stub
|
||||
ValueSet valueset = resolveBindingReference(profile, maxVSUrl, profile.getUrl());
|
||||
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND, describeReference(maxVSUrl))) {
|
||||
try {
|
||||
|
@ -1272,7 +1272,6 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
|
||||
private void checkMaxValueSet(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, String maxVSUrl, String value, NodeStack stack) {
|
||||
// TODO Auto-generated method stub
|
||||
ValueSet valueset = resolveBindingReference(profile, maxVSUrl, profile.getUrl());
|
||||
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND, describeReference(maxVSUrl))) {
|
||||
try {
|
||||
|
@ -1313,7 +1312,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
checkCodedElement(errors, path, element, profile, theElementCntext, inCodeableConcept, checkDisplay, stack, code, system, display);
|
||||
}
|
||||
|
||||
private void checkCodedElement(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, ElementDefinition theElementCntext, boolean inCodeableConcept, boolean checkDisplay, NodeStack stack, String theCode, String theSystem, String theDisplay) {
|
||||
private void checkCodedElement(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, ElementDefinition theElementCntext, boolean inCodeableConcept, boolean checkDisplay, NodeStack stack,
|
||||
String theCode, String theSystem, String theDisplay) {
|
||||
rule(errors, IssueType.CODEINVALID, element.line(), element.col(), path, isAbsolute(theSystem), I18nConstants.TERMINOLOGY_TX_SYSTEM_RELATIVE);
|
||||
warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, Utilities.noString(theCode) || !Utilities.noString(theSystem), I18nConstants.TERMINOLOGY_TX_SYSTEM_NO_CODE);
|
||||
|
||||
|
@ -1783,7 +1783,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
String regex = context.getExtensionString(ToolingExtensions.EXT_REGEX);
|
||||
if (regex != null)
|
||||
rule(errors, IssueType.INVALID, e.line(), e.col(), path, e.primitiveValue().matches(regex), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_PRIMITIVE_REGEX, e.primitiveValue(), regex);
|
||||
|
||||
|
||||
|
||||
if (type.equals("boolean")) {
|
||||
rule(errors, IssueType.INVALID, e.line(), e.col(), path, "true".equals(e.primitiveValue()) || "false".equals(e.primitiveValue()), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_BOOLEAN_VALUE);
|
||||
}
|
||||
|
@ -1882,6 +1883,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
* 2. This code doesn't actually decode, which is much easier on memory use for big payloads
|
||||
*/
|
||||
int charCount = 0;
|
||||
boolean ok = true;
|
||||
for (int i = 0; i < encoded.length(); i++) {
|
||||
char nextChar = encoded.charAt(i);
|
||||
if (Character.isWhitespace(nextChar)) {
|
||||
|
@ -1896,9 +1898,16 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
|
||||
if (charCount > 0 && charCount % 4 != 0) {
|
||||
ok = false;
|
||||
String value = encoded.length() < 100 ? encoded : "(snip)";
|
||||
rule(errors, IssueType.INVALID, e.line(), e.col(), path, false, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_BASE64_VALID, value);
|
||||
}
|
||||
if (ok && context.hasExtension("http://hl7.org/fhir/StructureDefinition/maxSize")) {
|
||||
byte[] cnt = Base64.getDecoder().decode(encoded);
|
||||
int size = cnt.length;
|
||||
long def = Long.parseLong(ToolingExtensions.readStringExtension(context, "http://hl7.org/fhir/StructureDefinition/maxSize"));
|
||||
rule(errors, IssueType.STRUCTURE, e.line(), e.col(), path, size <= def, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_BASE64_TOO_LONG, size, def);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type.equals("integer") || type.equals("unsignedInt") || type.equals("positiveInt")) {
|
||||
|
@ -1929,6 +1938,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (rule(errors, IssueType.INVALID, e.line(), e.col(), path, ds == DecimalStatus.OK || ds == DecimalStatus.RANGE, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_DECIMAL_VALID, e.primitiveValue()))
|
||||
warning(errors, IssueType.VALUE, e.line(), e.col(), path, ds != DecimalStatus.RANGE, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_DECIMAL_RANGE, e.primitiveValue());
|
||||
}
|
||||
if (context.hasExtension("http://hl7.org/fhir/StructureDefinition/maxDecimalPlaces")) {
|
||||
int dp = e.primitiveValue().contains(".") ? e.primitiveValue().substring(e.primitiveValue().indexOf(".")+1).length() : 0;
|
||||
int def = Integer.parseInt(ToolingExtensions.readStringExtension(context, "http://hl7.org/fhir/StructureDefinition/maxDecimalPlaces"));
|
||||
rule(errors, IssueType.STRUCTURE, e.line(), e.col(), path, dp <= def, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_DECIMAL_CHARS, dp, def);
|
||||
}
|
||||
}
|
||||
if (type.equals("instant")) {
|
||||
rule(errors, IssueType.INVALID, e.line(), e.col(), path,
|
||||
|
@ -2110,12 +2124,72 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
checkFixedValue(errors, path + ".code", focus.getNamedChild("code"), fixed.getCodeElement(), fixedSource, "code", focus, pattern);
|
||||
}
|
||||
|
||||
private void checkQuantity(List<ValidationMessage> theErrors, String thePath, Element theElement, StructureDefinition theProfile, ElementDefinition theDefinition, boolean theInCodeableConcept, boolean theCheckDisplayInContext, NodeStack theStack) {
|
||||
String unit = theElement.hasChild("unit") ? theElement.getNamedChild("unit").getValue() : null;
|
||||
String system = theElement.hasChild("system") ? theElement.getNamedChild("system").getValue() : null;
|
||||
String code = theElement.hasChild("code") ? theElement.getNamedChild("code").getValue() : null;
|
||||
private void checkQuantity(List<ValidationMessage> theErrors, String thePath, Element element, StructureDefinition theProfile, ElementDefinition definition, NodeStack theStack) {
|
||||
String unit = element.hasChild("unit") ? element.getNamedChild("unit").getValue() : null;
|
||||
String system = element.hasChild("system") ? element.getNamedChild("system").getValue() : null;
|
||||
String code = element.hasChild("code") ? element.getNamedChild("code").getValue() : null;
|
||||
|
||||
checkCodedElement(theErrors, thePath, theElement, theProfile, theDefinition, theInCodeableConcept, theCheckDisplayInContext, theStack, code, system, unit);
|
||||
// todo: allowedUnits http://hl7.org/fhir/StructureDefinition/elementdefinition-allowedUnits - codeableConcept, or canonical(ValueSet)
|
||||
// todo: http://hl7.org/fhir/StructureDefinition/iso21090-PQ-translation
|
||||
|
||||
if (definition.hasExtension("http://hl7.org/fhir/StructureDefinition/maxDecimalPlaces")) {
|
||||
String dec = element.getChildValue("value");
|
||||
int dp = dec.contains(".") ? dec.substring(dec.indexOf(".")+1).length() : 0;
|
||||
int def = Integer.parseInt(ToolingExtensions.readStringExtension(definition, "http://hl7.org/fhir/StructureDefinition/maxDecimalPlaces"));
|
||||
rule(theErrors, IssueType.STRUCTURE, element.line(), element.col(), thePath, dp <= def, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_DECIMAL_CHARS, dp, def);
|
||||
}
|
||||
|
||||
if (system != null || code != null ) {
|
||||
checkCodedElement(theErrors, thePath, element, theProfile, definition, false, false, theStack, code, system, unit);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAttachment(List<ValidationMessage> errors, String path, Element element, StructureDefinition theProfile, ElementDefinition definition, boolean theInCodeableConcept, boolean theCheckDisplayInContext, NodeStack theStack) {
|
||||
long size = -1;
|
||||
// first check size
|
||||
String fetchError = null;
|
||||
if (element.hasChild("data")) {
|
||||
String b64 = element.getChildValue("data");
|
||||
byte[] cnt = Base64.getDecoder().decode(b64.getBytes());
|
||||
size = cnt.length;
|
||||
if (element.hasChild("size")) {
|
||||
String sz = element.getChildValue("size");
|
||||
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, Long.toString(size).equals(sz), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_ATT_SIZE_CORRECT, sz, size);
|
||||
}
|
||||
} else if (element.hasChild("size")) {
|
||||
String sz = element.getChildValue("size");
|
||||
if (rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, Utilities.isLong(sz), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_ATT_SIZE_INVALID, sz)) {
|
||||
size = Long.parseLong(sz);
|
||||
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, size >= 0, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_ATT_SIZE_INVALID, sz);
|
||||
}
|
||||
} else if (element.hasChild("url")) {
|
||||
String url = element.getChildValue("url");
|
||||
if (definition.hasExtension("http://hl7.org/fhir/StructureDefinition/maxSize")) {
|
||||
try {
|
||||
if (url.startsWith("http://") || url.startsWith("https://")) {
|
||||
if (fetcher == null) {
|
||||
fetchError = context.formatMessage(I18nConstants.TYPE_SPECIFIC_CHECKS_DT_ATT_NO_FETCHER, url);
|
||||
} else {
|
||||
byte[] cnt = fetcher.fetchRaw(url);
|
||||
size = cnt.length;
|
||||
}
|
||||
} else if (url.startsWith("file:")) {
|
||||
size = new File(url.substring(5)).length();
|
||||
} else {
|
||||
fetchError = context.formatMessage(I18nConstants.TYPE_SPECIFIC_CHECKS_DT_ATT_UNKNOWN_URL_SCHEME, url); }
|
||||
} catch (Exception e) {
|
||||
fetchError = context.formatMessage(I18nConstants.TYPE_SPECIFIC_CHECKS_DT_ATT_URL_ERROR, url, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (definition.hasExtension("http://hl7.org/fhir/StructureDefinition/maxSize")) {
|
||||
if (warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, size >= 0, fetchError)) {
|
||||
long def = Long.parseLong(ToolingExtensions.readStringExtension(definition, "http://hl7.org/fhir/StructureDefinition/maxSize"));
|
||||
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, size <= def, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_ATT_TOO_LONG, size, def);
|
||||
}
|
||||
}
|
||||
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, (element.hasChild("data") || element.hasChild("url")) || (element.hasChild("contentType") || element.hasChild("language")),
|
||||
I18nConstants.TYPE_SPECIFIC_CHECKS_DT_ATT_NO_CONTENT);
|
||||
}
|
||||
|
||||
// implementation
|
||||
|
@ -3689,7 +3763,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
} else if (type.equals("Coding")) {
|
||||
checkCoding(errors, ei.getPath(), ei.getElement(), profile, ei.definition, inCodeableConcept, checkDisplayInContext, stack);
|
||||
} else if (type.equals("Quantity")) {
|
||||
checkQuantity(errors, ei.getPath(), ei.getElement(), profile, ei.definition, inCodeableConcept, checkDisplayInContext, stack);
|
||||
checkQuantity(errors, ei.getPath(), ei.getElement(), profile, ei.definition, stack);
|
||||
} else if (type.equals("Attachment")) {
|
||||
checkAttachment(errors, ei.getPath(), ei.getElement(), profile, ei.definition, inCodeableConcept, checkDisplayInContext, stack);
|
||||
} else if (type.equals("CodeableConcept")) {
|
||||
checkDisplay = checkCodeableConcept(errors, ei.getPath(), ei.getElement(), profile, ei.definition, stack);
|
||||
thisIsCodeableConcept = true;
|
||||
|
|
|
@ -53,6 +53,9 @@ import org.junit.jupiter.params.provider.MethodSource;
|
|||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -460,4 +463,11 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
|
|||
TextFile.stringToFile(content, Utilities.path("[tmp]", "validator-produced-manifest.json"));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] fetchRaw(String source) throws MalformedURLException, IOException {
|
||||
URL url = new URL(source);
|
||||
URLConnection c = url.openConnection();
|
||||
return TextFile.streamToBytes(c.getInputStream());
|
||||
}
|
||||
}
|
|
@ -9,6 +9,8 @@ title: FHIR Validator Release Notes
|
|||
* Fix to check invariants on Elements with type redirections (e.g. ValueSet.compose.exclude)
|
||||
* fix fatal NPE validating bundles when resource is missing
|
||||
* fix tests for R5 changes
|
||||
* Fix to validate code units on Quantity
|
||||
* Add validation for Attachment & check maxSize extension on base64Binary
|
||||
|
||||
## v4.2.30 (2020-05-12)
|
||||
|
||||
|
|
Loading…
Reference in New Issue