diff --git a/org.hl7.fhir.convertors/pom.xml b/org.hl7.fhir.convertors/pom.xml index 0e5ac5344..b10056d98 100644 --- a/org.hl7.fhir.convertors/pom.xml +++ b/org.hl7.fhir.convertors/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.9-SNAPSHOT + 3.7.10-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu2/pom.xml b/org.hl7.fhir.dstu2/pom.xml index 29ec6c8bd..7fec6c5e3 100644 --- a/org.hl7.fhir.dstu2/pom.xml +++ b/org.hl7.fhir.dstu2/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.9-SNAPSHOT + 3.7.10-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu2016may/pom.xml b/org.hl7.fhir.dstu2016may/pom.xml index 21f0c078f..51350f7ec 100644 --- a/org.hl7.fhir.dstu2016may/pom.xml +++ b/org.hl7.fhir.dstu2016may/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.9-SNAPSHOT + 3.7.10-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu3/pom.xml b/org.hl7.fhir.dstu3/pom.xml index 22075bfb6..d7229aaeb 100644 --- a/org.hl7.fhir.dstu3/pom.xml +++ b/org.hl7.fhir.dstu3/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.9-SNAPSHOT + 3.7.10-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r4/pom.xml b/org.hl7.fhir.r4/pom.xml index e157f8f3e..858d1c550 100644 --- a/org.hl7.fhir.r4/pom.xml +++ b/org.hl7.fhir.r4/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.9-SNAPSHOT + 3.7.10-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r5/pom.xml b/org.hl7.fhir.r5/pom.xml index 7f1278180..abdc93b66 100644 --- a/org.hl7.fhir.r5/pom.xml +++ b/org.hl7.fhir.r5/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.9-SNAPSHOT + 3.7.10-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.utilities/pom.xml b/org.hl7.fhir.utilities/pom.xml index 7fe1f4988..6c4751613 100644 --- a/org.hl7.fhir.utilities/pom.xml +++ b/org.hl7.fhir.utilities/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.9-SNAPSHOT + 3.7.10-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.validation.cli/pom.xml b/org.hl7.fhir.validation.cli/pom.xml index df44b1b9d..17c34740a 100644 --- a/org.hl7.fhir.validation.cli/pom.xml +++ b/org.hl7.fhir.validation.cli/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.9-SNAPSHOT + 3.7.10-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.validation/pom.xml b/org.hl7.fhir.validation/pom.xml index 370c2818b..99fd407dc 100644 --- a/org.hl7.fhir.validation/pom.xml +++ b/org.hl7.fhir.validation/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.9-SNAPSHOT + 3.7.10-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r4/validation/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r4/validation/InstanceValidator.java index 8d6aaf053..b8a77aae4 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r4/validation/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r4/validation/InstanceValidator.java @@ -237,7 +237,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat throw new NotImplementedException("Not done yet (ValidatorHostServices.conformsToProfile), when item is element"); boolean ok = true; for (ValidationMessage v : valerrors) - ok = ok && v.getLevel().isError(); + ok = ok && !v.getLevel().isError(); return ok; } @@ -1483,7 +1483,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } if (type.equals("dateTime")) { - rule(errors, IssueType.INVALID, e.line(), e.col(), path, yearIsValid(e.primitiveValue()), "The value '" + e.primitiveValue() + "' does not have a valid year"); + warning(errors, IssueType.INVALID, e.line(), e.col(), path, yearIsValid(e.primitiveValue()), "The value '" + e.primitiveValue() + "' is outside the range of reasonable years - check for data entry error"); rule(errors, IssueType.INVALID, e.line(), e.col(), path, e.primitiveValue() .matches("([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)(-(0[1-9]|1[0-2])(-(0[1-9]|[1-2][0-9]|3[0-1])(T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\\.[0-9]+)?(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?)?)?)?"), @@ -1508,7 +1508,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } if (type.equals("date")) { - rule(errors, IssueType.INVALID, e.line(), e.col(), path, yearIsValid(e.primitiveValue()), "The value '" + e.primitiveValue() + "' does not have a valid year"); + warning(errors, IssueType.INVALID, e.line(), e.col(), path, yearIsValid(e.primitiveValue()), "The value '" + e.primitiveValue() + "' is outside the range of reasonable years - check for data entry error"); rule(errors, IssueType.INVALID, e.line(), e.col(), path, e.primitiveValue().matches("([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)(-(0[1-9]|1[0-2])(-(0[1-9]|[1-2][0-9]|3[0-1]))?)?"), "Not a valid date"); rule(errors, IssueType.INVALID, e.line(), e.col(), path, !context.hasMaxLength() || context.getMaxLength()==0 || e.primitiveValue().length() <= context.getMaxLength(), "value is longer than permitted maximum value of " + context.getMaxLength()); @@ -1579,7 +1579,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat rule(errors, IssueType.INVALID, e.line(), e.col(), path, e.primitiveValue().matches("-?[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\\.[0-9]+)?(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))"), "The instant '" + e.primitiveValue() + "' is not valid (by regex)"); - rule(errors, IssueType.INVALID, e.line(), e.col(), path, yearIsValid(e.primitiveValue()), "The value '" + e.primitiveValue() + "' does not have a valid year"); + warning(errors, IssueType.INVALID, e.line(), e.col(), path, yearIsValid(e.primitiveValue()), "The value '" + e.primitiveValue() + "' is outside the range of reasonable years - check for data entry error"); try { InstantType dt = new InstantType(e.primitiveValue()); } catch (Exception ex) { @@ -4127,12 +4127,16 @@ private String misplacedItemError(QuestionnaireItemComponent qItem) { } try { int i = Integer.parseInt(v.substring(0, Math.min(4, v.length()))); - return i >= 1800 && i <= 2100; + return i >= 1800 && i <= thisYear() + 80; } catch (NumberFormatException e) { return false; } } + private int thisYear() { + return Calendar.getInstance().get(Calendar.YEAR); + } + public class ChildIterator { private String basePath; private Element parent; @@ -4400,5 +4404,9 @@ private String misplacedItemError(QuestionnaireItemComponent qItem) { return expr; } + public IEvaluationContext getExternalHostServices() { + return externalHostServices; + } + } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java index 1c1f86d9e..8e9d20b9f 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java @@ -26,6 +26,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.Calendar; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -1483,7 +1484,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } if (type.equals("dateTime")) { - rule(errors, IssueType.INVALID, e.line(), e.col(), path, yearIsValid(e.primitiveValue()), "The value '" + e.primitiveValue() + "' does not have a valid year"); + warning(errors, IssueType.INVALID, e.line(), e.col(), path, yearIsValid(e.primitiveValue()), "The value '" + e.primitiveValue() + "' is outside the range of reasonable years - check for data entry error"); rule(errors, IssueType.INVALID, e.line(), e.col(), path, e.primitiveValue() .matches("([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)(-(0[1-9]|1[0-2])(-(0[1-9]|[1-2][0-9]|3[0-1])(T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\\.[0-9]+)?(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?)?)?)?"), @@ -1508,7 +1509,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } if (type.equals("date")) { - rule(errors, IssueType.INVALID, e.line(), e.col(), path, yearIsValid(e.primitiveValue()), "The value '" + e.primitiveValue() + "' does not have a valid year"); + warning(errors, IssueType.INVALID, e.line(), e.col(), path, yearIsValid(e.primitiveValue()), "The value '" + e.primitiveValue() + "' is outside the range of reasonable years - check for data entry error"); rule(errors, IssueType.INVALID, e.line(), e.col(), path, e.primitiveValue().matches("([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)(-(0[1-9]|1[0-2])(-(0[1-9]|[1-2][0-9]|3[0-1]))?)?"), "Not a valid date"); rule(errors, IssueType.INVALID, e.line(), e.col(), path, !context.hasMaxLength() || context.getMaxLength()==0 || e.primitiveValue().length() <= context.getMaxLength(), "value is longer than permitted maximum value of " + context.getMaxLength()); @@ -1579,7 +1580,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat rule(errors, IssueType.INVALID, e.line(), e.col(), path, e.primitiveValue().matches("-?[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\\.[0-9]+)?(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))"), "The instant '" + e.primitiveValue() + "' is not valid (by regex)"); - rule(errors, IssueType.INVALID, e.line(), e.col(), path, yearIsValid(e.primitiveValue()), "The value '" + e.primitiveValue() + "' does not have a valid year"); + warning(errors, IssueType.INVALID, e.line(), e.col(), path, yearIsValid(e.primitiveValue()), "The value '" + e.primitiveValue() + "' is outside the range of reasonable years - check for data entry error"); try { InstantType dt = new InstantType(e.primitiveValue()); } catch (Exception ex) { @@ -4127,12 +4128,16 @@ private String misplacedItemError(QuestionnaireItemComponent qItem) { } try { int i = Integer.parseInt(v.substring(0, Math.min(4, v.length()))); - return i >= 1800 && i <= 2100; + return i >= 1800 && i <= thisYear() + 80; } catch (NumberFormatException e) { return false; } } + private int thisYear() { + return Calendar.getInstance().get(Calendar.YEAR); + } + public class ChildIterator { private String basePath; private Element parent; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/ValidationEngine.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/ValidationEngine.java index f7dde7e75..6cd9e022c 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/ValidationEngine.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/ValidationEngine.java @@ -465,7 +465,7 @@ public class ValidationEngine { if (stream != null) return readZip(stream); stream = fetchFromUrlSpecific(Utilities.pathURL(src, "validator.pack"), true); - FhirFormat fmt = checkIsResource(stream); + FhirFormat fmt = checkIsResource(stream, src); if (fmt != null) { Map res = new HashMap(); res.put(Utilities.changeFileExt(src, "."+fmt.getExtension()), TextFile.fileToBytes(src)); @@ -490,15 +490,21 @@ public class ValidationEngine { private Map scanDirectory(File f) throws FileNotFoundException, IOException { Map res = new HashMap(); for (File ff : f.listFiles()) { + if (!isIgnoreFile(ff)) { FhirFormat fmt = checkIsResource(ff.getAbsolutePath()); if (fmt != null) { res.put(Utilities.changeFileExt(ff.getName(), "."+fmt.getExtension()), TextFile.fileToBytes(ff.getAbsolutePath())); } } + } return res; } + private boolean isIgnoreFile(File ff) { + return Utilities.existsInList(ff.getName(), ".DS_Store"); + } + private Map loadPackage(InputStream stream, String name) throws FileNotFoundException, IOException { return loadPackage(pcm.extractLocally(stream, name)); } @@ -587,7 +593,8 @@ public class ValidationEngine { this.noInvariantChecks = value; } - private FhirFormat checkIsResource(InputStream stream) { + private FhirFormat checkIsResource(InputStream stream, String filename) { + System.out.println(" ..Detect format for "+filename); try { Manager.parse(context, stream, FhirFormat.XML); return FhirFormat.XML; @@ -608,6 +615,7 @@ public class ValidationEngine { return FhirFormat.TEXT; } catch (Exception e) { } + System.out.println(" .. not a resource: "+filename); return null; } @@ -621,8 +629,10 @@ public class ValidationEngine { return FhirFormat.TURTLE; if (Utilities.existsInList(ext, "map")) return FhirFormat.TEXT; + if (Utilities.existsInList(ext, "txt")) + return FhirFormat.TEXT; - return checkIsResource(new FileInputStream(path)); + return checkIsResource(new FileInputStream(path), path); } public void connectToTSServer(String url, String log, FhirPublication version) throws URISyntaxException, FHIRException { @@ -657,6 +667,7 @@ public class ValidationEngine { for (Entry t : source.entrySet()) { String fn = t.getKey(); if (!exemptFile(fn)) { + System.out.print(" ..file: "+fn); Resource r = null; try { if (version.equals("3.0.1") || version.equals("3.0.0")) { @@ -665,6 +676,8 @@ public class ValidationEngine { res = new org.hl7.fhir.dstu3.formats.XmlParser().parse(new ByteArrayInputStream(t.getValue())); else if (fn.endsWith(".json") && !fn.endsWith("template.json")) res = new org.hl7.fhir.dstu3.formats.JsonParser().parse(new ByteArrayInputStream(t.getValue())); + else if (fn.endsWith(".txt") || fn.endsWith(".map") ) + res = new org.hl7.fhir.dstu3.utils.StructureMapUtilities(null).parse(new String(t.getValue())); else throw new Exception("Unsupported format for "+fn); r = VersionConvertor_30_50.convertResource(res, false); @@ -674,6 +687,8 @@ public class ValidationEngine { res = new org.hl7.fhir.r4.formats.XmlParser().parse(new ByteArrayInputStream(t.getValue())); else if (fn.endsWith(".json") && !fn.endsWith("template.json")) res = new org.hl7.fhir.r4.formats.JsonParser().parse(new ByteArrayInputStream(t.getValue())); + else if (fn.endsWith(".txt") || fn.endsWith(".map") ) + res = new org.hl7.fhir.r4.utils.StructureMapUtilities(null).parse(new String(t.getValue()), fn); else throw new Exception("Unsupported format for "+fn); r = VersionConvertor_40_50.convertResource(res); @@ -703,6 +718,8 @@ public class ValidationEngine { r = new JsonParser().parse(new ByteArrayInputStream(t.getValue())); else if (fn.endsWith(".txt")) r = new StructureMapUtilities(context, null, null).parse(TextFile.bytesToString(t.getValue()), fn); + else if (fn.endsWith(".txt") || fn.endsWith(".map") ) + r = new org.hl7.fhir.r5.utils.StructureMapUtilities(null).parse(new String(t.getValue()), fn); else throw new Exception("Unsupported format for "+fn); } else @@ -771,6 +788,8 @@ public class ValidationEngine { res.cntType = FhirFormat.XML; else if (t.getKey().endsWith(".ttl")) res.cntType = FhirFormat.TURTLE; + else if (t.getKey().endsWith(".txt") || t.getKey().endsWith(".map")) + res.cntType = FhirFormat.TEXT; else throw new Exception("Todo: Determining resource type is not yet done"); } diff --git a/pom.xml b/pom.xml index 22766e579..d50235183 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ each other. It is fine to bump the point version of this POM without affecting HAPI FHIR. --> - 3.7.9-SNAPSHOT + 3.7.10-SNAPSHOT 3.7.0-SNAPSHOT