diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 3d178e66ab..889c801e6c 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -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
diff --git a/org.hl7.fhir.dstu2/src/test/java/org/hl7/fhir/dstu2/test/TestingUtilities.java b/org.hl7.fhir.dstu2/src/test/java/org/hl7/fhir/dstu2/test/TestingUtilities.java
index 5a0e65f5f4..1caa5cc2f5 100644
--- a/org.hl7.fhir.dstu2/src/test/java/org/hl7/fhir/dstu2/test/TestingUtilities.java
+++ b/org.hl7.fhir.dstu2/src/test/java/org/hl7/fhir/dstu2/test/TestingUtilities.java
@@ -5,6 +5,7 @@
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 @@ else if (n1 instanceof JsonPrimitive) {
return null;
}
+ public static boolean runningAsSurefire() {
+ return "true".equals(System.getProperty("runningAsSurefire") != null ? System.getProperty("runningAsSurefire").toLowerCase(Locale.ENGLISH) : "");
+ }
}
\ No newline at end of file
diff --git a/org.hl7.fhir.dstu2016may/src/test/java/org/hl7/fhir/dstu2016may/test/TestingUtilities.java b/org.hl7.fhir.dstu2016may/src/test/java/org/hl7/fhir/dstu2016may/test/TestingUtilities.java
index a6c297ee3a..645df0f830 100644
--- a/org.hl7.fhir.dstu2016may/src/test/java/org/hl7/fhir/dstu2016may/test/TestingUtilities.java
+++ b/org.hl7.fhir.dstu2016may/src/test/java/org/hl7/fhir/dstu2016may/test/TestingUtilities.java
@@ -5,6 +5,7 @@
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 @@ else if (n1 instanceof JsonPrimitive) {
return null;
}
+ public static boolean runningAsSurefire() {
+ return "true".equals(System.getProperty("runningAsSurefire") != null ? System.getProperty("runningAsSurefire").toLowerCase(Locale.ENGLISH) : "");
+ }
+
}
\ No newline at end of file
diff --git a/org.hl7.fhir.dstu3/src/test/java/org/hl7/fhir/dstu3/test/support/TestingUtilities.java b/org.hl7.fhir.dstu3/src/test/java/org/hl7/fhir/dstu3/test/support/TestingUtilities.java
index 8606179934..ea23d05cb6 100644
--- a/org.hl7.fhir.dstu3/src/test/java/org/hl7/fhir/dstu3/test/support/TestingUtilities.java
+++ b/org.hl7.fhir.dstu3/src/test/java/org/hl7/fhir/dstu3/test/support/TestingUtilities.java
@@ -7,6 +7,7 @@
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 @@ else if (n1 instanceof JsonNull) {
return null;
}
-
+ public static boolean runningAsSurefire() {
+ return "true".equals(System.getProperty("runningAsSurefire") != null ? System.getProperty("runningAsSurefire").toLowerCase(Locale.ENGLISH) : "");
+ }
}
\ No newline at end of file
diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/test/utils/TestingUtilities.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/test/utils/TestingUtilities.java
index c11cf89ece..b71cd66628 100644
--- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/test/utils/TestingUtilities.java
+++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/test/utils/TestingUtilities.java
@@ -38,6 +38,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS
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 static String loadTestResource(String... paths) throws IOException {
}
}
+ public static boolean runningAsSurefire() {
+ return "true".equals(System.getProperty("runningAsSurefire") != null ? System.getProperty("runningAsSurefire").toLowerCase(Locale.ENGLISH) : "");
+ }
}
\ No newline at end of file
diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/FHIRPathEngine.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/FHIRPathEngine.java
index 4a7dc0c142..d493cf8cfe 100644
--- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/FHIRPathEngine.java
+++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/FHIRPathEngine.java
@@ -59,6 +59,7 @@
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 interface IEvaluationContext {
* @return the value of the reference (or null, if it's not valid, though can
* throw an exception if desired)
*/
- public List resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException;
+ public List 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 interface IEvaluationContext {
* @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 interface IEvaluationContext {
* @param parameters
* @return
*/
- public TypeDetails checkFunction(Object appContext, String functionName, List parameters)
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List parameters)
throws PathEngineException;
/**
@@ -188,7 +189,7 @@ public TypeDetails checkFunction(Object appContext, String functionName, List executeFunction(Object appContext, List focus, String functionName,
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName,
List> parameters);
/**
@@ -200,14 +201,14 @@ public List executeFunction(Object appContext, List focus, String fu
* @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 @@ private ExpressionNode parseExpression(FHIRLexer lexer, boolean proximal) throws
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 @@ private List execute(ExecutionContext context, List focus, Expressio
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 @@ private TypeDetails executeType(ExecutionTypeContext context, TypeDetails focus,
} 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 @@ private TypeDetails executeType(ExecutionTypeContext context, TypeDetails focus,
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 @@ private TypeDetails executeType(ExecutionTypeContext context, TypeDetails focus,
return result;
}
- private List resolveConstant(ExecutionContext context, Base constant, boolean beforeContext,
- ExpressionNode expr) throws PathEngineException {
+ private List resolveConstant(ExecutionContext context, Base constant, boolean beforeContext, ExpressionNode expr, boolean explicitConstant) throws PathEngineException {
if (constant == null) {
return new ArrayList();
}
@@ -1622,7 +1622,7 @@ private List resolveConstant(ExecutionContext context, Base constant, bool
}
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(Arrays.asList(processDateConstant(context.appInfo, c.getValue().substring(1), expr)));
} else {
@@ -1692,7 +1692,7 @@ private Base processDateConstant(Object appInfo, String value, ExpressionNode ex
}
}
- private List resolveConstant(ExecutionContext context, String s, boolean beforeContext, ExpressionNode expr)
+ private List resolveConstant(ExecutionContext context, String s, boolean beforeContext, ExpressionNode expr, boolean explicitConstant)
throws PathEngineException {
if (s.equals("%sct")) {
return new ArrayList(Arrays.asList(new StringType("http://snomed.info/sct").noExtensions()));
@@ -1726,7 +1726,7 @@ private List resolveConstant(ExecutionContext context, String s, boolean b
} 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 @@ private List opMemberOf(ExecutionContext context, List left, List opMod(List left, List right, ExpressionNode expr)
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 @@ private TypeDetails resolveConstantType(ExecutionTypeContext context, Base const
} 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 @@ private TypeDetails resolveConstantType(ExecutionTypeContext context, Base const
}
}
- 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 @@ private TypeDetails resolveConstantType(ExecutionTypeContext context, String s,
} 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 @@ private List execute(ExecutionContext context, Base item, ExpressionNode e
List result = new ArrayList();
if (atEntry && context.appInfo != null && hostServices != null) {
// we'll see if the name matches a constant known by the context.
- List temp = hostServices.resolveConstant(context.appInfo, exp.getName(), true);
+ List temp = hostServices.resolveConstant(this, context.appInfo, exp.getName(), true, false);
if (!temp.isEmpty()) {
result.addAll(temp);
return result;
@@ -3177,7 +3177,7 @@ private List execute(ExecutionContext context, Base item, ExpressionNode e
// 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 @@ private String getParent(String rn) {
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 @@ private TypeDetails evaluateFunctionType(ExecutionTypeContext context, TypeDetai
}
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 @@ private List evaluateFunction(ExecutionContext context, List focus,
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 @@ private List funcMemberOf(ExecutionContext context, List focus, Expr
}
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();
@@ -5210,7 +5210,7 @@ private List funcResolve(ExecutionContext context, List focus, Expre
}
} 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 @@ private List funcConformsTo(ExecutionContext context, List focus, Ex
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;
}
diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/LiquidEngine.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/LiquidEngine.java
index eb73998a9f..c4c21baf2c 100644
--- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/LiquidEngine.java
+++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/LiquidEngine.java
@@ -369,21 +369,21 @@ private LiquidStatement parseStatement() throws FHIRException {
}
@Override
- public List resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
+ public List 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 boolean log(String argument, List focus) {
}
@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 parameters)
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List 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 executeFunction(Object appContext, List focus, String functionName,
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName,
List> 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);
}
diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/StructureMapUtilities.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/StructureMapUtilities.java
index fea611d934..d83edeb05c 100644
--- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/StructureMapUtilities.java
+++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/StructureMapUtilities.java
@@ -177,7 +177,7 @@ public interface ITransformerServices {
private class FHIRPathHostServices implements IEvaluationContext {
- public List resolveConstant(Object appContext, String name, boolean beforeContext)
+ public List 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 List resolveConstant(Object appContext, String name, boolean before
}
@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 boolean log(String argument, List focus) {
}
@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 parameters)
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List parameters)
throws PathEngineException {
throw new Error("Not Implemented Yet");
}
@Override
- public List executeFunction(Object appContext, List focus, String functionName,
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName,
List> 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 valerrors = new ArrayList();
if (item instanceof Resource) {
@@ -245,7 +245,7 @@ public boolean conformsToProfile(Object appContext, Base item, String url) throw
}
@Override
- public ValueSet resolveValueSet(Object appContext, String url) {
+ public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
throw new Error("Not Implemented Yet");
}
diff --git a/org.hl7.fhir.r4/src/test/java/org/hl7/fhir/r4/test/FHIRPathTests.java b/org.hl7.fhir.r4/src/test/java/org/hl7/fhir/r4/test/FHIRPathTests.java
index 51e3105ab9..e8bbd622e5 100644
--- a/org.hl7.fhir.r4/src/test/java/org/hl7/fhir/r4/test/FHIRPathTests.java
+++ b/org.hl7.fhir.r4/src/test/java/org/hl7/fhir/r4/test/FHIRPathTests.java
@@ -58,14 +58,14 @@ public enum TestResultType {
public class FHIRPathTestEvaluationServices implements IEvaluationContext {
@Override
- public List resolveConstant(Object appContext, String name, boolean beforeContext)
+ public List 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 boolean log(String argument, List focus) {
}
@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 parameters)
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List parameters)
throws PathEngineException {
throw new NotImplementedException(
"Not done yet (FHIRPathTestEvaluationServices.checkFunction), when item is element");
}
@Override
- public List executeFunction(Object appContext, List focus, String functionName,
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName,
List> 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 boolean conformsToProfile(Object appContext, Base item, String url) throw
}
@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 void resolveConstantReturnsList() {
final String DUMMY_CONSTANT_2 = "dummyConstant2";
fp.setHostServices(new FHIRPathTestEvaluationServices() {
@Override
- public List resolveConstant(Object appContext, String name, boolean beforeContext)
+ public List resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant)
throws PathEngineException {
return Arrays.asList(new StringType(DUMMY_CONSTANT_1).noExtensions(),
diff --git a/org.hl7.fhir.r4/src/test/java/org/hl7/fhir/r4/test/SnapShotGenerationTests.java b/org.hl7.fhir.r4/src/test/java/org/hl7/fhir/r4/test/SnapShotGenerationTests.java
index 3077c83e22..f1a5047788 100644
--- a/org.hl7.fhir.r4/src/test/java/org/hl7/fhir/r4/test/SnapShotGenerationTests.java
+++ b/org.hl7.fhir.r4/src/test/java/org/hl7/fhir/r4/test/SnapShotGenerationTests.java
@@ -300,13 +300,13 @@ else if (p[1].equals("include"))
// FHIRPath methods
@Override
- public List resolveConstant(Object appContext, String name, boolean beforeContext)
+ public List 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 boolean log(String argument, List focus) {
}
@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 parameters)
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List parameters)
throws PathEngineException {
if ("fixture".equals(functionName))
return new TypeDetails(CollectionStatus.SINGLETON, TestingUtilities.context().getResourceNamesAsSet());
@@ -332,7 +332,7 @@ public TypeDetails checkFunction(Object appContext, String functionName, List executeFunction(Object appContext, List focus, String functionName,
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName,
List> parameters) {
if ("fixture".equals(functionName)) {
String id = fp.convertToString(parameters.get(0));
@@ -348,13 +348,13 @@ public List executeFunction(Object appContext, List focus, String fu
}
@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 valerrors = new ArrayList();
if (item instanceof Resource) {
@@ -381,7 +381,7 @@ public StructureDefinition getByUrl(String url) {
}
@Override
- public ValueSet resolveValueSet(Object appContext, String url) {
+ public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
throw new Error("Not implemented yet");
}
diff --git a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/comparison/ComparisonRenderer.java b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/comparison/ComparisonRenderer.java
index 4a355f1b6b..65d4f3d58e 100644
--- a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/comparison/ComparisonRenderer.java
+++ b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/comparison/ComparisonRenderer.java
@@ -14,6 +14,7 @@
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 @@ private String processTemplate(String template, String name, Map v
}
@Override
- public List resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
+ public List resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
@SuppressWarnings("unchecked")
Map vars = (Map) appContext;
List res = new ArrayList<>();
@@ -242,7 +243,7 @@ public List resolveConstant(Object appContext, String name, boolean before
}
@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 vars = (Map) appContext;
Base b = vars.get(name);
@@ -255,34 +256,34 @@ public boolean log(String argument, List focus) {
}
@Override
- public FunctionDetails resolveFunction(String functionName) {
+ public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
return null;
}
@Override
- public TypeDetails checkFunction(Object appContext, String functionName, List parameters)
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List parameters)
throws PathEngineException {
return null;
}
@Override
- public List executeFunction(Object appContext, List focus, String functionName,
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName,
List> 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;
}
diff --git a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/test/utils/TestingUtilities.java b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/test/utils/TestingUtilities.java
index ac718895e9..1940a103a8 100644
--- a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/test/utils/TestingUtilities.java
+++ b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/test/utils/TestingUtilities.java
@@ -5,10 +5,7 @@
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 static String tempFolder(String name) throws IOException {
return path;
}
}
+
+ public static boolean runningAsSurefire() {
+ return "true".equals(System.getProperty("runningAsSurefire") != null ? System.getProperty("runningAsSurefire").toLowerCase(Locale.ENGLISH) : "");
+ }
}
\ No newline at end of file
diff --git a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/FHIRPathEngine.java b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/FHIRPathEngine.java
index ba05b69e66..99cc200f38 100644
--- a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/FHIRPathEngine.java
+++ b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/FHIRPathEngine.java
@@ -152,9 +152,9 @@ public interface IEvaluationContext {
* @return the value of the reference (or null, if it's not valid, though can
* throw an exception if desired)
*/
- public List resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException;
+ public List 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 interface IEvaluationContext {
* @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 interface IEvaluationContext {
* @param parameters
* @return
*/
- public TypeDetails checkFunction(Object appContext, String functionName, List parameters)
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List parameters)
throws PathEngineException;
/**
@@ -190,7 +190,7 @@ public TypeDetails checkFunction(Object appContext, String functionName, List executeFunction(Object appContext, List focus, String functionName,
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName,
List> parameters);
/**
@@ -202,14 +202,14 @@ public List executeFunction(Object appContext, List focus, String fu
* @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 @@ private ExpressionNode parseExpression(FHIRLexer lexer, boolean proximal) throws
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 @@ private List execute(ExecutionContext context, List focus, Expressio
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 @@ private TypeDetails executeType(ExecutionTypeContext context, TypeDetails focus,
} 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 @@ private TypeDetails executeType(ExecutionTypeContext context, TypeDetails focus,
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 @@ private TypeDetails executeType(ExecutionTypeContext context, TypeDetails focus,
}
private List resolveConstant(ExecutionContext context, Base constant, boolean beforeContext,
- ExpressionNode expr) throws PathEngineException {
+ ExpressionNode expr, boolean explicitConstant) throws PathEngineException {
if (constant == null) {
return new ArrayList();
}
@@ -1623,7 +1623,7 @@ private List resolveConstant(ExecutionContext context, Base constant, bool
}
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(Arrays.asList(processDateConstant(context.appInfo, c.getValue().substring(1), expr)));
} else {
@@ -1693,7 +1693,7 @@ private Base processDateConstant(Object appInfo, String value, ExpressionNode ex
}
}
- private List resolveConstant(ExecutionContext context, String s, boolean beforeContext, ExpressionNode expr)
+ private List resolveConstant(ExecutionContext context, String s, boolean beforeContext, ExpressionNode expr, boolean explicitConstant)
throws PathEngineException {
if (s.equals("%sct")) {
return new ArrayList(Arrays.asList(new StringType("http://snomed.info/sct").noExtensions()));
@@ -1727,7 +1727,7 @@ private List resolveConstant(ExecutionContext context, String s, boolean b
} 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 @@ private List opMemberOf(ExecutionContext context, List left, List opMod(List left, List right, ExpressionNode expr)
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 @@ private TypeDetails resolveConstantType(ExecutionTypeContext context, Base const
} 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 @@ private TypeDetails resolveConstantType(ExecutionTypeContext context, Base const
}
}
- 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 @@ private TypeDetails resolveConstantType(ExecutionTypeContext context, String s,
} 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 @@ private List execute(ExecutionContext context, Base item, ExpressionNode e
List result = new ArrayList();
if (atEntry && context.appInfo != null && hostServices != null) {
// we'll see if the name matches a constant known by the context.
- List temp = hostServices.resolveConstant(context.appInfo, exp.getName(), true);
+ List temp = hostServices.resolveConstant(this, context.appInfo, exp.getName(), true, false);
if (!temp.isEmpty()) {
result.addAll(temp);
return result;
@@ -3179,7 +3179,7 @@ private List execute(ExecutionContext context, Base item, ExpressionNode e
// 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 @@ private String getParent(String rn) {
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 @@ private TypeDetails evaluateFunctionType(ExecutionTypeContext context, TypeDetai
}
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 @@ private List evaluateFunction(ExecutionContext context, List focus,
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 @@ private List funcMemberOf(ExecutionContext context, List focus, Expr
}
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();
@@ -5213,7 +5213,7 @@ private List funcResolve(ExecutionContext context, List focus, Expre
}
} 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 @@ private List funcConformsTo(ExecutionContext context, List focus, Ex
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;
}
diff --git a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/LiquidEngine.java b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/LiquidEngine.java
index 5a94f53af3..b07fa8c792 100644
--- a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/LiquidEngine.java
+++ b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/LiquidEngine.java
@@ -738,7 +738,7 @@ private LiquidStatement parseStatement() throws FHIRException {
}
@Override
- public List resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
+ public List 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(Arrays.asList(ctxt.loopVars.get(name)));
@@ -746,15 +746,15 @@ public List resolveConstant(Object appContext, String name, boolean before
return new ArrayList(Arrays.asList(ctxt.globalVars.get(name)));
if (externalHostServices == null)
return new ArrayList();
- 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 boolean log(String argument, List focus) {
}
@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 parameters) throws PathEngineException {
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List 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 executeFunction(Object appContext, List focus, String functionName, List> parameters) {
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName, List> 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);
}
diff --git a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/structuremap/FHIRPathHostServices.java b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/structuremap/FHIRPathHostServices.java
index 76f27269e7..a779f77865 100644
--- a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/structuremap/FHIRPathHostServices.java
+++ b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/structuremap/FHIRPathHostServices.java
@@ -24,7 +24,7 @@ public FHIRPathHostServices(StructureMapUtilities structureMapUtilities) {
this.structureMapUtilities = structureMapUtilities;
}
- public List resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
+ public List 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 List resolveConstant(Object appContext, String name, boolean before
}
@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 boolean log(String argument, List focus) {
}
@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 parameters)
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List parameters)
throws PathEngineException {
throw new Error("Not Implemented Yet");
}
@Override
- public List executeFunction(Object appContext, List focus, String functionName,
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName,
List> 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 @@ private boolean noErrorValidationMessages(List valerrors) {
}
@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 valerrors = new ArrayList();
if (item instanceof Resource) {
@@ -100,7 +100,7 @@ public boolean conformsToProfile(Object appContext, Base item, String url) throw
}
@Override
- public ValueSet resolveValueSet(Object appContext, String url) {
+ public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
throw new Error("Not Implemented Yet");
}
diff --git a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/structuremap/StructureMapUtilities.java b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/structuremap/StructureMapUtilities.java
index bb60ace800..208182c962 100644
--- a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/structuremap/StructureMapUtilities.java
+++ b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/structuremap/StructureMapUtilities.java
@@ -111,7 +111,7 @@ public class ResolvedGroup {
private class FHIRPathHostServices implements IEvaluationContext {
- public List resolveConstant(Object appContext, String name, boolean beforeContext)
+ public List resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant)
throws PathEngineException {
Variables vars = (Variables) appContext;
List list = new ArrayList();
@@ -126,7 +126,7 @@ public List resolveConstant(Object appContext, String name, boolean before
}
@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 boolean log(String argument, List focus) {
}
@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 parameters)
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List parameters)
throws PathEngineException {
throw new Error("Not Implemented Yet");
}
@Override
- public List executeFunction(Object appContext, List focus, String functionName,
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName,
List> 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 valerrors = new ArrayList();
if (item instanceof Resource) {
@@ -181,7 +181,7 @@ public boolean conformsToProfile(Object appContext, Base item, String url) throw
}
@Override
- public ValueSet resolveValueSet(Object appContext, String url) {
+ public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
throw new Error("Not Implemented Yet");
}
diff --git a/org.hl7.fhir.r4b/src/test/java/org/hl7/fhir/r4b/test/FHIRPathTests.java b/org.hl7.fhir.r4b/src/test/java/org/hl7/fhir/r4b/test/FHIRPathTests.java
index b600f79e19..fbb32f2dde 100644
--- a/org.hl7.fhir.r4b/src/test/java/org/hl7/fhir/r4b/test/FHIRPathTests.java
+++ b/org.hl7.fhir.r4b/src/test/java/org/hl7/fhir/r4b/test/FHIRPathTests.java
@@ -44,14 +44,14 @@ public enum TestResultType {
public class FHIRPathTestEvaluationServices implements IEvaluationContext {
@Override
- public List resolveConstant(Object appContext, String name, boolean beforeContext)
+ public List 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 boolean log(String argument, List focus) {
}
@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 parameters)
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List parameters)
throws PathEngineException {
throw new NotImplementedException(
"Not done yet (FHIRPathTestEvaluationServices.checkFunction), when item is element");
}
@Override
- public List executeFunction(Object appContext, List focus, String functionName,
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName,
List> 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 boolean conformsToProfile(Object appContext, Base item, String url) throw
}
@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 void resolveConstantReturnsList() {
final String DUMMY_CONSTANT_2 = "dummyConstant2";
fp.setHostServices(new FHIRPathTestEvaluationServices() {
@Override
- public List resolveConstant(Object appContext, String name, boolean beforeContext)
+ public List resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant)
throws PathEngineException {
return Arrays.asList(new StringType(DUMMY_CONSTANT_1).noExtensions(),
diff --git a/org.hl7.fhir.r4b/src/test/java/org/hl7/fhir/r4b/test/SnapShotGenerationTests.java b/org.hl7.fhir.r4b/src/test/java/org/hl7/fhir/r4b/test/SnapShotGenerationTests.java
index 6ef70764fc..2e3a2b5808 100644
--- a/org.hl7.fhir.r4b/src/test/java/org/hl7/fhir/r4b/test/SnapShotGenerationTests.java
+++ b/org.hl7.fhir.r4b/src/test/java/org/hl7/fhir/r4b/test/SnapShotGenerationTests.java
@@ -368,13 +368,13 @@ else if (p[1].equals("include"))
// FHIRPath methods
@Override
- public List resolveConstant(Object appContext, String name, boolean beforeContext)
+ public List 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 boolean log(String argument, List focus) {
}
@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 parameters)
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List parameters)
throws PathEngineException {
if ("fixture".equals(functionName))
return new TypeDetails(CollectionStatus.SINGLETON, TestingUtilities.context().getResourceNamesAsSet());
@@ -400,7 +400,7 @@ public TypeDetails checkFunction(Object appContext, String functionName, List executeFunction(Object appContext, List focus, String functionName,
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName,
List> parameters) {
if ("fixture".equals(functionName)) {
String id = fp.convertToString(parameters.get(0));
@@ -416,13 +416,13 @@ public List executeFunction(Object appContext, List focus, String fu
}
@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 valerrors = new ArrayList();
if (item instanceof Resource) {
@@ -451,7 +451,7 @@ public StructureDefinition getByUrl(String url) {
}
@Override
- public ValueSet resolveValueSet(Object appContext, String url) {
+ public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
throw new Error("Not implemented yet");
}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/comparison/ComparisonRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/comparison/ComparisonRenderer.java
index 71963825a6..9a3bd18822 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/comparison/ComparisonRenderer.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/comparison/ComparisonRenderer.java
@@ -14,6 +14,7 @@
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 @@ private String processTemplate(String template, String name, Map v
}
@Override
- public List resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
+ public List resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
@SuppressWarnings("unchecked")
Map vars = (Map) appContext;
List res = new ArrayList<>();
@@ -266,7 +267,7 @@ public List resolveConstant(Object appContext, String name, boolean before
}
@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 vars = (Map) appContext;
Base b = vars.get(name);
@@ -279,32 +280,32 @@ public boolean log(String argument, List focus) {
}
@Override
- public FunctionDetails resolveFunction(String functionName) {
+ public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
return null;
}
@Override
- public TypeDetails checkFunction(Object appContext, String functionName, List parameters) throws PathEngineException {
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List parameters) throws PathEngineException {
return null;
}
@Override
- public List executeFunction(Object appContext, List focus, String functionName, List> parameters) {
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName, List> 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;
}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java
index d83f572eaf..7908ebe1b2 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java
@@ -881,7 +881,7 @@ public ValueSetExpansionOutcome expandVS(ValueSet vs, boolean cacheOk, boolean h
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 T fetchResourceWithExceptionByVersion(Class class
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,
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java
index 546dfd9a6b..373d4e32ef 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java
@@ -38,6 +38,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS
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 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS
*
*/
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 extensionList = new HashSet<>(Arrays.asList("extension", "modifierExtension"));
public enum SpecialElement {
@@ -133,6 +160,7 @@ public String toHuman() {
private boolean ignorePropertyOrder;
private FhirFormat format;
private Object nativeObject;
+ private List sliceDefinitions;
public Element(String name) {
super();
@@ -1498,5 +1526,23 @@ public void removeExtension(String url) {
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;
+ }
+
}
\ No newline at end of file
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEBuilder.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEBuilder.java
index 2063a90454..73eddbfc56 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEBuilder.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEBuilder.java
@@ -531,7 +531,7 @@ public IWorkerContext getContext() {
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 {
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java
index f185e127b1..f5dbe05ba5 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java
@@ -37,6 +37,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS
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 List children(boolean allFixed) {
/**
* @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 children, boolean allFixed);
@Override
@@ -290,7 +296,7 @@ protected void setInFixedValue(boolean inFixedValue) {
public boolean isList() {
- return "*".equals(definition.getMax());
+ return "*".equals(definition.getMax()) || (Utilities.parseInt(definition.getMax(), 2) > 1);
}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/BindingStrength.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/BindingStrength.java
new file mode 100644
index 0000000000..6f7d369c9c
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/BindingStrength.java
@@ -0,0 +1,7 @@
+package org.hl7.fhir.r5.profilemodel.gen;
+
+public @interface BindingStrength {
+
+ String value();
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/Definition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/Definition.java
new file mode 100644
index 0000000000..d0febdf886
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/Definition.java
@@ -0,0 +1,7 @@
+package org.hl7.fhir.r5.profilemodel.gen;
+
+public @interface Definition {
+
+ String value();
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/Doco.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/Doco.java
new file mode 100644
index 0000000000..3e30eca7b1
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/Doco.java
@@ -0,0 +1,7 @@
+package org.hl7.fhir.r5.profilemodel.gen;
+
+public @interface Doco {
+
+ String value();
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/Label.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/Label.java
new file mode 100644
index 0000000000..0b8fa2d6fc
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/Label.java
@@ -0,0 +1,7 @@
+package org.hl7.fhir.r5.profilemodel.gen;
+
+public @interface Label {
+
+ String value();
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/Max.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/Max.java
new file mode 100644
index 0000000000..94425bcb2a
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/Max.java
@@ -0,0 +1,7 @@
+package org.hl7.fhir.r5.profilemodel.gen;
+
+public @interface Max {
+
+ String value();
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/Min.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/Min.java
new file mode 100644
index 0000000000..0bfc78835a
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/Min.java
@@ -0,0 +1,7 @@
+package org.hl7.fhir.r5.profilemodel.gen;
+
+public @interface Min {
+
+ String value();
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/MustSupport.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/MustSupport.java
new file mode 100644
index 0000000000..02284f8bd9
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/MustSupport.java
@@ -0,0 +1,7 @@
+package org.hl7.fhir.r5.profilemodel.gen;
+
+public @interface MustSupport {
+
+ boolean value();
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/PECodeGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/PECodeGenerator.java
index 8c0e2f224c..e8e4d50b7c 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/PECodeGenerator.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/PECodeGenerator.java
@@ -33,22 +33,30 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS
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 @@ private class PEGenClass {
private String doco;
private String url;
private boolean isResource;
+ private Set unfixed = new HashSet<>();
+ private Set 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 @@ private class PEGenClass {
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 void write(StringBuilder b, String copyright) {
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 void write(StringBuilder b, String copyright) {
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 void write(StringBuilder b, String copyright) {
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 @@ private void defineField(PEDefinition source, PEDefinition field) {
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 @@ private void defineField(PEDefinition source, PEDefinition field) {
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 @@ private void genClear(boolean list, String name) {
}
}
- 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 @@ private void genLoad(boolean isPrim, boolean isAbstract, String name, String sna
}
}
- 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 @@ private void genSave(boolean isPrim, boolean isAbstract, String name, String sna
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 @@ private void genSave(boolean isPrim, boolean isAbstract, String name, String sna
}
}
- 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 @@ private void genAccessors(boolean isPrim, boolean isAbstract, String name, Strin
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 @@ private void genField(boolean isPrim, String name, String ptype, String ltype, S
} 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 void setGenDate(String genDate) {
*
*/
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 void execute() throws IOException {
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+";");
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/ValueSet.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/ValueSet.java
new file mode 100644
index 0000000000..5d54f3b79c
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/ValueSet.java
@@ -0,0 +1,7 @@
+package org.hl7.fhir.r5.profilemodel.gen;
+
+public @interface ValueSet {
+
+ String value();
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/CodeSystemUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/CodeSystemUtilities.java
index a3a2514142..aa5074afc6 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/CodeSystemUtilities.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/CodeSystemUtilities.java
@@ -70,7 +70,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS
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;
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyUtilities.java
new file mode 100644
index 0000000000..6dc1a7c9d6
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyUtilities.java
@@ -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 listOids(CanonicalResource cr) {
+ Set 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;
+ }
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetUtilities.java
index 7edcff5415..87511c494a 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetUtilities.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetUtilities.java
@@ -3,7 +3,9 @@
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 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS
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 @@ private static int countExpansion(ValueSetExpansionContainsComponent c) {
return i;
}
+ public static Set listSystems(IWorkerContext ctxt, ValueSet vs) {
+ Set 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;
+ }
}
\ No newline at end of file
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/test/utils/TestingUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/test/utils/TestingUtilities.java
index 1039d3b73a..42a61d2081 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/test/utils/TestingUtilities.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/test/utils/TestingUtilities.java
@@ -4,6 +4,7 @@
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 static void injectCorePackageLoader() {
FilesystemPackageCacheManager.setPackageProvider(new TestingUtilities.PackageProvider());
}
-
+ public static boolean runningAsSurefire() {
+ return "true".equals(System.getProperty("runningAsSurefire") != null ? System.getProperty("runningAsSurefire").toLowerCase(Locale.ENGLISH) : "");
+ }
}
\ No newline at end of file
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java
index 5def56759c..3c89a1901e 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java
@@ -153,8 +153,8 @@ public interface IEvaluationContext {
* @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 resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException;
- public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException;
+ public List 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 interface IEvaluationContext {
* @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 interface IEvaluationContext {
* @param parameters
* @return
*/
- public TypeDetails checkFunction(Object appContext, String functionName, List parameters) throws PathEngineException;
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List parameters) throws PathEngineException;
/**
* @param appContext
@@ -187,7 +187,7 @@ public interface IEvaluationContext {
* @param parameters
* @return
*/
- public List executeFunction(Object appContext, List focus, String functionName, List> parameters);
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName, List> parameters);
/**
* Implementation of resolve() function. Passed a string, return matching resource, if one is known - else null
@@ -196,14 +196,14 @@ public interface IEvaluationContext {
* @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 @@ private ExpressionNode parseExpression(FHIRLexer lexer, boolean proximal) throws
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 @@ private TypeDetails executeType(ExecutionTypeContext context, TypeDetails focus,
} 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 @@ private TypeDetails executeType(ExecutionTypeContext context, TypeDetails focus,
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 @@ private List resolveConstant(ExecutionContext context, Base constant, bool
}
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(Arrays.asList(processDateConstant(context.appInfo, c.getValue().substring(1), expr)));
} else {
@@ -1683,7 +1683,7 @@ private Base processDateConstant(Object appInfo, String value, ExpressionNode ex
}
- private List resolveConstant(ExecutionContext context, String s, boolean beforeContext, ExpressionNode expr) throws PathEngineException {
+ private List resolveConstant(ExecutionContext context, String s, boolean beforeContext, ExpressionNode expr, boolean explicitConstant) throws PathEngineException {
if (s.equals("%sct")) {
return new ArrayList(Arrays.asList(new StringType("http://snomed.info/sct").noExtensions()));
} else if (s.equals("%loinc")) {
@@ -1713,7 +1713,7 @@ private List resolveConstant(ExecutionContext context, String s, boolean b
} 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 @@ private List opGreaterOrEqual(List left, List right, Expressio
private List opMemberOf(ExecutionContext context, List left, List 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 @@ private List opMod(List left, List right, ExpressionNode expr)
}
- 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 @@ private TypeDetails resolveConstantType(ExecutionTypeContext context, Base const
} 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 @@ private TypeDetails resolveConstantType(ExecutionTypeContext context, Base const
}
}
- 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 @@ private TypeDetails resolveConstantType(ExecutionTypeContext context, String s,
} 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 @@ private List execute(ExecutionContext context, Base item, ExpressionNode e
List result = new ArrayList();
if (atEntry && context.appInfo != null && hostServices != null) {
// we'll see if the name matches a constant known by the context.
- List temp = hostServices.resolveConstant(context.appInfo, exp.getName(), true);
+ List temp = hostServices.resolveConstant(this, context.appInfo, exp.getName(), true, false);
if (!temp.isEmpty()) {
result.addAll(temp);
return result;
@@ -3123,7 +3123,7 @@ private List execute(ExecutionContext context, Base item, ExpressionNode e
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 @@ private String getParent(String rn) {
}
- 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 elementDependencies) throws PathEngineException, DefinitionException {
@@ -3585,7 +3585,7 @@ private TypeDetails evaluateFunctionType(ExecutionTypeContext context, TypeDetai
}
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 @@ private void checkOrdered(TypeDetails focus, String name, ExpressionNode expr) t
}
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 @@ private List evaluateFunction(ExecutionContext context, List focus,
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 @@ private List funcMemberOf(ExecutionContext context, List focus, Expr
}
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();
}
@@ -5108,7 +5108,7 @@ private List funcResolve(ExecutionContext context, List focus, Expre
}
} 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 @@ private List funcConformsTo(ExecutionContext context, List focus, Ex
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;
}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/LiquidEngine.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/LiquidEngine.java
index 32ba081b9a..091491246a 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/LiquidEngine.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/LiquidEngine.java
@@ -741,7 +741,7 @@ private LiquidStatement parseStatement() throws FHIRException {
}
@Override
- public List resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
+ public List 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(Arrays.asList(ctxt.loopVars.get(name)));
@@ -749,15 +749,15 @@ public List resolveConstant(Object appContext, String name, boolean before
return new ArrayList(Arrays.asList(ctxt.globalVars.get(name)));
if (externalHostServices == null)
return new ArrayList();
- 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 boolean log(String argument, List focus) {
}
@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 parameters) throws PathEngineException {
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List 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 executeFunction(Object appContext, List focus, String functionName, List> parameters) {
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName, List> 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);
}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ResourceSorters.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ResourceSorters.java
index 81ad8906fc..fa9608a6b8 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ResourceSorters.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ResourceSorters.java
@@ -10,7 +10,13 @@ public static class CanonicalResourceSortByUrl implements Comparator cells, String columnName) {
}
@Override
- public List resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
+ public List 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 boolean log(String argument, List focus) {
}
@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 FunctionDetails resolveFunction(String functionName) {
}
}
@Override
- public TypeDetails checkFunction(Object appContext, String functionName, List parameters) throws PathEngineException {
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List 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 TypeDetails checkFunction(Object appContext, String functionName, List executeFunction(Object appContext, List focus, String functionName, List> parameters) {
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName, List> parameters) {
switch (functionName) {
case "getResourceKey" : return executeResourceKey(focus);
case "getReferenceKey" : return executeReferenceKey(focus, parameters);
@@ -420,17 +420,17 @@ private String getRef(Base res) {
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
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/structuremap/FHIRPathHostServices.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/structuremap/FHIRPathHostServices.java
index 678d2b3579..fce5c072c7 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/structuremap/FHIRPathHostServices.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/structuremap/FHIRPathHostServices.java
@@ -24,7 +24,7 @@ public FHIRPathHostServices(StructureMapUtilities structureMapUtilities) {
this.structureMapUtilities = structureMapUtilities;
}
- public List resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
+ public List 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 List resolveConstant(Object appContext, String name, boolean before
}
@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 boolean log(String argument, List focus) {
}
@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 parameters) throws PathEngineException {
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List parameters) throws PathEngineException {
throw new Error("Not Implemented Yet");
}
@Override
- public List executeFunction(Object appContext, List focus, String functionName, List> parameters) {
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName, List> 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 @@ private boolean noErrorValidationMessages(List valerrors) {
}
@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 valerrors = new ArrayList();
if (item instanceof Resource) {
@@ -96,7 +96,7 @@ public boolean conformsToProfile(Object appContext, Base item, String url) throw
}
@Override
- public ValueSet resolveValueSet(Object appContext, String url) {
+ public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
return structureMapUtilities.getWorker().fetchResource(ValueSet.class, url);
}
diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/PETests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/PETests.java
index 61a9cff730..0812934fcf 100644
--- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/PETests.java
+++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/PETests.java
@@ -112,7 +112,7 @@ public void testProfile() throws IOException {
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 @@ private void checkElement(PEDefinition pe, String schemaName, String name, int m
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());
diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestComplexExtension.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestComplexExtension.java
index 066eb76c62..0786a662b3 100644
--- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestComplexExtension.java
+++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestComplexExtension.java
@@ -12,33 +12,17 @@
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 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 slice2s = new ArrayList<>(); // More Details
+
+ @Min("1") @Max("1") @Doco("Justification Details")
+ @MustSupport(true)
+ @Definition("Justification Details.")
private Extension slice3;// @NotNull // Justification Details
/**
diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestDatatypeProfile.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestDatatypeProfile.java
index acdad868a7..630c49383b 100644
--- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestDatatypeProfile.java
+++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestDatatypeProfile.java
@@ -12,21 +12,17 @@
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;
+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: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
diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestProfile.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestProfile.java
index 996cb0d07f..9e7edde7a8 100644
--- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestProfile.java
+++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestProfile.java
@@ -24,9 +24,23 @@
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 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 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 TestProfile() {
*
*/
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 void load(PEInstance src) {
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 void save(PEInstance tgt, boolean nulls) {
}
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 void save(PEInstance tgt, boolean nulls) {
}
+ private void initFixedValues() {
+ status = "final";
+
+ }
+
/**
* Test Observation Profile.
*
@@ -309,13 +440,25 @@ public String getStatus() {
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 void clear() {
complex = null;
identifier = null;
status = null;
+ category = null;
code = null;
subject = null;
encounter = null;
diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/FHIRPathTests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/FHIRPathTests.java
index b82d84db92..88de6464e1 100644
--- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/FHIRPathTests.java
+++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/FHIRPathTests.java
@@ -46,12 +46,12 @@ public enum TestResultType {OK, SYNTAX, SEMANTICS, EXECUTION}
public class FHIRPathTestEvaluationServices implements IEvaluationContext {
@Override
- public List resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
+ public List 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 boolean log(String argument, List focus) {
}
@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 parameters) throws PathEngineException {
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List parameters) throws PathEngineException {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.checkFunction), when item is element");
}
@Override
- public List executeFunction(Object appContext, List focus, String functionName, List> parameters) {
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName, List> 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 boolean conformsToProfile(Object appContext, Base item, String url) throw
}
@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 void resolveConstantReturnsList() {
final String DUMMY_CONSTANT_2 = "dummyConstant2";
fp.setHostServices(new FHIRPathTestEvaluationServices() {
@Override
- public List resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
+ public List resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
return Arrays.asList(
new StringType(DUMMY_CONSTANT_1).noExtensions(),
diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/SnapShotGenerationTests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/SnapShotGenerationTests.java
index d089a373d4..4288d2822b 100644
--- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/SnapShotGenerationTests.java
+++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/SnapShotGenerationTests.java
@@ -337,12 +337,12 @@ else if (p[1].equals("include"))
// FHIRPath methods
@Override
- public List resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
+ public List 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 boolean log(String argument, List focus) {
}
@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 parameters) throws PathEngineException {
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List parameters) throws PathEngineException {
if ("fixture".equals(functionName))
return new TypeDetails(CollectionStatus.SINGLETON, TestingUtilities.getSharedWorkerContext().getResourceNamesAsSet());
return null;
}
@Override
- public List executeFunction(Object appContext, List focus, String functionName, List> parameters) {
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName, List> parameters) {
if ("fixture".equals(functionName)) {
String id = fp.convertToString(parameters.get(0));
Resource res = fetchFixture(id);
@@ -382,13 +382,13 @@ public List executeFunction(Object appContext, List focus, String fu
}
@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 valerrors = new ArrayList();
if (item instanceof Resource) {
@@ -416,7 +416,7 @@ public StructureDefinition getByUrl(String url) {
}
@Override
- public ValueSet resolveValueSet(Object appContext, String url) {
+ public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
throw new Error("Not implemented yet");
}
diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/utils/structuremap/FHIRPathHostServicesTest.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/utils/structuremap/FHIRPathHostServicesTest.java
index d0766fb4c4..5bb2b8a802 100644
--- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/utils/structuremap/FHIRPathHostServicesTest.java
+++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/utils/structuremap/FHIRPathHostServicesTest.java
@@ -24,7 +24,7 @@ static public void setUp() throws Exception {
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());
}
diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/Utilities.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/Utilities.java
index c98e2adc10..43cd93f757 100644
--- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/Utilities.java
+++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/Utilities.java
@@ -109,6 +109,12 @@ public static String pluralize(String word, int count) {
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 @@ else if (e.toString().equals("mu"))
return b.toString();
}
+
+
public static String unescapeJson(String json) throws FHIRException {
if (json == null)
return null;
@@ -991,6 +999,23 @@ public static boolean isURL(String s) {
}
+ 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 "";
diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java
index a8c2467750..bc66ea8869 100644
--- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java
+++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java
@@ -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";
diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java
index fbd90c707f..35c4d63e06 100644
--- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java
+++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java
@@ -275,16 +275,23 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
private class ValidatorHostServices implements IEvaluationContext {
@Override
- public List resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
+ public List resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
ValidationContext c = (ValidationContext) appContext;
+ if ("profile".equals(name) && explicitConstant) {
+ List 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();
}
@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 TypeDetails resolveConstantType(Object appContext, String name) throws Pa
}
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 boolean log(String argument, List focus) {
}
@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 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 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 executeFunction(Object appContext, List focus, String functionName, List> parameters) {
- throw new Error(context.formatMessage(I18nConstants.NOT_DONE_YET_VALIDATORHOSTSERVICESEXECUTEFUNCTION));
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName, List> parameters) {
+ switch (functionName) {
+ case "slice": return executeSlice(engine, appContext, focus, parameters);
+ default: throw new Error(context.formatMessage(I18nConstants.NOT_DONE_YET_VALIDATORHOSTSERVICESEXECUTEFUNCTION));
+ }
+ }
+
+ private List executeSlice(FHIRPathEngine engine, Object appContext, List focus, List> parameters) {
+ ValidationContext c = (ValidationContext) appContext;
+
+ List 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 Base resolveReference(Object appContext, String url, Base refContext) thr
}
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 Base resolveReference(Object appContext, String url, Base refContext) thr
@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 boolean conformsToProfile(Object appContext, Base item, String url) throw
}
@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 @@ private boolean validateElement(ValidationContext valContext, List 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 @@ private boolean validateElement(ValidationContext valContext, List templates = element.getChildren("templateId");
@@ -6694,7 +6759,9 @@ public boolean checkInvariant(ValidationContext valContext, List resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
+ public List 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 boolean log(String argument, List focus) {
}
@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 parameters) throws PathEngineException {
+ public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List parameters) throws PathEngineException {
if ("fixture".equals(functionName))
return new TypeDetails(CollectionStatus.SINGLETON, UtilitiesXTests.context(version).getResourceNamesAsSet());
return null;
}
@Override
- public List executeFunction(Object appContext, List focus, String functionName, List> parameters) {
+ public List executeFunction(FHIRPathEngine engine, Object appContext, List focus, String functionName, List> parameters) {
if ("fixture".equals(functionName)) {
String id = fp.convertToString(parameters.get(0));
Resource res = fetchFixture(id);
@@ -361,13 +361,13 @@ public List executeFunction(Object appContext, List focus, String fu
}
@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 valerrors = new ArrayList();
if (item instanceof Resource) {
@@ -393,7 +393,7 @@ public StructureDefinition getByUrl(String url) {
}
@Override
- public ValueSet resolveValueSet(Object appContext, String url) {
+ public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
throw new Error("Not implemented yet");
}
diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/LocalTerminologyServiceTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/LocalTerminologyServiceTests.java
index 91db02a4c6..23e6c263c2 100644
--- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/LocalTerminologyServiceTests.java
+++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/LocalTerminologyServiceTests.java
@@ -4,11 +4,7 @@
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.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 com.google.common.base.Charsets;
@RunWith(Parameterized.class)
-@EnabledIf("localTxRunning")
-@Disabled
+
public class LocalTerminologyServiceTests implements ITxTesterLoader {
public static class JsonObjectPair {
@@ -60,6 +53,8 @@ private static boolean localTxRunning() {
return new File("/Users/grahamegrieve/work/server/serverx").exists();
}
+
+
@Parameters(name = "{index}: id {0}")
public static Iterable