From e9a369f4e28d00b043684c678628220b35a91ccb Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sat, 24 Oct 2020 06:06:51 +1100 Subject: [PATCH 01/32] fix issue validating # references --- .../instance/InstanceValidator.java | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java index 770dc1f26..825557af8 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java @@ -3054,9 +3054,22 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat // work back through the parent list. // really, there should only be one level for this (contained resources cannot contain // contained resources), but we'll leave that to some other code to worry about + boolean wasContained = false; while (stack != null && stack.getElement() != null) { if (stack.getElement().getProperty().isResource()) { // ok, we'll try to find the contained reference + if (ref.equals("#") && stack.getElement().getSpecial() != SpecialElement.CONTAINED && wasContained) { + ResolvedReference rr = new ResolvedReference(); + rr.setResource(stack.getElement()); + rr.setFocus(stack.getElement()); + rr.setExternal(false); + rr.setStack(stack.push(stack.getElement(), -1, stack.getElement().getProperty().getDefinition(), stack.getElement().getProperty().getDefinition())); + rr.getStack().qualifyPath(".ofType("+stack.getElement().fhirType()+")"); + return rr; + } + if (stack.getElement().getSpecial() == SpecialElement.CONTAINED) { + wasContained = true; + } IndexedElement res = getContainedById(stack.getElement(), ref.substring(1)); if (res != null) { ResolvedReference rr = new ResolvedReference(); @@ -4186,7 +4199,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } else if (checkDefn.getType().size() > 1) { String prefix = tail(checkDefn.getPath()); - assert typesAreAllReference(checkDefn.getType()) || checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR) || prefix.endsWith("[x]") : prefix; + assert typesAreAllReference(checkDefn.getType()) || checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR) || prefix.endsWith("[x]") || isResourceAndTypes(checkDefn) : "Multiple Types allowed, but name is wrong @ "+checkDefn.getPath()+": "+checkDefn.typeSummaryVB(); if (checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR)) type = ei.getElement().getType(); @@ -4386,6 +4399,18 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } + private boolean isResourceAndTypes(ElementDefinition ed) { + if (!Utilities.existsInList(ed.getBase().getPath(), "Bundle.entry.resource", "Bundle.entry.response.outcome", "DomainResource.contained", "Parameters.parameter.resource", "Parameters.parameter.part.resource")) { + return false; + } + for (TypeRefComponent tr : ed.getType()) { + if (!isResource(tr.getCode())) { + return false; + } + } + return true; + } + private boolean isResource(String type) { StructureDefinition sd = context.fetchTypeDefinition(type); return sd != null && sd.getKind().equals(StructureDefinitionKind.RESOURCE); @@ -4983,6 +5008,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if ("(component.empty() and related.empty()) implies (dataAbsentReason or value)".equals(expr)) return "(component.empty() and related.empty()) implies (dataAbsentReason.exists() or value.exists())"; + if ("reference.startsWith('#').not() or (reference.substring(1).trace('url') in %rootResource.contained.id.trace('ids'))".equals(expr)) { + return "(reference = '#') or reference.startsWith('#').not() or (reference.substring(1).trace('url') in %rootResource.contained.id.trace('ids'))"; + } + if ("reference.startsWith('#').not() or (reference.substring(1).trace('url') in %resource.contained.id.trace('ids'))".equals(expr)) { + return "(reference = '#') or reference.startsWith('#').not() or (reference.substring(1).trace('url') in %resource.contained.id.trace('ids'))"; + } if ("".equals(expr)) return ""; return expr; From a658fc982bdce18ae67631a64002171ff5e1e55b Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 29 Oct 2020 13:53:14 +1100 Subject: [PATCH 02/32] Mark it has an error if a JSON Array is empty --- .../src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java | 3 +++ pom.xml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java index 82701ee7f..0d29e0cf0 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java @@ -208,6 +208,9 @@ public class JsonParser extends ParserBase { JsonElement e = object.get(name); if (property.isList() && (e instanceof JsonArray)) { JsonArray arr = (JsonArray) e; + if (arr.size() == 0) { + logError(line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ARRAY_CANNOT_BE_EMPTY), IssueSeverity.ERROR); + } int c = 0; for (JsonElement am : arr) { parseChildComplexInstance(npath+"["+c+"]", object, element, property, name, am); diff --git a/pom.xml b/pom.xml index 2956882bd..4433e7e77 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 5.1.0 - 1.1.46 + 1.1.47-SNAPSHOT 5.6.2 3.0.0-M4 0.8.5 From 09b1cc5beaf18c3dbb942c943f039ec59d564511 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 29 Oct 2020 13:54:14 +1100 Subject: [PATCH 03/32] Don't make wrong error reports for profiling resources in bundles --- .../type/StructureDefinitionValidator.java | 16 +++++++++++++++- .../validation/instance/utils/NodeStack.java | 8 ++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java index 86b805852..0f8de3f63 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java @@ -165,11 +165,25 @@ public class StructureDefinitionValidator extends BaseValidator { if (t == null) { rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), code.equals(t), I18nConstants.SD_ED_TYPE_PROFILE_NOTYPE, p); } else { - rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), code.equals(t), I18nConstants.SD_ED_TYPE_PROFILE_WRONG, p, t, code); + rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), isInstanceOf(t, code), I18nConstants.SD_ED_TYPE_PROFILE_WRONG, p, t, code); } } } + private boolean isInstanceOf(String t, String code) { + StructureDefinition sd = context.fetchTypeDefinition(t); + while (sd != null) { + if (sd.getType().equals(code)) { + return true; + } + sd = sd.hasBaseDefinition() ? context.fetchResource(StructureDefinition.class, sd.getBaseDefinition()) : null; + if (sd != null && !sd.getAbstract()) { + sd = null; + } + } + return false; + } + private String determineBaseType(StructureDefinition sd) { while (sd != null && !sd.hasType() && sd.getDerivation() == TypeDerivationRule.CONSTRAINT) { sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition()); diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/NodeStack.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/NodeStack.java index cf32d7f03..abb85ac64 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/NodeStack.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/NodeStack.java @@ -187,5 +187,13 @@ public class NodeStack { return literalPath; } + public int depth() { + if (parent == null) { + return 0; + } else { + return parent.depth()+1; + } + } + } \ No newline at end of file From 4c421eefd758d248f3d5ef9bba8801b6b3fd9b53 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 29 Oct 2020 13:56:56 +1100 Subject: [PATCH 04/32] * Render binding description in profile tables if it doesn't contain paragraphs * fix bug with wrong value for contentReference in derived profiles (profiles do not and cannot change the value) --- .../fhir/r5/conformance/ProfileUtilities.java | 55 ++++++++++++++----- .../hl7/fhir/utilities/MarkDownProcessor.java | 5 ++ 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java index fbb99dd77..7155da406 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java @@ -111,6 +111,7 @@ import org.hl7.fhir.r5.utils.XVerExtensionManager.XVerExtensionStatus; import org.hl7.fhir.r5.utils.formats.CSVWriter; import org.hl7.fhir.r5.utils.formats.XLSXWriter; import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; +import org.hl7.fhir.utilities.MarkDownProcessor; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.i18n.I18nConstants; @@ -362,9 +363,28 @@ public class ProfileUtilities extends TranslatingUtilities { public List getChildMap(StructureDefinition profile, ElementDefinition element) throws DefinitionException { - if (element.getContentReference()!=null) { - for (ElementDefinition e : profile.getSnapshot().getElement()) { - if (element.getContentReference().equals("#"+e.getId())) + if (element.getContentReference() != null) { + List list = null; + String id = null; + if (element.getContentReference().startsWith("#")) { + // internal reference + id = element.getContentReference().substring(1); + list = profile.getSnapshot().getElement(); + } else if (element.getContentReference().contains("#")) { + // external reference + String ref = element.getContentReference(); + StructureDefinition sd = context.fetchResource(StructureDefinition.class, ref.substring(0, ref.indexOf("#"))); + if (sd == null) { + throw new DefinitionException("unable to process contentReference '"+element.getContentReference()+"' on element '"+element.getId()+"'"); + } + list = sd.getSnapshot().getElement(); + id = ref.substring(ref.indexOf("#")+1); + } else { + throw new DefinitionException("unable to process contentReference '"+element.getContentReference()+"' on element '"+element.getId()+"'"); + } + + for (ElementDefinition e : list) { + if (id.equals(e.getId())) return getChildMap(profile, e); } throw new DefinitionException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_NAME_REFERENCE__AT_PATH_, element.getContentReference(), element.getPath())); @@ -3155,6 +3175,10 @@ public class ProfileUtilities extends TranslatingUtilities { c.getPieces().add(checkForNoChange(ved.getBinding(), gen.new Piece(corePath+"terminologies.html#"+ved.getBinding().getStrength().toCode(), egt(ved.getBinding().getStrengthElement()), ved.getBinding().getStrength().getDefinition()))); c.getPieces().add(gen.new Piece(null, ")", null)); } + if (ved.getBinding().hasDescription() && MarkDownProcessor.isSimpleMarkdown(ved.getBinding().getDescription())) { + c.getPieces().add(gen.new Piece(null, ": ", null)); + c.addMarkdownNoPara(ved.getBinding().getDescription()); + } } c.addPiece(gen.new Piece("br")).addPiece(gen.new Piece(null, describeExtensionContext(ed), null)); r.getCells().add(c); @@ -4282,6 +4306,10 @@ public class ProfileUtilities extends TranslatingUtilities { c.getPieces().add(checkForNoChange(binding, gen.new Piece(corePath+"extension-elementdefinition-minvalueset.html", translate("sd.table", "Min Binding")+": ", "Min Value Set Extension").addStyle("font-weight:bold"))); c.getPieces().add(checkForNoChange(binding, gen.new Piece(br.url == null ? null : Utilities.isAbsoluteUrl(br.url) || !pkp.prependLinks() ? br.url : corePath+br.url, br.display, null))); } + if (binding.hasDescription() && MarkDownProcessor.isSimpleMarkdown(binding.getDescription())) { + c.getPieces().add(gen.new Piece(null, ": ", null)); + c.addMarkdownNoPara(binding.getDescription()); + } } for (ElementDefinitionConstraintComponent inv : definition.getConstraint()) { if (!inv.hasSource() || profile == null || inv.getSource().equals(profile.getUrl()) || allInvariants) { @@ -4300,7 +4328,6 @@ public class ProfileUtilities extends TranslatingUtilities { // don't show this, this it's important: c.getPieces().add(gen.new Piece(null, "This repeating element has no defined order", null)); } } - if (definition.hasFixed()) { if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); } c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, translate("sd.table", "Fixed Value")+": ", null).addStyle("font-weight:bold"))); @@ -4594,6 +4621,10 @@ public class ProfileUtilities extends TranslatingUtilities { c.getPieces().add(checkForNoChange(binding, gen.new Piece(null, " (", null))); c.getPieces().add(checkForNoChange(binding, gen.new Piece(corePath+"terminologies.html#"+binding.getStrength().toCode(), binding.getStrength().toCode(), binding.getStrength().getDefinition()))); c.getPieces().add(gen.new Piece(null, ")", null)); } + if (binding.hasDescription() && MarkDownProcessor.isSimpleMarkdown(binding.getDescription())) { + c.getPieces().add(gen.new Piece(null, ": ", null)); + c.addMarkdownNoPara(binding.getDescription()); + } } for (ElementDefinitionConstraintComponent inv : definition.getConstraint()) { if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); } @@ -5338,12 +5369,12 @@ public class ProfileUtilities extends TranslatingUtilities { if (!checkFirst || !sd.hasDifferential() || hasMissingIds(sd.getDifferential().getElement())) { if (!sd.hasDifferential()) sd.setDifferential(new StructureDefinitionDifferentialComponent()); - generateIds(sd.getDifferential().getElement(), sd.getUrl()); + generateIds(sd.getDifferential().getElement(), sd.getUrl(), sd.getType()); } if (!checkFirst || !sd.hasSnapshot() || hasMissingIds(sd.getSnapshot().getElement())) { if (!sd.hasSnapshot()) sd.setSnapshot(new StructureDefinitionSnapshotComponent()); - generateIds(sd.getSnapshot().getElement(), sd.getUrl()); + generateIds(sd.getSnapshot().getElement(), sd.getUrl(), sd.getType()); } } @@ -5388,11 +5419,10 @@ public class ProfileUtilities extends TranslatingUtilities { } - private void generateIds(List list, String name) throws DefinitionException { + private void generateIds(List list, String name, String type) throws DefinitionException { if (list.isEmpty()) return; - Map idMap = new HashMap(); Map idList = new HashMap(); SliceList sliceInfo = new SliceList(); @@ -5420,7 +5450,6 @@ public class ProfileUtilities extends TranslatingUtilities { } } String bs = b.toString(); - idMap.put(ed.hasId() ? ed.getId() : ed.getPath(), bs); ed.setId(bs); if (idList.containsKey(bs)) { if (exception || messages == null) { @@ -5429,11 +5458,9 @@ public class ProfileUtilities extends TranslatingUtilities { messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, name+"."+bs, "Duplicate Element id "+bs, ValidationMessage.IssueSeverity.ERROR)); } idList.put(bs, ed.getPath()); - if (ed.hasContentReference()) { - String s = ed.getContentReference().substring(1); - if (idMap.containsKey(s)) - ed.setContentReference("#"+idMap.get(s)); - + if (ed.hasContentReference() && ed.getContentReference().startsWith("#")) { + String s = ed.getContentReference(); + ed.setContentReference("http://hl7.org/fhir/StructureDefinition/"+type+s); } } // second path - fix up any broken path based id references diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/MarkDownProcessor.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/MarkDownProcessor.java index d85ddc14a..eb6bb9a3e 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/MarkDownProcessor.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/MarkDownProcessor.java @@ -78,5 +78,10 @@ public class MarkDownProcessor { html = html.replace("", "
"); return html; } + + + public static boolean isSimpleMarkdown(String description) { + return !description.contains("\n"); + } } \ No newline at end of file From 944be1cfba87479fac519dd476b2427823dcb794 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 29 Oct 2020 13:57:25 +1100 Subject: [PATCH 05/32] fix bug with wrong value for contentReference in derived profiles (profiles do not and cannot change the value) (missed testing change) --- .../test/java/org/hl7/fhir/r5/test/ProfileUtilitiesTests.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/ProfileUtilitiesTests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/ProfileUtilitiesTests.java index 08b9264e2..0c53d558b 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/ProfileUtilitiesTests.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/ProfileUtilitiesTests.java @@ -104,6 +104,8 @@ public class ProfileUtilitiesTests { f.setComment(null); b.setDefinition(null); f.setDefinition(null); + b.setContentReference(null); + f.setContentReference(null); ok = Base.compareDeep(b, f, true); } } From 14cc22f9a293f33b9c02a5c3b565997c241d1a04 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 29 Oct 2020 13:59:45 +1100 Subject: [PATCH 06/32] * fix bug not recognising some content as xml or json --- .../hl7/fhir/validation/ValidationEngine.java | 78 ++++++++++++++++++- .../tests/ValidationEngineTests.java | 2 +- 2 files changed, 77 insertions(+), 3 deletions(-) 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 648f57520..ac11e57fa 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 @@ -29,6 +29,10 @@ import java.util.UUID; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + import org.apache.commons.io.IOUtils; import org.hl7.fhir.convertors.VersionConvertorAdvisor50; import org.hl7.fhir.convertors.VersionConvertor_10_30; @@ -56,6 +60,7 @@ import org.hl7.fhir.r5.context.SimpleWorkerContext; import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.elementmodel.Manager; import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat; +import org.hl7.fhir.r5.elementmodel.ParserBase.ValidationPolicy; import org.hl7.fhir.r5.elementmodel.ObjectConverter; import org.hl7.fhir.r5.formats.FormatUtilities; import org.hl7.fhir.r5.formats.IParser.OutputStyle; @@ -98,9 +103,11 @@ import org.hl7.fhir.utilities.TimeTracker; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.i18n.I18nConstants; +import org.hl7.fhir.utilities.json.JsonTrackingParser; import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; import org.hl7.fhir.utilities.npm.NpmPackage; import org.hl7.fhir.utilities.npm.ToolsVersion; +import org.hl7.fhir.utilities.turtle.Turtle; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; @@ -111,6 +118,7 @@ import org.hl7.fhir.validation.cli.model.ScanOutputItem; import org.hl7.fhir.validation.cli.services.StandAloneValidatorFetcher.IPackageInstaller; import org.hl7.fhir.validation.cli.utils.*; import org.hl7.fhir.validation.instance.InstanceValidator; +import org.w3c.dom.Document; import org.xml.sax.SAXException; @@ -538,7 +546,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst throw new FHIRException("Unable to fetch content from "+src+" ("+errors.toString()+")"); } - FhirFormat fmt = checkIsResource(cnt, src); + FhirFormat fmt = checkFormat(cnt, src); if (fmt != null) { Map res = new HashMap(); res.put(Utilities.changeFileExt(src, "."+fmt.getExtension()), cnt); @@ -809,33 +817,99 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst this.noInvariantChecks = value; } + private FhirFormat checkFormat(byte[] cnt, String filename) { + System.out.println(" ..Detect format for "+filename); + try { + JsonTrackingParser.parseJson(cnt); + return FhirFormat.JSON; + } catch (Exception e) { + if (debug) { + System.out.println("Not JSON: "+e.getMessage()); + } + } + try { + parseXml(cnt); + return FhirFormat.XML; + } catch (Exception e) { + if (debug) { + System.out.println("Not XML: "+e.getMessage()); + } + } + try { + new Turtle().parse(TextFile.bytesToString(cnt)); + return FhirFormat.TURTLE; + } catch (Exception e) { + if (debug) { + System.out.println("Not Turtle: "+e.getMessage()); + } + } + try { + new StructureMapUtilities(context, null, null).parse(TextFile.bytesToString(cnt), null); + return FhirFormat.TEXT; + } catch (Exception e) { + if (debug) { + System.out.println("Not Text: "+e.getMessage()); + } + } + if (debug) + System.out.println(" .. not a resource: "+filename); + return null; + } + + private FhirFormat checkIsResource(byte[] cnt, String filename) { System.out.println(" ..Detect format for "+filename); try { Manager.parse(context, new ByteArrayInputStream(cnt), FhirFormat.JSON); return FhirFormat.JSON; } catch (Exception e) { + if (debug) { + System.out.println("Not JSON: "+e.getMessage()); + } } try { - Manager.parse(context, new ByteArrayInputStream(cnt),FhirFormat.XML); + parseXml(cnt); return FhirFormat.XML; } catch (Exception e) { + if (debug) { + System.out.println("Not XML: "+e.getMessage()); + } } try { Manager.parse(context, new ByteArrayInputStream(cnt),FhirFormat.TURTLE); return FhirFormat.TURTLE; } catch (Exception e) { + if (debug) { + System.out.println("Not Turtle: "+e.getMessage()); + } } try { new StructureMapUtilities(context, null, null).parse(TextFile.bytesToString(cnt), null); return FhirFormat.TEXT; } catch (Exception e) { + if (debug) { + System.out.println("Not Text: "+e.getMessage()); + } } if (debug) System.out.println(" .. not a resource: "+filename); return null; } + private Document parseXml(byte[] cnt) throws ParserConfigurationException, SAXException, IOException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + // xxe protection + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + factory.setFeature("http://xml.org/sax/features/external-general-entities", false); + factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + factory.setXIncludeAware(false); + factory.setExpandEntityReferences(false); + factory.setNamespaceAware(true); + DocumentBuilder builder = factory.newDocumentBuilder(); + return builder.parse(new ByteArrayInputStream(cnt)); + } + private FhirFormat checkIsResource(String path) throws IOException { String ext = Utilities.getFileExtension(path); if (Utilities.existsInList(ext, "xml")) diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationEngineTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationEngineTests.java index 18be9008a..636c04747 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationEngineTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationEngineTests.java @@ -90,7 +90,7 @@ public class ValidationEngineTests { } if (!org.hl7.fhir.validation.tests.utilities.TestUtilities.silent) System.out.println("Test102: Validate patient-example.xml in v1.0.2 version"); - ValidationEngine ve = new ValidationEngine("hl7.fhir.r2.core#1.0.2", DEF_TX, null, FhirPublication.DSTU2, "41.0.2"); + ValidationEngine ve = new ValidationEngine("hl7.fhir.r2.core#1.0.2", DEF_TX, null, FhirPublication.DSTU2, "1.0.2"); ve.setNoInvariantChecks(true); OperationOutcome op = ve.validate(FhirFormat.XML, TestingUtilities.loadTestResourceStream("validator", "patient102.xml"), null); if (!TestUtilities.silent) From 49fbc739fd3ad619224798566f184619d2407a62 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 29 Oct 2020 14:00:21 +1100 Subject: [PATCH 07/32] improved markdown support in table generator --- .../xhtml/HierarchicalTableGenerator.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/HierarchicalTableGenerator.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/HierarchicalTableGenerator.java index 8edbee65b..94e337d33 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/HierarchicalTableGenerator.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/HierarchicalTableGenerator.java @@ -240,6 +240,7 @@ public class HierarchicalTableGenerator extends TranslatingUtilities { pieces.add(piece); return this; } + public Cell addMarkdown(String md) { try { Parser parser = Parser.builder().build(); @@ -253,6 +254,19 @@ public class HierarchicalTableGenerator extends TranslatingUtilities { return this; } + public Cell addMarkdownNoPara(String md) { + try { + Parser parser = Parser.builder().build(); + Node document = parser.parse(md); + HtmlRenderer renderer = HtmlRenderer.builder().escapeHtml(true).build(); + String html = renderer.render(document); + pieces.addAll(htmlToParagraphPieces(html)); + } catch (Exception e) { + e.printStackTrace(); + } + return this; + } + private List htmlToParagraphPieces(String html) { List myPieces = new ArrayList(); try { From bc1d67db960175146f73a4005b423ffff8eb86fa Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 29 Oct 2020 14:03:08 +1100 Subject: [PATCH 08/32] * fix bug checking unfixed values for HumanName patterns * fix bug checking patterns (missed in some circumstances) * fix bug checking type of resources in bundles * improve messages around cardinality errors in profiles --- RELEASE_NOTES.md | 11 +++ .../fhir/utilities/i18n/I18nConstants.java | 1 + .../src/main/resources/Messages.properties | 10 +- .../instance/InstanceValidator.java | 93 +++++++++++-------- 4 files changed, 73 insertions(+), 42 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e69de29bb..28ab95b23 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -0,0 +1,11 @@ +Validator Changes: +* Mark it has an error if a JSON Array is empty +* Don't make wrong error reports for profiling resources in bundles +* fix bug checking unfixed values for HumanName patterns +* fix bug checking patterns (missed in some circumstances) +* fix bug checking type of resources in bundles +* improve messages around cardinality errors in profiles + +Other code changes: +* Render binding description in profile tables if it doesn't contain paragraphs +* fix bug with wrong value for contentReference in derived profiles (profiles do not and cannot change the value) diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java index 23c15cc22..36a9960a6 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java @@ -12,6 +12,7 @@ public class I18nConstants { public static final String ALL_OBSERVATIONS_SHOULD_HAVE_A_PERFORMER = "All_observations_should_have_a_performer"; public static final String ALL_OBSERVATIONS_SHOULD_HAVE_A_SUBJECT = "All_observations_should_have_a_subject"; public static final String ALL_OK = "ALL_OK"; + public static final String ARRAY_CANNOT_BE_EMPTY = "ARRAY_CANNOT_BE_EMPTY"; public static final String ATTEMPT_TO_A_SLICE_AN_ELEMENT_THAT_DOES_NOT_REPEAT__FROM__IN_ = "Attempt_to_a_slice_an_element_that_does_not_repeat__from__in_"; public static final String ATTEMPT_TO_REPLACE_ELEMENT_NAME_FOR_A_NONCHOICE_TYPE = "Attempt_to_replace_element_name_for_a_nonchoice_type"; public static final String ATTEMPT_TO_USE_A_SNAPSHOT_ON_PROFILE__AS__BEFORE_IT_IS_GENERATED = "Attempt_to_use_a_snapshot_on_profile__as__before_it_is_generated"; diff --git a/org.hl7.fhir.utilities/src/main/resources/Messages.properties b/org.hl7.fhir.utilities/src/main/resources/Messages.properties index 38e7af318..038b16b7c 100644 --- a/org.hl7.fhir.utilities/src/main/resources/Messages.properties +++ b/org.hl7.fhir.utilities/src/main/resources/Messages.properties @@ -209,11 +209,12 @@ 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} Validation_VAL_Profile_MatchMultiple = Profile {0}, Element matches more than one slice - {1}, {2} -Validation_VAL_Profile_Maximum = {0}: max allowed = {1}, but found {2} -Validation_VAL_Profile_Minimum = {0}: minimum required = {1}, but only found {2} +// for the next 4 messages, the available parameters are: 0: profile url, 1: ed.path, 2: ed.id, 3: ed.sliceName, 4: ed.label, 5: element.path, 6: ed.min and optionally 7: actual count +Validation_VAL_Profile_Maximum = {2}: max allowed = {6}, but found {7} (from {0}) +Validation_VAL_Profile_Minimum = {2}: minimum required = {6}, but only found {7} (from {0}) +Validation_VAL_Profile_NoCheckMax = {2}: Unable to check max allowed ({1}) due to lack of slicing validation (from {0}) +Validation_VAL_Profile_NoCheckMin = {2}: Unable to check minimum required ({1}) due to lack of slicing validation (from {0}) Validation_VAL_Profile_MultipleMatches = Found multiple matching profiles among choices: {0} -Validation_VAL_Profile_NoCheckMax = {0}: Unable to check max allowed ({1}) due to lack of slicing validation -Validation_VAL_Profile_NoCheckMin = {0}'': Unable to check minimum required ({1}) due to lack of slicing validation Validation_VAL_Profile_NoDefinition = No definition found for resource type ''{0}'' Validation_VAL_Profile_NoMatch = Unable to find matching profile among choices: {0} Validation_VAL_Profile_NoSnapshot = StructureDefinition has no snapshot - validation is against the snapshot, so it must be provided @@ -617,4 +618,5 @@ SD_ED_TYPE_PROFILE_NOTYPE = Found profile {0}, but unable to determine the type SD_ED_TYPE_PROFILE_WRONG = Profile {0} is for type {1}, but this element has type {2} TERMINOLOGY_TX_NOSVC_BOUND_REQ = Could not confirm that the codes provided are from the required value set {0} because there is no terminology service TERMINOLOGY_TX_NOSVC_BOUND_EXT = Could not confirm that the codes provided are from the extensible value set {0} because there is no terminology service +ARRAY_CANNOT_BE_EMPTY = Array cannot be empty - the property should not be present if it has no values \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java index 0df8742e7..1727acab8 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java @@ -961,7 +961,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } else { if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, codings.size() == fixed.getCoding().size(), I18nConstants.TERMINOLOGY_TX_CODING_COUNT, Integer.toString(fixed.getCoding().size()), Integer.toString(codings.size()))) { for (int i = 0; i < codings.size(); i++) - checkFixedValue(errors, path + ".coding", codings.get(i), fixed.getCoding().get(i), fixedSource, "coding", focus); + checkFixedValue(errors, path + ".coding", codings.get(i), fixed.getCoding().get(i), fixedSource, "coding", focus, false); } } } @@ -1748,10 +1748,6 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat return b.toString(); } - private void checkFixedValue(List errors, String path, Element focus, org.hl7.fhir.r5.model.Element fixed, String fixedSource, String propName, Element parent) { - checkFixedValue(errors, path, focus, fixed, fixedSource, propName, parent, false); - } - @SuppressWarnings("rawtypes") private void checkFixedValue(List errors, String path, Element focus, org.hl7.fhir.r5.model.Element fixed, String fixedSource, String propName, Element parent, boolean pattern) { if ((fixed == null || fixed.isEmpty()) && focus == null) { @@ -1829,7 +1825,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat for (Extension e : fixed.getExtension()) { Element ex = getExtensionByUrl(extensions, e.getUrl()); if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, ex != null, I18nConstants.EXTENSION_EXT_COUNT_NOTFOUND, e.getUrl())) { - checkFixedValue(errors, path, ex.getNamedChild("extension").getNamedChild("value"), e.getValue(), fixedSource, "extension.value", ex.getNamedChild("extension")); + checkFixedValue(errors, path, ex.getNamedChild("extension").getNamedChild("value"), e.getValue(), fixedSource, "extension.value", ex.getNamedChild("extension"), false); } } } @@ -1842,25 +1838,33 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat checkFixedValue(errors, path + ".period", focus.getNamedChild("period"), fixed.getPeriod(), fixedSource, "period", focus, pattern); List parts = new ArrayList(); - focus.getNamedChildren("family", parts); - if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, parts.size() > 0 == fixed.hasFamily(), I18nConstants.FIXED_TYPE_CHECKS_DT_NAME_FAMILY, (fixed.hasFamily() ? "1" : "0"), Integer.toString(parts.size()))) { - for (int i = 0; i < parts.size(); i++) - checkFixedValue(errors, path + ".family", parts.get(i), fixed.getFamilyElement(), fixedSource, "family", focus, pattern); + if (!pattern || fixed.hasFamily()) { + focus.getNamedChildren("family", parts); + if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, parts.size() > 0 == fixed.hasFamily(), I18nConstants.FIXED_TYPE_CHECKS_DT_NAME_FAMILY, (fixed.hasFamily() ? "1" : "0"), Integer.toString(parts.size()))) { + for (int i = 0; i < parts.size(); i++) + checkFixedValue(errors, path + ".family", parts.get(i), fixed.getFamilyElement(), fixedSource, "family", focus, pattern); + } } - focus.getNamedChildren("given", parts); - if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, parts.size() == fixed.getGiven().size(), I18nConstants.FIXED_TYPE_CHECKS_DT_NAME_GIVEN, Integer.toString(fixed.getGiven().size()), Integer.toString(parts.size()))) { - for (int i = 0; i < parts.size(); i++) - checkFixedValue(errors, path + ".given", parts.get(i), fixed.getGiven().get(i), fixedSource, "given", focus, pattern); + if (!pattern || fixed.hasGiven()) { + focus.getNamedChildren("given", parts); + if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, parts.size() == fixed.getGiven().size(), I18nConstants.FIXED_TYPE_CHECKS_DT_NAME_GIVEN, Integer.toString(fixed.getGiven().size()), Integer.toString(parts.size()))) { + for (int i = 0; i < parts.size(); i++) + checkFixedValue(errors, path + ".given", parts.get(i), fixed.getGiven().get(i), fixedSource, "given", focus, pattern); + } } - focus.getNamedChildren("prefix", parts); - if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, parts.size() == fixed.getPrefix().size(), I18nConstants.FIXED_TYPE_CHECKS_DT_NAME_PREFIX, Integer.toString(fixed.getPrefix().size()), Integer.toString(parts.size()))) { - for (int i = 0; i < parts.size(); i++) - checkFixedValue(errors, path + ".prefix", parts.get(i), fixed.getPrefix().get(i), fixedSource, "prefix", focus, pattern); + if (!pattern || fixed.hasPrefix()) { + focus.getNamedChildren("prefix", parts); + if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, parts.size() == fixed.getPrefix().size(), I18nConstants.FIXED_TYPE_CHECKS_DT_NAME_PREFIX, Integer.toString(fixed.getPrefix().size()), Integer.toString(parts.size()))) { + for (int i = 0; i < parts.size(); i++) + checkFixedValue(errors, path + ".prefix", parts.get(i), fixed.getPrefix().get(i), fixedSource, "prefix", focus, pattern); + } } - focus.getNamedChildren("suffix", parts); - if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, parts.size() == fixed.getSuffix().size(), I18nConstants.FIXED_TYPE_CHECKS_DT_NAME_SUFFIX, Integer.toString(fixed.getSuffix().size()), Integer.toString(parts.size()))) { - for (int i = 0; i < parts.size(); i++) - checkFixedValue(errors, path + ".suffix", parts.get(i), fixed.getSuffix().get(i), fixedSource, "suffix", focus, pattern); + if (!pattern || fixed.hasSuffix()) { + focus.getNamedChildren("suffix", parts); + if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, parts.size() == fixed.getSuffix().size(), I18nConstants.FIXED_TYPE_CHECKS_DT_NAME_SUFFIX, Integer.toString(fixed.getSuffix().size()), Integer.toString(parts.size()))) { + for (int i = 0; i < parts.size(); i++) + checkFixedValue(errors, path + ".suffix", parts.get(i), fixed.getSuffix().get(i), fixedSource, "suffix", focus, pattern); + } } } @@ -4082,8 +4086,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat // check type invariants checkInvariants(hostContext, errors, profile, definition, resource, element, stack, false); - if (definition.getFixed() != null) - checkFixedValue(errors, stack.getLiteralPath(), element, definition.getFixed(), profile.getUrl(), definition.getSliceName(), null); + if (definition.getFixed() != null) { + checkFixedValue(errors, stack.getLiteralPath(), element, definition.getFixed(), profile.getUrl(), definition.getSliceName(), null, false); + } + if (definition.getPattern() != null) { + checkFixedValue(errors, stack.getLiteralPath(), element, definition.getPattern(), profile.getUrl(), definition.getSliceName(), null, true); + } // get the list of direct defined children, including slices List childDefinitions = profileUtilities.getChildMap(profile, definition); @@ -4149,13 +4157,20 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat Element resource, Element element, String actualType, NodeStack stack, boolean inCodeableConcept, boolean checkDisplayInContext, ElementInfo ei, String extensionUrl) throws FHIRException, DefinitionException { + if (debug && ei.definition != null && ei.slice != null) { + System.out.println(Utilities.padLeft("", ' ', stack.depth())+ "Check "+ei.getPath()+" against both "+ei.definition.getId()+" and "+ei.slice.getId()); + } if (ei.definition != null) { - checkChildByDefinition(hostContext, errors, profile, definition, resource, element, actualType, stack, inCodeableConcept, checkDisplayInContext, ei, - extensionUrl, ei.definition, false); + if (debug) { + System.out.println(Utilities.padLeft("", ' ', stack.depth())+ "Check "+ei.getPath()+" against defn "+ei.definition.getId()); + } + checkChildByDefinition(hostContext, errors, profile, definition, resource, element, actualType, stack, inCodeableConcept, checkDisplayInContext, ei, extensionUrl, ei.definition, false); } if (ei.slice != null) { - checkChildByDefinition(hostContext, errors, profile, definition, resource, element, actualType, stack, inCodeableConcept, checkDisplayInContext, ei, - extensionUrl, ei.slice, true); + if (debug) { + System.out.println(Utilities.padLeft("", ' ', stack.depth())+ "Check "+ei.getPath()+" against slice "+ei.slice.getId()); + } + checkChildByDefinition(hostContext, errors, profile, definition, resource, element, actualType, stack, inCodeableConcept, checkDisplayInContext, ei, extensionUrl, ei.slice, true); } } @@ -4201,9 +4216,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat String prefix = tail(checkDefn.getPath()); assert typesAreAllReference(checkDefn.getType()) || checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR) || prefix.endsWith("[x]") || isResourceAndTypes(checkDefn) : "Multiple Types allowed, but name is wrong @ "+checkDefn.getPath()+": "+checkDefn.typeSummaryVB(); - if (checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR)) + if (checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR)) { type = ei.getElement().getType(); - else { + } else if (ei.getElement().isResource()) { + type = ei.getElement().fhirType(); + } else { prefix = prefix.substring(0, prefix.length() - 3); for (TypeRefComponent t : checkDefn.getType()) if ((prefix + Utilities.capitalize(t.getWorkingCode())).equals(ei.getName())) { @@ -4264,7 +4281,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat checkPrimitive(hostContext, errors, ei.getPath(), type, checkDefn, ei.getElement(), profile, stack); } else { if (checkDefn.hasFixed()) { - checkFixedValue(errors, ei.getPath(), ei.getElement(), checkDefn.getFixed(), profile.getUrl(), checkDefn.getSliceName(), null); + checkFixedValue(errors, ei.getPath(), ei.getElement(), checkDefn.getFixed(), profile.getUrl(), checkDefn.getSliceName(), null, false); } if (checkDefn.hasPattern()) { checkFixedValue(errors, ei.getPath(), ei.getElement(), checkDefn.getPattern(), profile.getUrl(), checkDefn.getSliceName(), null, true); @@ -4501,18 +4518,18 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } } - String location = "Profile " + profile.getUrl() + ", Element '" + stack.getLiteralPath() + "." + tail(ed.getPath()) + (ed.hasSliceName() ? "[" + ed.getSliceName() + (ed.hasLabel() ? " (" + ed.getLabel() + ")" : "") + "]" : "") + "'"; if (ed.getMin() > 0) { if (problematicPaths.contains(ed.getPath())) - hint(errors, IssueType.NOTSUPPORTED, element.line(), element.col(), stack.getLiteralPath(), count >= ed.getMin(), I18nConstants.VALIDATION_VAL_PROFILE_NOCHECKMIN, location, Integer.toString(ed.getMin())); + hint(errors, IssueType.NOTSUPPORTED, element.line(), element.col(), stack.getLiteralPath(), count >= ed.getMin(), I18nConstants.VALIDATION_VAL_PROFILE_NOCHECKMIN, profile.getUrl(), ed.getPath(), ed.getId(), ed.getSliceName(),ed.getLabel(), stack.getLiteralPath(), Integer.toString(ed.getMin())); else - rule(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), count >= ed.getMin(), I18nConstants.VALIDATION_VAL_PROFILE_MINIMUM, location, Integer.toString(ed.getMin()), Integer.toString(count)); + rule(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), count >= ed.getMin(), I18nConstants.VALIDATION_VAL_PROFILE_MINIMUM, profile.getUrl(), ed.getPath(), ed.getId(), ed.getSliceName(),ed.getLabel(), stack.getLiteralPath(), Integer.toString(ed.getMin()), Integer.toString(count)); } if (ed.hasMax() && !ed.getMax().equals("*")) { if (problematicPaths.contains(ed.getPath())) - hint(errors, IssueType.NOTSUPPORTED, element.line(), element.col(), stack.getLiteralPath(), count <= Integer.parseInt(ed.getMax()), I18nConstants.VALIDATION_VAL_PROFILE_NOCHECKMAX, location, ed.getMax()); - else - rule(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), count <= Integer.parseInt(ed.getMax()), I18nConstants.VALIDATION_VAL_PROFILE_MAXIMUM, location, ed.getMax(), Integer.toString(count)); + hint(errors, IssueType.NOTSUPPORTED, element.line(), element.col(), stack.getLiteralPath(), count <= Integer.parseInt(ed.getMax()), I18nConstants.VALIDATION_VAL_PROFILE_NOCHECKMAX, profile.getUrl(), ed.getPath(), ed.getId(), ed.getSliceName(),ed.getLabel(), stack.getLiteralPath(), ed.getMax()); + else if (count > Integer.parseInt(ed.getMax())) { + rule(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_MAXIMUM, profile.getUrl(), ed.getPath(), ed.getId(), ed.getSliceName(),ed.getLabel(), stack.getLiteralPath(), ed.getMax(), Integer.toString(count)); + } } } } @@ -4888,7 +4905,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat private boolean valueMatchesCriteria(Element value, ElementDefinition criteria, StructureDefinition profile) throws FHIRException { if (criteria.hasFixed()) { List msgs = new ArrayList(); - checkFixedValue(msgs, "{virtual}", value, criteria.getFixed(), profile.getUrl(), "value", null); + checkFixedValue(msgs, "{virtual}", value, criteria.getFixed(), profile.getUrl(), "value", null, false); return msgs.size() == 0; } else if (criteria.hasBinding() && criteria.getBinding().getStrength() == BindingStrength.REQUIRED && criteria.getBinding().hasValueSet()) { throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_SLICE_MATCHING__SLICE_MATCHING_BY_VALUE_SET_NOT_DONE)); From 82afa47590667dc5f23b32e304d6f47a7924585a Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 29 Oct 2020 17:51:34 +1100 Subject: [PATCH 09/32] add parameter -html-output for enhanced presentation of slicing information (issue #283) --- RELEASE_NOTES.md | 1 + .../r5/utils/OperationOutcomeUtilities.java | 1 + .../hl7/fhir/validation/ValidationEngine.java | 56 +++++- .../fhir/validation/cli/model/CliContext.java | 17 +- .../cli/services/HTMLOutputGenerator.java | 181 ++++++++++++++++++ .../cli/services/ValidationService.java | 16 +- .../hl7/fhir/validation/cli/utils/Params.java | 6 + 7 files changed, 270 insertions(+), 8 deletions(-) create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/HTMLOutputGenerator.java diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 28ab95b23..3b0d388be 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -5,6 +5,7 @@ Validator Changes: * fix bug checking patterns (missed in some circumstances) * fix bug checking type of resources in bundles * improve messages around cardinality errors in profiles +* add parameter -html-output for enhanced presentation of slicing information Other code changes: * Render binding description in profile tables if it doesn't contain paragraphs diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/OperationOutcomeUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/OperationOutcomeUtilities.java index 23c2ab5e7..d273381d4 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/OperationOutcomeUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/OperationOutcomeUtilities.java @@ -46,6 +46,7 @@ public class OperationOutcomeUtilities { public static OperationOutcomeIssueComponent convertToIssue(ValidationMessage message, OperationOutcome op) { OperationOutcomeIssueComponent issue = new OperationOutcome.OperationOutcomeIssueComponent(); + issue.setUserData("source.vm", message); issue.setCode(convert(message.getType())); if (message.getLocation() != null) { 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 ac11e57fa..4784f88c3 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 @@ -114,6 +114,7 @@ import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; import org.hl7.fhir.utilities.validation.ValidationMessage.Source; import org.hl7.fhir.utilities.xhtml.XhtmlComposer; import org.hl7.fhir.validation.BaseValidator.ValidationControl; +import org.hl7.fhir.validation.ValidationEngine.ValidationRecord; import org.hl7.fhir.validation.cli.model.ScanOutputItem; import org.hl7.fhir.validation.cli.services.StandAloneValidatorFetcher.IPackageInstaller; import org.hl7.fhir.validation.cli.utils.*; @@ -195,6 +196,50 @@ POSSIBILITY OF SUCH DAMAGE. */ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInstaller { + public class ValidationRecord { + + private String location; + private List messages; + int err = 0; + int warn = 0; + int info = 0; + + public ValidationRecord(String location, List messages) { + this.location = location; + this.messages = messages; + for (ValidationMessage vm : messages) { + if (vm.getLevel().equals(ValidationMessage.IssueSeverity.FATAL)||vm.getLevel().equals(ValidationMessage.IssueSeverity.ERROR)) + err++; + else if (vm.getLevel().equals(ValidationMessage.IssueSeverity.WARNING)) + warn++; + else if (!vm.isSignpost()) { + info++; + } + } + } + + public String getLocation() { + return location; + } + + public List getMessages() { + return messages; + } + + public int getErr() { + return err; + } + + public int getWarn() { + return warn; + } + + public int getInfo() { + return info; + } + + } + public class TransformSupportServices implements ITransformerServices { private List outputs; @@ -1171,7 +1216,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst public OperationOutcome validate(String source, List profiles) throws FHIRException, IOException { List l = new ArrayList(); l.add(source); - return (OperationOutcome)validate(l, profiles); + return (OperationOutcome)validate(l, profiles, null); } public List validateScan(List sources, Set guides) throws FHIRException, IOException, EOperationOutcome { @@ -1267,7 +1312,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst } } - public Resource validate(List sources, List profiles) throws FHIRException, IOException { + public Resource validate(List sources, List profiles, List record) throws FHIRException, IOException { if (profiles.size() > 0) { System.out.println(" Profiles: "+profiles); } @@ -1281,7 +1326,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst System.out.print(" Validate " + ref); Content cnt = loadContent(ref, "validate", false); try { - OperationOutcome outcome = validate(ref, cnt.focus, cnt.cntType, profiles); + OperationOutcome outcome = validate(ref, cnt.focus, cnt.cntType, profiles, record); ToolingExtensions.addStringExtension(outcome, ToolingExtensions.EXT_OO_FILE, ref); System.out.println(" " + context.clock().milestone()); results.addEntry().setResource(outcome); @@ -1355,7 +1400,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst } - public OperationOutcome validate(String location, byte[] source, FhirFormat cntType, List profiles) throws FHIRException, IOException, EOperationOutcome, SAXException { + public OperationOutcome validate(String location, byte[] source, FhirFormat cntType, List profiles, List record) throws FHIRException, IOException, EOperationOutcome, SAXException { List messages = new ArrayList(); if (doNative) { SchemaValidator.validateSchema(location, cntType, messages); @@ -1365,6 +1410,9 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst if (showTimes) { System.out.println(location+": "+validator.reportTimes()); } + if (record != null) { + record.add(new ValidationRecord(location, messages)); + } return messagesToOutcome(messages); } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java index 551277f28..e729046ee 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java @@ -41,6 +41,8 @@ public class CliContext { private String map = null; @JsonProperty("output") private String output = null; + @JsonProperty("htmlOutput") + private String htmlOutput = null; @JsonProperty("txServer") private String txServer = "http://tx.fhir.org"; @JsonProperty("sv") @@ -252,6 +254,17 @@ public class CliContext { return this; } + @JsonProperty("output") + public String getHtmlOutput() { + return htmlOutput; + } + + @JsonProperty("output") + public CliContext setHtmlOutput(String htmlOutput) { + this.htmlOutput = htmlOutput; + return this; + } + @JsonProperty("canDoNative") public boolean getCanDoNative() { return canDoNative; @@ -472,6 +485,7 @@ public class CliContext { noExtensibleBindingMessages == that.noExtensibleBindingMessages && Objects.equals(map, that.map) && Objects.equals(output, that.output) && + Objects.equals(htmlOutput, that.htmlOutput) && Objects.equals(txServer, that.txServer) && Objects.equals(sv, that.sv) && Objects.equals(txLog, that.txLog) && @@ -493,7 +507,7 @@ public class CliContext { @Override public int hashCode() { - return Objects.hash(doNative, anyExtensionsAllowed, hintAboutNonMustSupport, recursive, doDebug, assumeValidRestReferences, canDoNative, noInternalCaching, noExtensibleBindingMessages, map, output, txServer, sv, txLog, mapLog, lang, fhirpath, snomedCT, targetVer, igs, questionnaireMode, profiles, sources, mode, locale, locations, crumbTrails, showTimes); + return Objects.hash(doNative, anyExtensionsAllowed, hintAboutNonMustSupport, recursive, doDebug, assumeValidRestReferences, canDoNative, noInternalCaching, noExtensibleBindingMessages, map, output, htmlOutput, txServer, sv, txLog, mapLog, lang, fhirpath, snomedCT, targetVer, igs, questionnaireMode, profiles, sources, mode, locale, locations, crumbTrails, showTimes); } @Override @@ -510,6 +524,7 @@ public class CliContext { ", noExtensibleBindingMessages=" + noExtensibleBindingMessages + ", map='" + map + '\'' + ", output='" + output + '\'' + + ", htmlOutput='" + htmlOutput + '\'' + ", txServer='" + txServer + '\'' + ", sv='" + sv + '\'' + ", txLog='" + txLog + '\'' + diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/HTMLOutputGenerator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/HTMLOutputGenerator.java new file mode 100644 index 000000000..a13abb813 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/HTMLOutputGenerator.java @@ -0,0 +1,181 @@ +package org.hl7.fhir.validation.cli.services; + +import java.text.DateFormat; +import java.util.Date; +import java.util.List; + +import org.hl7.fhir.utilities.Utilities; +import org.hl7.fhir.utilities.validation.ValidationMessage; +import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; +import org.hl7.fhir.validation.ValidationEngine.ValidationRecord; +import org.hl7.fhir.validation.cli.utils.VersionUtil; + +public class HTMLOutputGenerator { + + private List records; + + public HTMLOutputGenerator(List records) { + super(); + this.records = records; + } + + public String generate(long time) { + + StringBuilder b = new StringBuilder(); + b.append(genHeader(time)); + int i = 0; + for (ValidationRecord f : records) { + i++; + b.append(genSummaryRow(i, f)); + } + b.append("
\r\n"); + + i = 0; + int id = 0; + for (ValidationRecord f : records) { + i++; + b.append(genStart(i, f)); + if (f.getMessages().size() > 0) { + b.append( + " \r\n"+ + " \r\n"+ + " \r\n"+ + " \r\n"); + for (ValidationMessage vm : f.getMessages()) { + id++; + b.append(genDetails(vm, "m"+id)); + } + b.append("
PathSeverityMessage
\r\n"); + } else { + b.append("

No Issues detected

\r\n"); + } + } + return b.toString(); + } + + private String genHeader(long time) { + int err = 0; + int warn = 0; + int info = 0; + for (ValidationRecord f : records) { + err = err + f.getErr(); + warn = warn + f.getWarn(); + info = info + f.getInfo(); + } + + return + "\r\n"+ + "\r\n"+ + "\r\n"+ + " Validation Results\r\n"+ + " \r\n"+ + " \r\n"+ + " \r\n"+ + "\r\n"+ + "\r\n"+ + "

Validation Results

\r\n"+ + "

"+err+" "+Utilities.pluralize("error", err)+", "+warn+" "+Utilities.pluralize("warning", warn)+", "+info+" "+Utilities.pluralize("hint", info)+". Generated "+now()+" by Validator "+VersionUtil.getVersionString()+" ("+time+"ms)

\r\n"+ + " \r\n"+ + " \r\n"+ + " \r\n"+ + " \r\n"; + } + + private String now() { + return DateFormat.getDateTimeInstance().format(new Date()); + } + + private String genSummaryRow(int i, ValidationRecord rec) { + String color = colorForLevel(IssueSeverity.ERROR, false); + if (rec.getErr() == 0) { + color = "#EFFFEF"; + } + return + " \r\n"+ + " \r\n"+ + " \r\n"; + } + + private String genStart(int i, ValidationRecord f) { + String xlink = Utilities.isAbsoluteUrl(f.getLocation()) ? f.getLocation() : "file:"+f.getLocation(); + return + "
\r\n"+ + " \r\n"+ + "

"+Utilities.escapeXml(f.getLocation())+"

\r\n"; + } + + + private String genDetails(ValidationMessage vm, String id) { + String path = vm.getLocation() == null ? "" : vm.getLocation()+ lineCol(vm); + String level = vm.isSlicingHint() ? "Slicing Information" : vm.isSignpost() ? "Process Info" : vm.getLevel().toCode(); + String color = colorForLevel(vm.getLevel(), vm.isSignpost()); + String mid = vm.getMessageId(); + String msg = vm.getHtml(); + String msgdetails = vm.isSlicingHint() ? vm.getSliceHtml() : vm.getHtml(); + if (vm.isSlicingHint()) { + return + " \r\n"+ + " \r\n"+ + " \r\n"; + + } else { + return + " \r\n"+ + " \r\n"+ + " \r\n"; + } + } + + private String lineCol(ValidationMessage vm) { + return vm.getLine() > 0 ? " (l"+vm.getLine()+"/c"+vm.getCol()+")" : ""; + } + + + private String colorForLevel(IssueSeverity level, boolean signpost) { + if (signpost) { + return "#d6feff"; + } + switch (level) { + case ERROR: + return "#ffcccc"; + case FATAL: + return "#ff9999"; + case WARNING: + return "#ffebcc"; + default: // INFORMATION: + return "#ffffe6"; + } + } + + private String halfColorForLevel(IssueSeverity level, boolean signpost) { + if (signpost) { + return "#e3feff"; + } + switch (level) { + case ERROR: + return "#ffeeee"; + case FATAL: + return "#ffcccc"; + case WARNING: + return "#fff4ee"; + default: // INFORMATION: + return "#fffff2"; + } + } + + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java index 6d4aa8acc..16417caa8 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java @@ -27,6 +27,7 @@ import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.ValidationEngine.ValidationRecord; import org.hl7.fhir.validation.cli.model.*; import org.hl7.fhir.validation.cli.utils.EngineMode; import org.hl7.fhir.validation.cli.utils.VersionSourceInformation; @@ -69,7 +70,9 @@ public class ValidationService { } public static void validateSources(CliContext cliContext, ValidationEngine validator) throws Exception { - Resource r = validator.validate(cliContext.getSources(), cliContext.getProfiles()); + long start = System.currentTimeMillis(); + List records = new ArrayList<>(); + Resource r = validator.validate(cliContext.getSources(), cliContext.getProfiles(), records); int ec = 0; System.out.println("Done. "+validator.getContext().clock().report()); System.out.println(); @@ -92,6 +95,11 @@ public class ValidationService { x.compose(s, r); s.close(); } + if (cliContext.getHtmlOutput() != null) { + String html = new HTMLOutputGenerator(records).generate(System.currentTimeMillis()-start); + TextFile.stringToFile(html, cliContext.getHtmlOutput()); + System.out.println("HTML Summary in "+cliContext.getHtmlOutput()); + } System.exit(ec > 0 ? 1 : 0); } @@ -288,10 +296,12 @@ public class ValidationService { System.out.println("Scanning for versions (no -version parameter):"); VersionSourceInformation versions = ValidationService.scanForVersions(cliContext); for (String s : versions.getReport()) { - System.out.println(" " + s); + if (!s.equals("(nothing found)")) { + System.out.println(" " + s); + } } if (versions.isEmpty()) { - System.out.println("-> Using Default version '" + VersionUtilities.CURRENT_VERSION + "'"); + System.out.println(" No Version Info found: Using Default version '" + VersionUtilities.CURRENT_VERSION + "'"); return "current"; } if (versions.size() == 1) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java index 3790f511f..51fdfc99d 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java @@ -12,6 +12,7 @@ public class Params { public static final String VERSION = "-version"; public static final String OUTPUT = "-output"; + public static final String HTML_OUTPUT = "-html-output"; public static final String PROXY = "-proxy"; public static final String PROFILE = "-profile"; public static final String BUNDLE = "-bundle"; @@ -93,6 +94,11 @@ public class Params { throw new Error("Specified -output without indicating output file"); else cliContext.setOutput(args[++i]); + } else if (args[i].equals(HTML_OUTPUT)) { + if (i + 1 == args.length) + throw new Error("Specified -html-output without indicating output file"); + else + cliContext.setHtmlOutput(args[++i]); } else if (args[i].equals(PROXY)) { i++; // ignore next parameter } else if (args[i].equals(PROFILE)) { From c5255a0f80c5ed683540d5809baa2341e6715b67 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 30 Oct 2020 00:17:24 +1100 Subject: [PATCH 10/32] Gg v5118 (#368) * fix issue validating # references * Mark it has an error if a JSON Array is empty * Don't make wrong error reports for profiling resources in bundles * * Render binding description in profile tables if it doesn't contain paragraphs * fix bug with wrong value for contentReference in derived profiles (profiles do not and cannot change the value) * fix bug with wrong value for contentReference in derived profiles (profiles do not and cannot change the value) (missed testing change) * * fix bug not recognising some content as xml or json * improved markdown support in table generator * * fix bug checking unfixed values for HumanName patterns * fix bug checking patterns (missed in some circumstances) * fix bug checking type of resources in bundles * improve messages around cardinality errors in profiles * add parameter -html-output for enhanced presentation of slicing information (issue #283) --- RELEASE_NOTES.md | 12 ++ .../fhir/r5/conformance/ProfileUtilities.java | 55 ++++-- .../hl7/fhir/r5/elementmodel/JsonParser.java | 3 + .../r5/utils/OperationOutcomeUtilities.java | 1 + .../fhir/r5/test/ProfileUtilitiesTests.java | 2 + .../hl7/fhir/utilities/MarkDownProcessor.java | 5 + .../fhir/utilities/i18n/I18nConstants.java | 1 + .../xhtml/HierarchicalTableGenerator.java | 14 ++ .../src/main/resources/Messages.properties | 10 +- .../hl7/fhir/validation/ValidationEngine.java | 134 ++++++++++++- .../fhir/validation/cli/model/CliContext.java | 17 +- .../cli/services/HTMLOutputGenerator.java | 181 ++++++++++++++++++ .../cli/services/ValidationService.java | 16 +- .../hl7/fhir/validation/cli/utils/Params.java | 6 + .../instance/InstanceValidator.java | 126 ++++++++---- .../type/StructureDefinitionValidator.java | 16 +- .../validation/instance/utils/NodeStack.java | 8 + .../tests/ValidationEngineTests.java | 2 +- pom.xml | 2 +- 19 files changed, 541 insertions(+), 70 deletions(-) create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/HTMLOutputGenerator.java diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e69de29bb..3b0d388be 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -0,0 +1,12 @@ +Validator Changes: +* Mark it has an error if a JSON Array is empty +* Don't make wrong error reports for profiling resources in bundles +* fix bug checking unfixed values for HumanName patterns +* fix bug checking patterns (missed in some circumstances) +* fix bug checking type of resources in bundles +* improve messages around cardinality errors in profiles +* add parameter -html-output for enhanced presentation of slicing information + +Other code changes: +* Render binding description in profile tables if it doesn't contain paragraphs +* fix bug with wrong value for contentReference in derived profiles (profiles do not and cannot change the value) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java index fbb99dd77..7155da406 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java @@ -111,6 +111,7 @@ import org.hl7.fhir.r5.utils.XVerExtensionManager.XVerExtensionStatus; import org.hl7.fhir.r5.utils.formats.CSVWriter; import org.hl7.fhir.r5.utils.formats.XLSXWriter; import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; +import org.hl7.fhir.utilities.MarkDownProcessor; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.i18n.I18nConstants; @@ -362,9 +363,28 @@ public class ProfileUtilities extends TranslatingUtilities { public List getChildMap(StructureDefinition profile, ElementDefinition element) throws DefinitionException { - if (element.getContentReference()!=null) { - for (ElementDefinition e : profile.getSnapshot().getElement()) { - if (element.getContentReference().equals("#"+e.getId())) + if (element.getContentReference() != null) { + List list = null; + String id = null; + if (element.getContentReference().startsWith("#")) { + // internal reference + id = element.getContentReference().substring(1); + list = profile.getSnapshot().getElement(); + } else if (element.getContentReference().contains("#")) { + // external reference + String ref = element.getContentReference(); + StructureDefinition sd = context.fetchResource(StructureDefinition.class, ref.substring(0, ref.indexOf("#"))); + if (sd == null) { + throw new DefinitionException("unable to process contentReference '"+element.getContentReference()+"' on element '"+element.getId()+"'"); + } + list = sd.getSnapshot().getElement(); + id = ref.substring(ref.indexOf("#")+1); + } else { + throw new DefinitionException("unable to process contentReference '"+element.getContentReference()+"' on element '"+element.getId()+"'"); + } + + for (ElementDefinition e : list) { + if (id.equals(e.getId())) return getChildMap(profile, e); } throw new DefinitionException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_NAME_REFERENCE__AT_PATH_, element.getContentReference(), element.getPath())); @@ -3155,6 +3175,10 @@ public class ProfileUtilities extends TranslatingUtilities { c.getPieces().add(checkForNoChange(ved.getBinding(), gen.new Piece(corePath+"terminologies.html#"+ved.getBinding().getStrength().toCode(), egt(ved.getBinding().getStrengthElement()), ved.getBinding().getStrength().getDefinition()))); c.getPieces().add(gen.new Piece(null, ")", null)); } + if (ved.getBinding().hasDescription() && MarkDownProcessor.isSimpleMarkdown(ved.getBinding().getDescription())) { + c.getPieces().add(gen.new Piece(null, ": ", null)); + c.addMarkdownNoPara(ved.getBinding().getDescription()); + } } c.addPiece(gen.new Piece("br")).addPiece(gen.new Piece(null, describeExtensionContext(ed), null)); r.getCells().add(c); @@ -4282,6 +4306,10 @@ public class ProfileUtilities extends TranslatingUtilities { c.getPieces().add(checkForNoChange(binding, gen.new Piece(corePath+"extension-elementdefinition-minvalueset.html", translate("sd.table", "Min Binding")+": ", "Min Value Set Extension").addStyle("font-weight:bold"))); c.getPieces().add(checkForNoChange(binding, gen.new Piece(br.url == null ? null : Utilities.isAbsoluteUrl(br.url) || !pkp.prependLinks() ? br.url : corePath+br.url, br.display, null))); } + if (binding.hasDescription() && MarkDownProcessor.isSimpleMarkdown(binding.getDescription())) { + c.getPieces().add(gen.new Piece(null, ": ", null)); + c.addMarkdownNoPara(binding.getDescription()); + } } for (ElementDefinitionConstraintComponent inv : definition.getConstraint()) { if (!inv.hasSource() || profile == null || inv.getSource().equals(profile.getUrl()) || allInvariants) { @@ -4300,7 +4328,6 @@ public class ProfileUtilities extends TranslatingUtilities { // don't show this, this it's important: c.getPieces().add(gen.new Piece(null, "This repeating element has no defined order", null)); } } - if (definition.hasFixed()) { if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); } c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, translate("sd.table", "Fixed Value")+": ", null).addStyle("font-weight:bold"))); @@ -4594,6 +4621,10 @@ public class ProfileUtilities extends TranslatingUtilities { c.getPieces().add(checkForNoChange(binding, gen.new Piece(null, " (", null))); c.getPieces().add(checkForNoChange(binding, gen.new Piece(corePath+"terminologies.html#"+binding.getStrength().toCode(), binding.getStrength().toCode(), binding.getStrength().getDefinition()))); c.getPieces().add(gen.new Piece(null, ")", null)); } + if (binding.hasDescription() && MarkDownProcessor.isSimpleMarkdown(binding.getDescription())) { + c.getPieces().add(gen.new Piece(null, ": ", null)); + c.addMarkdownNoPara(binding.getDescription()); + } } for (ElementDefinitionConstraintComponent inv : definition.getConstraint()) { if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); } @@ -5338,12 +5369,12 @@ public class ProfileUtilities extends TranslatingUtilities { if (!checkFirst || !sd.hasDifferential() || hasMissingIds(sd.getDifferential().getElement())) { if (!sd.hasDifferential()) sd.setDifferential(new StructureDefinitionDifferentialComponent()); - generateIds(sd.getDifferential().getElement(), sd.getUrl()); + generateIds(sd.getDifferential().getElement(), sd.getUrl(), sd.getType()); } if (!checkFirst || !sd.hasSnapshot() || hasMissingIds(sd.getSnapshot().getElement())) { if (!sd.hasSnapshot()) sd.setSnapshot(new StructureDefinitionSnapshotComponent()); - generateIds(sd.getSnapshot().getElement(), sd.getUrl()); + generateIds(sd.getSnapshot().getElement(), sd.getUrl(), sd.getType()); } } @@ -5388,11 +5419,10 @@ public class ProfileUtilities extends TranslatingUtilities { } - private void generateIds(List list, String name) throws DefinitionException { + private void generateIds(List list, String name, String type) throws DefinitionException { if (list.isEmpty()) return; - Map idMap = new HashMap(); Map idList = new HashMap(); SliceList sliceInfo = new SliceList(); @@ -5420,7 +5450,6 @@ public class ProfileUtilities extends TranslatingUtilities { } } String bs = b.toString(); - idMap.put(ed.hasId() ? ed.getId() : ed.getPath(), bs); ed.setId(bs); if (idList.containsKey(bs)) { if (exception || messages == null) { @@ -5429,11 +5458,9 @@ public class ProfileUtilities extends TranslatingUtilities { messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, name+"."+bs, "Duplicate Element id "+bs, ValidationMessage.IssueSeverity.ERROR)); } idList.put(bs, ed.getPath()); - if (ed.hasContentReference()) { - String s = ed.getContentReference().substring(1); - if (idMap.containsKey(s)) - ed.setContentReference("#"+idMap.get(s)); - + if (ed.hasContentReference() && ed.getContentReference().startsWith("#")) { + String s = ed.getContentReference(); + ed.setContentReference("http://hl7.org/fhir/StructureDefinition/"+type+s); } } // second path - fix up any broken path based id references diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java index 82701ee7f..0d29e0cf0 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java @@ -208,6 +208,9 @@ public class JsonParser extends ParserBase { JsonElement e = object.get(name); if (property.isList() && (e instanceof JsonArray)) { JsonArray arr = (JsonArray) e; + if (arr.size() == 0) { + logError(line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ARRAY_CANNOT_BE_EMPTY), IssueSeverity.ERROR); + } int c = 0; for (JsonElement am : arr) { parseChildComplexInstance(npath+"["+c+"]", object, element, property, name, am); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/OperationOutcomeUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/OperationOutcomeUtilities.java index 23c2ab5e7..d273381d4 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/OperationOutcomeUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/OperationOutcomeUtilities.java @@ -46,6 +46,7 @@ public class OperationOutcomeUtilities { public static OperationOutcomeIssueComponent convertToIssue(ValidationMessage message, OperationOutcome op) { OperationOutcomeIssueComponent issue = new OperationOutcome.OperationOutcomeIssueComponent(); + issue.setUserData("source.vm", message); issue.setCode(convert(message.getType())); if (message.getLocation() != null) { diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/ProfileUtilitiesTests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/ProfileUtilitiesTests.java index 08b9264e2..0c53d558b 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/ProfileUtilitiesTests.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/ProfileUtilitiesTests.java @@ -104,6 +104,8 @@ public class ProfileUtilitiesTests { f.setComment(null); b.setDefinition(null); f.setDefinition(null); + b.setContentReference(null); + f.setContentReference(null); ok = Base.compareDeep(b, f, true); } } diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/MarkDownProcessor.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/MarkDownProcessor.java index d85ddc14a..eb6bb9a3e 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/MarkDownProcessor.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/MarkDownProcessor.java @@ -78,5 +78,10 @@ public class MarkDownProcessor { html = html.replace("
FilenameErrorsWarningsHints
"+Utilities.escapeXml(rec.getLocation())+""+rec.getErr()+""+rec.getWarn()+""+rec.getInfo()+"
"+path+""+level+""+msg+" Show Reasoning

 

"+msgdetails+"
"+path+""+level+""+msg+"
", "
"); return html; } + + + public static boolean isSimpleMarkdown(String description) { + return !description.contains("\n"); + } } \ No newline at end of file diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java index 23c15cc22..36a9960a6 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java @@ -12,6 +12,7 @@ public class I18nConstants { public static final String ALL_OBSERVATIONS_SHOULD_HAVE_A_PERFORMER = "All_observations_should_have_a_performer"; public static final String ALL_OBSERVATIONS_SHOULD_HAVE_A_SUBJECT = "All_observations_should_have_a_subject"; public static final String ALL_OK = "ALL_OK"; + public static final String ARRAY_CANNOT_BE_EMPTY = "ARRAY_CANNOT_BE_EMPTY"; public static final String ATTEMPT_TO_A_SLICE_AN_ELEMENT_THAT_DOES_NOT_REPEAT__FROM__IN_ = "Attempt_to_a_slice_an_element_that_does_not_repeat__from__in_"; public static final String ATTEMPT_TO_REPLACE_ELEMENT_NAME_FOR_A_NONCHOICE_TYPE = "Attempt_to_replace_element_name_for_a_nonchoice_type"; public static final String ATTEMPT_TO_USE_A_SNAPSHOT_ON_PROFILE__AS__BEFORE_IT_IS_GENERATED = "Attempt_to_use_a_snapshot_on_profile__as__before_it_is_generated"; diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/HierarchicalTableGenerator.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/HierarchicalTableGenerator.java index 8edbee65b..94e337d33 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/HierarchicalTableGenerator.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/HierarchicalTableGenerator.java @@ -240,6 +240,7 @@ public class HierarchicalTableGenerator extends TranslatingUtilities { pieces.add(piece); return this; } + public Cell addMarkdown(String md) { try { Parser parser = Parser.builder().build(); @@ -253,6 +254,19 @@ public class HierarchicalTableGenerator extends TranslatingUtilities { return this; } + public Cell addMarkdownNoPara(String md) { + try { + Parser parser = Parser.builder().build(); + Node document = parser.parse(md); + HtmlRenderer renderer = HtmlRenderer.builder().escapeHtml(true).build(); + String html = renderer.render(document); + pieces.addAll(htmlToParagraphPieces(html)); + } catch (Exception e) { + e.printStackTrace(); + } + return this; + } + private List htmlToParagraphPieces(String html) { List myPieces = new ArrayList(); try { diff --git a/org.hl7.fhir.utilities/src/main/resources/Messages.properties b/org.hl7.fhir.utilities/src/main/resources/Messages.properties index 38e7af318..038b16b7c 100644 --- a/org.hl7.fhir.utilities/src/main/resources/Messages.properties +++ b/org.hl7.fhir.utilities/src/main/resources/Messages.properties @@ -209,11 +209,12 @@ 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} Validation_VAL_Profile_MatchMultiple = Profile {0}, Element matches more than one slice - {1}, {2} -Validation_VAL_Profile_Maximum = {0}: max allowed = {1}, but found {2} -Validation_VAL_Profile_Minimum = {0}: minimum required = {1}, but only found {2} +// for the next 4 messages, the available parameters are: 0: profile url, 1: ed.path, 2: ed.id, 3: ed.sliceName, 4: ed.label, 5: element.path, 6: ed.min and optionally 7: actual count +Validation_VAL_Profile_Maximum = {2}: max allowed = {6}, but found {7} (from {0}) +Validation_VAL_Profile_Minimum = {2}: minimum required = {6}, but only found {7} (from {0}) +Validation_VAL_Profile_NoCheckMax = {2}: Unable to check max allowed ({1}) due to lack of slicing validation (from {0}) +Validation_VAL_Profile_NoCheckMin = {2}: Unable to check minimum required ({1}) due to lack of slicing validation (from {0}) Validation_VAL_Profile_MultipleMatches = Found multiple matching profiles among choices: {0} -Validation_VAL_Profile_NoCheckMax = {0}: Unable to check max allowed ({1}) due to lack of slicing validation -Validation_VAL_Profile_NoCheckMin = {0}'': Unable to check minimum required ({1}) due to lack of slicing validation Validation_VAL_Profile_NoDefinition = No definition found for resource type ''{0}'' Validation_VAL_Profile_NoMatch = Unable to find matching profile among choices: {0} Validation_VAL_Profile_NoSnapshot = StructureDefinition has no snapshot - validation is against the snapshot, so it must be provided @@ -617,4 +618,5 @@ SD_ED_TYPE_PROFILE_NOTYPE = Found profile {0}, but unable to determine the type SD_ED_TYPE_PROFILE_WRONG = Profile {0} is for type {1}, but this element has type {2} TERMINOLOGY_TX_NOSVC_BOUND_REQ = Could not confirm that the codes provided are from the required value set {0} because there is no terminology service TERMINOLOGY_TX_NOSVC_BOUND_EXT = Could not confirm that the codes provided are from the extensible value set {0} because there is no terminology service +ARRAY_CANNOT_BE_EMPTY = Array cannot be empty - the property should not be present if it has no values \ 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 648f57520..4784f88c3 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 @@ -29,6 +29,10 @@ import java.util.UUID; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + import org.apache.commons.io.IOUtils; import org.hl7.fhir.convertors.VersionConvertorAdvisor50; import org.hl7.fhir.convertors.VersionConvertor_10_30; @@ -56,6 +60,7 @@ import org.hl7.fhir.r5.context.SimpleWorkerContext; import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.elementmodel.Manager; import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat; +import org.hl7.fhir.r5.elementmodel.ParserBase.ValidationPolicy; import org.hl7.fhir.r5.elementmodel.ObjectConverter; import org.hl7.fhir.r5.formats.FormatUtilities; import org.hl7.fhir.r5.formats.IParser.OutputStyle; @@ -98,19 +103,23 @@ import org.hl7.fhir.utilities.TimeTracker; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.i18n.I18nConstants; +import org.hl7.fhir.utilities.json.JsonTrackingParser; import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; import org.hl7.fhir.utilities.npm.NpmPackage; import org.hl7.fhir.utilities.npm.ToolsVersion; +import org.hl7.fhir.utilities.turtle.Turtle; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; import org.hl7.fhir.utilities.validation.ValidationMessage.Source; import org.hl7.fhir.utilities.xhtml.XhtmlComposer; import org.hl7.fhir.validation.BaseValidator.ValidationControl; +import org.hl7.fhir.validation.ValidationEngine.ValidationRecord; import org.hl7.fhir.validation.cli.model.ScanOutputItem; import org.hl7.fhir.validation.cli.services.StandAloneValidatorFetcher.IPackageInstaller; import org.hl7.fhir.validation.cli.utils.*; import org.hl7.fhir.validation.instance.InstanceValidator; +import org.w3c.dom.Document; import org.xml.sax.SAXException; @@ -187,6 +196,50 @@ POSSIBILITY OF SUCH DAMAGE. */ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInstaller { + public class ValidationRecord { + + private String location; + private List messages; + int err = 0; + int warn = 0; + int info = 0; + + public ValidationRecord(String location, List messages) { + this.location = location; + this.messages = messages; + for (ValidationMessage vm : messages) { + if (vm.getLevel().equals(ValidationMessage.IssueSeverity.FATAL)||vm.getLevel().equals(ValidationMessage.IssueSeverity.ERROR)) + err++; + else if (vm.getLevel().equals(ValidationMessage.IssueSeverity.WARNING)) + warn++; + else if (!vm.isSignpost()) { + info++; + } + } + } + + public String getLocation() { + return location; + } + + public List getMessages() { + return messages; + } + + public int getErr() { + return err; + } + + public int getWarn() { + return warn; + } + + public int getInfo() { + return info; + } + + } + public class TransformSupportServices implements ITransformerServices { private List outputs; @@ -538,7 +591,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst throw new FHIRException("Unable to fetch content from "+src+" ("+errors.toString()+")"); } - FhirFormat fmt = checkIsResource(cnt, src); + FhirFormat fmt = checkFormat(cnt, src); if (fmt != null) { Map res = new HashMap(); res.put(Utilities.changeFileExt(src, "."+fmt.getExtension()), cnt); @@ -809,33 +862,99 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst this.noInvariantChecks = value; } + private FhirFormat checkFormat(byte[] cnt, String filename) { + System.out.println(" ..Detect format for "+filename); + try { + JsonTrackingParser.parseJson(cnt); + return FhirFormat.JSON; + } catch (Exception e) { + if (debug) { + System.out.println("Not JSON: "+e.getMessage()); + } + } + try { + parseXml(cnt); + return FhirFormat.XML; + } catch (Exception e) { + if (debug) { + System.out.println("Not XML: "+e.getMessage()); + } + } + try { + new Turtle().parse(TextFile.bytesToString(cnt)); + return FhirFormat.TURTLE; + } catch (Exception e) { + if (debug) { + System.out.println("Not Turtle: "+e.getMessage()); + } + } + try { + new StructureMapUtilities(context, null, null).parse(TextFile.bytesToString(cnt), null); + return FhirFormat.TEXT; + } catch (Exception e) { + if (debug) { + System.out.println("Not Text: "+e.getMessage()); + } + } + if (debug) + System.out.println(" .. not a resource: "+filename); + return null; + } + + private FhirFormat checkIsResource(byte[] cnt, String filename) { System.out.println(" ..Detect format for "+filename); try { Manager.parse(context, new ByteArrayInputStream(cnt), FhirFormat.JSON); return FhirFormat.JSON; } catch (Exception e) { + if (debug) { + System.out.println("Not JSON: "+e.getMessage()); + } } try { - Manager.parse(context, new ByteArrayInputStream(cnt),FhirFormat.XML); + parseXml(cnt); return FhirFormat.XML; } catch (Exception e) { + if (debug) { + System.out.println("Not XML: "+e.getMessage()); + } } try { Manager.parse(context, new ByteArrayInputStream(cnt),FhirFormat.TURTLE); return FhirFormat.TURTLE; } catch (Exception e) { + if (debug) { + System.out.println("Not Turtle: "+e.getMessage()); + } } try { new StructureMapUtilities(context, null, null).parse(TextFile.bytesToString(cnt), null); return FhirFormat.TEXT; } catch (Exception e) { + if (debug) { + System.out.println("Not Text: "+e.getMessage()); + } } if (debug) System.out.println(" .. not a resource: "+filename); return null; } + private Document parseXml(byte[] cnt) throws ParserConfigurationException, SAXException, IOException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + // xxe protection + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + factory.setFeature("http://xml.org/sax/features/external-general-entities", false); + factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + factory.setXIncludeAware(false); + factory.setExpandEntityReferences(false); + factory.setNamespaceAware(true); + DocumentBuilder builder = factory.newDocumentBuilder(); + return builder.parse(new ByteArrayInputStream(cnt)); + } + private FhirFormat checkIsResource(String path) throws IOException { String ext = Utilities.getFileExtension(path); if (Utilities.existsInList(ext, "xml")) @@ -1097,7 +1216,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst public OperationOutcome validate(String source, List profiles) throws FHIRException, IOException { List l = new ArrayList(); l.add(source); - return (OperationOutcome)validate(l, profiles); + return (OperationOutcome)validate(l, profiles, null); } public List validateScan(List sources, Set guides) throws FHIRException, IOException, EOperationOutcome { @@ -1193,7 +1312,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst } } - public Resource validate(List sources, List profiles) throws FHIRException, IOException { + public Resource validate(List sources, List profiles, List record) throws FHIRException, IOException { if (profiles.size() > 0) { System.out.println(" Profiles: "+profiles); } @@ -1207,7 +1326,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst System.out.print(" Validate " + ref); Content cnt = loadContent(ref, "validate", false); try { - OperationOutcome outcome = validate(ref, cnt.focus, cnt.cntType, profiles); + OperationOutcome outcome = validate(ref, cnt.focus, cnt.cntType, profiles, record); ToolingExtensions.addStringExtension(outcome, ToolingExtensions.EXT_OO_FILE, ref); System.out.println(" " + context.clock().milestone()); results.addEntry().setResource(outcome); @@ -1281,7 +1400,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst } - public OperationOutcome validate(String location, byte[] source, FhirFormat cntType, List profiles) throws FHIRException, IOException, EOperationOutcome, SAXException { + public OperationOutcome validate(String location, byte[] source, FhirFormat cntType, List profiles, List record) throws FHIRException, IOException, EOperationOutcome, SAXException { List messages = new ArrayList(); if (doNative) { SchemaValidator.validateSchema(location, cntType, messages); @@ -1291,6 +1410,9 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst if (showTimes) { System.out.println(location+": "+validator.reportTimes()); } + if (record != null) { + record.add(new ValidationRecord(location, messages)); + } return messagesToOutcome(messages); } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java index 551277f28..e729046ee 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java @@ -41,6 +41,8 @@ public class CliContext { private String map = null; @JsonProperty("output") private String output = null; + @JsonProperty("htmlOutput") + private String htmlOutput = null; @JsonProperty("txServer") private String txServer = "http://tx.fhir.org"; @JsonProperty("sv") @@ -252,6 +254,17 @@ public class CliContext { return this; } + @JsonProperty("output") + public String getHtmlOutput() { + return htmlOutput; + } + + @JsonProperty("output") + public CliContext setHtmlOutput(String htmlOutput) { + this.htmlOutput = htmlOutput; + return this; + } + @JsonProperty("canDoNative") public boolean getCanDoNative() { return canDoNative; @@ -472,6 +485,7 @@ public class CliContext { noExtensibleBindingMessages == that.noExtensibleBindingMessages && Objects.equals(map, that.map) && Objects.equals(output, that.output) && + Objects.equals(htmlOutput, that.htmlOutput) && Objects.equals(txServer, that.txServer) && Objects.equals(sv, that.sv) && Objects.equals(txLog, that.txLog) && @@ -493,7 +507,7 @@ public class CliContext { @Override public int hashCode() { - return Objects.hash(doNative, anyExtensionsAllowed, hintAboutNonMustSupport, recursive, doDebug, assumeValidRestReferences, canDoNative, noInternalCaching, noExtensibleBindingMessages, map, output, txServer, sv, txLog, mapLog, lang, fhirpath, snomedCT, targetVer, igs, questionnaireMode, profiles, sources, mode, locale, locations, crumbTrails, showTimes); + return Objects.hash(doNative, anyExtensionsAllowed, hintAboutNonMustSupport, recursive, doDebug, assumeValidRestReferences, canDoNative, noInternalCaching, noExtensibleBindingMessages, map, output, htmlOutput, txServer, sv, txLog, mapLog, lang, fhirpath, snomedCT, targetVer, igs, questionnaireMode, profiles, sources, mode, locale, locations, crumbTrails, showTimes); } @Override @@ -510,6 +524,7 @@ public class CliContext { ", noExtensibleBindingMessages=" + noExtensibleBindingMessages + ", map='" + map + '\'' + ", output='" + output + '\'' + + ", htmlOutput='" + htmlOutput + '\'' + ", txServer='" + txServer + '\'' + ", sv='" + sv + '\'' + ", txLog='" + txLog + '\'' + diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/HTMLOutputGenerator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/HTMLOutputGenerator.java new file mode 100644 index 000000000..a13abb813 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/HTMLOutputGenerator.java @@ -0,0 +1,181 @@ +package org.hl7.fhir.validation.cli.services; + +import java.text.DateFormat; +import java.util.Date; +import java.util.List; + +import org.hl7.fhir.utilities.Utilities; +import org.hl7.fhir.utilities.validation.ValidationMessage; +import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; +import org.hl7.fhir.validation.ValidationEngine.ValidationRecord; +import org.hl7.fhir.validation.cli.utils.VersionUtil; + +public class HTMLOutputGenerator { + + private List records; + + public HTMLOutputGenerator(List records) { + super(); + this.records = records; + } + + public String generate(long time) { + + StringBuilder b = new StringBuilder(); + b.append(genHeader(time)); + int i = 0; + for (ValidationRecord f : records) { + i++; + b.append(genSummaryRow(i, f)); + } + b.append("
\r\n"); + + i = 0; + int id = 0; + for (ValidationRecord f : records) { + i++; + b.append(genStart(i, f)); + if (f.getMessages().size() > 0) { + b.append( + " \r\n"+ + " \r\n"+ + " \r\n"+ + " \r\n"); + for (ValidationMessage vm : f.getMessages()) { + id++; + b.append(genDetails(vm, "m"+id)); + } + b.append("
PathSeverityMessage
\r\n"); + } else { + b.append("

No Issues detected

\r\n"); + } + } + return b.toString(); + } + + private String genHeader(long time) { + int err = 0; + int warn = 0; + int info = 0; + for (ValidationRecord f : records) { + err = err + f.getErr(); + warn = warn + f.getWarn(); + info = info + f.getInfo(); + } + + return + "\r\n"+ + "\r\n"+ + "\r\n"+ + " Validation Results\r\n"+ + " \r\n"+ + " \r\n"+ + " \r\n"+ + "\r\n"+ + "\r\n"+ + "

Validation Results

\r\n"+ + "

"+err+" "+Utilities.pluralize("error", err)+", "+warn+" "+Utilities.pluralize("warning", warn)+", "+info+" "+Utilities.pluralize("hint", info)+". Generated "+now()+" by Validator "+VersionUtil.getVersionString()+" ("+time+"ms)

\r\n"+ + " \r\n"+ + " \r\n"+ + " \r\n"+ + " \r\n"; + } + + private String now() { + return DateFormat.getDateTimeInstance().format(new Date()); + } + + private String genSummaryRow(int i, ValidationRecord rec) { + String color = colorForLevel(IssueSeverity.ERROR, false); + if (rec.getErr() == 0) { + color = "#EFFFEF"; + } + return + " \r\n"+ + " \r\n"+ + " \r\n"; + } + + private String genStart(int i, ValidationRecord f) { + String xlink = Utilities.isAbsoluteUrl(f.getLocation()) ? f.getLocation() : "file:"+f.getLocation(); + return + "
\r\n"+ + " \r\n"+ + "

"+Utilities.escapeXml(f.getLocation())+"

\r\n"; + } + + + private String genDetails(ValidationMessage vm, String id) { + String path = vm.getLocation() == null ? "" : vm.getLocation()+ lineCol(vm); + String level = vm.isSlicingHint() ? "Slicing Information" : vm.isSignpost() ? "Process Info" : vm.getLevel().toCode(); + String color = colorForLevel(vm.getLevel(), vm.isSignpost()); + String mid = vm.getMessageId(); + String msg = vm.getHtml(); + String msgdetails = vm.isSlicingHint() ? vm.getSliceHtml() : vm.getHtml(); + if (vm.isSlicingHint()) { + return + " \r\n"+ + " \r\n"+ + " \r\n"; + + } else { + return + " \r\n"+ + " \r\n"+ + " \r\n"; + } + } + + private String lineCol(ValidationMessage vm) { + return vm.getLine() > 0 ? " (l"+vm.getLine()+"/c"+vm.getCol()+")" : ""; + } + + + private String colorForLevel(IssueSeverity level, boolean signpost) { + if (signpost) { + return "#d6feff"; + } + switch (level) { + case ERROR: + return "#ffcccc"; + case FATAL: + return "#ff9999"; + case WARNING: + return "#ffebcc"; + default: // INFORMATION: + return "#ffffe6"; + } + } + + private String halfColorForLevel(IssueSeverity level, boolean signpost) { + if (signpost) { + return "#e3feff"; + } + switch (level) { + case ERROR: + return "#ffeeee"; + case FATAL: + return "#ffcccc"; + case WARNING: + return "#fff4ee"; + default: // INFORMATION: + return "#fffff2"; + } + } + + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java index 6d4aa8acc..16417caa8 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java @@ -27,6 +27,7 @@ import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.ValidationEngine.ValidationRecord; import org.hl7.fhir.validation.cli.model.*; import org.hl7.fhir.validation.cli.utils.EngineMode; import org.hl7.fhir.validation.cli.utils.VersionSourceInformation; @@ -69,7 +70,9 @@ public class ValidationService { } public static void validateSources(CliContext cliContext, ValidationEngine validator) throws Exception { - Resource r = validator.validate(cliContext.getSources(), cliContext.getProfiles()); + long start = System.currentTimeMillis(); + List records = new ArrayList<>(); + Resource r = validator.validate(cliContext.getSources(), cliContext.getProfiles(), records); int ec = 0; System.out.println("Done. "+validator.getContext().clock().report()); System.out.println(); @@ -92,6 +95,11 @@ public class ValidationService { x.compose(s, r); s.close(); } + if (cliContext.getHtmlOutput() != null) { + String html = new HTMLOutputGenerator(records).generate(System.currentTimeMillis()-start); + TextFile.stringToFile(html, cliContext.getHtmlOutput()); + System.out.println("HTML Summary in "+cliContext.getHtmlOutput()); + } System.exit(ec > 0 ? 1 : 0); } @@ -288,10 +296,12 @@ public class ValidationService { System.out.println("Scanning for versions (no -version parameter):"); VersionSourceInformation versions = ValidationService.scanForVersions(cliContext); for (String s : versions.getReport()) { - System.out.println(" " + s); + if (!s.equals("(nothing found)")) { + System.out.println(" " + s); + } } if (versions.isEmpty()) { - System.out.println("-> Using Default version '" + VersionUtilities.CURRENT_VERSION + "'"); + System.out.println(" No Version Info found: Using Default version '" + VersionUtilities.CURRENT_VERSION + "'"); return "current"; } if (versions.size() == 1) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java index 3790f511f..51fdfc99d 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java @@ -12,6 +12,7 @@ public class Params { public static final String VERSION = "-version"; public static final String OUTPUT = "-output"; + public static final String HTML_OUTPUT = "-html-output"; public static final String PROXY = "-proxy"; public static final String PROFILE = "-profile"; public static final String BUNDLE = "-bundle"; @@ -93,6 +94,11 @@ public class Params { throw new Error("Specified -output without indicating output file"); else cliContext.setOutput(args[++i]); + } else if (args[i].equals(HTML_OUTPUT)) { + if (i + 1 == args.length) + throw new Error("Specified -html-output without indicating output file"); + else + cliContext.setHtmlOutput(args[++i]); } else if (args[i].equals(PROXY)) { i++; // ignore next parameter } else if (args[i].equals(PROFILE)) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java index cc147f5c3..1727acab8 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java @@ -961,7 +961,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } else { if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, codings.size() == fixed.getCoding().size(), I18nConstants.TERMINOLOGY_TX_CODING_COUNT, Integer.toString(fixed.getCoding().size()), Integer.toString(codings.size()))) { for (int i = 0; i < codings.size(); i++) - checkFixedValue(errors, path + ".coding", codings.get(i), fixed.getCoding().get(i), fixedSource, "coding", focus); + checkFixedValue(errors, path + ".coding", codings.get(i), fixed.getCoding().get(i), fixedSource, "coding", focus, false); } } } @@ -1748,10 +1748,6 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat return b.toString(); } - private void checkFixedValue(List errors, String path, Element focus, org.hl7.fhir.r5.model.Element fixed, String fixedSource, String propName, Element parent) { - checkFixedValue(errors, path, focus, fixed, fixedSource, propName, parent, false); - } - @SuppressWarnings("rawtypes") private void checkFixedValue(List errors, String path, Element focus, org.hl7.fhir.r5.model.Element fixed, String fixedSource, String propName, Element parent, boolean pattern) { if ((fixed == null || fixed.isEmpty()) && focus == null) { @@ -1829,7 +1825,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat for (Extension e : fixed.getExtension()) { Element ex = getExtensionByUrl(extensions, e.getUrl()); if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, ex != null, I18nConstants.EXTENSION_EXT_COUNT_NOTFOUND, e.getUrl())) { - checkFixedValue(errors, path, ex.getNamedChild("extension").getNamedChild("value"), e.getValue(), fixedSource, "extension.value", ex.getNamedChild("extension")); + checkFixedValue(errors, path, ex.getNamedChild("extension").getNamedChild("value"), e.getValue(), fixedSource, "extension.value", ex.getNamedChild("extension"), false); } } } @@ -1842,25 +1838,33 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat checkFixedValue(errors, path + ".period", focus.getNamedChild("period"), fixed.getPeriod(), fixedSource, "period", focus, pattern); List parts = new ArrayList(); - focus.getNamedChildren("family", parts); - if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, parts.size() > 0 == fixed.hasFamily(), I18nConstants.FIXED_TYPE_CHECKS_DT_NAME_FAMILY, (fixed.hasFamily() ? "1" : "0"), Integer.toString(parts.size()))) { - for (int i = 0; i < parts.size(); i++) - checkFixedValue(errors, path + ".family", parts.get(i), fixed.getFamilyElement(), fixedSource, "family", focus, pattern); + if (!pattern || fixed.hasFamily()) { + focus.getNamedChildren("family", parts); + if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, parts.size() > 0 == fixed.hasFamily(), I18nConstants.FIXED_TYPE_CHECKS_DT_NAME_FAMILY, (fixed.hasFamily() ? "1" : "0"), Integer.toString(parts.size()))) { + for (int i = 0; i < parts.size(); i++) + checkFixedValue(errors, path + ".family", parts.get(i), fixed.getFamilyElement(), fixedSource, "family", focus, pattern); + } } - focus.getNamedChildren("given", parts); - if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, parts.size() == fixed.getGiven().size(), I18nConstants.FIXED_TYPE_CHECKS_DT_NAME_GIVEN, Integer.toString(fixed.getGiven().size()), Integer.toString(parts.size()))) { - for (int i = 0; i < parts.size(); i++) - checkFixedValue(errors, path + ".given", parts.get(i), fixed.getGiven().get(i), fixedSource, "given", focus, pattern); + if (!pattern || fixed.hasGiven()) { + focus.getNamedChildren("given", parts); + if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, parts.size() == fixed.getGiven().size(), I18nConstants.FIXED_TYPE_CHECKS_DT_NAME_GIVEN, Integer.toString(fixed.getGiven().size()), Integer.toString(parts.size()))) { + for (int i = 0; i < parts.size(); i++) + checkFixedValue(errors, path + ".given", parts.get(i), fixed.getGiven().get(i), fixedSource, "given", focus, pattern); + } } - focus.getNamedChildren("prefix", parts); - if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, parts.size() == fixed.getPrefix().size(), I18nConstants.FIXED_TYPE_CHECKS_DT_NAME_PREFIX, Integer.toString(fixed.getPrefix().size()), Integer.toString(parts.size()))) { - for (int i = 0; i < parts.size(); i++) - checkFixedValue(errors, path + ".prefix", parts.get(i), fixed.getPrefix().get(i), fixedSource, "prefix", focus, pattern); + if (!pattern || fixed.hasPrefix()) { + focus.getNamedChildren("prefix", parts); + if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, parts.size() == fixed.getPrefix().size(), I18nConstants.FIXED_TYPE_CHECKS_DT_NAME_PREFIX, Integer.toString(fixed.getPrefix().size()), Integer.toString(parts.size()))) { + for (int i = 0; i < parts.size(); i++) + checkFixedValue(errors, path + ".prefix", parts.get(i), fixed.getPrefix().get(i), fixedSource, "prefix", focus, pattern); + } } - focus.getNamedChildren("suffix", parts); - if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, parts.size() == fixed.getSuffix().size(), I18nConstants.FIXED_TYPE_CHECKS_DT_NAME_SUFFIX, Integer.toString(fixed.getSuffix().size()), Integer.toString(parts.size()))) { - for (int i = 0; i < parts.size(); i++) - checkFixedValue(errors, path + ".suffix", parts.get(i), fixed.getSuffix().get(i), fixedSource, "suffix", focus, pattern); + if (!pattern || fixed.hasSuffix()) { + focus.getNamedChildren("suffix", parts); + if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, parts.size() == fixed.getSuffix().size(), I18nConstants.FIXED_TYPE_CHECKS_DT_NAME_SUFFIX, Integer.toString(fixed.getSuffix().size()), Integer.toString(parts.size()))) { + for (int i = 0; i < parts.size(); i++) + checkFixedValue(errors, path + ".suffix", parts.get(i), fixed.getSuffix().get(i), fixedSource, "suffix", focus, pattern); + } } } @@ -3054,9 +3058,22 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat // work back through the parent list. // really, there should only be one level for this (contained resources cannot contain // contained resources), but we'll leave that to some other code to worry about + boolean wasContained = false; while (stack != null && stack.getElement() != null) { if (stack.getElement().getProperty().isResource()) { // ok, we'll try to find the contained reference + if (ref.equals("#") && stack.getElement().getSpecial() != SpecialElement.CONTAINED && wasContained) { + ResolvedReference rr = new ResolvedReference(); + rr.setResource(stack.getElement()); + rr.setFocus(stack.getElement()); + rr.setExternal(false); + rr.setStack(stack.push(stack.getElement(), -1, stack.getElement().getProperty().getDefinition(), stack.getElement().getProperty().getDefinition())); + rr.getStack().qualifyPath(".ofType("+stack.getElement().fhirType()+")"); + return rr; + } + if (stack.getElement().getSpecial() == SpecialElement.CONTAINED) { + wasContained = true; + } IndexedElement res = getContainedById(stack.getElement(), ref.substring(1)); if (res != null) { ResolvedReference rr = new ResolvedReference(); @@ -4069,8 +4086,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat // check type invariants checkInvariants(hostContext, errors, profile, definition, resource, element, stack, false); - if (definition.getFixed() != null) - checkFixedValue(errors, stack.getLiteralPath(), element, definition.getFixed(), profile.getUrl(), definition.getSliceName(), null); + if (definition.getFixed() != null) { + checkFixedValue(errors, stack.getLiteralPath(), element, definition.getFixed(), profile.getUrl(), definition.getSliceName(), null, false); + } + if (definition.getPattern() != null) { + checkFixedValue(errors, stack.getLiteralPath(), element, definition.getPattern(), profile.getUrl(), definition.getSliceName(), null, true); + } // get the list of direct defined children, including slices List childDefinitions = profileUtilities.getChildMap(profile, definition); @@ -4136,13 +4157,20 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat Element resource, Element element, String actualType, NodeStack stack, boolean inCodeableConcept, boolean checkDisplayInContext, ElementInfo ei, String extensionUrl) throws FHIRException, DefinitionException { + if (debug && ei.definition != null && ei.slice != null) { + System.out.println(Utilities.padLeft("", ' ', stack.depth())+ "Check "+ei.getPath()+" against both "+ei.definition.getId()+" and "+ei.slice.getId()); + } if (ei.definition != null) { - checkChildByDefinition(hostContext, errors, profile, definition, resource, element, actualType, stack, inCodeableConcept, checkDisplayInContext, ei, - extensionUrl, ei.definition, false); + if (debug) { + System.out.println(Utilities.padLeft("", ' ', stack.depth())+ "Check "+ei.getPath()+" against defn "+ei.definition.getId()); + } + checkChildByDefinition(hostContext, errors, profile, definition, resource, element, actualType, stack, inCodeableConcept, checkDisplayInContext, ei, extensionUrl, ei.definition, false); } if (ei.slice != null) { - checkChildByDefinition(hostContext, errors, profile, definition, resource, element, actualType, stack, inCodeableConcept, checkDisplayInContext, ei, - extensionUrl, ei.slice, true); + if (debug) { + System.out.println(Utilities.padLeft("", ' ', stack.depth())+ "Check "+ei.getPath()+" against slice "+ei.slice.getId()); + } + checkChildByDefinition(hostContext, errors, profile, definition, resource, element, actualType, stack, inCodeableConcept, checkDisplayInContext, ei, extensionUrl, ei.slice, true); } } @@ -4186,11 +4214,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } else if (checkDefn.getType().size() > 1) { String prefix = tail(checkDefn.getPath()); - assert typesAreAllReference(checkDefn.getType()) || checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR) || prefix.endsWith("[x]") : prefix; + assert typesAreAllReference(checkDefn.getType()) || checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR) || prefix.endsWith("[x]") || isResourceAndTypes(checkDefn) : "Multiple Types allowed, but name is wrong @ "+checkDefn.getPath()+": "+checkDefn.typeSummaryVB(); - if (checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR)) + if (checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR)) { type = ei.getElement().getType(); - else { + } else if (ei.getElement().isResource()) { + type = ei.getElement().fhirType(); + } else { prefix = prefix.substring(0, prefix.length() - 3); for (TypeRefComponent t : checkDefn.getType()) if ((prefix + Utilities.capitalize(t.getWorkingCode())).equals(ei.getName())) { @@ -4251,7 +4281,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat checkPrimitive(hostContext, errors, ei.getPath(), type, checkDefn, ei.getElement(), profile, stack); } else { if (checkDefn.hasFixed()) { - checkFixedValue(errors, ei.getPath(), ei.getElement(), checkDefn.getFixed(), profile.getUrl(), checkDefn.getSliceName(), null); + checkFixedValue(errors, ei.getPath(), ei.getElement(), checkDefn.getFixed(), profile.getUrl(), checkDefn.getSliceName(), null, false); } if (checkDefn.hasPattern()) { checkFixedValue(errors, ei.getPath(), ei.getElement(), checkDefn.getPattern(), profile.getUrl(), checkDefn.getSliceName(), null, true); @@ -4386,6 +4416,18 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } + private boolean isResourceAndTypes(ElementDefinition ed) { + if (!Utilities.existsInList(ed.getBase().getPath(), "Bundle.entry.resource", "Bundle.entry.response.outcome", "DomainResource.contained", "Parameters.parameter.resource", "Parameters.parameter.part.resource")) { + return false; + } + for (TypeRefComponent tr : ed.getType()) { + if (!isResource(tr.getCode())) { + return false; + } + } + return true; + } + private boolean isResource(String type) { StructureDefinition sd = context.fetchTypeDefinition(type); return sd != null && sd.getKind().equals(StructureDefinitionKind.RESOURCE); @@ -4476,18 +4518,18 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } } - String location = "Profile " + profile.getUrl() + ", Element '" + stack.getLiteralPath() + "." + tail(ed.getPath()) + (ed.hasSliceName() ? "[" + ed.getSliceName() + (ed.hasLabel() ? " (" + ed.getLabel() + ")" : "") + "]" : "") + "'"; if (ed.getMin() > 0) { if (problematicPaths.contains(ed.getPath())) - hint(errors, IssueType.NOTSUPPORTED, element.line(), element.col(), stack.getLiteralPath(), count >= ed.getMin(), I18nConstants.VALIDATION_VAL_PROFILE_NOCHECKMIN, location, Integer.toString(ed.getMin())); + hint(errors, IssueType.NOTSUPPORTED, element.line(), element.col(), stack.getLiteralPath(), count >= ed.getMin(), I18nConstants.VALIDATION_VAL_PROFILE_NOCHECKMIN, profile.getUrl(), ed.getPath(), ed.getId(), ed.getSliceName(),ed.getLabel(), stack.getLiteralPath(), Integer.toString(ed.getMin())); else - rule(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), count >= ed.getMin(), I18nConstants.VALIDATION_VAL_PROFILE_MINIMUM, location, Integer.toString(ed.getMin()), Integer.toString(count)); + rule(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), count >= ed.getMin(), I18nConstants.VALIDATION_VAL_PROFILE_MINIMUM, profile.getUrl(), ed.getPath(), ed.getId(), ed.getSliceName(),ed.getLabel(), stack.getLiteralPath(), Integer.toString(ed.getMin()), Integer.toString(count)); } if (ed.hasMax() && !ed.getMax().equals("*")) { if (problematicPaths.contains(ed.getPath())) - hint(errors, IssueType.NOTSUPPORTED, element.line(), element.col(), stack.getLiteralPath(), count <= Integer.parseInt(ed.getMax()), I18nConstants.VALIDATION_VAL_PROFILE_NOCHECKMAX, location, ed.getMax()); - else - rule(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), count <= Integer.parseInt(ed.getMax()), I18nConstants.VALIDATION_VAL_PROFILE_MAXIMUM, location, ed.getMax(), Integer.toString(count)); + hint(errors, IssueType.NOTSUPPORTED, element.line(), element.col(), stack.getLiteralPath(), count <= Integer.parseInt(ed.getMax()), I18nConstants.VALIDATION_VAL_PROFILE_NOCHECKMAX, profile.getUrl(), ed.getPath(), ed.getId(), ed.getSliceName(),ed.getLabel(), stack.getLiteralPath(), ed.getMax()); + else if (count > Integer.parseInt(ed.getMax())) { + rule(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_MAXIMUM, profile.getUrl(), ed.getPath(), ed.getId(), ed.getSliceName(),ed.getLabel(), stack.getLiteralPath(), ed.getMax(), Integer.toString(count)); + } } } } @@ -4863,7 +4905,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat private boolean valueMatchesCriteria(Element value, ElementDefinition criteria, StructureDefinition profile) throws FHIRException { if (criteria.hasFixed()) { List msgs = new ArrayList(); - checkFixedValue(msgs, "{virtual}", value, criteria.getFixed(), profile.getUrl(), "value", null); + checkFixedValue(msgs, "{virtual}", value, criteria.getFixed(), profile.getUrl(), "value", null, false); return msgs.size() == 0; } else if (criteria.hasBinding() && criteria.getBinding().getStrength() == BindingStrength.REQUIRED && criteria.getBinding().hasValueSet()) { throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_SLICE_MATCHING__SLICE_MATCHING_BY_VALUE_SET_NOT_DONE)); @@ -4983,6 +5025,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if ("(component.empty() and related.empty()) implies (dataAbsentReason or value)".equals(expr)) return "(component.empty() and related.empty()) implies (dataAbsentReason.exists() or value.exists())"; + if ("reference.startsWith('#').not() or (reference.substring(1).trace('url') in %rootResource.contained.id.trace('ids'))".equals(expr)) { + return "(reference = '#') or reference.startsWith('#').not() or (reference.substring(1).trace('url') in %rootResource.contained.id.trace('ids'))"; + } + if ("reference.startsWith('#').not() or (reference.substring(1).trace('url') in %resource.contained.id.trace('ids'))".equals(expr)) { + return "(reference = '#') or reference.startsWith('#').not() or (reference.substring(1).trace('url') in %resource.contained.id.trace('ids'))"; + } if ("".equals(expr)) return ""; return expr; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java index 86b805852..0f8de3f63 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java @@ -165,11 +165,25 @@ public class StructureDefinitionValidator extends BaseValidator { if (t == null) { rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), code.equals(t), I18nConstants.SD_ED_TYPE_PROFILE_NOTYPE, p); } else { - rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), code.equals(t), I18nConstants.SD_ED_TYPE_PROFILE_WRONG, p, t, code); + rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), isInstanceOf(t, code), I18nConstants.SD_ED_TYPE_PROFILE_WRONG, p, t, code); } } } + private boolean isInstanceOf(String t, String code) { + StructureDefinition sd = context.fetchTypeDefinition(t); + while (sd != null) { + if (sd.getType().equals(code)) { + return true; + } + sd = sd.hasBaseDefinition() ? context.fetchResource(StructureDefinition.class, sd.getBaseDefinition()) : null; + if (sd != null && !sd.getAbstract()) { + sd = null; + } + } + return false; + } + private String determineBaseType(StructureDefinition sd) { while (sd != null && !sd.hasType() && sd.getDerivation() == TypeDerivationRule.CONSTRAINT) { sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition()); diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/NodeStack.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/NodeStack.java index cf32d7f03..abb85ac64 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/NodeStack.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/NodeStack.java @@ -187,5 +187,13 @@ public class NodeStack { return literalPath; } + public int depth() { + if (parent == null) { + return 0; + } else { + return parent.depth()+1; + } + } + } \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationEngineTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationEngineTests.java index 18be9008a..636c04747 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationEngineTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationEngineTests.java @@ -90,7 +90,7 @@ public class ValidationEngineTests { } if (!org.hl7.fhir.validation.tests.utilities.TestUtilities.silent) System.out.println("Test102: Validate patient-example.xml in v1.0.2 version"); - ValidationEngine ve = new ValidationEngine("hl7.fhir.r2.core#1.0.2", DEF_TX, null, FhirPublication.DSTU2, "41.0.2"); + ValidationEngine ve = new ValidationEngine("hl7.fhir.r2.core#1.0.2", DEF_TX, null, FhirPublication.DSTU2, "1.0.2"); ve.setNoInvariantChecks(true); OperationOutcome op = ve.validate(FhirFormat.XML, TestingUtilities.loadTestResourceStream("validator", "patient102.xml"), null); if (!TestUtilities.silent) diff --git a/pom.xml b/pom.xml index 2956882bd..4433e7e77 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 5.1.0 - 1.1.46 + 1.1.47-SNAPSHOT 5.6.2 3.0.0-M4 0.8.5 From 7a668bff52d81e7fcc13347ac148395504e9af7f Mon Sep 17 00:00:00 2001 From: Mark Iantorno Date: Thu, 29 Oct 2020 12:05:07 -0400 Subject: [PATCH 11/32] I totally missed this on the code review, and it is entirely my fault. (#369) --- .../java/org/hl7/fhir/validation/cli/model/CliContext.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java index e729046ee..6c85d25c9 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java @@ -254,12 +254,12 @@ public class CliContext { return this; } - @JsonProperty("output") + @JsonProperty("htmlOutput") public String getHtmlOutput() { return htmlOutput; } - @JsonProperty("output") + @JsonProperty("htmlOutput") public CliContext setHtmlOutput(String htmlOutput) { this.htmlOutput = htmlOutput; return this; From 02f136d67f5021ac51c05c34f268c8becbc2c6de Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 30 Oct 2020 06:40:14 +1100 Subject: [PATCH 12/32] update for new test cases --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4433e7e77..f49bc2c5e 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 5.1.0 - 1.1.47-SNAPSHOT + 1.1.47 5.6.2 3.0.0-M4 0.8.5 From 53f6f1e9cff5e0f82ca867b89735df6e9fcdd9c6 Mon Sep 17 00:00:00 2001 From: Mark Iantorno Date: Thu, 29 Oct 2020 18:01:43 -0400 Subject: [PATCH 13/32] adding explicit github repo dependency (#370) --- pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pom.xml b/pom.xml index f49bc2c5e..5635b5d55 100644 --- a/pom.xml +++ b/pom.xml @@ -62,6 +62,13 @@ false + + github-releases + https://maven.pkg.github.com/FHIR/fhir-test-cases/ + + false + + From dcaa67ef1c2e9b5158b097b9d540e6682b2df168 Mon Sep 17 00:00:00 2001 From: markiantorno Date: Thu, 29 Oct 2020 23:41:20 +0000 Subject: [PATCH 14/32] Release: v5.1.18 Validator Changes: * Mark it has an error if a JSON Array is empty * Don't make wrong error reports for profiling resources in bundles * fix bug checking unfixed values for HumanName patterns * fix bug checking patterns (missed in some circumstances) * fix bug checking type of resources in bundles * improve messages around cardinality errors in profiles * add parameter -html-output for enhanced presentation of slicing information Other code changes: * Render binding description in profile tables if it doesn't contain paragraphs * fix bug with wrong value for contentReference in derived profiles (profiles do not and cannot change the value) ***NO_CI*** --- org.hl7.fhir.convertors/pom.xml | 2 +- org.hl7.fhir.dstu2/pom.xml | 2 +- org.hl7.fhir.dstu2016may/pom.xml | 2 +- org.hl7.fhir.dstu3/pom.xml | 2 +- org.hl7.fhir.r4/pom.xml | 2 +- org.hl7.fhir.r5/pom.xml | 2 +- org.hl7.fhir.report/pom.xml | 2 +- org.hl7.fhir.utilities/pom.xml | 2 +- org.hl7.fhir.validation.cli/pom.xml | 2 +- org.hl7.fhir.validation/pom.xml | 2 +- pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/org.hl7.fhir.convertors/pom.xml b/org.hl7.fhir.convertors/pom.xml index 50215f666..4b387ad84 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 - 5.1.18-SNAPSHOT + 5.1.18 ../pom.xml diff --git a/org.hl7.fhir.dstu2/pom.xml b/org.hl7.fhir.dstu2/pom.xml index f1632c8b0..f3a34b1c4 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 - 5.1.18-SNAPSHOT + 5.1.18 ../pom.xml diff --git a/org.hl7.fhir.dstu2016may/pom.xml b/org.hl7.fhir.dstu2016may/pom.xml index bba455752..58c8cef75 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 - 5.1.18-SNAPSHOT + 5.1.18 ../pom.xml diff --git a/org.hl7.fhir.dstu3/pom.xml b/org.hl7.fhir.dstu3/pom.xml index 77155d089..b96bba9c4 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 - 5.1.18-SNAPSHOT + 5.1.18 ../pom.xml diff --git a/org.hl7.fhir.r4/pom.xml b/org.hl7.fhir.r4/pom.xml index fde67a543..65eda60b4 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 - 5.1.18-SNAPSHOT + 5.1.18 ../pom.xml diff --git a/org.hl7.fhir.r5/pom.xml b/org.hl7.fhir.r5/pom.xml index 1bf00257b..941657e42 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 - 5.1.18-SNAPSHOT + 5.1.18 ../pom.xml diff --git a/org.hl7.fhir.report/pom.xml b/org.hl7.fhir.report/pom.xml index 524eeab19..7e8c9af29 100644 --- a/org.hl7.fhir.report/pom.xml +++ b/org.hl7.fhir.report/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 5.1.18-SNAPSHOT + 5.1.18 ../pom.xml diff --git a/org.hl7.fhir.utilities/pom.xml b/org.hl7.fhir.utilities/pom.xml index 83223747b..ec1a68e84 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 - 5.1.18-SNAPSHOT + 5.1.18 ../pom.xml diff --git a/org.hl7.fhir.validation.cli/pom.xml b/org.hl7.fhir.validation.cli/pom.xml index 8362c8676..d6a6878fc 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 - 5.1.18-SNAPSHOT + 5.1.18 ../pom.xml diff --git a/org.hl7.fhir.validation/pom.xml b/org.hl7.fhir.validation/pom.xml index 6c7e1a8e3..0a2a41b0f 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 - 5.1.18-SNAPSHOT + 5.1.18 ../pom.xml diff --git a/pom.xml b/pom.xml index 5635b5d55..6e4da6502 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ HAPI FHIR. --> org.hl7.fhir.core - 5.1.18-SNAPSHOT + 5.1.18 pom From b7661db83e6cb0bfb1d13832d6f5c8ada6cbff2d Mon Sep 17 00:00:00 2001 From: markiantorno Date: Fri, 30 Oct 2020 00:08:34 +0000 Subject: [PATCH 15/32] Updating version to: 5.1.19-SNAPSHOT and incrementing test cases dependency. --- RELEASE_NOTES.md | 12 ------------ org.hl7.fhir.convertors/pom.xml | 2 +- org.hl7.fhir.dstu2/pom.xml | 2 +- org.hl7.fhir.dstu2016may/pom.xml | 2 +- org.hl7.fhir.dstu3/pom.xml | 2 +- org.hl7.fhir.r4/pom.xml | 2 +- org.hl7.fhir.r5/pom.xml | 2 +- org.hl7.fhir.report/pom.xml | 2 +- org.hl7.fhir.utilities/pom.xml | 2 +- org.hl7.fhir.validation.cli/pom.xml | 2 +- org.hl7.fhir.validation/pom.xml | 2 +- pom.xml | 2 +- 12 files changed, 11 insertions(+), 23 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 3b0d388be..e69de29bb 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,12 +0,0 @@ -Validator Changes: -* Mark it has an error if a JSON Array is empty -* Don't make wrong error reports for profiling resources in bundles -* fix bug checking unfixed values for HumanName patterns -* fix bug checking patterns (missed in some circumstances) -* fix bug checking type of resources in bundles -* improve messages around cardinality errors in profiles -* add parameter -html-output for enhanced presentation of slicing information - -Other code changes: -* Render binding description in profile tables if it doesn't contain paragraphs -* fix bug with wrong value for contentReference in derived profiles (profiles do not and cannot change the value) diff --git a/org.hl7.fhir.convertors/pom.xml b/org.hl7.fhir.convertors/pom.xml index 4b387ad84..248a6ff9b 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 - 5.1.18 + 5.1.19-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu2/pom.xml b/org.hl7.fhir.dstu2/pom.xml index f3a34b1c4..491cb986b 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 - 5.1.18 + 5.1.19-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu2016may/pom.xml b/org.hl7.fhir.dstu2016may/pom.xml index 58c8cef75..31a0d42d7 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 - 5.1.18 + 5.1.19-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu3/pom.xml b/org.hl7.fhir.dstu3/pom.xml index b96bba9c4..f67cb3002 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 - 5.1.18 + 5.1.19-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r4/pom.xml b/org.hl7.fhir.r4/pom.xml index 65eda60b4..05c3e6f1f 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 - 5.1.18 + 5.1.19-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r5/pom.xml b/org.hl7.fhir.r5/pom.xml index 941657e42..6e7545c60 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 - 5.1.18 + 5.1.19-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.report/pom.xml b/org.hl7.fhir.report/pom.xml index 7e8c9af29..d606cf29c 100644 --- a/org.hl7.fhir.report/pom.xml +++ b/org.hl7.fhir.report/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 5.1.18 + 5.1.19-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.utilities/pom.xml b/org.hl7.fhir.utilities/pom.xml index ec1a68e84..25c3244ed 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 - 5.1.18 + 5.1.19-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.validation.cli/pom.xml b/org.hl7.fhir.validation.cli/pom.xml index d6a6878fc..dbed092a8 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 - 5.1.18 + 5.1.19-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.validation/pom.xml b/org.hl7.fhir.validation/pom.xml index 0a2a41b0f..e0980c396 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 - 5.1.18 + 5.1.19-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 6e4da6502..a1efd2fc9 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ HAPI FHIR. --> org.hl7.fhir.core - 5.1.18 + 5.1.19-SNAPSHOT pom From 6cd0af3b8c952b31b7989d6c96e1199ab53fff01 Mon Sep 17 00:00:00 2001 From: jamesagnew Date: Sun, 1 Nov 2020 14:00:12 -0500 Subject: [PATCH 16/32] Clean up integer64 type --- .../org/hl7/fhir/r5/model/Integer64Type.java | 68 +++++++++---------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Integer64Type.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Integer64Type.java index 99010e11c..114a837b3 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Integer64Type.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Integer64Type.java @@ -1,44 +1,42 @@ package org.hl7.fhir.r5.model; -/* - Copyright (c) 2011+, HL7, Inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of HL7 nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - */ +/* + Copyright (c) 2011+, HL7, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of HL7 nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + */ -import org.hl7.fhir.instance.model.api.IBaseIntegerDatatype; - import ca.uhn.fhir.model.api.annotation.DatatypeDef; /** - * Primitive type "integer" in FHIR: A signed 32-bit integer + * Primitive type "integer64" in FHIR: A signed 64-bit integer */ -@DatatypeDef(name = "integer") +@DatatypeDef(name = "integer64") public class Integer64Type extends PrimitiveType /* implements IBaseInteger64Datatype */ { private static final long serialVersionUID = 3L; @@ -76,12 +74,8 @@ public class Integer64Type extends PrimitiveType /* implements IBaseIntege * @throws IllegalArgumentException If the value is too large to fit in a signed integer */ public Integer64Type(Long theValue) { - if (theValue < java.lang.Long.MIN_VALUE || theValue > java.lang.Long.MAX_VALUE) { - throw new IllegalArgumentException - (theValue + " cannot be cast to int without changing its value."); - } if(theValue!=null) { - setValue((long)theValue.longValue()); + setValue(theValue); } } From 0c01404a4f5a961c6e53f094e2eef64c73442e46 Mon Sep 17 00:00:00 2001 From: jamesagnew Date: Sun, 1 Nov 2020 17:00:22 -0500 Subject: [PATCH 17/32] Improve numeric comparison --- .../hl7/fhir/utilities/VersionUtilities.java | 42 +++++++++++++++---- .../fhir/utilities/VersionUtilitiesTest.java | 34 +++++++++++++++ 2 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/VersionUtilitiesTest.java diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java index c74687d8b..90a1cc8dd 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java @@ -3,6 +3,7 @@ package org.hl7.fhir.utilities; import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.utilities.npm.NpmPackage; @@ -216,13 +217,17 @@ public class VersionUtilities { } /** - * return true if the current version equals test, or later - * - * so if a feature is defined in 4.0, if (VersionUtilities.isThisOrLater("4.0", version))... + * return true if the current version equals test, or later, + * so if a feature is defined in 4.0, if (VersionUtilities.isThisOrLater("4.0", version)) + *

+ * This method tries to perform a numeric parse, so that 0.9 will be considered below 0.10 + * in accordance with SemVer. If either side contains a non-numeric character in a version string, a simple text + * compare will be done instead. + *

* - * @param test - * @param current - * @return + * @param test The value to compare to + * @param current The value being compared + * @return Is {@literal current} later or equal to {@literal test}? For example, if this = 0.5 and current = 0.6 this method will return true */ public static boolean isThisOrLater(String test, String current) { String t = getMajMin(test); @@ -230,8 +235,29 @@ public class VersionUtilities { if (c.compareTo(t) == 0) { return isMajMinOrLaterPatch(test, current); } - boolean ok = c.compareTo(t) >= 0; - return ok; + + String[] testParts = t.split("\\."); + String[] currentParts = c.split("\\."); + + for (int i = 0; i < Math.max(testParts.length, currentParts.length); i++) { + if (i == testParts.length) { + return true; + } else if (i == currentParts.length) { + return false; + } + String testPart = testParts[i]; + String currentPart = currentParts[i]; + if (testPart.equals(currentPart)) { + continue; + } + if (StringUtils.isNumeric(testPart) && StringUtils.isNumeric(currentPart)) { + return Integer.parseInt(currentPart) - Integer.parseInt(testPart) > 0; + } else { + return currentPart.compareTo(testPart) >= 0; + } + } + + return true; } /** diff --git a/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/VersionUtilitiesTest.java b/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/VersionUtilitiesTest.java new file mode 100644 index 000000000..9d61ffc39 --- /dev/null +++ b/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/VersionUtilitiesTest.java @@ -0,0 +1,34 @@ +package org.hl7.fhir.utilities; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class VersionUtilitiesTest { + + @Test + public void isThisOrLater_Simple() { + assertTrue(VersionUtilities.isThisOrLater("0.1", "0.2")); + assertFalse(VersionUtilities.isThisOrLater("0.2", "0.1")); + } + + @Test + public void isThisOrLater_NeedNumericComparison() { + assertTrue(VersionUtilities.isThisOrLater("0.9", "0.10")); + assertFalse(VersionUtilities.isThisOrLater("0.10", "0.9")); + } + + @Test + public void isThisOrLater_DifferentLengths() { + assertTrue(VersionUtilities.isThisOrLater("0.9", "0.9.1")); + assertFalse(VersionUtilities.isThisOrLater("0.9.1", "0.9")); + } + + @Test + public void isThisOrLater_NonNumeric() { + assertTrue(VersionUtilities.isThisOrLater("0.A", "0.B")); + assertFalse(VersionUtilities.isThisOrLater("0.B", "0.A")); + } + + +} \ No newline at end of file From 943bc7413cd920f539c9a67dd0f7d06c2a2aeeb9 Mon Sep 17 00:00:00 2001 From: jamesagnew Date: Sun, 1 Nov 2020 17:26:55 -0500 Subject: [PATCH 18/32] Add more tests --- .../hl7/fhir/utilities/VersionUtilities.java | 17 ++++++++++------- .../fhir/utilities/VersionUtilitiesTest.java | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java index 90a1cc8dd..a5476d661 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java @@ -5,7 +5,6 @@ import java.util.List; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.utilities.npm.NpmPackage; /* Copyright (c) 2011+, HL7, Inc. @@ -250,16 +249,20 @@ public class VersionUtilities { if (testPart.equals(currentPart)) { continue; } - if (StringUtils.isNumeric(testPart) && StringUtils.isNumeric(currentPart)) { - return Integer.parseInt(currentPart) - Integer.parseInt(testPart) > 0; - } else { - return currentPart.compareTo(testPart) >= 0; - } + return compareVersionPart(testPart, currentPart); } return true; } + private static boolean compareVersionPart(String theTestPart, String theCurrentPart) { + if (StringUtils.isNumeric(theTestPart) && StringUtils.isNumeric(theCurrentPart)) { + return Integer.parseInt(theCurrentPart) - Integer.parseInt(theTestPart) >= 0; + } else { + return theCurrentPart.compareTo(theTestPart) >= 0; + } + } + /** * return true if the current version equals test for major and min, or later patch * @@ -277,7 +280,7 @@ public class VersionUtilities { return true; } if (pc!=null) { - return pc.compareTo(pt) >= 0; + return compareVersionPart(pt, pc); } } return false; diff --git a/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/VersionUtilitiesTest.java b/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/VersionUtilitiesTest.java index 9d61ffc39..1e8b68694 100644 --- a/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/VersionUtilitiesTest.java +++ b/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/VersionUtilitiesTest.java @@ -31,4 +31,18 @@ public class VersionUtilitiesTest { } + @Test + public void isMajMinOrLaterPatch_Simple() { + assertTrue(VersionUtilities.isMajMinOrLaterPatch("0.9.0", "0.9.0")); + assertTrue(VersionUtilities.isMajMinOrLaterPatch("0.9.0", "0.9.1")); + assertFalse(VersionUtilities.isThisOrLater("0.9.0", "0.8.1")); + } + + @Test + public void isMajMinOrLaterPatch_VersionWithX() { + assertTrue(VersionUtilities.isMajMinOrLaterPatch("0.9.x", "0.9.0")); + assertTrue(VersionUtilities.isMajMinOrLaterPatch("0.9.x", "0.9.1")); + assertFalse(VersionUtilities.isThisOrLater("0.9.x", "0.8.1")); + } + } \ No newline at end of file From 66400565e99d53ec3a8a694190a99d3ba79c05bc Mon Sep 17 00:00:00 2001 From: Mark Iantorno Date: Tue, 3 Nov 2020 09:08:21 -0500 Subject: [PATCH 19/32] Update master-branch-pipeline.yml for Azure Pipelines --- master-branch-pipeline.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/master-branch-pipeline.yml b/master-branch-pipeline.yml index 475fffa5b..92211e3c5 100644 --- a/master-branch-pipeline.yml +++ b/master-branch-pipeline.yml @@ -58,6 +58,11 @@ steps: $(PGP_KEYNAME) $(PGP_PASSPHRASE) + + github-releases + markiantorno + $(GIT_PACKAGE_PAT) + From 93f3cad9ecaf8ad8b717261ccd51e0879876d46c Mon Sep 17 00:00:00 2001 From: Mark Iantorno Date: Tue, 3 Nov 2020 11:03:54 -0500 Subject: [PATCH 20/32] Update RELEASE_NOTES.md --- RELEASE_NOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e69de29bb..0fbae8f28 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -0,0 +1 @@ +* Release changes From a765efa34340d5aa512484f7839172bb270e404e Mon Sep 17 00:00:00 2001 From: markiantorno Date: Tue, 3 Nov 2020 16:45:59 +0000 Subject: [PATCH 21/32] Release: v5.1.19 * Release changes ***NO_CI*** --- org.hl7.fhir.convertors/pom.xml | 2 +- org.hl7.fhir.dstu2/pom.xml | 2 +- org.hl7.fhir.dstu2016may/pom.xml | 2 +- org.hl7.fhir.dstu3/pom.xml | 2 +- org.hl7.fhir.r4/pom.xml | 2 +- org.hl7.fhir.r5/pom.xml | 2 +- org.hl7.fhir.report/pom.xml | 2 +- org.hl7.fhir.utilities/pom.xml | 2 +- org.hl7.fhir.validation.cli/pom.xml | 2 +- org.hl7.fhir.validation/pom.xml | 2 +- pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/org.hl7.fhir.convertors/pom.xml b/org.hl7.fhir.convertors/pom.xml index 248a6ff9b..7cc76c445 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 - 5.1.19-SNAPSHOT + 5.1.19 ../pom.xml diff --git a/org.hl7.fhir.dstu2/pom.xml b/org.hl7.fhir.dstu2/pom.xml index 491cb986b..5924208ea 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 - 5.1.19-SNAPSHOT + 5.1.19 ../pom.xml diff --git a/org.hl7.fhir.dstu2016may/pom.xml b/org.hl7.fhir.dstu2016may/pom.xml index 31a0d42d7..4fa2cf6c3 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 - 5.1.19-SNAPSHOT + 5.1.19 ../pom.xml diff --git a/org.hl7.fhir.dstu3/pom.xml b/org.hl7.fhir.dstu3/pom.xml index f67cb3002..0cdf3cf7a 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 - 5.1.19-SNAPSHOT + 5.1.19 ../pom.xml diff --git a/org.hl7.fhir.r4/pom.xml b/org.hl7.fhir.r4/pom.xml index 05c3e6f1f..373567781 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 - 5.1.19-SNAPSHOT + 5.1.19 ../pom.xml diff --git a/org.hl7.fhir.r5/pom.xml b/org.hl7.fhir.r5/pom.xml index 6e7545c60..ad03c88be 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 - 5.1.19-SNAPSHOT + 5.1.19 ../pom.xml diff --git a/org.hl7.fhir.report/pom.xml b/org.hl7.fhir.report/pom.xml index d606cf29c..a0a5ff69c 100644 --- a/org.hl7.fhir.report/pom.xml +++ b/org.hl7.fhir.report/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 5.1.19-SNAPSHOT + 5.1.19 ../pom.xml diff --git a/org.hl7.fhir.utilities/pom.xml b/org.hl7.fhir.utilities/pom.xml index 25c3244ed..15438868c 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 - 5.1.19-SNAPSHOT + 5.1.19 ../pom.xml diff --git a/org.hl7.fhir.validation.cli/pom.xml b/org.hl7.fhir.validation.cli/pom.xml index dbed092a8..d5eb3ab32 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 - 5.1.19-SNAPSHOT + 5.1.19 ../pom.xml diff --git a/org.hl7.fhir.validation/pom.xml b/org.hl7.fhir.validation/pom.xml index e0980c396..6217a5e4d 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 - 5.1.19-SNAPSHOT + 5.1.19 ../pom.xml diff --git a/pom.xml b/pom.xml index a1efd2fc9..47a46d9e4 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ HAPI FHIR. --> org.hl7.fhir.core - 5.1.19-SNAPSHOT + 5.1.19 pom From 7a3da4239eb14e7ca35adce55c76c1ce6b2f35cd Mon Sep 17 00:00:00 2001 From: markiantorno Date: Tue, 3 Nov 2020 18:45:02 +0000 Subject: [PATCH 22/32] Updating version to: 5.1.20-SNAPSHOT and incrementing test cases dependency. --- RELEASE_NOTES.md | 1 - org.hl7.fhir.convertors/pom.xml | 2 +- org.hl7.fhir.dstu2/pom.xml | 2 +- org.hl7.fhir.dstu2016may/pom.xml | 2 +- org.hl7.fhir.dstu3/pom.xml | 2 +- org.hl7.fhir.r4/pom.xml | 2 +- org.hl7.fhir.r5/pom.xml | 2 +- org.hl7.fhir.report/pom.xml | 2 +- org.hl7.fhir.utilities/pom.xml | 2 +- org.hl7.fhir.validation.cli/pom.xml | 2 +- org.hl7.fhir.validation/pom.xml | 2 +- pom.xml | 2 +- 12 files changed, 11 insertions(+), 12 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 0fbae8f28..e69de29bb 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1 +0,0 @@ -* Release changes diff --git a/org.hl7.fhir.convertors/pom.xml b/org.hl7.fhir.convertors/pom.xml index 7cc76c445..7f66e4254 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 - 5.1.19 + 5.1.20-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu2/pom.xml b/org.hl7.fhir.dstu2/pom.xml index 5924208ea..db6b64e6b 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 - 5.1.19 + 5.1.20-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu2016may/pom.xml b/org.hl7.fhir.dstu2016may/pom.xml index 4fa2cf6c3..0cc20b537 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 - 5.1.19 + 5.1.20-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu3/pom.xml b/org.hl7.fhir.dstu3/pom.xml index 0cdf3cf7a..f70a3f4e1 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 - 5.1.19 + 5.1.20-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r4/pom.xml b/org.hl7.fhir.r4/pom.xml index 373567781..aed4d0220 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 - 5.1.19 + 5.1.20-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r5/pom.xml b/org.hl7.fhir.r5/pom.xml index ad03c88be..faf68ef5e 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 - 5.1.19 + 5.1.20-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.report/pom.xml b/org.hl7.fhir.report/pom.xml index a0a5ff69c..b512f6731 100644 --- a/org.hl7.fhir.report/pom.xml +++ b/org.hl7.fhir.report/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 5.1.19 + 5.1.20-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.utilities/pom.xml b/org.hl7.fhir.utilities/pom.xml index 15438868c..dac95044f 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 - 5.1.19 + 5.1.20-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.validation.cli/pom.xml b/org.hl7.fhir.validation.cli/pom.xml index d5eb3ab32..6b756a56c 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 - 5.1.19 + 5.1.20-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.validation/pom.xml b/org.hl7.fhir.validation/pom.xml index 6217a5e4d..ccf014753 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 - 5.1.19 + 5.1.20-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 47a46d9e4..65e45ff81 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ HAPI FHIR. --> org.hl7.fhir.core - 5.1.19 + 5.1.20-SNAPSHOT pom From 6e4bbe60fee4c77583cfc0374849246829aa436c Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 5 Nov 2020 14:09:40 +1100 Subject: [PATCH 23/32] fix bug when converting positiveInt between versions --- .../convertors/VersionConvertor_10_40.java | 8 ++++---- .../convertors/VersionConvertor_10_50.java | 8 ++++---- .../convertors/VersionConvertor_14_30.java | 8 ++++---- .../convertors/VersionConvertor_14_40.java | 8 ++++---- .../convertors/VersionConvertor_14_50.java | 8 ++++---- .../convertors/VersionConvertor_30_50.java | 20 +++++++++---------- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_10_40.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_10_40.java index 4db50132b..d4628df6e 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_10_40.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_10_40.java @@ -2479,8 +2479,6 @@ public class VersionConvertor_10_40 { return convertId((org.hl7.fhir.dstu2.model.IdType) src); if (src instanceof org.hl7.fhir.dstu2.model.InstantType) return convertInstant((org.hl7.fhir.dstu2.model.InstantType) src); - if (src instanceof org.hl7.fhir.dstu2.model.IntegerType) - return convertInteger((org.hl7.fhir.dstu2.model.IntegerType) src); if (src instanceof org.hl7.fhir.dstu2.model.MarkdownType) return convertMarkdown((org.hl7.fhir.dstu2.model.MarkdownType) src); if (src instanceof org.hl7.fhir.dstu2.model.OidType) @@ -2493,6 +2491,8 @@ public class VersionConvertor_10_40 { return convertTime((org.hl7.fhir.dstu2.model.TimeType) src); if (src instanceof org.hl7.fhir.dstu2.model.UnsignedIntType) return convertUnsignedInt((org.hl7.fhir.dstu2.model.UnsignedIntType) src); + if (src instanceof org.hl7.fhir.dstu2.model.IntegerType) + return convertInteger((org.hl7.fhir.dstu2.model.IntegerType) src); if (src instanceof org.hl7.fhir.dstu2.model.UriType) return convertUri((org.hl7.fhir.dstu2.model.UriType) src); if (src instanceof org.hl7.fhir.dstu2.model.UuidType) @@ -2569,8 +2569,6 @@ public class VersionConvertor_10_40 { return convertId((org.hl7.fhir.r4.model.IdType) src); if (src instanceof org.hl7.fhir.r4.model.InstantType) return convertInstant((org.hl7.fhir.r4.model.InstantType) src); - if (src instanceof org.hl7.fhir.r4.model.IntegerType) - return convertInteger((org.hl7.fhir.r4.model.IntegerType) src); if (src instanceof org.hl7.fhir.r4.model.MarkdownType) return convertMarkdown((org.hl7.fhir.r4.model.MarkdownType) src); if (src instanceof org.hl7.fhir.r4.model.OidType) @@ -2583,6 +2581,8 @@ public class VersionConvertor_10_40 { return convertTime((org.hl7.fhir.r4.model.TimeType) src); if (src instanceof org.hl7.fhir.r4.model.UnsignedIntType) return convertUnsignedInt((org.hl7.fhir.r4.model.UnsignedIntType) src); + if (src instanceof org.hl7.fhir.r4.model.IntegerType) + return convertInteger((org.hl7.fhir.r4.model.IntegerType) src); if (src instanceof org.hl7.fhir.r4.model.UriType) return convertUri((org.hl7.fhir.r4.model.UriType) src); if (src instanceof org.hl7.fhir.r4.model.UuidType) diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_10_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_10_50.java index 3903d68bf..16f419902 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_10_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_10_50.java @@ -2503,8 +2503,6 @@ public class VersionConvertor_10_50 { return convertId((org.hl7.fhir.dstu2.model.IdType) src); if (src instanceof org.hl7.fhir.dstu2.model.InstantType) return convertInstant((org.hl7.fhir.dstu2.model.InstantType) src); - if (src instanceof org.hl7.fhir.dstu2.model.IntegerType) - return convertInteger((org.hl7.fhir.dstu2.model.IntegerType) src); if (src instanceof org.hl7.fhir.dstu2.model.MarkdownType) return convertMarkdown((org.hl7.fhir.dstu2.model.MarkdownType) src); if (src instanceof org.hl7.fhir.dstu2.model.OidType) @@ -2517,6 +2515,8 @@ public class VersionConvertor_10_50 { return convertTime((org.hl7.fhir.dstu2.model.TimeType) src); if (src instanceof org.hl7.fhir.dstu2.model.UnsignedIntType) return convertUnsignedInt((org.hl7.fhir.dstu2.model.UnsignedIntType) src); + if (src instanceof org.hl7.fhir.dstu2.model.IntegerType) + return convertInteger((org.hl7.fhir.dstu2.model.IntegerType) src); if (src instanceof org.hl7.fhir.dstu2.model.UriType) return convertUri((org.hl7.fhir.dstu2.model.UriType) src); if (src instanceof org.hl7.fhir.dstu2.model.UuidType) @@ -2593,8 +2593,6 @@ public class VersionConvertor_10_50 { return convertId((org.hl7.fhir.r5.model.IdType) src); if (src instanceof org.hl7.fhir.r5.model.InstantType) return convertInstant((org.hl7.fhir.r5.model.InstantType) src); - if (src instanceof org.hl7.fhir.r5.model.IntegerType) - return convertInteger((org.hl7.fhir.r5.model.IntegerType) src); if (src instanceof org.hl7.fhir.r5.model.MarkdownType) return convertMarkdown((org.hl7.fhir.r5.model.MarkdownType) src); if (src instanceof org.hl7.fhir.r5.model.OidType) @@ -2607,6 +2605,8 @@ public class VersionConvertor_10_50 { return convertTime((org.hl7.fhir.r5.model.TimeType) src); if (src instanceof org.hl7.fhir.r5.model.UnsignedIntType) return convertUnsignedInt((org.hl7.fhir.r5.model.UnsignedIntType) src); + if (src instanceof org.hl7.fhir.r5.model.IntegerType) + return convertInteger((org.hl7.fhir.r5.model.IntegerType) src); if (src instanceof org.hl7.fhir.r5.model.UriType) return convertUri((org.hl7.fhir.r5.model.UriType) src); if (src instanceof org.hl7.fhir.r5.model.UuidType) diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_14_30.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_14_30.java index 02f5bf909..a6170f876 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_14_30.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_14_30.java @@ -2454,8 +2454,6 @@ public class VersionConvertor_14_30 { return convertId((org.hl7.fhir.dstu2016may.model.IdType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.InstantType) return convertInstant((org.hl7.fhir.dstu2016may.model.InstantType) src); - if (src instanceof org.hl7.fhir.dstu2016may.model.IntegerType) - return convertInteger((org.hl7.fhir.dstu2016may.model.IntegerType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.MarkdownType) return convertMarkdown((org.hl7.fhir.dstu2016may.model.MarkdownType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.OidType) @@ -2468,6 +2466,8 @@ public class VersionConvertor_14_30 { return convertTime((org.hl7.fhir.dstu2016may.model.TimeType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.UnsignedIntType) return convertUnsignedInt((org.hl7.fhir.dstu2016may.model.UnsignedIntType) src); + if (src instanceof org.hl7.fhir.dstu2016may.model.IntegerType) + return convertInteger((org.hl7.fhir.dstu2016may.model.IntegerType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.UriType) return convertUri((org.hl7.fhir.dstu2016may.model.UriType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.UuidType) @@ -2544,8 +2544,6 @@ public class VersionConvertor_14_30 { return convertId((org.hl7.fhir.dstu3.model.IdType) src); if (src instanceof org.hl7.fhir.dstu3.model.InstantType) return convertInstant((org.hl7.fhir.dstu3.model.InstantType) src); - if (src instanceof org.hl7.fhir.dstu3.model.IntegerType) - return convertInteger((org.hl7.fhir.dstu3.model.IntegerType) src); if (src instanceof org.hl7.fhir.dstu3.model.MarkdownType) return convertMarkdown((org.hl7.fhir.dstu3.model.MarkdownType) src); if (src instanceof org.hl7.fhir.dstu3.model.OidType) @@ -2558,6 +2556,8 @@ public class VersionConvertor_14_30 { return convertTime((org.hl7.fhir.dstu3.model.TimeType) src); if (src instanceof org.hl7.fhir.dstu3.model.UnsignedIntType) return convertUnsignedInt((org.hl7.fhir.dstu3.model.UnsignedIntType) src); + if (src instanceof org.hl7.fhir.dstu3.model.IntegerType) + return convertInteger((org.hl7.fhir.dstu3.model.IntegerType) src); if (src instanceof org.hl7.fhir.dstu3.model.UriType) return convertUri((org.hl7.fhir.dstu3.model.UriType) src); if (src instanceof org.hl7.fhir.dstu3.model.UuidType) diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_14_40.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_14_40.java index e90801926..96b92e16c 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_14_40.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_14_40.java @@ -2607,8 +2607,6 @@ public class VersionConvertor_14_40 { return convertId((org.hl7.fhir.dstu2016may.model.IdType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.InstantType) return convertInstant((org.hl7.fhir.dstu2016may.model.InstantType) src); - if (src instanceof org.hl7.fhir.dstu2016may.model.IntegerType) - return convertInteger((org.hl7.fhir.dstu2016may.model.IntegerType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.MarkdownType) return convertMarkdown((org.hl7.fhir.dstu2016may.model.MarkdownType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.OidType) @@ -2621,6 +2619,8 @@ public class VersionConvertor_14_40 { return convertTime((org.hl7.fhir.dstu2016may.model.TimeType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.UnsignedIntType) return convertUnsignedInt((org.hl7.fhir.dstu2016may.model.UnsignedIntType) src); + if (src instanceof org.hl7.fhir.dstu2016may.model.IntegerType) + return convertInteger((org.hl7.fhir.dstu2016may.model.IntegerType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.UriType) return convertUri((org.hl7.fhir.dstu2016may.model.UriType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.UuidType) @@ -2695,8 +2695,6 @@ public class VersionConvertor_14_40 { return convertId((org.hl7.fhir.r4.model.IdType) src); if (src instanceof org.hl7.fhir.r4.model.InstantType) return convertInstant((org.hl7.fhir.r4.model.InstantType) src); - if (src instanceof org.hl7.fhir.r4.model.IntegerType) - return convertInteger((org.hl7.fhir.r4.model.IntegerType) src); if (src instanceof org.hl7.fhir.r4.model.MarkdownType) return convertMarkdown((org.hl7.fhir.r4.model.MarkdownType) src); if (src instanceof org.hl7.fhir.r4.model.OidType) @@ -2709,6 +2707,8 @@ public class VersionConvertor_14_40 { return convertTime((org.hl7.fhir.r4.model.TimeType) src); if (src instanceof org.hl7.fhir.r4.model.UnsignedIntType) return convertUnsignedInt((org.hl7.fhir.r4.model.UnsignedIntType) src); + if (src instanceof org.hl7.fhir.r4.model.IntegerType) + return convertInteger((org.hl7.fhir.r4.model.IntegerType) src); if (src instanceof org.hl7.fhir.r4.model.UriType) return convertUri((org.hl7.fhir.r4.model.UriType) src); if (src instanceof org.hl7.fhir.r4.model.UuidType) diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_14_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_14_50.java index 878f56233..d0ad44110 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_14_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_14_50.java @@ -2614,8 +2614,6 @@ public class VersionConvertor_14_50 { return convertId((org.hl7.fhir.dstu2016may.model.IdType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.InstantType) return convertInstant((org.hl7.fhir.dstu2016may.model.InstantType) src); - if (src instanceof org.hl7.fhir.dstu2016may.model.IntegerType) - return convertInteger((org.hl7.fhir.dstu2016may.model.IntegerType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.MarkdownType) return convertMarkdown((org.hl7.fhir.dstu2016may.model.MarkdownType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.OidType) @@ -2628,6 +2626,8 @@ public class VersionConvertor_14_50 { return convertTime((org.hl7.fhir.dstu2016may.model.TimeType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.UnsignedIntType) return convertUnsignedInt((org.hl7.fhir.dstu2016may.model.UnsignedIntType) src); + if (src instanceof org.hl7.fhir.dstu2016may.model.IntegerType) + return convertInteger((org.hl7.fhir.dstu2016may.model.IntegerType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.UriType) return convertUri((org.hl7.fhir.dstu2016may.model.UriType) src); if (src instanceof org.hl7.fhir.dstu2016may.model.UuidType) @@ -2702,8 +2702,6 @@ public class VersionConvertor_14_50 { return convertId((org.hl7.fhir.r5.model.IdType) src); if (src instanceof org.hl7.fhir.r5.model.InstantType) return convertInstant((org.hl7.fhir.r5.model.InstantType) src); - if (src instanceof org.hl7.fhir.r5.model.IntegerType) - return convertInteger((org.hl7.fhir.r5.model.IntegerType) src); if (src instanceof org.hl7.fhir.r5.model.MarkdownType) return convertMarkdown((org.hl7.fhir.r5.model.MarkdownType) src); if (src instanceof org.hl7.fhir.r5.model.OidType) @@ -2716,6 +2714,8 @@ public class VersionConvertor_14_50 { return convertTime((org.hl7.fhir.r5.model.TimeType) src); if (src instanceof org.hl7.fhir.r5.model.UnsignedIntType) return convertUnsignedInt((org.hl7.fhir.r5.model.UnsignedIntType) src); + if (src instanceof org.hl7.fhir.r5.model.IntegerType) + return convertInteger((org.hl7.fhir.r5.model.IntegerType) src); if (src instanceof org.hl7.fhir.r5.model.UriType) return convertUri((org.hl7.fhir.r5.model.UriType) src); if (src instanceof org.hl7.fhir.r5.model.UuidType) diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_30_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_30_50.java index fedf56bb1..7097f9fdd 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_30_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_30_50.java @@ -3498,20 +3498,20 @@ public class VersionConvertor_30_50 { return convertId((org.hl7.fhir.dstu3.model.IdType) src); if (src instanceof org.hl7.fhir.dstu3.model.InstantType) return convertInstant((org.hl7.fhir.dstu3.model.InstantType) src); + if (src instanceof org.hl7.fhir.dstu3.model.PositiveIntType) + return convertPositiveInt((org.hl7.fhir.dstu3.model.PositiveIntType) src); + if (src instanceof org.hl7.fhir.dstu3.model.UnsignedIntType) + return convertUnsignedInt((org.hl7.fhir.dstu3.model.UnsignedIntType) src); if (src instanceof org.hl7.fhir.dstu3.model.IntegerType) return convertInteger((org.hl7.fhir.dstu3.model.IntegerType) src); if (src instanceof org.hl7.fhir.dstu3.model.MarkdownType) return convertMarkdown((org.hl7.fhir.dstu3.model.MarkdownType) src); if (src instanceof org.hl7.fhir.dstu3.model.OidType) return convertOid((org.hl7.fhir.dstu3.model.OidType) src); - if (src instanceof org.hl7.fhir.dstu3.model.PositiveIntType) - return convertPositiveInt((org.hl7.fhir.dstu3.model.PositiveIntType) src); if (src instanceof org.hl7.fhir.dstu3.model.StringType) return convertString((org.hl7.fhir.dstu3.model.StringType) src); if (src instanceof org.hl7.fhir.dstu3.model.TimeType) return convertTime((org.hl7.fhir.dstu3.model.TimeType) src); - if (src instanceof org.hl7.fhir.dstu3.model.UnsignedIntType) - return convertUnsignedInt((org.hl7.fhir.dstu3.model.UnsignedIntType) src); if (src instanceof org.hl7.fhir.dstu3.model.UriType) return convertUri((org.hl7.fhir.dstu3.model.UriType) src); if (src instanceof org.hl7.fhir.dstu3.model.UuidType) @@ -3604,22 +3604,22 @@ public class VersionConvertor_30_50 { return convertId((org.hl7.fhir.r5.model.IdType) src); if (src instanceof org.hl7.fhir.r5.model.InstantType) return convertInstant((org.hl7.fhir.r5.model.InstantType) src); - if (src instanceof org.hl7.fhir.r5.model.IntegerType) - return convertInteger((org.hl7.fhir.r5.model.IntegerType) src); + if (src instanceof org.hl7.fhir.r5.model.PositiveIntType) + return convertPositiveInt((org.hl7.fhir.r5.model.PositiveIntType) src); + if (src instanceof org.hl7.fhir.r5.model.UnsignedIntType) + return convertUnsignedInt((org.hl7.fhir.r5.model.UnsignedIntType) src); if (src instanceof org.hl7.fhir.r5.model.Integer64Type) return convertInteger64((org.hl7.fhir.r5.model.Integer64Type) src); + if (src instanceof org.hl7.fhir.r5.model.IntegerType) + return convertInteger((org.hl7.fhir.r5.model.IntegerType) src); if (src instanceof org.hl7.fhir.r5.model.MarkdownType) return convertMarkdown((org.hl7.fhir.r5.model.MarkdownType) src); if (src instanceof org.hl7.fhir.r5.model.OidType) return convertOid((org.hl7.fhir.r5.model.OidType) src); - if (src instanceof org.hl7.fhir.r5.model.PositiveIntType) - return convertPositiveInt((org.hl7.fhir.r5.model.PositiveIntType) src); if (src instanceof org.hl7.fhir.r5.model.StringType) return convertString((org.hl7.fhir.r5.model.StringType) src); if (src instanceof org.hl7.fhir.r5.model.TimeType) return convertTime((org.hl7.fhir.r5.model.TimeType) src); - if (src instanceof org.hl7.fhir.r5.model.UnsignedIntType) - return convertUnsignedInt((org.hl7.fhir.r5.model.UnsignedIntType) src); if (src instanceof org.hl7.fhir.r5.model.UriType) return convertUri((org.hl7.fhir.r5.model.UriType) src); if (src instanceof org.hl7.fhir.r5.model.UuidType) From 2c22d8fa233cb2290d4973820bdf8547895f648c Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 5 Nov 2020 14:10:23 +1100 Subject: [PATCH 24/32] fix bug raising error when processing bundles --- .../main/java/org/hl7/fhir/r5/elementmodel/Element.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java index 1b14a2dea..73406ba26 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java @@ -75,15 +75,15 @@ public class Element extends Base { CONTAINED, BUNDLE_ENTRY, BUNDLE_OUTCOME, PARAMETER; public static SpecialElement fromProperty(Property property) { - if (property.getStructure().getIdElement().getIdPart().equals("Parameters")) + if (property.getStructure().getType().equals("Parameters")) return PARAMETER; - if (property.getStructure().getIdElement().getIdPart().equals("Bundle") && property.getName().equals("resource")) + if (property.getStructure().getType().equals("Bundle") && property.getName().equals("resource")) return BUNDLE_ENTRY; - if (property.getStructure().getIdElement().getIdPart().equals("Bundle") && property.getName().equals("outcome")) + if (property.getStructure().getType().equals("Bundle") && property.getName().equals("outcome")) return BUNDLE_OUTCOME; if (property.getName().equals("contained")) return CONTAINED; - throw new Error("Unknown resource containing a native resource: "+property.getDefinition().getId()); + throw new FHIRException("Unknown resource containing a native resource: "+property.getDefinition().getId()); } } From 49cf605b06c7b2dfb1124a6d1a580779f6aaa3f7 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 5 Nov 2020 14:11:18 +1100 Subject: [PATCH 25/32] don't use prism for big binaries when rendering library --- .../java/org/hl7/fhir/r5/renderers/LibraryRenderer.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/LibraryRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/LibraryRenderer.java index 7173349a3..ecb0d1ccf 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/LibraryRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/LibraryRenderer.java @@ -401,7 +401,7 @@ public class LibraryRenderer extends ResourceRenderer { p.code().tx(att.getContentType()+lang(att)); } String prismCode = determinePrismCode(att); - if (prismCode != null) { + if (prismCode != null && !tooBig(txt)) { x.pre().code().setAttribute("class", "language-"+prismCode).tx(txt); } else { x.pre().code().tx(txt); @@ -420,6 +420,10 @@ public class LibraryRenderer extends ResourceRenderer { } } + private boolean tooBig(String txt) { + return txt.length() > 16384; + } + private String imgExtension(String contentType) { if (contentType != null && contentType.startsWith("image/")) { if (contentType.startsWith("image/png")) { From 01430d8d988888b1e07763c2322709d72b6a8307 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 5 Nov 2020 14:11:54 +1100 Subject: [PATCH 26/32] fix parameters renderer to create proper anchors --- .../org/hl7/fhir/r5/renderers/ParametersRenderer.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ParametersRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ParametersRenderer.java index d6fcf528e..571e7fa57 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ParametersRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ParametersRenderer.java @@ -118,8 +118,13 @@ public class ParametersRenderer extends ResourceRenderer { if (p.hasValue()) { render(tr.td(), p.getValue()); } else if (p.hasResource()) { - ResourceRenderer rr = RendererFactory.factory(p.getResource(), context); - rr.render(tr.td(), p.getResource()); + Resource r = p.getResource(); + td = tr.td(); + XhtmlNode para = td.para(); + para.tx(r.fhirType()+"/"+r.getId()); + para.an(r.fhirType()+"_"+r.getId()).tx(" "); + ResourceRenderer rr = RendererFactory.factory(r, context); + rr.render(td, r); } else if (p.hasPart()) { tr.td(); params(tbl, p.getPart(), 1); From ca48cf7f79021f75ea9b240d997696b661e8d908 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 5 Nov 2020 14:12:57 +1100 Subject: [PATCH 27/32] * Don't render id/base/other properties of Resource itself in auto-narrative generator * fix bug where extension values not generated for simple extensions --- .../hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java | 1 + 1 file changed, 1 insertion(+) 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 985065479..23a23ec27 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 @@ -351,6 +351,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple System.out.println(); System.out.print(" Installing: "); } + if (npm.name() == null || id == null || !id.equals(npm.name())) { if (!id.equals("hl7.fhir.r5.core")) {// temporary work around throw new IOException("Attempt to import a mis-identified package. Expected " + id + ", got " + npm.name()); From e6cda402745c333ada7bd372756380c9eb02985f Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 5 Nov 2020 14:13:17 +1100 Subject: [PATCH 28/32] * Don't render id/base/other properties of Resource itself in auto-narrative generator * fix bug where extension values not generated for simple extensions --- .../org/hl7/fhir/r5/renderers/ProfileDrivenRenderer.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ProfileDrivenRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ProfileDrivenRenderer.java index 155e8bbc0..12235debe 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ProfileDrivenRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ProfileDrivenRenderer.java @@ -651,7 +651,9 @@ public class ProfileDrivenRenderer extends ResourceRenderer { child = p.getElementDefinition(); } if (child != null) { - generateElementByProfile(res, profile, allElements, x, path, showCodeDetails, indent, p, child); + if (!child.getBase().hasPath() || !child.getBase().getPath().startsWith("Resource.")) { + generateElementByProfile(res, profile, allElements, x, path, showCodeDetails, indent, p, child); + } } } } @@ -721,7 +723,7 @@ public class ProfileDrivenRenderer extends ResourceRenderer { XhtmlNode para = x.para(); para.b().addText(p.getStructure().present()); para.tx(": "); - renderLeaf(res, v, child, x, para, false, showCodeDetails, displayHints, path, indent); + renderLeaf(res, vv, child, x, para, false, showCodeDetails, displayHints, path, indent); } else if (ev.hasValues()) { XhtmlNode bq = x.addTag("blockquote"); bq.para().b().addText(isExtension(p) ? p.getStructure().present() : p.getName()); From 6626b72b4fcafbd49893392ad3cf2d65d65c787d Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 5 Nov 2020 14:13:50 +1100 Subject: [PATCH 29/32] * fix bug rendering content references in profiles --- .../fhir/r5/conformance/ProfileUtilities.java | 60 +++++++++++++++---- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java index 7155da406..bc59a1e1f 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java @@ -3219,12 +3219,17 @@ public class ProfileUtilities extends TranslatingUtilities { Cell c = gen.new Cell(); r.getCells().add(c); if (e.hasContentReference()) { - ElementDefinition ed = getElementByName(profile.getSnapshot().getElement(), e.getContentReference()); + ElementInStructure ed = getElementByName(profile.getSnapshot().getElement(), e.getContentReference(), profile); if (ed == null) c.getPieces().add(gen.new Piece(null, translate("sd.table", "Unknown reference to %s", e.getContentReference()), null)); else { - c.getPieces().add(gen.new Piece(null, translate("sd.table", "See ", ed.getPath()), null)); - c.getPieces().add(gen.new Piece("#"+ed.getPath(), tail(ed.getPath()), ed.getPath())); + if (ed.getSource() == profile) { + c.getPieces().add(gen.new Piece(null, translate("sd.table", "See ", ed.getElement().getPath()), null)); + c.getPieces().add(gen.new Piece("#"+ed.getElement().getPath(), tail(ed.getElement().getPath()), ed.getElement().getPath())); + } else { + c.getPieces().add(gen.new Piece(null, translate("sd.table", "See ", ed.getElement().getPath()), null)); + c.getPieces().add(gen.new Piece(ed.getSource().getUserString("path")+"#"+ed.getElement().getPath(), tail(ed.getElement().getPath())+" ("+ed.getSource().getType()+")", ed.getElement().getPath())); + } } return c; } @@ -3409,16 +3414,46 @@ public class ProfileUtilities extends TranslatingUtilities { } - private ElementDefinition getElementByName(List elements, String contentReference) { + private class ElementInStructure { + + private StructureDefinition source; + private ElementDefinition element; + + public ElementInStructure(StructureDefinition source, ElementDefinition ed) { + this.source = source; + this.element = ed; + } + + public StructureDefinition getSource() { + return source; + } + + public ElementDefinition getElement() { + return element; + } + + } + private ElementInStructure getElementByName(List elements, String contentReference, StructureDefinition source) { + if (contentReference.contains("#")) { + String url = contentReference.substring(0, contentReference.indexOf("#")); + contentReference = contentReference.substring(contentReference.indexOf("#")); + if (!url.equals(source.getUrl())) { + source = context.fetchResource(StructureDefinition.class, url); + if (source == null) { + throw new FHIRException("Unable to resolve StructureDefinition "+url+" resolving content reference "+contentReference); + } + elements = source.getSnapshot().getElement(); + } + } for (ElementDefinition ed : elements) { if (("#"+ed.getPath()).equals(contentReference)) { - return ed; + return new ElementInStructure(source, ed); } if (("#"+ed.getId()).equals(contentReference)) { - return ed; + return new ElementInStructure(source, ed); } } - throw new Error("getElementByName: can't find "+contentReference+"in "+elements.toString()); + throw new Error("getElementByName: can't find "+contentReference+" in "+elements.toString()+" from "+source.getUrl()); // return null; } @@ -4575,11 +4610,16 @@ public class ProfileUtilities extends TranslatingUtilities { if (used) { if (definition.hasContentReference()) { - ElementDefinition ed = getElementByName(profile.getSnapshot().getElement(), definition.getContentReference()); + ElementInStructure ed = getElementByName(profile.getSnapshot().getElement(), definition.getContentReference(), profile); if (ed == null) c.getPieces().add(gen.new Piece(null, "Unknown reference to "+definition.getContentReference(), null)); - else - c.getPieces().add(gen.new Piece("#"+ed.getPath(), "See "+ed.getPath(), null)); + else { + if (ed.getSource() == profile) { + c.getPieces().add(gen.new Piece("#"+ed.getElement().getPath(), "See "+ed.getElement().getPath(), null)); + } else { + c.getPieces().add(gen.new Piece(ed.getSource().getUserData("path")+"#"+ed.getElement().getPath(), "See "+ed.getSource().getType()+"."+ed.getElement().getPath(), null)); + } + } } if (definition.getPath().endsWith("url") && definition.hasFixed()) { c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, "\""+buildJson(definition.getFixed())+"\"", null).addStyle("color: darkgreen"))); From 581799d01c242364b915f1b34177af3aa482b218 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 5 Nov 2020 14:56:30 +1100 Subject: [PATCH 30/32] update test case dependency --- RELEASE_NOTES.md | 11 +++++++++++ pom.xml | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e69de29bb..007ac857a 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -0,0 +1,11 @@ +Validator changes: +* (none) + +other code changes: +* fix bug when converting positiveInt between versions +* fix bug raising error when processing bundles +* don't use prism for big binaries when rendering library +* fix parameters renderer to create proper anchors +* Don't render id/base/other properties of Resource itself in auto-narrative generator +* fix bug where extension values not generated for simple extensions +* fix bug rendering content references in profiles diff --git a/pom.xml b/pom.xml index 65e45ff81..1297ec418 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 5.1.0 - 1.1.47 + 1.1.48-SNAPSHOT 5.6.2 3.0.0-M4 0.8.5 From 05056e643e5bcd4835b1fcf29ff71267e5d08e7f Mon Sep 17 00:00:00 2001 From: markiantorno Date: Thu, 5 Nov 2020 05:11:22 +0000 Subject: [PATCH 31/32] Release: v5.1.20 Validator changes: * (none) other code changes: * fix bug when converting positiveInt between versions * fix bug raising error when processing bundles * don't use prism for big binaries when rendering library * fix parameters renderer to create proper anchors * Don't render id/base/other properties of Resource itself in auto-narrative generator * fix bug where extension values not generated for simple extensions * fix bug rendering content references in profiles ***NO_CI*** --- org.hl7.fhir.convertors/pom.xml | 2 +- org.hl7.fhir.dstu2/pom.xml | 2 +- org.hl7.fhir.dstu2016may/pom.xml | 2 +- org.hl7.fhir.dstu3/pom.xml | 2 +- org.hl7.fhir.r4/pom.xml | 2 +- org.hl7.fhir.r5/pom.xml | 2 +- org.hl7.fhir.report/pom.xml | 2 +- org.hl7.fhir.utilities/pom.xml | 2 +- org.hl7.fhir.validation.cli/pom.xml | 2 +- org.hl7.fhir.validation/pom.xml | 2 +- pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/org.hl7.fhir.convertors/pom.xml b/org.hl7.fhir.convertors/pom.xml index 7f66e4254..91d1bb766 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 - 5.1.20-SNAPSHOT + 5.1.20 ../pom.xml diff --git a/org.hl7.fhir.dstu2/pom.xml b/org.hl7.fhir.dstu2/pom.xml index db6b64e6b..8a6f61054 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 - 5.1.20-SNAPSHOT + 5.1.20 ../pom.xml diff --git a/org.hl7.fhir.dstu2016may/pom.xml b/org.hl7.fhir.dstu2016may/pom.xml index 0cc20b537..456c2daa8 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 - 5.1.20-SNAPSHOT + 5.1.20 ../pom.xml diff --git a/org.hl7.fhir.dstu3/pom.xml b/org.hl7.fhir.dstu3/pom.xml index f70a3f4e1..6ace225c3 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 - 5.1.20-SNAPSHOT + 5.1.20 ../pom.xml diff --git a/org.hl7.fhir.r4/pom.xml b/org.hl7.fhir.r4/pom.xml index aed4d0220..e750f415a 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 - 5.1.20-SNAPSHOT + 5.1.20 ../pom.xml diff --git a/org.hl7.fhir.r5/pom.xml b/org.hl7.fhir.r5/pom.xml index faf68ef5e..a96750963 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 - 5.1.20-SNAPSHOT + 5.1.20 ../pom.xml diff --git a/org.hl7.fhir.report/pom.xml b/org.hl7.fhir.report/pom.xml index b512f6731..eca8eb2a6 100644 --- a/org.hl7.fhir.report/pom.xml +++ b/org.hl7.fhir.report/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 5.1.20-SNAPSHOT + 5.1.20 ../pom.xml diff --git a/org.hl7.fhir.utilities/pom.xml b/org.hl7.fhir.utilities/pom.xml index dac95044f..d5e1b87dd 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 - 5.1.20-SNAPSHOT + 5.1.20 ../pom.xml diff --git a/org.hl7.fhir.validation.cli/pom.xml b/org.hl7.fhir.validation.cli/pom.xml index 6b756a56c..7727cb7e8 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 - 5.1.20-SNAPSHOT + 5.1.20 ../pom.xml diff --git a/org.hl7.fhir.validation/pom.xml b/org.hl7.fhir.validation/pom.xml index ccf014753..bc0bd3785 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 - 5.1.20-SNAPSHOT + 5.1.20 ../pom.xml diff --git a/pom.xml b/pom.xml index 1297ec418..dad1a8526 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ HAPI FHIR. --> org.hl7.fhir.core - 5.1.20-SNAPSHOT + 5.1.20 pom From 1db9a028bf0abdc4263d2c8edd0ecdf7314b2632 Mon Sep 17 00:00:00 2001 From: markiantorno Date: Thu, 5 Nov 2020 05:40:28 +0000 Subject: [PATCH 32/32] Updating version to: 5.1.21-SNAPSHOT and incrementing test cases dependency. --- RELEASE_NOTES.md | 11 ----------- org.hl7.fhir.convertors/pom.xml | 2 +- org.hl7.fhir.dstu2/pom.xml | 2 +- org.hl7.fhir.dstu2016may/pom.xml | 2 +- org.hl7.fhir.dstu3/pom.xml | 2 +- org.hl7.fhir.r4/pom.xml | 2 +- org.hl7.fhir.r5/pom.xml | 2 +- org.hl7.fhir.report/pom.xml | 2 +- org.hl7.fhir.utilities/pom.xml | 2 +- org.hl7.fhir.validation.cli/pom.xml | 2 +- org.hl7.fhir.validation/pom.xml | 2 +- pom.xml | 2 +- 12 files changed, 11 insertions(+), 22 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 007ac857a..e69de29bb 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,11 +0,0 @@ -Validator changes: -* (none) - -other code changes: -* fix bug when converting positiveInt between versions -* fix bug raising error when processing bundles -* don't use prism for big binaries when rendering library -* fix parameters renderer to create proper anchors -* Don't render id/base/other properties of Resource itself in auto-narrative generator -* fix bug where extension values not generated for simple extensions -* fix bug rendering content references in profiles diff --git a/org.hl7.fhir.convertors/pom.xml b/org.hl7.fhir.convertors/pom.xml index 91d1bb766..d1d3cd7f8 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 - 5.1.20 + 5.1.21-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu2/pom.xml b/org.hl7.fhir.dstu2/pom.xml index 8a6f61054..50bf1db0d 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 - 5.1.20 + 5.1.21-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu2016may/pom.xml b/org.hl7.fhir.dstu2016may/pom.xml index 456c2daa8..cb520f546 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 - 5.1.20 + 5.1.21-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu3/pom.xml b/org.hl7.fhir.dstu3/pom.xml index 6ace225c3..da94f2fe6 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 - 5.1.20 + 5.1.21-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r4/pom.xml b/org.hl7.fhir.r4/pom.xml index e750f415a..dde7ecaa6 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 - 5.1.20 + 5.1.21-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r5/pom.xml b/org.hl7.fhir.r5/pom.xml index a96750963..99fc53216 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 - 5.1.20 + 5.1.21-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.report/pom.xml b/org.hl7.fhir.report/pom.xml index eca8eb2a6..fa7b2b286 100644 --- a/org.hl7.fhir.report/pom.xml +++ b/org.hl7.fhir.report/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 5.1.20 + 5.1.21-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.utilities/pom.xml b/org.hl7.fhir.utilities/pom.xml index d5e1b87dd..d6da0d28c 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 - 5.1.20 + 5.1.21-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.validation.cli/pom.xml b/org.hl7.fhir.validation.cli/pom.xml index 7727cb7e8..849541b16 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 - 5.1.20 + 5.1.21-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.validation/pom.xml b/org.hl7.fhir.validation/pom.xml index bc0bd3785..7ad6a3959 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 - 5.1.20 + 5.1.21-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index dad1a8526..c1c73023a 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ HAPI FHIR. --> org.hl7.fhir.core - 5.1.20 + 5.1.21-SNAPSHOT pom
FilenameErrorsWarningsHints
"+Utilities.escapeXml(rec.getLocation())+""+rec.getErr()+""+rec.getWarn()+""+rec.getInfo()+"
"+path+""+level+""+msg+" Show Reasoning

 

"+msgdetails+"
"+path+""+level+""+msg+"