fix decimal validation + fix profile slicing validation

This commit is contained in:
Grahame Grieve 2019-07-30 16:22:54 +10:00
parent f9a06ae2b8
commit fe219985b4
30 changed files with 683 additions and 135 deletions

View File

@ -959,7 +959,7 @@ public class ArgonautConverter extends ConverterBase {
obs.setStatus(ObservationStatus.FINAL);
obs.setEffective(convert.makeDateTimeFromTS(cda.getChild(o, "effectiveTime")));
String v = cda.getChild(o, "value").getAttribute("value");
if (!Utilities.isDecimal(v)) {
if (!Utilities.isDecimal(v, true)) {
obs.setDataAbsentReason(inspectCode(new CodeableConcept().setText(v), null));
} else
obs.setValue(convert.makeQuantityFromPQ(cda.getChild(o, "value")));
@ -1059,7 +1059,7 @@ public class ArgonautConverter extends ConverterBase {
} else if ("PQ".equals(type)) {
obs.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/observation-daf-results-dafresultobsquantity");
String va = cda.getChild(o, "value").getAttribute("value");
if (!Utilities.isDecimal(va)) {
if (!Utilities.isDecimal(va, true)) {
obs.setDataAbsentReason(inspectCode(new CodeableConcept().setText(va), null));
} else
obs.setValue(convert.makeQuantityFromPQ(cda.getChild(o, "value"), null));

View File

@ -945,7 +945,7 @@ public class FHIRPathEngine {
return null;
} else if (Utilities.isInteger(constant)) {
return new IntegerType(constant);
} else if (Utilities.isDecimal(constant)) {
} else if (Utilities.isDecimal(constant, false)) {
return new DecimalType(constant);
} else if (constant.startsWith("\'")) {
return new StringType(processConstantString(constant));
@ -1663,7 +1663,7 @@ public class FHIRPathEngine {
return "boolean";
else if (Utilities.isInteger(constant))
return "integer";
else if (Utilities.isDecimal(constant))
else if (Utilities.isDecimal(constant, false))
return "decimal";
else if (constant.startsWith("%"))
return resolveConstantType(context, constant);
@ -2134,7 +2134,7 @@ public class FHIRPathEngine {
private List<Base> funcToDecimal(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
String s = convertToString(focus);
List<Base> result = new ArrayList<Base>();
if (Utilities.isDecimal(s))
if (Utilities.isDecimal(s, true))
result.add(new DecimalType(s));
return result;
}

View File

@ -918,7 +918,7 @@ public class FHIRPathEngine {
return null;
} else if (Utilities.isInteger(constant)) {
return new IntegerType(constant);
} else if (Utilities.isDecimal(constant)) {
} else if (Utilities.isDecimal(constant, false)) {
return new DecimalType(constant);
} else if (constant.startsWith("\'")) {
return new StringType(processConstantString(constant));
@ -1633,7 +1633,7 @@ public class FHIRPathEngine {
return "boolean";
else if (Utilities.isInteger(constant))
return "integer";
else if (Utilities.isDecimal(constant))
else if (Utilities.isDecimal(constant, false))
return "decimal";
else if (constant.startsWith("%"))
return resolveConstantType(context, constant);
@ -2100,7 +2100,7 @@ public class FHIRPathEngine {
private List<Base> funcToDecimal(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
String s = convertToString(focus);
List<Base> result = new ArrayList<Base>();
if (Utilities.isDecimal(s))
if (Utilities.isDecimal(s, true))
result.add(new DecimalType(s));
return result;
}

View File

@ -654,7 +654,7 @@ public class StructureMapUtilities {
private Type readConstant(String s, FHIRLexer lexer) throws FHIRLexerException {
if (Utilities.isInteger(s))
return new IntegerType(s);
else if (Utilities.isDecimal(s))
else if (Utilities.isDecimal(s, false))
return new DecimalType(s);
else if (Utilities.existsInList(s, "true", "false"))
return new BooleanType(s.equals("true"));

View File

@ -1006,7 +1006,7 @@ public class FHIRPathEngine {
return null;
} else if (Utilities.isInteger(constant)) {
return new IntegerType(constant);
} else if (Utilities.isDecimal(constant)) {
} else if (Utilities.isDecimal(constant, false)) {
return new DecimalType(constant);
} else if (constant.startsWith("\'")) {
return new StringType(processConstantString(constant));
@ -1725,7 +1725,7 @@ public class FHIRPathEngine {
return new TypeDetails(CollectionStatus.SINGLETON, "boolean");
else if (Utilities.isInteger(constant))
return new TypeDetails(CollectionStatus.SINGLETON, "integer");
else if (Utilities.isDecimal(constant))
else if (Utilities.isDecimal(constant, false))
return new TypeDetails(CollectionStatus.SINGLETON, "decimal");
else if (constant.startsWith("%"))
return resolveConstantType(context, constant);
@ -2266,7 +2266,7 @@ public class FHIRPathEngine {
private List<Base> funcToDecimal(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
String s = convertToString(focus);
List<Base> result = new ArrayList<Base>();
if (Utilities.isDecimal(s))
if (Utilities.isDecimal(s, true))
result.add(new DecimalType(s));
return result;
}

View File

@ -1078,7 +1078,7 @@ public class StructureMapUtilities {
private Type readConstant(String s, FHIRLexer lexer) throws FHIRLexerException {
if (Utilities.isInteger(s))
return new IntegerType(s);
else if (Utilities.isDecimal(s))
else if (Utilities.isDecimal(s, false))
return new DecimalType(s);
else if (Utilities.existsInList(s, "true", "false"))
return new BooleanType(s.equals("true"));

View File

@ -1176,7 +1176,7 @@ public class Turtle {
int sl = lexer.startLine;
int sc = lexer.startCol;
String pfx = lexer.peekType() == LexerTokenType.WORD ? lexer.word() : null;
if (Utilities.isDecimal(pfx) && !lexer.peek(LexerTokenType.TOKEN, ":")) {
if (Utilities.isDecimal(pfx, true) && !lexer.peek(LexerTokenType.TOKEN, ":")) {
TTLLiteral u = new TTLLiteral(sl, sc);
u.value = pfx;
result.addPredicate(uri, u);

View File

@ -995,7 +995,7 @@ public class FHIRPathEngine {
return new StringType(processConstantString(lexer.take(), lexer)).noExtensions();
} else if (Utilities.isInteger(lexer.getCurrent())) {
return new IntegerType(lexer.take()).noExtensions();
} else if (Utilities.isDecimal(lexer.getCurrent())) {
} else if (Utilities.isDecimal(lexer.getCurrent(), false)) {
return new DecimalType(lexer.take()).noExtensions();
} else if (Utilities.existsInList(lexer.getCurrent(), "true", "false")) {
return new BooleanType(lexer.take()).noExtensions();
@ -2980,7 +2980,7 @@ public class FHIRPathEngine {
private List<Base> funcToDecimal(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
String s = convertToString(focus);
List<Base> result = new ArrayList<Base>();
if (Utilities.isDecimal(s))
if (Utilities.isDecimal(s, true))
result.add(new DecimalType(s).noExtensions());
if ("true".equals(s))
result.add(new DecimalType(1).noExtensions());
@ -3716,7 +3716,7 @@ public class FHIRPathEngine {
if (s.contains(" ")) {
String v = s.substring(0, s.indexOf(" ")).trim();
s = s.substring(s.indexOf(" ")).trim();
if (!Utilities.isDecimal(v))
if (!Utilities.isDecimal(v, false))
return null;
if (s.startsWith("'") && s.endsWith("'"))
return Quantity.fromUcum(v, s.substring(1, s.length()-1));
@ -3739,7 +3739,7 @@ public class FHIRPathEngine {
else
return null;
} else {
if (Utilities.isDecimal(s))
if (Utilities.isDecimal(s, false))
return new Quantity().setValue(new BigDecimal(s)).setSystem("http://unitsofmeasure.org").setCode("1");
else
return null;
@ -3758,7 +3758,7 @@ public class FHIRPathEngine {
else if (focus.get(0) instanceof DecimalType)
result.add(new BooleanType(true).noExtensions());
else if (focus.get(0) instanceof StringType)
result.add(new BooleanType(Utilities.isDecimal(convertToString(focus.get(0)))).noExtensions());
result.add(new BooleanType(Utilities.isDecimal(convertToString(focus.get(0)), true)).noExtensions());
else
result.add(new BooleanType(false).noExtensions());
return result;
@ -4241,7 +4241,7 @@ public class FHIRPathEngine {
return Equality.False;
else if (Utilities.isInteger(item.primitiveValue()))
return asBoolFromInt(item.primitiveValue());
else if (Utilities.isDecimal(item.primitiveValue()))
else if (Utilities.isDecimal(item.primitiveValue(), false))
return asBoolFromDec(item.primitiveValue());
else
return Equality.Null;

View File

@ -1194,7 +1194,7 @@ public class StructureMapUtilities {
private Type readConstant(String s, FHIRLexer lexer) throws FHIRLexerException {
if (Utilities.isInteger(s))
return new IntegerType(s);
else if (Utilities.isDecimal(s))
else if (Utilities.isDecimal(s, true))
return new DecimalType(s);
else if (Utilities.existsInList(s, "true", "false"))
return new BooleanType(s.equals("true"));

View File

@ -1176,7 +1176,7 @@ public class Turtle {
int sl = lexer.startLine;
int sc = lexer.startCol;
String pfx = lexer.peekType() == LexerTokenType.WORD ? lexer.word() : null;
if (Utilities.isDecimal(pfx) && !lexer.peek(LexerTokenType.TOKEN, ":")) {
if (Utilities.isDecimal(pfx, true) && !lexer.peek(LexerTokenType.TOKEN, ":")) {
TTLLiteral u = new TTLLiteral(sl, sc);
u.value = pfx;
result.addPredicate(uri, u);

View File

@ -1,13 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/test/java" output="target/test-classes" including="**/*.java"/>
<classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
<classpathentry kind="src" path="src/main/java" including="**/*.java"/>
<classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
<classpathentry kind="output" path="target/classes"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="test" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar" sourcepath="M2_REPO/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0-sources.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="var" path="M2_REPO/ca/uhn/hapi/fhir/org.hl7.fhir.utilities/3.8.12-SNAPSHOT/org.hl7.fhir.utilities-3.8.12-SNAPSHOT.jar" sourcepath="M2_REPO/ca/uhn/hapi/fhir/org.hl7.fhir.utilities/3.8.12-SNAPSHOT/org.hl7.fhir.utilities-3.8.12-SNAPSHOT-sources.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/ca/uhn/hapi/fhir/hapi-fhir-base/4.0.0-SNAPSHOT/hapi-fhir-base-4.0.0-SNAPSHOT.jar" sourcepath="M2_REPO/ca/uhn/hapi/fhir/hapi-fhir-base/4.0.0-SNAPSHOT/hapi-fhir-base-4.0.0-SNAPSHOT-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/com/google/code/gson/gson/2.8.5/gson-2.8.5.jar" sourcepath="M2_REPO/com/google/code/gson/gson/2.8.5/gson-2.8.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/apache/commons/commons-lang3/3.8.1/commons-lang3-3.8.1.jar" sourcepath="M2_REPO/org/apache/commons/commons-lang3/3.8.1/commons-lang3-3.8.1-sources.jar"/>
@ -55,4 +77,10 @@
<classpathentry kind="var" path="M2_REPO/net/bytebuddy/byte-buddy/1.9.3/byte-buddy-1.9.3.jar" sourcepath="M2_REPO/net/bytebuddy/byte-buddy/1.9.3/byte-buddy-1.9.3-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/net/bytebuddy/byte-buddy-agent/1.9.3/byte-buddy-agent-1.9.3.jar" sourcepath="M2_REPO/net/bytebuddy/byte-buddy-agent/1.9.3/byte-buddy-agent-1.9.3-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/objenesis/objenesis/2.6/objenesis-2.6.jar" sourcepath="M2_REPO/org/objenesis/objenesis/2.6/objenesis-2.6-sources.jar"/>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -2,13 +2,22 @@
<projectDescription>
<name>org.hl7.fhir.r5</name>
<comment>An open-source implementation of the FHIR specification in Java. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment>
<projects/>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -1876,7 +1876,7 @@ public class ProfileUtilities extends TranslatingUtilities {
if (tt == null && td.getCodeElement().hasExtension(ToolingExtensions.EXT_JSON_TYPE))
tt = "*"; //
b.append(tt);
if (td.hasCode() && (t.equals(tt) || "Extension".equals(tt) ||
if (td.hasCode() && (tt.equals(t) || "Extension".equals(tt) ||
"Element".equals(tt) || "*".equals(tt) ||
(("Resource".equals(tt) || ("DomainResource".equals(tt)) && pkp.isResource(t)))))
ok = true;

View File

@ -1002,7 +1002,7 @@ public class FHIRPathEngine {
return new StringType(processConstantString(lexer.take(), lexer)).noExtensions();
} else if (Utilities.isInteger(lexer.getCurrent())) {
return new IntegerType(lexer.take()).noExtensions();
} else if (Utilities.isDecimal(lexer.getCurrent())) {
} else if (Utilities.isDecimal(lexer.getCurrent(), false)) {
return new DecimalType(lexer.take()).noExtensions();
} else if (Utilities.existsInList(lexer.getCurrent(), "true", "false")) {
return new BooleanType(lexer.take()).noExtensions();
@ -2993,7 +2993,7 @@ public class FHIRPathEngine {
private List<Base> funcToDecimal(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
String s = convertToString(focus);
List<Base> result = new ArrayList<Base>();
if (Utilities.isDecimal(s))
if (Utilities.isDecimal(s, true))
result.add(new DecimalType(s).noExtensions());
if ("true".equals(s))
result.add(new DecimalType(1).noExtensions());
@ -3739,7 +3739,7 @@ public class FHIRPathEngine {
if (s.contains(" ")) {
String v = s.substring(0, s.indexOf(" ")).trim();
s = s.substring(s.indexOf(" ")).trim();
if (!Utilities.isDecimal(v))
if (!Utilities.isDecimal(v, false))
return null;
if (s.startsWith("'") && s.endsWith("'"))
return Quantity.fromUcum(v, s.substring(1, s.length()-1));
@ -3762,7 +3762,7 @@ public class FHIRPathEngine {
else
return null;
} else {
if (Utilities.isDecimal(s))
if (Utilities.isDecimal(s, true))
return new Quantity().setValue(new BigDecimal(s)).setSystem("http://unitsofmeasure.org").setCode("1");
else
return null;
@ -3781,7 +3781,7 @@ public class FHIRPathEngine {
else if (focus.get(0) instanceof DecimalType)
result.add(new BooleanType(true).noExtensions());
else if (focus.get(0) instanceof StringType)
result.add(new BooleanType(Utilities.isDecimal(convertToString(focus.get(0)))).noExtensions());
result.add(new BooleanType(Utilities.isDecimal(convertToString(focus.get(0)), true)).noExtensions());
else
result.add(new BooleanType(false).noExtensions());
return result;
@ -4182,7 +4182,7 @@ public class FHIRPathEngine {
}
if (focus == null)
throw new DefinitionException("Unable to resolve discriminator: "+expr.toString());
throw new DefinitionException("Unable to resolve discriminator in definitions: "+expr.toString());
else if (expr.getInner() == null)
return focus;
else {
@ -4222,7 +4222,8 @@ public class FHIRPathEngine {
return true;
else if (t.getType().size() == 1 && t.getType().get(0).getCode() != null && t.getPath() != null && t.getPath().toUpperCase().endsWith(t.getType().get(0).getCode().toUpperCase()))
return tail.startsWith(d);
else if (t.getPath().endsWith("[x]") && tail.startsWith(d))
return true;
return false;
}
@ -4287,7 +4288,7 @@ public class FHIRPathEngine {
return Equality.False;
else if (Utilities.isInteger(item.primitiveValue()))
return asBoolFromInt(item.primitiveValue());
else if (Utilities.isDecimal(item.primitiveValue()))
else if (Utilities.isDecimal(item.primitiveValue(), true))
return asBoolFromDec(item.primitiveValue());
else
return Equality.Null;

View File

@ -1202,7 +1202,7 @@ public class StructureMapUtilities {
private Type readConstant(String s, FHIRLexer lexer) throws FHIRLexerException {
if (Utilities.isInteger(s))
return new IntegerType(s);
else if (Utilities.isDecimal(s))
else if (Utilities.isDecimal(s, false))
return new DecimalType(s);
else if (Utilities.existsInList(s, "true", "false"))
return new BooleanType(s.equals("true"));

View File

@ -1176,7 +1176,7 @@ public class Turtle {
int sl = lexer.startLine;
int sc = lexer.startCol;
String pfx = lexer.peekType() == LexerTokenType.WORD ? lexer.word() : null;
if (Utilities.isDecimal(pfx) && !lexer.peek(LexerTokenType.TOKEN, ":")) {
if (Utilities.isDecimal(pfx, true) && !lexer.peek(LexerTokenType.TOKEN, ":")) {
TTLLiteral u = new TTLLiteral(sl, sc);
u.value = pfx;
result.addPredicate(uri, u);

View File

@ -123,13 +123,22 @@ public class Utilities {
if (isBlank(string)) {
return false;
}
if (string.startsWith("-"))
string = string.substring(1);
for (char next : string.toCharArray()) {
String value = string.startsWith("-") ? string.substring(1) : string;
for (char next : value.toCharArray()) {
if (!Character.isDigit(next)) {
return false;
}
}
// check bounds -2,147,483,648..2,147,483,647
if (value.length() > 10)
return false;
if (string.startsWith("-")) {
if (value.length() == 10 && string.compareTo("2147483648") > 0)
return false;
} else {
if (value.length() == 10 && string.compareTo("2147483647") > 0)
return false;
}
return true;
}
@ -142,25 +151,71 @@ public class Utilities {
}
}
public static boolean isDecimal(String string) {
if (isBlank(string)) {
return false;
public enum DecimalStatus {
BLANK, SYNTAX, RANGE, OK
}
public static boolean isDecimal(String value, boolean exponent) {
DecimalStatus ds = checkDecimal(value, exponent);
return ds == DecimalStatus.OK || ds == DecimalStatus.RANGE;
}
public static DecimalStatus checkDecimal(String value, boolean exponent) {
if (isBlank(value)) {
return DecimalStatus.BLANK;
}
if (string.startsWith("-"))
string = string.substring(1);
boolean havePeriod = false;
for (char next : string.toCharArray()) {
boolean haveExponent = false;
boolean haveMinus = false;
boolean haveDigits = false;
int preDecLength = 0;
int postDecLength = 0;
int exponentLength = 0;
int length = 0;
for (char next : value.toCharArray()) {
if (next == '.') {
if (havePeriod) {
return false;
}
if (!haveDigits || havePeriod || haveExponent)
return DecimalStatus.SYNTAX;
havePeriod = true;
preDecLength = length;
length = 0;
} else if (next == '-') {
if (haveDigits || haveMinus)
return DecimalStatus.SYNTAX;
haveMinus = true;
} else if (next == 'e') {
if (!haveDigits || haveExponent || !exponent)
return DecimalStatus.SYNTAX;
haveExponent = true;
haveMinus = false;
haveDigits = false;
if (havePeriod)
postDecLength = length;
else
preDecLength = length;
length = 0;
} else if (!Character.isDigit(next)) {
return false;
return DecimalStatus.SYNTAX;
} else {
haveDigits = true;
length++;
}
}
return true;
if (haveExponent)
exponentLength = length;
else if (havePeriod)
postDecLength = length;
else
preDecLength = length;
// now, bounds checking - these are arbitrary
if (exponentLength > 4)
return DecimalStatus.RANGE;
if (preDecLength + postDecLength > 18)
return DecimalStatus.RANGE;
return DecimalStatus.OK;
}
public static String camelCase(String value) {

View File

@ -1562,7 +1562,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
if (type.equals("decimal")) {
if (e.primitiveValue() != null) {
rule(errors, IssueType.INVALID, e.line(), e.col(), path, Utilities.isDecimal(e.primitiveValue()), "The value '" + e.primitiveValue() + "' is not a valid decimal");
rule(errors, IssueType.INVALID, e.line(), e.col(), path, Utilities.isDecimal(e.primitiveValue(), true), "The value '" + e.primitiveValue() + "' is not a valid decimal");
if (e.primitiveValue().contains(".")) {
String head = e.primitiveValue().substring(0, e.primitiveValue().indexOf("."));
if (head.startsWith("-"))

View File

@ -135,6 +135,7 @@ import org.hl7.fhir.r5.utils.Version;
import org.hl7.fhir.r5.validation.EnableWhenEvaluator.QStack;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.Utilities.DecimalStatus;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
@ -251,6 +252,10 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
boolean ok = true;
for (ValidationMessage v : valerrors)
ok = ok && !v.getLevel().isError();
if(item instanceof Element) {
Element e = (Element) item;
System.out.println("Conforms to: resource "+(e.getIdBase() != null ? item.getIdBase() : e.getChildValue("id"))+", url = "+url+", outcome = "+Boolean.toString(ok));
}
return ok;
}
@ -332,7 +337,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
public ResourceProfiles(Element resource, NodeStack stack) {
this.resource = resource;
if (this.resource.getName().equals("contained"))
if (this.resource.getName().equals("contained") && stack.parent != null)
this.owner = stack.parent.element;
else
this.owner = resource;
@ -794,7 +799,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
private boolean check(String v1, String v2) {
return v1 == null ? Utilities.noString(v1) : v1.equals(v2);
return v1 == null ? Utilities.noString(v2) : v1.equals(v2);
}
private void checkAddress(List<ValidationMessage> errors, String path, Element focus, Address fixed) {
@ -1379,6 +1384,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
else if (fixed instanceof org.hl7.fhir.r5.model.InstantType)
rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, check(((org.hl7.fhir.r5.model.InstantType) fixed).getValue().toString(), value),
"Value is '" + value + "' but must be '" + ((org.hl7.fhir.r5.model.InstantType) fixed).asStringValue() + "'");
else if (fixed instanceof org.hl7.fhir.r5.model.CodeType)
rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, check(((org.hl7.fhir.r5.model.CodeType) fixed).getValue(), value),
"Value is '" + value + "' but must be '" + ((org.hl7.fhir.r5.model.CodeType) fixed).getValue() + "'");
else if (fixed instanceof org.hl7.fhir.r5.model.StringType)
rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, check(((org.hl7.fhir.r5.model.StringType) fixed).getValue(), value),
"Value is '" + value + "' but must be '" + ((org.hl7.fhir.r5.model.StringType) fixed).getValue() + "'");
@ -1397,9 +1405,6 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
else if (fixed instanceof org.hl7.fhir.r5.model.UuidType)
rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, check(((org.hl7.fhir.r5.model.UuidType) fixed).getValue(), value),
"Value is '" + value + "' but must be '" + ((org.hl7.fhir.r5.model.UuidType) fixed).getValue() + "'");
else if (fixed instanceof org.hl7.fhir.r5.model.CodeType)
rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, check(((org.hl7.fhir.r5.model.CodeType) fixed).getValue(), value),
"Value is '" + value + "' but must be '" + ((org.hl7.fhir.r5.model.CodeType) fixed).getValue() + "'");
else if (fixed instanceof org.hl7.fhir.r5.model.IdType)
rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, check(((org.hl7.fhir.r5.model.IdType) fixed).getValue(), value),
"Value is '" + value + "' but must be '" + ((org.hl7.fhir.r5.model.IdType) fixed).getValue() + "'");
@ -1633,7 +1638,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
if (type.equals("decimal")) {
if (e.primitiveValue() != null) {
rule(errors, IssueType.INVALID, e.line(), e.col(), path, Utilities.isDecimal(e.primitiveValue()), "The value '" + e.primitiveValue() + "' is not a valid decimal");
DecimalStatus ds = Utilities.checkDecimal(e.primitiveValue(), true);
if (rule(errors, IssueType.INVALID, e.line(), e.col(), path, ds == DecimalStatus.OK || ds == DecimalStatus.RANGE, "The value '" + e.primitiveValue() + "' is not a valid decimal"))
warning(errors, IssueType.VALUE, e.line(), e.col(), path, ds != DecimalStatus.RANGE, "The value '" + e.primitiveValue() + "' is outside the range of commonly/reasonably supported decimals");
if (e.primitiveValue().contains(".")) {
String head = e.primitiveValue().substring(0, e.primitiveValue().indexOf("."));
if (head.startsWith("-"))
@ -4207,8 +4214,9 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L
Element resource, Element element, NodeStack stack) throws FHIRException {
if (resource.getName().equals("contained")) {
NodeStack ancestor = stack;
while (!ancestor.element.isResource() || ancestor.element.getName().equals("contained"))
while (ancestor != null && ancestor.element != null && (!ancestor.element.isResource() || "contained".equals(ancestor.element.getName())))
ancestor = ancestor.parent;
if (ancestor != null && ancestor.element != null)
checkInvariants(hostContext, errors, stack.getLiteralPath(), profile, definition, null, null, ancestor.element, element);
} else
checkInvariants(hostContext, errors, stack.getLiteralPath(), profile, definition, null, null, resource, element);

View File

@ -806,6 +806,26 @@
"source": "azatadha/param-profile.xml",
"errorCount": 0
}
},
"profile-slicing-ok-1.xml": {
"errorCount": 0,
"profiles": [
"profile-slicing-profile-1.xml", "profile-slicing-profile-2.xml", "profile-slicing-profile-3.xml"
],
"profile": {
"source": "profile-slicing-profile-open.xml",
"errorCount": 0
}
},
"profile-slicing-bad-1.xml": {
"errorCount": 0,
"profiles": [
"profile-slicing-profile-1.xml", "profile-slicing-profile-2.xml", "profile-slicing-profile-3.xml"
],
"profile": {
"source": "profile-slicing-profile-open.xml",
"errorCount": 1
}
}
}
}

View File

@ -27,14 +27,6 @@
<name value="paramDecimal0"/>
<valueDecimal value="00.1"/>
</parameter>
<parameter> <!-- 8 -->
<name value="paramDecimal1"/>
<valueDecimal value="1e09"/>
</parameter>
<parameter> <!-- 9 -->
<name value="paramDecimal2"/>
<valueDecimal value="0.12e3"/>
</parameter>
<parameter> <!-- 10 -->
<name value="paramBase64Binary"/>
<valueBase64Binary value="YXNhcs2Rhc2Q="/>

View File

@ -31,6 +31,26 @@
<name value="paramDecimal3"/>
<valueDecimal value="121233786234234234234234.12323"/>
</parameter>
<parameter>
<name value="paramDecimal4"/>
<valueDecimal value="1e1"/>
</parameter>
<parameter>
<name value="paramDecimal5"/>
<valueDecimal value="1.0e-1"/>
</parameter>
<parameter>
<name value="paramDecimal6"/>
<valueDecimal value="0.1e11"/>
</parameter>
<parameter>
<name value="paramDecimal7"/>
<valueDecimal value="1e09"/>
</parameter>
<parameter>
<name value="paramDecimal8"/>
<valueDecimal value="0.12e3"/>
</parameter>
<parameter>
<name value="paramBase64Binary"/>
<valueBase64Binary value="YXNhc2Rhc2Q="/>

View File

@ -0,0 +1,68 @@
<List xmlns="http://hl7.org/fhir">
<contained>
<Basic>
<id value="i1"/>
<code>
<coding>
<system value="http://hl7.org/fhir/test/CodeSystem/profile-slicing-codes"/>
<code value="profile2"/>
</coding>
</code>
</Basic>
</contained>
<contained>
<Basic>
<id value="i2"/>
<code>
<coding>
<system value="http://hl7.org/fhir/test/CodeSystem/profile-slicing-codes"/>
<code value="profile2"/>
</coding>
</code>
</Basic>
</contained>
<contained>
<Basic>
<id value="i3"/>
<code>
<coding>
<system value="http://hl7.org/fhir/test/CodeSystem/profile-slicing-codes"/>
<code value="profile2"/>
</coding>
</code>
</Basic>
</contained>
<contained>
<Basic>
<id value="i4"/>
<code>
<coding>
<system value="http://hl7.org/fhir/test/CodeSystem/profile-slicing-codes"/>
<code value="profile3"/>
</coding>
</code>
</Basic>
</contained>
<status value="current"/>
<mode value="working"/>
<entry>
<item>
<reference value="#i1"/>
</item>
</entry>
<entry>
<item>
<reference value="#i2"/>
</item>
</entry>
<entry>
<item>
<reference value="#i3"/>
</item>
</entry>
<entry>
<item>
<reference value="#i4"/>
</item>
</entry>
</List>

View File

@ -0,0 +1,68 @@
<List xmlns="http://hl7.org/fhir">
<contained>
<Basic>
<id value="i1"/>
<code>
<coding>
<system value="http://hl7.org/fhir/test/CodeSystem/profile-slicing-codes"/>
<code value="profile1"/>
</coding>
</code>
</Basic>
</contained>
<contained>
<Basic>
<id value="i2"/>
<code>
<coding>
<system value="http://hl7.org/fhir/test/CodeSystem/profile-slicing-codes"/>
<code value="profile2"/>
</coding>
</code>
</Basic>
</contained>
<contained>
<Basic>
<id value="i3"/>
<code>
<coding>
<system value="http://hl7.org/fhir/test/CodeSystem/profile-slicing-codes"/>
<code value="profile2"/>
</coding>
</code>
</Basic>
</contained>
<contained>
<Basic>
<id value="i4"/>
<code>
<coding>
<system value="http://hl7.org/fhir/test/CodeSystem/profile-slicing-codes"/>
<code value="profile3"/>
</coding>
</code>
</Basic>
</contained>
<status value="current"/>
<mode value="working"/>
<entry>
<item>
<reference value="#i1"/>
</item>
</entry>
<entry>
<item>
<reference value="#i2"/>
</item>
</entry>
<entry>
<item>
<reference value="#i3"/>
</item>
</entry>
<entry>
<item>
<reference value="#i4"/>
</item>
</entry>
</List>

View File

@ -0,0 +1,27 @@
<StructureDefinition xmlns="http://hl7.org/fhir">
<id value="profile-slicing-profile-1"/>
<url value="http://hl7.org/fhir/test/StructureDefinition/profile-slicing-profile-1"/>
<version value="0.1.0"/>
<name value="TestProfile1"/>
<title value="Test Profile #1"/>
<status value="draft"/>
<date value="2017-09-06T06:30:54+00:00"/>
<publisher value="HL7"/>
<fhirVersion value="4.0.0"/>
<kind value="resource"/>
<abstract value="false"/>
<type value="Basic"/>
<baseDefinition value="http://hl7.org/fhir/StructureDefinition/Basic"/>
<derivation value="constraint"/>
<differential>
<element id="Basic.code">
<path value="Basic.code"/>
<fixedCodeableConcept>
<coding>
<system value="http://hl7.org/fhir/test/CodeSystem/profile-slicing-codes"/>
<code value="profile1"/>
</coding>
</fixedCodeableConcept>
</element>
</differential>
</StructureDefinition>

View File

@ -0,0 +1,27 @@
<StructureDefinition xmlns="http://hl7.org/fhir">
<id value="profile-slicing-profile-2"/>
<url value="http://hl7.org/fhir/test/StructureDefinition/profile-slicing-profile-2"/>
<version value="0.1.0"/>
<name value="TestProfile2"/>
<title value="Test Profile #2"/>
<status value="draft"/>
<date value="2017-09-06T06:30:54+00:00"/>
<publisher value="HL7"/>
<fhirVersion value="4.0.0"/>
<kind value="resource"/>
<abstract value="false"/>
<type value="Basic"/>
<baseDefinition value="http://hl7.org/fhir/StructureDefinition/Basic"/>
<derivation value="constraint"/>
<differential>
<element id="Basic.code">
<path value="Basic.code"/>
<fixedCodeableConcept>
<coding>
<system value="http://hl7.org/fhir/test/CodeSystem/profile-slicing-codes"/>
<code value="profile2"/>
</coding>
</fixedCodeableConcept>
</element>
</differential>
</StructureDefinition>

View File

@ -0,0 +1,27 @@
<StructureDefinition xmlns="http://hl7.org/fhir">
<id value="profile-slicing-profile-3"/>
<url value="http://hl7.org/fhir/test/StructureDefinition/profile-slicing-profile-3"/>
<version value="0.1.0"/>
<name value="TestProfile3"/>
<title value="Test Profile #3"/>
<status value="draft"/>
<date value="3017-09-06T06:30:54+00:00"/>
<publisher value="HL7"/>
<fhirVersion value="4.0.0"/>
<kind value="resource"/>
<abstract value="false"/>
<type value="Basic"/>
<baseDefinition value="http://hl7.org/fhir/StructureDefinition/Basic"/>
<derivation value="constraint"/>
<differential>
<element id="Basic.code">
<path value="Basic.code"/>
<fixedCodeableConcept>
<coding>
<system value="http://hl7.org/fhir/test/CodeSystem/profile-slicing-codes"/>
<code value="profile3"/>
</coding>
</fixedCodeableConcept>
</element>
</differential>
</StructureDefinition>

View File

@ -0,0 +1,66 @@
<StructureDefinition xmlns="http://hl7.org/fhir">
<id value="profile-slicing-profile-list"/>
<url value="http://hl7.org/fhir/test/StructureDefinition/profile-slicing-profile-list"/>
<version value="0.1.0"/>
<name value="TestProfileList"/>
<title value="Test Profile List"/>
<status value="draft"/>
<date value="3017-09-06T06:30:54+00:00"/>
<publisher value="HL7"/>
<fhirVersion value="4.0.0"/>
<kind value="resource"/>
<abstract value="false"/>
<type value="List"/>
<baseDefinition value="http://hl7.org/fhir/StructureDefinition/List"/>
<derivation value="constraint"/>
<differential>
<element id="List.entry">
<path value="List.entry"/>
<slicing>
<discriminator>
<type value="profile"/>
<path value="item.resolve()"/>
</discriminator>
<ordered vale="false"/>
<rules value="closed"/>
</slicing>
</element>
<element id="List.entry:slice1">
<path value="List.entry"/>
<sliceName value="slice1"/>
<min value="1"/>
</element>
<element id="List.entry:slice1.item">
<path value="List.entry.item"/>
<type>
<code value="Reference"/>
<targetProfile value="http://hl7.org/fhir/test/StructureDefinition/profile-slicing-profile-1"/>
</type>
</element>
<element id="List.entry:slice2">
<path value="List.entry"/>
<sliceName value="slice2"/>
<min value="1"/>
<max value="3"/>
</element>
<element id="List.entry:slice2.item">
<path value="List.entry.item"/>
<type>
<code value="Reference"/>
<targetProfile value="http://hl7.org/fhir/test/StructureDefinition/profile-slicing-profile-2"/>
</type>
</element>
<element id="List.entry:slice3">
<path value="List.entry"/>
<sliceName value="slice3"/>
<max value="1"/>
</element>
<element id="List.entry:slice3.item">
<path value="List.entry.item"/>
<type>
<code value="Reference"/>
<targetProfile value="http://hl7.org/fhir/test/StructureDefinition/profile-slicing-profile-3"/>
</type>
</element>
</differential>
</StructureDefinition>

View File

@ -0,0 +1,66 @@
<StructureDefinition xmlns="http://hl7.org/fhir">
<id value="profile-slicing-profile-list"/>
<url value="http://hl7.org/fhir/test/StructureDefinition/profile-slicing-profile-list"/>
<version value="0.1.0"/>
<name value="TestProfileList"/>
<title value="Test Profile List"/>
<status value="draft"/>
<date value="3017-09-06T06:30:54+00:00"/>
<publisher value="HL7"/>
<fhirVersion value="4.0.0"/>
<kind value="resource"/>
<abstract value="false"/>
<type value="List"/>
<baseDefinition value="http://hl7.org/fhir/StructureDefinition/List"/>
<derivation value="constraint"/>
<differential>
<element id="List.entry">
<path value="List.entry"/>
<slicing>
<discriminator>
<type value="profile"/>
<path value="item.resolve()"/>
</discriminator>
<ordered vale="false"/>
<rules value="open"/>
</slicing>
</element>
<element id="List.entry:slice1">
<path value="List.entry"/>
<sliceName value="slice1"/>
<min value="1"/>
</element>
<element id="List.entry:slice1.item">
<path value="List.entry.item"/>
<type>
<code value="Reference"/>
<targetProfile value="http://hl7.org/fhir/test/StructureDefinition/profile-slicing-profile-1"/>
</type>
</element>
<element id="List.entry:slice2">
<path value="List.entry"/>
<sliceName value="slice2"/>
<min value="1"/>
<max value="3"/>
</element>
<element id="List.entry:slice2.item">
<path value="List.entry.item"/>
<type>
<code value="Reference"/>
<targetProfile value="http://hl7.org/fhir/test/StructureDefinition/profile-slicing-profile-2"/>
</type>
</element>
<element id="List.entry:slice3">
<path value="List.entry"/>
<sliceName value="slice3"/>
<max value="1"/>
</element>
<element id="List.entry:slice3.item">
<path value="List.entry.item"/>
<type>
<code value="Reference"/>
<targetProfile value="http://hl7.org/fhir/test/StructureDefinition/profile-slicing-profile-3"/>
</type>
</element>
</differential>
</StructureDefinition>

View File

@ -0,0 +1,66 @@
<StructureDefinition xmlns="http://hl7.org/fhir">
<id value="profile-slicing-profile-list"/>
<url value="http://hl7.org/fhir/test/StructureDefinition/profile-slicing-profile-list"/>
<version value="0.1.0"/>
<name value="TestProfileList"/>
<title value="Test Profile List"/>
<status value="draft"/>
<date value="3017-09-06T06:30:54+00:00"/>
<publisher value="HL7"/>
<fhirVersion value="4.0.0"/>
<kind value="resource"/>
<abstract value="false"/>
<type value="List"/>
<baseDefinition value="http://hl7.org/fhir/StructureDefinition/List"/>
<derivation value="constraint"/>
<differential>
<element id="List.entry">
<path value="List.entry"/>
<slicing>
<discriminator>
<type value="profile"/>
<path value="item.resolve()"/>
</discriminator>
<ordered vale="true"/>
<rules value="open"/>
</slicing>
</element>
<element id="List.entry:slice1">
<path value="List.entry"/>
<sliceName value="slice1"/>
<min value="1"/>
</element>
<element id="List.entry:slice1.item">
<path value="List.entry.item"/>
<type>
<code value="Reference"/>
<targetProfile value="http://hl7.org/fhir/test/StructureDefinition/profile-slicing-profile-1"/>
</type>
</element>
<element id="List.entry:slice2">
<path value="List.entry"/>
<sliceName value="slice2"/>
<min value="1"/>
<max value="3"/>
</element>
<element id="List.entry:slice2.item">
<path value="List.entry.item"/>
<type>
<code value="Reference"/>
<targetProfile value="http://hl7.org/fhir/test/StructureDefinition/profile-slicing-profile-2"/>
</type>
</element>
<element id="List.entry:slice3">
<path value="List.entry"/>
<sliceName value="slice3"/>
<max value="1"/>
</element>
<element id="List.entry:slice3.item">
<path value="List.entry.item"/>
<type>
<code value="Reference"/>
<targetProfile value="http://hl7.org/fhir/test/StructureDefinition/profile-slicing-profile-3"/>
</type>
</element>
</differential>
</StructureDefinition>