2023 10 gg code gen (#1469)

* Revise FHIRPath API so hosts can evaluate expressions in custom functions

* Implement slice() function in validator

* more improvements to profile generation

* Fix issue where .resolve() in FHIRPath didn't work with URL values (and fix typo in i18n system)

* release notes

* Fix test ignore/exclude issues, bump test cases

---------

Co-authored-by: Grahame Grieve <grahameg@gmail.ccom>
Co-authored-by: dotasek <david.otasek@smilecdr.com>
This commit is contained in:
Grahame Grieve 2023-10-25 06:26:24 +11:00 committed by GitHub
parent 1534a5b6eb
commit e431770caf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
56 changed files with 1052 additions and 386 deletions

View File

@ -5,12 +5,16 @@
* Update ViewDefinition validator for change (alias -> name)
* Fix for NPE validating sql-on-fhir ViewDefinition
* Fix for index out of bounds error when extension uses itself
* Fix issue where .resolve() in FHIRPath didn't work with URL values (and fix typo in i18n system)
* Implement FHIRPath slice() function in validator
## Other code changes
* Breaking API Change: Revise FHIRPath API so hosts can evaluate expressions in custom functions
* Add package use tracking to FHIR cache for validator.fhir.org
* Support for instance-name and instance-description in IG publisher
* Element.removeExtension (support for instance-name and instance-description extensions in IG publisher)
* Split terminology service tests
* Hack for wrong URLs in subscriptions backport
* Remove dependencies for unused UI experiment
* More improvements to profile code generation

View File

@ -5,6 +5,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
@ -245,4 +246,7 @@ public class TestingUtilities {
return null;
}
public static boolean runningAsSurefire() {
return "true".equals(System.getProperty("runningAsSurefire") != null ? System.getProperty("runningAsSurefire").toLowerCase(Locale.ENGLISH) : "");
}
}

View File

@ -5,6 +5,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
@ -245,4 +246,8 @@ public class TestingUtilities {
return null;
}
public static boolean runningAsSurefire() {
return "true".equals(System.getProperty("runningAsSurefire") != null ? System.getProperty("runningAsSurefire").toLowerCase(Locale.ENGLISH) : "");
}
}

View File

@ -7,6 +7,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
@ -276,5 +277,7 @@ public class TestingUtilities extends BaseTestingUtilities {
return null;
}
public static boolean runningAsSurefire() {
return "true".equals(System.getProperty("runningAsSurefire") != null ? System.getProperty("runningAsSurefire").toLowerCase(Locale.ENGLISH) : "");
}
}

View File

@ -38,6 +38,7 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
@ -528,4 +529,7 @@ public class TestingUtilities {
}
}
public static boolean runningAsSurefire() {
return "true".equals(System.getProperty("runningAsSurefire") != null ? System.getProperty("runningAsSurefire").toLowerCase(Locale.ENGLISH) : "");
}
}

View File

@ -59,6 +59,7 @@ import org.hl7.fhir.r4.utils.FHIRLexer.FHIRLexerException;
import org.hl7.fhir.r4.utils.FHIRPathUtilityClasses.FHIRConstant;
import org.hl7.fhir.r4.utils.FHIRPathUtilityClasses.ClassTypeInfo;
import org.hl7.fhir.r4.utils.FHIRPathUtilityClasses.TypedElementDefinition;
import org.hl7.fhir.r4.utils.FHIRPathEngine;
import org.hl7.fhir.r4.utils.FHIRPathUtilityClasses.FunctionDetails;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.MergedList;
@ -150,9 +151,9 @@ public class FHIRPathEngine {
* @return the value of the reference (or null, if it's not valid, though can
* throw an exception if desired)
*/
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException;
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException;
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException;
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException;
/**
* when the .log() function is called
@ -169,7 +170,7 @@ public class FHIRPathEngine {
* @param functionName
* @return null if the function is not known
*/
public FunctionDetails resolveFunction(String functionName);
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName);
/**
* Check the function parameters, and throw an error if they are incorrect, or
@ -179,7 +180,7 @@ public class FHIRPathEngine {
* @param parameters
* @return
*/
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters)
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters)
throws PathEngineException;
/**
@ -188,7 +189,7 @@ public class FHIRPathEngine {
* @param parameters
* @return
*/
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName,
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName,
List<List<Base>> parameters);
/**
@ -200,14 +201,14 @@ public class FHIRPathEngine {
* @return
* @throws FHIRException
*/
public Base resolveReference(Object appContext, String url, Base refContext) throws FHIRException;
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) throws FHIRException;
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException;
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException;
/*
* return the value set referenced by the url, which has been used in memberOf()
*/
public ValueSet resolveValueSet(Object appContext, String url);
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url);
}
/**
@ -1032,7 +1033,7 @@ public class FHIRPathEngine {
FunctionDetails details = null;
if (f == null) {
if (hostServices != null) {
details = hostServices.resolveFunction(result.getName());
details = hostServices.resolveFunction(this, result.getName());
}
if (details == null) {
throw lexer.error("The name " + result.getName() + " is not a valid function name");
@ -1473,7 +1474,7 @@ public class FHIRPathEngine {
work.addAll(work2);
break;
case Constant:
work.addAll(resolveConstant(context, exp.getConstant(), false, exp));
work.addAll(resolveConstant(context, exp.getConstant(), false, exp, true));
break;
case Group:
work2 = execute(context, focus, exp.getGroup(), atEntry);
@ -1563,7 +1564,7 @@ public class FHIRPathEngine {
} else if (atEntry && exp.getName().equals("$index")) {
result.addType(TypeDetails.FP_Integer);
} else if (atEntry && focus == null) {
result.update(executeContextType(context, exp.getName(), exp));
result.update(executeContextType(context, exp.getName(), exp, false));
} else {
for (String s : focus.getTypes()) {
result.update(executeType(s, exp, atEntry));
@ -1582,7 +1583,7 @@ public class FHIRPathEngine {
result.addType(TypeDetails.FP_Quantity);
break;
case Constant:
result.update(resolveConstantType(context, exp.getConstant(), exp));
result.update(resolveConstantType(context, exp.getConstant(), exp, true));
break;
case Group:
result.update(executeType(context, focus, exp.getGroup(), atEntry));
@ -1612,8 +1613,7 @@ public class FHIRPathEngine {
return result;
}
private List<Base> resolveConstant(ExecutionContext context, Base constant, boolean beforeContext,
ExpressionNode expr) throws PathEngineException {
private List<Base> resolveConstant(ExecutionContext context, Base constant, boolean beforeContext, ExpressionNode expr, boolean explicitConstant) throws PathEngineException {
if (constant == null) {
return new ArrayList<Base>();
}
@ -1622,7 +1622,7 @@ public class FHIRPathEngine {
}
FHIRConstant c = (FHIRConstant) constant;
if (c.getValue().startsWith("%")) {
return resolveConstant(context, c.getValue(), beforeContext, expr);
return resolveConstant(context, c.getValue(), beforeContext, expr, explicitConstant);
} else if (c.getValue().startsWith("@")) {
return new ArrayList<Base>(Arrays.asList(processDateConstant(context.appInfo, c.getValue().substring(1), expr)));
} else {
@ -1692,7 +1692,7 @@ public class FHIRPathEngine {
}
}
private List<Base> resolveConstant(ExecutionContext context, String s, boolean beforeContext, ExpressionNode expr)
private List<Base> resolveConstant(ExecutionContext context, String s, boolean beforeContext, ExpressionNode expr, boolean explicitConstant)
throws PathEngineException {
if (s.equals("%sct")) {
return new ArrayList<Base>(Arrays.asList(new StringType("http://snomed.info/sct").noExtensions()));
@ -1726,7 +1726,7 @@ public class FHIRPathEngine {
} else if (hostServices == null) {
throw makeException(expr, I18nConstants.FHIRPATH_UNKNOWN_CONSTANT, s);
} else {
return hostServices.resolveConstant(context.appInfo, s.substring(1), beforeContext);
return hostServices.resolveConstant(this, context.appInfo, s.substring(1), beforeContext, explicitConstant);
}
}
@ -2549,7 +2549,7 @@ public class FHIRPathEngine {
throws FHIRException {
boolean ans = false;
String url = right.get(0).primitiveValue();
ValueSet vs = hostServices != null ? hostServices.resolveValueSet(context.appInfo, url)
ValueSet vs = hostServices != null ? hostServices.resolveValueSet(this, context.appInfo, url)
: worker.fetchResource(ValueSet.class, url);
if (vs != null) {
for (Base l : left) {
@ -3079,7 +3079,7 @@ public class FHIRPathEngine {
return result;
}
private TypeDetails resolveConstantType(ExecutionTypeContext context, Base constant, ExpressionNode expr)
private TypeDetails resolveConstantType(ExecutionTypeContext context, Base constant, ExpressionNode expr, boolean explicitConstant)
throws PathEngineException {
if (constant instanceof BooleanType) {
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
@ -3090,7 +3090,7 @@ public class FHIRPathEngine {
} else if (constant instanceof Quantity) {
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Quantity);
} else if (constant instanceof FHIRConstant) {
return resolveConstantType(context, ((FHIRConstant) constant).getValue(), expr);
return resolveConstantType(context, ((FHIRConstant) constant).getValue(), expr, explicitConstant);
} else if (constant == null) {
return new TypeDetails(CollectionStatus.SINGLETON);
} else {
@ -3098,7 +3098,7 @@ public class FHIRPathEngine {
}
}
private TypeDetails resolveConstantType(ExecutionTypeContext context, String s, ExpressionNode expr)
private TypeDetails resolveConstantType(ExecutionTypeContext context, String s, ExpressionNode expr, boolean explicitConstant)
throws PathEngineException {
if (s.startsWith("@")) {
if (s.startsWith("@T")) {
@ -3137,7 +3137,7 @@ public class FHIRPathEngine {
} else if (hostServices == null) {
throw makeException(expr, I18nConstants.FHIRPATH_UNKNOWN_CONSTANT, s);
} else {
return hostServices.resolveConstantType(context.appInfo, s);
return hostServices.resolveConstantType(this, context.appInfo, s, explicitConstant);
}
}
@ -3146,7 +3146,7 @@ public class FHIRPathEngine {
List<Base> result = new ArrayList<Base>();
if (atEntry && context.appInfo != null && hostServices != null) {
// we'll see if the name matches a constant known by the context.
List<Base> temp = hostServices.resolveConstant(context.appInfo, exp.getName(), true);
List<Base> temp = hostServices.resolveConstant(this, context.appInfo, exp.getName(), true, false);
if (!temp.isEmpty()) {
result.addAll(temp);
return result;
@ -3177,7 +3177,7 @@ public class FHIRPathEngine {
// constant known by the context.
// (if the name does match, and the user wants to get the constant value,
// they'll have to try harder...
result.addAll(hostServices.resolveConstant(context.appInfo, exp.getName(), false));
result.addAll(hostServices.resolveConstant(this, context.appInfo, exp.getName(), false, false));
}
return result;
}
@ -3186,12 +3186,12 @@ public class FHIRPathEngine {
return null;
}
private TypeDetails executeContextType(ExecutionTypeContext context, String name, ExpressionNode expr)
private TypeDetails executeContextType(ExecutionTypeContext context, String name, ExpressionNode expr, boolean explicitConstant)
throws PathEngineException, DefinitionException {
if (hostServices == null) {
throw makeException(expr, I18nConstants.FHIRPATH_HO_HOST_SERVICES, "Context Reference");
}
return hostServices.resolveConstantType(context.appInfo, name);
return hostServices.resolveConstantType(this, context.appInfo, name, explicitConstant);
}
private TypeDetails executeType(String type, ExpressionNode exp, boolean atEntry)
@ -3607,7 +3607,7 @@ public class FHIRPathEngine {
}
case Custom: {
return hostServices.checkFunction(context.appInfo, exp.getName(), paramTypes);
return hostServices.checkFunction(this, context.appInfo, exp.getName(), focus, paramTypes);
}
default:
break;
@ -3932,7 +3932,7 @@ public class FHIRPathEngine {
for (ExpressionNode p : exp.getParameters()) {
params.add(execute(context, focus, p, true));
}
return hostServices.executeFunction(context.appInfo, focus, exp.getName(), params);
return hostServices.executeFunction(this, context.appInfo, focus, exp.getName(), params);
}
default:
throw new Error("not Implemented yet");
@ -4605,7 +4605,7 @@ public class FHIRPathEngine {
}
String url = nl.get(0).primitiveValue();
ValueSet vs = hostServices != null ? hostServices.resolveValueSet(context.appInfo, url)
ValueSet vs = hostServices != null ? hostServices.resolveValueSet(this, context.appInfo, url)
: worker.fetchResource(ValueSet.class, url);
if (vs == null) {
return new ArrayList<Base>();
@ -5210,7 +5210,7 @@ public class FHIRPathEngine {
}
} else if (hostServices != null) {
try {
res = hostServices.resolveReference(context.appInfo, s, refContext);
res = hostServices.resolveReference(this, context.appInfo, s, refContext);
} catch (Exception e) {
res = null;
}
@ -5740,7 +5740,7 @@ public class FHIRPathEngine {
result.add(new BooleanType(false).noExtensions());
} else {
String url = convertToString(execute(context, focus, expr.getParameters().get(0), true));
result.add(new BooleanType(hostServices.conformsToProfile(context.appInfo, focus.get(0), url)).noExtensions());
result.add(new BooleanType(hostServices.conformsToProfile(this, context.appInfo, focus.get(0), url)).noExtensions());
}
return result;
}

View File

@ -369,21 +369,21 @@ public class LiquidEngine implements IEvaluationContext {
}
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
if (ctxt.vars.containsKey(name))
return new ArrayList<>(Arrays.asList(ctxt.vars.get(name)));
if (externalHostServices == null)
return null;
return externalHostServices.resolveConstant(ctxt.externalContext, name, beforeContext);
return externalHostServices.resolveConstant(engine, ctxt.externalContext, name, beforeContext, explicitConstant);
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
if (externalHostServices == null)
return null;
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
return externalHostServices.resolveConstantType(ctxt.externalContext, name);
return externalHostServices.resolveConstantType(engine, ctxt.externalContext, name, explicitConstant);
}
@Override
@ -394,51 +394,51 @@ public class LiquidEngine implements IEvaluationContext {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
if (externalHostServices == null)
return null;
return externalHostServices.resolveFunction(functionName);
return externalHostServices.resolveFunction(engine, functionName);
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters)
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters)
throws PathEngineException {
if (externalHostServices == null)
return null;
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
return externalHostServices.checkFunction(ctxt.externalContext, functionName, parameters);
return externalHostServices.checkFunction(engine, ctxt.externalContext, functionName, focus, parameters);
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName,
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName,
List<List<Base>> parameters) {
if (externalHostServices == null)
return null;
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
return externalHostServices.executeFunction(ctxt.externalContext, focus, functionName, parameters);
return externalHostServices.executeFunction(engine, ctxt.externalContext, focus, functionName, parameters);
}
@Override
public Base resolveReference(Object appContext, String url, Base base) throws FHIRException {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base base) throws FHIRException {
if (externalHostServices == null)
return null;
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
return resolveReference(ctxt.externalContext, url, base);
return resolveReference(engine, ctxt.externalContext, url, base);
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
if (externalHostServices == null)
return false;
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
return conformsToProfile(ctxt.externalContext, item, url);
return conformsToProfile(engine, ctxt.externalContext, item, url);
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
if (externalHostServices != null)
return externalHostServices.resolveValueSet(ctxt.externalContext, url);
return externalHostServices.resolveValueSet(engine, ctxt.externalContext, url);
else
return engine.getWorker().fetchResource(ValueSet.class, url);
}

View File

@ -177,7 +177,7 @@ public class StructureMapUtilities {
private class FHIRPathHostServices implements IEvaluationContext {
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext)
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant)
throws PathEngineException {
Variables vars = (Variables) appContext;
Base res = vars.get(VariableMode.INPUT, name);
@ -190,7 +190,7 @@ public class StructureMapUtilities {
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
if (!(appContext instanceof VariablesForProfiling))
throw new Error(
"Internal Logic Error (wrong type '" + appContext.getClass().getName() + "' in resolveConstantType)");
@ -207,31 +207,31 @@ public class StructureMapUtilities {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
return null; // throw new Error("Not Implemented Yet");
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters)
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters)
throws PathEngineException {
throw new Error("Not Implemented Yet");
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName,
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName,
List<List<Base>> parameters) {
throw new Error("Not Implemented Yet");
}
@Override
public Base resolveReference(Object appContext, String url, Base base) throws FHIRException {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base base) throws FHIRException {
if (services == null)
return null;
return services.resolveReference(appContext, url);
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
IResourceValidator val = worker.newValidator();
List<ValidationMessage> valerrors = new ArrayList<ValidationMessage>();
if (item instanceof Resource) {
@ -245,7 +245,7 @@ public class StructureMapUtilities {
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
throw new Error("Not Implemented Yet");
}

View File

@ -58,14 +58,14 @@ public class FHIRPathTests {
public class FHIRPathTestEvaluationServices implements IEvaluationContext {
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext)
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant)
throws PathEngineException {
throw new NotImplementedException(
"Not done yet (FHIRPathTestEvaluationServices.resolveConstant), when item is element");
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
throw new NotImplementedException(
"Not done yet (FHIRPathTestEvaluationServices.resolveConstantType), when item is element");
}
@ -76,34 +76,34 @@ public class FHIRPathTests {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
throw new NotImplementedException(
"Not done yet (FHIRPathTestEvaluationServices.resolveFunction), when item is element (for " + functionName
+ ")");
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters)
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters)
throws PathEngineException {
throw new NotImplementedException(
"Not done yet (FHIRPathTestEvaluationServices.checkFunction), when item is element");
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName,
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName,
List<List<Base>> parameters) {
throw new NotImplementedException(
"Not done yet (FHIRPathTestEvaluationServices.executeFunction), when item is element");
}
@Override
public Base resolveReference(Object appContext, String url, Base base) throws FHIRException {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base base) throws FHIRException {
throw new NotImplementedException(
"Not done yet (FHIRPathTestEvaluationServices.resolveReference), when item is element");
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
if (url.equals("http://hl7.org/fhir/StructureDefinition/Patient"))
return true;
if (url.equals("http://hl7.org/fhir/StructureDefinition/Person"))
@ -113,7 +113,7 @@ public class FHIRPathTests {
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
return TestingUtilities.context().fetchResource(ValueSet.class, url);
}
@ -323,7 +323,7 @@ public class FHIRPathTests {
final String DUMMY_CONSTANT_2 = "dummyConstant2";
fp.setHostServices(new FHIRPathTestEvaluationServices() {
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext)
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant)
throws PathEngineException {
return Arrays.asList(new StringType(DUMMY_CONSTANT_1).noExtensions(),

View File

@ -300,13 +300,13 @@ public class SnapShotGenerationTests {
// FHIRPath methods
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext)
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant)
throws PathEngineException {
throw new Error("Not implemented yet");
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
throw new Error("Not implemented yet");
}
@ -317,14 +317,14 @@ public class SnapShotGenerationTests {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
if ("fixture".equals(functionName))
return new FunctionDetails("Access a fixture defined in the testing context", 0, 1);
return null;
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters)
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters)
throws PathEngineException {
if ("fixture".equals(functionName))
return new TypeDetails(CollectionStatus.SINGLETON, TestingUtilities.context().getResourceNamesAsSet());
@ -332,7 +332,7 @@ public class SnapShotGenerationTests {
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName,
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName,
List<List<Base>> parameters) {
if ("fixture".equals(functionName)) {
String id = fp.convertToString(parameters.get(0));
@ -348,13 +348,13 @@ public class SnapShotGenerationTests {
}
@Override
public Base resolveReference(Object appContext, String url, Base base) {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base base) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
IResourceValidator val = TestingUtilities.context().newValidator();
List<ValidationMessage> valerrors = new ArrayList<ValidationMessage>();
if (item instanceof Resource) {
@ -381,7 +381,7 @@ public class SnapShotGenerationTests {
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
throw new Error("Not implemented yet");
}

View File

@ -14,6 +14,7 @@ import java.util.Set;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.PathEngineException;
import org.hl7.fhir.r4b.utils.FHIRPathEngine;
import org.hl7.fhir.r4b.comparison.CodeSystemComparer.CodeSystemComparison;
import org.hl7.fhir.r4b.comparison.ProfileComparer.ProfileComparison;
import org.hl7.fhir.r4b.comparison.ResourceComparer.PlaceHolderComparison;
@ -231,7 +232,7 @@ public class ComparisonRenderer implements IEvaluationContext {
}
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
@SuppressWarnings("unchecked")
Map<String, Base> vars = (Map<String, Base>) appContext;
List<Base> res = new ArrayList<>();
@ -242,7 +243,7 @@ public class ComparisonRenderer implements IEvaluationContext {
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
@SuppressWarnings("unchecked")
Map<String, Base> vars = (Map<String, Base>) appContext;
Base b = vars.get(name);
@ -255,34 +256,34 @@ public class ComparisonRenderer implements IEvaluationContext {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
return null;
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters)
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters)
throws PathEngineException {
return null;
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName,
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName,
List<List<Base>> parameters) {
return null;
}
@Override
public Base resolveReference(Object appContext, String url, Base refContext) throws FHIRException {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) throws FHIRException {
return null;
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
return false;
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
return null;
}

View File

@ -5,10 +5,7 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@ -499,4 +496,8 @@ public class TestingUtilities extends BaseTestingUtilities {
return path;
}
}
public static boolean runningAsSurefire() {
return "true".equals(System.getProperty("runningAsSurefire") != null ? System.getProperty("runningAsSurefire").toLowerCase(Locale.ENGLISH) : "");
}
}

View File

@ -152,9 +152,9 @@ public class FHIRPathEngine {
* @return the value of the reference (or null, if it's not valid, though can
* throw an exception if desired)
*/
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException;
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException;
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException;
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException;
/**
* when the .log() function is called
@ -171,7 +171,7 @@ public class FHIRPathEngine {
* @param functionName
* @return null if the function is not known
*/
public FunctionDetails resolveFunction(String functionName);
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName);
/**
* Check the function parameters, and throw an error if they are incorrect, or
@ -181,7 +181,7 @@ public class FHIRPathEngine {
* @param parameters
* @return
*/
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters)
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters)
throws PathEngineException;
/**
@ -190,7 +190,7 @@ public class FHIRPathEngine {
* @param parameters
* @return
*/
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName,
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName,
List<List<Base>> parameters);
/**
@ -202,14 +202,14 @@ public class FHIRPathEngine {
* @return
* @throws FHIRException
*/
public Base resolveReference(Object appContext, String url, Base refContext) throws FHIRException;
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) throws FHIRException;
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException;
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException;
/*
* return the value set referenced by the url, which has been used in memberOf()
*/
public ValueSet resolveValueSet(Object appContext, String url);
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url);
}
/**
@ -1034,7 +1034,7 @@ public class FHIRPathEngine {
FunctionDetails details = null;
if (f == null) {
if (hostServices != null) {
details = hostServices.resolveFunction(result.getName());
details = hostServices.resolveFunction(this, result.getName());
}
if (details == null) {
throw lexer.error("The name " + result.getName() + " is not a valid function name");
@ -1474,7 +1474,7 @@ public class FHIRPathEngine {
work.addAll(work2);
break;
case Constant:
work.addAll(resolveConstant(context, exp.getConstant(), false, exp));
work.addAll(resolveConstant(context, exp.getConstant(), false, exp, true));
break;
case Group:
work2 = execute(context, focus, exp.getGroup(), atEntry);
@ -1564,7 +1564,7 @@ public class FHIRPathEngine {
} else if (atEntry && exp.getName().equals("$index")) {
result.addType(TypeDetails.FP_Integer);
} else if (atEntry && focus == null) {
result.update(executeContextType(context, exp.getName(), exp));
result.update(executeContextType(context, exp.getName(), exp, false));
} else {
for (String s : focus.getTypes()) {
result.update(executeType(s, exp, atEntry));
@ -1583,7 +1583,7 @@ public class FHIRPathEngine {
result.addType(TypeDetails.FP_Quantity);
break;
case Constant:
result.update(resolveConstantType(context, exp.getConstant(), exp));
result.update(resolveConstantType(context, exp.getConstant(), exp, true));
break;
case Group:
result.update(executeType(context, focus, exp.getGroup(), atEntry));
@ -1614,7 +1614,7 @@ public class FHIRPathEngine {
}
private List<Base> resolveConstant(ExecutionContext context, Base constant, boolean beforeContext,
ExpressionNode expr) throws PathEngineException {
ExpressionNode expr, boolean explicitConstant) throws PathEngineException {
if (constant == null) {
return new ArrayList<Base>();
}
@ -1623,7 +1623,7 @@ public class FHIRPathEngine {
}
FHIRConstant c = (FHIRConstant) constant;
if (c.getValue().startsWith("%")) {
return resolveConstant(context, c.getValue(), beforeContext, expr);
return resolveConstant(context, c.getValue(), beforeContext, expr, explicitConstant);
} else if (c.getValue().startsWith("@")) {
return new ArrayList<Base>(Arrays.asList(processDateConstant(context.appInfo, c.getValue().substring(1), expr)));
} else {
@ -1693,7 +1693,7 @@ public class FHIRPathEngine {
}
}
private List<Base> resolveConstant(ExecutionContext context, String s, boolean beforeContext, ExpressionNode expr)
private List<Base> resolveConstant(ExecutionContext context, String s, boolean beforeContext, ExpressionNode expr, boolean explicitConstant)
throws PathEngineException {
if (s.equals("%sct")) {
return new ArrayList<Base>(Arrays.asList(new StringType("http://snomed.info/sct").noExtensions()));
@ -1727,7 +1727,7 @@ public class FHIRPathEngine {
} else if (hostServices == null) {
throw makeException(expr, I18nConstants.FHIRPATH_UNKNOWN_CONSTANT, s);
} else {
return hostServices.resolveConstant(context.appInfo, s.substring(1), beforeContext);
return hostServices.resolveConstant(this, context.appInfo, s.substring(1), beforeContext, explicitConstant);
}
}
@ -2550,7 +2550,7 @@ public class FHIRPathEngine {
throws FHIRException {
boolean ans = false;
String url = right.get(0).primitiveValue();
ValueSet vs = hostServices != null ? hostServices.resolveValueSet(context.appInfo, url)
ValueSet vs = hostServices != null ? hostServices.resolveValueSet(this, context.appInfo, url)
: worker.fetchResource(ValueSet.class, url);
if (vs != null) {
for (Base l : left) {
@ -3081,7 +3081,7 @@ public class FHIRPathEngine {
return result;
}
private TypeDetails resolveConstantType(ExecutionTypeContext context, Base constant, ExpressionNode expr)
private TypeDetails resolveConstantType(ExecutionTypeContext context, Base constant, ExpressionNode expr, boolean explicitConstant)
throws PathEngineException {
if (constant instanceof BooleanType) {
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
@ -3092,7 +3092,7 @@ public class FHIRPathEngine {
} else if (constant instanceof Quantity) {
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Quantity);
} else if (constant instanceof FHIRConstant) {
return resolveConstantType(context, ((FHIRConstant) constant).getValue(), expr);
return resolveConstantType(context, ((FHIRConstant) constant).getValue(), expr, explicitConstant);
} else if (constant == null) {
return new TypeDetails(CollectionStatus.SINGLETON);
} else {
@ -3100,7 +3100,7 @@ public class FHIRPathEngine {
}
}
private TypeDetails resolveConstantType(ExecutionTypeContext context, String s, ExpressionNode expr)
private TypeDetails resolveConstantType(ExecutionTypeContext context, String s, ExpressionNode expr, boolean explicitConstant)
throws PathEngineException {
if (s.startsWith("@")) {
if (s.startsWith("@T")) {
@ -3139,7 +3139,7 @@ public class FHIRPathEngine {
} else if (hostServices == null) {
throw makeException(expr, I18nConstants.FHIRPATH_UNKNOWN_CONSTANT, s);
} else {
return hostServices.resolveConstantType(context.appInfo, s);
return hostServices.resolveConstantType(this, context.appInfo, s, explicitConstant);
}
}
@ -3148,7 +3148,7 @@ public class FHIRPathEngine {
List<Base> result = new ArrayList<Base>();
if (atEntry && context.appInfo != null && hostServices != null) {
// we'll see if the name matches a constant known by the context.
List<Base> temp = hostServices.resolveConstant(context.appInfo, exp.getName(), true);
List<Base> temp = hostServices.resolveConstant(this, context.appInfo, exp.getName(), true, false);
if (!temp.isEmpty()) {
result.addAll(temp);
return result;
@ -3179,7 +3179,7 @@ public class FHIRPathEngine {
// constant known by the context.
// (if the name does match, and the user wants to get the constant value,
// they'll have to try harder...
result.addAll(hostServices.resolveConstant(context.appInfo, exp.getName(), false));
result.addAll(hostServices.resolveConstant(this, context.appInfo, exp.getName(), false, false));
}
return result;
}
@ -3188,12 +3188,12 @@ public class FHIRPathEngine {
return null;
}
private TypeDetails executeContextType(ExecutionTypeContext context, String name, ExpressionNode expr)
private TypeDetails executeContextType(ExecutionTypeContext context, String name, ExpressionNode expr, boolean explicitConstant)
throws PathEngineException, DefinitionException {
if (hostServices == null) {
throw makeException(expr, I18nConstants.FHIRPATH_HO_HOST_SERVICES, "Context Reference");
}
return hostServices.resolveConstantType(context.appInfo, name);
return hostServices.resolveConstantType(this, context.appInfo, name, explicitConstant);
}
private TypeDetails executeType(String type, ExpressionNode exp, boolean atEntry)
@ -3609,7 +3609,7 @@ public class FHIRPathEngine {
}
case Custom: {
return hostServices.checkFunction(context.appInfo, exp.getName(), paramTypes);
return hostServices.checkFunction(this, context.appInfo, exp.getName(), focus, paramTypes);
}
default:
break;
@ -3934,7 +3934,7 @@ public class FHIRPathEngine {
for (ExpressionNode p : exp.getParameters()) {
params.add(execute(context, focus, p, true));
}
return hostServices.executeFunction(context.appInfo, focus, exp.getName(), params);
return hostServices.executeFunction(this, context.appInfo, focus, exp.getName(), params);
}
default:
throw new Error("not Implemented yet");
@ -4607,7 +4607,7 @@ public class FHIRPathEngine {
}
String url = nl.get(0).primitiveValue();
ValueSet vs = hostServices != null ? hostServices.resolveValueSet(context.appInfo, url)
ValueSet vs = hostServices != null ? hostServices.resolveValueSet(this, context.appInfo, url)
: worker.fetchResource(ValueSet.class, url);
if (vs == null) {
return new ArrayList<Base>();
@ -5213,7 +5213,7 @@ public class FHIRPathEngine {
}
} else if (hostServices != null) {
try {
res = hostServices.resolveReference(context.appInfo, s, refContext);
res = hostServices.resolveReference(this, context.appInfo, s, refContext);
} catch (Exception e) {
res = null;
}
@ -5743,7 +5743,7 @@ public class FHIRPathEngine {
result.add(new BooleanType(false).noExtensions());
} else {
String url = convertToString(execute(context, focus, expr.getParameters().get(0), true));
result.add(new BooleanType(hostServices.conformsToProfile(context.appInfo, focus.get(0), url)).noExtensions());
result.add(new BooleanType(hostServices.conformsToProfile(this, context.appInfo, focus.get(0), url)).noExtensions());
}
return result;
}

View File

@ -738,7 +738,7 @@ public class LiquidEngine implements IEvaluationContext {
}
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
if (ctxt.loopVars.containsKey(name))
return new ArrayList<Base>(Arrays.asList(ctxt.loopVars.get(name)));
@ -746,15 +746,15 @@ public class LiquidEngine implements IEvaluationContext {
return new ArrayList<Base>(Arrays.asList(ctxt.globalVars.get(name)));
if (externalHostServices == null)
return new ArrayList<Base>();
return externalHostServices.resolveConstant(ctxt.externalContext, name, beforeContext);
return externalHostServices.resolveConstant(engine, ctxt.externalContext, name, beforeContext, explicitConstant);
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
if (externalHostServices == null)
return null;
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
return externalHostServices.resolveConstantType(ctxt.externalContext, name);
return externalHostServices.resolveConstantType(engine, ctxt.externalContext, name, explicitConstant);
}
@Override
@ -765,49 +765,49 @@ public class LiquidEngine implements IEvaluationContext {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
if (externalHostServices == null)
return null;
return externalHostServices.resolveFunction(functionName);
return externalHostServices.resolveFunction(engine, functionName);
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) throws PathEngineException {
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters) throws PathEngineException {
if (externalHostServices == null)
return null;
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
return externalHostServices.checkFunction(ctxt.externalContext, functionName, parameters);
return externalHostServices.checkFunction(engine, ctxt.externalContext, functionName, focus, parameters);
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
if (externalHostServices == null)
return null;
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
return externalHostServices.executeFunction(ctxt.externalContext, focus, functionName, parameters);
return externalHostServices.executeFunction(engine, ctxt.externalContext, focus, functionName, parameters);
}
@Override
public Base resolveReference(Object appContext, String url, Base refContext) throws FHIRException {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) throws FHIRException {
if (externalHostServices == null)
return null;
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
return resolveReference(ctxt.externalContext, url, refContext);
return resolveReference(engine, ctxt.externalContext, url, refContext);
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
if (externalHostServices == null)
return false;
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
return conformsToProfile(ctxt.externalContext, item, url);
return conformsToProfile(engine, ctxt.externalContext, item, url);
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
if (externalHostServices != null)
return externalHostServices.resolveValueSet(ctxt.externalContext, url);
return externalHostServices.resolveValueSet(engine, ctxt.externalContext, url);
else
return engine.getWorker().fetchResource(ValueSet.class, url);
}

View File

@ -24,7 +24,7 @@ public class FHIRPathHostServices implements FHIRPathEngine.IEvaluationContext {
this.structureMapUtilities = structureMapUtilities;
}
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
Variables vars = (Variables) appContext;
Base res = vars.get(VariableMode.INPUT, name);
if (res == null)
@ -36,7 +36,7 @@ public class FHIRPathHostServices implements FHIRPathEngine.IEvaluationContext {
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
if (!(appContext instanceof VariablesForProfiling))
throw new Error(
"Internal Logic Error (wrong type '" + appContext.getClass().getName() + "' in resolveConstantType)");
@ -53,24 +53,24 @@ public class FHIRPathHostServices implements FHIRPathEngine.IEvaluationContext {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
return null; // throw new Error("Not Implemented Yet");
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters)
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters)
throws PathEngineException {
throw new Error("Not Implemented Yet");
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName,
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName,
List<List<Base>> parameters) {
throw new Error("Not Implemented Yet");
}
@Override
public Base resolveReference(Object appContext, String url, Base refContext) throws FHIRException {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) throws FHIRException {
if (structureMapUtilities.getServices() == null)
return null;
return structureMapUtilities.getServices().resolveReference(appContext, url);
@ -84,7 +84,7 @@ public class FHIRPathHostServices implements FHIRPathEngine.IEvaluationContext {
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
IResourceValidator val = structureMapUtilities.getWorker().newValidator();
List<ValidationMessage> valerrors = new ArrayList<ValidationMessage>();
if (item instanceof Resource) {
@ -100,7 +100,7 @@ public class FHIRPathHostServices implements FHIRPathEngine.IEvaluationContext {
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
throw new Error("Not Implemented Yet");
}

View File

@ -111,7 +111,7 @@ public class StructureMapUtilities {
private class FHIRPathHostServices implements IEvaluationContext {
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext)
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant)
throws PathEngineException {
Variables vars = (Variables) appContext;
List<Base> list = new ArrayList<Base>();
@ -126,7 +126,7 @@ public class StructureMapUtilities {
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
if (!(appContext instanceof VariablesForProfiling))
throw new Error(
"Internal Logic Error (wrong type '" + appContext.getClass().getName() + "' in resolveConstantType)");
@ -143,31 +143,31 @@ public class StructureMapUtilities {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
return null; // throw new Error("Not Implemented Yet");
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters)
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters)
throws PathEngineException {
throw new Error("Not Implemented Yet");
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName,
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName,
List<List<Base>> parameters) {
throw new Error("Not Implemented Yet");
}
@Override
public Base resolveReference(Object appContext, String url, Base base) throws FHIRException {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base base) throws FHIRException {
if (services == null)
return null;
return services.resolveReference(appContext, url);
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
IResourceValidator val = worker.newValidator();
List<ValidationMessage> valerrors = new ArrayList<ValidationMessage>();
if (item instanceof Resource) {
@ -181,7 +181,7 @@ public class StructureMapUtilities {
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
throw new Error("Not Implemented Yet");
}

View File

@ -44,14 +44,14 @@ public class FHIRPathTests {
public class FHIRPathTestEvaluationServices implements IEvaluationContext {
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext)
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant)
throws PathEngineException {
throw new NotImplementedException(
"Not done yet (FHIRPathTestEvaluationServices.resolveConstant), when item is element");
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
throw new NotImplementedException(
"Not done yet (FHIRPathTestEvaluationServices.resolveConstantType), when item is element");
}
@ -62,34 +62,34 @@ public class FHIRPathTests {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
throw new NotImplementedException(
"Not done yet (FHIRPathTestEvaluationServices.resolveFunction), when item is element (for " + functionName
+ ")");
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters)
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters)
throws PathEngineException {
throw new NotImplementedException(
"Not done yet (FHIRPathTestEvaluationServices.checkFunction), when item is element");
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName,
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName,
List<List<Base>> parameters) {
throw new NotImplementedException(
"Not done yet (FHIRPathTestEvaluationServices.executeFunction), when item is element");
}
@Override
public Base resolveReference(Object appContext, String url, Base refContext) throws FHIRException {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) throws FHIRException {
throw new NotImplementedException(
"Not done yet (FHIRPathTestEvaluationServices.resolveReference), when item is element");
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
if (url.equals("http://hl7.org/fhir/StructureDefinition/Patient"))
return true;
if (url.equals("http://hl7.org/fhir/StructureDefinition/Person"))
@ -99,7 +99,7 @@ public class FHIRPathTests {
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
return TestingUtilities.context().fetchResource(ValueSet.class, url);
}
@ -310,7 +310,7 @@ public class FHIRPathTests {
final String DUMMY_CONSTANT_2 = "dummyConstant2";
fp.setHostServices(new FHIRPathTestEvaluationServices() {
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext)
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant)
throws PathEngineException {
return Arrays.asList(new StringType(DUMMY_CONSTANT_1).noExtensions(),

View File

@ -368,13 +368,13 @@ public class SnapShotGenerationTests {
// FHIRPath methods
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext)
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant)
throws PathEngineException {
throw new Error("Not implemented yet");
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
throw new Error("Not implemented yet");
}
@ -385,14 +385,14 @@ public class SnapShotGenerationTests {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
if ("fixture".equals(functionName))
return new FunctionDetails("Access a fixture defined in the testing context", 0, 1);
return null;
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters)
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters)
throws PathEngineException {
if ("fixture".equals(functionName))
return new TypeDetails(CollectionStatus.SINGLETON, TestingUtilities.context().getResourceNamesAsSet());
@ -400,7 +400,7 @@ public class SnapShotGenerationTests {
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName,
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName,
List<List<Base>> parameters) {
if ("fixture".equals(functionName)) {
String id = fp.convertToString(parameters.get(0));
@ -416,13 +416,13 @@ public class SnapShotGenerationTests {
}
@Override
public Base resolveReference(Object appContext, String url, Base refContext) {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
IResourceValidator val = TestingUtilities.context().newValidator();
List<ValidationMessage> valerrors = new ArrayList<ValidationMessage>();
if (item instanceof Resource) {
@ -451,7 +451,7 @@ public class SnapShotGenerationTests {
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
throw new Error("Not implemented yet");
}

View File

@ -14,6 +14,7 @@ import java.util.Set;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.PathEngineException;
import org.hl7.fhir.r5.utils.FHIRPathEngine;
import org.hl7.fhir.r5.comparison.CapabilityStatementComparer.CapabilityStatementComparison;
import org.hl7.fhir.r5.comparison.CodeSystemComparer.CodeSystemComparison;
import org.hl7.fhir.r5.comparison.ResourceComparer.PlaceHolderComparison;
@ -255,7 +256,7 @@ public class ComparisonRenderer implements IEvaluationContext {
}
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
@SuppressWarnings("unchecked")
Map<String, Base> vars = (Map<String, Base>) appContext;
List<Base> res = new ArrayList<>();
@ -266,7 +267,7 @@ public class ComparisonRenderer implements IEvaluationContext {
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
@SuppressWarnings("unchecked")
Map<String, Base> vars = (Map<String, Base>) appContext;
Base b = vars.get(name);
@ -279,32 +280,32 @@ public class ComparisonRenderer implements IEvaluationContext {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
return null;
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) throws PathEngineException {
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters) throws PathEngineException {
return null;
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
return null;
}
@Override
public Base resolveReference(Object appContext, String url, Base refContext) throws FHIRException {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) throws FHIRException {
return null;
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
return false;
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
return null;
}

View File

@ -881,7 +881,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
if (pIn == null) {
throw new Error(formatMessage(I18nConstants.NO_PARAMETERS_PROVIDED_TO_EXPANDVS));
}
if (vs.getUrl().equals("http://hl7.org/fhir/ValueSet/all-time-units") || vs.getUrl().equals("http://hl7.org/fhir/ValueSet/all-distance-units")) {
if (vs.hasUrl() && (vs.getUrl().equals("http://hl7.org/fhir/ValueSet/all-time-units") || vs.getUrl().equals("http://hl7.org/fhir/ValueSet/all-distance-units"))) {
return new ValueSetExpansionOutcome("This value set is not expanded correctly at this time (will be fixed in a future version)", TerminologyServiceErrorClass.VALUESET_UNSUPPORTED, false);
}
@ -1792,6 +1792,22 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
if (uri == null) {
return null;
}
if (uri.startsWith("#")) {
if (sourceForReference != null && sourceForReference instanceof DomainResource) {
for (Resource r : ((DomainResource) sourceForReference).getContained()) {
if (r.getClass() == class_ &&( "#"+r.getIdBase()).equals(uri)) {
if (r instanceof CanonicalResource) {
CanonicalResource cr = (CanonicalResource) r;
if (!cr.hasUrl()) {
cr.setUrl(Utilities.makeUuidUrn());
}
}
return (T) r;
}
}
}
return null;
}
if (QA_CHECK_REFERENCE_SOURCE) {
// it can be tricky to trace the source of a reference correctly. The code isn't water tight,

View File

@ -38,6 +38,7 @@ import org.apache.commons.lang3.Validate;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.elementmodel.Element.SliceDefinition;
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
import org.hl7.fhir.r5.extensions.ExtensionsUtils;
import org.hl7.fhir.r5.model.Base;
@ -73,6 +74,32 @@ import org.hl7.fhir.utilities.xhtml.XhtmlNode;
*
*/
public class Element extends Base implements NamedItem {
public class SliceDefinition {
private StructureDefinition profile;
private ElementDefinition definition;
private ElementDefinition slice;
public SliceDefinition(StructureDefinition profile, ElementDefinition definition, ElementDefinition slice) {
this.profile = profile;
this.definition = definition;
this.slice = slice;
}
public StructureDefinition getProfile() {
return profile;
}
public ElementDefinition getDefinition() {
return definition;
}
public ElementDefinition getSlice() {
return slice;
}
}
private static final HashSet<String> extensionList = new HashSet<>(Arrays.asList("extension", "modifierExtension"));
public enum SpecialElement {
@ -133,6 +160,7 @@ public class Element extends Base implements NamedItem {
private boolean ignorePropertyOrder;
private FhirFormat format;
private Object nativeObject;
private List<SliceDefinition> sliceDefinitions;
public Element(String name) {
super();
@ -1498,5 +1526,23 @@ public class Element extends Base implements NamedItem {
children.removeAll(rem);
}
public void addSliceDefinition(StructureDefinition profile, ElementDefinition definition, ElementDefinition slice) {
if (sliceDefinitions == null) {
sliceDefinitions = new ArrayList<>();
}
sliceDefinitions.add(new SliceDefinition(profile, definition, slice));
}
public boolean hasSlice(StructureDefinition sd, String sliceName) {
if (sliceDefinitions != null) {
for (SliceDefinition def : sliceDefinitions) {
if (def.profile == sd && sliceName.equals(def.definition.getSliceName())) {
return true;
}
}
}
return false;
}
}

View File

@ -531,7 +531,7 @@ public class PEBuilder {
protected void populateByProfile(Base base, PEDefinition definition) {
if (definition.types().size() == 1) {
for (PEDefinition pe : definition.directChildren(true)) {
if (pe.fixedValue()) {
if (pe.hasFixedValue()) {
if (pe.definition().hasPattern()) {
base.setProperty(pe.schemaName(), pe.definition().getPattern());
} else {

View File

@ -37,6 +37,7 @@ import org.apache.xmlbeans.impl.xb.xsdschema.All;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.DataType;
import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
import org.hl7.fhir.r5.model.StructureDefinition;
@ -236,10 +237,15 @@ public abstract class PEDefinition {
/**
* @return True if the element has a fixed value. This will always be false if fixedProps = false when the builder is created
*/
public boolean fixedValue() {
public boolean hasFixedValue() {
return definition.hasFixed() || definition.hasPattern();
}
public DataType getFixedValue() {
return definition.hasFixed() ? definition.getFixed() : definition.getPattern();
}
protected abstract void makeChildren(String typeUrl, List<PEDefinition> children, boolean allFixed);
@Override
@ -290,7 +296,7 @@ public abstract class PEDefinition {
public boolean isList() {
return "*".equals(definition.getMax());
return "*".equals(definition.getMax()) || (Utilities.parseInt(definition.getMax(), 2) > 1);
}

View File

@ -0,0 +1,7 @@
package org.hl7.fhir.r5.profilemodel.gen;
public @interface BindingStrength {
String value();
}

View File

@ -0,0 +1,7 @@
package org.hl7.fhir.r5.profilemodel.gen;
public @interface Definition {
String value();
}

View File

@ -0,0 +1,7 @@
package org.hl7.fhir.r5.profilemodel.gen;
public @interface Doco {
String value();
}

View File

@ -0,0 +1,7 @@
package org.hl7.fhir.r5.profilemodel.gen;
public @interface Label {
String value();
}

View File

@ -0,0 +1,7 @@
package org.hl7.fhir.r5.profilemodel.gen;
public @interface Max {
String value();
}

View File

@ -0,0 +1,7 @@
package org.hl7.fhir.r5.profilemodel.gen;
public @interface Min {
String value();
}

View File

@ -0,0 +1,7 @@
package org.hl7.fhir.r5.profilemodel.gen;
public @interface MustSupport {
boolean value();
}

View File

@ -33,22 +33,30 @@ import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TimeZone;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.DataType;
import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
import org.hl7.fhir.r5.model.Identifier;
import org.hl7.fhir.r5.model.Observation;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
import org.hl7.fhir.r5.profilemodel.PEBuilder;
import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy;
import org.hl7.fhir.r5.profilemodel.gen.PECodeGenerator.ExtensionPolicy;
import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome;
import org.hl7.fhir.r5.profilemodel.PEDefinition;
import org.hl7.fhir.r5.profilemodel.PEInstance;
import org.hl7.fhir.r5.profilemodel.PEType;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
@ -73,7 +81,12 @@ public class PECodeGenerator {
private String doco;
private String url;
private boolean isResource;
private Set<String> unfixed = new HashSet<>();
private Set<String> enumNames = new HashSet<>();
private StringBuilder inits = new StringBuilder();
private StringBuilder fields = new StringBuilder();
private StringBuilder enums = new StringBuilder();
private StringBuilder load = new StringBuilder();
private StringBuilder save = new StringBuilder();
private StringBuilder clear = new StringBuilder();
@ -82,10 +95,10 @@ public class PECodeGenerator {
private StringBuilder hash = new StringBuilder();
public void genId() {
if (isResource) {
genField(true, "id", "String", "id", "", false, "");
genAccessors(true, false, "id", "String", "", "String", "String", "Id", "Ids", false, "", false);
genLoad(true, false, "id", "id", "IdType", "", "String", "String", "Id", "Ids", false, false, null);
genSave(true, false, "id", "id", "IdType", "", "String", "String", "Id", "Ids", false, false, false, null);
genField(true, "id", "String", "id", "", false, "", 0, 1, null);
genAccessors(true, false, "id", "String", "", "String", "String", "Id", "Ids", false, "", false, false);
genLoad(true, false, "id", "id", "IdType", "", "String", "String", "Id", "Ids", false, false, null, false);
genSave(true, false, "id", "id", "IdType", "", "String", "String", "Id", "Ids", false, false, false, null, false);
genClear(false, "id");
}
}
@ -106,15 +119,27 @@ public class PECodeGenerator {
w(b, " private static final String CANONICAL_URL = \""+url+"\";");
w(b);
}
if (enums.length() > 0) {
w(b, enums.toString());
}
w(b, fields.toString());
jdoc(b, "Parameter-less constructor. If you use this, the fixed values won't be filled out - they'll be missing. They'll be filled in if/when you call build, so they won't be missing from the resource, only from this particular object model", 2, true);
if (unfixed.isEmpty()) {
jdoc(b, "Parameter-less constructor.", 2, true);
} else {
jdoc(b, "Parameter-less constructor. If you use this, the fixed values on "+CommaSeparatedStringBuilder.join(",", unfixed)+" won't be filled out - they'll be missing. They'll be filled in if/when you call build, so they won't be missing from the resource, only from this particular object model", 2, true);
}
w(b, " public "+name+"() {");
w(b, " // todo");
if (inits.length() > 0) {
w(b, " initFixedValues();");
}
w(b, " }");
w(b);
if (isResource) {
jdoc(b, "Construct an instance of the object, and fill out all the fixed values ", 2, true);
w(b, " public "+name+"(IWorkerContext context) {");
if (inits.length() > 0) {
w(b, " initFixedValues();");
}
w(b, " workerContext = context;");
w(b, " PEBuilder builder = new PEBuilder(context, PEElementPropertiesPolicy.EXTENSION, true);");
w(b, " PEInstance src = builder.buildPEInstance(CANONICAL_URL, builder.createResource(CANONICAL_URL, false));");
@ -171,6 +196,12 @@ public class PECodeGenerator {
w(b, save.toString());
w(b, " }");
w(b);
if (inits.length() > 0) {
w(b, " private void initFixedValues() {");
w(b, inits.toString());
w(b, " }");
w(b);
}
w(b, accessors.toString());
w(b);
w(b, " public void clear() {");
@ -180,10 +211,114 @@ public class PECodeGenerator {
w(b, "}");
}
private String generateEnum(PEDefinition source, PEDefinition field) {
if (field.definition().hasBinding() && !field.hasFixedValue()) {
ElementDefinitionBindingComponent binding = field.definition().getBinding();
if (binding.getStrength() == org.hl7.fhir.r5.model.Enumerations.BindingStrength.REQUIRED && binding.hasValueSet()) {
org.hl7.fhir.r5.model.ValueSet vs = workerContext.fetchResource(org.hl7.fhir.r5.model.ValueSet.class, binding.getValueSet(), field.getProfile());
if (vs != null) {
ValueSetExpansionOutcome vse = workerContext.expandVS(vs, false, false);
if (vse.isOk()) {
String baseName = Utilities.nmtokenize(Utilities.singularise(vs.getName()));
String name = baseName;
int c = 0;
while (enumNames.contains(name)) {
c++;
name = baseName+c;
}
w(enums, " public enum "+name+" {");
for (int i = 0; i < vse.getValueset().getExpansion().getContains().size(); i++) {
ValueSetExpansionContainsComponent cc = vse.getValueset().getExpansion().getContains().get(i);
String code = Utilities.nmtokenize(cc.getCode()).toUpperCase();
if (cc.getAbstract()) {
code = "_"+code;
}
cc.setUserData("java.code", code);
w(enums, " "+code+(i < vse.getValueset().getExpansion().getContains().size() - 1 ? "," : ";")+" // \""+cc.getDisplay()+"\" = "+cc.getSystem()+"#"+cc.getCode());
}
w(enums, "");
w(enums, " public static "+name+" fromCode(String s) {");
w(enums, " switch (s) {");
for (ValueSetExpansionContainsComponent cc : vse.getValueset().getExpansion().getContains()) {
w(enums, " case \""+cc.getCode()+"\": return "+cc.getUserString("java.code")+";");
}
w(enums, " default: return null;");
w(enums, " }");
w(enums, " }");
w(enums, "");
w(enums, " public static "+name+" fromCoding(Coding c) {");
for (ValueSetExpansionContainsComponent cc : vse.getValueset().getExpansion().getContains()) {
if (cc.hasVersion()) {
w(enums, " if (\""+cc.getSystem()+"\".equals(c.getSystem()) && \""+cc.getCode()+"\".equals(c.getCode()) && (!c.hasVersion() || \""+cc.getVersion()+"\".equals(c.getVersion()))) {");
} else {
w(enums, " if (\""+cc.getSystem()+"\".equals(c.getSystem()) && \""+cc.getCode()+"\".equals(c.getCode())) {");
}
w(enums, " return "+cc.getUserString("java.code")+";");
w(enums, " }");
}
w(enums, " return null;");
w(enums, " }");
w(enums, "");
w(enums, " public static "+name+" fromCodeableConcept(CodeableConcept cc) {");
w(enums, " for (Coding c : cc.getCoding()) {");
w(enums, " "+name+" v = fromCoding(c);");
w(enums, " if (v != null) {");
w(enums, " return v;");
w(enums, " }");
w(enums, " }");
w(enums, " return null;");
w(enums, " }");
w(enums, "");
w(enums, " public String toDisplay() {");
w(enums, " switch (this) {");
for (ValueSetExpansionContainsComponent cc : vse.getValueset().getExpansion().getContains()) {
w(enums, " case "+cc.getUserString("java.code")+": return \""+Utilities.escapeJava(cc.getDisplay())+"\";");
}
w(enums, " default: return null;");
w(enums, " }");
w(enums, " }");
w(enums, "");
w(enums, " public String toCode() {");
w(enums, " switch (this) {");
for (ValueSetExpansionContainsComponent cc : vse.getValueset().getExpansion().getContains()) {
w(enums, " case "+cc.getUserString("java.code")+": return \""+cc.getCode()+"\";");
}
w(enums, " default: return null;");
w(enums, " }");
w(enums, " }");
w(enums, "");
w(enums, " public Coding toCoding() {");
w(enums, " switch (this) {");
for (ValueSetExpansionContainsComponent cc : vse.getValueset().getExpansion().getContains()) {
if (cc.hasVersion()) {
w(enums, " case "+cc.getUserString("java.code")+": return new Coding().setSystem(\""+cc.getSystem()+"\").setVersion(\""+cc.getVersion()+"\").setCode()\""+cc.getCode()+"\";");
} else {
w(enums, " case "+cc.getUserString("java.code")+": return new Coding().setSystem(\""+cc.getSystem()+"\").setCode(\""+cc.getCode()+"\");");
}
}
w(enums, " default: return null;");
w(enums, " }");
w(enums, " }");
w(enums, "");
w(enums, " public CodeableConcept toCodeableConcept() {");
w(enums, " Coding c = toCoding();");
w(enums, " return c == null ? null : new CodeableConcept().addCoding(c);");
w(enums, " }");
w(enums, " }");
return name;
}
}
}
}
return null;
}
private void defineField(PEDefinition source, PEDefinition field) {
if (field.types().size() == 1) {
StructureDefinition sd = workerContext.fetchTypeDefinition(field.types().get(0).getUrl());
if (sd != null) {
String enumName = generateEnum(source, field);
boolean isPrim = sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE;
boolean isAbstract = sd.getAbstract();
String name = field.name().replace("[x]", "");
@ -191,7 +326,12 @@ public class PECodeGenerator {
String type = null;
String init = "";
String ptype = type;
if (isPrim) {
boolean isEnum = false;
if (enumName != null) {
type = enumName;
ptype = enumName;
isEnum = true;
} else if (isPrim) {
// todo: are we extension-less?
type = Utilities.capitalize(field.types().get(0).getName()+"Type");
ptype = getPrimitiveType(sd);
@ -210,18 +350,20 @@ public class PECodeGenerator {
String csname = Utilities.capitalize(sname);
String nn = field.min() == 1 ? "// @NotNull" : "";
boolean isExtension = field.isExtension();
genField(isPrim, name, ptype, ltype, nn, field.isList(), field.shortDocumentation());
genAccessors(isPrim, isAbstract, name, type, init, ptype, ltype, cname, csname, field.isList(), field.documentation(), field.fixedValue());
genLoad(isPrim, isAbstract, name, sname, type, init, ptype, ltype, cname, csname, field.isList(), field.fixedValue(), field.types().get(0));
genSave(isPrim, isAbstract, name, sname, type, init, ptype, ltype, cname, csname, field.isList(), field.fixedValue(), isExtension, field.types().get(0));
genField(isPrim, name, ptype, ltype, nn, field.isList(), field.shortDocumentation(), field.min(), field.max(), field.definition());
if (isPrim && field.hasFixedValue()) {
genFixed(name, ptype, field.getFixedValue());
}
genAccessors(isPrim, isAbstract, name, type, init, ptype, ltype, cname, csname, field.isList(), field.documentation(), field.hasFixedValue(), isEnum);
genLoad(isPrim, isAbstract, name, sname, type, init, ptype, ltype, cname, csname, field.isList(), field.hasFixedValue(), field.types().get(0), isEnum);
genSave(isPrim, isAbstract, name, sname, type, init, ptype, ltype, cname, csname, field.isList(), field.hasFixedValue(), isExtension, field.types().get(0), isEnum);
genClear(field.isList(), name);
}
} else {
// ignoring polymorphics for now
}
}
private void genClear(boolean list, String name) {
if (list) {
w(clear, " "+name+".clear();");
@ -230,11 +372,21 @@ public class PECodeGenerator {
}
}
private void genLoad(boolean isPrim, boolean isAbstract, String name, String sname, String type, String init, String ptype, String ltype, String cname, String csname, boolean isList, boolean isFixed, PEType typeInfo) {
private void genLoad(boolean isPrim, boolean isAbstract, String name, String sname, String type, String init, String ptype, String ltype, String cname, String csname, boolean isList, boolean isFixed, PEType typeInfo, boolean isEnum) {
if (isList) {
w(load, " for (PEInstance item : src.children(\""+sname+"\")) {");
w(load, " "+name+".add(("+type+") item.asDataType());");
w(load, " }");
} else if (isEnum) {
w(load, " if (src.hasChild(\""+name+"\")) {");
if ("CodeableConcept".equals(typeInfo.getName())) {
w(load, " "+name+" = "+type+".fromCodeableConcept((CodeableConcept) src.child(\""+name+"\").asDataType());");
} else if ("Coding".equals(typeInfo.getName())) {
w(load, " "+name+" = "+type+".fromCoding((Coding) src.child(\""+name+"\").asDataType());");
} else {
w(load, " "+name+" = "+type+".fromCode(src.child(\""+name+"\").asDataType()).primitiveValue());");
}
w(load, " }");
} else if (isPrim) {
w(load, " if (src.hasChild(\""+name+"\")) {");
if ("CodeType".equals(type)) {
@ -255,7 +407,7 @@ public class PECodeGenerator {
}
}
private void genSave(boolean isPrim, boolean isAbstract, String name, String sname, String type, String init, String ptype, String ltype, String cname, String csname, boolean isList, boolean isFixed, boolean isExtension, PEType typeInfo) {
private void genSave(boolean isPrim, boolean isAbstract, String name, String sname, String type, String init, String ptype, String ltype, String cname, String csname, boolean isList, boolean isFixed, boolean isExtension, PEType typeInfo, boolean isEnum) {
w(save, " tgt.clear(\""+sname+"\");");
if (isList) {
w(save, " for ("+type+" item : "+name+") {");
@ -265,6 +417,16 @@ public class PECodeGenerator {
w(save, " tgt.addChild(\""+sname+"\", item);");
}
w(save, " }");
} else if (isEnum) {
w(save, " if ("+name+" != null) {");
if ("CodeableConcept".equals(typeInfo.getName())) {
w(save, " tgt.addChild(\""+sname+"\", "+name+".toCodeableConcept());");
} else if ("Coding".equals(typeInfo.getName())) {
w(save, " tgt.addChild(\""+sname+"\", "+name+".toCoding());");
} else {
w(save, " tgt.addChild(\""+sname+"\", "+name+").toCode();");
}
w(save, " }");
} else if (isPrim) {
w(save, " if ("+name+" != null) {");
if (isExtension) {
@ -290,21 +452,27 @@ public class PECodeGenerator {
}
}
private void genAccessors(boolean isPrim, boolean isAbstract, String name, String type, String init, String ptype, String ltype, String cname, String csname, boolean isList, String shortDoco, boolean isFixed) {
private void genAccessors(boolean isPrim, boolean isAbstract, String name, String type, String init, String ptype, String ltype, String cname, String csname, boolean isList, String shortDoco, boolean isFixed, boolean isEnum) {
jdoc(accessors, doco, 2, true);
if (isPrim && extensionPolicy != ExtensionPolicy.Primitives && !isList) {
if ((isEnum || isPrim) && extensionPolicy != ExtensionPolicy.Primitives && !isList) {
w(accessors, " public "+ptype+" get"+cname+"() {");
w(accessors, " return "+name+";");
w(accessors, " }");
w(accessors);
w(accessors, " public "+this.name+" set"+cname+"("+ptype+" value) {");
w(accessors, " this."+name+" = value;");
w(accessors, " return this;");
w(accessors, " }");
w(accessors);
w(accessors, " public boolean has"+cname+"() {");
w(accessors, " return "+name+" != null;");
w(accessors, " }");
if (isFixed) {
w(accessors, " public boolean has"+cname+"() {");
w(accessors, " return true;");
w(accessors, " }");
} else {
w(accessors, " public "+this.name+" set"+cname+"("+ptype+" value) {");
w(accessors, " this."+name+" = value;");
w(accessors, " return this;");
w(accessors, " }");
w(accessors);
w(accessors, " public boolean has"+cname+"() {");
w(accessors, " return "+name+" != null;");
w(accessors, " }");
}
} else {
if (isPrim && !isList) {
w(accessors, " public "+ptype+" get"+cname+"() {");
@ -379,8 +547,27 @@ public class PECodeGenerator {
w(accessors);
}
private void genField(boolean isPrim, String name, String ptype, String ltype, String nn, boolean isList, String shortDoco) {
// jdoc(fields, field.documentation(), 2, true);
private void genField(boolean isPrim, String name, String ptype, String ltype, String nn, boolean isList, String shortDoco, int min, int max, ElementDefinition ed) {
// jdoc(fields, shortDoco, 2, true);
w(fields, " @Min(\""+min+"\") @Max(\""+(max == Integer.MAX_VALUE ? "*" : max) +"\")"+(" @Doco(\""+Utilities.escapeJava(shortDoco)+"\")"));
if (ed != null) {
if (ed.hasBinding() && ed.getBinding().hasValueSet()) {
w(fields, " @BindingStrength(\""+ed.getBinding().getStrength().toCode()+"\") @ValueSet(\""+ed.getBinding().getValueSet()+"\")");
}
if (ed.getMustSupport()) {
w(fields, " @MustSupport(true)");
}
if (ed.hasLabel() || ed.hasDefinition()) {
String s = "";
if (ed.hasLabel()) {
s = s + " @Label(\""+Utilities.escapeJava(ed.getLabel())+"\")";
}
if (ed.hasDefinition()) {
s = s + " @Definition(\""+Utilities.escapeJava(ed.getDefinition())+"\")";
}
w(fields, " "+s);
}
}
if (isPrim && extensionPolicy != ExtensionPolicy.Primitives && !isList) {
w(fields, " private "+ptype+" "+name+";"+nn+" // "+shortDoco);
} else if (isList) {
@ -388,6 +575,17 @@ public class PECodeGenerator {
} else {
w(fields, " private "+ltype+" "+name+";"+nn+" // "+shortDoco);
}
w(fields, "");
}
private void genFixed(String name, String pType, DataType fixedValue) {
if ("String".equals(pType)) {
w(inits, " "+name+" = \""+Utilities.escapeJava(fixedValue.primitiveValue())+"\";");
} else {
unfixed.add(name);
System.out.println("Unable to handle the fixed value for "+name+" of type "+pType+" = "+fixedValue.toString());
}
}
}
@ -501,6 +699,8 @@ public class PECodeGenerator {
*
*/
public void execute() throws IOException {
imports = new StringBuilder();
PEDefinition source = new PEBuilder(workerContext, PEElementPropertiesPolicy.EXTENSION, true).buildPEDefinition(canonical);
w(imports, "import java.util.List;");
w(imports, "import java.util.ArrayList;");
@ -513,6 +713,16 @@ public class PECodeGenerator {
w(imports, "import org.hl7.fhir.r5.profilemodel.PEInstance;");
w(imports, "import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy;");
w(imports, "import org.hl7.fhir.r5.profilemodel.gen.PEGeneratedBase;");
w(imports, "import org.hl7.fhir.r5.profilemodel.gen.Min;");
w(imports, "import org.hl7.fhir.r5.profilemodel.gen.Max;");
w(imports, "import org.hl7.fhir.r5.profilemodel.gen.Label;");
w(imports, "import org.hl7.fhir.r5.profilemodel.gen.Doco;");
w(imports, "import org.hl7.fhir.r5.profilemodel.gen.BindingStrength;");
w(imports, "import org.hl7.fhir.r5.profilemodel.gen.ValueSet;");
w(imports, "import org.hl7.fhir.r5.profilemodel.gen.MustSupport;");
w(imports, "import org.hl7.fhir.r5.profilemodel.gen.Definition;");
PEGenClass cls = genClass(source);
StringBuilder b = new StringBuilder();
w(b, "package "+pkgName+";");

View File

@ -0,0 +1,7 @@
package org.hl7.fhir.r5.profilemodel.gen;
public @interface ValueSet {
String value();
}

View File

@ -70,7 +70,7 @@ import org.hl7.fhir.utilities.MarkDownProcessor;
import org.hl7.fhir.utilities.StandardsStatus;
import org.hl7.fhir.utilities.Utilities;
public class CodeSystemUtilities {
public class CodeSystemUtilities extends TerminologyUtilities {
public static class SystemReference {
private String link;

View File

@ -0,0 +1,27 @@
package org.hl7.fhir.r5.terminologies;
import java.util.HashSet;
import java.util.Set;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.Identifier;
import org.hl7.fhir.utilities.json.model.JsonObject;
public class TerminologyUtilities {
public static Set<String> listOids(CanonicalResource cr) {
Set<String> oids = new HashSet<>();
if (cr.hasUrl() && cr.getUrl().startsWith("urn:oid:")) {
oids.add(cr.getUrl().substring(8));
}
for (Identifier id : cr.getIdentifier()) {
String v = id.getValue();
if (v != null && v.startsWith("urn:oid:")) {
oids.add(v.substring(8));
}
}
return oids;
}
}

View File

@ -3,7 +3,9 @@ package org.hl7.fhir.r5.terminologies;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/*
Copyright (c) 2011+, HL7, Inc.
@ -66,7 +68,7 @@ import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.utilities.StandardsStatus;
import org.hl7.fhir.utilities.Utilities;
public class ValueSetUtilities {
public class ValueSetUtilities extends TerminologyUtilities {
public static boolean isServerSide(String url) {
@ -401,5 +403,20 @@ public class ValueSetUtilities {
return i;
}
public static Set<String> listSystems(IWorkerContext ctxt, ValueSet vs) {
Set<String> systems = new HashSet<>();
for (ConceptSetComponent inc : vs.getCompose().getInclude()) {
for (CanonicalType ct : inc.getValueSet()) {
ValueSet vsr = ctxt.fetchResource(ValueSet.class, ct.asStringValue(), vs);
if (vsr != null) {
systems.addAll(listSystems(ctxt, vsr));
}
}
if (inc.hasSystem()) {
systems.add(inc.getSystem());
}
}
return systems;
}
}

View File

@ -4,6 +4,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.fhir.ucum.UcumEssenceService;
@ -175,5 +176,7 @@ public class TestingUtilities extends BaseTestingUtilities {
FilesystemPackageCacheManager.setPackageProvider(new TestingUtilities.PackageProvider());
}
public static boolean runningAsSurefire() {
return "true".equals(System.getProperty("runningAsSurefire") != null ? System.getProperty("runningAsSurefire").toLowerCase(Locale.ENGLISH) : "");
}
}

View File

@ -153,8 +153,8 @@ public class FHIRPathEngine {
* @param beforeContext - whether this is being called before the name is resolved locally, or not
* @return the value of the reference (or null, if it's not valid, though can throw an exception if desired)
*/
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException;
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException;
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException;
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException;
/**
* when the .log() function is called
@ -171,7 +171,7 @@ public class FHIRPathEngine {
* @param functionName
* @return null if the function is not known
*/
public FunctionDetails resolveFunction(String functionName);
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName);
/**
* Check the function parameters, and throw an error if they are incorrect, or return the type for the function
@ -179,7 +179,7 @@ public class FHIRPathEngine {
* @param parameters
* @return
*/
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) throws PathEngineException;
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters) throws PathEngineException;
/**
* @param appContext
@ -187,7 +187,7 @@ public class FHIRPathEngine {
* @param parameters
* @return
*/
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters);
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters);
/**
* Implementation of resolve() function. Passed a string, return matching resource, if one is known - else null
@ -196,14 +196,14 @@ public class FHIRPathEngine {
* @return
* @throws FHIRException
*/
public Base resolveReference(Object appContext, String url, Base refContext) throws FHIRException;
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) throws FHIRException;
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException;
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException;
/*
* return the value set referenced by the url, which has been used in memberOf()
*/
public ValueSet resolveValueSet(Object appContext, String url);
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url);
/**
* For the moment, there can only be one parameter if it's a type parameter
@ -1112,7 +1112,7 @@ public class FHIRPathEngine {
FunctionDetails details = null;
if (f == null) {
if (hostServices != null) {
details = hostServices.resolveFunction(result.getName());
details = hostServices.resolveFunction(this, result.getName());
}
if (details == null) {
throw lexer.error("The name "+result.getName()+" is not a valid function name");
@ -1536,7 +1536,7 @@ public class FHIRPathEngine {
} else if (atEntry && exp.getName().equals("$index")) {
result.addType(TypeDetails.FP_Integer);
} else if (atEntry && focus == null) {
result.update(executeContextType(context, exp.getName(), exp));
result.update(executeContextType(context, exp.getName(), exp, false));
} else {
for (String s : focus.getTypes()) {
result.update(executeType(s, exp, atEntry, focus, elementDependencies));
@ -1560,7 +1560,7 @@ public class FHIRPathEngine {
result.addType(TypeDetails.FP_Quantity);
break;
case Constant:
result.update(resolveConstantType(context, exp.getConstant(), exp));
result.update(resolveConstantType(context, exp.getConstant(), exp, true));
break;
case Group:
result.update(executeType(context, focus, exp.getGroup(), elementDependencies, atEntry, canBeNone, exp));
@ -1612,7 +1612,7 @@ public class FHIRPathEngine {
}
FHIRConstant c = (FHIRConstant) constant;
if (c.getValue().startsWith("%")) {
return resolveConstant(context, c.getValue(), beforeContext, expr);
return resolveConstant(context, c.getValue(), beforeContext, expr, true);
} else if (c.getValue().startsWith("@")) {
return new ArrayList<Base>(Arrays.asList(processDateConstant(context.appInfo, c.getValue().substring(1), expr)));
} else {
@ -1683,7 +1683,7 @@ public class FHIRPathEngine {
}
private List<Base> resolveConstant(ExecutionContext context, String s, boolean beforeContext, ExpressionNode expr) throws PathEngineException {
private List<Base> resolveConstant(ExecutionContext context, String s, boolean beforeContext, ExpressionNode expr, boolean explicitConstant) throws PathEngineException {
if (s.equals("%sct")) {
return new ArrayList<Base>(Arrays.asList(new StringType("http://snomed.info/sct").noExtensions()));
} else if (s.equals("%loinc")) {
@ -1713,7 +1713,7 @@ public class FHIRPathEngine {
} else if (hostServices == null) {
throw makeException(expr, I18nConstants.FHIRPATH_UNKNOWN_CONSTANT, s);
} else {
return hostServices.resolveConstant(context.appInfo, s.substring(1), beforeContext);
return hostServices.resolveConstant(this, context.appInfo, s.substring(1), beforeContext, explicitConstant);
}
}
@ -2532,7 +2532,7 @@ public class FHIRPathEngine {
private List<Base> opMemberOf(ExecutionContext context, List<Base> left, List<Base> right, ExpressionNode expr) throws FHIRException {
boolean ans = false;
String url = right.get(0).primitiveValue();
ValueSet vs = hostServices != null ? hostServices.resolveValueSet(context.appInfo, url) : worker.fetchResource(ValueSet.class, url);
ValueSet vs = hostServices != null ? hostServices.resolveValueSet(this, context.appInfo, url) : worker.fetchResource(ValueSet.class, url);
if (vs != null) {
for (Base l : left) {
if (Utilities.existsInList(l.fhirType(), "code", "string", "uri")) {
@ -3031,7 +3031,7 @@ public class FHIRPathEngine {
}
private TypeDetails resolveConstantType(ExecutionTypeContext context, Base constant, ExpressionNode expr) throws PathEngineException {
private TypeDetails resolveConstantType(ExecutionTypeContext context, Base constant, ExpressionNode expr, boolean explicitConstant) throws PathEngineException {
if (constant instanceof BooleanType) {
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
} else if (constant instanceof IntegerType) {
@ -3041,7 +3041,7 @@ public class FHIRPathEngine {
} else if (constant instanceof Quantity) {
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Quantity);
} else if (constant instanceof FHIRConstant) {
return resolveConstantType(context, ((FHIRConstant) constant).getValue(), expr);
return resolveConstantType(context, ((FHIRConstant) constant).getValue(), expr, explicitConstant);
} else if (constant == null) {
return new TypeDetails(CollectionStatus.SINGLETON);
} else {
@ -3049,7 +3049,7 @@ public class FHIRPathEngine {
}
}
private TypeDetails resolveConstantType(ExecutionTypeContext context, String s, ExpressionNode expr) throws PathEngineException {
private TypeDetails resolveConstantType(ExecutionTypeContext context, String s, ExpressionNode expr, boolean explicitConstant) throws PathEngineException {
if (s.startsWith("@")) {
if (s.startsWith("@T")) {
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Time);
@ -3087,7 +3087,7 @@ public class FHIRPathEngine {
} else if (hostServices == null) {
throw makeException(expr, I18nConstants.FHIRPATH_UNKNOWN_CONSTANT, s);
} else {
return hostServices.resolveConstantType(context.appInfo, s);
return hostServices.resolveConstantType(this, context.appInfo, s, explicitConstant);
}
}
@ -3095,7 +3095,7 @@ public class FHIRPathEngine {
List<Base> result = new ArrayList<Base>();
if (atEntry && context.appInfo != null && hostServices != null) {
// we'll see if the name matches a constant known by the context.
List<Base> temp = hostServices.resolveConstant(context.appInfo, exp.getName(), true);
List<Base> temp = hostServices.resolveConstant(this, context.appInfo, exp.getName(), true, false);
if (!temp.isEmpty()) {
result.addAll(temp);
return result;
@ -3123,7 +3123,7 @@ public class FHIRPathEngine {
if (atEntry && context.appInfo != null && hostServices != null && result.isEmpty()) {
// well, we didn't get a match on the name - we'll see if the name matches a constant known by the context.
// (if the name does match, and the user wants to get the constant value, they'll have to try harder...
result.addAll(hostServices.resolveConstant(context.appInfo, exp.getName(), false));
result.addAll(hostServices.resolveConstant(this, context.appInfo, exp.getName(), false, false));
}
return result;
}
@ -3133,11 +3133,11 @@ public class FHIRPathEngine {
}
private TypeDetails executeContextType(ExecutionTypeContext context, String name, ExpressionNode expr) throws PathEngineException, DefinitionException {
private TypeDetails executeContextType(ExecutionTypeContext context, String name, ExpressionNode expr, boolean explicitConstant) throws PathEngineException, DefinitionException {
if (hostServices == null) {
throw makeException(expr, I18nConstants.FHIRPATH_HO_HOST_SERVICES, "Context Reference");
}
return hostServices.resolveConstantType(context.appInfo, name);
return hostServices.resolveConstantType(this, context.appInfo, name, explicitConstant);
}
private TypeDetails executeType(String type, ExpressionNode exp, boolean atEntry, TypeDetails focus, Set<ElementDefinition> elementDependencies) throws PathEngineException, DefinitionException {
@ -3585,7 +3585,7 @@ public class FHIRPathEngine {
}
case Custom : {
return hostServices.checkFunction(context.appInfo, exp.getName(), paramTypes);
return hostServices.checkFunction(this, context.appInfo,exp.getName(), focus, paramTypes);
}
default:
break;
@ -3632,7 +3632,7 @@ public class FHIRPathEngine {
}
private void checkContextReference(TypeDetails focus, String name, ExpressionNode expr) throws PathEngineException {
if (!focus.hasType(worker, "string") && !focus.hasType(worker, "uri") && !focus.hasType(worker, "Reference") && !focus.hasType(worker, "canonical")) {
if (!focus.hasType(worker, "string") && !focus.hasType(worker, "uri") && !focus.hasType(worker, "url") && !focus.hasType(worker, "Reference") && !focus.hasType(worker, "canonical")) {
throw makeException(expr, I18nConstants.FHIRPATH_REFERENCE_ONLY, name, focus.describe());
}
}
@ -3818,7 +3818,7 @@ public class FHIRPathEngine {
params.add(execute(context, focus, p, true));
}
}
return hostServices.executeFunction(context.appInfo, focus, exp.getName(), params);
return hostServices.executeFunction(this, context.appInfo, focus, exp.getName(), params);
}
default:
throw new Error("not Implemented yet");
@ -4481,7 +4481,7 @@ public class FHIRPathEngine {
}
String url = nl.get(0).primitiveValue();
ValueSet vs = hostServices != null ? hostServices.resolveValueSet(context.appInfo, url) : worker.fetchResource(ValueSet.class, url);
ValueSet vs = hostServices != null ? hostServices.resolveValueSet(this, context.appInfo, url) : worker.fetchResource(ValueSet.class, url);
if (vs == null) {
return new ArrayList<Base>();
}
@ -5108,7 +5108,7 @@ public class FHIRPathEngine {
}
} else if (hostServices != null) {
try {
res = hostServices.resolveReference(context.appInfo, s, refContext);
res = hostServices.resolveReference(this, context.appInfo, s, refContext);
} catch (Exception e) {
res = null;
}
@ -5616,7 +5616,7 @@ public class FHIRPathEngine {
result.add(new BooleanType(false).noExtensions());
} else {
String url = convertToString(execute(context, focus, expr.getParameters().get(0), true));
result.add(new BooleanType(hostServices.conformsToProfile(context.appInfo, focus.get(0), url)).noExtensions());
result.add(new BooleanType(hostServices.conformsToProfile(this, context.appInfo, focus.get(0), url)).noExtensions());
}
return result;
}

View File

@ -741,7 +741,7 @@ public class LiquidEngine implements IEvaluationContext {
}
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
if (ctxt.loopVars.containsKey(name))
return new ArrayList<Base>(Arrays.asList(ctxt.loopVars.get(name)));
@ -749,15 +749,15 @@ public class LiquidEngine implements IEvaluationContext {
return new ArrayList<Base>(Arrays.asList(ctxt.globalVars.get(name)));
if (externalHostServices == null)
return new ArrayList<Base>();
return externalHostServices.resolveConstant(ctxt.externalContext, name, beforeContext);
return externalHostServices.resolveConstant(engine, ctxt.externalContext, name, beforeContext, explicitConstant);
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
if (externalHostServices == null)
return null;
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
return externalHostServices.resolveConstantType(ctxt.externalContext, name);
return externalHostServices.resolveConstantType(engine, ctxt.externalContext, name, explicitConstant);
}
@Override
@ -768,49 +768,49 @@ public class LiquidEngine implements IEvaluationContext {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
if (externalHostServices == null)
return null;
return externalHostServices.resolveFunction(functionName);
return externalHostServices.resolveFunction(engine, functionName);
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) throws PathEngineException {
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters) throws PathEngineException {
if (externalHostServices == null)
return null;
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
return externalHostServices.checkFunction(ctxt.externalContext, functionName, parameters);
return externalHostServices.checkFunction(engine, ctxt.externalContext, functionName, focus, parameters);
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
if (externalHostServices == null)
return null;
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
return externalHostServices.executeFunction(ctxt.externalContext, focus, functionName, parameters);
return externalHostServices.executeFunction(engine, ctxt.externalContext, focus, functionName, parameters);
}
@Override
public Base resolveReference(Object appContext, String url, Base refContext) throws FHIRException {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) throws FHIRException {
if (externalHostServices == null)
return null;
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
return resolveReference(ctxt.externalContext, url, refContext);
return resolveReference(engine, ctxt.externalContext, url, refContext);
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
if (externalHostServices == null)
return false;
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
return conformsToProfile(ctxt.externalContext, item, url);
return conformsToProfile(engine, ctxt.externalContext, item, url);
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
LiquidEngineContext ctxt = (LiquidEngineContext) appContext;
if (externalHostServices != null)
return externalHostServices.resolveValueSet(ctxt.externalContext, url);
return externalHostServices.resolveValueSet(engine, ctxt.externalContext, url);
else
return engine.getWorker().fetchResource(ValueSet.class, url);
}

View File

@ -10,7 +10,13 @@ public class ResourceSorters {
@Override
public int compare(CanonicalResource arg0, CanonicalResource arg1) {
return arg0.getUrl().compareTo(arg1.getUrl());
if (arg0.getUrl() != null) {
return arg0.getUrl().compareTo(arg1.getUrl());
} else if (arg1.getUrl() != null) {
return -arg1.getUrl().compareTo(arg0.getUrl());
} else {
return 0;
}
}
}

View File

@ -318,12 +318,12 @@ public class Runner implements IEvaluationContext {
}
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
throw new Error("Not implemented yet: resolveConstant");
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
throw new Error("Not implemented yet: resolveConstantType");
}
@ -333,7 +333,7 @@ public class Runner implements IEvaluationContext {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
switch (functionName) {
case "getResourceKey" : return new FunctionDetails("Unique Key for resource", 0, 0);
case "getReferenceKey" : return new FunctionDetails("Unique Key for resource that is the target of the reference", 0, 1);
@ -341,7 +341,7 @@ public class Runner implements IEvaluationContext {
}
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) throws PathEngineException {
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters) throws PathEngineException {
switch (functionName) {
case "getResourceKey" : return new TypeDetails(CollectionStatus.SINGLETON, "string");
case "getReferenceKey" : return new TypeDetails(CollectionStatus.SINGLETON, "string");
@ -350,7 +350,7 @@ public class Runner implements IEvaluationContext {
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
switch (functionName) {
case "getResourceKey" : return executeResourceKey(focus);
case "getReferenceKey" : return executeReferenceKey(focus, parameters);
@ -420,17 +420,17 @@ public class Runner implements IEvaluationContext {
return null;
}
@Override
public Base resolveReference(Object appContext, String url, Base refContext) throws FHIRException {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) throws FHIRException {
throw new Error("Not implemented yet: resolveReference");
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
throw new Error("Not implemented yet: conformsToProfile");
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
throw new Error("Not implemented yet: resolveValueSet");
}
@Override

View File

@ -24,7 +24,7 @@ public class FHIRPathHostServices implements FHIRPathEngine.IEvaluationContext {
this.structureMapUtilities = structureMapUtilities;
}
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
Variables vars = (Variables) appContext;
Base res = vars.get(VariableMode.INPUT, name);
if (res == null)
@ -36,7 +36,7 @@ public class FHIRPathHostServices implements FHIRPathEngine.IEvaluationContext {
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
if (!(appContext instanceof VariablesForProfiling))
throw new Error("Internal Logic Error (wrong type '" + appContext.getClass().getName() + "' in resolveConstantType)");
VariablesForProfiling vars = (VariablesForProfiling) appContext;
@ -52,22 +52,22 @@ public class FHIRPathHostServices implements FHIRPathEngine.IEvaluationContext {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
return null; // throw new Error("Not Implemented Yet");
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) throws PathEngineException {
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters) throws PathEngineException {
throw new Error("Not Implemented Yet");
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
throw new Error("Not Implemented Yet");
}
@Override
public Base resolveReference(Object appContext, String url, Base refContext) throws FHIRException {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) throws FHIRException {
if (structureMapUtilities.getServices() == null)
return null;
return structureMapUtilities.getServices().resolveReference(appContext, url);
@ -81,7 +81,7 @@ public class FHIRPathHostServices implements FHIRPathEngine.IEvaluationContext {
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
IResourceValidator val = structureMapUtilities.getWorker().newValidator();
List<ValidationMessage> valerrors = new ArrayList<ValidationMessage>();
if (item instanceof Resource) {
@ -96,7 +96,7 @@ public class FHIRPathHostServices implements FHIRPathEngine.IEvaluationContext {
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
return structureMapUtilities.getWorker().fetchResource(ValueSet.class, url);
}

View File

@ -112,7 +112,7 @@ public class PETests {
checkElement(children.get(7), "extension", "complex", 0, 1, false, "http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex", 4, "extension('http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex')");
checkElement(children.get(8), "identifier", "identifier", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/Identifier", 7, "identifier");
checkElement(children.get(9), "status", "status", 1, 1, true, "http://hl7.org/fhir/StructureDefinition/code", 2, "status");
checkElement(children.get(10), "category", "category", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/CodeableConcept", 3, "category");
checkElement(children.get(10), "category", "category", 1, 1, false, "http://hl7.org/fhir/StructureDefinition/CodeableConcept", 3, "category");
checkElement(children.get(11), "code", "code", 1, 1, true, "http://hl7.org/fhir/StructureDefinition/CodeableConcept", 3, "code");
checkElement(children.get(12), "subject", "subject", 1, 1, false, "http://hl7.org/fhir/StructureDefinition/Reference", 5, "subject");
checkElement(children.get(13), "encounter", "encounter", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/Reference", 5, "encounter");
@ -154,7 +154,7 @@ public class PETests {
Assertions.assertEquals(schemaName, pe.schemaName());
Assertions.assertEquals(min, pe.min());
Assertions.assertEquals(max, pe.max());
Assertions.assertEquals(fixed, pe.fixedValue() || pe.isInFixedValue());
Assertions.assertEquals(fixed, pe.hasFixedValue() || pe.isInFixedValue());
if (type != null) {
Assertions.assertEquals(1, pe.types().size());
Assertions.assertEquals(type, pe.types().get(0).getUrl());

View File

@ -12,33 +12,17 @@ import org.hl7.fhir.r5.profilemodel.PEBuilder;
import org.hl7.fhir.r5.profilemodel.PEInstance;
import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy;
import org.hl7.fhir.r5.profilemodel.gen.PEGeneratedBase;
import java.util.List;
import java.util.ArrayList;
import javax.annotation.Nullable;
import java.util.Date;
import org.hl7.fhir.r5.profilemodel.gen.Min;
import org.hl7.fhir.r5.profilemodel.gen.Max;
import org.hl7.fhir.r5.profilemodel.gen.Label;
import org.hl7.fhir.r5.profilemodel.gen.Doco;
import org.hl7.fhir.r5.profilemodel.gen.BindingStrength;
import org.hl7.fhir.r5.profilemodel.gen.ValueSet;
import org.hl7.fhir.r5.profilemodel.gen.MustSupport;
import org.hl7.fhir.r5.profilemodel.gen.Definition;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.model.*;
import org.hl7.fhir.r5.profilemodel.PEBuilder;
import org.hl7.fhir.r5.profilemodel.PEInstance;
import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy;
import org.hl7.fhir.r5.profilemodel.gen.PEGeneratedBase;
import java.util.List;
import java.util.ArrayList;
import javax.annotation.Nullable;
import java.util.Date;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.model.*;
import org.hl7.fhir.r5.profilemodel.PEBuilder;
import org.hl7.fhir.r5.profilemodel.PEInstance;
import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy;
import org.hl7.fhir.r5.profilemodel.gen.PEGeneratedBase;
// Generated by the HAPI Java Profile Generator, Tue, Sep 26, 2023 00:00+1000
// Generated by the HAPI Java Profile Generator, {date}
/**
* A complex extension - an extension with 2 levels
@ -48,9 +32,22 @@ public class TestComplexExtension extends PEGeneratedBase {
private static final String CANONICAL_URL = "http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex|0.1";
@Min("1") @Max("*") @Doco("Additional content defined by implementations")
@Definition("May be used to represent additional information that is not part of the basic definition of the element. To make the use of extensions safe and managable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension.")
private List<Extension> extensions = new ArrayList<>();// @NotNull // Additional content defined by implementations
@Min("0") @Max("2") @Doco("A code")
@MustSupport(true)
@Definition("A code for the extension")
private Coding slice1; // A code
@Min("0") @Max("*") @Doco("More Details")
@Definition("More details")
private List<StringType> slice2s = new ArrayList<>(); // More Details
@Min("1") @Max("1") @Doco("Justification Details")
@MustSupport(true)
@Definition("Justification Details.")
private Extension slice3;// @NotNull // Justification Details
/**

View File

@ -12,21 +12,17 @@ import org.hl7.fhir.r5.profilemodel.PEBuilder;
import org.hl7.fhir.r5.profilemodel.PEInstance;
import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy;
import org.hl7.fhir.r5.profilemodel.gen.PEGeneratedBase;
import java.util.List;
import java.util.ArrayList;
import javax.annotation.Nullable;
import java.util.Date;
import org.hl7.fhir.r5.profilemodel.gen.Min;
import org.hl7.fhir.r5.profilemodel.gen.Max;
import org.hl7.fhir.r5.profilemodel.gen.Label;
import org.hl7.fhir.r5.profilemodel.gen.Doco;
import org.hl7.fhir.r5.profilemodel.gen.BindingStrength;
import org.hl7.fhir.r5.profilemodel.gen.ValueSet;
import org.hl7.fhir.r5.profilemodel.gen.MustSupport;
import org.hl7.fhir.r5.profilemodel.gen.Definition;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.model.*;
import org.hl7.fhir.r5.profilemodel.PEBuilder;
import org.hl7.fhir.r5.profilemodel.PEInstance;
import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy;
import org.hl7.fhir.r5.profilemodel.gen.PEGeneratedBase;
// Generated by the HAPI Java Profile Generator, Sun, Aug 20, 2023 19:05+1000
// Generated by the HAPI Java Profile Generator, {date}
/**
* Test CodeableConcept Profile.
@ -36,11 +32,23 @@ public class TestDatatypeProfile extends PEGeneratedBase {
private static final String CANONICAL_URL = "http://hl7.org/fhir/test/StructureDefinition/pe-profile2|0.1";
@Min("1") @Max("2") @Doco("Code defined by a terminology system")
@Definition("A reference to a code defined by a terminology system.")
private Coding coding;// @NotNull // Code defined by a terminology system
@Min("1") @Max("1") @Doco("Code defined by a terminology system")
@Definition("A reference to a code defined by a terminology system.")
private Coding snomedct;// @NotNull // Code defined by a terminology system
@Min("0") @Max("1") @Doco("Code defined by a terminology system")
@Definition("A reference to a code defined by a terminology system.")
private Coding loinc; // Code defined by a terminology system
@Min("1") @Max("1") @Doco("Plain text representation of the concept")
@Definition("A human language representation of the concept as seen/selected/uttered by the user who entered the data and/or which represents the intended meaning of the user.")
private String text;// @NotNull // Plain text representation of the concept
/**
* Parameter-less constructor. If you use this, the fixed values won't be filled
* out - they'll be missing. They'll be filled in if/when you call build, so they

View File

@ -24,9 +24,23 @@ import org.hl7.fhir.r5.profilemodel.PEBuilder;
import org.hl7.fhir.r5.profilemodel.PEInstance;
import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy;
import org.hl7.fhir.r5.profilemodel.gen.PEGeneratedBase;
import org.hl7.fhir.r5.profilemodel.gen.Min;
import org.hl7.fhir.r5.profilemodel.gen.Max;
import org.hl7.fhir.r5.profilemodel.gen.Label;
import org.hl7.fhir.r5.profilemodel.gen.Doco;
import org.hl7.fhir.r5.profilemodel.gen.BindingStrength;
import org.hl7.fhir.r5.profilemodel.gen.ValueSet;
import org.hl7.fhir.r5.profilemodel.gen.MustSupport;
import org.hl7.fhir.r5.profilemodel.gen.Definition;
// Generated by the HAPI Java Profile Generator, Sun, Aug 20, 2023 19:01+1000
/*
Licensed under CC0 1.0 Universal (CC0 1.0).
The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law.
You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. See Other Information below.
*/
// Generated by the HAPI Java Profile Generator, {date}
/**
* Test Observation Profile.
@ -36,28 +50,132 @@ public class TestProfile extends PEGeneratedBase {
private static final String CANONICAL_URL = "http://hl7.org/fhir/test/StructureDefinition/pe-profile1|0.1";
public enum ProfileObservationCategoryCode {
LABORATORY, // "Laboratory" = http://terminology.hl7.org/CodeSystem/observation-category#laboratory
IMAGING; // "Imaging" = http://terminology.hl7.org/CodeSystem/observation-category#imaging
public static ProfileObservationCategoryCode fromCode(String s) {
switch (s) {
case "laboratory": return LABORATORY;
case "imaging": return IMAGING;
default: return null;
}
}
public static ProfileObservationCategoryCode fromCoding(Coding c) {
if ("http://terminology.hl7.org/CodeSystem/observation-category".equals(c.getSystem()) && "laboratory".equals(c.getCode())) {
return LABORATORY;
}
if ("http://terminology.hl7.org/CodeSystem/observation-category".equals(c.getSystem()) && "imaging".equals(c.getCode())) {
return IMAGING;
}
return null;
}
public static ProfileObservationCategoryCode fromCodeableConcept(CodeableConcept cc) {
for (Coding c : cc.getCoding()) {
ProfileObservationCategoryCode v = fromCoding(c);
if (v != null) {
return v;
}
}
return null;
}
public String toDisplay() {
switch (this) {
case LABORATORY: return "Laboratory";
case IMAGING: return "Imaging";
default: return null;
}
}
public String toCode() {
switch (this) {
case LABORATORY: return "laboratory";
case IMAGING: return "imaging";
default: return null;
}
}
public Coding toCoding() {
switch (this) {
case LABORATORY: return new Coding().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("laboratory");
case IMAGING: return new Coding().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("imaging");
default: return null;
}
}
public CodeableConcept toCodeableConcept() {
Coding c = toCoding();
return c == null ? null : new CodeableConcept().addCoding(c);
}
}
@Min("0") @Max("1") @Doco("")
private String id; //
@Min("0") @Max("*") @Doco("Extension")
@Definition("An Extension")
private List<Extension> extensions = new ArrayList<>(); // Extension
@Min("0") @Max("1") @Doco("A simple extension")
@Definition("A simple extension - an extension with just a value")
private String simple; // A simple extension
// @ProfileAnnotation(max = 1, min=1, path="Observation.extension('url')", doco = "blah", type="")
@Min("0") @Max("1") @Doco("A complex extension")
@Definition("A complex extension - an extension with 2 levels")
private TestComplexExtension complex; // A complex extension
@Min("0") @Max("1") @Doco("Business Identifier for observation")
@Definition("A unique identifier assigned to this observation.")
private Identifier identifier; // Business Identifier for observation
@Min("1") @Max("1") @Doco("registered | preliminary | final | amended +")
@BindingStrength("required") @ValueSet("http://hl7.org/fhir/ValueSet/observation-status|5.0.0")
@Definition("The status of the result value.")
private String status;// @NotNull // registered | preliminary | final | amended +
@Min("1") @Max("1") @Doco("Classification of type of observation")
@BindingStrength("required") @ValueSet("#vs1")
@Definition("A code that classifies the general type of observation being made.")
private ProfileObservationCategoryCode category;// @NotNull // Classification of type of observation
@Min("1") @Max("1") @Doco("Sexual Orientation")
@BindingStrength("example") @ValueSet("http://hl7.org/fhir/ValueSet/observation-codes")
@Definition("Describes what was observed. Sometimes this is called the observation \"name\".")
private CodeableConcept code;// @NotNull // Sexual Orientation
@Min("1") @Max("1") @Doco("Who and/or what the observation is about")
@MustSupport(true)
@Definition("The patient, or group of patients, location, device, organization, procedure or practitioner this observation is about and into whose or what record the observation is placed. If the actual focus of the observation is different from the subject (or a sample of, part, or region of the subject), the `focus` element or the `code` itself specifies the actual focus of the observation.")
private Reference subject;// @NotNull // Who and/or what the observation is about
@Min("0") @Max("1") @Doco("Healthcare event during which this observation is made")
@Definition("The healthcare event (e.g. a patient and healthcare provider interaction) during which this observation is made.")
private Reference encounter; // Healthcare event during which this observation is made
@Min("1") @Max("1") @Doco("Clinically relevant time/time-period for observation")
@Definition("Time of observation")
private Date effective;// @NotNull // Clinically relevant time/time-period for observation
@Min("0") @Max("*") @Doco("Who is responsible for the observation")
@Definition("Who was responsible for asserting the observed value as \"true\".")
private List<Reference> performers = new ArrayList<>(); // Who is responsible for the observation
@Min("0") @Max("1") @Doco("Sexual Orientation")
@BindingStrength("extensible") @ValueSet("http://hl7.org/fhir/us/core/ValueSet/us-core-sexual-orientation")
@MustSupport(true)
@Definition("The Sexual Orientation value.")
private TestDatatypeProfile valueCodeableConcept; // Sexual Orientation
/**
* Parameter-less constructor. If you use this, the fixed values won't be filled
* out - they'll be missing. They'll be filled in if/when you call build, so they
* won't be missing from the resource, only from this particular object model
* Parameter-less constructor.
*
*/
public TestProfile() {
// todo
initFixedValues();
}
/**
@ -65,6 +183,7 @@ public class TestProfile extends PEGeneratedBase {
*
*/
public TestProfile(IWorkerContext context) {
initFixedValues();
workerContext = context;
PEBuilder builder = new PEBuilder(context, PEElementPropertiesPolicy.EXTENSION, true);
PEInstance src = builder.buildPEInstance(CANONICAL_URL, builder.createResource(CANONICAL_URL, false));
@ -105,6 +224,9 @@ public class TestProfile extends PEGeneratedBase {
if (src.hasChild("status")) {
status = src.child("status").asDataType().primitiveValue();
}
if (src.hasChild("category")) {
category = ProfileObservationCategoryCode.fromCodeableConcept((CodeableConcept) src.child("category").asDataType());
}
if (src.hasChild("code")) {
code = (CodeableConcept) src.child("code").asDataType();
}
@ -174,7 +296,11 @@ public class TestProfile extends PEGeneratedBase {
}
tgt.clear("status");
if (status != null) {
tgt.makeChild("status").data().setProperty("value", new StringType(status));
tgt.makeChild("status").data().setProperty("value", new CodeType(status));
}
tgt.clear("category");
if (category != null) {
tgt.addChild("category", category.toCodeableConcept());
}
tgt.clear("code");
if (code != null) {
@ -203,6 +329,11 @@ public class TestProfile extends PEGeneratedBase {
}
private void initFixedValues() {
status = "final";
}
/**
* Test Observation Profile.
*
@ -309,13 +440,25 @@ public class TestProfile extends PEGeneratedBase {
return status;
}
public TestProfile setStatus(String value) {
this.status = value;
public boolean hasStatus() {
return true;
}
/**
* Test Observation Profile.
*
*/
public ProfileObservationCategoryCode getCategory() {
return category;
}
public TestProfile setCategory(ProfileObservationCategoryCode value) {
this.category = value;
return this;
}
public boolean hasStatus() {
return status != null;
public boolean hasCategory() {
return category != null;
}
/**
@ -438,6 +581,7 @@ public class TestProfile extends PEGeneratedBase {
complex = null;
identifier = null;
status = null;
category = null;
code = null;
subject = null;
encounter = null;

View File

@ -46,12 +46,12 @@ public class FHIRPathTests {
public class FHIRPathTestEvaluationServices implements IEvaluationContext {
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.resolveConstant), when item is element");
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.resolveConstantType), when item is element");
}
@ -61,27 +61,27 @@ public class FHIRPathTests {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.resolveFunction), when item is element (for " + functionName + ")");
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) throws PathEngineException {
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters) throws PathEngineException {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.checkFunction), when item is element");
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.executeFunction), when item is element");
}
@Override
public Base resolveReference(Object appContext, String url, Base refContext) throws FHIRException {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) throws FHIRException {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.resolveReference), when item is element");
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
if (url.equals("http://hl7.org/fhir/StructureDefinition/Patient"))
return true;
if (url.equals("http://hl7.org/fhir/StructureDefinition/Person"))
@ -91,7 +91,7 @@ public class FHIRPathTests {
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
return TestingUtilities.getSharedWorkerContext().fetchResource(ValueSet.class, url);
}
@ -291,7 +291,7 @@ public class FHIRPathTests {
final String DUMMY_CONSTANT_2 = "dummyConstant2";
fp.setHostServices(new FHIRPathTestEvaluationServices() {
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
return Arrays.asList(
new StringType(DUMMY_CONSTANT_1).noExtensions(),

View File

@ -337,12 +337,12 @@ public class SnapShotGenerationTests {
// FHIRPath methods
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
throw new Error("Not implemented yet");
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
throw new Error("Not implemented yet");
}
@ -353,21 +353,21 @@ public class SnapShotGenerationTests {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
if ("fixture".equals(functionName))
return new FunctionDetails("Access a fixture defined in the testing context", 0, 1);
return null;
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) throws PathEngineException {
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters) throws PathEngineException {
if ("fixture".equals(functionName))
return new TypeDetails(CollectionStatus.SINGLETON, TestingUtilities.getSharedWorkerContext().getResourceNamesAsSet());
return null;
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
if ("fixture".equals(functionName)) {
String id = fp.convertToString(parameters.get(0));
Resource res = fetchFixture(id);
@ -382,13 +382,13 @@ public class SnapShotGenerationTests {
}
@Override
public Base resolveReference(Object appContext, String url, Base refContext) {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
IResourceValidator val = TestingUtilities.getSharedWorkerContext().newValidator();
List<ValidationMessage> valerrors = new ArrayList<ValidationMessage>();
if (item instanceof Resource) {
@ -416,7 +416,7 @@ public class SnapShotGenerationTests {
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
throw new Error("Not implemented yet");
}

View File

@ -24,7 +24,7 @@ class FHIRPathHostServicesTest {
public void testrResolveValueSet() throws IOException, FHIRException {
StructureMapUtilities scu = new StructureMapUtilities(context);
FHIRPathHostServices fphs = new FHIRPathHostServices(scu);
ValueSet v = fphs.resolveValueSet(null, "http://hl7.org/fhir/ValueSet/FHIR-version");
ValueSet v = fphs.resolveValueSet(null, null, "http://hl7.org/fhir/ValueSet/FHIR-version");
Assertions.assertNotNull(v);
Assertions.assertEquals("http://hl7.org/fhir/ValueSet/FHIR-version", v.getUrl());
}

View File

@ -109,6 +109,12 @@ public class Utilities {
return inf.pluralize(word);
}
public static String singularise(String word) {
Inflector inf = new Inflector();
return inf.singularize(word);
}
public static boolean isInteger(String string) {
if (isBlank(string)) {
return false;
@ -556,6 +562,8 @@ public class Utilities {
return b.toString();
}
public static String unescapeJson(String json) throws FHIRException {
if (json == null)
return null;
@ -991,6 +999,23 @@ public class Utilities {
}
public static String escapeCSV(String value) {
if (value == null)
return "";
StringBuilder b = new StringBuilder();
for (char c : value.toCharArray()) {
if (c == '"')
b.append("\"\"");
else if (isWhitespace(c))
b.append(" ");
else
b.append(c);
}
return b.toString();
}
public static String escapeJson(String value) {
if (value == null)
return "";

View File

@ -177,7 +177,7 @@ public class I18nConstants {
public static final String FHIRPATH_ORDERED_ONLY = "FHIRPATH_ORDERED_ONLY";
public static final String FHIRPATH_PARAM_WRONG = "FHIRPATH_PARAM_WRONG";
public static final String FHIRPATH_PRIMITIVE_ONLY = "FHIRPATH_PRIMITIVE_ONLY";
public static final String FHIRPATH_REFERENCE_ONLY = "FHIRPATH_ORDERED_ONLY";
public static final String FHIRPATH_REFERENCE_ONLY = "FHIRPATH_REFERENCE_ONLY";
public static final String FHIRPATH_RESOLVE_DISCRIMINATOR_CANT_FIND = "FHIRPATH_RESOLVE_DISCRIMINATOR_CANT_FIND";
public static final String FHIRPATH_RESOLVE_DISCRIMINATOR_NO_TARGET = "FHIRPATH_RESOLVE_DISCRIMINATOR_NO_TARGET";
public static final String FHIRPATH_RIGHT_VALUE = "FHIRPATH_RIGHT_VALUE";

View File

@ -275,16 +275,23 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
private class ValidatorHostServices implements IEvaluationContext {
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
ValidationContext c = (ValidationContext) appContext;
if ("profile".equals(name) && explicitConstant) {
List<Base> b = new ArrayList<>();
if (c.getProfile() != null) {
b.add(c.getProfile());
}
return b;
}
if (externalHostServices != null)
return externalHostServices.resolveConstant(c.getAppContext(), name, beforeContext);
return externalHostServices.resolveConstant(engine, c.getAppContext(), name, beforeContext, explicitConstant);
else
return new ArrayList<Base>();
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
if (appContext instanceof VariableSet) {
VariableSet vars = (VariableSet) appContext;
VariableDefn v = vars.getVariable(name.substring(1));
@ -296,7 +303,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
ValidationContext c = (ValidationContext) appContext;
if (externalHostServices != null)
return externalHostServices.resolveConstantType(c.getAppContext(), name);
return externalHostServices.resolveConstantType(engine, c.getAppContext(), name, explicitConstant);
else
return null;
}
@ -310,22 +317,76 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
@Override
public FunctionDetails resolveFunction(String functionName) {
throw new FHIRException(context.formatMessage(I18nConstants.NOT_DONE_YET_VALIDATORHOSTSERVICESRESOLVEFUNCTION_, functionName));
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
switch (functionName) {
case "slice": return new FunctionDetails("Returns the given slice as defined in the given structure definition. If in an invariant, First parameter can be %profile - current profile", 2, 2);
default: throw new FHIRException(context.formatMessage(I18nConstants.NOT_DONE_YET_VALIDATORHOSTSERVICESRESOLVEFUNCTION_, functionName));
}
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) throws PathEngineException {
throw new Error(context.formatMessage(I18nConstants.NOT_DONE_YET_VALIDATORHOSTSERVICESCHECKFUNCTION));
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters) throws PathEngineException {
switch (functionName) {
case "slice":
// todo: check parameters
return focus;
default: throw new Error(context.formatMessage(I18nConstants.NOT_DONE_YET_VALIDATORHOSTSERVICESCHECKFUNCTION));
}
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
throw new Error(context.formatMessage(I18nConstants.NOT_DONE_YET_VALIDATORHOSTSERVICESEXECUTEFUNCTION));
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
switch (functionName) {
case "slice": return executeSlice(engine, appContext, focus, parameters);
default: throw new Error(context.formatMessage(I18nConstants.NOT_DONE_YET_VALIDATORHOSTSERVICESEXECUTEFUNCTION));
}
}
private List<Base> executeSlice(FHIRPathEngine engine, Object appContext, List<Base> focus, List<List<Base>> parameters) {
ValidationContext c = (ValidationContext) appContext;
List<Base> res = new ArrayList<>();
if (parameters.size() != 2 && !(appContext instanceof ValidationContext)) {
return res;
}
StructureDefinition sd = null;
// if present, first parameter must be a singleton that points to the current profile
if (parameters.get(0).size() > 1) {
return res;
} else if (parameters.get(0).size() == 1) { // if it's there, we have to check it
Base b = parameters.get(0).get(0);
if (b.isPrimitive()) {
sd = context.fetchResource(StructureDefinition.class, b.primitiveValue());
} else if (b instanceof StructureDefinition) {
sd = (StructureDefinition) b;
}
} else {
sd = c.getProfile();
}
// second parameter must be present
if (parameters.get(1).size() != 1) {
return res;
}
String name = parameters.get(1).get(0).primitiveValue();
if (!Utilities.noString(name)) {
for (Base b : focus) {
if (b instanceof Element) {
Element e = (Element) b;
if (e.hasSlice(sd, name)) {
res.add(e);
}
}
}
}
return res;
}
@Override
public Base resolveReference(Object appContext, String url, Base refContext) throws FHIRException {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) throws FHIRException {
ValidationContext c = (ValidationContext) appContext;
if (refContext != null && refContext.hasUserData("validator.bundle.resolution")) {
@ -356,7 +417,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
if (externalHostServices != null) {
return setParentsBase(externalHostServices.resolveReference(c.getAppContext(), url, refContext));
return setParentsBase(externalHostServices.resolveReference(engine, c.getAppContext(), url, refContext));
} else if (fetcher != null) {
try {
return setParents(fetcher.fetch(InstanceValidator.this, c.getAppContext(), url));
@ -370,7 +431,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
ValidationContext ctxt = (ValidationContext) appContext;
StructureDefinition sd = context.fetchResource(StructureDefinition.class, url);
if (sd == null) {
@ -414,7 +475,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
ValidationContext c = (ValidationContext) appContext;
if (c.getProfile() != null && url.startsWith("#")) {
for (Resource r : c.getProfile().getContained()) {
@ -5760,8 +5821,6 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
ValidationInfo vi = element.addDefinition(profile, definition, mode);
// check type invariants
ok = checkInvariants(valContext, errors, profile, definition, resource, element, stack, false) & ok;
if (definition.getFixed() != null) {
ok = checkFixedValue(errors, stack.getLiteralPath(), element, definition.getFixed(), profile.getVersionedUrl(), definition.getSliceName(), null, false) && ok;
}
@ -5792,6 +5851,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
BooleanHolder bh = new BooleanHolder();
List<String> problematicPaths = assignChildren(valContext, errors, profile, resource, stack, childDefinitions, children, bh);
ok = bh.ok() && ok;
for (ElementInfo ei : children) {
ei.getElement().addSliceDefinition(profile, ei.getDefinition(), ei.getSlice());
}
ok = checkCardinalities(errors, profile, element, stack, childDefinitions, children, problematicPaths) && ok;
// 4. check order if any slices are ordered. (todo)
@ -5800,8 +5862,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
for (ElementInfo ei : children) {
ok = checkChild(valContext, errors, profile, definition, resource, element, actualType, stack, inCodeableConcept, checkDisplayInContext, ei, extensionUrl, pct, mode) && ok;
}
vi.setValid(ok);
// check type invariants (after we've sliced the children)
ok = checkInvariants(valContext, errors, profile, definition, resource, element, stack, false) & ok;
vi.setValid(ok);
if (!definition.getPath().contains(".") && profile.hasExtension(ToolingExtensions.EXT_PROFILE_STYLE) && "cda".equals(ToolingExtensions.readStringExtension(profile, ToolingExtensions.EXT_PROFILE_STYLE))) {
List<Element> templates = element.getChildren("templateId");
@ -6694,7 +6759,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
timeTracker.fpe(t);
inv.setUserData("validator.expression.cache", n);
}
valContext.setProfile(profile);
boolean invOK;
String msg;
try {

View File

@ -316,12 +316,12 @@ public class SnapShotGenerationXTests {
// FHIRPath methods
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
throw new Error("Not implemented yet");
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
throw new Error("Not implemented yet");
}
@ -332,21 +332,21 @@ public class SnapShotGenerationXTests {
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
if ("fixture".equals(functionName))
return new FunctionDetails("Access a fixture defined in the testing context", 0, 1);
return null;
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) throws PathEngineException {
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters) throws PathEngineException {
if ("fixture".equals(functionName))
return new TypeDetails(CollectionStatus.SINGLETON, UtilitiesXTests.context(version).getResourceNamesAsSet());
return null;
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
if ("fixture".equals(functionName)) {
String id = fp.convertToString(parameters.get(0));
Resource res = fetchFixture(id);
@ -361,13 +361,13 @@ public class SnapShotGenerationXTests {
}
@Override
public Base resolveReference(Object appContext, String url, Base refContext) {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
IResourceValidator val = UtilitiesXTests.context(version).newValidator();
List<ValidationMessage> valerrors = new ArrayList<ValidationMessage>();
if (item instanceof Resource) {
@ -393,7 +393,7 @@ public class SnapShotGenerationXTests {
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
throw new Error("Not implemented yet");
}

View File

@ -4,11 +4,7 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50;
@ -27,11 +23,9 @@ import org.hl7.fhir.utilities.json.model.JsonObject;
import org.hl7.fhir.utilities.settings.FhirSettings;
import org.hl7.fhir.validation.special.TxTester;
import org.hl7.fhir.validation.special.TxTester.ITxTesterLoader;
import org.hl7.fhir.validation.tests.utilities.TestUtilities;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.condition.EnabledIf;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@ -39,8 +33,7 @@ import org.junit.runners.Parameterized.Parameters;
import com.google.common.base.Charsets;
@RunWith(Parameterized.class)
@EnabledIf("localTxRunning")
@Disabled
public class LocalTerminologyServiceTests implements ITxTesterLoader {
public static class JsonObjectPair {
@ -60,6 +53,8 @@ public class LocalTerminologyServiceTests implements ITxTesterLoader {
return new File("/Users/grahamegrieve/work/server/serverx").exists();
}
@Parameters(name = "{index}: id {0}")
public static Iterable<Object[]> data() throws IOException {
@ -99,10 +94,16 @@ public class LocalTerminologyServiceTests implements ITxTesterLoader {
}
@SuppressWarnings("deprecation")
@Test
@Tag("excludedInSurefire")
@Disabled
@Test
public void test() throws Exception {
if (TestUtilities.runningAsSurefire()) {
logTestSkip("Running in surefire.");
return;
}
if (!localTxRunning()) {
logTestSkip("No local terminology server available.");
return;
}
if (SERVER != null) {
if (tester == null) {
tester = new TxTester(this, SERVER, true, externals);
@ -114,6 +115,10 @@ public class LocalTerminologyServiceTests implements ITxTesterLoader {
}
}
private void logTestSkip(String reason) {
System.out.println("Skipping test: " + setup.suite.asString("name") + " " + setup.test.asString("name") + " reason: " + reason);
}
public Resource loadResource(String filename) throws IOException, FHIRFormatError, FileNotFoundException, FHIRException, DefinitionException {
String contents = TestingUtilities.loadTestResource("tx", filename);
try (InputStream inputStream = IOUtils.toInputStream(contents, Charsets.UTF_8)) {

View File

@ -656,12 +656,12 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
}
@Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
return new ArrayList<Base>();
}
@Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
return null;
}
@ -671,22 +671,22 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
return null;
}
@Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) throws PathEngineException {
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters) throws PathEngineException {
return null;
}
@Override
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
return null;
}
@Override
public Base resolveReference(Object appContext, String url, Base refContext) {
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) {
if (url.equals("Patient/test"))
return new Patient();
return null;
@ -752,7 +752,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
}
@Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
IResourceValidator val = vCurr.getContext().newValidator();
List<ValidationMessage> valerrors = new ArrayList<ValidationMessage>();
if (item instanceof Resource) {
@ -766,7 +766,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
return vCurr.getContext().fetchResource(ValueSet.class, url);
}

View File

@ -1,6 +1,7 @@
package org.hl7.fhir.validation.tests.utilities;
import java.nio.file.Paths;
import java.util.Locale;
import org.hl7.fhir.r5.context.TerminologyCache;
import org.hl7.fhir.r5.test.utils.TestingUtilities;
@ -65,4 +66,8 @@ public class TestUtilities {
return validationEngine;
}
public static boolean runningAsSurefire() {
return "true".equals(System.getProperty("runningAsSurefire") != null ? System.getProperty("runningAsSurefire").toLowerCase(Locale.ENGLISH) : "");
}
}

View File

@ -20,7 +20,7 @@
<properties>
<guava_version>32.0.1-jre</guava_version>
<hapi_fhir_version>6.4.1</hapi_fhir_version>
<validator_test_case_version>1.4.12-SNAPSHOT</validator_test_case_version>
<validator_test_case_version>1.4.13-SNAPSHOT</validator_test_case_version>
<jackson_version>2.15.2</jackson_version>
<junit_jupiter_version>5.9.2</junit_jupiter_version>
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>
@ -341,8 +341,13 @@
<argLine>@{argLine} -Xmx5632m</argLine>
<systemPropertyVariables>
<java.locale.providers>COMPAT</java.locale.providers>
<!-- For JUnit4 use TestUtilities.runningAsSurefire() or
TestingUtilities.runningAsSurefire() to exclude a test from surefire executions-->
<runningAsSurefire>true</runningAsSurefire>
</systemPropertyVariables>
<redirectTestOutputToFile>false</redirectTestOutputToFile>
<!-- For JUnit5 use an excludedInSurefire tag to exclude a test from surefire executions -->
<excludedGroups>excludedInSurefire</excludedGroups>
</configuration>
</plugin>