Merge branch 'master' of https://github.com/hapifhir/org.hl7.fhir.core
This commit is contained in:
commit
5259bf9847
|
@ -4,4 +4,5 @@
|
|||
|
||||
## Other code changes
|
||||
|
||||
* no changes
|
||||
* More comprehensive internationalization phrase coverage reporting.
|
||||
* Shim interfaces and classes to support clinical reasoning project updates.
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
@ -1,5 +1,5 @@
|
|||
Locale,Coverage #,Coverage %
|
||||
de,869,43%
|
||||
es,740,37%
|
||||
es,740,36%
|
||||
ja,935,46%
|
||||
nl,873,43%
|
||||
|
|
|
|
@ -277,7 +277,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
protected boolean canRunWithoutTerminology;
|
||||
protected boolean noTerminologyServer;
|
||||
private int expandCodesLimit = 1000;
|
||||
protected ILoggingService logger = new SystemOutLoggingService();
|
||||
protected org.hl7.fhir.r5.context.ILoggingService logger = new SystemOutLoggingService();
|
||||
protected Parameters expParameters;
|
||||
private Map<String, PackageInformation> packages = new HashMap<>();
|
||||
|
||||
|
@ -1991,7 +1991,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
this.canRunWithoutTerminology = canRunWithoutTerminology;
|
||||
}
|
||||
|
||||
public void setLogger(@Nonnull ILoggingService logger) {
|
||||
public void setLogger(@Nonnull org.hl7.fhir.r5.context.ILoggingService logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
|
@ -2816,7 +2816,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
|
||||
@Override
|
||||
public ILoggingService getLogger() {
|
||||
public org.hl7.fhir.r5.context.ILoggingService getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
|
|
|
@ -109,6 +109,18 @@ import javax.annotation.Nonnull;
|
|||
|
||||
public interface IWorkerContext {
|
||||
|
||||
/**
|
||||
@deprecated This interface only exists to provide backward compatibility for the following two projects:
|
||||
<a href="https://github.com/cqframework/clinical-reasoning">clinical-reasoning</a>
|
||||
<a href="https://github.com/cqframework/clinical_quality_language/">clinical_quality-language</a>
|
||||
|
||||
Due to a circular dependency, they cannot be updated without a release of HAPI, which requires backwards
|
||||
compatibility with core version 6.1.2.2
|
||||
**/
|
||||
@Deprecated(forRemoval = true)
|
||||
public interface ILoggingService extends org.hl7.fhir.r5.context.ILoggingService{
|
||||
|
||||
}
|
||||
public class OIDDefinitionComparer implements Comparator<OIDDefinition> {
|
||||
|
||||
@Override
|
||||
|
@ -630,8 +642,8 @@ public interface IWorkerContext {
|
|||
// todo: figure these out
|
||||
public Map<String, NamingSystem> getNSUrlMap();
|
||||
|
||||
public void setLogger(@Nonnull ILoggingService logger);
|
||||
public ILoggingService getLogger();
|
||||
public void setLogger(@Nonnull org.hl7.fhir.r5.context.ILoggingService logger);
|
||||
public org.hl7.fhir.r5.context.ILoggingService getLogger();
|
||||
|
||||
public boolean isNoTerminologyServer();
|
||||
public Set<String> getCodeSystemsUsed();
|
||||
|
|
|
@ -214,7 +214,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
private final boolean allowLoadingDuplicates;
|
||||
|
||||
@With
|
||||
private final ILoggingService loggingService;
|
||||
private final org.hl7.fhir.r5.context.ILoggingService loggingService;
|
||||
|
||||
public SimpleWorkerContextBuilder() {
|
||||
cacheTerminologyClientErrors = false;
|
||||
|
|
|
@ -0,0 +1,228 @@
|
|||
package org.hl7.fhir.r5.model;
|
||||
|
||||
import org.hl7.fhir.r5.fhirpath.TypeDetails;
|
||||
import org.hl7.fhir.utilities.SourceLocation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@deprecated This interface only exists to provide backward compatibility for the following two projects:
|
||||
<a href="https://github.com/cqframework/clinical-reasoning">clinical-reasoning</a>
|
||||
<a href="https://github.com/cqframework/clinical_quality_language/">clinical_quality-language</a>
|
||||
|
||||
Due to a circular dependency, they cannot be updated without a release of HAPI, which requires backwards
|
||||
compatibility with core version 6.1.2.2
|
||||
**/
|
||||
public class ExpressionNode extends org.hl7.fhir.r5.fhirpath.ExpressionNode{
|
||||
|
||||
private final org.hl7.fhir.r5.fhirpath.ExpressionNode wrappedExpressionNode;
|
||||
public ExpressionNode(int uniqueId) {
|
||||
super(0);
|
||||
wrappedExpressionNode = new org.hl7.fhir.r5.fhirpath.ExpressionNode(uniqueId);
|
||||
}
|
||||
|
||||
public ExpressionNode(org.hl7.fhir.r5.fhirpath.ExpressionNode wrappedExpressionNode) {
|
||||
super(0);
|
||||
this.wrappedExpressionNode = wrappedExpressionNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return wrappedExpressionNode.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return wrappedExpressionNode.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
wrappedExpressionNode.setName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base getConstant() {
|
||||
return wrappedExpressionNode.getConstant();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConstant(Base constant) {
|
||||
wrappedExpressionNode.setConstant(constant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function getFunction() {
|
||||
return wrappedExpressionNode.getFunction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFunction(Function function) {
|
||||
wrappedExpressionNode.setFunction(function);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProximal() {
|
||||
return wrappedExpressionNode.isProximal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProximal(boolean proximal) {
|
||||
wrappedExpressionNode.setProximal(proximal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Operation getOperation() {
|
||||
return wrappedExpressionNode.getOperation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOperation(Operation operation) {
|
||||
wrappedExpressionNode.setOperation(operation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.hl7.fhir.r5.fhirpath.ExpressionNode getInner() {
|
||||
return wrappedExpressionNode.getInner();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInner(org.hl7.fhir.r5.fhirpath.ExpressionNode value) {
|
||||
wrappedExpressionNode.setInner(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.hl7.fhir.r5.fhirpath.ExpressionNode getOpNext() {
|
||||
return wrappedExpressionNode.getOpNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOpNext(org.hl7.fhir.r5.fhirpath.ExpressionNode value) {
|
||||
wrappedExpressionNode.setOpNext(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<org.hl7.fhir.r5.fhirpath.ExpressionNode> getParameters() {
|
||||
return wrappedExpressionNode.getParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkName() {
|
||||
return wrappedExpressionNode.checkName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Kind getKind() {
|
||||
return wrappedExpressionNode.getKind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setKind(Kind kind) {
|
||||
wrappedExpressionNode.setKind(kind);
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.hl7.fhir.r5.fhirpath.ExpressionNode getGroup() {
|
||||
return wrappedExpressionNode.getGroup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGroup(org.hl7.fhir.r5.fhirpath.ExpressionNode group) {
|
||||
wrappedExpressionNode.setGroup(group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceLocation getStart() {
|
||||
return wrappedExpressionNode.getStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStart(SourceLocation start) {
|
||||
wrappedExpressionNode.setStart(start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceLocation getEnd() {
|
||||
return wrappedExpressionNode.getEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnd(SourceLocation end) {
|
||||
wrappedExpressionNode.setEnd(end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceLocation getOpStart() {
|
||||
return wrappedExpressionNode.getOpStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOpStart(SourceLocation opStart) {
|
||||
wrappedExpressionNode.setOpStart(opStart);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceLocation getOpEnd() {
|
||||
return wrappedExpressionNode.getOpEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOpEnd(SourceLocation opEnd) {
|
||||
wrappedExpressionNode.setOpEnd(opEnd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUniqueId() {
|
||||
return wrappedExpressionNode.getUniqueId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int parameterCount() {
|
||||
return wrappedExpressionNode.parameterCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String Canonical() {
|
||||
return wrappedExpressionNode.Canonical();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String summary() {
|
||||
return wrappedExpressionNode.summary();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String check() {
|
||||
return wrappedExpressionNode.check();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeDetails getTypes() {
|
||||
return wrappedExpressionNode.getTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTypes(TypeDetails types) {
|
||||
wrappedExpressionNode.setTypes(types);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeDetails getOpTypes() {
|
||||
return wrappedExpressionNode.getOpTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOpTypes(TypeDetails opTypes) {
|
||||
wrappedExpressionNode.setOpTypes(opTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getDistalNames() {
|
||||
return wrappedExpressionNode.getDistalNames();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNullSet() {
|
||||
return wrappedExpressionNode.isNullSet();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package org.hl7.fhir.r5.utils;
|
||||
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@deprecated This interface only exists to provide backward compatibility for the following two projects:
|
||||
<a href="https://github.com/cqframework/clinical-reasoning">clinical-reasoning</a>
|
||||
<a href="https://github.com/cqframework/clinical_quality_language/">clinical_quality-language</a>
|
||||
|
||||
Due to a circular dependency, they cannot be updated without a release of HAPI, which requires backwards
|
||||
compatibility with core version 6.1.2.2
|
||||
**/
|
||||
public class FHIRPathEngine extends org.hl7.fhir.r5.fhirpath.FHIRPathEngine {
|
||||
|
||||
public interface IEvaluationContext extends org.hl7.fhir.r5.fhirpath.FHIRPathEngine.IEvaluationContext{ }
|
||||
public FHIRPathEngine(IWorkerContext worker) {
|
||||
super(worker);
|
||||
}
|
||||
|
||||
public org.hl7.fhir.r5.model.ExpressionNode parse(String string) {
|
||||
return new org.hl7.fhir.r5.model.ExpressionNode(super.parse(string));
|
||||
}
|
||||
|
||||
public List<Base> evaluate(Base base, org.hl7.fhir.r5.model.ExpressionNode expressionNode) {
|
||||
return super.evaluate(base, expressionNode);
|
||||
}
|
||||
}
|
|
@ -1,26 +1,82 @@
|
|||
package org.hl7.fhir.utilities;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* Abstraction that splits a canonical in form of {@code <url>|<version>} into a URL and a version part.
|
||||
*/
|
||||
public class CanonicalPair {
|
||||
|
||||
private String url;
|
||||
private String version;
|
||||
private final String url;
|
||||
private final String version;
|
||||
|
||||
/**
|
||||
* Static factory method, that invokes the {@link CanonicalPair#CanonicalPair(String) CanonicalPair constructor}
|
||||
* with the given argument.
|
||||
* @param target the canonical to be split. May be {@code null}.
|
||||
* @return new instance of CanonicalPair
|
||||
*/
|
||||
public static CanonicalPair of(String target) {
|
||||
return new CanonicalPair(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given canonical and if needed splits off the version part.<p>
|
||||
* The given parameter {@code target} is expected to be a canonical.
|
||||
* @param target canonical to create a url, version pair from. May be {@code null}.
|
||||
*/
|
||||
public CanonicalPair(String target) {
|
||||
if (target != null && target.contains("|")) {
|
||||
this.url = target.substring(0, target.indexOf("|"));
|
||||
this.version = target.substring(target.indexOf("|")+1);
|
||||
int pipeIndex = target != null ? target.indexOf('|') : -1;
|
||||
if (pipeIndex >= 0) {
|
||||
this.url = target.substring(0, pipeIndex);
|
||||
this.version = target.substring(pipeIndex+1);
|
||||
} else {
|
||||
this.url = target;
|
||||
this.version = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL part of the canonical (everything before the {@code "|"} character, or the complete
|
||||
* canonical if the character is not present). If the source
|
||||
* @return URL part of the source canonical. May be {@code null}, if source canonical was {@code null}
|
||||
*/
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version part of the source canonical (everything after the {@code "|"} character.
|
||||
* @return version part of the canonical, may be {@code null}, if canonical was {@code null}, or canonical contains no
|
||||
* {@code "|"} character.
|
||||
*/
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the version part of the canonical is not {@code null}
|
||||
* @return {@code true} if version is not {@code null}, otherwise {@code false}
|
||||
*/
|
||||
public boolean hasVersion() {
|
||||
return version != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version of this pair, or the parameter {@code alternative},
|
||||
* if the version of this pair is {@code null}.
|
||||
* @param alternative to be returned from this method if the encapsulated version is {@code null}.
|
||||
* @return either the held version, or {@code alternative}, if version is {@code null}
|
||||
*/
|
||||
public String getVersionOr(String alternative) {
|
||||
return hasVersion() ? version : alternative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the encapsulated version of this pair is not {@code null} and not an empty string.
|
||||
* @return {@code true} if the version of this pair is not {@code null} and not an empty string, {@code false} otherwise
|
||||
*/
|
||||
public boolean hasNonEmptyVersion() {
|
||||
return StringUtils.isNotEmpty(version);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.hl7.fhir.utilities;
|
||||
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
|
||||
package org.hl7.fhir.utilities;
|
||||
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
@ -30,21 +30,23 @@ import org.hl7.fhir.utilities.validation.ValidationOptions;
|
|||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* This class is superceded by TerminologyValidationOptions but retained here for backwards compatibility
|
||||
* @author graha
|
||||
*
|
||||
*/
|
||||
public class TerminologyServiceOptions extends ValidationOptions {
|
||||
|
||||
public TerminologyServiceOptions(FhirPublication fhirVersion) {
|
||||
super(fhirVersion);
|
||||
}
|
||||
|
||||
public TerminologyServiceOptions(FhirPublication fhirVersion, String lang) {
|
||||
super(fhirVersion, lang);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class is superceded by TerminologyValidationOptions but retained here for backwards compatibility
|
||||
* @author graha
|
||||
*
|
||||
*/
|
||||
public class TerminologyServiceOptions extends ValidationOptions {
|
||||
|
||||
public TerminologyServiceOptions() { this(FhirPublication.R5); }
|
||||
|
||||
public TerminologyServiceOptions(FhirPublication fhirVersion) {
|
||||
super(fhirVersion);
|
||||
}
|
||||
|
||||
public TerminologyServiceOptions(FhirPublication fhirVersion, String lang) {
|
||||
super(fhirVersion, lang);
|
||||
}
|
||||
|
||||
}
|
|
@ -25,6 +25,8 @@ public class ValidationOptions {
|
|||
private boolean exampleOK = false;
|
||||
private FhirPublication fhirVersion;
|
||||
|
||||
public ValidationOptions() { this(FhirPublication.R5); }
|
||||
|
||||
public ValidationOptions(FhirPublication fhirVersion) {
|
||||
super();
|
||||
this.fhirVersion = fhirVersion;
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
package org.hl7.fhir.utilities;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class CanonicalPairTest {
|
||||
|
||||
@Test
|
||||
void testCanonicalNull() {
|
||||
var canonical = new CanonicalPair(null);
|
||||
assertNull(canonical.getUrl());
|
||||
assertNull(canonical.getVersion());
|
||||
assertFalse(canonical.hasVersion());
|
||||
assertFalse(canonical.hasNonEmptyVersion());
|
||||
String expectedVer = "1.0";
|
||||
String actualVer = canonical.getVersionOr(expectedVer);
|
||||
assertEquals(expectedVer, actualVer);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCanonicalEmpty() {
|
||||
var url = "";
|
||||
var canonical = new CanonicalPair(url);
|
||||
assertEquals(url, canonical.getUrl());
|
||||
assertFalse(canonical.hasVersion());
|
||||
assertFalse(canonical.hasNonEmptyVersion());
|
||||
String expectedVer = "1.0";
|
||||
String actualVer = canonical.getVersionOr(expectedVer);
|
||||
assertEquals(expectedVer, actualVer);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCanonicalWithoutVersion() {
|
||||
var url = "https://www.test.org";
|
||||
var canonical = new CanonicalPair(url);
|
||||
assertEquals(url, canonical.getUrl());
|
||||
assertNull(canonical.getVersion());
|
||||
assertFalse(canonical.hasVersion());
|
||||
assertFalse(canonical.hasNonEmptyVersion());
|
||||
String expectedVer = "1.0";
|
||||
String actualVer = canonical.getVersionOr(expectedVer);
|
||||
assertEquals(expectedVer, actualVer);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCanonicalWithEmptyVersion() {
|
||||
var expectedUrl = "https://www.test.org";
|
||||
var url = expectedUrl + "|";
|
||||
var canonical = new CanonicalPair(url);
|
||||
assertEquals(expectedUrl, canonical.getUrl());
|
||||
assertEquals("", canonical.getVersion());
|
||||
assertTrue(canonical.hasVersion());
|
||||
assertFalse(canonical.hasNonEmptyVersion());
|
||||
String alternativeVer = "1.0";
|
||||
String actualVer = canonical.getVersionOr(alternativeVer);
|
||||
assertEquals("", actualVer);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCanonicalWithVersion() {
|
||||
var expectedUrl = "https://www.test.org";
|
||||
var expectedVersion = "2.6";
|
||||
var url = expectedUrl + "|" + expectedVersion;
|
||||
var canonical = new CanonicalPair(url);
|
||||
assertEquals(expectedUrl, canonical.getUrl());
|
||||
assertEquals(expectedVersion, canonical.getVersion());
|
||||
assertTrue(canonical.hasVersion());
|
||||
assertTrue(canonical.hasNonEmptyVersion());
|
||||
String alternativeVer = "1.0";
|
||||
String actualVer = canonical.getVersionOr(alternativeVer);
|
||||
assertEquals(expectedVersion, actualVer);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCanonicalWithVersionIncludingPipe() {
|
||||
var expectedUrl = "https://www.test.org";
|
||||
var expectedVersion = "2024|05";
|
||||
var url = expectedUrl + "|" + expectedVersion;
|
||||
var canonical = new CanonicalPair(url);
|
||||
assertEquals(expectedUrl, canonical.getUrl());
|
||||
assertEquals(expectedVersion, canonical.getVersion());
|
||||
assertTrue(canonical.hasVersion());
|
||||
assertTrue(canonical.hasNonEmptyVersion());
|
||||
String alternativeVer = "1.0";
|
||||
String actualVer = canonical.getVersionOr(alternativeVer);
|
||||
assertEquals(expectedVersion, actualVer);
|
||||
}
|
||||
|
||||
}
|
|
@ -1428,25 +1428,7 @@ public class BaseValidator implements IValidationContextResourceLoader {
|
|||
return null;
|
||||
}
|
||||
|
||||
protected String versionFromCanonical(String system) {
|
||||
if (system == null) {
|
||||
return null;
|
||||
} else if (system.contains("|")) {
|
||||
return system.substring(0, system.indexOf("|"));
|
||||
} else {
|
||||
return system;
|
||||
}
|
||||
}
|
||||
|
||||
protected String systemFromCanonical(String system) {
|
||||
if (system == null) {
|
||||
return null;
|
||||
} else if (system.contains("|")) {
|
||||
return system.substring(system.indexOf("|")+1);
|
||||
} else {
|
||||
return system;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource loadContainedResource(List<ValidationMessage> errors, String path, Element resource, String id, Class<? extends Resource> class1) throws FHIRException {
|
||||
|
|
|
@ -1456,9 +1456,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
timeTracker.tx(t, "vc "+cc.toString());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (STACK_TRACE) e.printStackTrace();
|
||||
warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_ERROR_CODEABLECONCEPT, e.getMessage());
|
||||
} catch (CheckCodeOnServerException e) {
|
||||
if (STACK_TRACE) e.getCause().printStackTrace();
|
||||
warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_ERROR_CODEABLECONCEPT, e.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
} else if (binding.hasValueSet()) {
|
||||
|
@ -1469,12 +1469,17 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
}
|
||||
if (!noTerminologyChecks && theElementCntext != null && !checked) { // no binding check, so we just check the CodeableConcept generally
|
||||
CodeableConcept cc = ObjectConverter.readAsCodeableConcept(element);
|
||||
if (cc.hasCoding()) {
|
||||
long t = System.nanoTime();
|
||||
ValidationResult vr = checkCodeOnServer(stack, null, cc);
|
||||
bh.see(processTxIssues(errors, vr, element, path, org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.INFORMATION, false, null));
|
||||
timeTracker.tx(t, "vc "+cc.toString());
|
||||
try {
|
||||
CodeableConcept cc = ObjectConverter.readAsCodeableConcept(element);
|
||||
if (cc.hasCoding()) {
|
||||
long t = System.nanoTime();
|
||||
ValidationResult vr = checkCodeOnServer(stack, null, cc);
|
||||
bh.see(processTxIssues(errors, vr, element, path, org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.INFORMATION, false, null));
|
||||
timeTracker.tx(t, "vc " + cc.toString());
|
||||
}
|
||||
} catch (CheckCodeOnServerException e) {
|
||||
if (STACK_TRACE) e.getCause().printStackTrace();
|
||||
warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_ERROR_CODEABLECONCEPT, e.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
return checkDisp;
|
||||
|
@ -1502,8 +1507,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
boolean ok = true;
|
||||
if (vr != null) {
|
||||
for (OperationOutcomeIssueComponent iss : vr.getIssues()) {
|
||||
if (!iss.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "not-in-vs") &&
|
||||
!iss.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "this-code-not-in-vs")
|
||||
if (!iss.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "not-in-vs")
|
||||
&& !iss.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "this-code-not-in-vs")
|
||||
&& !(ignoreCantInfer || iss.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "cannot-infer"))) {
|
||||
OperationOutcomeIssueComponent i = iss.copy();
|
||||
if (notFoundLevel != null && i.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "not-found")) {
|
||||
|
@ -1653,9 +1658,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
timeTracker.tx(t, DataRenderer.display(context, cc));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (STACK_TRACE) e.printStackTrace();
|
||||
warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_ERROR_CODEABLECONCEPT, e.getMessage());
|
||||
} catch (CheckCodeOnServerException e) {
|
||||
if (STACK_TRACE) e.getCause().printStackTrace();
|
||||
warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_ERROR_CODEABLECONCEPT, e.getCause().getMessage());
|
||||
}
|
||||
// special case: if the logical model has both CodeableConcept and Coding mappings, we'll also check the first coding.
|
||||
if (getMapping("http://hl7.org/fhir/terminology-pattern", logical, logical.getSnapshot().getElementFirstRep()).contains("Coding")) {
|
||||
|
@ -1861,9 +1866,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
else
|
||||
ok = txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_8, describeReference(maxVSUrl, valueset), ccSummary(cc)) && ok;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (STACK_TRACE) e.printStackTrace();
|
||||
warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_ERROR_CODEABLECONCEPT_MAX, e.getMessage());
|
||||
} catch (CheckCodeOnServerException e) {
|
||||
if (STACK_TRACE) e.getCause().printStackTrace();
|
||||
warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_ERROR_CODEABLECONCEPT_MAX, e.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
|
@ -7474,6 +7479,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
return checkForInactive(filterOutSpecials(stack.getLiteralPath(), vs, context.validateCode(options, value, vs)), new CodeType(value));
|
||||
}
|
||||
|
||||
static class CheckCodeOnServerException extends Exception {
|
||||
public CheckCodeOnServerException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
}
|
||||
|
||||
// no delay on this one?
|
||||
public ValidationResult checkCodeOnServer(NodeStack stack, String code, String system, String version, String display, boolean checkDisplay) {
|
||||
|
@ -7490,9 +7500,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
return checkForInactive(filterOutSpecials(stack.getLiteralPath(), valueset, context.validateCode(baseOptions.withLanguage(stack.getWorkingLang()), c, valueset)), c);
|
||||
}
|
||||
|
||||
public ValidationResult checkCodeOnServer(NodeStack stack, ValueSet valueset, CodeableConcept cc) {
|
||||
public ValidationResult checkCodeOnServer(NodeStack stack, ValueSet valueset, CodeableConcept cc) throws CheckCodeOnServerException {
|
||||
codingObserver.seeCode(stack, cc);
|
||||
return checkForInactive(filterOutSpecials(stack.getLiteralPath(), valueset, context.validateCode(baseOptions.withLanguage(stack.getWorkingLang()), cc, valueset)), cc);
|
||||
try {
|
||||
return checkForInactive(filterOutSpecials(stack.getLiteralPath(), valueset, context.validateCode(baseOptions.withLanguage(stack.getWorkingLang()), cc, valueset)), cc);
|
||||
} catch (Exception e) {
|
||||
throw new CheckCodeOnServerException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ValidationResult filterOutSpecials(String path, ValueSet vs, ValidationResult vr) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.hl7.fhir.r5.model.CodeSystem;
|
|||
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
||||
import org.hl7.fhir.utilities.CanonicalPair;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||
|
@ -620,7 +621,8 @@ public class CodeSystemValidator extends BaseValidator {
|
|||
private boolean validateSupplementConcept(List<ValidationMessage> errors, Element concept, NodeStack stack, String supp, ValidationOptions options) {
|
||||
String code = concept.getChildValue("code");
|
||||
if (!Utilities.noString(code)) {
|
||||
org.hl7.fhir.r5.terminologies.utilities.ValidationResult res = context.validateCode(options, systemFromCanonical(supp), versionFromCanonical(supp), code, null);
|
||||
var canonical = new CanonicalPair(supp);
|
||||
org.hl7.fhir.r5.terminologies.utilities.ValidationResult res = context.validateCode(options, canonical.getUrl(), canonical.getVersion(), code, null);
|
||||
return rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), res.isOk(), I18nConstants.CODESYSTEM_CS_SUPP_INVALID_CODE, supp, code);
|
||||
} else {
|
||||
return true;
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package org.hl7.fhir.validation;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -10,6 +14,7 @@ import org.hl7.fhir.r5.formats.XmlParser;
|
|||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||
import org.hl7.fhir.utilities.FhirPublication;
|
||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||
import org.hl7.fhir.utilities.settings.FhirSettings;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.validation.instance.InstanceValidator;
|
||||
|
@ -25,7 +30,7 @@ public class ResourceValidationTests {
|
|||
private static InstanceValidator val;
|
||||
|
||||
|
||||
private void runTest(String filename) throws IOException, FileNotFoundException, Exception {
|
||||
private List<ValidationMessage> runTest(String filename) throws IOException, FileNotFoundException, Exception {
|
||||
TestingUtilities.injectCorePackageLoader();
|
||||
if (val == null) {
|
||||
ctxt = TestingUtilities.getSharedWorkerContext();
|
||||
|
@ -37,6 +42,7 @@ public class ResourceValidationTests {
|
|||
Resource res = (Resource) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", filename));
|
||||
val.validate(val, errors, res);
|
||||
Assertions.assertNotNull(errors);
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
|
@ -123,4 +129,26 @@ public class ResourceValidationTests {
|
|||
}
|
||||
|
||||
|
||||
}
|
||||
@Test
|
||||
public void testCodesystemSupplementsVersion() throws Exception {
|
||||
List<ValidationMessage> errors = runTest("codesystem-example-supplement-version.xml");
|
||||
assertNoErrors(errors);
|
||||
}
|
||||
|
||||
|
||||
private void assertNoErrors(List<ValidationMessage> errors) {
|
||||
List<String> errorMessages = new ArrayList<>();
|
||||
for(ValidationMessage message : errors) {
|
||||
// we will skip the message that WG citation is needed
|
||||
if(I18nConstants.VALIDATION_HL7_WG_NEEDED.equals(message.getMessageId())) {
|
||||
continue;
|
||||
}
|
||||
if(message.getLevel().isError()) {
|
||||
errorMessages.add(message.getMessage());
|
||||
}
|
||||
}
|
||||
assertThat("No error message expected in validation outcome.", errorMessages, is(empty()));
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue