diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 8c8eeef40..9824e3b22 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1 +1,8 @@ -* fix for issue 383 \ No newline at end of file +Validator Changes: +* no effective changes + +Other Code Changes: +* fix bug converting type mode in Structure Map +* fix bug converting Timing.when (issue 383) +* fix bug doing date time comparisons with seconds in FHIRPath +* Add support for instance-name and instance-description extensions \ No newline at end of file diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/StructureMap40_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/StructureMap40_50.java index ee3be5756..f525cb558 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/StructureMap40_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/StructureMap40_50.java @@ -3,6 +3,7 @@ package org.hl7.fhir.convertors.conv40_50; import org.hl7.fhir.convertors.VersionConvertor_40_50; import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.r4.model.StructureMap.StructureMapGroupTypeMode; import java.util.stream.Collectors; @@ -220,8 +221,11 @@ public class StructureMap40_50 extends VersionConvertor_40_50 { tgt.setNameElement(convertId(src.getNameElement())); if (src.hasExtends()) tgt.setExtendsElement(convertId(src.getExtendsElement())); - if (src.hasTypeMode()) + if (src.hasTypeMode()) { tgt.setTypeModeElement(convertStructureMapGroupTypeMode(src.getTypeModeElement())); + } else { + tgt.setTypeMode(StructureMapGroupTypeMode.NONE); + } if (src.hasDocumentation()) tgt.setDocumentationElement(convertString(src.getDocumentationElement())); for (org.hl7.fhir.r5.model.StructureMap.StructureMapGroupInputComponent t : src.getInput()) tgt.addInput(convertStructureMapGroupInputComponent(t)); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java index 6f220ce9f..14cb75b2a 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java @@ -812,6 +812,10 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon return loadedPackages.contains(id+"#"+ver); } + public boolean hasPackage(String idAndver) { + return loadedPackages.contains(idAndver); + } + public void setClock(TimeTracker tt) { clock = tt; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BaseDateTimeType.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BaseDateTimeType.java index 544642cf2..defd051a3 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BaseDateTimeType.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BaseDateTimeType.java @@ -899,16 +899,12 @@ public abstract class BaseDateTimeType extends PrimitiveType { lowRight = lowRight - (14 * DateUtils.MILLIS_PER_HOUR); highRight = highRight + (14 * DateUtils.MILLIS_PER_HOUR); } - System.out.print("["+((lowLeft / 1000) - 130000000)+"-"+((highLeft / 1000) - 130000000)+"] vs ["+((lowRight / 1000) - 130000000)+"-"+((highRight / 1000) - 130000000)+"] = "); if (highRight < lowLeft) { - System.out.println("false"); return false; } if (highLeft < lowRight) { - System.out.println("false"); return false; } - System.out.println("true"); return true; } @@ -1000,6 +996,14 @@ public abstract class BaseDateTimeType extends PrimitiveType { return def; } + if (left.getSecond() < right.getSecond()) { + return -1; + } else if (left.getSecond() > right.getSecond()) { + return 1; + } else if (left.getPrecision() == TemporalPrecisionEnum.SECOND && right.getPrecision() == TemporalPrecisionEnum.SECOND) { + return 0; + } + if (left.getSecondsMilli() < right.getSecondsMilli()) { return -1; } else if (left.getSecondsMilli() > right.getSecondsMilli()) { diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java index fdb9338c2..f51396162 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java @@ -523,7 +523,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple InputStream stream = fetchFromUrlSpecific(Utilities.pathURL("http://build.fhir.org", id + ".tgz"), false); return new InputStreamWithSrc(stream, Utilities.pathURL("http://build.fhir.org", id + ".tgz"), "current"); } else { - throw new FHIRException("The package '" + id + "' has not entry on the current build server"); + throw new FHIRException("The package '" + id + "' has no entry on the current build server"); } } diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java index 414cb0784..4e7479f0d 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java @@ -1087,6 +1087,12 @@ public class NpmPackage { return false; } } + if (Utilities.existsInList(name(), "fhir.test.data.r2", "fhir.test.data.r3", "fhir.test.data.r4", "fhir.tx.support.r2", "fhir.tx.support.r3", "fhir.tx.support.r4", "us.nlm.vsac")) { + return true; + } + if (JSONUtil.bool(npm, "lazy-load")) { + return true; + } if (!hasFile("other", "spec.internals")) { return false; } diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlParser.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlParser.java index af088b66b..c67e81ce5 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlParser.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlParser.java @@ -55,6 +55,7 @@ import org.xmlpull.v1.XmlPullParserException; public class XhtmlParser { public static final String XHTML_NS = "http://www.w3.org/1999/xhtml"; + private static final char END_OF_CHARS = (char) -1; public class NSMap { private Map nslist = new HashMap(); @@ -515,7 +516,7 @@ private boolean elementIsOk(String name) throws FHIRFormatError { private void parseElementInner(XhtmlNode node, List parents, NSMap nsm, boolean escaping) throws FHIRFormatError, IOException { StringBuilder s = new StringBuilder(); - while (peekChar() != '\0' && !parents.contains(unwindPoint) && !(node == unwindPoint)) + while (peekChar() != END_OF_CHARS && !parents.contains(unwindPoint) && !(node == unwindPoint)) { if (peekChar() == '<') { @@ -606,7 +607,7 @@ private boolean elementIsOk(String name) throws FHIRFormatError { { while (Character.isWhitespace(peekChar())) readChar(); - while (peekChar() != '>' && peekChar() != '/' && peekChar() != '\0') + while (peekChar() != '>' && peekChar() != '/' && peekChar() != END_OF_CHARS) { String name = readName(); if (name.length() == 0) @@ -630,7 +631,7 @@ private boolean elementIsOk(String name) throws FHIRFormatError { if (peekChar() == '"' || peekChar() == '\'') node.getAttributes().put(name, parseAttributeValue(readChar())); else - node.getAttributes().put(name, parseAttributeValue('\0')); + node.getAttributes().put(name, parseAttributeValue(END_OF_CHARS)); } while (Character.isWhitespace(peekChar())) readChar(); @@ -640,7 +641,7 @@ private boolean elementIsOk(String name) throws FHIRFormatError { private String parseAttributeValue(char term) throws IOException, FHIRFormatError { StringBuilder b = new StringBuilder(); - while (peekChar() != '\0' && peekChar() != '>' && (term != '\0' || peekChar() != '/') && peekChar() != term) + while (peekChar() != END_OF_CHARS && peekChar() != '>' && (term != END_OF_CHARS || peekChar() != '/') && peekChar() != term) { if (peekChar() == '&') { @@ -704,15 +705,15 @@ private boolean elementIsOk(String name) throws FHIRFormatError { if (cache.length() > 0) return cache.charAt(0); else if (!rdr.ready()) - return '\0'; + return END_OF_CHARS; else { - char c = (char)rdr.read(); - if (c == (char)-1) - { + int i = rdr.read(); + if (i == -1) { cache = ""; - return '\0'; + return END_OF_CHARS; } + char c = (char) i; cache = Character.toString(c); return c; } @@ -727,7 +728,7 @@ private boolean elementIsOk(String name) throws FHIRFormatError { cache = cache.length() == 1 ? "" : cache.substring(1); } else if (!rdr.ready()) - c = '\0'; + c = END_OF_CHARS; else c = (char)rdr.read(); if (c == '\r' || c == '\n') { @@ -744,9 +745,9 @@ private boolean elementIsOk(String name) throws FHIRFormatError { private String readToTagEnd() throws IOException, FHIRFormatError { StringBuilder s = new StringBuilder(); - while (peekChar() != '>' && peekChar() != '\0') + while (peekChar() != '>' && peekChar() != END_OF_CHARS) s.append(readChar()); - if (peekChar() != '\0') + if (peekChar() != END_OF_CHARS) { readChar(); skipWhiteSpace(); @@ -765,7 +766,7 @@ private boolean elementIsOk(String name) throws FHIRFormatError { if (c == '>') { done = true; readChar(); - } else if (c != '\0') + } else if (c != END_OF_CHARS) s.append(readChar()); else if (mustBeWellFormed) throw new FHIRFormatError("Unexpected termination of html source"+descLoc()); @@ -814,12 +815,12 @@ private boolean elementIsOk(String name) throws FHIRFormatError { } else if (c == '[' && s.toString().startsWith("DOCTYPE ")) { doctypeEntities = true; s.append(readChar()); - } else if (c != '\0') + } else if (c != END_OF_CHARS) s.append(readChar()); else if (mustBeWellFormed) throw new FHIRFormatError("Unexpected termination of html source"+descLoc()); } - if (peekChar() != '\0') + if (peekChar() != END_OF_CHARS) { readChar(); skipWhiteSpace(); diff --git a/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/tests/XhtmlNodeTest.java b/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/tests/XhtmlNodeTest.java index 9792ecea1..1ff8ffc7e 100644 --- a/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/tests/XhtmlNodeTest.java +++ b/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/tests/XhtmlNodeTest.java @@ -1,6 +1,8 @@ package org.hl7.fhir.utilities.tests; +import org.hl7.fhir.exceptions.FHIRFormatError; import org.hl7.fhir.utilities.xhtml.XhtmlNode; +import org.hl7.fhir.utilities.xhtml.XhtmlParser; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.slf4j.Logger; @@ -88,4 +90,9 @@ public class XhtmlNodeTest { ObjectOutputStream oout = new ObjectOutputStream(bout); oout.writeObject(node); } + + @Test + public void testParseBadChars() throws FHIRFormatError, IOException { + XhtmlNode x = new XhtmlParser().parse(BaseTestingUtilities.loadTestResource("xhtml", "bad-chars.html"), "div"); + } } \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java index 4784f88c3..23929b0c5 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java @@ -1007,7 +1007,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst } public void loadIg(String src, boolean recursive) throws IOException, FHIRException { - NpmPackage npm = src.matches(FilesystemPackageCacheManager.PACKAGE_VERSION_REGEX_OPT) ? pcm.loadPackage(src, null) : null; + NpmPackage npm = src.matches(FilesystemPackageCacheManager.PACKAGE_VERSION_REGEX_OPT) && !new File(src).exists() ? pcm.loadPackage(src, null) : null; if (npm != null) { for (String s : npm.dependencies()) { if (!context.getLoadedPackages().contains(s)) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java index 24ccf2b73..d8e67fa8c 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java @@ -11,17 +11,23 @@ public class SpecialExtensions { // copied from R5 spec private static final String MUST_SUPPORT_SOURCE = "{\"resourceType\" : \"StructureDefinition\",\"id\" : \"elementdefinition-type-must-support\",\"extension\" : [{\"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-wg\",\"valueCode\" : \"fhir\"},{\"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm\",\"valueInteger\" : 1}],\"url\" : \"http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support\",\"version\" : \"4.5.0\",\"name\" : \"type-must-support\",\"status\" : \"draft\",\"date\" : \"2015-02-28\",\"publisher\" : \"Health Level Seven, Inc. - FHIR Core WG\",\"contact\" : [{\"telecom\" : [{\"system\" : \"url\",\"value\" : \"http://hl7.org/special/committees/FHIR\"}]}],\"description\" : \"If true indicates that the specified type, profile or targetProfile must be supported by implementations.\",\"fhirVersion\" : \"4.5.0\",\"mapping\" : [{\"identity\" : \"rim\",\"uri\" : \"http://hl7.org/v3\",\"name\" : \"RIM Mapping\"}],\"kind\" : \"complex-type\",\"abstract\" : false,\"context\" : [{\"type\" : \"element\",\"expression\" : \"ElementDefinition.type\"},{\"type\" : \"element\",\"expression\" : \"ElementDefinition.type.profile\"},{\"type\" : \"element\",\"expression\" : \"ElementDefinition.type.targetProfile\"}],\"type\" : \"Extension\",\"baseDefinition\" : \"http://hl7.org/fhir/StructureDefinition/Extension\",\"derivation\" : \"constraint\",\"snapshot\" : {\"element\" : [{\"id\" : \"Extension\",\"path\" : \"Extension\",\"short\" : \"The specified type/profile/target must be supported by implementations\",\"definition\" : \"If true indicates that the specified type, profile or targetProfile must be supported by implementations.\",\"comment\" : \"An element may be labelled as must support. This extension clarifies which types/profiles/targetProfiles are must-support. It has no meaning if the element itself is not must-support. If the element is labelled must-support, and none of the options are labelled as must support, then an application must support at least one of the possible options, but is not required to support all of them.\",\"min\" : 0,\"max\" : \"1\",\"base\" : {\"path\" : \"Extension\",\"min\" : 0,\"max\" : \"*\"},\"constraint\" : [{\"key\" : \"ele-1\",\"severity\" : \"error\",\"human\" : \"All FHIR elements must have a @value or children\",\"expression\" : \"hasValue() or (children().count() > id.count())\",\"xpath\" : \"@value|f:*|h:div\",\"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\"},{\"key\" : \"ext-1\",\"severity\" : \"error\",\"human\" : \"Must have either extensions or value[x], not both\",\"expression\" : \"extension.exists() != value.exists()\",\"xpath\" : \"exists(f:extension)!=exists(f:*[starts-with(local-name(.), 'value')])\",\"source\" : \"http://hl7.org/fhir/StructureDefinition/Extension\"}],\"isModifier\" : false},{\"id\" : \"Extension.id\",\"path\" : \"Extension.id\",\"representation\" : [\"xmlAttr\"],\"short\" : \"Unique id for inter-element referencing\",\"definition\" : \"Unique id for the element within a resource (for internal references). This may be any string value that does not contain spaces.\",\"min\" : 0,\"max\" : \"1\",\"base\" : {\"path\" : \"Element.id\",\"min\" : 0,\"max\" : \"1\"},\"type\" : [{\"extension\" : [{\"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type\",\"valueUri\" : \"string\"}],\"code\" : \"http://hl7.org/fhirpath/System.String\"}],\"isModifier\" : false,\"isSummary\" : false,\"mapping\" : [{\"identity\" : \"rim\",\"map\" : \"n/a\"}]},{\"id\" : \"Extension.extension\",\"path\" : \"Extension.extension\",\"slicing\" : {\"discriminator\" : [{\"type\" : \"value\",\"path\" : \"url\"}],\"description\" : \"Extensions are always sliced by (at least) url\",\"rules\" : \"open\"},\"short\" : \"Extension\",\"definition\" : \"An Extension\",\"min\" : 0,\"max\" : \"0\",\"base\" : {\"path\" : \"Element.extension\",\"min\" : 0,\"max\" : \"*\"},\"type\" : [{\"code\" : \"Extension\"}],\"constraint\" : [{\"key\" : \"ele-1\",\"severity\" : \"error\",\"human\" : \"All FHIR elements must have a @value or children\",\"expression\" : \"hasValue() or (children().count() > id.count())\",\"xpath\" : \"@value|f:*|h:div\",\"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\"},{\"key\" : \"ext-1\",\"severity\" : \"error\",\"human\" : \"Must have either extensions or value[x], not both\",\"expression\" : \"extension.exists() != value.exists()\",\"xpath\" : \"exists(f:extension)!=exists(f:*[starts-with(local-name(.), \\\"value\\\")])\",\"source\" : \"http://hl7.org/fhir/StructureDefinition/Extension\"}],\"isModifier\" : false,\"isSummary\" : false},{\"id\" : \"Extension.url\",\"path\" : \"Extension.url\",\"representation\" : [\"xmlAttr\"],\"short\" : \"identifies the meaning of the extension\",\"definition\" : \"Source of the definition for the extension code - a logical name or a URL.\",\"comment\" : \"The definition may point directly to a computable or human-readable definition of the extensibility codes, or it may be a logical URI as declared in some other specification. The definition SHALL be a URI for the Structure Definition defining the extension.\",\"min\" : 1,\"max\" : \"1\",\"base\" : {\"path\" : \"Extension.url\",\"min\" : 1,\"max\" : \"1\"},\"type\" : [{\"extension\" : [{\"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type\",\"valueUri\" : \"uri\"}],\"code\" : \"http://hl7.org/fhirpath/System.String\"}],\"fixedUri\" : \"http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support\",\"isModifier\" : false,\"isSummary\" : false,\"mapping\" : [{\"identity\" : \"rim\",\"map\" : \"N/A\"}]},{\"id\" : \"Extension.value[x]\",\"path\" : \"Extension.value[x]\",\"short\" : \"Value of extension\",\"definition\" : \"Value of extension - must be one of a constrained set of the data types (see [Extensibility](extensibility.html) for a list).\",\"min\" : 1,\"max\" : \"1\",\"base\" : {\"path\" : \"Extension.value[x]\",\"min\" : 0,\"max\" : \"1\"},\"type\" : [{\"code\" : \"boolean\"}],\"constraint\" : [{\"key\" : \"ele-1\",\"severity\" : \"error\",\"human\" : \"All FHIR elements must have a @value or children\",\"expression\" : \"hasValue() or (children().count() > id.count())\",\"xpath\" : \"@value|f:*|h:div\",\"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\"}],\"isModifier\" : false,\"isSummary\" : false,\"mapping\" : [{\"identity\" : \"rim\",\"map\" : \"N/A\"}]}]},\"differential\" : {\"element\" : [{\"id\" : \"Extension\",\"path\" : \"Extension\",\"short\" : \"The specified type/profile/target must be supported by implementations\",\"definition\" : \"If true indicates that the specified type, profile or targetProfile must be supported by implementations.\",\"comment\" : \"An element may be labelled as must support. This extension clarifies which types/profiles/targetProfiles are must-support. It has no meaning if the element itself is not must-support. If the element is labelled must-support, and none of the options are labelled as must support, then an application must support at least one of the possible options, but is not required to support all of them.\",\"min\" : 0,\"max\" : \"1\"},{\"id\" : \"Extension.extension\",\"path\" : \"Extension.extension\",\"max\" : \"0\"},{\"id\" : \"Extension.url\",\"path\" : \"Extension.url\",\"fixedUri\" : \"http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support\"},{\"id\" : \"Extension.value[x]\",\"path\" : \"Extension.value[x]\",\"min\" : 1,\"type\" : [{\"code\" : \"boolean\"}]}]}}"; + private static final String INSTANCE_NAME_SOURCE = "{\"resourceType\" : \"StructureDefinition\",\"id\" : \"instance-name\",\"extension\" : [{\"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-wg\",\"valueCode\" : \"fhir\"},{\"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm\",\"valueInteger\" : 1}],\"url\" : \"http://hl7.org/fhir/StructureDefinition/instance-name\",\"version\" : \"4.5.0\",\"name\" : \"instance-name\",\"status\" : \"draft\",\"date\" : \"2015-02-28\",\"publisher\" : \"Health Level Seven, Inc. - FHIR Core WG\",\"contact\" : [{\"telecom\" : [{\"system\" : \"url\",\"value\" : \"http://hl7.org/special/committees/FHIR\"}]}],\"description\" : \"If true indicates that the specified type, profile or targetProfile must be supported by implementations.\",\"fhirVersion\" : \"4.5.0\",\"mapping\" : [{\"identity\" : \"rim\",\"uri\" : \"http://hl7.org/v3\",\"name\" : \"RIM Mapping\"}],\"kind\" : \"complex-type\",\"abstract\" : false,\"context\" : [{\"type\" : \"element\",\"expression\" : \"Resource.meta\"}],\"type\" : \"Extension\",\"baseDefinition\" : \"http://hl7.org/fhir/StructureDefinition/Extension\",\"derivation\" : \"constraint\",\"snapshot\" : {\"element\" : [{\"id\" : \"Extension\",\"path\" : \"Extension\",\"short\" : \"The specified type/profile/target must be supported by implementations\",\"definition\" : \"If true indicates that the specified type, profile or targetProfile must be supported by implementations.\",\"comment\" : \"todo.\",\"min\" : 0,\"max\" : \"1\",\"base\" : {\"path\" : \"Extension\",\"min\" : 0,\"max\" : \"*\"},\"constraint\" : [{\"key\" : \"ele-1\",\"severity\" : \"error\",\"human\" : \"All FHIR elements must have a @value or children\",\"expression\" : \"hasValue() or (children().count() > id.count())\",\"xpath\" : \"@value|f:*|h:div\",\"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\"},{\"key\" : \"ext-1\",\"severity\" : \"error\",\"human\" : \"Must have either extensions or value[x], not both\",\"expression\" : \"extension.exists() != value.exists()\",\"xpath\" : \"exists(f:extension)!=exists(f:*[starts-with(local-name(.), 'value')])\",\"source\" : \"http://hl7.org/fhir/StructureDefinition/Extension\"}],\"isModifier\" : false},{\"id\" : \"Extension.id\",\"path\" : \"Extension.id\",\"representation\" : [\"xmlAttr\"],\"short\" : \"Unique id for inter-element referencing\",\"definition\" : \"Unique id for the element within a resource (for internal references). This may be any string value that does not contain spaces.\",\"min\" : 0,\"max\" : \"1\",\"base\" : {\"path\" : \"Element.id\",\"min\" : 0,\"max\" : \"1\"},\"type\" : [{\"extension\" : [{\"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type\",\"valueUri\" : \"string\"}],\"code\" : \"http://hl7.org/fhirpath/System.String\"}],\"isModifier\" : false,\"isSummary\" : false,\"mapping\" : [{\"identity\" : \"rim\",\"map\" : \"n/a\"}]},{\"id\" : \"Extension.extension\",\"path\" : \"Extension.extension\",\"slicing\" : {\"discriminator\" : [{\"type\" : \"value\",\"path\" : \"url\"}],\"description\" : \"Extensions are always sliced by (at least) url\",\"rules\" : \"open\"},\"short\" : \"Extension\",\"definition\" : \"An Extension\",\"min\" : 0,\"max\" : \"0\",\"base\" : {\"path\" : \"Element.extension\",\"min\" : 0,\"max\" : \"*\"},\"type\" : [{\"code\" : \"Extension\"}],\"constraint\" : [{\"key\" : \"ele-1\",\"severity\" : \"error\",\"human\" : \"All FHIR elements must have a @value or children\",\"expression\" : \"hasValue() or (children().count() > id.count())\",\"xpath\" : \"@value|f:*|h:div\",\"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\"},{\"key\" : \"ext-1\",\"severity\" : \"error\",\"human\" : \"Must have either extensions or value[x], not both\",\"expression\" : \"extension.exists() != value.exists()\",\"xpath\" : \"exists(f:extension)!=exists(f:*[starts-with(local-name(.), \\\"value\\\")])\",\"source\" : \"http://hl7.org/fhir/StructureDefinition/Extension\"}],\"isModifier\" : false,\"isSummary\" : false},{\"id\" : \"Extension.url\",\"path\" : \"Extension.url\",\"representation\" : [\"xmlAttr\"],\"short\" : \"identifies the meaning of the extension\",\"definition\" : \"Source of the definition for the extension code - a logical name or a URL.\",\"comment\" : \"The definition may point directly to a computable or human-readable definition of the extensibility codes, or it may be a logical URI as declared in some other specification. The definition SHALL be a URI for the Structure Definition defining the extension.\",\"min\" : 1,\"max\" : \"1\",\"base\" : {\"path\" : \"Extension.url\",\"min\" : 1,\"max\" : \"1\"},\"type\" : [{\"extension\" : [{\"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type\",\"valueUri\" : \"uri\"}],\"code\" : \"http://hl7.org/fhirpath/System.String\"}],\"fixedUri\" : \"http://hl7.org/fhir/StructureDefinition/instance-name\",\"isModifier\" : false,\"isSummary\" : false,\"mapping\" : [{\"identity\" : \"rim\",\"map\" : \"N/A\"}]},{\"id\" : \"Extension.value[x]\",\"path\" : \"Extension.value[x]\",\"short\" : \"Value of extension\",\"definition\" : \"Value of extension - must be one of a constrained set of the data types (see [Extensibility](extensibility.html) for a list).\",\"min\" : 1,\"max\" : \"1\",\"base\" : {\"path\" : \"Extension.value[x]\",\"min\" : 0,\"max\" : \"1\"},\"type\" : [{\"code\" : \"string\"}],\"constraint\" : [{\"key\" : \"ele-1\",\"severity\" : \"error\",\"human\" : \"All FHIR elements must have a @value or children\",\"expression\" : \"hasValue() or (children().count() > id.count())\",\"xpath\" : \"@value|f:*|h:div\",\"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\"}],\"isModifier\" : false,\"isSummary\" : false,\"mapping\" : [{\"identity\" : \"rim\",\"map\" : \"N/A\"}]}]},\"differential\" : {\"element\" : [{\"id\" : \"Extension\",\"path\" : \"Extension\",\"short\" : \"The specified type/profile/target must be supported by implementations\",\"definition\" : \"If true indicates that the specified type, profile or targetProfile must be supported by implementations.\",\"comment\" : \"todo.\",\"min\" : 0,\"max\" : \"1\"},{\"id\" : \"Extension.extension\",\"path\" : \"Extension.extension\",\"max\" : \"0\"},{\"id\" : \"Extension.url\",\"path\" : \"Extension.url\",\"fixedUri\" : \"http://hl7.org/fhir/StructureDefinition/instance-name\"},{\"id\" : \"Extension.value[x]\",\"path\" : \"Extension.value[x]\",\"min\" : 1,\"type\" : [{\"code\" : \"string\"}]}]}}"; + private static final String INSTANCE_DESC_SOURCE = "{\"resourceType\" : \"StructureDefinition\",\"id\" : \"instance-description\",\"extension\" : [{\"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-wg\",\"valueCode\" : \"fhir\"},{\"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm\",\"valueInteger\" : 1}],\"url\" : \"http://hl7.org/fhir/StructureDefinition/instance-description\",\"version\" : \"4.5.0\",\"name\" : \"instance-description\",\"status\" : \"draft\",\"date\" : \"2015-02-28\",\"publisher\" : \"Health Level Seven, Inc. - FHIR Core WG\",\"contact\" : [{\"telecom\" : [{\"system\" : \"url\",\"value\" : \"http://hl7.org/special/committees/FHIR\"}]}],\"description\" : \"If true indicates that the specified type, profile or targetProfile must be supported by implementations.\",\"fhirVersion\" : \"4.5.0\",\"mapping\" : [{\"identity\" : \"rim\",\"uri\" : \"http://hl7.org/v3\",\"name\" : \"RIM Mapping\"}],\"kind\" : \"complex-type\",\"abstract\" : false,\"context\" : [{\"type\" : \"element\",\"expression\" : \"Resource.meta\"}],\"type\" : \"Extension\",\"baseDefinition\" : \"http://hl7.org/fhir/StructureDefinition/Extension\",\"derivation\" : \"constraint\",\"snapshot\" : {\"element\" : [{\"id\" : \"Extension\",\"path\" : \"Extension\",\"short\" : \"The specified type/profile/target must be supported by implementations\",\"definition\" : \"If true indicates that the specified type, profile or targetProfile must be supported by implementations.\",\"comment\" : \"todo.\",\"min\" : 0,\"max\" : \"1\",\"base\" : {\"path\" : \"Extension\",\"min\" : 0,\"max\" : \"*\"},\"constraint\" : [{\"key\" : \"ele-1\",\"severity\" : \"error\",\"human\" : \"All FHIR elements must have a @value or children\",\"expression\" : \"hasValue() or (children().count() > id.count())\",\"xpath\" : \"@value|f:*|h:div\",\"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\"},{\"key\" : \"ext-1\",\"severity\" : \"error\",\"human\" : \"Must have either extensions or value[x], not both\",\"expression\" : \"extension.exists() != value.exists()\",\"xpath\" : \"exists(f:extension)!=exists(f:*[starts-with(local-name(.), 'value')])\",\"source\" : \"http://hl7.org/fhir/StructureDefinition/Extension\"}],\"isModifier\" : false},{\"id\" : \"Extension.id\",\"path\" : \"Extension.id\",\"representation\" : [\"xmlAttr\"],\"short\" : \"Unique id for inter-element referencing\",\"definition\" : \"Unique id for the element within a resource (for internal references). This may be any string value that does not contain spaces.\",\"min\" : 0,\"max\" : \"1\",\"base\" : {\"path\" : \"Element.id\",\"min\" : 0,\"max\" : \"1\"},\"type\" : [{\"extension\" : [{\"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type\",\"valueUri\" : \"markdown\"}],\"code\" : \"http://hl7.org/fhirpath/System.String\"}],\"isModifier\" : false,\"isSummary\" : false,\"mapping\" : [{\"identity\" : \"rim\",\"map\" : \"n/a\"}]},{\"id\" : \"Extension.extension\",\"path\" : \"Extension.extension\",\"slicing\" : {\"discriminator\" : [{\"type\" : \"value\",\"path\" : \"url\"}],\"description\" : \"Extensions are always sliced by (at least) url\",\"rules\" : \"open\"},\"short\" : \"Extension\",\"definition\" : \"An Extension\",\"min\" : 0,\"max\" : \"0\",\"base\" : {\"path\" : \"Element.extension\",\"min\" : 0,\"max\" : \"*\"},\"type\" : [{\"code\" : \"Extension\"}],\"constraint\" : [{\"key\" : \"ele-1\",\"severity\" : \"error\",\"human\" : \"All FHIR elements must have a @value or children\",\"expression\" : \"hasValue() or (children().count() > id.count())\",\"xpath\" : \"@value|f:*|h:div\",\"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\"},{\"key\" : \"ext-1\",\"severity\" : \"error\",\"human\" : \"Must have either extensions or value[x], not both\",\"expression\" : \"extension.exists() != value.exists()\",\"xpath\" : \"exists(f:extension)!=exists(f:*[starts-with(local-name(.), \\\"value\\\")])\",\"source\" : \"http://hl7.org/fhir/StructureDefinition/Extension\"}],\"isModifier\" : false,\"isSummary\" : false},{\"id\" : \"Extension.url\",\"path\" : \"Extension.url\",\"representation\" : [\"xmlAttr\"],\"short\" : \"identifies the meaning of the extension\",\"definition\" : \"Source of the definition for the extension code - a logical name or a URL.\",\"comment\" : \"The definition may point directly to a computable or human-readable definition of the extensibility codes, or it may be a logical URI as declared in some other specification. The definition SHALL be a URI for the Structure Definition defining the extension.\",\"min\" : 1,\"max\" : \"1\",\"base\" : {\"path\" : \"Extension.url\",\"min\" : 1,\"max\" : \"1\"},\"type\" : [{\"extension\" : [{\"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type\",\"valueUri\" : \"uri\"}],\"code\" : \"http://hl7.org/fhirpath/System.String\"}],\"fixedUri\" : \"http://hl7.org/fhir/StructureDefinition/instance-description\",\"isModifier\" : false,\"isSummary\" : false,\"mapping\" : [{\"identity\" : \"rim\",\"map\" : \"N/A\"}]},{\"id\" : \"Extension.value[x]\",\"path\" : \"Extension.value[x]\",\"short\" : \"Value of extension\",\"definition\" : \"Value of extension - must be one of a constrained set of the data types (see [Extensibility](extensibility.html) for a list).\",\"min\" : 1,\"max\" : \"1\",\"base\" : {\"path\" : \"Extension.value[x]\",\"min\" : 0,\"max\" : \"1\"},\"type\" : [{\"code\" : \"markdown\"}],\"constraint\" : [{\"key\" : \"ele-1\",\"severity\" : \"error\",\"human\" : \"All FHIR elements must have a @value or children\",\"expression\" : \"hasValue() or (children().count() > id.count())\",\"xpath\" : \"@value|f:*|h:div\",\"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\"}],\"isModifier\" : false,\"isSummary\" : false,\"mapping\" : [{\"identity\" : \"rim\",\"map\" : \"N/A\"}]}]},\"differential\" : {\"element\" : [{\"id\" : \"Extension\",\"path\" : \"Extension\",\"short\" : \"The specified type/profile/target must be supported by implementations\",\"definition\" : \"If true indicates that the specified type, profile or targetProfile must be supported by implementations.\",\"comment\" : \"todo.\",\"min\" : 0,\"max\" : \"1\"},{\"id\" : \"Extension.extension\",\"path\" : \"Extension.extension\",\"max\" : \"0\"},{\"id\" : \"Extension.url\",\"path\" : \"Extension.url\",\"fixedUri\" : \"http://hl7.org/fhir/StructureDefinition/instance-description\"},{\"id\" : \"Extension.value[x]\",\"path\" : \"Extension.value[x]\",\"min\" : 1,\"type\" : [{\"code\" : \"markdown\"}]}]}}"; public static boolean isKnownExtension(String url) { return Utilities.existsInList(url, - "http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support" + "http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support", + "http://hl7.org/fhir/StructureDefinition/instance-name", + "http://hl7.org/fhir/StructureDefinition/instance-description" ); } public static StructureDefinition getDefinition(String url) { try { switch (url) { - case "http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support" : return makeMustSupport(); + case "http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support" : return makeExt(MUST_SUPPORT_SOURCE); + case "http://hl7.org/fhir/StructureDefinition/instance-name" : return makeExt(INSTANCE_NAME_SOURCE); + case "http://hl7.org/fhir/StructureDefinition/instance-description" : return makeExt(INSTANCE_DESC_SOURCE); default: return null; } } catch (Exception e) { @@ -29,8 +35,8 @@ public class SpecialExtensions { } } - private static StructureDefinition makeMustSupport() throws FHIRFormatError, IOException { - return (StructureDefinition) new JsonParser().parse(MUST_SUPPORT_SOURCE); + private static StructureDefinition makeExt(String src) throws FHIRFormatError, IOException { + return (StructureDefinition) new JsonParser().parse(src); } } diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTests.java index 1c36fe32c..843dde1c7 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTests.java @@ -52,6 +52,7 @@ import org.hl7.fhir.r5.utils.IResourceValidator.ReferenceValidationPolicy; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; +import org.hl7.fhir.utilities.json.JSONUtil; import org.hl7.fhir.utilities.npm.NpmPackage; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; @@ -81,8 +82,9 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe Map examples = new HashMap(); manifest = (JsonObject) new com.google.gson.JsonParser().parse(contents); - for (Entry e : manifest.getAsJsonObject("test-cases").entrySet()) { - examples.put(e.getKey(), e.getValue().getAsJsonObject()); + for (JsonElement e : manifest.getAsJsonArray("test-cases")) { + JsonObject o = (JsonObject) e; + examples.put(JSONUtil.str(o, "name"), o); } List names = new ArrayList(examples.size()); @@ -154,7 +156,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe if (content.has("use-test") && !content.get("use-test").getAsBoolean()) return; - String testCaseContent = TestingUtilities.loadTestResource("validator", name); + String testCaseContent = TestingUtilities.loadTestResource("validator", JSONUtil.str(content, "file")); InstanceValidator val = vCurr.getValidator(); val.setWantCheckSnapshotUnchanged(true); val.getContext().setClientRetryCount(4); @@ -226,7 +228,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe if (content.has("logical")==false) { val.setAssumeValidRestReferences(content.has("assumeValidRestReferences") ? content.get("assumeValidRestReferences").getAsBoolean() : false); System.out.println(String.format("Start Validating (%d to set up)", (System.nanoTime() - setup) / 1000000)); - if (name.endsWith(".json")) + if (JSONUtil.str(content, "file").endsWith(".json")) val.validate(null, errors, IOUtils.toInputStream(testCaseContent, Charsets.UTF_8), FhirFormat.JSON); else val.validate(null, errors, IOUtils.toInputStream(testCaseContent, Charsets.UTF_8), FhirFormat.XML); @@ -258,7 +260,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe val.getContext().cacheResource(sd); val.setAssumeValidRestReferences(profile.has("assumeValidRestReferences") ? profile.get("assumeValidRestReferences").getAsBoolean() : false); List errorsProfile = new ArrayList(); - if (name.endsWith(".json")) + if (JSONUtil.str(content, "file").endsWith(".json")) val.validate(null, errorsProfile, IOUtils.toInputStream(testCaseContent, Charsets.UTF_8), FhirFormat.JSON, asSdList(sd)); else val.validate(null, errorsProfile, IOUtils.toInputStream(testCaseContent, Charsets.UTF_8), FhirFormat.XML, asSdList(sd)); diff --git a/pom.xml b/pom.xml index 81c307c44..609706240 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 5.1.0 - 1.1.50 + 1.1.51-SNAPSHOT 5.6.2 3.0.0-M4 0.8.5