Skip to content

Commit

Permalink
Merge pull request #1814 from hapifhir/2024-11-gg-vs-filter-fix
Browse files Browse the repository at this point in the history
2024 11 gg vs filter fix
  • Loading branch information
grahamegrieve authored Nov 19, 2024
2 parents 75aba73 + a26fcf5 commit 9b83d18
Show file tree
Hide file tree
Showing 18 changed files with 257 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ public static org.hl7.fhir.r5.model.ConceptMap.SourceElementComponent convertSou
if (t.getEquivalence() == org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence.UNMATCHED) {
tgt.setNoMap(true);
if (t.hasComment()) {
if (tgt.hasExtension("http://hl7.org/fhir/4.0/StructureDefinition/extension-ConceptMap.group.element.target.comment")) {
throw new FHIRException("A source can only have one 'unmatched' relationship. Consider using 'disjoint' ");
}
tgt.addExtension("http://hl7.org/fhir/4.0/StructureDefinition/extension-ConceptMap.group.element.target.comment", ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().convertType(t.getCommentElement()));
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ private void w(StringBuilder b, String line) {

private PEGenClass genClass(PEDefinition source) {
PEGenClass cls = new PEGenClass();
cls.name = source.getProfile().getName();
cls.name = Utilities.javaTokenize(source.getProfile().getName(), true);
cls.base = source.getProfile().getType();
cls.doco = source.documentation();
cls.url = source.getProfile().getVersionedUrl();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ private String generateEnum(PEDefinition source, PEDefinition field) {
}
return null;
}

private void defineField(PEDefinition source, PEDefinition field) {
if (field.types().size() == 1) {
StructureDefinition sd = workerContext.fetchTypeDefinition(field.types().get(0).getUrl());
Expand Down Expand Up @@ -846,7 +847,7 @@ private void w(StringBuilder b, String line) {

private PEGenClass genClass(PEDefinition source) {
PEGenClass cls = new PEGenClass();
cls.name = source.getProfile().getName();
cls.name = Utilities.javaTokenize(source.getProfile().getName(), true);
cls.base = source.getProfile().getType();
cls.doco = source.documentation();
cls.url = source.getProfile().getVersionedUrl();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS
import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier;
import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier.ValidationContextResourceProxy;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.DebugUtilities;
import org.hl7.fhir.utilities.FhirPublication;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
Expand Down Expand Up @@ -183,6 +184,22 @@ private void analyseValueSet() {
for (Extension s : valueset.getExtensionsByUrl(ExtensionConstants.EXT_VSSUPPLEMENT)) {
requiredSupplements.add(s.getValue().primitiveValue());
}

if (!requiredSupplements.isEmpty()) {
for (ConceptSetComponent inc : valueset.getCompose().getInclude()) {
if (inc.hasSystem()) {
checkCodeSystemResolves(inc);
}
}
for (ConceptSetComponent inc : valueset.getCompose().getExclude()) {
if (inc.hasSystem()) {
checkCodeSystemResolves(inc);
}
}
if (!requiredSupplements.isEmpty()) {
DebugUtilities.breakpoint();
}
}
} else {
opContext.note("vs = null");
}
Expand All @@ -202,6 +219,15 @@ private void analyseValueSet() {
opContext.note("analysed");
}

private void checkCodeSystemResolves(ConceptSetComponent c) {
VersionInfo vi = new VersionInfo(this);
CodeSystem cs = resolveCodeSystem(c.getSystem(), vi.getVersion(c.getSystem(), c.getVersion()));
if (cs == null) {
// well, it doesn't really matter at this point. Mainly we're triggering the supplement analysis to happen
opContext.note("Unable to resolve "+c.getSystem()+"#"+vi.getVersion(c.getSystem(), c.getVersion()));
}
}

private void analyseComponent(ConceptSetComponent i, String name) {
opContext.deadCheck("analyse Component "+name);
if (i.getSystemElement().hasExtension(ToolingExtensions.EXT_VALUESET_SYSTEM)) {
Expand Down Expand Up @@ -446,7 +472,7 @@ private int checkValueSetLoad(ConceptSetComponent inc, ValidationProcessInfo inf

private boolean checkRequiredSupplements(ValidationProcessInfo info) {
if (!requiredSupplements.isEmpty()) {
String msg= context.formatMessagePlural(requiredSupplements.size(), I18nConstants.VALUESET_SUPPLEMENT_MISSING, CommaSeparatedStringBuilder.build(requiredSupplements));
String msg = context.formatMessagePlural(requiredSupplements.size(), I18nConstants.VALUESET_SUPPLEMENT_MISSING, CommaSeparatedStringBuilder.build(requiredSupplements));
throw new TerminologyServiceProtectionException(msg, TerminologyServiceErrorClass.BUSINESS_RULE, IssueType.NOTFOUND);
}
return requiredSupplements.isEmpty();
Expand Down Expand Up @@ -492,6 +518,17 @@ public CodeSystem resolveCodeSystem(String system, String version) {
if (cs == null) {
cs = findSpecialCodeSystem(system, version);
}
if (cs != null) {
if (cs.hasUserData("supplements.installed")) {
for (String s : cs.getUserString("supplements.installed").split("\\,")) {
requiredSupplements.remove(s);
if (s.contains("|")) {
s = s.substring(0, s.indexOf("|"));
requiredSupplements.remove(s);
}
}
}
}
return cs;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

public interface IValidationPolicyAdvisor {


public IValidationPolicyAdvisor getPolicyAdvisor();
public IValidationPolicyAdvisor setPolicyAdvisor(IValidationPolicyAdvisor policyAdvisor);

/**
* Internal use, for chaining advisors
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1142,4 +1142,6 @@ public class I18nConstants {
public static final String VIEWDEFINITION_TYPE_MISMATCH = "VIEWDEFINITION_TYPE_MISMATCH";
public static final String VIEWDEFINITION_UNABLE_TO_TYPE = "VIEWDEFINITION_UNABLE_TO_TYPE";
public static final String VIEWDEFINITION_COMPLEX_TYPE = "VIEWDEFINITION_COMPLEX_TYPE";
public static final String CODESYSTEM_PROPERTY_ABSOLUTE_URI = "CODESYSTEM_PROPERTY_ABSOLUTE_URI";
public static final String CODESYSTEM_CS_SUPP_HIERARCHY_MEANING = "CODESYSTEM_CS_SUPP_HIERARCHY_MEANING";
}
2 changes: 2 additions & 0 deletions org.hl7.fhir.utilities/src/main/resources/Messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1172,3 +1172,5 @@ VIEWDEFINITION_COLLECTION_NEEDED2 = This column is defined to be not a collectio
VIEWDEFINITION_TYPE_MISMATCH = The path expression ''{0}'' does not return a value of the type ''{1}'' - found ''{2}''{3}
VIEWDEFINITION_UNABLE_TO_TYPE = Unable to determine a type (found ''{0}''){1}
VIEWDEFINITION_COMPLEX_TYPE = Column from path ''{0}'' is a complex type (''{1}''){2}. This is not supported in some Runners
CODESYSTEM_PROPERTY_ABSOLUTE_URI = A property URI must be an absolute URI, but ''{0}'' is not
CODESYSTEM_CS_SUPP_HIERARCHY_MEANING = The supplement declares a heirarchyMeaning of ''{0}'' that doesn''t match that in the base code system ''{1}''
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package org.hl7.fhir.validation.cli.services;

import java.util.EnumSet;
import java.util.List;

import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.elementmodel.Element.SpecialElement;
import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.utils.validation.IMessagingServices;
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor.AdditionalBindingPurpose;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor.CodedContentValidationAction;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor.ElementValidationAction;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor.ResourceValidationAction;
import org.hl7.fhir.r5.utils.validation.constants.BindingKind;
import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.hl7.fhir.utilities.validation.ValidationMessage;

public class DisabledValidationPolicyAdvisor implements IValidationPolicyAdvisor {

private IValidationPolicyAdvisor policyAdvisor;

@Override
public ReferenceValidationPolicy getReferencePolicy() {
return ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS;
}

@Override
public boolean isSuppressMessageId(String path, String messageId) {
return policyAdvisor.isSuppressMessageId(path, messageId);
}

@Override
public ContainedReferenceValidationPolicy policyForContained(IResourceValidator validator, Object appContext,
StructureDefinition structure, ElementDefinition element, String containerType, String containerId,
SpecialElement containingResourceType, String path, String url) {
return policyAdvisor.policyForContained(validator, appContext, structure, element, containerType, containerId, containingResourceType, path, url);
}

@Override
public EnumSet<ResourceValidationAction> policyForResource(IResourceValidator validator, Object appContext,
StructureDefinition type, String path) {
return policyAdvisor.policyForResource(validator, appContext, type, path);
}

@Override
public EnumSet<ElementValidationAction> policyForElement(IResourceValidator validator, Object appContext,
StructureDefinition structure, ElementDefinition element, String path) {
return policyAdvisor.policyForElement(validator, appContext, structure, element, path);
}

@Override
public EnumSet<CodedContentValidationAction> policyForCodedContent(IResourceValidator validator, Object appContext,
String stackPath, ElementDefinition definition, StructureDefinition structure, BindingKind kind,
AdditionalBindingPurpose purpose, ValueSet valueSet, List<String> systems) {
return policyAdvisor.policyForCodedContent(validator, appContext, stackPath, definition, structure, kind, purpose, valueSet, systems);
}

@Override
public List<StructureDefinition> getImpliedProfilesForResource(IResourceValidator validator, Object appContext,
String stackPath, ElementDefinition definition, StructureDefinition structure, Element resource, boolean valid,
IMessagingServices msgServices, List<ValidationMessage> messages) {
return policyAdvisor.getImpliedProfilesForResource(validator, appContext, stackPath, definition, structure, resource, valid, msgServices, messages);
}

public IValidationPolicyAdvisor getPolicyAdvisor() {
return policyAdvisor;
}

public IValidationPolicyAdvisor setPolicyAdvisor(IValidationPolicyAdvisor policyAdvisor) {
this.policyAdvisor = policyAdvisor;
return this;
}

@Override
public ReferenceValidationPolicy policyForReference(IResourceValidator validator,
Object appContext,
String path,
String url) {
return ReferenceValidationPolicy.IGNORE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,9 @@ public IValidationPolicyAdvisor getPolicyAdvisor() {
return policyAdvisor;
}

public void setPolicyAdvisor(IValidationPolicyAdvisor policyAdvisor) {
public IValidationPolicyAdvisor setPolicyAdvisor(IValidationPolicyAdvisor policyAdvisor) {
this.policyAdvisor = policyAdvisor;
return this;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
import org.hl7.fhir.r5.terminologies.client.TerminologyClientManager.InternalLogEvent;
import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.hl7.fhir.utilities.FhirPublication;
import org.hl7.fhir.utilities.SystemExitManager;
import org.hl7.fhir.utilities.TextFile;
Expand Down Expand Up @@ -72,6 +73,7 @@
import org.hl7.fhir.validation.cli.utils.Common;
import org.hl7.fhir.validation.cli.utils.EngineMode;
import org.hl7.fhir.validation.cli.utils.VersionSourceInformation;
import org.hl7.fhir.validation.instance.advisor.BasePolicyAdvisorForFullValidation;
import org.hl7.fhir.validation.instance.advisor.JsonDrivenPolicyAdvisor;
import org.hl7.fhir.validation.instance.advisor.TextDrivenPolicyAdvisor;

Expand Down Expand Up @@ -604,18 +606,25 @@ protected ValidationEngine buildValidationEngine(CliContext cliContext, String d
validationEngine.setForPublication(cliContext.isForPublication());
validationEngine.setShowTimes(cliContext.isShowTimes());
validationEngine.setAllowExampleUrls(cliContext.isAllowExampleUrls());
ReferenceValidationPolicy refpol = ReferenceValidationPolicy.CHECK_VALID;
if (!cliContext.isDisableDefaultResourceFetcher()) {
StandAloneValidatorFetcher fetcher = new StandAloneValidatorFetcher(validationEngine.getPcm(), validationEngine.getContext(), validationEngine);
validationEngine.setFetcher(fetcher);
validationEngine.getContext().setLocator(fetcher);
validationEngine.setPolicyAdvisor(fetcher);
if (cliContext.getAdvisorFile() != null) {
if (cliContext.getAdvisorFile().endsWith(".json")) {
fetcher.setPolicyAdvisor(new JsonDrivenPolicyAdvisor(fetcher.getPolicyAdvisor(), new File(cliContext.getAdvisorFile())));
} else {
fetcher.setPolicyAdvisor(new TextDrivenPolicyAdvisor(fetcher.getPolicyAdvisor(), new File(cliContext.getAdvisorFile())));
}
} else {
DisabledValidationPolicyAdvisor fetcher = new DisabledValidationPolicyAdvisor();
validationEngine.setPolicyAdvisor(fetcher);
refpol = ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS;
}
if (cliContext.getAdvisorFile() != null) {
if (cliContext.getAdvisorFile().endsWith(".json")) {
validationEngine.getPolicyAdvisor().setPolicyAdvisor(new JsonDrivenPolicyAdvisor(validationEngine.getPolicyAdvisor().getPolicyAdvisor(), new File(cliContext.getAdvisorFile())));
} else {
validationEngine.getPolicyAdvisor().setPolicyAdvisor(new TextDrivenPolicyAdvisor(validationEngine.getPolicyAdvisor().getPolicyAdvisor(), new File(cliContext.getAdvisorFile())));
}
} else {
validationEngine.getPolicyAdvisor().setPolicyAdvisor(new BasePolicyAdvisorForFullValidation(validationEngine.getPolicyAdvisor() == null ? refpol : validationEngine.getPolicyAdvisor().getReferencePolicy()));
}
validationEngine.getBundleValidationRules().addAll(cliContext.getBundleValidationRules());
validationEngine.setJurisdiction(CodeSystemUtilities.readCoding(cliContext.getJurisdiction()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,12 @@ public PropertyValidationRules rulesForFilter(String property, EnumSet<PropertyO

if (Utilities.existsInList(property,
"concept")) {
return new PropertyValidationRules(PropertyFilterType.Code, CodeValidationRule.None, addToOps(ops, PropertyOperation.IsA));
return new PropertyValidationRules(PropertyFilterType.Code, CodeValidationRule.None, addToOps(ops, PropertyOperation.Equals, PropertyOperation.IsA, PropertyOperation.IsNotA));
}
if (Utilities.existsInList(property,
"code")) {
return new PropertyValidationRules(PropertyFilterType.Code, CodeValidationRule.None, addToOps(ops, PropertyOperation.Equals, PropertyOperation.IsA, PropertyOperation.IsNotA));
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@
public class BasePolicyAdvisorForFullValidation implements IValidationPolicyAdvisor {

private ReferenceValidationPolicy refpol = ReferenceValidationPolicy.CHECK_VALID;

public IValidationPolicyAdvisor getPolicyAdvisor() {
return null;
}

public IValidationPolicyAdvisor setPolicyAdvisor(IValidationPolicyAdvisor policyAdvisor) {
throw new Error("This policy advisor is the end of the chain");
}

public BasePolicyAdvisorForFullValidation(ReferenceValidationPolicy refpol) {
super();
Expand Down
Loading

0 comments on commit 9b83d18

Please sign in to comment.