rework rules based advisor
This commit is contained in:
parent
3b8b2a94c3
commit
f19f8f4ed2
|
@ -29,7 +29,7 @@ public interface IValidationPolicyAdvisor {
|
||||||
* @param messageId - the message id (from messages.properties)
|
* @param messageId - the message id (from messages.properties)
|
||||||
* @return true if the validator should ignore the message
|
* @return true if the validator should ignore the message
|
||||||
*/
|
*/
|
||||||
boolean suppressMessageId(String path, String messageId);
|
boolean isSuppressMessageId(String path, String messageId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
@ -278,7 +278,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
|
||||||
if (policyAdvisor == null) {
|
if (policyAdvisor == null) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return policyAdvisor.suppressMessageId(path, theMessage);
|
return policyAdvisor.isSuppressMessageId(path, theMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1289,8 +1289,8 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean suppressMessageId(String path, String messageId) {
|
public boolean isSuppressMessageId(String path, String messageId) {
|
||||||
return policyAdvisor.suppressMessageId(path, messageId);
|
return policyAdvisor.isSuppressMessageId(path, messageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -302,8 +302,8 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher, IV
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean suppressMessageId(String path, String messageId) {
|
public boolean isSuppressMessageId(String path, String messageId) {
|
||||||
return policyAdvisor.suppressMessageId(path, messageId);
|
return policyAdvisor.isSuppressMessageId(path, messageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -13,10 +13,6 @@ import org.hl7.fhir.r5.model.ValueSet;
|
||||||
import org.hl7.fhir.r5.utils.validation.IMessagingServices;
|
import org.hl7.fhir.r5.utils.validation.IMessagingServices;
|
||||||
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
|
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
|
||||||
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
|
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.BindingKind;
|
||||||
import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy;
|
import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy;
|
||||||
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
|
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
|
||||||
|
@ -170,7 +166,7 @@ public class BasePolicyAdvisorForFullValidation implements IValidationPolicyAdvi
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean suppressMessageId(String path, String messageId) {
|
public boolean isSuppressMessageId(String path, String messageId) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,16 @@
|
||||||
package org.hl7.fhir.validation.instance.advisor;
|
package org.hl7.fhir.validation.instance.advisor;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.hl7.fhir.r5.elementmodel.Element;
|
import javax.annotation.Nonnull;
|
||||||
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;
|
||||||
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.r5.utils.validation.constants.ReferenceValidationPolicy;
|
||||||
import org.hl7.fhir.utilities.json.JsonException;
|
import org.hl7.fhir.utilities.json.JsonException;
|
||||||
import org.hl7.fhir.utilities.json.model.JsonElement;
|
import org.hl7.fhir.utilities.json.model.JsonElement;
|
||||||
import org.hl7.fhir.utilities.json.model.JsonObject;
|
import org.hl7.fhir.utilities.json.model.JsonObject;
|
||||||
import org.hl7.fhir.utilities.json.parser.JsonParser;
|
import org.hl7.fhir.utilities.json.parser.JsonParser;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
|
||||||
|
|
||||||
public class JsonDrivenPolicyAdvisor extends RulesDrivenPolicyAdvisor {
|
public class JsonDrivenPolicyAdvisor extends RulesDrivenPolicyAdvisor {
|
||||||
|
|
||||||
|
@ -38,14 +27,19 @@ public class JsonDrivenPolicyAdvisor extends RulesDrivenPolicyAdvisor {
|
||||||
private void load(File source) throws JsonException, IOException {
|
private void load(File source) throws JsonException, IOException {
|
||||||
JsonObject json = JsonParser.parseObject(source);
|
JsonObject json = JsonParser.parseObject(source);
|
||||||
for (JsonElement e : json.forceArray("suppress").getItems()) {
|
for (JsonElement e : json.forceArray("suppress").getItems()) {
|
||||||
String s = e.asString();
|
@Nonnull String s = e.asString();
|
||||||
String id = s;
|
|
||||||
String path = null;
|
|
||||||
if (s.contains("@")) {
|
if (s.contains("@")) {
|
||||||
id = s.substring(0, s.indexOf("@"));
|
String id = s.substring(0, s.indexOf("@"));
|
||||||
path = s.substring(s.indexOf("@")+1);
|
String path = s.substring(s.indexOf("@")+1);
|
||||||
|
boolean regex = false;
|
||||||
|
if (path.startsWith("^")) {
|
||||||
|
regex = true;
|
||||||
|
path = path.substring(1);
|
||||||
|
}
|
||||||
|
addSuppressMessageRule(id, path, regex);
|
||||||
|
} else {
|
||||||
|
addSuppressMessageRule(s);
|
||||||
}
|
}
|
||||||
addSuppressMessageRule(id, path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ import java.util.ArrayList;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.elementmodel.Element;
|
import org.hl7.fhir.r5.elementmodel.Element;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
|
@ -11,12 +13,7 @@ import org.hl7.fhir.r5.model.ValueSet;
|
||||||
import org.hl7.fhir.r5.utils.validation.IMessagingServices;
|
import org.hl7.fhir.r5.utils.validation.IMessagingServices;
|
||||||
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
|
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
|
||||||
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
|
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.BindingKind;
|
||||||
import org.hl7.fhir.r5.utils.validation.constants.CodedContentValidationPolicy;
|
|
||||||
import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy;
|
import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy;
|
||||||
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
|
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||||
|
@ -38,48 +35,105 @@ public class RulesDrivenPolicyAdvisor extends BasePolicyAdvisorForFullValidation
|
||||||
private class SuppressMessageRule {
|
private class SuppressMessageRule {
|
||||||
private String id;
|
private String id;
|
||||||
private String path;
|
private String path;
|
||||||
protected SuppressMessageRule(String id, String path) {
|
private String[] pathSegments;
|
||||||
|
private boolean regex;
|
||||||
|
|
||||||
|
protected SuppressMessageRule(@Nonnull String id, String path, boolean regex) {
|
||||||
super();
|
super();
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
|
this.pathSegments = path.split("\\.");
|
||||||
|
this.regex = regex;
|
||||||
}
|
}
|
||||||
public String getId() {
|
|
||||||
return id;
|
protected SuppressMessageRule(@Nonnull String id) {
|
||||||
|
super();
|
||||||
|
this.id = id;
|
||||||
}
|
}
|
||||||
public String getPath() {
|
|
||||||
return path;
|
public boolean matches(@Nonnull String mid, @Nonnull String path, String[] p) {
|
||||||
}
|
if (regex) {
|
||||||
public boolean matches(String mid, String p) {
|
return stringMatches(id, mid) && regexMatches(path, path);
|
||||||
if (((id == null) || id.equals(mid)) && ((path == null) || path.equals(p))) {
|
|
||||||
suppressed++;
|
|
||||||
return true;
|
|
||||||
} else if (((id == null) || mid.matches(id)) && ((path == null) || p.matches(path))) {
|
|
||||||
suppressed++;
|
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
|
return stringMatches(id, mid) && pathMatches(pathSegments, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// string matching
|
||||||
|
|
||||||
|
boolean pathMatches(String[] specifier, String[] actual) {
|
||||||
|
if (specifier == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < specifier.length; i++) {
|
||||||
|
if (i == actual.length) {
|
||||||
|
return false;
|
||||||
|
} else if (!pathSegmentMatches(specifier[i], actual[i])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (actual.length > specifier.length) {
|
||||||
|
return specifier[specifier.length-1].equals("*");
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean pathSegmentMatches(String specifier, String actual) {
|
||||||
|
if ("*".equals(specifier)) {
|
||||||
|
return true;
|
||||||
|
} else if (!specifier.contains("[")) {
|
||||||
|
if (actual.contains("[")) {
|
||||||
|
actual = actual.substring(0, actual.indexOf("["));
|
||||||
|
}
|
||||||
|
return specifier.equals(actual);
|
||||||
|
} else {
|
||||||
|
return specifier.equals(actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean stringMatches(String specifier, @Nonnull String actual) {
|
||||||
|
if (specifier == null) {
|
||||||
|
return true;
|
||||||
|
} else if (specifier.endsWith("*")) {
|
||||||
|
return specifier.substring(0, specifier.length()-1).equalsIgnoreCase(actual.substring(0, specifier.length()-1));
|
||||||
|
} else {
|
||||||
|
return specifier.equalsIgnoreCase(actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean regexMatches(String specifier, @Nonnull String actual) {
|
||||||
|
if (specifier == null) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return actual.matches(specifier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SuppressMessageRule> suppressMessageRules = new ArrayList<>();
|
private List<SuppressMessageRule> suppressMessageRules = new ArrayList<>();
|
||||||
private int suppressed = 0;
|
private int suppressed = 0;
|
||||||
|
|
||||||
protected void addSuppressMessageRule(String id, String path) {
|
protected void addSuppressMessageRule(@Nonnull String id, String path, boolean regex) {
|
||||||
suppressMessageRules.add(new SuppressMessageRule(id, path));
|
suppressMessageRules.add(new SuppressMessageRule(id, path, regex));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addSuppressMessageRule(@Nonnull String id) {
|
||||||
|
suppressMessageRules.add(new SuppressMessageRule(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean suppressMessageId(String path, String messageId) {
|
public boolean isSuppressMessageId(String path, String messageId) {
|
||||||
|
String[] p = path.split("\\.");
|
||||||
for (SuppressMessageRule rule : suppressMessageRules) {
|
for (SuppressMessageRule rule : suppressMessageRules) {
|
||||||
if (rule.matches(messageId, path)) {
|
if (rule.matches(messageId, path, p)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (base != null) {
|
if (base != null) {
|
||||||
return base.suppressMessageId(path, messageId);
|
return base.isSuppressMessageId(path, messageId);
|
||||||
} else {
|
} else {
|
||||||
return super.suppressMessageId(path, messageId);
|
return super.isSuppressMessageId(path, messageId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@ import java.io.File;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
|
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
|
||||||
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
|
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
@ -38,14 +40,19 @@ public class TextDrivenPolicyAdvisor extends RulesDrivenPolicyAdvisor {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (line.startsWith("-")) {
|
if (line.startsWith("-")) {
|
||||||
String s = line.substring(1).trim();
|
@Nonnull String s = line.substring(1).trim();
|
||||||
String id = s;
|
|
||||||
String path = null;
|
|
||||||
if (s.contains("@")) {
|
if (s.contains("@")) {
|
||||||
id = s.substring(0, s.indexOf("@"));
|
String id = s.substring(0, s.indexOf("@"));
|
||||||
path = s.substring(s.indexOf("@")+1);
|
String path = s.substring(s.indexOf("@")+1);
|
||||||
|
boolean regex = false;
|
||||||
|
if (path.startsWith("^")) {
|
||||||
|
regex = true;
|
||||||
|
path = path.substring(1);
|
||||||
|
}
|
||||||
|
addSuppressMessageRule(id, path, regex);
|
||||||
|
} else {
|
||||||
|
addSuppressMessageRule(s);
|
||||||
}
|
}
|
||||||
addSuppressMessageRule(id, path);
|
|
||||||
} else {
|
} else {
|
||||||
// ignore it for now
|
// ignore it for now
|
||||||
}
|
}
|
||||||
|
|
|
@ -922,7 +922,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean suppressMessageId(String path, String messageId) {
|
public boolean isSuppressMessageId(String path, String messageId) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue