Merge pull request #782 from hapifhir/gg-202204-various

various fixes
This commit is contained in:
Grahame Grieve 2022-04-06 09:28:09 +10:00 committed by GitHub
commit 76411218ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 689 additions and 366 deletions

1
.gitignore vendored
View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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";

View File

@ -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

View File

@ -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;
}

View File

@ -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) {

View File

@ -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());

View File

@ -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"
}
-------------------------------------------------------------------------------------

View File

@ -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"
}
-------------------------------------------------------------------------------------

View File

@ -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"
}
-------------------------------------------------------------------------------------

View File

@ -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"
}
-------------------------------------------------------------------------------------

View File

@ -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"
}
-------------------------------------------------------------------------------------

View File

@ -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>