commit
76411218ac
|
@ -293,7 +293,6 @@ local.properties
|
|||
/org.hl7.fhir.r5/src/test/resources/snapshot-generation/t9-actual.xml
|
||||
/org.hl7.fhir.r5/src/test/resources/snapshot-generation/dv1-actual.xml
|
||||
/org.hl7.fhir.r5/src/test/resources/snapshot-generation/t45-actual.xml
|
||||
/org.hl7.fhir.r4b
|
||||
/org.hl7.fhir.r5/src/test/resources/gen/gen.xml
|
||||
/org.hl7.fhir.r5/src/test/resources/graphql/*.out
|
||||
/org.hl7.fhir.validation/src/test/resources/comparison/output
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
## Validator Changes
|
||||
|
||||
* no changes
|
||||
* Handle reslicing within the same profile
|
||||
* Fix up wrong handling of context on exists() in FHIRPath
|
||||
* Add hints to profiles around behavior of pattern on repeating elements
|
||||
* Ignore all tooling extensions when validating
|
||||
*
|
||||
|
||||
## Other code changes
|
||||
|
||||
|
|
|
@ -1168,7 +1168,15 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (diffMatches.get(0).hasType() && "Reference".equals(diffMatches.get(0).getType().get(0).getWorkingCode()) && !isValidType(diffMatches.get(0).getType().get(0), currentBase)) {
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.VALIDATION_VAL_ILLEGAL_TYPE_CONSTRAINT, url, diffMatches.get(0).getPath(), diffMatches.get(0).getType().get(0), currentBase.typeSummary()));
|
||||
}
|
||||
if (diffMatches.get(0).hasType() && diffMatches.get(0).getType().size() == 1 && diffMatches.get(0).getType().get(0).hasProfile() && !"Reference".equals(diffMatches.get(0).getType().get(0).getWorkingCode())) {
|
||||
String id = diffMatches.get(0).getId();
|
||||
String lid = tail(id);
|
||||
if (lid.contains("/")) {
|
||||
// the template comes from the snapshot of the base
|
||||
generateIds(result.getElement(), url, srcSD.getType());
|
||||
String baseId = id.substring(0, id.length()-lid.length()) + lid.substring(0, lid.indexOf("/")); // this is wrong if there's more than one reslice (todo: one thing at a time)
|
||||
template = getById(result.getElement(), baseId);
|
||||
|
||||
} else if (diffMatches.get(0).hasType() && diffMatches.get(0).getType().size() == 1 && diffMatches.get(0).getType().get(0).hasProfile() && !"Reference".equals(diffMatches.get(0).getType().get(0).getWorkingCode())) {
|
||||
CanonicalType p = diffMatches.get(0).getType().get(0).getProfile().get(0);
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, p.getValue());
|
||||
if (sd == null && xver != null && xver.matchingUrl(p.getValue())) {
|
||||
|
@ -1928,6 +1936,15 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
return res;
|
||||
}
|
||||
|
||||
private ElementDefinition getById(List<ElementDefinition> list, String baseId) {
|
||||
for (ElementDefinition t : list) {
|
||||
if (baseId.equals(t.getId())) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void updateConstraintSources(ElementDefinition ed, String url) {
|
||||
for (ElementDefinitionConstraintComponent c : ed.getConstraint()) {
|
||||
if (!c.hasSource()) {
|
||||
|
@ -2507,19 +2524,22 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (webUrl != null) {
|
||||
// also, must touch up the markdown
|
||||
if (element.hasDefinition())
|
||||
element.setDefinition(processRelativeUrls(element.getDefinition(), webUrl, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames, true));
|
||||
element.setDefinition(processRelativeUrls(element.getDefinition(), webUrl, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames, null, false));
|
||||
if (element.hasComment())
|
||||
element.setComment(processRelativeUrls(element.getComment(), webUrl, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames, true));
|
||||
element.setComment(processRelativeUrls(element.getComment(), webUrl, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames, null, false));
|
||||
if (element.hasRequirements())
|
||||
element.setRequirements(processRelativeUrls(element.getRequirements(), webUrl, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames, true));
|
||||
element.setRequirements(processRelativeUrls(element.getRequirements(), webUrl, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames, null, false));
|
||||
if (element.hasMeaningWhenMissing())
|
||||
element.setMeaningWhenMissing(processRelativeUrls(element.getMeaningWhenMissing(), webUrl, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames, true));
|
||||
element.setMeaningWhenMissing(processRelativeUrls(element.getMeaningWhenMissing(), webUrl, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames, null, false));
|
||||
}
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
public static String processRelativeUrls(String markdown, String webUrl, String basePath, List<String> resourceNames, Set<String> filenames, boolean processRelatives) {
|
||||
public static String processRelativeUrls(String markdown, String webUrl, String basePath, List<String> resourceNames, Set<String> baseFilenames, Set<String> localFilenames, boolean processRelatives) {
|
||||
if (markdown == null) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder b = new StringBuilder();
|
||||
int i = 0;
|
||||
while (i < markdown.length()) {
|
||||
|
@ -2540,7 +2560,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
// This code is trying to guess which relative references are actually to the
|
||||
// base specification.
|
||||
//
|
||||
if (isLikelySourceURLReference(url, resourceNames, filenames)) {
|
||||
if (isLikelySourceURLReference(url, resourceNames, baseFilenames, localFilenames)) {
|
||||
b.append("](");
|
||||
b.append(basePath);
|
||||
i = i + 1;
|
||||
|
@ -2549,7 +2569,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
// disabled 7-Dec 2021 GDG - we don't want to fool with relative URLs at all?
|
||||
// re-enabled 11-Feb 2022 GDG - we do want to do this. At least, $assemble in davinci-dtr, where the markdown comes from the SDC IG, and an SDC local reference must be changed to point to SDC. in this case, it's called when generating snapshots
|
||||
// added processRelatives parameter to deal with this (well, to try)
|
||||
if (processRelatives && webUrl != null) {
|
||||
if (processRelatives && webUrl != null && !issLocalFileName(url, localFilenames)) {
|
||||
// System.out.println("Making "+url+" relative to '"+webUrl+"'");
|
||||
b.append(webUrl);
|
||||
} else {
|
||||
|
@ -2570,7 +2590,19 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
|
||||
|
||||
public static boolean isLikelySourceURLReference(String url, List<String> resourceNames, Set<String> filenames) {
|
||||
public static boolean issLocalFileName(String url, Set<String> localFilenames) {
|
||||
if (localFilenames != null) {
|
||||
for (String n : localFilenames) {
|
||||
if (url.startsWith(n.toLowerCase())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isLikelySourceURLReference(String url, List<String> resourceNames, Set<String> baseFilenames, Set<String> localFilenames) {
|
||||
if (resourceNames != null) {
|
||||
for (String n : resourceNames) {
|
||||
if (url.startsWith(n.toLowerCase()+".html")) {
|
||||
|
@ -2581,8 +2613,15 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (filenames != null) {
|
||||
for (String n : filenames) {
|
||||
if (localFilenames != null) {
|
||||
for (String n : localFilenames) {
|
||||
if (url.startsWith(n.toLowerCase())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (baseFilenames != null) {
|
||||
for (String n : baseFilenames) {
|
||||
if (url.startsWith(n.toLowerCase())) {
|
||||
return true;
|
||||
}
|
||||
|
@ -2814,7 +2853,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
ElementDefinition e = profile.getSnapshot().getElement().get(0);
|
||||
String webroot = profile.getUserString("webroot");
|
||||
|
||||
base.setDefinition(processRelativeUrls(e.getDefinition(), webroot, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames, true));
|
||||
if (e.hasDefinition()) {
|
||||
base.setDefinition(processRelativeUrls(e.getDefinition(), webroot, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames, null, true));
|
||||
}
|
||||
base.setShort(e.getShort());
|
||||
if (e.hasCommentElement())
|
||||
base.setCommentElement(e.getCommentElement());
|
||||
|
@ -5247,7 +5288,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
|
||||
private String tail(String path) {
|
||||
if (path.contains("."))
|
||||
if (path == null) {
|
||||
return "";
|
||||
} else if (path.contains("."))
|
||||
return path.substring(path.lastIndexOf('.')+1);
|
||||
else
|
||||
return path;
|
||||
|
|
|
@ -1172,7 +1172,15 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (diffMatches.get(0).hasType() && "Reference".equals(diffMatches.get(0).getType().get(0).getWorkingCode()) && !isValidType(diffMatches.get(0).getType().get(0), currentBase)) {
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.VALIDATION_VAL_ILLEGAL_TYPE_CONSTRAINT, url, diffMatches.get(0).getPath(), diffMatches.get(0).getType().get(0), currentBase.typeSummary()));
|
||||
}
|
||||
if (diffMatches.get(0).hasType() && diffMatches.get(0).getType().size() == 1 && diffMatches.get(0).getType().get(0).hasProfile() && !"Reference".equals(diffMatches.get(0).getType().get(0).getWorkingCode())) {
|
||||
String id = diffMatches.get(0).getId();
|
||||
String lid = tail(id);
|
||||
if (lid.contains("/")) {
|
||||
// the template comes from the snapshot of the base
|
||||
generateIds(result.getElement(), url, srcSD.getType());
|
||||
String baseId = id.substring(0, id.length()-lid.length()) + lid.substring(0, lid.indexOf("/")); // this is wrong if there's more than one reslice (todo: one thing at a time)
|
||||
template = getById(result.getElement(), baseId);
|
||||
|
||||
} else if (diffMatches.get(0).hasType() && diffMatches.get(0).getType().size() == 1 && diffMatches.get(0).getType().get(0).hasProfile() && !"Reference".equals(diffMatches.get(0).getType().get(0).getWorkingCode())) {
|
||||
CanonicalType p = diffMatches.get(0).getType().get(0).getProfile().get(0);
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, p.getValue());
|
||||
if (sd == null && xver != null && xver.matchingUrl(p.getValue())) {
|
||||
|
@ -1932,6 +1940,15 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
return res;
|
||||
}
|
||||
|
||||
private ElementDefinition getById(List<ElementDefinition> list, String baseId) {
|
||||
for (ElementDefinition t : list) {
|
||||
if (baseId.equals(t.getId())) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void updateConstraintSources(ElementDefinition ed, String url) {
|
||||
for (ElementDefinitionConstraintComponent c : ed.getConstraint()) {
|
||||
if (!c.hasSource()) {
|
||||
|
@ -4844,6 +4861,8 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
String valueSet = ext.getExtensionString("valueSet");
|
||||
String doco = ext.getExtensionString("documentation");
|
||||
UsageContext usage = (ext.hasExtension("usage")) ? ext.getExtensionByUrl("usage").getValueUsageContext() : null;
|
||||
boolean any = "any".equals(ext.getExtensionString("scope"));
|
||||
|
||||
//
|
||||
// purpose: code - defines how the binding is used
|
||||
// usage : UsageContext - defines the contexts in which this binding is used for it's purpose
|
||||
|
@ -5275,7 +5294,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
|
||||
private String tail(String path) {
|
||||
if (path.contains("."))
|
||||
if (path == null) {
|
||||
return "";
|
||||
} else if (path.contains("."))
|
||||
return path.substring(path.lastIndexOf('.')+1);
|
||||
else
|
||||
return path;
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
package org.hl7.fhir.r5.utils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BuildExtensions extends ToolingExtensions {
|
||||
|
||||
public static final String EXT_DESCRIPTION = "http://hl7.org/fhir/build/StructureDefinition/description";
|
||||
public static final String EXT_TITLE = "http://hl7.org/fhir/build/StructureDefinition/title";
|
||||
public static final String EXT_EXAMPLE_TYPE = "http://hl7.org/fhir/build/CodeSystem/example-type";
|
||||
public static final String EXT_NOT_REGISTERED = "http://hl7.org/fhir/build/StructureDefinition/registered";
|
||||
public static final String EXT_IG = "http://hl7.org/fhir/build/StructureDefinition/ig";
|
||||
public static final String EXT_EXAMPLE_FOR = "http://hl7.org/fhir/build/StructureDefinition/example-for";
|
||||
public static final String EXT_PATH = "http://hl7.org/fhir/build/StructureDefinition/path";
|
||||
public static final String EXT_FOOTER = "http://hl7.org/fhir/build/StructureDefinition/footer";
|
||||
public static final String EXT_FOOTER2 = "http://hl7.org/fhir/build/StructureDefinition/footer2";
|
||||
public static final String EXT_ENTERED_IN_ERROR_STATUS = "http://hl7.org/fhir/build/StructureDefinition/entered-in-error-status";
|
||||
public static final String EXT_PROPOSED_ORDER = "http://hl7.org/fhir/build/StructureDefinition/proposed-order";
|
||||
public static final String EXT_HINT = "http://hl7.org/fhir/build/StructureDefinition/hint";
|
||||
public static final String EXT_LAYOUT = "http://hl7.org/fhir/build/StructureDefinition/layout";
|
||||
public static final String EXT_TODO = "http://hl7.org/fhir/build/StructureDefinition/todo";
|
||||
public static final String EXT_COMMITTEE_NOTES = "http://hl7.org/fhir/build/StructureDefinition/committee-notes";
|
||||
public static final String EXT_UML_DIR = "http://hl7.org/fhir/build/StructureDefinition/uml-dir";
|
||||
public static final String EXT_UML_BREAK = "http://hl7.org/fhir/build/StructureDefinition/uml-break";
|
||||
public static final String EXT_SVG = "http://hl7.org/fhir/build/StructureDefinition/svg";
|
||||
public static final String EXT_OCL = "http://hl7.org/fhir/build/StructureDefinition/ocl";
|
||||
public static final String EXT_FIXED_NAME = "http://hl7.org/fhir/build/StructureDefinition/fixed-name";
|
||||
public static final String EXT_TURTLE = "http://hl7.org/fhir/build/StructureDefinition/turtle";
|
||||
public static final String EXT_NAME = "http://hl7.org/fhir/build/StructureDefinition/name";
|
||||
public static final String EXT_V2_MAP = "http://hl7.org/fhir/build/StructureDefinition/v2-map";
|
||||
public static final String EXT_V3_MAP = "http://hl7.org/fhir/build/StructureDefinition/v3-map";
|
||||
public static final String EXT_BINDING_DEFINITION = "http://hl7.org/fhir/build/StructureDefinition/binding-definition";
|
||||
public static final String EXT_URI = "http://hl7.org/fhir/build/StructureDefinition/uri";
|
||||
public static final String EXT_WEBSITE = "http://hl7.org/fhir/build/StructureDefinition/website";
|
||||
public static final String EXT_EMAIL = "http://hl7.org/fhir/build/StructureDefinition/email";
|
||||
public static final String EXT_COPYRIGHT = "http://hl7.org/fhir/build/StructureDefinition/copyright";
|
||||
public static final String EXT_CS_OID = "http://hl7.org/fhir/build/StructureDefinition/cs-oid";
|
||||
public static final String EXT_VS_OID = "http://hl7.org/fhir/build/StructureDefinition/vs-oid";
|
||||
public static final String EXT_STATUS = "http://hl7.org/fhir/build/StructureDefinition/status";
|
||||
public static final String EXT_INTRODUCTION = "http://hl7.org/fhir/build/StructureDefinition/introduction";
|
||||
public static final String EXT_NOTES = "http://hl7.org/fhir/build/StructureDefinition/notes";
|
||||
public static final String EXT_CODE = "http://hl7.org/fhir/build/StructureDefinition/code";
|
||||
public static final String EXT_TYPE = "http://hl7.org/fhir/build/StructureDefinition/type";
|
||||
public static final String EXT_SUMMARY = "http://hl7.org/fhir/build/StructureDefinition/summary";
|
||||
// public static final String EXT_EXPLANATION = "http://hl7.org/fhir/build/StructureDefinition/explanation";
|
||||
public static final String EXT_NO_BINDING = "http://hl7.org/fhir/build/StructureDefinition/no-binding";
|
||||
public static final String EXT_OP_EXAMPLE = "http://hl7.org/fhir/build/StructureDefinition/example";
|
||||
public static final String EXT_OP_EXAMPLE_CONTENT = "content";
|
||||
public static final String EXT_OP_EXAMPLE_COMMENT = "comment";
|
||||
public static final String EXT_OP_EXAMPLE_RESPONSE = "response";
|
||||
public static final String EXT_OP_EXAMPLE_LIST = "list";
|
||||
public static final String EXT_TEMPLATE = "http://hl7.org/fhir/build/StructureDefinition/template";
|
||||
public static final String EXT_BINDING_NAME = "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName";
|
||||
|
||||
|
||||
public static List<String> allConsts() {
|
||||
List<String> list = new ArrayList<>();
|
||||
for (Field field : BuildExtensions.class.getDeclaredFields()) {
|
||||
int modifiers = field.getModifiers();
|
||||
if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) {
|
||||
try {
|
||||
list.add(field.get(field.getType()).toString());
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
list.addAll(ToolingExtensions.allConsts());
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,8 @@
|
|||
package org.hl7.fhir.r5.utils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
@ -61,6 +64,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -941,5 +945,21 @@ public class ToolingExtensions {
|
|||
return false;
|
||||
}
|
||||
|
||||
public static List<String> allConsts() {
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
for (Field field : ToolingExtensions.class.getDeclaredFields()) {
|
||||
int modifiers = field.getModifiers();
|
||||
if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) {
|
||||
try {
|
||||
list.add(field.get(field.getType()).toString());
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -377,6 +377,8 @@ public class I18nConstants {
|
|||
public static final String SD_ED_BIND_NO_BINDABLE = "SD_ED_BIND_NO_BINDABLE";
|
||||
public static final String SD_ED_BIND_MULTIPLE_TYPES = "SD_ED_BIND_MULTIPLE_TYPES";
|
||||
public static final String SD_VALUE_TYPE_IILEGAL = "SD_VALUE_TYPE_IILEGAL";
|
||||
public static final String SD_VALUE_TYPE_REPEAT_HINT = "SD_VALUE_TYPE_REPEAT_HINT";
|
||||
public static final String SD_VALUE_TYPE_REPEAT_WARNING_DOTNET = "SD_VALUE_TYPE_REPEAT_WARNING_DOTNET";
|
||||
public static final String SD_NO_TYPES_OR_CONTENTREF = "SD_NO_TYPES_OR_CONTENTREF";
|
||||
public static final String SEARCHPARAMETER_BASE_WRONG = "SEARCHPARAMETER_BASE_WRONG";
|
||||
public static final String SEARCHPARAMETER_EXP_WRONG = "SEARCHPARAMETER_EXP_WRONG";
|
||||
|
|
|
@ -543,7 +543,7 @@ FHIRPATH_LOCATION = (at {0})
|
|||
FHIRPATH_UNKNOWN_CONTEXT = Unknown context evaluating FHIRPath expression: {0}
|
||||
FHIRPATH_UNKNOWN_CONTEXT_ELEMENT = Unknown context element evaluating FHIRPath expression: {0}
|
||||
FHIRPATH_ALIAS_COLLECTION = Attempt to alias a collection, not a singleton evaluating FHIRPath expression
|
||||
FHIRPATH_UNKNOWN_NAME = Error evaluating FHIRPath expression: The name {0} is not valid for any of the possible types: {2}
|
||||
FHIRPATH_UNKNOWN_NAME = Error evaluating FHIRPath expression: The name {0} is not valid for any of the possible types: {1}
|
||||
FHIRPATH_UNKNOWN_CONSTANT = Error evaluating FHIRPath expression: Invalid FHIR Constant {0}
|
||||
FHIRPATH_CANNOT_USE = Error evaluating FHIRPath expression: Cannot use {0} in this context because {1}
|
||||
FHIRPATH_CANT_COMPARE = Error evaluating FHIRPath expression: Unable to compare values of type {0} and {1}
|
||||
|
@ -655,6 +655,8 @@ CODESYSTEM_CS_NO_SUPPLEMENT = CodeSystem {0} is a supplement, so can't be used a
|
|||
CODESYSTEM_CS_SUPP_CANT_CHECK = CodeSystem {0} cannot be found, so can't check if concepts are valid
|
||||
CODESYSTEM_CS_SUPP_INVALID_CODE = The code ''{1}'' is not declared in the base CodeSystem {0} so is not valid in the supplement
|
||||
SD_VALUE_TYPE_IILEGAL = The element {0} has a {1} of type {2}, which is not in the list of allowed types ({3})
|
||||
SD_VALUE_TYPE_REPEAT_HINT = The repeating element has a {1}. The {1} will apply to all the repeats (this has not been clear to all users)
|
||||
SD_VALUE_TYPE_REPEAT_WARNING_DOTNET = The repeating element has a {1} value for a primitive type. The DotNet validator will not apply this to all the repeats - this is an error
|
||||
SD_NO_TYPES_OR_CONTENTREF = The element {0} has no assigned types, and no content reference
|
||||
CODESYSTEM_CS_UNK_EXPANSION = The code provided ({2}) is not in the value set {0}, and a code is required from this value set. The system {1} is unknown.
|
||||
BUNDLE_SEARCH_NOSELF = SearchSet Bundles should have a self link that specifies what the search was
|
||||
|
|
|
@ -132,6 +132,7 @@ import org.hl7.fhir.r5.model.ValueSet;
|
|||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.r5.renderers.DataRenderer;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
|
||||
import org.hl7.fhir.r5.utils.BuildExtensions;
|
||||
import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException;
|
||||
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
||||
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
||||
|
@ -1686,6 +1687,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
} else if (SpecialExtensions.isKnownExtension(url)) {
|
||||
ex = SpecialExtensions.getDefinition(url);
|
||||
} else if (Utilities.existsInList(url, BuildExtensions.allConsts())) {
|
||||
// nothing
|
||||
} else if (rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, allowUnknownExtension(url), I18nConstants.EXTENSION_EXT_UNKNOWN_NOTHERE, url)) {
|
||||
hint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, isKnownExtension(url), I18nConstants.EXTENSION_EXT_UNKNOWN, url);
|
||||
}
|
||||
|
@ -1761,6 +1764,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
res.add(tr.getWorkingCode());
|
||||
}
|
||||
}
|
||||
// special hacks
|
||||
if (ex.getUrl().equals("http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type")) {
|
||||
res.add("uri");
|
||||
res.add("url");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -165,6 +165,9 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
// in a snapshot, we validate that fixedValue, pattern, and defaultValue, if present, are all of the right type
|
||||
if (snapshot && (element.getIdBase() != null) && (element.getIdBase().contains("."))) {
|
||||
if (rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), !typeCodes.isEmpty() || element.hasChild("contentReference"), I18nConstants.SD_NO_TYPES_OR_CONTENTREF, element.getIdBase())) {
|
||||
// if we see fixed[x] or pattern[x] applied to a repeating element, we'll give the user a hint
|
||||
boolean repeating = !Utilities.existsInList(element.getChildValue("max"), "0", "1");
|
||||
|
||||
Element v = element.getNamedChild("defaultValue");
|
||||
if (v != null) {
|
||||
rule(errors, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), typeCodes.contains(v.fhirType()), I18nConstants.SD_VALUE_TYPE_IILEGAL, element.getIdBase(), "defaultValue", v.fhirType(), typeCodes);
|
||||
|
@ -172,15 +175,31 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
v = element.getNamedChild("fixed");
|
||||
if (v != null) {
|
||||
rule(errors, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), typeCodes.contains(v.fhirType()), I18nConstants.SD_VALUE_TYPE_IILEGAL, element.getIdBase(), "fixed", v.fhirType(), typeCodes);
|
||||
hint(errors, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), !repeating, I18nConstants.SD_VALUE_TYPE_REPEAT_HINT, element.getIdBase(), "fixed");
|
||||
if (isPrimitiveType(v.fhirType())) {
|
||||
warning(errors, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), !repeating, I18nConstants.SD_VALUE_TYPE_REPEAT_WARNING_DOTNET, element.getIdBase(), "fixed");
|
||||
}
|
||||
}
|
||||
v = element.getNamedChild("pattern");
|
||||
if (v != null) {
|
||||
rule(errors, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), typeCodes.contains(v.fhirType()), I18nConstants.SD_VALUE_TYPE_IILEGAL, element.getIdBase(), "pattern", v.fhirType(), typeCodes);
|
||||
hint(errors, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), !repeating, I18nConstants.SD_VALUE_TYPE_REPEAT_HINT, element.getIdBase(), "pattern");
|
||||
if (isPrimitiveType(v.fhirType())) {
|
||||
warning(errors, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), !repeating, I18nConstants.SD_VALUE_TYPE_REPEAT_WARNING_DOTNET, element.getIdBase(), "pattern");
|
||||
}
|
||||
}
|
||||
}
|
||||
// if we see fixed[x] or pattern[x] applied to a repeating element, we'll give the user a hint
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean isPrimitiveType(String fhirType) {
|
||||
StructureDefinition sd = context.fetchTypeDefinition(fhirType);
|
||||
return sd != null && sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE;
|
||||
}
|
||||
|
||||
private String boundType(Set<String> typeCodes) {
|
||||
for (String tc : typeCodes) {
|
||||
if (Utilities.existsInList(tc, "code", "Coding", "CodeableConcept", "Quantity", "CodeableReference")) {
|
||||
|
@ -355,7 +374,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
private void validateTargetProfile(List<ValidationMessage> errors, Element profile, String code, NodeStack stack, String path) {
|
||||
String p = profile.primitiveValue();
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, p);
|
||||
if (code.equals("Reference")) {
|
||||
if (code.equals("Reference") || code.equals("CodeableReference")) {
|
||||
if (warning(errors, IssueType.EXCEPTION, stack.getLiteralPath(), sd != null, I18nConstants.SD_ED_TYPE_PROFILE_UNKNOWN, p)) {
|
||||
StructureDefinition t = determineBaseType(sd);
|
||||
if (t == null) {
|
||||
|
|
|
@ -234,7 +234,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
|
|||
for (JsonElement je : content.getAsJsonArray("profiles")) {
|
||||
String filename = je.getAsString();
|
||||
String contents = TestingUtilities.loadTestResource("validator", filename);
|
||||
StructureDefinition sd = loadProfile(filename, contents, messages);
|
||||
StructureDefinition sd = loadProfile(filename, contents, messages, val.isDebug());
|
||||
val.getContext().cacheResource(sd);
|
||||
}
|
||||
}
|
||||
|
@ -293,7 +293,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
|
|||
String contents = TestingUtilities.loadTestResource("validator", filename);
|
||||
System.out.println("Name: " + name + " - profile : " + profile.get("source").getAsString());
|
||||
version = content.has("version") ? content.get("version").getAsString() : Constants.VERSION;
|
||||
sd = loadProfile(filename, contents, messages);
|
||||
sd = loadProfile(filename, contents, messages, val.isDebug());
|
||||
val.getContext().cacheResource(sd);
|
||||
}
|
||||
val.setAssumeValidRestReferences(profile.has("assumeValidRestReferences") ? profile.get("assumeValidRestReferences").getAsBoolean() : false);
|
||||
|
@ -348,9 +348,10 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
|
|||
return res;
|
||||
}
|
||||
|
||||
public StructureDefinition loadProfile(String filename, String contents, List<ValidationMessage> messages) throws IOException, FHIRFormatError, FileNotFoundException, FHIRException, DefinitionException {
|
||||
public StructureDefinition loadProfile(String filename, String contents, List<ValidationMessage> messages, boolean debug) throws IOException, FHIRFormatError, FileNotFoundException, FHIRException, DefinitionException {
|
||||
StructureDefinition sd = (StructureDefinition) loadResource(filename, contents);
|
||||
ProfileUtilities pu = new ProfileUtilities(TestingUtilities.getSharedWorkerContext(version), messages, null);
|
||||
pu.setDebug(debug);
|
||||
if (!sd.hasSnapshot()) {
|
||||
StructureDefinition base = TestingUtilities.getSharedWorkerContext(version).fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
pu.generateSnapshot(base, sd, sd.getUrl(), null, sd.getTitle());
|
||||
|
|
|
@ -82,3 +82,25 @@ v: {
|
|||
"system" : "urn:ietf:bcp:47"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
||||
{"code" : {
|
||||
"system" : "http://terminology.hl7.org/CodeSystem/v3-ParticipationType",
|
||||
"code" : "IRCP",
|
||||
"display" : "information recipient"
|
||||
}, "url": "http://hl7.org/fhir/ValueSet/participation-role-type", "version": "4.5.0", "lang":"null", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false"}####
|
||||
v: {
|
||||
"severity" : "error",
|
||||
"error" : "Error from server: Unable to find value set http://hl7.org/fhir/ValueSet/provenance-participant-type",
|
||||
"class" : "SERVER_ERROR"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
||||
{"code" : {
|
||||
"system" : "http://terminology.hl7.org/CodeSystem/v3-RoleClass",
|
||||
"code" : "PROV",
|
||||
"display" : "healthcare provider"
|
||||
}, "url": "http://hl7.org/fhir/ValueSet/participation-role-type", "version": "4.5.0", "lang":"null", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false"}####
|
||||
v: {
|
||||
"severity" : "error",
|
||||
"error" : "Error from server: Unable to find value set http://hl7.org/fhir/ValueSet/provenance-participant-type",
|
||||
"class" : "SERVER_ERROR"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
-------------------------------------------------------------------------------------
|
||||
{"code" : {
|
||||
"system" : "http://terminology.hl7.org/CodeSystem/security-source-type",
|
||||
"code" : "4",
|
||||
"display" : "Application Server"
|
||||
}, "valueSet" :null, "lang":"null", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false"}####
|
||||
v: {
|
||||
"display" : "Application Server",
|
||||
"code" : "4",
|
||||
"system" : "http://terminology.hl7.org/CodeSystem/security-source-type"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
||||
{"code" : {
|
||||
"system" : "http://terminology.hl7.org/CodeSystem/security-source-type",
|
||||
"code" : "4"
|
||||
}, "url": "http://hl7.org/fhir/ValueSet/audit-source-type--0", "version": "4.5.0", "lang":"null", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false"}####
|
||||
v: {
|
||||
"display" : "Application Server",
|
||||
"code" : "4",
|
||||
"system" : "http://terminology.hl7.org/CodeSystem/security-source-type"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
|
@ -0,0 +1,11 @@
|
|||
-------------------------------------------------------------------------------------
|
||||
{"code" : {
|
||||
"system" : "http://terminology.hl7.org/CodeSystem/v3-ActReason",
|
||||
"code" : "HTEST"
|
||||
}, "valueSet" :null, "lang":"null", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false"}####
|
||||
v: {
|
||||
"display" : "test health data",
|
||||
"code" : "HTEST",
|
||||
"system" : "http://terminology.hl7.org/CodeSystem/v3-ActReason"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
|
@ -0,0 +1,21 @@
|
|||
-------------------------------------------------------------------------------------
|
||||
{"code" : {
|
||||
"system" : "http://terminology.hl7.org/CodeSystem/v3-ParticipationType",
|
||||
"code" : "IRCP"
|
||||
}, "url": "http://hl7.org/fhir/ValueSet/participation-role-type--5", "version": "4.5.0", "lang":"null", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false"}####
|
||||
v: {
|
||||
"display" : "information recipient",
|
||||
"code" : "IRCP",
|
||||
"system" : "http://terminology.hl7.org/CodeSystem/v3-ParticipationType"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
||||
{"code" : {
|
||||
"system" : "http://terminology.hl7.org/CodeSystem/v3-ParticipationType",
|
||||
"code" : "IRCP"
|
||||
}, "valueSet" :null, "lang":"null", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false"}####
|
||||
v: {
|
||||
"display" : "information recipient",
|
||||
"code" : "IRCP",
|
||||
"system" : "http://terminology.hl7.org/CodeSystem/v3-ParticipationType"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
|
@ -0,0 +1,21 @@
|
|||
-------------------------------------------------------------------------------------
|
||||
{"code" : {
|
||||
"system" : "http://terminology.hl7.org/CodeSystem/v3-RoleClass",
|
||||
"code" : "PROV"
|
||||
}, "url": "http://hl7.org/fhir/ValueSet/participation-role-type--1", "version": "4.5.0", "lang":"null", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false"}####
|
||||
v: {
|
||||
"display" : "healthcare provider",
|
||||
"code" : "PROV",
|
||||
"system" : "http://terminology.hl7.org/CodeSystem/v3-RoleClass"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
||||
{"code" : {
|
||||
"system" : "http://terminology.hl7.org/CodeSystem/v3-RoleClass",
|
||||
"code" : "PROV"
|
||||
}, "valueSet" :null, "lang":"null", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false"}####
|
||||
v: {
|
||||
"display" : "healthcare provider",
|
||||
"code" : "PROV",
|
||||
"system" : "http://terminology.hl7.org/CodeSystem/v3-RoleClass"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
2
pom.xml
2
pom.xml
|
@ -19,7 +19,7 @@
|
|||
|
||||
<properties>
|
||||
<hapi_fhir_version>5.4.0</hapi_fhir_version>
|
||||
<validator_test_case_version>1.1.95</validator_test_case_version>
|
||||
<validator_test_case_version>1.1.96-SNAPSHOT</validator_test_case_version>
|
||||
<junit_jupiter_version>5.7.1</junit_jupiter_version>
|
||||
<junit_platform_launcher_version>1.7.1</junit_platform_launcher_version>
|
||||
<maven_surefire_version>3.0.0-M5</maven_surefire_version>
|
||||
|
|
Loading…
Reference in New Issue