diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/UTGVersionSorter.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/UTGVersionSorter.java new file mode 100644 index 000000000..8dfa13310 --- /dev/null +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/UTGVersionSorter.java @@ -0,0 +1,210 @@ +package org.hl7.fhir.convertors.misc; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URISyntaxException; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.hl7.fhir.convertors.VersionConvertor_10_50; +import org.hl7.fhir.convertors.VersionConvertor_30_50; +import org.hl7.fhir.convertors.VersionConvertor_40_50; +import org.hl7.fhir.r5.model.Base; +import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.r5.formats.JsonParser; +import org.hl7.fhir.r5.formats.XmlParser; +import org.hl7.fhir.r5.model.CanonicalResource; +import org.hl7.fhir.r5.model.CodeSystem; +import org.hl7.fhir.r5.model.Resource; +import org.hl7.fhir.r5.model.ValueSet; +import org.hl7.fhir.r5.utils.ToolingExtensions; +import org.hl7.fhir.utilities.Utilities; +import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; +import org.hl7.fhir.utilities.npm.NpmPackage; +import org.hl7.fhir.utilities.npm.NpmPackage.PackageResourceInformation; +import org.hl7.fhir.utilities.npm.ToolsVersion; + +public class UTGVersionSorter { + + private FilesystemPackageCacheManager pcm; + + public class CanonicalResourceAnalysis { + + private CanonicalResource resource; + private CanonicalResource r2; + private CanonicalResource r3; + private CanonicalResource r4; + private String fmm; + private boolean normative; + private String recommendation; + + public CanonicalResourceAnalysis(CanonicalResource cr) { + this.resource = cr; + } + + public String summary() { +// return "Relevant: "+resource.getUrl()+" [r2: "+r2Ver+"/"+r2Fmm+"]"+" [r3: "+r3Ver+"/"+r3Fmm+"]"+" [r4: "+r4Ver+"/"+r4Fmm+"/"+r4Normative+"] ---> "+recommendation; + return resource.getUrl()+" ---> "+recommendation; + } + + public void analyse(Map r2l, Map r3l, Map r4l) { + r2 = findMatch(r2l); + r3 = findMatch(r3l); + r4 = findMatch(r4l); + + fmm = r4 != null ? ToolingExtensions.readStringExtension(r4, ToolingExtensions.EXT_FMM_LEVEL) : null; + normative = (r4 != null) && ToolingExtensions.readStringExtension(r4, ToolingExtensions.EXT_NORMATIVE_VERSION) != null; + if (normative) { + recommendation = "1.0.0"; + } else if (Utilities.existsInList(fmm,"3", "4", "5")) { + recommendation = "0.5.0"; + } else { + int i = 1; + if (r2 != null && r3 != null && !match(r2, r3, r2l, r3l)) { + i++; + } + if (r3 != null && r4 != null && !match(r3, r4, r3l, r4l)) { + i++; + } + recommendation = "0."+i+".0"; + } + } + + private boolean match(CanonicalResource l, CanonicalResource r, Map ll, Map rl) { + if (l instanceof CodeSystem && r instanceof CodeSystem) { + return matchCS((CodeSystem) l, (CodeSystem) r); + } else if (l instanceof ValueSet && r instanceof ValueSet) { + return matchVS((ValueSet) l, (ValueSet) r, ll, rl); + } else { + return false; + } + } + + private boolean matchVS(ValueSet l, ValueSet r, Map ll, Map rl) { + if (l.getCompose().getInclude().size() == 1 && l.getCompose().getExclude().isEmpty() && l.getCompose().getIncludeFirstRep().hasSystem() && !l.getCompose().getIncludeFirstRep().hasConcept() && !l.getCompose().getIncludeFirstRep().hasFilter() && + r.getCompose().getInclude().size() == 1 && r.getCompose().getExclude().isEmpty() && r.getCompose().getIncludeFirstRep().hasSystem() && !r.getCompose().getIncludeFirstRep().hasConcept() && !r.getCompose().getIncludeFirstRep().hasFilter()) { + CodeSystem lc = (CodeSystem) ll.get(l.getCompose().getIncludeFirstRep().getSystem()); + CodeSystem rc = (CodeSystem) rl.get(l.getCompose().getIncludeFirstRep().getSystem()); + if (lc != null && rc != null) { + return matchCS(lc, rc); + } + } + return false; + } + + private boolean matchCS(CodeSystem l, CodeSystem r) { + return Base.compareDeep(l.getConcept(), r.getConcept(), false); + } + + public CanonicalResource findMatch(Map r2) { + CanonicalResource r = r2.get(resource.getUrl()); + if (r == null) { + r = r2.get(resource.getUrl().replaceAll("http://terminology.hl7.org/", "http://hl7.org/fhir/")); + } + if (r == null) { + r = r2.get(resource.getUrl().replaceAll("http://terminology.hl7.org/CodeSystem", "http://hl7.org/fhir/")); + } + return r; + } + + } + + public static void main(String[] args) throws FileNotFoundException, FHIRException, IOException, ParseException, URISyntaxException { + new UTGVersionSorter().execute("C:\\work\\org.hl7.fhir.igs\\UTG\\input\\sourceOfTruth"); + } + + private void execute(String source) throws IOException { + List list = new ArrayList<>(); + System.out.println("Loading UTG"); + loadFromSource(list, new File(source)); + + Map r2 = loadPackageR2("hl7.fhir.r2.core"); + Map r3 = loadPackageR3("hl7.fhir.r3.core"); + Map r4 = loadPackageR4("hl7.fhir.r4.core"); + + System.out.println("Processing"); + for (CanonicalResourceAnalysis cr : list) { + cr.analyse(r2,r3,r4); + } + + System.out.println("Summary"); + for (CanonicalResourceAnalysis cr : list) { + System.out.println(cr.summary()); + } + System.out.println(); + System.out.println("Done"); + } + + private Map loadPackageR2(String id) throws IOException { + Mapres = new HashMap<>(); + if (pcm == null) { + pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION); + } + System.out.println("Load "+id); + NpmPackage npm = pcm.loadPackage(id); + for (PackageResourceInformation p : npm.listIndexedResources("CodeSystem", "ValueSet")) { + CanonicalResource r = (CanonicalResource) VersionConvertor_10_50.convertResource(new org.hl7.fhir.dstu2.formats.JsonParser().parse(npm.load(p))); + res.put(r.getUrl(), r); + } + return res; + } + + private Map loadPackageR3(String id) throws IOException { + Mapres = new HashMap<>(); + if (pcm == null) { + pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION); + } + System.out.println("Load "+id); + NpmPackage npm = pcm.loadPackage(id); + for (PackageResourceInformation p : npm.listIndexedResources("CodeSystem", "ValueSet")) { + CanonicalResource r = (CanonicalResource) VersionConvertor_30_50.convertResource(new org.hl7.fhir.dstu3.formats.JsonParser().parse(npm.load(p)), false); + res.put(r.getUrl(), r); + } + return res; + } + + private Map loadPackageR4(String id) throws IOException { + Mapres = new HashMap<>(); + if (pcm == null) { + pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION); + } + System.out.println("Load "+id); + NpmPackage npm = pcm.loadPackage(id); + for (PackageResourceInformation p : npm.listIndexedResources("CodeSystem", "ValueSet")) { + CanonicalResource r = (CanonicalResource) VersionConvertor_40_50.convertResource(new org.hl7.fhir.r4.formats.JsonParser().parse(npm.load(p))); + res.put(r.getUrl(), r); + } + return res; + } + + + private void loadFromSource(List list, File source) { + for (File f : source.listFiles()) { + if (f.isDirectory()) { + loadFromSource(list, f); + } else if (f.getName().endsWith(".xml")) { + try { + Resource r = new XmlParser().parse(new FileInputStream(f)); + if (r instanceof CanonicalResource) { + CanonicalResource cr = (CanonicalResource) r; + cr.setUserData("path", f.getAbsolutePath()); + if (cr.hasVersion() && cr.getVersion().startsWith("4.")) { + list.add(new CanonicalResourceAnalysis(cr)); + } + } + } catch (Exception e) { + System.out.println(f.getAbsolutePath()+" not a resource? "+e.getMessage()); + } + } + } + + } + + + +} diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java index 33fbd0dc2..a34f528e4 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java @@ -49,6 +49,7 @@ import org.apache.commons.lang3.StringUtils; import org.fhir.ucum.UcumService; import org.hl7.fhir.exceptions.DefinitionException; import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.exceptions.NoTerminologyServiceException; import org.hl7.fhir.exceptions.TerminologyServiceException; import org.hl7.fhir.r5.conformance.ProfileUtilities; import org.hl7.fhir.r5.context.CanonicalResourceManager.CanonicalResourceProxy; @@ -910,6 +911,9 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte txCache.cacheValidation(cacheToken, res, TerminologyCache.TRANSIENT); return res; } catch (Exception e) { + if (e instanceof NoTerminologyServiceException) { + return new ValidationResult(IssueSeverity.ERROR, "No Terminology Service", TerminologyServiceErrorClass.NOSERVICE); + } } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java index 87b8571f7..6f220ce9f 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java @@ -148,6 +148,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon private boolean ignoreProfileErrors; private boolean progress; private List loadedPackages = new ArrayList(); + private boolean canNoTS; public SimpleWorkerContext() throws FileNotFoundException, IOException, FHIRException { super(); @@ -299,7 +300,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon setTxCaps(txClient.getTerminologyCapabilities()); return cps.getSoftware().getVersion(); } catch (Exception e) { - throw new FHIRException(formatMessage(I18nConstants.UNABLE_TO_CONNECT_TO_TERMINOLOGY_SERVER_USE_PARAMETER_TX_NA_TUN_RUN_WITHOUT_USING_TERMINOLOGY_SERVICES_TO_VALIDATE_LOINC_SNOMED_ICDX_ETC_ERROR__, e.getMessage()), e); + throw new FHIRException(formatMessage(canNoTS ? I18nConstants.UNABLE_TO_CONNECT_TO_TERMINOLOGY_SERVER_USE_PARAMETER_TX_NA_TUN_RUN_WITHOUT_USING_TERMINOLOGY_SERVICES_TO_VALIDATE_LOINC_SNOMED_ICDX_ETC_ERROR__ : I18nConstants.UNABLE_TO_CONNECT_TO_TERMINOLOGY_SERVER, e.getMessage()), e); } } @@ -813,6 +814,15 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon public void setClock(TimeTracker tt) { clock = tt; - } + + public boolean isCanNoTS() { + return canNoTS; + } + + public void setCanNoTS(boolean canNoTS) { + this.canNoTS = canNoTS; + } + + } \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/CanonicalResource.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/CanonicalResource.java index a9c0caf61..c28dac081 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/CanonicalResource.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/CanonicalResource.java @@ -442,7 +442,8 @@ public abstract class CanonicalResource extends DomainResource { /** * @param value A copyright statement relating to the canonical resource and/or its contents. Copyright statements are generally legal restrictions on the use and publishing of the canonical resource. */ - public abstract CanonicalResource setCopyright(String value); + public abstract CanonicalResource setCopyright(String value); + protected void listChildren(List children) { super.listChildren(children); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/CodeType.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/CodeType.java index 25112fb5c..5c1d34656 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/CodeType.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/CodeType.java @@ -34,6 +34,7 @@ package org.hl7.fhir.r5.model; import static org.apache.commons.lang3.StringUtils.defaultString; import org.hl7.fhir.utilities.Utilities; +import org.hl7.fhir.utilities.xhtml.XhtmlNode; import ca.uhn.fhir.model.api.annotation.DatatypeDef; @@ -137,4 +138,5 @@ public class CodeType extends StringType implements Comparable, ICodin public boolean supportsDisplay() { return false; } + } \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/CompartmentDefinition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/CompartmentDefinition.java index 9e301f1a9..e37bee024 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/CompartmentDefinition.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/CompartmentDefinition.java @@ -2323,6 +2323,9 @@ public class CompartmentDefinition extends CanonicalResource { */ public static final ca.uhn.fhir.rest.gclient.TokenClientParam VERSION = new ca.uhn.fhir.rest.gclient.TokenClientParam(SP_VERSION); + public boolean supportsCopyright() { + return false; + } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/GraphDefinition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/GraphDefinition.java index 85c6c6c8b..b6e5bce8c 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/GraphDefinition.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/GraphDefinition.java @@ -3766,6 +3766,9 @@ public class GraphDefinition extends CanonicalResource { */ public static final ca.uhn.fhir.rest.gclient.TokenClientParam VERSION = new ca.uhn.fhir.rest.gclient.TokenClientParam(SP_VERSION); + public boolean supportsCopyright() { + return false; + } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/SearchParameter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/SearchParameter.java index 604addf74..d3e06c3f7 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/SearchParameter.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/SearchParameter.java @@ -3875,6 +3875,8 @@ public class SearchParameter extends CanonicalResource { */ public static final ca.uhn.fhir.rest.gclient.TokenClientParam VERSION = new ca.uhn.fhir.rest.gclient.TokenClientParam(SP_VERSION); - + public boolean supportsCopyright() { + return false; + } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/RendererFactory.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/RendererFactory.java index fef306984..98a8bacfa 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/RendererFactory.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/RendererFactory.java @@ -36,6 +36,9 @@ public class RendererFactory { if ("OperationDefinition".equals(resourceName)) { return new OperationDefinitionRenderer(context); } + if ("SearchParameter".equals(resourceName)) { + return new SearchParameterRenderer(context); + } if ("CompartmentDefinition".equals(resourceName)) { return new CompartmentDefinitionRenderer(context); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/SearchParameterRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/SearchParameterRenderer.java new file mode 100644 index 000000000..6c96a64a1 --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/SearchParameterRenderer.java @@ -0,0 +1,160 @@ +package org.hl7.fhir.r5.renderers; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +import org.hl7.fhir.exceptions.DefinitionException; +import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.exceptions.FHIRFormatError; +import org.hl7.fhir.r5.model.CodeType; +import org.hl7.fhir.r5.model.DomainResource; +import org.hl7.fhir.r5.model.Enumeration; +import org.hl7.fhir.r5.model.Extension; +import org.hl7.fhir.r5.model.OperationDefinition; +import org.hl7.fhir.r5.model.OperationDefinition.OperationDefinitionParameterComponent; +import org.hl7.fhir.r5.model.Resource; +import org.hl7.fhir.r5.model.SearchParameter; +import org.hl7.fhir.r5.model.SearchParameter.SearchComparator; +import org.hl7.fhir.r5.model.SearchParameter.SearchModifierCode; +import org.hl7.fhir.r5.model.SearchParameter.SearchParameterComponentComponent; +import org.hl7.fhir.r5.model.StringType; +import org.hl7.fhir.r5.model.StructureDefinition; +import org.hl7.fhir.r5.renderers.utils.RenderingContext; +import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext; +import org.hl7.fhir.r5.utils.EOperationOutcome; +import org.hl7.fhir.r5.utils.ToolingExtensions; +import org.hl7.fhir.utilities.Utilities; +import org.hl7.fhir.utilities.xhtml.XhtmlNode; + +public class SearchParameterRenderer extends TerminologyRenderer { + + public SearchParameterRenderer(RenderingContext context) { + super(context); + } + + public SearchParameterRenderer(RenderingContext context, ResourceContext rcontext) { + super(context, rcontext); + } + + public boolean render(XhtmlNode x, Resource dr) throws IOException, FHIRException, EOperationOutcome { + return render(x, (OperationDefinition) dr); + } + + public boolean render(XhtmlNode x, SearchParameter spd) throws IOException, FHIRException, EOperationOutcome { + x.h2().addText(spd.getName()); + XhtmlNode p = x.para(); + p.tx("Parameter "); + p.code().tx(spd.getCode()); + p.tx(":"); + p.code().tx(spd.getType().toCode()); + addMarkdown(x, spd.getDescription()); + + XhtmlNode tbl = x.table("grid"); + XhtmlNode tr = tbl.tr(); + tr.td().tx(Utilities.pluralize("Resource", spd.getBase().size())); + XhtmlNode td = tr.td(); + for (CodeType t : spd.getBase()) { + StructureDefinition sd = context.getWorker().fetchTypeDefinition(t.toString()); + if (sd != null && sd.hasUserData("path")) { + td.sep(", ").ah(sd.getUserString("path")).tx(t.getCode()); + } else { + td.sep(", ").tx(t.getCode()); + } + } + tr = tbl.tr(); + tr.td().tx("Expression"); + if (spd.hasExpression()) { + tr.td().code().tx(spd.getExpression()); + } else { + tr.td().tx("(none)"); + } + if (spd.hasXpathUsage()) { + tr = tbl.tr(); + tr.td().tx("Usage"); + tr.td().tx(spd.getXpathUsage().getDisplay()); + } + if (spd.hasXpath()) { + tr = tbl.tr(); + tr.td().tx("XPath"); + tr.td().code().tx(spd.getXpath()); + } + if (spd.hasTarget()) { + tr = tbl.tr(); + tr.td().tx(Utilities.pluralize("Target Resources", spd.getTarget().size())); + td = tr.td(); + for (CodeType t : spd.getTarget()) { + StructureDefinition sd = context.getWorker().fetchTypeDefinition(t.toString()); + if (sd != null && sd.hasUserData("path")) { + td.sep(", ").ah(sd.getUserString("path")).tx(t.getCode()); + } else { + td.sep(", ").tx(t.getCode()); + } + } + } + tr = tbl.tr(); + tr.td().tx("Multiples"); + if (spd.getMultipleAnd() && spd.getMultipleOr()) { + tr.td().tx("The parameter can repeat (and) and can have repeating values (or)"); + } else if (spd.getMultipleOr()) { + tr.td().tx("The parameter can repeat (and) but each repeat can only have one value"); + } else if (spd.getMultipleAnd()) { + tr.td().tx("The parameter cannot repeat (and) but the single parameter can have multiple values (or)"); + } else { + tr.td().tx("The parameter cannot repeat or have multiple values"); + } + if (spd.hasComparator()) { + tr = tbl.tr(); + tr.td().tx("Comparators"); + td = tr.td().tx("Allowed: "); + for (Enumeration t : spd.getComparator()) { + td.sep(", ").tx(t.asStringValue()); + } + } + if (spd.hasModifier()) { + tr = tbl.tr(); + tr.td().tx("Modifiers"); + td = tr.td().tx("Allowed: "); + for (Enumeration t : spd.getModifier()) { + td.sep(", ").tx(t.asStringValue()); + } + } + if (spd.hasChain()) { + tr = tbl.tr(); + tr.td().tx("Chains"); + td = tr.td().tx("Allowed: "); + for (StringType t : spd.getChain()) { + td.sep(", ").tx(t.asStringValue()); + } + } + + if (spd.hasComponent()) { + x.para().b().tx("Components"); + tbl = x.table("grid"); + for (SearchParameterComponentComponent t : spd.getComponent()) { + tr = tbl.tr(); + SearchParameter tsp = context.getWorker().fetchResource(SearchParameter.class, t.getDefinition()); + if (tsp != null && tsp.hasUserData("path")) { + tr.td().ah(tsp.getUserString("path")).tx(tsp.present()); + } else { + tr.td().tx(t.getDefinition()); + } + tr.td().code().tx(t.getExpression()); + } + } + return false; + } + + public void describe(XhtmlNode x, OperationDefinition opd) { + x.tx(display(opd)); + } + + public String display(OperationDefinition opd) { + return opd.present(); + } + + @Override + public String display(Resource r) throws UnsupportedEncodingException, IOException { + return ((OperationDefinition) r).present(); + } + +} diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetCheckerSimple.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetCheckerSimple.java index cbb70ea89..3a4015afa 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetCheckerSimple.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetCheckerSimple.java @@ -37,6 +37,7 @@ import java.util.List; import java.util.Map; import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.exceptions.NoTerminologyServiceException; import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult; import org.hl7.fhir.r5.model.CanonicalType; @@ -515,6 +516,9 @@ public class ValueSetCheckerSimple implements ValueSetChecker { if (res.getErrorClass() == TerminologyServiceErrorClass.UNKNOWN || res.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED || res.getErrorClass() == TerminologyServiceErrorClass.VALUESET_UNSUPPORTED) { return null; } + if (res.getErrorClass() == TerminologyServiceErrorClass.NOSERVICE) { + throw new NoTerminologyServiceException(); + } return res.isOk(); } else { if (vsi.hasFilter()) { diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/IResourceValidator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/IResourceValidator.java index 0f36d332d..c78223d3d 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/IResourceValidator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/IResourceValidator.java @@ -184,6 +184,14 @@ public interface IResourceValidator { public boolean isShowMessagesFromReferences(); public void setShowMessagesFromReferences(boolean value); + /** + * this is used internally in the publishing stack to ensure that everything is water tight, but + * this check is not necessary or appropriate at run time when the validator is hosted in HAPI + * @return + */ + public boolean isWantCheckSnapshotUnchanged(); + public void setWantCheckSnapshotUnchanged(boolean wantCheckSnapshotUnchanged); + //FIXME: don't need that, gets never used? // public String getValidationLanguage(); // public void setValidationLanguage(String value); diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/ResourceTests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/ResourceTests.java new file mode 100644 index 000000000..d1ec769f1 --- /dev/null +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/ResourceTests.java @@ -0,0 +1,43 @@ +package org.hl7.fhir.r5.test; + +import static org.junit.jupiter.api.Assertions.*; + +import org.hl7.fhir.r5.model.CapabilityStatement; +import org.hl7.fhir.r5.model.CodeSystem; +import org.hl7.fhir.r5.model.CompartmentDefinition; +import org.hl7.fhir.r5.model.ConceptMap; +import org.hl7.fhir.r5.model.ExampleScenario; +import org.hl7.fhir.r5.model.GraphDefinition; +import org.hl7.fhir.r5.model.ImplementationGuide; +import org.hl7.fhir.r5.model.MessageDefinition; +import org.hl7.fhir.r5.model.NamingSystem; +import org.hl7.fhir.r5.model.OperationDefinition; +import org.hl7.fhir.r5.model.SearchParameter; +import org.hl7.fhir.r5.model.StructureDefinition; +import org.hl7.fhir.r5.model.StructureMap; +import org.hl7.fhir.r5.model.TerminologyCapabilities; +import org.hl7.fhir.r5.model.ValueSet; +import org.junit.jupiter.api.Test; + +class ResourceTests { + + @Test + void testSupportsCopyright() { + assertTrue(new CodeSystem().supportsCopyright()); + assertTrue(new ValueSet().supportsCopyright()); + assertTrue(new ConceptMap().supportsCopyright()); + assertTrue(new TerminologyCapabilities().supportsCopyright()); + assertTrue(new CapabilityStatement().supportsCopyright()); + assertTrue(new StructureDefinition().supportsCopyright()); + assertTrue(new ImplementationGuide().supportsCopyright()); + assertTrue(new MessageDefinition().supportsCopyright()); + assertTrue(new StructureMap().supportsCopyright()); + assertTrue(new ExampleScenario().supportsCopyright()); + assertFalse(new SearchParameter().supportsCopyright()); + assertFalse(new NamingSystem().supportsCopyright()); + assertFalse(new OperationDefinition().supportsCopyright()); + assertFalse(new CompartmentDefinition().supportsCopyright()); + assertFalse(new GraphDefinition().supportsCopyright()); + } + +} 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 4d9da697d..23c15cc22 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 @@ -1,5 +1,7 @@ package org.hl7.fhir.utilities.i18n; +import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; + public class I18nConstants { @@ -343,6 +345,9 @@ public class I18nConstants { public static final String SD_MUST_HAVE_DERIVATION = "SD_MUST_HAVE_DERIVATION"; public static final String SD_NESTED_MUST_SUPPORT_DIFF = "SD_NESTED_MUST_SUPPORT_DIFF"; public static final String SD_NESTED_MUST_SUPPORT_SNAPSHOT = "SD_NESTED_MUST_SUPPORT_SNAPSHOT"; + public static final String SD_ED_TYPE_PROFILE_UNKNOWN = "SD_ED_TYPE_PROFILE_UNKNOWN"; + public static final String SD_ED_TYPE_PROFILE_NOTYPE = "SD_ED_TYPE_PROFILE_NOTYPE"; + public static final String SD_ED_TYPE_PROFILE_WRONG = "SD_ED_TYPE_PROFILE_WRONG"; public static final String SEARCHPARAMETER_BASE_WRONG = "SEARCHPARAMETER_BASE_WRONG"; public static final String SEARCHPARAMETER_EXP_WRONG = "SEARCHPARAMETER_EXP_WRONG"; public static final String SEARCHPARAMETER_NOTFOUND = "SEARCHPARAMETER_NOTFOUND"; @@ -410,6 +415,8 @@ public class I18nConstants { public static final String TERMINOLOGY_TX_SYSTEM_VALUESET2 = "Terminology_TX_System_ValueSet2"; public static final String TERMINOLOGY_TX_VALUESET_NOTFOUND = "Terminology_TX_ValueSet_NotFound"; public static final String TERMINOLOGY_TX_VALUESET_NOTFOUND2 = "Terminology_TX_ValueSet_NotFound2"; + public static final String TERMINOLOGY_TX_NOSVC_BOUND_REQ = "TERMINOLOGY_TX_NOSVC_BOUND_REQ"; + public static final String TERMINOLOGY_TX_NOSVC_BOUND_EXT = "TERMINOLOGY_TX_NOSVC_BOUND_EXT"; public static final String TEXT_SHOULD_NOT_BE_PRESENT = "Text_should_not_be_present"; public static final String THE_BASE_SNAPSHOT_MARKS_A_SLICING_AS_CLOSED_BUT_THE_DIFFERENTIAL_TRIES_TO_EXTEND_IT_IN__AT__ = "The_base_snapshot_marks_a_slicing_as_closed_but_the_differential_tries_to_extend_it_in__at__"; public static final String THIS_BASE_PROPERTY_MUST_BE_AN_ARRAY_NOT_A_ = "This_base_property_must_be_an_Array_not_a_"; @@ -478,6 +485,7 @@ public class I18nConstants { public static final String TYPE_SPECIFIC_CHECKS_DT_URL_RESOLVE = "Type_Specific_Checks_DT_URL_Resolve"; public static final String TYPE_SPECIFIC_CHECKS_DT_UUID_STRAT = "Type_Specific_Checks_DT_UUID_Strat"; public static final String TYPE_SPECIFIC_CHECKS_DT_UUID_VAID = "Type_Specific_Checks_DT_UUID_Vaid"; + public static final String UNABLE_TO_CONNECT_TO_TERMINOLOGY_SERVER = "Unable_to_connect_to_terminology_server"; public static final String UNABLE_TO_CONNECT_TO_TERMINOLOGY_SERVER_USE_PARAMETER_TX_NA_TUN_RUN_WITHOUT_USING_TERMINOLOGY_SERVICES_TO_VALIDATE_LOINC_SNOMED_ICDX_ETC_ERROR__ = "Unable_to_connect_to_terminology_server_Use_parameter_tx_na_tun_run_without_using_terminology_services_to_validate_LOINC_SNOMED_ICDX_etc_Error__"; public static final String UNABLE_TO_FIND_BASE_DEFINITION_FOR_LOGICAL_MODEL__FROM_ = "Unable_to_find_base_definition_for_logical_model__from_"; public static final String UNABLE_TO_FIND_BASE__FOR_ = "Unable_to_find_base__for_"; diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java index 5f1415f62..414cb0784 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java @@ -35,6 +35,7 @@ import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -1095,6 +1096,10 @@ public class NpmPackage { public boolean isNotForPublication() { return JSONUtil.bool(npm, "notForPublication"); } + + public InputStream load(PackageResourceInformation p) throws FileNotFoundException { + return new FileInputStream(p.filename); + } } \ No newline at end of file diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java index e561009f2..32a8bbf02 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java @@ -92,7 +92,7 @@ public class XhtmlNode implements IBaseXhtml { private boolean notPretty; private boolean inPara; private boolean inLink; - + private boolean seperated; public XhtmlNode() { super(); @@ -842,6 +842,17 @@ public class XhtmlNode implements IBaseXhtml { } + public XhtmlNode sep(String separator) { + // if there's already text, add the separator + if (seperated) { + return this; + } + seperated = true; + return tx(separator); + } + + + diff --git a/org.hl7.fhir.utilities/src/main/resources/Messages.properties b/org.hl7.fhir.utilities/src/main/resources/Messages.properties index f9d145fbf..38e7af318 100644 --- a/org.hl7.fhir.utilities/src/main/resources/Messages.properties +++ b/org.hl7.fhir.utilities/src/main/resources/Messages.properties @@ -418,7 +418,7 @@ Parser_Type__not_supported = Parser Type {0} not supported Version_mismatch_The_context_has_version__loaded_and_the_new_content_being_loaded_is_version_ = Version mismatch. The context has version {0} loaded, and the new content being loaded is version {1} Error_reading__from_package__ = Error reading {0} from package {1}#{2}: {3} Error_parsing_ = Error parsing {0}:{1} -Unable_to_connect_to_terminology_server_Use_parameter_tx_na_tun_run_without_using_terminology_services_to_validate_LOINC_SNOMED_ICDX_etc_Error__ = Unable to connect to terminology server. Use parameter ''-tx n/a'' tun run without using terminology services to validate LOINC, SNOMED, ICD-X etc. Error = {0} +Unable_to_connect_to_terminology_server_Use_parameter_tx_na_tun_run_without_using_terminology_services_to_validate_LOINC_SNOMED_ICDX_etc_Error__ = Unable to connect to terminology server. Use parameter ''-tx n/a'' to run without using terminology services to validate LOINC, SNOMED, ICD-X etc. Error = {0} Display_Name_for__should_be_one_of__instead_of_ = Display Name for {0}#{1} should be one of ''{2}'' instead of ''{3}'' Unknown_Code__in_ = Unknown Code {0} in {1} UNKNOWN_CODE__IN_FRAGMENT = Unknown Code {0} in {1} - note that the code system is labelled as a fragment, so the code may be valid in some other fragment @@ -611,4 +611,10 @@ UNSUPPORTED_IDENTIFIER_PATTERN_PROPERTY_NOT_SUPPORTED_FOR_DISCRIMINATOR_FOR_SLIC UNSUPPORTED_IDENTIFIER_PATTERN_NO_PROPERTY_NOT_SUPPORTED_FOR_DISCRIMINATOR_FOR_SLICE = Unsupported: no properties with values found on type {2} for pattern for discriminator({0}) for slice {1} SD_NESTED_MUST_SUPPORT_DIFF = The element {0} has types/profiles/targets that are marked as must support, but the element itself is not marked as must-support. The inner must-supports will be ignored unless the element inherits must-support = true SD_NESTED_MUST_SUPPORT_SNAPSHOT = The element {0} has types/profiles/targets that are marked as must support, but the element itself is not marked as must-support - \ No newline at end of file +Unable_to_connect_to_terminology_server = Unable to connect to terminology server. Error = {0} +SD_ED_TYPE_PROFILE_UNKNOWN = Unable to resolve profile {0} +SD_ED_TYPE_PROFILE_NOTYPE = Found profile {0}, but unable to determine the type it applies it +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 + \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java index 8e7b585a7..4ea182bbe 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java @@ -2,11 +2,7 @@ package org.hl7.fhir.validation; import static org.apache.commons.lang3.StringUtils.isBlank; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Date; import java.util.HashMap; /* @@ -85,7 +81,6 @@ 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.validation.BaseValidator.ValidationControl; import org.hl7.fhir.validation.instance.utils.IndexedElement; public class BaseValidator { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/NativeHostServices.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/NativeHostServices.java index 7b3224130..5d7eb8266 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/NativeHostServices.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/NativeHostServices.java @@ -34,7 +34,11 @@ package org.hl7.fhir.validation; import java.io.ByteArrayOutputStream; import java.io.IOException; -import org.hl7.fhir.convertors.*; +import org.hl7.fhir.convertors.VersionConvertorAdvisor50; +import org.hl7.fhir.convertors.VersionConvertor_10_50; +import org.hl7.fhir.convertors.VersionConvertor_14_50; +import org.hl7.fhir.convertors.VersionConvertor_30_50; +import org.hl7.fhir.convertors.VersionConvertor_40_50; import org.hl7.fhir.exceptions.FHIRException; /** 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 596055d66..21ac84707 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 @@ -1,7 +1,46 @@ package org.hl7.fhir.validation; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.net.HttpURLConnection; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.UUID; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + import org.apache.commons.io.IOUtils; -import org.hl7.fhir.convertors.*; +import org.hl7.fhir.convertors.VersionConvertorAdvisor50; +import org.hl7.fhir.convertors.VersionConvertor_10_30; +import org.hl7.fhir.convertors.VersionConvertor_10_40; +import org.hl7.fhir.convertors.VersionConvertor_10_50; +import org.hl7.fhir.convertors.VersionConvertor_14_30; +import org.hl7.fhir.convertors.VersionConvertor_14_40; +import org.hl7.fhir.convertors.VersionConvertor_14_50; +import org.hl7.fhir.convertors.VersionConvertor_30_40; +import org.hl7.fhir.convertors.VersionConvertor_30_50; +import org.hl7.fhir.convertors.VersionConvertor_40_50; import org.hl7.fhir.convertors.loaders.BaseLoaderR5.NullLoaderKnowledgeProvider; import org.hl7.fhir.convertors.loaders.R2016MayToR5Loader; import org.hl7.fhir.convertors.loaders.R2ToR5Loader; @@ -23,50 +62,57 @@ import org.hl7.fhir.r5.formats.FormatUtilities; import org.hl7.fhir.r5.formats.IParser.OutputStyle; import org.hl7.fhir.r5.formats.JsonParser; import org.hl7.fhir.r5.formats.XmlParser; -import org.hl7.fhir.r5.model.*; +import org.hl7.fhir.r5.model.Base; +import org.hl7.fhir.r5.model.Bundle; +import org.hl7.fhir.r5.model.Coding; +import org.hl7.fhir.r5.model.Constants; +import org.hl7.fhir.r5.model.DomainResource; +import org.hl7.fhir.r5.model.FhirPublication; +import org.hl7.fhir.r5.model.ImplementationGuide; import org.hl7.fhir.r5.model.ImplementationGuide.ImplementationGuideGlobalComponent; +import org.hl7.fhir.r5.model.OperationOutcome; import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent; +import org.hl7.fhir.r5.model.Parameters; +import org.hl7.fhir.r5.model.Reference; +import org.hl7.fhir.r5.model.Resource; +import org.hl7.fhir.r5.model.StructureDefinition; +import org.hl7.fhir.r5.model.StructureMap; import org.hl7.fhir.r5.renderers.RendererFactory; import org.hl7.fhir.r5.renderers.utils.RenderingContext; import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode; import org.hl7.fhir.r5.terminologies.ConceptMapEngine; -import org.hl7.fhir.r5.utils.*; -import org.hl7.fhir.r5.utils.IResourceValidator.*; +import org.hl7.fhir.r5.utils.EOperationOutcome; +import org.hl7.fhir.r5.utils.FHIRPathEngine; +import org.hl7.fhir.r5.utils.IResourceValidator.BestPracticeWarningLevel; +import org.hl7.fhir.r5.utils.IResourceValidator.BundleValidationRule; +import org.hl7.fhir.r5.utils.IResourceValidator.CheckDisplayOption; +import org.hl7.fhir.r5.utils.IResourceValidator.IValidatorResourceFetcher; +import org.hl7.fhir.r5.utils.IResourceValidator.IdStatus; +import org.hl7.fhir.r5.utils.IResourceValidator.ReferenceValidationPolicy; +import org.hl7.fhir.r5.utils.OperationOutcomeUtilities; +import org.hl7.fhir.r5.utils.StructureMapUtilities; import org.hl7.fhir.r5.utils.StructureMapUtilities.ITransformerServices; -import org.hl7.fhir.utilities.i18n.I18nConstants; -import org.hl7.fhir.utilities.npm.BasePackageCacheManager; -import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; -import org.hl7.fhir.utilities.npm.NpmPackage; -import org.hl7.fhir.utilities.npm.PackageClient; -import org.hl7.fhir.utilities.npm.ToolsVersion; -import org.hl7.fhir.validation.BaseValidator.ValidationControl; -import org.hl7.fhir.validation.Validator.QuestionnaireMode; -import org.hl7.fhir.validation.cli.services.StandAloneValidatorFetcher.IPackageInstaller; -import org.hl7.fhir.validation.instance.InstanceValidator; +import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.utilities.IniFile; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.TimeTracker; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; -import org.hl7.fhir.utilities.i18n.I18nBase; import org.hl7.fhir.utilities.i18n.I18nConstants; +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.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.Validator.QuestionnaireMode; +import org.hl7.fhir.validation.cli.services.StandAloneValidatorFetcher.IPackageInstaller; +import org.hl7.fhir.validation.instance.InstanceValidator; import org.xml.sax.SAXException; -import java.io.*; -import java.net.HttpURLConnection; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; -import java.util.*; -import java.util.Map.Entry; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - /* Copyright (c) 2011+, HL7, Inc. All rights reserved. @@ -354,6 +400,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst public ValidationEngine() throws IOException { pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION); context = SimpleWorkerContext.fromNothing(); + initContext(null); } public String setTerminologyServer(String src, String log, FhirPublication version) throws FHIRException, URISyntaxException { @@ -436,6 +483,11 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst context = SimpleWorkerContext.fromDefinitions(source, loaderForVersion(), new PackageVersion(src)); grabNatives(source, "http://hl7.org/fhir"); } + initContext(tt); + } + + public void initContext(TimeTracker tt) throws IOException, FileNotFoundException { + context.setCanNoTS(true); context.setCacheId(UUID.randomUUID().toString()); context.setAllowLoadingDuplicates(true); // because of Forge context.setExpansionProfile(makeExpProfile()); diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Validator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Validator.java index be1da42f0..add394963 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Validator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Validator.java @@ -68,10 +68,12 @@ import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.validation.ValidationEngine.VersionSourceInformation; import org.hl7.fhir.validation.cli.ValidatorGui; +import org.hl7.fhir.validation.cli.model.CliContext; import org.hl7.fhir.validation.cli.services.ComparisonService; import org.hl7.fhir.validation.cli.services.ValidationService; -import org.hl7.fhir.validation.cli.model.CliContext; -import org.hl7.fhir.validation.cli.utils.*; +import org.hl7.fhir.validation.cli.utils.Common; +import org.hl7.fhir.validation.cli.utils.Display; +import org.hl7.fhir.validation.cli.utils.Params; /** * A executable class that will validate one or more FHIR resources against diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/VersionUtil.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/VersionUtil.java index 32ced0711..798359660 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/VersionUtil.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/VersionUtil.java @@ -1,5 +1,8 @@ package org.hl7.fhir.validation; +import static org.apache.commons.lang3.StringUtils.defaultIfBlank; +import static org.apache.commons.lang3.StringUtils.left; + /* Copyright (c) 2011+, HL7, Inc. All rights reserved. @@ -31,19 +34,13 @@ package org.hl7.fhir.validation; import java.io.InputStream; -import java.text.SimpleDateFormat; import java.time.Duration; -import java.time.Instant; -import java.time.OffsetDateTime; import java.util.Date; import java.util.Properties; import org.hl7.fhir.r5.model.InstantType; import org.hl7.fhir.utilities.Utilities; -import static org.apache.commons.lang3.StringUtils.defaultIfBlank; -import static org.apache.commons.lang3.StringUtils.left; - /** * Used internally by HAPI to log the version of the HAPI FHIR framework * once, when the framework is first loaded by the classloader. diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/RestEndpoints.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/RestEndpoints.java index 3cc8d390f..8762f6177 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/RestEndpoints.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/RestEndpoints.java @@ -1,12 +1,13 @@ package org.hl7.fhir.validation.cli; -import io.javalin.Javalin; import org.hl7.fhir.validation.ValidationEngine; import org.hl7.fhir.validation.cli.controller.CliContextController; -import org.hl7.fhir.validation.cli.controller.ValidationController; import org.hl7.fhir.validation.cli.controller.UIController; +import org.hl7.fhir.validation.cli.controller.ValidationController; import org.hl7.fhir.validation.cli.model.CliContext; +import io.javalin.Javalin; + public class RestEndpoints { public UIController myUIController; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidatorGui.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidatorGui.java index 35a423a13..4e190008f 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidatorGui.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidatorGui.java @@ -1,15 +1,14 @@ package org.hl7.fhir.validation.cli; -import io.javalin.Javalin; +import java.awt.Desktop; +import java.net.URI; + import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.validation.ValidationEngine; import org.hl7.fhir.validation.cli.model.CliContext; import org.hl7.fhir.validation.cli.utils.Common; -import java.awt.*; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; +import io.javalin.Javalin; public class ValidatorGui { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/CliContextController.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/CliContextController.java index 45184a6bf..cac9194ba 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/CliContextController.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/CliContextController.java @@ -1,12 +1,14 @@ package org.hl7.fhir.validation.cli.controller; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.javalin.http.Context; import org.apache.http.HttpStatus; import org.hl7.fhir.validation.cli.model.CliContext; import org.jetbrains.annotations.NotNull; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.javalin.http.Context; + public class CliContextController { private final String JSON_MIME_TYPE = "application/json"; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/ValidationController.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/ValidationController.java index 3dda47a0c..1edb0c9b0 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/ValidationController.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/ValidationController.java @@ -1,14 +1,15 @@ package org.hl7.fhir.validation.cli.controller; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.javalin.http.Context; -import io.javalin.http.Handler; import org.apache.http.HttpStatus; import org.hl7.fhir.validation.ValidationEngine; import org.hl7.fhir.validation.cli.model.ValidationRequest; import org.hl7.fhir.validation.cli.model.ValidationResponse; import org.hl7.fhir.validation.cli.services.ValidationService; +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.javalin.http.Context; + public class ValidationController { private ValidationEngine myValidationEngine; 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 eea13ac6c..5870b5f98 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 @@ -1,11 +1,16 @@ package org.hl7.fhir.validation.cli.model; -import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; import org.hl7.fhir.r5.utils.IResourceValidator.BundleValidationRule; import org.hl7.fhir.validation.Validator; -import java.util.*; +import com.fasterxml.jackson.annotation.JsonProperty; /** * A POJO for storing the flags/values for the CLI validator. diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/FileInfo.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/FileInfo.java index c44545c1b..73e785fe9 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/FileInfo.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/FileInfo.java @@ -1,7 +1,6 @@ package org.hl7.fhir.validation.cli.model; import com.fasterxml.jackson.annotation.JsonProperty; -import org.hl7.fhir.r5.elementmodel.Manager; public class FileInfo { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationOutcome.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationOutcome.java index 406b33f2a..a34bc4704 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationOutcome.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationOutcome.java @@ -1,11 +1,12 @@ package org.hl7.fhir.validation.cli.model; -import com.fasterxml.jackson.annotation.JsonProperty; -import org.hl7.fhir.utilities.validation.ValidationMessage; - import java.util.ArrayList; import java.util.List; +import org.hl7.fhir.utilities.validation.ValidationMessage; + +import com.fasterxml.jackson.annotation.JsonProperty; + public class ValidationOutcome { @JsonProperty("fileInfo") diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationRequest.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationRequest.java index bf0ee6ed7..ad95e7a5d 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationRequest.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationRequest.java @@ -1,10 +1,10 @@ package org.hl7.fhir.validation.cli.model; -import com.fasterxml.jackson.annotation.JsonProperty; - import java.util.ArrayList; import java.util.List; +import com.fasterxml.jackson.annotation.JsonProperty; + public class ValidationRequest { @JsonProperty("cliContext") diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationResponse.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationResponse.java index c509e7c7e..10248caa4 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationResponse.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationResponse.java @@ -1,10 +1,10 @@ package org.hl7.fhir.validation.cli.model; -import com.fasterxml.jackson.annotation.JsonProperty; - import java.util.ArrayList; import java.util.List; +import com.fasterxml.jackson.annotation.JsonProperty; + public class ValidationResponse { @JsonProperty("outcomes") diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ComparisonService.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ComparisonService.java index 30afb9c22..a5589d145 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ComparisonService.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ComparisonService.java @@ -1,27 +1,19 @@ package org.hl7.fhir.validation.cli.services; +import java.awt.Desktop; +import java.io.File; +import java.io.IOException; + import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.r5.conformance.CapabilityStatementUtilities; -import org.hl7.fhir.r5.formats.IParser; -import org.hl7.fhir.r5.formats.JsonParser; -import org.hl7.fhir.r5.formats.XmlParser; import org.hl7.fhir.r5.model.CanonicalResource; import org.hl7.fhir.r5.model.CapabilityStatement; import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.r5.utils.EOperationOutcome; -import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; -import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.validation.ValidationEngine; import org.hl7.fhir.validation.cli.utils.Params; -import java.awt.*; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.UUID; - public class ComparisonService { public static void doLeftRightComparison(String[] args, String dest, ValidationEngine validator) throws IOException, FHIRException, EOperationOutcome { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/StandAloneValidatorFetcher.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/StandAloneValidatorFetcher.java index 0dd0b3412..6b40f1e31 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/StandAloneValidatorFetcher.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/StandAloneValidatorFetcher.java @@ -17,7 +17,6 @@ import org.hl7.fhir.utilities.VersionUtilities.VersionURLInfo; import org.hl7.fhir.utilities.npm.BasePackageCacheManager; import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; import org.hl7.fhir.utilities.npm.NpmPackage; -import org.hl7.fhir.validation.cli.services.StandAloneValidatorFetcher.IPackageInstaller; public class StandAloneValidatorFetcher implements IValidatorResourceFetcher { 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 0b8580e40..17aca317e 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 @@ -1,11 +1,24 @@ package org.hl7.fhir.validation.cli.services; +import java.io.File; +import java.io.FileOutputStream; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + import org.hl7.fhir.r5.context.TerminologyCache; import org.hl7.fhir.r5.elementmodel.Manager; import org.hl7.fhir.r5.formats.IParser; import org.hl7.fhir.r5.formats.JsonParser; import org.hl7.fhir.r5.formats.XmlParser; -import org.hl7.fhir.r5.model.*; +import org.hl7.fhir.r5.model.Bundle; +import org.hl7.fhir.r5.model.DomainResource; +import org.hl7.fhir.r5.model.FhirPublication; +import org.hl7.fhir.r5.model.ImplementationGuide; +import org.hl7.fhir.r5.model.OperationOutcome; +import org.hl7.fhir.r5.model.Resource; +import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind; import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.utilities.TextFile; @@ -14,14 +27,11 @@ import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.validation.ValidationEngine; import org.hl7.fhir.validation.ValidationEngine.VersionSourceInformation; -import org.hl7.fhir.validation.cli.model.*; - -import java.io.File; -import java.io.FileOutputStream; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.model.FileInfo; +import org.hl7.fhir.validation.cli.model.ValidationOutcome; +import org.hl7.fhir.validation.cli.model.ValidationRequest; +import org.hl7.fhir.validation.cli.model.ValidationResponse; public class ValidationService { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Display.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Display.java index 09397e776..a224cd23d 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Display.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Display.java @@ -1,12 +1,12 @@ package org.hl7.fhir.validation.cli.utils; +import java.io.IOException; + import org.hl7.fhir.r5.model.Constants; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; import org.hl7.fhir.utilities.npm.ToolsVersion; -import java.io.IOException; - /** * Class for displaying output to the cli user. * 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 20211de73..81c4218dd 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 @@ -1,14 +1,14 @@ package org.hl7.fhir.validation.cli.utils; +import java.io.File; +import java.util.Arrays; +import java.util.Locale; + import org.hl7.fhir.r5.utils.IResourceValidator.BundleValidationRule; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.validation.Validator; import org.hl7.fhir.validation.cli.model.CliContext; -import java.io.File; -import java.util.Arrays; -import java.util.Locale; - public class Params { public static final String GUI = "-gui"; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/EnableWhenEvaluator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/EnableWhenEvaluator.java index 632e27dd5..a070630a5 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/EnableWhenEvaluator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/EnableWhenEvaluator.java @@ -27,17 +27,26 @@ package org.hl7.fhir.validation.instance; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -import java.util.*; -import java.util.stream.*; + */ +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.r5.elementmodel.Element; -import org.hl7.fhir.r5.model.*; -import org.hl7.fhir.r5.model.MeasureReport.MeasureReportGroupComponent; -import org.hl7.fhir.r5.model.Questionnaire.*; +import org.hl7.fhir.r5.model.BooleanType; +import org.hl7.fhir.r5.model.Coding; +import org.hl7.fhir.r5.model.DataType; +import org.hl7.fhir.r5.model.Expression; +import org.hl7.fhir.r5.model.ExpressionNode; +import org.hl7.fhir.r5.model.Factory; +import org.hl7.fhir.r5.model.PrimitiveType; +import org.hl7.fhir.r5.model.Quantity; +import org.hl7.fhir.r5.model.Questionnaire; +import org.hl7.fhir.r5.model.Questionnaire.EnableWhenBehavior; +import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent; +import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemEnableWhenComponent; +import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemOperator; import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.hl7.fhir.validation.instance.utils.ValidatorHostContext; 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 e42434539..770dc1f26 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 @@ -37,10 +37,8 @@ import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Base64; import java.util.Calendar; import java.util.Collection; import java.util.HashMap; @@ -51,15 +49,10 @@ import java.util.Set; import java.util.UUID; import org.apache.commons.codec.binary.Base64InputStream; -import org.apache.commons.io.Charsets; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.StringUtils; -import org.hl7.fhir.r5.model.Reference; -import org.hl7.fhir.convertors.*; import org.hl7.fhir.exceptions.DefinitionException; import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.exceptions.FHIRFormatError; import org.hl7.fhir.exceptions.PathEngineException; import org.hl7.fhir.exceptions.TerminologyServiceException; import org.hl7.fhir.r5.conformance.ProfileUtilities; @@ -86,6 +79,7 @@ import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; import org.hl7.fhir.r5.model.CodeableConcept; import org.hl7.fhir.r5.model.Coding; import org.hl7.fhir.r5.model.ContactPoint; +import org.hl7.fhir.r5.model.DataType; import org.hl7.fhir.r5.model.DateTimeType; import org.hl7.fhir.r5.model.DateType; import org.hl7.fhir.r5.model.DecimalType; @@ -114,6 +108,7 @@ import org.hl7.fhir.r5.model.PrimitiveType; import org.hl7.fhir.r5.model.Quantity; import org.hl7.fhir.r5.model.Range; import org.hl7.fhir.r5.model.Ratio; +import org.hl7.fhir.r5.model.Reference; import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.SampledData; import org.hl7.fhir.r5.model.SearchParameter; @@ -127,18 +122,30 @@ import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionSnapshotComp import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule; import org.hl7.fhir.r5.model.TimeType; import org.hl7.fhir.r5.model.Timing; -import org.hl7.fhir.r5.model.DataType; import org.hl7.fhir.r5.model.TypeDetails; import org.hl7.fhir.r5.model.UriType; import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; +import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass; import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException; import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext; import org.hl7.fhir.r5.utils.IResourceValidator; import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.r5.utils.XVerExtensionManager; +import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; +import org.hl7.fhir.utilities.Utilities; +import org.hl7.fhir.utilities.Utilities.DecimalStatus; +import org.hl7.fhir.utilities.VersionUtilities; +import org.hl7.fhir.utilities.VersionUtilities.VersionURLInfo; import org.hl7.fhir.utilities.i18n.I18nConstants; +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.validation.ValidationOptions; +import org.hl7.fhir.utilities.xhtml.NodeType; +import org.hl7.fhir.utilities.xhtml.XhtmlNode; import org.hl7.fhir.validation.BaseValidator; import org.hl7.fhir.validation.Validator.QuestionnaireMode; import org.hl7.fhir.validation.instance.type.BundleValidator; @@ -148,19 +155,13 @@ import org.hl7.fhir.validation.instance.type.QuestionnaireValidator; import org.hl7.fhir.validation.instance.type.SearchParameterValidator; import org.hl7.fhir.validation.instance.type.StructureDefinitionValidator; import org.hl7.fhir.validation.instance.type.ValueSetValidator; -import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; -import org.hl7.fhir.utilities.Utilities; -import org.hl7.fhir.utilities.Utilities.DecimalStatus; -import org.hl7.fhir.utilities.VersionUtilities; -import org.hl7.fhir.utilities.VersionUtilities.VersionURLInfo; -import org.hl7.fhir.utilities.validation.ValidationOptions; -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.NodeType; -import org.hl7.fhir.utilities.xhtml.XhtmlNode; -import org.hl7.fhir.validation.instance.utils.*; +import org.hl7.fhir.validation.instance.utils.ChildIterator; +import org.hl7.fhir.validation.instance.utils.ElementInfo; +import org.hl7.fhir.validation.instance.utils.IndexedElement; +import org.hl7.fhir.validation.instance.utils.NodeStack; +import org.hl7.fhir.validation.instance.utils.ResolvedReference; +import org.hl7.fhir.validation.instance.utils.ResourceValidationTracker; +import org.hl7.fhir.validation.instance.utils.ValidatorHostContext; import org.w3c.dom.Document; import com.google.gson.Gson; @@ -343,6 +344,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat private String validationLanguage; private boolean baseOnly; private boolean noCheckAggregation; + private boolean wantCheckSnapshotUnchanged; private List igs = new ArrayList<>(); private List extensionDomains = new ArrayList(); @@ -1004,7 +1006,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat ValidationResult vr = checkCodeOnServer(stack, valueset, cc, true); // we're going to validate the codings directly, so only check the valueset if (!vr.isOk()) { bindingsOk = false; - if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure()) { + if (vr.getErrorClass() != null && vr.getErrorClass() == TerminologyServiceErrorClass.NOSERVICE) { + if (binding.getStrength() == BindingStrength.REQUIRED || (binding.getStrength() == BindingStrength.EXTENSIBLE && binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))) { + hint(errors, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOSVC_BOUND_REQ, describeReference(binding.getValueSet())); + } else if (binding.getStrength() == BindingStrength.EXTENSIBLE) { + hint(errors, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOSVC_BOUND_EXT, describeReference(binding.getValueSet())); + } + } else if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure()) { if (binding.getStrength() == BindingStrength.REQUIRED) txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_1, describeReference(binding.getValueSet()), vr.getErrorClass().toString()); else if (binding.getStrength() == BindingStrength.EXTENSIBLE) { @@ -3860,7 +3868,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } else if (element.getType().equals("SearchParameter")) { new SearchParameterValidator(context, timeTracker, fpe).validateSearchParameter(errors, element, stack); } else if (element.getType().equals("StructureDefinition")) { - new StructureDefinitionValidator(context, timeTracker, fpe).validateStructureDefinition(errors, element, stack); + new StructureDefinitionValidator(context, timeTracker, fpe, wantCheckSnapshotUnchanged).validateStructureDefinition(errors, element, stack); } else if (element.getType().equals("ValueSet")) { new ValueSetValidator(context, timeTracker, this).validateValueSet(errors, element, stack); } @@ -4128,236 +4136,252 @@ 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 { - List profiles = new ArrayList(); if (ei.definition != null) { - String type = null; - ElementDefinition typeDefn = null; - checkMustSupport(profile, ei); + 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 (ei.definition.getType().size() == 1 && !"*".equals(ei.definition.getType().get(0).getWorkingCode()) && !"Element".equals(ei.definition.getType().get(0).getWorkingCode()) - && !"BackboneElement".equals(ei.definition.getType().get(0).getWorkingCode())) { - type = ei.definition.getType().get(0).getWorkingCode(); - String stype = ei.getElement().fhirType(); - if (ei.definition.isChoice() && !stype.equals(type)) { - if ("Extension".equals(profile.getType())) { - // error will be raised elsewhere - } else { - rule(errors, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), false, I18nConstants.EXTENSION_PROF_TYPE, profile.getUrl(), type, stype); - } - } - // - // Excluding reference is a kludge to get around versioning issues - if (ei.definition.getType().get(0).hasProfile()) { - for (CanonicalType p : ei.definition.getType().get(0).getProfile()) { - profiles.add(p.getValue()); - } - } - } else if (ei.definition.getType().size() == 1 && "*".equals(ei.definition.getType().get(0).getWorkingCode())) { - String prefix = tail(ei.definition.getPath()); - assert prefix.endsWith("[x]"); - type = ei.getName().substring(prefix.length() - 3); - if (isPrimitiveType(type)) - type = Utilities.uncapitalize(type); - if (ei.definition.getType().get(0).hasProfile()) { - for (CanonicalType p : ei.definition.getType().get(0).getProfile()) { - profiles.add(p.getValue()); - } - } - } else if (ei.definition.getType().size() > 1) { + public void checkChildByDefinition(ValidatorHostContext hostContext, List errors, StructureDefinition profile, + ElementDefinition definition, Element resource, Element element, String actualType, NodeStack stack, boolean inCodeableConcept, + boolean checkDisplayInContext, ElementInfo ei, String extensionUrl, ElementDefinition checkDefn, boolean isSlice) { + List profiles = new ArrayList(); + String type = null; + ElementDefinition typeDefn = null; + checkMustSupport(profile, ei); - String prefix = tail(ei.definition.getPath()); - assert typesAreAllReference(ei.definition.getType()) || ei.definition.hasRepresentation(PropertyRepresentation.TYPEATTR) || prefix.endsWith("[x]") : prefix; - - if (ei.definition.hasRepresentation(PropertyRepresentation.TYPEATTR)) - type = ei.getElement().getType(); - else { - prefix = prefix.substring(0, prefix.length() - 3); - for (TypeRefComponent t : ei.definition.getType()) - if ((prefix + Utilities.capitalize(t.getWorkingCode())).equals(ei.getName())) { - type = t.getWorkingCode(); - // Excluding reference is a kludge to get around versioning issues - if (t.hasProfile() && !type.equals("Reference")) - profiles.add(t.getProfile().get(0).getValue()); - } - } - if (type == null) { - TypeRefComponent trc = ei.definition.getType().get(0); - if (trc.getWorkingCode().equals("Reference")) - type = "Reference"; - else - rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), stack.getLiteralPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOTYPE, ei.getName(), describeTypes(ei.definition.getType())); - } - } else if (ei.definition.getContentReference() != null) { - typeDefn = resolveNameReference(profile.getSnapshot(), ei.definition.getContentReference()); - - } else if (ei.definition.getType().size() == 1 && ("Element".equals(ei.definition.getType().get(0).getWorkingCode()) || "BackboneElement".equals(ei.definition.getType().get(0).getWorkingCode()))) { - if (ei.definition.getType().get(0).hasProfile()) { - CanonicalType pu = ei.definition.getType().get(0).getProfile().get(0); - if (pu.hasExtension(ToolingExtensions.EXT_PROFILE_ELEMENT)) - profiles.add(pu.getValue() + "#" + pu.getExtensionString(ToolingExtensions.EXT_PROFILE_ELEMENT)); - else - profiles.add(pu.getValue()); + if (checkDefn.getType().size() == 1 && !"*".equals(checkDefn.getType().get(0).getWorkingCode()) && !"Element".equals(checkDefn.getType().get(0).getWorkingCode()) + && !"BackboneElement".equals(checkDefn.getType().get(0).getWorkingCode())) { + type = checkDefn.getType().get(0).getWorkingCode(); + String stype = ei.getElement().fhirType(); + if (checkDefn.isChoice() && !stype.equals(type)) { + if ("Extension".equals(profile.getType())) { + // error will be raised elsewhere + } else { + rule(errors, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), false, I18nConstants.EXTENSION_PROF_TYPE, profile.getUrl(), type, stype); } } - - if (type != null) { - if (type.startsWith("@")) { - ei.definition = findElement(profile, type.substring(1)); - type = null; + // + // Excluding reference is a kludge to get around versioning issues + if (checkDefn.getType().get(0).hasProfile()) { + for (CanonicalType p : checkDefn.getType().get(0).getProfile()) { + profiles.add(p.getValue()); } } - NodeStack localStack = stack.push(ei.getElement(), ei.count, ei.definition, type == null ? typeDefn : resolveType(type, ei.definition.getType())); + } else if (checkDefn.getType().size() == 1 && "*".equals(checkDefn.getType().get(0).getWorkingCode())) { + String prefix = tail(checkDefn.getPath()); + assert prefix.endsWith("[x]"); + type = ei.getName().substring(prefix.length() - 3); + if (isPrimitiveType(type)) + type = Utilities.uncapitalize(type); + if (checkDefn.getType().get(0).hasProfile()) { + for (CanonicalType p : checkDefn.getType().get(0).getProfile()) { + profiles.add(p.getValue()); + } + } + } else if (checkDefn.getType().size() > 1) { + + String prefix = tail(checkDefn.getPath()); + assert typesAreAllReference(checkDefn.getType()) || checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR) || prefix.endsWith("[x]") : prefix; + + if (checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR)) + type = ei.getElement().getType(); + else { + prefix = prefix.substring(0, prefix.length() - 3); + for (TypeRefComponent t : checkDefn.getType()) + if ((prefix + Utilities.capitalize(t.getWorkingCode())).equals(ei.getName())) { + type = t.getWorkingCode(); + // Excluding reference is a kludge to get around versioning issues + if (t.hasProfile() && !type.equals("Reference")) + profiles.add(t.getProfile().get(0).getValue()); + } + } + if (type == null) { + TypeRefComponent trc = checkDefn.getType().get(0); + if (trc.getWorkingCode().equals("Reference")) + type = "Reference"; + else + rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), stack.getLiteralPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOTYPE, ei.getName(), describeTypes(checkDefn.getType())); + } + } else if (checkDefn.getContentReference() != null) { + typeDefn = resolveNameReference(profile.getSnapshot(), checkDefn.getContentReference()); + + } else if (checkDefn.getType().size() == 1 && ("Element".equals(checkDefn.getType().get(0).getWorkingCode()) || "BackboneElement".equals(checkDefn.getType().get(0).getWorkingCode()))) { + if (checkDefn.getType().get(0).hasProfile()) { + CanonicalType pu = checkDefn.getType().get(0).getProfile().get(0); + if (pu.hasExtension(ToolingExtensions.EXT_PROFILE_ELEMENT)) + profiles.add(pu.getValue() + "#" + pu.getExtensionString(ToolingExtensions.EXT_PROFILE_ELEMENT)); + else + profiles.add(pu.getValue()); + } + } + + if (type != null) { + if (type.startsWith("@")) { + checkDefn = findElement(profile, type.substring(1)); + if (isSlice) { + ei.slice = ei.definition; + } else { + ei.definition = ei.definition; + } + type = null; + } + } + NodeStack localStack = stack.push(ei.getElement(), ei.count, checkDefn, type == null ? typeDefn : resolveType(type, checkDefn.getType())); // if (debug) { // System.out.println(" check " + localStack.getLiteralPath()+" against "+ei.getDefinition().getId()+" in profile "+profile.getUrl()); // } - String localStackLiterapPath = localStack.getLiteralPath(); - String eiPath = ei.getPath(); - assert (eiPath.equals(localStackLiterapPath)) : "ei.path: " + ei.getPath() + " - localStack.getLiteralPath: " + localStackLiterapPath; - boolean thisIsCodeableConcept = false; - String thisExtension = null; - boolean checkDisplay = true; + String localStackLiterapPath = localStack.getLiteralPath(); + String eiPath = ei.getPath(); + assert (eiPath.equals(localStackLiterapPath)) : "ei.path: " + ei.getPath() + " - localStack.getLiteralPath: " + localStackLiterapPath; + boolean thisIsCodeableConcept = false; + String thisExtension = null; + boolean checkDisplay = true; - checkInvariants(hostContext, errors, profile, typeDefn != null ? typeDefn : ei.definition, resource, ei.getElement(), localStack, true); + checkInvariants(hostContext, errors, profile, typeDefn != null ? typeDefn : checkDefn, resource, ei.getElement(), localStack, true); - ei.getElement().markValidation(profile, ei.definition); - boolean elementValidated = false; - if (type != null) { - if (isPrimitiveType(type)) { - checkPrimitive(hostContext, errors, ei.getPath(), type, ei.definition, ei.getElement(), profile, stack); - } else { - if (ei.definition.hasFixed()) { - checkFixedValue(errors, ei.getPath(), ei.getElement(), ei.definition.getFixed(), profile.getUrl(), ei.definition.getSliceName(), null); - } - if (ei.definition.hasPattern()) { - checkFixedValue(errors, ei.getPath(), ei.getElement(), ei.definition.getPattern(), profile.getUrl(), ei.definition.getSliceName(), null, true); - } - } - if (type.equals("Identifier")) { - checkIdentifier(errors, ei.getPath(), ei.getElement(), ei.definition); - } else if (type.equals("Coding")) { - checkCoding(errors, ei.getPath(), ei.getElement(), profile, ei.definition, inCodeableConcept, checkDisplayInContext, stack); - } else if (type.equals("Quantity")) { - checkQuantity(errors, ei.getPath(), ei.getElement(), profile, ei.definition, stack); - } else if (type.equals("Attachment")) { - checkAttachment(errors, ei.getPath(), ei.getElement(), profile, ei.definition, inCodeableConcept, checkDisplayInContext, stack); - } else if (type.equals("CodeableConcept")) { - checkDisplay = checkCodeableConcept(errors, ei.getPath(), ei.getElement(), profile, ei.definition, stack); - thisIsCodeableConcept = true; - } else if (type.equals("Reference")) { - checkReference(hostContext, errors, ei.getPath(), ei.getElement(), profile, ei.definition, actualType, localStack); - // We only check extensions if we're not in a complex extension or if the element we're dealing with is not defined as part of that complex extension - } else if (type.equals("Extension")) { - Element eurl = ei.getElement().getNamedChild("url"); - if (rule(errors, IssueType.INVALID, ei.getPath(), eurl != null, I18nConstants.EXTENSION_EXT_URL_NOTFOUND)) { - String url = eurl.primitiveValue(); - thisExtension = url; - if (rule(errors, IssueType.INVALID, ei.getPath(), !Utilities.noString(url), I18nConstants.EXTENSION_EXT_URL_NOTFOUND)) { - if (rule(errors, IssueType.INVALID, ei.getPath(), (extensionUrl != null) || Utilities.isAbsoluteUrl(url), I18nConstants.EXTENSION_EXT_URL_ABSOLUTE)) { - checkExtension(hostContext, errors, ei.getPath(), resource, element, ei.getElement(), ei.definition, profile, localStack, stack, extensionUrl); - } - } - } - } else if (type.equals("Resource") || isResource(type)) { - validateContains(hostContext, errors, ei.getPath(), ei.definition, definition, resource, ei.getElement(), localStack, idStatusForEntry(element, ei)); // if - elementValidated = true; - // (str.matches(".*([.,/])work\\1$")) - } else if (Utilities.isAbsoluteUrl(type)) { - StructureDefinition defn = context.fetchTypeDefinition(type); - if (defn != null && hasMapping("http://hl7.org/fhir/terminology-pattern", defn, defn.getSnapshot().getElementFirstRep())) { - List txtype = getMapping("http://hl7.org/fhir/terminology-pattern", defn, defn.getSnapshot().getElementFirstRep()); - if (txtype.contains("CodeableConcept")) { - checkTerminologyCodeableConcept(errors, ei.getPath(), ei.getElement(), profile, ei.definition, stack, defn); - thisIsCodeableConcept = true; - } else if (txtype.contains("Coding")) { - checkTerminologyCoding(errors, ei.getPath(), ei.getElement(), profile, ei.definition, inCodeableConcept, checkDisplayInContext, stack, defn); - } - } - } + ei.getElement().markValidation(profile, checkDefn); + boolean elementValidated = false; + if (type != null) { + if (isPrimitiveType(type)) { + checkPrimitive(hostContext, errors, ei.getPath(), type, checkDefn, ei.getElement(), profile, stack); } else { - if (rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), stack.getLiteralPath(), ei.definition != null, I18nConstants.VALIDATION_VAL_CONTENT_UNKNOWN, ei.getName())) - validateElement(hostContext, errors, profile, ei.definition, null, null, resource, ei.getElement(), type, localStack, false, true, null); - } - StructureDefinition p = null; - String tail = null; - if (profiles.isEmpty()) { - if (type != null) { - p = getProfileForType(type, ei.definition.getType()); - - // If dealing with a primitive type, then we need to check the current child against - // the invariants (constraints) on the current element, because otherwise it only gets - // checked against the primary type's invariants: LLoyd - //if (p.getKind() == StructureDefinitionKind.PRIMITIVETYPE) { - // checkInvariants(hostContext, errors, ei.path, profile, ei.definition, null, null, resource, ei.element); - //} - - rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), p != null, I18nConstants.VALIDATION_VAL_NOTYPE, type); + if (checkDefn.hasFixed()) { + checkFixedValue(errors, ei.getPath(), ei.getElement(), checkDefn.getFixed(), profile.getUrl(), checkDefn.getSliceName(), null); } - } else if (profiles.size() == 1) { - String url = profiles.get(0); + if (checkDefn.hasPattern()) { + checkFixedValue(errors, ei.getPath(), ei.getElement(), checkDefn.getPattern(), profile.getUrl(), checkDefn.getSliceName(), null, true); + } + } + if (type.equals("Identifier")) { + checkIdentifier(errors, ei.getPath(), ei.getElement(), checkDefn); + } else if (type.equals("Coding")) { + checkCoding(errors, ei.getPath(), ei.getElement(), profile, checkDefn, inCodeableConcept, checkDisplayInContext, stack); + } else if (type.equals("Quantity")) { + checkQuantity(errors, ei.getPath(), ei.getElement(), profile, checkDefn, stack); + } else if (type.equals("Attachment")) { + checkAttachment(errors, ei.getPath(), ei.getElement(), profile, checkDefn, inCodeableConcept, checkDisplayInContext, stack); + } else if (type.equals("CodeableConcept")) { + checkDisplay = checkCodeableConcept(errors, ei.getPath(), ei.getElement(), profile, checkDefn, stack); + thisIsCodeableConcept = true; + } else if (type.equals("Reference")) { + checkReference(hostContext, errors, ei.getPath(), ei.getElement(), profile, checkDefn, actualType, localStack); + // We only check extensions if we're not in a complex extension or if the element we're dealing with is not defined as part of that complex extension + } else if (type.equals("Extension")) { + Element eurl = ei.getElement().getNamedChild("url"); + if (rule(errors, IssueType.INVALID, ei.getPath(), eurl != null, I18nConstants.EXTENSION_EXT_URL_NOTFOUND)) { + String url = eurl.primitiveValue(); + thisExtension = url; + if (rule(errors, IssueType.INVALID, ei.getPath(), !Utilities.noString(url), I18nConstants.EXTENSION_EXT_URL_NOTFOUND)) { + if (rule(errors, IssueType.INVALID, ei.getPath(), (extensionUrl != null) || Utilities.isAbsoluteUrl(url), I18nConstants.EXTENSION_EXT_URL_ABSOLUTE)) { + checkExtension(hostContext, errors, ei.getPath(), resource, element, ei.getElement(), checkDefn, profile, localStack, stack, extensionUrl); + } + } + } + } else if (type.equals("Resource") || isResource(type)) { + validateContains(hostContext, errors, ei.getPath(), checkDefn, definition, resource, ei.getElement(), localStack, idStatusForEntry(element, ei)); // if + elementValidated = true; + // (str.matches(".*([.,/])work\\1$")) + } else if (Utilities.isAbsoluteUrl(type)) { + StructureDefinition defn = context.fetchTypeDefinition(type); + if (defn != null && hasMapping("http://hl7.org/fhir/terminology-pattern", defn, defn.getSnapshot().getElementFirstRep())) { + List txtype = getMapping("http://hl7.org/fhir/terminology-pattern", defn, defn.getSnapshot().getElementFirstRep()); + if (txtype.contains("CodeableConcept")) { + checkTerminologyCodeableConcept(errors, ei.getPath(), ei.getElement(), profile, checkDefn, stack, defn); + thisIsCodeableConcept = true; + } else if (txtype.contains("Coding")) { + checkTerminologyCoding(errors, ei.getPath(), ei.getElement(), profile, checkDefn, inCodeableConcept, checkDisplayInContext, stack, defn); + } + } + } + } else { + if (rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), stack.getLiteralPath(), checkDefn != null, I18nConstants.VALIDATION_VAL_CONTENT_UNKNOWN, ei.getName())) + validateElement(hostContext, errors, profile, checkDefn, null, null, resource, ei.getElement(), type, localStack, false, true, null); + } + StructureDefinition p = null; + String tail = null; + if (profiles.isEmpty()) { + if (type != null) { + p = getProfileForType(type, checkDefn.getType()); + + // If dealing with a primitive type, then we need to check the current child against + // the invariants (constraints) on the current element, because otherwise it only gets + // checked against the primary type's invariants: LLoyd + //if (p.getKind() == StructureDefinitionKind.PRIMITIVETYPE) { + // checkInvariants(hostContext, errors, ei.path, profile, ei.definition, null, null, resource, ei.element); + //} + + rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), p != null, I18nConstants.VALIDATION_VAL_NOTYPE, type); + } + } else if (profiles.size() == 1) { + String url = profiles.get(0); + if (url.contains("#")) { + tail = url.substring(url.indexOf("#") + 1); + url = url.substring(0, url.indexOf("#")); + } + p = this.context.fetchResource(StructureDefinition.class, url); + rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), p != null, I18nConstants.VALIDATION_VAL_UNKNOWN_PROFILE, profiles.get(0)); + } else { + elementValidated = true; + HashMap> goodProfiles = new HashMap>(); + HashMap> badProfiles = new HashMap>(); + for (String typeProfile : profiles) { + String url = typeProfile; + tail = null; if (url.contains("#")) { tail = url.substring(url.indexOf("#") + 1); url = url.substring(0, url.indexOf("#")); } - p = this.context.fetchResource(StructureDefinition.class, url); - rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), p != null, I18nConstants.VALIDATION_VAL_UNKNOWN_PROFILE, profiles.get(0)); - } else { - elementValidated = true; - HashMap> goodProfiles = new HashMap>(); - HashMap> badProfiles = new HashMap>(); - for (String typeProfile : profiles) { - String url = typeProfile; - tail = null; - if (url.contains("#")) { - tail = url.substring(url.indexOf("#") + 1); - url = url.substring(0, url.indexOf("#")); - } - p = this.context.fetchResource(StructureDefinition.class, typeProfile); - if (rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), p != null, I18nConstants.VALIDATION_VAL_UNKNOWN_PROFILE, typeProfile)) { - List profileErrors = new ArrayList(); - validateElement(hostContext, profileErrors, p, getElementByTail(p, tail), profile, ei.definition, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension); - if (hasErrors(profileErrors)) - badProfiles.put(typeProfile, profileErrors); - else - goodProfiles.put(typeProfile, profileErrors); + p = this.context.fetchResource(StructureDefinition.class, typeProfile); + if (rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), p != null, I18nConstants.VALIDATION_VAL_UNKNOWN_PROFILE, typeProfile)) { + List profileErrors = new ArrayList(); + validateElement(hostContext, profileErrors, p, getElementByTail(p, tail), profile, checkDefn, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension); + if (hasErrors(profileErrors)) + badProfiles.put(typeProfile, profileErrors); + else + goodProfiles.put(typeProfile, profileErrors); + } + } + if (goodProfiles.size() == 1) { + errors.addAll(goodProfiles.values().iterator().next()); + } else if (goodProfiles.size() == 0) { + rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOMATCH, StringUtils.join("; ", profiles)); + for (String m : badProfiles.keySet()) { + p = this.context.fetchResource(StructureDefinition.class, m); + for (ValidationMessage message : badProfiles.get(m)) { + message.setMessage(message.getMessage() + " (validating against " + p.getUrl() + (p.hasVersion() ? "|" + p.getVersion() : "") + " [" + p.getName() + "])"); + errors.add(message); } } - if (goodProfiles.size() == 1) { - errors.addAll(goodProfiles.values().iterator().next()); - } else if (goodProfiles.size() == 0) { - rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOMATCH, StringUtils.join("; ", profiles)); - for (String m : badProfiles.keySet()) { - p = this.context.fetchResource(StructureDefinition.class, m); - for (ValidationMessage message : badProfiles.get(m)) { - message.setMessage(message.getMessage() + " (validating against " + p.getUrl() + (p.hasVersion() ? "|" + p.getVersion() : "") + " [" + p.getName() + "])"); - errors.add(message); - } - } - } else { - warning(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_MULTIPLEMATCHES, StringUtils.join("; ", goodProfiles.keySet())); - for (String m : goodProfiles.keySet()) { - p = this.context.fetchResource(StructureDefinition.class, m); - for (ValidationMessage message : goodProfiles.get(m)) { - message.setMessage(message.getMessage() + " (validating against " + p.getUrl() + (p.hasVersion() ? "|" + p.getVersion() : "") + " [" + p.getName() + "])"); - errors.add(message); - } + } else { + warning(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_MULTIPLEMATCHES, StringUtils.join("; ", goodProfiles.keySet())); + for (String m : goodProfiles.keySet()) { + p = this.context.fetchResource(StructureDefinition.class, m); + for (ValidationMessage message : goodProfiles.get(m)) { + message.setMessage(message.getMessage() + " (validating against " + p.getUrl() + (p.hasVersion() ? "|" + p.getVersion() : "") + " [" + p.getName() + "])"); + errors.add(message); } } } - if (p != null) { - trackUsage(p, hostContext, element); + } + if (p != null) { + trackUsage(p, hostContext, element); - if (!elementValidated) { - if (ei.getElement().getSpecial() == SpecialElement.BUNDLE_ENTRY || ei.getElement().getSpecial() == SpecialElement.BUNDLE_OUTCOME || ei.getElement().getSpecial() == SpecialElement.PARAMETER) - validateElement(hostContext, errors, p, getElementByTail(p, tail), profile, ei.definition, ei.getElement(), ei.getElement(), type, localStack.resetIds(), thisIsCodeableConcept, checkDisplay, thisExtension); - else - validateElement(hostContext, errors, p, getElementByTail(p, tail), profile, ei.definition, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension); - } - int index = profile.getSnapshot().getElement().indexOf(ei.definition); - if (index < profile.getSnapshot().getElement().size() - 1) { - String nextPath = profile.getSnapshot().getElement().get(index + 1).getPath(); - if (!nextPath.equals(ei.definition.getPath()) && nextPath.startsWith(ei.definition.getPath())) - validateElement(hostContext, errors, profile, ei.definition, null, null, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension); - } + if (!elementValidated) { + if (ei.getElement().getSpecial() == SpecialElement.BUNDLE_ENTRY || ei.getElement().getSpecial() == SpecialElement.BUNDLE_OUTCOME || ei.getElement().getSpecial() == SpecialElement.PARAMETER) + validateElement(hostContext, errors, p, getElementByTail(p, tail), profile, checkDefn, ei.getElement(), ei.getElement(), type, localStack.resetIds(), thisIsCodeableConcept, checkDisplay, thisExtension); + else + validateElement(hostContext, errors, p, getElementByTail(p, tail), profile, checkDefn, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension); + } + int index = profile.getSnapshot().getElement().indexOf(checkDefn); + if (index < profile.getSnapshot().getElement().size() - 1) { + String nextPath = profile.getSnapshot().getElement().get(index + 1).getPath(); + if (!nextPath.equals(checkDefn.getPath()) && nextPath.startsWith(checkDefn.getPath())) + validateElement(hostContext, errors, profile, checkDefn, null, null, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension); } } } @@ -5091,4 +5115,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat return questionnaireMode; } + public boolean isWantCheckSnapshotUnchanged() { + return wantCheckSnapshotUnchanged; + } + + public void setWantCheckSnapshotUnchanged(boolean wantCheckSnapshotUnchanged) { + this.wantCheckSnapshotUnchanged = wantCheckSnapshotUnchanged; + } + } \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java index a51f75ef1..24ccf2b73 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java @@ -1,12 +1,9 @@ package org.hl7.fhir.validation.instance; import java.io.IOException; -import java.io.InputStream; -import org.hl7.fhir.convertors.VersionConvertorConstants; import org.hl7.fhir.exceptions.FHIRFormatError; import org.hl7.fhir.r5.formats.JsonParser; -import org.hl7.fhir.r5.formats.XmlParser; import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.utilities.Utilities; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/MeasureContext.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/MeasureContext.java index 63cee2f80..e5eefdfa5 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/MeasureContext.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/MeasureContext.java @@ -1,19 +1,14 @@ package org.hl7.fhir.validation.instance.type; -import java.io.IOException; import java.util.ArrayList; import java.util.List; -import javax.xml.parsers.ParserConfigurationException; - import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.model.Attachment; -import org.hl7.fhir.r5.model.Coding; import org.hl7.fhir.r5.model.Library; import org.hl7.fhir.r5.model.Measure; import org.hl7.fhir.r5.model.Measure.MeasureGroupComponent; import org.hl7.fhir.utilities.xml.XMLUtil; -import org.xml.sax.SAXException; public class MeasureContext { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/MeasureValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/MeasureValidator.java index ebcbbc00b..ad12b1f2f 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/MeasureValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/MeasureValidator.java @@ -5,7 +5,6 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigDecimal; -import java.math.BigInteger; import java.util.ArrayList; import java.util.List; @@ -22,27 +21,23 @@ import org.hl7.fhir.r5.model.Coding; import org.hl7.fhir.r5.model.FhirPublication; import org.hl7.fhir.r5.model.Library; import org.hl7.fhir.r5.model.Measure; -import org.hl7.fhir.r5.model.Resource; -import org.hl7.fhir.r5.renderers.DataRenderer; -import org.hl7.fhir.r5.renderers.utils.RenderingContext; -import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode; import org.hl7.fhir.r5.model.Measure.MeasureGroupComponent; import org.hl7.fhir.r5.model.Measure.MeasureGroupPopulationComponent; import org.hl7.fhir.r5.model.Measure.MeasureGroupStratifierComponent; +import org.hl7.fhir.r5.model.Resource; +import org.hl7.fhir.r5.renderers.DataRenderer; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.i18n.I18nConstants; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; import org.hl7.fhir.utilities.validation.ValidationMessage.Source; import org.hl7.fhir.utilities.xml.XMLUtil; -import org.hl7.fhir.validation.instance.utils.NodeStack; import org.hl7.fhir.validation.BaseValidator; import org.hl7.fhir.validation.TimeTracker; +import org.hl7.fhir.validation.instance.utils.NodeStack; import org.hl7.fhir.validation.instance.utils.ValidatorHostContext; import org.w3c.dom.Document; -import net.sf.saxon.tree.tiny.LargeStringBuffer; - public class MeasureValidator extends BaseValidator { public MeasureValidator(IWorkerContext context, TimeTracker timeTracker) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/QuestionnaireValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/QuestionnaireValidator.java index d37ffa2a1..94b7cf1c9 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/QuestionnaireValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/QuestionnaireValidator.java @@ -23,26 +23,25 @@ import org.hl7.fhir.r5.elementmodel.ObjectConverter; import org.hl7.fhir.r5.formats.IParser.OutputStyle; import org.hl7.fhir.r5.model.Coding; import org.hl7.fhir.r5.model.DateType; +import org.hl7.fhir.r5.model.Enumerations.FHIRVersion; import org.hl7.fhir.r5.model.FhirPublication; import org.hl7.fhir.r5.model.IntegerType; import org.hl7.fhir.r5.model.Questionnaire; +import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemAnswerOptionComponent; +import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent; +import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemType; import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.StringType; import org.hl7.fhir.r5.model.TimeType; import org.hl7.fhir.r5.model.ValueSet; -import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent; -import org.hl7.fhir.r5.model.Enumerations.FHIRVersion; -import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemAnswerOptionComponent; -import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent; -import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemType; import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.i18n.I18nConstants; import org.hl7.fhir.utilities.validation.ValidationMessage; -import org.hl7.fhir.utilities.validation.ValidationOptions; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; import org.hl7.fhir.utilities.validation.ValidationMessage.Source; +import org.hl7.fhir.utilities.validation.ValidationOptions; import org.hl7.fhir.validation.BaseValidator; import org.hl7.fhir.validation.TimeTracker; import org.hl7.fhir.validation.Validator.QuestionnaireMode; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/SearchParameterValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/SearchParameterValidator.java index 98dce2a18..669f9646e 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/SearchParameterValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/SearchParameterValidator.java @@ -5,14 +5,12 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; -import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.model.ExpressionNode; import org.hl7.fhir.r5.model.ExpressionNode.Kind; import org.hl7.fhir.r5.model.ExpressionNode.Operation; import org.hl7.fhir.r5.model.SearchParameter; -import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.i18n.I18nConstants; @@ -21,7 +19,6 @@ import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; import org.hl7.fhir.utilities.validation.ValidationMessage.Source; import org.hl7.fhir.validation.BaseValidator; import org.hl7.fhir.validation.TimeTracker; -import org.hl7.fhir.validation.instance.type.SearchParameterValidator.FhirPathSorter; import org.hl7.fhir.validation.instance.utils.NodeStack; public class SearchParameterValidator extends BaseValidator { 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 f7631ef8b..86b805852 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 @@ -3,18 +3,15 @@ package org.hl7.fhir.validation.instance.type; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; import java.util.Comparator; import java.util.List; -import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.convertors.VersionConvertor_10_50; import org.hl7.fhir.convertors.VersionConvertor_14_50; import org.hl7.fhir.convertors.VersionConvertor_30_50; import org.hl7.fhir.convertors.VersionConvertor_40_50; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.r5.conformance.ProfileUtilities; -import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider; import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.elementmodel.Manager; @@ -22,14 +19,10 @@ import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat; import org.hl7.fhir.r5.formats.IParser.OutputStyle; import org.hl7.fhir.r5.model.ElementDefinition; import org.hl7.fhir.r5.model.ExpressionNode; -import org.hl7.fhir.r5.model.ExpressionNode.Kind; -import org.hl7.fhir.r5.model.ExpressionNode.Operation; +import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule; -import org.hl7.fhir.r5.model.SearchParameter; -import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.hl7.fhir.r5.utils.ToolingExtensions; -import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.i18n.I18nConstants; import org.hl7.fhir.utilities.validation.ValidationMessage; @@ -37,7 +30,6 @@ import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; import org.hl7.fhir.utilities.validation.ValidationMessage.Source; import org.hl7.fhir.validation.BaseValidator; import org.hl7.fhir.validation.TimeTracker; -import org.hl7.fhir.validation.instance.type.StructureDefinitionValidator.FhirPathSorter; import org.hl7.fhir.validation.instance.utils.NodeStack; public class StructureDefinitionValidator extends BaseValidator { @@ -52,16 +44,18 @@ public class StructureDefinitionValidator extends BaseValidator { } private FHIRPathEngine fpe; + private boolean wantCheckSnapshotUnchanged; - public StructureDefinitionValidator(IWorkerContext context, TimeTracker timeTracker, FHIRPathEngine fpe) { + public StructureDefinitionValidator(IWorkerContext context, TimeTracker timeTracker, FHIRPathEngine fpe, boolean wantCheckSnapshotUnchanged) { super(context); source = Source.InstanceValidator; this.fpe = fpe; this.timeTracker = timeTracker; + this.wantCheckSnapshotUnchanged = wantCheckSnapshotUnchanged; } public void validateStructureDefinition(List errors, Element src, NodeStack stack) { - StructureDefinition sd; + StructureDefinition sd = null; try { sd = loadAsSD(src); List snapshot = sd.getSnapshot().getElement(); @@ -85,7 +79,7 @@ public class StructureDefinitionValidator extends BaseValidator { errors.add(msg); } } - if (!snapshot.isEmpty()) { + if (!snapshot.isEmpty() && wantCheckSnapshotUnchanged) { int was = snapshot.size(); int is = sd.getSnapshot().getElement().size(); rule(errors, IssueType.NOTFOUND, stack.getLiteralPath(), was == is, I18nConstants.SNAPSHOT_EXISTING_PROBLEM, was, is); @@ -99,29 +93,33 @@ public class StructureDefinitionValidator extends BaseValidator { List differentials = src.getChildrenByName("differential"); List snapshots = src.getChildrenByName("snapshot"); for (Element differential : differentials) { - validateElementList(errors, differential, stack.push(differential, -1, null, null), false, snapshots.size() > 0); + validateElementList(errors, differential, stack.push(differential, -1, null, null), false, snapshots.size() > 0, sd); } for (Element snapshot : snapshots) { - validateElementList(errors, snapshot, stack.push(snapshot, -1, null, null), true, true); + validateElementList(errors, snapshot, stack.push(snapshot, -1, null, null), true, true, sd); } } - private void validateElementList(List errors, Element elementList, NodeStack stack, boolean snapshot, boolean hasSnapshot) { + private void validateElementList(List errors, Element elementList, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd) { List elements = elementList.getChildrenByName("element"); int cc = 0; for (Element element : elements) { - validateElementDefinition(errors, element, stack.push(element, cc, null, null), snapshot, hasSnapshot); + validateElementDefinition(errors, element, stack.push(element, cc, null, null), snapshot, hasSnapshot, sd); cc++; } } - private void validateElementDefinition(List errors, Element element, NodeStack stack, boolean snapshot, boolean hasSnapshot) { + private void validateElementDefinition(List errors, Element element, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd) { boolean typeMustSupport = false; List types = element.getChildrenByName("type"); for (Element type : types) { if (hasMustSupportExtension(type)) { typeMustSupport = true; } + // check the stated profile - must be a constraint on the type + if (snapshot || sd != null) { + validateElementType(errors, type, stack.push(type, -1, null, null), sd, element.getChildValue("path")); + } } if (typeMustSupport) { if (snapshot) { @@ -132,6 +130,53 @@ public class StructureDefinitionValidator extends BaseValidator { } } + private void validateElementType(List errors, Element type, NodeStack stack, StructureDefinition sd, String path) { + String code = type.getNamedChildValue("code"); + if (code == null && path != null) { + code = getTypeCodeFromSD(sd, path); + } + if (code != null) { + List profiles = type.getChildrenByName("profile"); + for (Element profile : profiles) { + validateTypeProfile(errors, profile, code, stack.push(type, -1, null, null)); + } + } + } + + private String getTypeCodeFromSD(StructureDefinition sd, String path) { + ElementDefinition ed = null; + for (ElementDefinition t : sd.getSnapshot().getElement()) { + if (t.hasPath() && t.getPath().equals(path)) { + if (ed == null) { + ed = t; + } else { + return null; // more than one match, we don't know which is which + } + } + } + return ed != null && ed.getType().size() == 1 ? ed.getTypeFirstRep().getCode() : null; + } + + private void validateTypeProfile(List errors, Element profile, String code, NodeStack stack) { + String p = profile.primitiveValue(); + StructureDefinition sd = context.fetchResource(StructureDefinition.class, p); + if (warning(errors, IssueType.EXCEPTION, stack.getLiteralPath(), sd != null, I18nConstants.SD_ED_TYPE_PROFILE_UNKNOWN, p)) { + String t = determineBaseType(sd); + 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); + } + } + } + + private String determineBaseType(StructureDefinition sd) { + while (sd != null && !sd.hasType() && sd.getDerivation() == TypeDerivationRule.CONSTRAINT) { + sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition()); + } + return sd == null ? null : sd.getType(); + } + private boolean hasMustSupportExtension(Element type) { if ("true".equals(getExtensionValue(type, ToolingExtensions.EXT_MUST_SUPPORT))) { return true; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ValueSetValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ValueSetValidator.java index b3d4c0e3c..7ce5a8f71 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ValueSetValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ValueSetValidator.java @@ -3,14 +3,13 @@ package org.hl7.fhir.validation.instance.type; import java.util.ArrayList; import java.util.List; -import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.context.IWorkerContext.CodingValidationRequest; import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult; import org.hl7.fhir.r5.elementmodel.Element; -import org.hl7.fhir.r5.model.CodeSystem; import org.hl7.fhir.r5.model.Coding; import org.hl7.fhir.r5.model.Resource; +import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; @@ -22,7 +21,6 @@ import org.hl7.fhir.utilities.validation.ValidationOptions; import org.hl7.fhir.validation.BaseValidator; import org.hl7.fhir.validation.TimeTracker; import org.hl7.fhir.validation.instance.InstanceValidator; -import org.hl7.fhir.validation.instance.type.ValueSetValidator.VSCodingValidationRequest; import org.hl7.fhir.validation.instance.utils.NodeStack; public class ValueSetValidator extends BaseValidator { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ChildIterator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ChildIterator.java index 7933df9c0..7d1520046 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ChildIterator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ChildIterator.java @@ -1,8 +1,8 @@ package org.hl7.fhir.validation.instance.utils; import org.hl7.fhir.r5.elementmodel.Element; -import org.hl7.fhir.validation.instance.InstanceValidator; import org.hl7.fhir.utilities.Utilities; +import org.hl7.fhir.validation.instance.InstanceValidator; public class ChildIterator { private final InstanceValidator instanceValidator; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ElementInfo.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ElementInfo.java index 88e850a79..a5e0d9cad 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ElementInfo.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ElementInfo.java @@ -1,11 +1,11 @@ package org.hl7.fhir.validation.instance.utils; +import java.util.List; + import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.model.ElementDefinition; import org.hl7.fhir.utilities.validation.ValidationMessage; -import java.util.List; - public class ElementInfo { public List sliceInfo; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/EntrySummary.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/EntrySummary.java index d743fbe9f..07b24f64a 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/EntrySummary.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/EntrySummary.java @@ -1,10 +1,10 @@ package org.hl7.fhir.validation.instance.utils; -import org.hl7.fhir.r5.elementmodel.Element; - import java.util.ArrayList; import java.util.List; +import org.hl7.fhir.r5.elementmodel.Element; + public class EntrySummary { Element entry; 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 abaa542c3..cf32d7f03 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 @@ -2,10 +2,8 @@ package org.hl7.fhir.validation.instance.utils; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.elementmodel.Element; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ResolvedReference.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ResolvedReference.java index 4157cca0b..eb706982a 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ResolvedReference.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ResolvedReference.java @@ -2,7 +2,6 @@ package org.hl7.fhir.validation.instance.utils; import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.model.StructureDefinition; -import org.hl7.fhir.validation.instance.InstanceValidator; public class ResolvedReference { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ResourceValidationTracker.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ResourceValidationTracker.java index 87248ac1c..67e7221bd 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ResourceValidationTracker.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ResourceValidationTracker.java @@ -1,13 +1,13 @@ package org.hl7.fhir.validation.instance.utils; -import org.hl7.fhir.r5.model.StructureDefinition; -import org.hl7.fhir.utilities.validation.ValidationMessage; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.hl7.fhir.r5.model.StructureDefinition; +import org.hl7.fhir.utilities.validation.ValidationMessage; + /** * The validator keeps one of these classes for each resource it validates (e.g. when chasing references) *

diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ValidatorHostContext.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ValidatorHostContext.java index 523a01a23..dcbe1e429 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ValidatorHostContext.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ValidatorHostContext.java @@ -1,15 +1,13 @@ package org.hl7.fhir.validation.instance.utils; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.utilities.validation.ValidationMessage; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Stack; - public class ValidatorHostContext { private Object appContext; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/packages/PackageValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/packages/PackageValidator.java index 6304f71d4..183725c04 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/packages/PackageValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/packages/PackageValidator.java @@ -10,8 +10,8 @@ import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.npm.CachingPackageClient; 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.npm.PackageClient.PackageInfo; +import org.hl7.fhir.utilities.npm.ToolsVersion; public class PackageValidator { diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/comparison/tests/ComparisonTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/comparison/tests/ComparisonTests.java index d0cdf5425..bdebe8302 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/comparison/tests/ComparisonTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/comparison/tests/ComparisonTests.java @@ -1,15 +1,25 @@ package org.hl7.fhir.comparison.tests; -import com.google.common.base.Charsets; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Stream; + import org.apache.commons.io.IOUtils; import org.hl7.fhir.convertors.VersionConvertor_10_50; import org.hl7.fhir.convertors.VersionConvertor_14_50; import org.hl7.fhir.convertors.VersionConvertor_30_50; import org.hl7.fhir.convertors.VersionConvertor_40_50; -import org.hl7.fhir.convertors.loaders.R4ToR5Loader; import org.hl7.fhir.convertors.loaders.BaseLoaderR5.NullLoaderKnowledgeProvider; +import org.hl7.fhir.convertors.loaders.R4ToR5Loader; import org.hl7.fhir.exceptions.DefinitionException; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRFormatError; @@ -49,18 +59,9 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.stream.Stream; +import com.google.common.base.Charsets; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; public class ComparisonTests { diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/R3R4ConversionTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/R3R4ConversionTests.java index ba1bcce23..8513af3c1 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/R3R4ConversionTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/R3R4ConversionTests.java @@ -1,6 +1,21 @@ package org.hl7.fhir.conversion.tests; -import com.google.gson.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import javax.xml.parsers.ParserConfigurationException; import org.hl7.fhir.convertors.loaders.R3ToR4Loader; import org.hl7.fhir.exceptions.DefinitionException; @@ -11,8 +26,16 @@ import org.hl7.fhir.r4.context.SimpleWorkerContext; import org.hl7.fhir.r4.elementmodel.Element; import org.hl7.fhir.r4.elementmodel.Manager; import org.hl7.fhir.r4.formats.IParser.OutputStyle; -import org.hl7.fhir.r4.model.*; +import org.hl7.fhir.r4.model.Base; +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.MetadataResource; +import org.hl7.fhir.r4.model.PractitionerRole; +import org.hl7.fhir.r4.model.Resource; +import org.hl7.fhir.r4.model.ResourceFactory; +import org.hl7.fhir.r4.model.StructureDefinition; import org.hl7.fhir.r4.model.StructureDefinition.StructureDefinitionKind; +import org.hl7.fhir.r4.model.StructureMap; +import org.hl7.fhir.r4.model.UriType; import org.hl7.fhir.r4.test.utils.TestingUtilities; import org.hl7.fhir.r4.utils.IResourceValidator; import org.hl7.fhir.r4.utils.IResourceValidator.IValidatorResourceFetcher; @@ -32,12 +55,11 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.xml.sax.SAXException; -import javax.xml.parsers.ParserConfigurationException; -import java.io.*; -import java.util.*; -import java.util.stream.Stream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; @Disabled public class R3R4ConversionTests implements ITransformerServices, IValidatorResourceFetcher { diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/SnapShotGenerationXTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/SnapShotGenerationXTests.java index 8b616af25..0eb5e0a0c 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/SnapShotGenerationXTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/SnapShotGenerationXTests.java @@ -1,5 +1,14 @@ package org.hl7.fhir.conversion.tests; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.parsers.ParserConfigurationException; + import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.NotImplementedException; import org.hl7.fhir.exceptions.DefinitionException; @@ -18,12 +27,12 @@ import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind; import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule; +import org.hl7.fhir.r5.model.TypeDetails; +import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.renderers.RendererFactory; import org.hl7.fhir.r5.renderers.utils.RenderingContext; import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode; import org.hl7.fhir.r5.test.utils.TestingUtilities; -import org.hl7.fhir.r5.model.TypeDetails; -import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext; import org.hl7.fhir.r5.utils.IResourceValidator; @@ -38,14 +47,6 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; -import javax.xml.parsers.ParserConfigurationException; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - public class SnapShotGenerationXTests { public enum TestFetchMode { diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/UtilitiesXTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/UtilitiesXTests.java index 1e65b8cb7..40fe98685 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/UtilitiesXTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/UtilitiesXTests.java @@ -46,14 +46,14 @@ import javax.xml.parsers.DocumentBuilderFactory; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.IOUtils; import org.fhir.ucum.UcumEssenceService; +import org.hl7.fhir.convertors.loaders.BaseLoaderR5.NullLoaderKnowledgeProvider; import org.hl7.fhir.convertors.loaders.R2016MayToR5Loader; import org.hl7.fhir.convertors.loaders.R2ToR5Loader; import org.hl7.fhir.convertors.loaders.R3ToR5Loader; import org.hl7.fhir.convertors.loaders.R4ToR5Loader; -import org.hl7.fhir.convertors.loaders.BaseLoaderR5.NullLoaderKnowledgeProvider; import org.hl7.fhir.r5.context.IWorkerContext; -import org.hl7.fhir.r5.context.SimpleWorkerContext; import org.hl7.fhir.r5.context.IWorkerContext.IContextResourceLoader; +import org.hl7.fhir.r5.context.SimpleWorkerContext; import org.hl7.fhir.r5.model.Parameters; import org.hl7.fhir.utilities.CSFile; import org.hl7.fhir.utilities.TextFile; diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/r5/test/FHIRMappingLanguageTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/r5/test/FHIRMappingLanguageTests.java index 4498f12ef..fa7aa045c 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/r5/test/FHIRMappingLanguageTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/r5/test/FHIRMappingLanguageTests.java @@ -6,7 +6,6 @@ import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; - import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; @@ -24,7 +23,6 @@ import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.xml.XMLUtil; import org.hl7.fhir.validation.ValidationEngine; - import org.hl7.fhir.validation.instance.InstanceValidatorFactory; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/BaseRestTest.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/BaseRestTest.java index 6b7a50226..3c30068b4 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/BaseRestTest.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/BaseRestTest.java @@ -1,14 +1,15 @@ package org.hl7.fhir.validation.cli; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; + import org.apache.http.HttpResponse; import org.apache.http.util.EntityUtils; import org.hl7.fhir.validation.cli.model.CliContext; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; -import java.io.IOException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; public abstract class BaseRestTest { diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/ValidatorGuiTest.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/ValidatorGuiTest.java index 652d80ca9..40e7fd46c 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/ValidatorGuiTest.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/ValidatorGuiTest.java @@ -1,17 +1,8 @@ package org.hl7.fhir.validation.cli; -import io.github.bonigarcia.wdm.WebDriverManager; -import org.hl7.fhir.r5.elementmodel.Manager; -import org.hl7.fhir.r5.model.FhirPublication; -import org.hl7.fhir.r5.model.OperationOutcome; -import org.hl7.fhir.r5.test.utils.TestingUtilities; -import org.hl7.fhir.r5.utils.EOperationOutcome; -import org.hl7.fhir.validation.ValidationEngine; +import java.io.IOException; + import org.hl7.fhir.validation.cli.model.CliContext; -import org.hl7.fhir.validation.cli.model.FileInfo; -import org.hl7.fhir.validation.cli.model.ValidationRequest; -import org.hl7.fhir.validation.cli.model.ValidationResponse; -import org.hl7.fhir.validation.cli.services.ValidationService; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -19,10 +10,7 @@ import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; -import java.io.IOException; -import java.io.InputStream; -import java.net.URISyntaxException; -import java.util.Arrays; +import io.github.bonigarcia.wdm.WebDriverManager; class ValidatorGuiTest { diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/controller/HttpGetContextTest.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/controller/HttpGetContextTest.java index c000d7016..fcc13ad4c 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/controller/HttpGetContextTest.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/controller/HttpGetContextTest.java @@ -1,5 +1,7 @@ package org.hl7.fhir.validation.cli.controller; +import java.io.IOException; + import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.methods.HttpGet; @@ -13,8 +15,6 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.io.IOException; - class HttpGetContextTest extends BaseRestTest { private final String GET_CONTEXT_URL = "http://localhost:" + ValidatorGui.getPort() + "/context"; diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/controller/HttpPutContextTest.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/controller/HttpPutContextTest.java index 70adff130..d166f1fa0 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/controller/HttpPutContextTest.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/controller/HttpPutContextTest.java @@ -1,12 +1,12 @@ package org.hl7.fhir.validation.cli.controller; -import io.javalin.http.Context; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; +import io.javalin.http.Context; class HttpPutContextTest { diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/JsonSchemaTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/JsonSchemaTests.java index 3c52dab69..1a202fce5 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/JsonSchemaTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/JsonSchemaTests.java @@ -1,5 +1,8 @@ package org.hl7.fhir.validation.tests; +import java.io.FileNotFoundException; +import java.io.IOException; + import org.everit.json.schema.Schema; import org.everit.json.schema.ValidationException; import org.everit.json.schema.loader.SchemaLoader; @@ -9,9 +12,6 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.FileNotFoundException; -import java.io.IOException; - public class JsonSchemaTests { diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/LoadIgTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/LoadIgTests.java index 1f878b65c..9367fef4a 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/LoadIgTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/LoadIgTests.java @@ -8,8 +8,6 @@ import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.validation.ValidationEngine; import org.junit.Test; -import net.sf.saxon.expr.instruct.Message; - public class LoadIgTests { @Test diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/TransformationTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/TransformationTests.java index 44e647aaf..81ae0cdc4 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/TransformationTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/TransformationTests.java @@ -3,8 +3,8 @@ package org.hl7.fhir.validation.tests; import java.io.File; import org.hl7.fhir.r4.test.utils.TestingUtilities; -import org.hl7.fhir.validation.Validator; import org.hl7.fhir.utilities.Utilities; +import org.hl7.fhir.validation.Validator; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; 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 742437fe3..18be9008a 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 @@ -1,5 +1,8 @@ package org.hl7.fhir.validation.tests; +import java.util.ArrayList; +import java.util.List; + import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat; import org.hl7.fhir.r5.model.FhirPublication; import org.hl7.fhir.r5.model.OperationOutcome; @@ -11,9 +14,6 @@ import org.hl7.fhir.validation.tests.utilities.TestUtilities; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import java.util.ArrayList; -import java.util.List; - public class ValidationEngineTests { private static final String DEF_TX = "http://tx.fhir.org"; diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTests.java index 7c8671c66..1c36fe32c 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTests.java @@ -1,10 +1,19 @@ package org.hl7.fhir.validation.tests; -import com.google.common.base.Charsets; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Map.Entry; + import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.NotImplementedException; import org.hl7.fhir.convertors.VersionConvertor_10_50; @@ -43,11 +52,11 @@ import org.hl7.fhir.r5.utils.IResourceValidator.ReferenceValidationPolicy; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; +import org.hl7.fhir.utilities.npm.NpmPackage; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; import org.hl7.fhir.validation.ValidationEngine; import org.hl7.fhir.validation.instance.InstanceValidator; - import org.junit.AfterClass; import org.junit.Assert; import org.junit.Test; @@ -55,19 +64,11 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; +import com.google.common.base.Charsets; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; @RunWith(Parameterized.class) public class ValidationTests implements IEvaluationContext, IValidatorResourceFetcher { @@ -100,7 +101,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe private String version; private String name; - private static final String DEF_TX = "http://tx.fhir.org"; + private static final String DEF_TX = "http://tx.fhir.org"; // private static final String DEF_TX = "http://local.fhir.org:960"; private static Map ve = new HashMap<>(); private static ValidationEngine vCurr; @@ -154,8 +155,8 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe return; String testCaseContent = TestingUtilities.loadTestResource("validator", name); - InstanceValidator val = vCurr.getValidator(); + val.setWantCheckSnapshotUnchanged(true); val.getContext().setClientRetryCount(4); val.setDebug(false); if (content.has("allowed-extension-domain")) @@ -170,7 +171,13 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe val.setFetcher(this); if (content.has("packages")) { for (JsonElement e : content.getAsJsonArray("packages")) { - vCurr.loadIg(e.getAsString(), true); + String n = e.getAsString(); + InputStream cnt = n.endsWith(".tgz") ? TestingUtilities.loadTestResourceStream("validator", n) : null; + if (cnt != null) { + vCurr.loadPackage(NpmPackage.fromPackage(cnt)); + } else { + vCurr.loadIg(n, true); + } } } if (content.has("crumb-trail")) { diff --git a/pom.xml b/pom.xml index 8e975d598..bb4f19616 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 5.1.0 - 1.1.45 + 1.1.46 5.6.2 3.0.0-M4 0.8.5