Merge pull request #1311 from hapifhir/gg-202206-validator-watch-mode
Gg 202206 validator watch mode
This commit is contained in:
commit
36e94ce4be
|
@ -190,7 +190,9 @@ public class TerminologyClientR3 implements ITerminologyClient {
|
|||
@Override
|
||||
public ITerminologyClient setClientHeaders(ClientHeaders clientHeaders) {
|
||||
this.clientHeaders = clientHeaders;
|
||||
this.client.setClientHeaders(this.clientHeaders.headers());
|
||||
if (this.clientHeaders != null) {
|
||||
this.client.setClientHeaders(this.clientHeaders.headers());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -206,7 +206,9 @@ public class TerminologyClientR4 implements ITerminologyClient {
|
|||
@Override
|
||||
public ITerminologyClient setClientHeaders(ClientHeaders clientHeaders) {
|
||||
this.clientHeaders = clientHeaders;
|
||||
this.client.setClientHeaders(this.clientHeaders.headers());
|
||||
if (this.clientHeaders != null) {
|
||||
this.client.setClientHeaders(this.clientHeaders.headers());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,9 @@ public class FhirRequestBuilder {
|
|||
* @param headers {@link Headers} to add to request.
|
||||
*/
|
||||
protected static void addHeaders(Request.Builder request, Headers headers) {
|
||||
headers.forEach(header -> request.addHeader(header.getFirst(), header.getSecond()));
|
||||
if (headers != null) {
|
||||
headers.forEach(header -> request.addHeader(header.getFirst(), header.getSecond()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3174,7 +3174,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
if (mandatory) {
|
||||
if (prefixLength == 0)
|
||||
errors.add("Differential contains path "+path+" which is not found in the in base "+baseName);
|
||||
errors.add("Differential contains path "+path+" which is not found in the base "+baseName);
|
||||
else
|
||||
errors.add("Differential contains path "+path+" which is actually "+actual+", which is not found in the in base "+ baseName);
|
||||
}
|
||||
|
@ -3293,7 +3293,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
edh.getChildren().get(0).baseIndex = cmp.find(edh.getChildren().get(0).getSelf().getPath(), false);
|
||||
else
|
||||
Collections.sort(edh.getChildren(), cmp);
|
||||
cmp.checkForErrors(errors);
|
||||
if (debug) {
|
||||
cmp.checkForErrors(errors);
|
||||
}
|
||||
|
||||
for (ElementDefinitionHolder child : edh.getChildren()) {
|
||||
if (child.getChildren().size() > 0) {
|
||||
|
|
|
@ -3,19 +3,19 @@ package org.hl7.fhir.r5.context;
|
|||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
|
@ -26,7 +26,7 @@ package org.hl7.fhir.r5.context;
|
|||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
@ -43,7 +43,7 @@ import org.hl7.fhir.utilities.Utilities;
|
|||
public class TextClientLogger extends BaseLogger implements ToolingClientLogger {
|
||||
|
||||
private PrintStream file;
|
||||
|
||||
|
||||
public TextClientLogger(String log) {
|
||||
if (log != null) {
|
||||
try {
|
||||
|
@ -60,8 +60,10 @@ public class TextClientLogger extends BaseLogger implements ToolingClientLogger
|
|||
String id = nextId();
|
||||
file.println("\r\n--- "+id+" -----------------\r\nRequest: \r\n");
|
||||
file.println(method+" "+url+" HTTP/1.0");
|
||||
for (String s : headers)
|
||||
file.println(s);
|
||||
if (headers != null) {
|
||||
for (String s : headers)
|
||||
file.println(s);
|
||||
}
|
||||
if (body != null) {
|
||||
file.println("");
|
||||
try {
|
||||
|
|
|
@ -57,7 +57,7 @@ public class FmlParser extends ParserBase {
|
|||
}
|
||||
|
||||
public Element parse(String text) throws FHIRException {
|
||||
FHIRLexer lexer = new FHIRLexer(text, "source", true);
|
||||
FHIRLexer lexer = new FHIRLexer(text, "source", true, true);
|
||||
if (lexer.done())
|
||||
throw lexer.error("Map Input cannot be empty");
|
||||
Element result = Manager.build(context, context.fetchTypeDefinition("StructureMap"));
|
||||
|
|
|
@ -399,7 +399,7 @@ public class AdditionalBindingsRenderer {
|
|||
return; // what should happen?
|
||||
}
|
||||
BindingResolution br = pkp.resolveBinding(profile, b.getValueSet(), corePath);
|
||||
XhtmlNode a = children.ah(br.url == null ? null : Utilities.isAbsoluteUrl(br.url) || !context.getPkp().prependLinks() ? br.url : corePath+br.url, b.hasDocumentation() ? b.getDocumentation() : null);
|
||||
XhtmlNode a = children.ahOrCode(br.url == null ? null : Utilities.isAbsoluteUrl(br.url) || !context.getPkp().prependLinks() ? br.url : corePath+br.url, b.hasDocumentation() ? b.getDocumentation() : null);
|
||||
if (b.hasDocumentation()) {
|
||||
a.attribute("title", b.getDocumentation());
|
||||
}
|
||||
|
|
|
@ -979,9 +979,9 @@ public class ValueSetValidator {
|
|||
for (ConceptSetComponent vsi : valueset.getCompose().getInclude()) {
|
||||
Boolean ok = inComponent(path, vsi, i, system, version, code, valueset.getCompose().getInclude().size() == 1, info);
|
||||
i++;
|
||||
if (ok == null && result == false) {
|
||||
if (ok == null && result != null && result == false) {
|
||||
result = null;
|
||||
} else if (ok) {
|
||||
} else if (ok != null && ok) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
|
@ -990,7 +990,7 @@ public class ValueSetValidator {
|
|||
for (ConceptSetComponent vsi : valueset.getCompose().getExclude()) {
|
||||
Boolean nok = inComponent(path, vsi, i, system, version, code, valueset.getCompose().getInclude().size() == 1, info);
|
||||
i++;
|
||||
if (nok == null && result == false) {
|
||||
if (nok == null && result != null && result == false) {
|
||||
result = null;
|
||||
} else if (nok != null && nok) {
|
||||
result = false;
|
||||
|
@ -1200,6 +1200,7 @@ public class ValueSetValidator {
|
|||
}
|
||||
ValueSet vs = context.fetchResource(ValueSet.class, url, valueset);
|
||||
ValueSetValidator vsc = new ValueSetValidator(options, vs, context, localContext, expansionProfile, txCaps);
|
||||
vsc.setThrowToServer(throwToServer);
|
||||
inner.put(url, vsc);
|
||||
return vsc;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,7 @@ public class FHIRLexer {
|
|||
private boolean liquidMode; // in liquid mode, || terminates the expression and hands the parser back to the host
|
||||
private SourceLocation commentLocation;
|
||||
private boolean metadataFormat;
|
||||
private boolean allowDoubleQuotes;
|
||||
|
||||
public FHIRLexer(String source, String name) throws FHIRLexerException {
|
||||
this.source = source == null ? "" : source;
|
||||
|
@ -101,10 +102,18 @@ public class FHIRLexer {
|
|||
currentLocation = new SourceLocation(1, 1);
|
||||
next();
|
||||
}
|
||||
public FHIRLexer(String source, String name, boolean metadataFormat) throws FHIRLexerException {
|
||||
public FHIRLexer(String source, int i, boolean allowDoubleQuotes) throws FHIRLexerException {
|
||||
this.source = source;
|
||||
this.cursor = i;
|
||||
this.allowDoubleQuotes = allowDoubleQuotes;
|
||||
currentLocation = new SourceLocation(1, 1);
|
||||
next();
|
||||
}
|
||||
public FHIRLexer(String source, String name, boolean metadataFormat, boolean allowDoubleQuotes) throws FHIRLexerException {
|
||||
this.source = source == null ? "" : source;
|
||||
this.name = name == null ? "??" : name;
|
||||
this.metadataFormat = metadataFormat;
|
||||
this.allowDoubleQuotes = allowDoubleQuotes;
|
||||
currentLocation = new SourceLocation(1, 1);
|
||||
next();
|
||||
}
|
||||
|
@ -235,7 +244,7 @@ public class FHIRLexer {
|
|||
if (ch == '}')
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '"') {
|
||||
} else if (ch == '"' && allowDoubleQuotes) {
|
||||
cursor++;
|
||||
boolean escape = false;
|
||||
while (cursor < source.length() && (escape || source.charAt(cursor) != '"')) {
|
||||
|
@ -588,5 +597,7 @@ public class FHIRLexer {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAllowDoubleQuotes() {
|
||||
return allowDoubleQuotes;
|
||||
}
|
||||
}
|
|
@ -280,6 +280,7 @@ public class FHIRPathEngine {
|
|||
private boolean liquidMode; // in liquid mode, || terminates the expression and hands the parser back to the host
|
||||
private boolean doNotEnforceAsSingletonRule;
|
||||
private boolean doNotEnforceAsCaseSensitive;
|
||||
private boolean allowDoubleQuotes;
|
||||
|
||||
// if the fhir path expressions are allowed to use constants beyond those defined in the specification
|
||||
// the application can implement them by providing a constant resolver
|
||||
|
@ -511,7 +512,7 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
public ExpressionNode parse(String path, String name) throws FHIRLexerException {
|
||||
FHIRLexer lexer = new FHIRLexer(path, name);
|
||||
FHIRLexer lexer = new FHIRLexer(path, name, false, allowDoubleQuotes);
|
||||
if (lexer.done()) {
|
||||
throw lexer.error("Path cannot be empty");
|
||||
}
|
||||
|
@ -548,7 +549,7 @@ public class FHIRPathEngine {
|
|||
* @throws Exception
|
||||
*/
|
||||
public ExpressionNodeWithOffset parsePartial(String path, int i) throws FHIRLexerException {
|
||||
FHIRLexer lexer = new FHIRLexer(path, i);
|
||||
FHIRLexer lexer = new FHIRLexer(path, i, allowDoubleQuotes);
|
||||
if (lexer.done()) {
|
||||
throw lexer.error("Path cannot be empty");
|
||||
}
|
||||
|
@ -4150,7 +4151,6 @@ public class FHIRPathEngine {
|
|||
String param = nl.get(0).primitiveValue();
|
||||
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
|
||||
if (focus.size() == 1) {
|
||||
String cnt = focus.get(0).primitiveValue();
|
||||
if ("hex".equals(param)) {
|
||||
|
@ -4163,7 +4163,6 @@ public class FHIRPathEngine {
|
|||
result.add(new StringType(new String(enc.decode(cnt))));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -5816,7 +5815,11 @@ public class FHIRPathEngine {
|
|||
String tail = "";
|
||||
StructureDefinition sd = worker.fetchResource(StructureDefinition.class, url);
|
||||
if (sd == null) {
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_NO_TYPE, url, "getChildTypesByName");
|
||||
if (url.startsWith(TypeDetails.FP_NS)) {
|
||||
return;
|
||||
} else {
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_UNKNOWN_TYPE, url, "getChildTypesByName");
|
||||
}
|
||||
}
|
||||
List<StructureDefinition> sdl = new ArrayList<StructureDefinition>();
|
||||
ElementDefinitionMatch m = null;
|
||||
|
@ -5826,14 +5829,14 @@ public class FHIRPathEngine {
|
|||
if (m.fixedType != null) {
|
||||
StructureDefinition dt = worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(m.fixedType, null), sd);
|
||||
if (dt == null) {
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_NO_TYPE, ProfileUtilities.sdNs(m.fixedType, null), "getChildTypesByName");
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_UNKNOWN_TYPE, ProfileUtilities.sdNs(m.fixedType, null), "getChildTypesByName");
|
||||
}
|
||||
sdl.add(dt);
|
||||
} else
|
||||
for (TypeRefComponent t : m.definition.getType()) {
|
||||
StructureDefinition dt = worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(t.getCode(), null));
|
||||
if (dt == null) {
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_NO_TYPE, ProfileUtilities.sdNs(t.getCode(), null), "getChildTypesByName");
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_UNKNOWN_TYPE, ProfileUtilities.sdNs(t.getCode(), null), "getChildTypesByName");
|
||||
}
|
||||
addTypeAndDescendents(sdl, dt, cu.allStructures());
|
||||
// also add any descendant types
|
||||
|
@ -6392,4 +6395,10 @@ public class FHIRPathEngine {
|
|||
return profileUtilities;
|
||||
}
|
||||
|
||||
public boolean isAllowDoubleQuotes() {
|
||||
return allowDoubleQuotes;
|
||||
}
|
||||
public void setAllowDoubleQuotes(boolean allowDoubleQuotes) {
|
||||
this.allowDoubleQuotes = allowDoubleQuotes;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
@Override
|
||||
public void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) throws FHIRException {
|
||||
if (compiled.size() == 0) {
|
||||
FHIRLexer lexer = new FHIRLexer(statement, "liquid statement");
|
||||
FHIRLexer lexer = new FHIRLexer(statement, "liquid statement", false, true);
|
||||
lexer.setLiquidMode(true);
|
||||
compiled.add(new LiquidExpressionNode(null, engine.parse(lexer)));
|
||||
while (!lexer.done()) {
|
||||
|
|
|
@ -626,7 +626,7 @@ public class StructureMapUtilities {
|
|||
}
|
||||
|
||||
public StructureMap parse(String text, String srcName) throws FHIRException {
|
||||
FHIRLexer lexer = new FHIRLexer(Utilities.stripBOM(text), srcName, true);
|
||||
FHIRLexer lexer = new FHIRLexer(Utilities.stripBOM(text), srcName, true, true);
|
||||
if (lexer.done())
|
||||
throw lexer.error("Map Input cannot be empty");
|
||||
StructureMap result = new StructureMap();
|
||||
|
|
|
@ -81,6 +81,7 @@ public class BaseWorkerContextTests {
|
|||
public String getSpecUrl() {
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
baseWorkerContext.expParameters = new Parameters();
|
||||
return baseWorkerContext;
|
||||
|
|
|
@ -8,7 +8,7 @@ class FHIRLexerTest {
|
|||
@Test
|
||||
@DisplayName("Test that a 'null' current value returns 'false' when FHIRLexer.isConstant() is called, and not NPE.")
|
||||
void getCurrent() {
|
||||
FHIRLexer lexer = new FHIRLexer(null, null);
|
||||
FHIRLexer lexer = new FHIRLexer(null, null, false, true);
|
||||
String lexerCurrent = lexer.getCurrent();
|
||||
Assertions.assertNull(lexerCurrent);
|
||||
Assertions.assertFalse(lexer.isConstant());
|
||||
|
|
|
@ -163,8 +163,10 @@ public class SimpleHTTPClient {
|
|||
}
|
||||
|
||||
private void setHeaders(HttpURLConnection c) {
|
||||
for (Header h : headers) {
|
||||
c.setRequestProperty(h.getName(), h.getValue());
|
||||
if (headers != null) {
|
||||
for (Header h : headers) {
|
||||
c.setRequestProperty(h.getName(), h.getValue());
|
||||
}
|
||||
}
|
||||
c.setConnectTimeout(15000);
|
||||
c.setReadTimeout(15000);
|
||||
|
|
|
@ -171,6 +171,7 @@ public class I18nConstants {
|
|||
public static final String FHIRPATH_NOT_IMPLEMENTED = "FHIRPATH_NOT_IMPLEMENTED";
|
||||
public static final String FHIRPATH_NO_COLLECTION = "FHIRPATH_NO_COLLECTION";
|
||||
public static final String FHIRPATH_NO_TYPE = "FHIRPATH_NO_TYPE";
|
||||
public static final String FHIRPATH_UNKNOWN_TYPE = "FHIRPATH_UNKNOWN_TYPE";
|
||||
public static final String FHIRPATH_NUMERICAL_ONLY = "FHIRPATH_NUMERICAL_ONLY";
|
||||
public static final String FHIRPATH_OP_INCOMPATIBLE = "FHIRPATH_OP_INCOMPATIBLE";
|
||||
public static final String FHIRPATH_ORDERED_ONLY = "FHIRPATH_ORDERED_ONLY";
|
||||
|
@ -909,6 +910,10 @@ public class I18nConstants {
|
|||
public static final String QUESTIONNAIRE_Q_ITEM_DERIVED_ANSWER_OPTIONS_NEW = "QUESTIONNAIRE_Q_ITEM_DERIVED_ANSWER_OPTIONS_NEW";
|
||||
public static final String PRIMITIVE_MUSTHAVEVALUE_MESSAGE = "PRIMITIVE_MUSTHAVEVALUE_MESSAGE";
|
||||
public static final String PRIMITIVE_VALUE_ALTERNATIVES_MESSAGE = "PRIMITIVE_VALUE_ALTERNATIVES_MESSAGE";
|
||||
public static final String ED_INVARIANT_NO_KEY = "ED_INVARIANT_NO_KEY";
|
||||
public static final String ED_INVARIANT_NO_EXPRESSION = "ED_INVARIANT_NO_EXPRESSION";
|
||||
public static final String ED_INVARIANT_EXPRESSION_CONFLICT = "ED_INVARIANT_EXPRESSION_CONFLICT";
|
||||
public static final String ED_INVARIANT_EXPRESSION_ERROR = "ED_INVARIANT_EXPRESSION_ERROR";
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -121,6 +121,26 @@ public abstract class XhtmlFluent {
|
|||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* make it a code if it's not a link
|
||||
* @param href
|
||||
* @param title
|
||||
* @return
|
||||
*/
|
||||
public XhtmlNode ahOrCode(String href, String title) {
|
||||
if (href != null) {
|
||||
return ah(href, title);
|
||||
} else if (title != null) {
|
||||
return code().setAttribute("title", title);
|
||||
} else {
|
||||
return code();
|
||||
}
|
||||
}
|
||||
|
||||
public XhtmlNode ahOrCode(String href) {
|
||||
return ahOrCode(href, null);
|
||||
}
|
||||
|
||||
public XhtmlNode img(String src, String alt) {
|
||||
return addTag("img").attribute("src", src).attribute("alt", alt);
|
||||
}
|
||||
|
|
|
@ -610,7 +610,8 @@ FHIRPATH_NO_COLLECTION = Error evaluating FHIRPath expression: The function {0}
|
|||
FHIRPATH_NOT_IMPLEMENTED = Error evaluating FHIRPath expression: The function {0} is not implemented
|
||||
FHIRPATH_PARAM_WRONG = Error evaluating FHIRPath expression: The expression type {0} is not supported for parameter {1} on function {2}
|
||||
FHIRPATH_CHECK_FAILED = Error evaluating FHIRPath expression: The check {0} failed
|
||||
FHIRPATH_NO_TYPE = Error evaluating FHIRPath expression: The type ''{0}'' is unknown or not supported at {1}
|
||||
FHIRPATH_NO_TYPE = Error evaluating FHIRPath expression: No type provided at {1}
|
||||
FHIRPATH_UNKNOWN_TYPE = Error evaluating FHIRPath expression: The type ''{0}'' is unknown or not supported at {1}
|
||||
FHIRPATH_DISCRIMINATOR_NAME_ALREADY_SLICED = Error in discriminator at {0}: found a sliced element while resolving the fixed value for one of the slices
|
||||
FHIRPATH_DISCRIMINATOR_THIS_CANNOT_FIND = Problem with use of resolve() - profile {0} on {1} could not be resolved
|
||||
FHIRPATH_DISCRIMINATOR_RESOLVE_NO_TYPE = Invalid use of resolve() in discriminator - no type on element {0}
|
||||
|
@ -963,3 +964,8 @@ QUESTIONNAIRE_Q_ITEM_DERIVED_ANSWER_OPTIONS_NEW = The item with linkId ''{1}'' f
|
|||
PRIMITIVE_MUSTHAVEVALUE_MESSAGE = The element definition ``{0}`` in the profile ''{1}'' requires that a value be present in this element
|
||||
PRIMITIVE_VALUE_ALTERNATIVES_MESSAGE_one = The element definition ``{0}`` in the profile ''{1}'' requires that if a value is not present, the extension ''{2}'' must be present
|
||||
PRIMITIVE_VALUE_ALTERNATIVES_MESSAGE_other = The element definition ``{0}`` in the profile ''{1}'' requires that if a value is not present, one of the extensions ''{2}'' must be present
|
||||
ED_INVARIANT_NO_KEY = The invariant has no key, so the content cannot be validated
|
||||
ED_INVARIANT_NO_EXPRESSION = The invariant ''{0}'' has no computable expression, so validators will not be able to check it
|
||||
ED_INVARIANT_EXPRESSION_CONFLICT = The invariant ''{0}'' has an expression ''{1}'', which differs from the earlier expression provided of ''{2}'' (invariants are allowed to repeat, but cannot differ)
|
||||
ED_INVARIANT_EXPRESSION_ERROR = Error in invariant ''{0}'' with expression ''{1}'': {2}
|
||||
|
||||
|
|
|
@ -211,6 +211,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
@Getter @Setter private boolean showMessagesFromReferences;
|
||||
@Getter @Setter private boolean doImplicitFHIRPathStringConversion;
|
||||
@Getter @Setter private HtmlInMarkdownCheck htmlInMarkdownCheck;
|
||||
@Getter @Setter private boolean allowDoubleQuotesInFHIRPath;
|
||||
@Getter @Setter private Locale locale;
|
||||
@Getter @Setter private List<ImplementationGuide> igs = new ArrayList<>();
|
||||
@Getter @Setter private List<String> extensionDomains = new ArrayList<>();
|
||||
|
@ -262,6 +263,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
showMessagesFromReferences = other.showMessagesFromReferences;
|
||||
doImplicitFHIRPathStringConversion = other.doImplicitFHIRPathStringConversion;
|
||||
htmlInMarkdownCheck = other.htmlInMarkdownCheck;
|
||||
allowDoubleQuotesInFHIRPath = other.allowDoubleQuotesInFHIRPath;
|
||||
locale = other.locale;
|
||||
igs.addAll(other.igs);
|
||||
extensionDomains.addAll(other.extensionDomains);
|
||||
|
@ -471,6 +473,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
context.loadFromPackage(npmX, null);
|
||||
|
||||
this.fhirPathEngine = new FHIRPathEngine(context);
|
||||
this.fhirPathEngine.setAllowDoubleQuotes(false);
|
||||
}
|
||||
|
||||
private String getVersionFromPack(Map<String, byte[]> source) {
|
||||
|
@ -839,6 +842,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
validator.setQuestionnaireMode(questionnaireMode);
|
||||
validator.setLevel(level);
|
||||
validator.setHtmlInMarkdownCheck(htmlInMarkdownCheck);
|
||||
validator.setAllowDoubleQuotesInFHIRPath(allowDoubleQuotesInFHIRPath);
|
||||
validator.setNoUnicodeBiDiControlChars(noUnicodeBiDiControlChars);
|
||||
validator.setDoImplicitFHIRPathStringConversion(doImplicitFHIRPathStringConversion);
|
||||
if (format == FhirFormat.SHC) {
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.hl7.fhir.r5.utils.validation.BundleValidationRule;
|
|||
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.settings.FhirSettings;
|
||||
import org.hl7.fhir.validation.cli.services.ValidatorWatchMode;
|
||||
import org.hl7.fhir.validation.cli.utils.EngineMode;
|
||||
import org.hl7.fhir.validation.cli.utils.QuestionnaireMode;
|
||||
import org.hl7.fhir.validation.cli.utils.ValidationLevel;
|
||||
|
@ -53,7 +54,8 @@ public class CliContext {
|
|||
private boolean doImplicitFHIRPathStringConversion = false;
|
||||
@JsonProperty("htmlInMarkdownCheck")
|
||||
private HtmlInMarkdownCheck htmlInMarkdownCheck = HtmlInMarkdownCheck.WARNING;
|
||||
|
||||
@JsonProperty("allowDoubleQuotesInFHIRPath")
|
||||
private boolean allowDoubleQuotesInFHIRPath = false;
|
||||
@JsonProperty("langTransform")
|
||||
private String langTransform = null;
|
||||
@JsonProperty("map")
|
||||
|
@ -139,6 +141,8 @@ public class CliContext {
|
|||
@JsonProperty("fhirSettingsFile")
|
||||
private String fhirSettingsFile;
|
||||
|
||||
@JsonProperty("watchMode")
|
||||
private ValidatorWatchMode watchMode = ValidatorWatchMode.NONE;
|
||||
|
||||
@JsonProperty("map")
|
||||
public String getMap() {
|
||||
|
@ -294,6 +298,16 @@ public class CliContext {
|
|||
this.htmlInMarkdownCheck = htmlInMarkdownCheck;
|
||||
}
|
||||
|
||||
@JsonProperty("allowDoubleQuotesInFHIRPath")
|
||||
public boolean isAllowDoubleQuotesInFHIRPath() {
|
||||
return allowDoubleQuotesInFHIRPath;
|
||||
}
|
||||
|
||||
@JsonProperty("allowDoubleQuotesInFHIRPath")
|
||||
public void setAllowDoubleQuotesInFHIRPath(boolean allowDoubleQuotesInFHIRPath) {
|
||||
this.allowDoubleQuotesInFHIRPath = allowDoubleQuotesInFHIRPath;
|
||||
}
|
||||
|
||||
@JsonProperty("locale")
|
||||
public String getLanguageCode() {
|
||||
return locale;
|
||||
|
@ -705,8 +719,10 @@ public class CliContext {
|
|||
noInvariants == that.noInvariants &&
|
||||
displayWarnings == that.displayWarnings &&
|
||||
wantInvariantsInMessages == that.wantInvariantsInMessages &&
|
||||
allowDoubleQuotesInFHIRPath == that.allowDoubleQuotesInFHIRPath &&
|
||||
Objects.equals(extensions, that.extensions) &&
|
||||
Objects.equals(map, that.map) &&
|
||||
Objects.equals(htmlInMarkdownCheck, that.htmlInMarkdownCheck) &&
|
||||
Objects.equals(output, that.output) &&
|
||||
Objects.equals(outputSuffix, that.outputSuffix) &&
|
||||
Objects.equals(htmlOutput, that.htmlOutput) &&
|
||||
|
@ -727,21 +743,23 @@ public class CliContext {
|
|||
Objects.equals(profiles, that.profiles) &&
|
||||
Objects.equals(sources, that.sources) &&
|
||||
Objects.equals(crumbTrails, that.crumbTrails) &&
|
||||
Objects.equals(forPublication, that.forPublication) &&
|
||||
Objects.equals(forPublication, that.forPublication)&&
|
||||
Objects.equals(allowExampleUrls, that.allowExampleUrls) &&
|
||||
Objects.equals(showTimes, that.showTimes) &&
|
||||
mode == that.mode &&
|
||||
Objects.equals(locale, that.locale) &&
|
||||
Objects.equals(outputStyle, that.outputStyle) &&
|
||||
Objects.equals(jurisdiction, that.jurisdiction) &&
|
||||
Objects.equals(locations, that.locations);
|
||||
Objects.equals(locations, that.locations) &&
|
||||
Objects.equals(watchMode, that.watchMode) ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(doNative, extensions, hintAboutNonMustSupport, recursive, doDebug, assumeValidRestReferences, canDoNative, noInternalCaching,
|
||||
noExtensibleBindingMessages, noInvariants, displayWarnings, wantInvariantsInMessages, map, output, outputSuffix, htmlOutput, txServer, sv, txLog, txCache, mapLog, lang, srcLang, tgtLang, fhirpath, snomedCT,
|
||||
targetVer, igs, questionnaireMode, level, profiles, sources, inputs, mode, locale, locations, crumbTrails, forPublication, showTimes, allowExampleUrls, outputStyle, jurisdiction, noUnicodeBiDiControlChars);
|
||||
targetVer, igs, questionnaireMode, level, profiles, sources, inputs, mode, locale, locations, crumbTrails, forPublication, showTimes, allowExampleUrls, outputStyle, jurisdiction, noUnicodeBiDiControlChars, watchMode,
|
||||
htmlInMarkdownCheck, allowDoubleQuotesInFHIRPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -792,6 +810,9 @@ public class CliContext {
|
|||
", locale='" + locale + '\'' +
|
||||
", locations=" + locations +
|
||||
", bundleValidationRules=" + bundleValidationRules +
|
||||
", htmlInMarkdownCheck=" + htmlInMarkdownCheck +
|
||||
", allowDoubleQuotesInFHIRPath=" + allowDoubleQuotesInFHIRPath +
|
||||
", watchMode=" + watchMode +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
@ -805,4 +826,17 @@ public class CliContext {
|
|||
public String getFhirSettingsFile() {
|
||||
return fhirSettingsFile;
|
||||
}
|
||||
|
||||
@JsonProperty("watchMode")
|
||||
public ValidatorWatchMode getWatchMode() {
|
||||
return watchMode;
|
||||
}
|
||||
|
||||
@JsonProperty("watchMode")
|
||||
public CliContext setWatchMode(ValidatorWatchMode watchMode) {
|
||||
this.watchMode = watchMode;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -143,11 +143,10 @@ public class ValidationService {
|
|||
return versions;
|
||||
}
|
||||
|
||||
public void validateSources(CliContext cliContext, ValidationEngine validator) throws Exception {
|
||||
public void validateSources(CliContext cliContext, ValidationEngine validator, ValidatorWatchMode watch) throws Exception {
|
||||
if (cliContext.getProfiles().size() > 0) {
|
||||
System.out.println(" Profiles: " + cliContext.getProfiles());
|
||||
}
|
||||
ValidatorWatchMode watch = ValidatorWatchMode.NONE;
|
||||
IgLoader igLoader = new IgLoader(validator.getPcm(), validator.getContext(), validator.getVersion());
|
||||
|
||||
List<ValidationRecord> records = new ArrayList<>();
|
||||
|
@ -467,6 +466,7 @@ public class ValidationService {
|
|||
validationEngine.setShowMessagesFromReferences(cliContext.isShowMessagesFromReferences());
|
||||
validationEngine.setDoImplicitFHIRPathStringConversion(cliContext.isDoImplicitFHIRPathStringConversion());
|
||||
validationEngine.setHtmlInMarkdownCheck(cliContext.getHtmlInMarkdownCheck());
|
||||
validationEngine.setAllowDoubleQuotesInFHIRPath(cliContext.isAllowDoubleQuotesInFHIRPath());
|
||||
validationEngine.setNoExtensibleBindingMessages(cliContext.isNoExtensibleBindingMessages());
|
||||
validationEngine.setNoUnicodeBiDiControlChars(cliContext.isNoUnicodeBiDiControlChars());
|
||||
validationEngine.setNoInvariantChecks(cliContext.isNoInvariants());
|
||||
|
@ -690,7 +690,7 @@ public class ValidationService {
|
|||
if (!sd.hasSnapshot()) {
|
||||
StructureDefinition base = validator.getContext().fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
cs++;
|
||||
new ProfileUtilities(validator.getContext(), null, null).setAutoFixSliceNames(true).generateSnapshot(base, sd, sd.getUrl(), null, sd.getName());
|
||||
new ProfileUtilities(validator.getContext(), new ArrayList<ValidationMessage>(), null).setAutoFixSliceNames(true).generateSnapshot(base, sd, sd.getUrl(), null, sd.getName());
|
||||
validator.handleOutput(sd, filename, validator.getVersion());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import org.hl7.fhir.utilities.TimeTracker;
|
|||
import org.hl7.fhir.validation.ValidationEngine;
|
||||
import org.hl7.fhir.validation.cli.model.CliContext;
|
||||
import org.hl7.fhir.validation.cli.services.ValidationService;
|
||||
import org.hl7.fhir.validation.cli.services.ValidatorWatchMode;
|
||||
import org.hl7.fhir.validation.cli.utils.Display;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
@ -54,7 +55,7 @@ public class ValidateTask extends ValidationEngineTask {
|
|||
}
|
||||
System.out.println("Validating");
|
||||
|
||||
validationService.validateSources(cliContext, validationEngine);
|
||||
validationService.validateSources(cliContext, validationEngine, cliContext.getWatchMode());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.hl7.fhir.r5.utils.validation.BundleValidationRule;
|
|||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.validation.cli.model.CliContext;
|
||||
import org.hl7.fhir.validation.cli.model.HtmlInMarkdownCheck;
|
||||
import org.hl7.fhir.validation.cli.services.ValidatorWatchMode;
|
||||
|
||||
public class Params {
|
||||
|
||||
|
@ -83,6 +84,7 @@ public class Params {
|
|||
public static final String HTML_IN_MARKDOWN = "-html-in-markdown";
|
||||
public static final String SRC_LANG = "-src-lang";
|
||||
public static final String TGT_LANG = "-tgt-lang";
|
||||
public static final String ALLOW_DOUBLE_QUOTES = "-allow-double-quotes-in-fhirpath";
|
||||
|
||||
|
||||
public static final String RUN_TESTS = "-run-tests";
|
||||
|
@ -96,6 +98,7 @@ public class Params {
|
|||
public static final String INPUT = "-input";
|
||||
public static final String FILTER = "-filter";
|
||||
private static final String FHIR_SETTINGS_PARAM = "-fhir-settings";
|
||||
private static final String WATCH_MODE_PARAM = "-watch-mode";
|
||||
|
||||
/**
|
||||
* Checks the list of passed in params to see if it contains the passed in param.
|
||||
|
@ -240,6 +243,8 @@ public class Params {
|
|||
cliContext.setNoInternalCaching(true);
|
||||
} else if (args[i].equals(NO_EXTENSIBLE_BINDING_WARNINGS)) {
|
||||
cliContext.setNoExtensibleBindingMessages(true);
|
||||
} else if (args[i].equals(ALLOW_DOUBLE_QUOTES)) {
|
||||
cliContext.setAllowDoubleQuotesInFHIRPath(true);
|
||||
} else if (args[i].equals(NO_UNICODE_BIDI_CONTROL_CHARS)) {
|
||||
cliContext.setNoUnicodeBiDiControlChars(true);
|
||||
} else if (args[i].equals(NO_INVARIANTS)) {
|
||||
|
@ -381,6 +386,12 @@ public class Params {
|
|||
} else {
|
||||
throw new Exception("Can only nominate a single -map parameter");
|
||||
}
|
||||
} else if (args[i].equals(WATCH_MODE_PARAM)) {
|
||||
if (i + 1 == args.length) {
|
||||
throw new Error("Specified -watch-mode without indicating mode value");
|
||||
} else {
|
||||
cliContext.setWatchMode(readWatchMode(args[++i]));
|
||||
}
|
||||
} else if (args[i].startsWith(X)) {
|
||||
i++;
|
||||
} else if (args[i].equals(CONVERT)) {
|
||||
|
@ -402,6 +413,21 @@ public class Params {
|
|||
return cliContext;
|
||||
}
|
||||
|
||||
private static ValidatorWatchMode readWatchMode(String s) {
|
||||
if (s == null) {
|
||||
return ValidatorWatchMode.NONE;
|
||||
}
|
||||
switch (s.toLowerCase()) {
|
||||
case "all" : return ValidatorWatchMode.ALL;
|
||||
case "none" : return ValidatorWatchMode.NONE;
|
||||
case "single" : return ValidatorWatchMode.SINGLE;
|
||||
case "a" : return ValidatorWatchMode.ALL;
|
||||
case "n" : return ValidatorWatchMode.NONE;
|
||||
case "s" : return ValidatorWatchMode.SINGLE;
|
||||
}
|
||||
throw new Error("The watch mode ''"+s+"'' is not valid");
|
||||
}
|
||||
|
||||
private static String processJurisdiction(String s) {
|
||||
if (s.startsWith("urn:iso:std:iso:3166#") || s.startsWith("urn:iso:std:iso:3166:-2#") || s.startsWith("http://unstats.un.org/unsd/methods/m49/m49.htm#")) {
|
||||
return s;
|
||||
|
|
|
@ -466,7 +466,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
private boolean noUnicodeBiDiControlChars;
|
||||
private HtmlInMarkdownCheck htmlInMarkdownCheck;
|
||||
private boolean allowComments;
|
||||
private boolean displayWarnings;
|
||||
private boolean allowDoubleQuotesInFHIRPath;
|
||||
|
||||
private List<ImplementationGuide> igs = new ArrayList<>();
|
||||
private List<String> extensionDomains = new ArrayList<String>();
|
||||
|
@ -518,6 +518,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
fpe.setLegacyMode(true);
|
||||
source = Source.InstanceValidator;
|
||||
fpe.setDoNotEnforceAsSingletonRule(!VersionUtilities.isR5VerOrLater(theContext.getVersion()));
|
||||
fpe.setAllowDoubleQuotes(allowDoubleQuotesInFHIRPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2036,12 +2037,19 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
} else if (ctxt.getType() == ExtensionContextType.EXTENSION) {
|
||||
contexts.append("x:" + ctxt.getExpression());
|
||||
NodeStack estack = stack.getParent();
|
||||
if (estack != null && estack.getElement().fhirType().equals("Extension")) {
|
||||
String ext = estack.getElement().getNamedChildValue("url");
|
||||
if (ctxt.getExpression().equals(ext)) {
|
||||
ok = true;
|
||||
String ext = null;
|
||||
if (stack.getElement().getName().startsWith("value")) {
|
||||
NodeStack estack = stack.getParent();
|
||||
if (estack != null && estack.getElement().fhirType().equals("Extension")) {
|
||||
ext = estack.getElement().getNamedChildValue("url");
|
||||
}
|
||||
} else {
|
||||
ext = stack.getElement().getNamedChildValue("url");
|
||||
}
|
||||
if (ctxt.getExpression().equals(ext)) {
|
||||
ok = true;
|
||||
} else if (ext != null) {
|
||||
plist.add(ext);
|
||||
}
|
||||
} else if (ctxt.getType() == ExtensionContextType.FHIRPATH) {
|
||||
contexts.append("p:" + ctxt.getExpression());
|
||||
|
@ -6490,6 +6498,14 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
|
||||
|
||||
public boolean isAllowDoubleQuotesInFHIRPath() {
|
||||
return allowDoubleQuotesInFHIRPath;
|
||||
}
|
||||
|
||||
public void setAllowDoubleQuotesInFHIRPath(boolean allowDoubleQuotesInFHIRPath) {
|
||||
this.allowDoubleQuotesInFHIRPath = allowDoubleQuotesInFHIRPath;
|
||||
}
|
||||
|
||||
public static void setParents(Element element) {
|
||||
if (element != null && !element.hasParentForValidator()) {
|
||||
element.setParentForValidator(null);
|
||||
|
|
|
@ -5,7 +5,9 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50;
|
||||
|
@ -129,10 +131,10 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
boolean logical = "logical".equals(src.getNamedChildValue("kind"));
|
||||
boolean constraint = "constraint".equals(src.getNamedChildValue("derivation"));
|
||||
for (Element differential : differentials) {
|
||||
ok = validateElementList(errors, differential, stack.push(differential, -1, null, null), false, snapshots.size() > 0, sd, typeName, logical, constraint) && ok;
|
||||
ok = validateElementList(errors, differential, stack.push(differential, -1, null, null), false, snapshots.size() > 0, sd, typeName, logical, constraint, src.getNamedChildValue("type"), src.getNamedChildValue("url")) && ok;
|
||||
}
|
||||
for (Element snapshotE : snapshots) {
|
||||
ok = validateElementList(errors, snapshotE, stack.push(snapshotE, -1, null, null), true, true, sd, typeName, logical, constraint) && ok;
|
||||
ok = validateElementList(errors, snapshotE, stack.push(snapshotE, -1, null, null), true, true, sd, typeName, logical, constraint, src.getNamedChildValue("type"), src.getNamedChildValue("url")) && ok;
|
||||
}
|
||||
|
||||
// obligation profile support
|
||||
|
@ -330,18 +332,19 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean validateElementList(List<ValidationMessage> errors, Element elementList, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName, boolean logical, boolean constraint) {
|
||||
private boolean validateElementList(List<ValidationMessage> errors, Element elementList, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName, boolean logical, boolean constraint, String rootPath, String profileUrl) {
|
||||
Map<String, String> invariantMap = new HashMap<>();
|
||||
boolean ok = true;
|
||||
List<Element> elements = elementList.getChildrenByName("element");
|
||||
int cc = 0;
|
||||
for (Element element : elements) {
|
||||
ok = validateElementDefinition(errors, element, stack.push(element, cc, null, null), snapshot, hasSnapshot, sd, typeName, logical, constraint) && ok;
|
||||
ok = validateElementDefinition(errors, element, stack.push(element, cc, null, null), snapshot, hasSnapshot, sd, typeName, logical, constraint, invariantMap, rootPath, profileUrl) && ok;
|
||||
cc++;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
private boolean validateElementDefinition(List<ValidationMessage> errors, Element element, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName, boolean logical, boolean constraint) {
|
||||
private boolean validateElementDefinition(List<ValidationMessage> errors, Element element, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName, boolean logical, boolean constraint, Map<String, String> invariantMap, String rootPath, String profileUrl) {
|
||||
boolean ok = true;
|
||||
boolean typeMustSupport = false;
|
||||
String path = element.getNamedChildValue("path");
|
||||
|
@ -466,9 +469,40 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
}
|
||||
// if we see fixed[x] or pattern[x] applied to a repeating element, we'll give the user a hint
|
||||
}
|
||||
List<Element> constraints = element.getChildrenByName("constraint");
|
||||
int cc = 0;
|
||||
for (Element invariant : constraints) {
|
||||
ok = validateElementDefinitionInvariant(errors, invariant, stack.push(invariant, cc, null, null), invariantMap, element.getNamedChildValue("path"), rootPath, profileUrl) && ok;
|
||||
cc++;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
private boolean validateElementDefinitionInvariant(List<ValidationMessage> errors, Element invariant, NodeStack stack, Map<String, String> invariantMap, String path, String rootPath, String profileUrl) {
|
||||
boolean ok = true;
|
||||
String key = invariant.getNamedChildValue("key");
|
||||
String expression = invariant.getNamedChildValue("expression");
|
||||
String source = invariant.getNamedChildValue("source");
|
||||
if (warning(errors, "2023-06-19", IssueType.INFORMATIONAL, stack, !Utilities.noString(key), I18nConstants.ED_INVARIANT_NO_KEY)) {
|
||||
if (hint(errors, "2023-06-19", IssueType.INFORMATIONAL, stack, !Utilities.noString(expression), I18nConstants.ED_INVARIANT_NO_EXPRESSION, key)) {
|
||||
if (invariantMap.containsKey(key)) {
|
||||
// it's legal - and common - for a list of elemnts to contain the same invariant more than once, but it's not valid if it's not always the same
|
||||
ok = rule(errors, "2023-06-19", IssueType.INVALID, stack, expression.equals(invariantMap.get(key)), I18nConstants.ED_INVARIANT_EXPRESSION_CONFLICT, key, expression, invariantMap.get(key));
|
||||
} else {
|
||||
invariantMap.put(key, expression);
|
||||
}
|
||||
if (Utilities.noString(source) || (source.equals(profileUrl))) { // no need to revalidate FHIRPath from elsewhere
|
||||
try {
|
||||
fpe.check(invariant, rootPath, path, fpe.parse(expression));
|
||||
} catch (Exception e) {
|
||||
ok = rule(errors, "2023-06-19", IssueType.INVALID, stack, false, I18nConstants.ED_INVARIANT_EXPRESSION_ERROR, key, expression, e.getMessage()) && ok;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
private boolean meaningWhenMissingAllowed(Element element) {
|
||||
// allowed to use meaningWhenMissing on the root of an element to say what it means when the extension
|
||||
// is not present.
|
||||
|
|
|
@ -51,11 +51,13 @@ public class ProfileValidator extends BaseValidator {
|
|||
|
||||
private boolean checkAggregation = false;
|
||||
private boolean checkMustSupport = false;
|
||||
private boolean allowDoubleQuotesInFHIRPath = false;
|
||||
private FHIRPathEngine fpe;
|
||||
|
||||
public ProfileValidator(IWorkerContext context, XVerExtensionManager xverManager) {
|
||||
super(context, xverManager);
|
||||
fpe = new FHIRPathEngine(context);
|
||||
fpe.setAllowDoubleQuotes(allowDoubleQuotesInFHIRPath);
|
||||
}
|
||||
|
||||
public boolean isCheckAggregation() {
|
||||
|
@ -74,6 +76,14 @@ public class ProfileValidator extends BaseValidator {
|
|||
this.checkMustSupport = checkMustSupport;
|
||||
}
|
||||
|
||||
public boolean isAllowDoubleQuotesInFHIRPath() {
|
||||
return allowDoubleQuotesInFHIRPath;
|
||||
}
|
||||
|
||||
public void setAllowDoubleQuotesInFHIRPath(boolean allowDoubleQuotesInFHIRPath) {
|
||||
this.allowDoubleQuotesInFHIRPath = allowDoubleQuotesInFHIRPath;
|
||||
}
|
||||
|
||||
protected boolean rule(List<ValidationMessage> errors, IssueType type, String path, boolean b, String msg) {
|
||||
String rn = path.contains(".") ? path.substring(0, path.indexOf(".")) : path;
|
||||
return super.ruleHtml(errors, NO_RULE_DATE, type, path, b, msg, "<a href=\""+(rn.toLowerCase())+".html\">"+rn+"</a>: "+Utilities.escapeXml(msg));
|
||||
|
|
|
@ -5,8 +5,8 @@ The validation tool compares a resource against the base definitions and any
|
|||
profiles declared in the resource (Resource.meta.profile) or specified on the
|
||||
command line
|
||||
|
||||
The FHIR validation tool validates a FHIR resource or bundle. Schema and
|
||||
schematron checking is performed, then some additional checks are performed.
|
||||
The FHIR validation tool validates a FHIR resource or bundle. Syntax and content is checked
|
||||
against the specification and other profiles as specified.
|
||||
|
||||
* XML & Json (FHIR versions {{XML_AND_JSON_FHIR_VERSIONS}})
|
||||
* Turtle (FHIR versions {{TURTLE_FHIR_VERSIONS}})
|
||||
|
@ -72,6 +72,16 @@ The following parameters are supported:
|
|||
Default: results are sent to the std out.
|
||||
-outputSuffix [string]: used in -convert and -snapshot to deal with
|
||||
one or more result files (where -output can only have one)
|
||||
-watch-mode [mode]:
|
||||
Specify that the validator remain running and re-validate when any
|
||||
of the validated files changes. The validator has to be terminated with
|
||||
ctrl-c etc in this mode.
|
||||
This parameter can have one of the following values:
|
||||
* none: the default - don't wait, just stop when finished
|
||||
* single: when any of the validated files changes, re-validate it
|
||||
* all: when any of the validated files changes, re-validate all of them
|
||||
All is useful when the content includes internal dependencies e.g.
|
||||
a profile and it's value sets.
|
||||
-debug
|
||||
Produce additional information about the loading/validation process
|
||||
-recurse
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.hl7.fhir.validation;
|
|||
import org.hl7.fhir.utilities.TimeTracker;
|
||||
import org.hl7.fhir.validation.cli.model.CliContext;
|
||||
import org.hl7.fhir.validation.cli.services.ValidationService;
|
||||
import org.hl7.fhir.validation.cli.services.ValidatorWatchMode;
|
||||
import org.hl7.fhir.validation.cli.tasks.*;
|
||||
import org.hl7.fhir.validation.cli.utils.Params;
|
||||
|
||||
|
@ -245,9 +246,10 @@ public class ValidatorCliTests {
|
|||
final String[] args = new String[]{"dummyFile.json"};
|
||||
CliContext cliContext = Params.loadCliContext(args);
|
||||
ValidatorCli cli = mockValidatorCliWithService(cliContext);
|
||||
ValidatorWatchMode watchMode = ValidatorWatchMode.NONE;
|
||||
cli.readParamsAndExecuteTask(cliContext, args);
|
||||
Mockito.verify(validationService).determineVersion(same(cliContext));
|
||||
Mockito.verify(validationService).validateSources(same(cliContext), same(validationEngine));
|
||||
Mockito.verify(validationService).validateSources(same(cliContext), same(validationEngine), same(watchMode));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue