Skip to content

Commit

Permalink
Issue #2377 - update ConstraintGenerator (#2389)
Browse files Browse the repository at this point in the history
* Issue #2377 - update ConstraintGenerator

Signed-off-by: John T.E. Timm <johntimm@us.ibm.com>
  • Loading branch information
JohnTimm authored May 19, 2021
1 parent 5f1c25b commit d6fbdad
Show file tree
Hide file tree
Showing 5 changed files with 5,993 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* (C) Copyright IBM Corp. 2021
*
* SPDX-License-Identifier: Apache-2.0
*/

package com.ibm.fhir.ig.carin.bb.test;

import static org.testng.Assert.assertTrue;

import java.io.InputStream;
import java.util.List;

import org.testng.annotations.Test;

import com.ibm.fhir.model.annotation.Constraint;
import com.ibm.fhir.model.format.Format;
import com.ibm.fhir.model.parser.FHIRParser;
import com.ibm.fhir.model.resource.StructureDefinition;
import com.ibm.fhir.profile.ConstraintGenerator;

public class C4BBPatientConstraintGeneratorTest {
@Test
public void testConstraintGenerator() throws Exception {
InputStream in = C4BBPatientConstraintGeneratorTest.class.getClassLoader().getResourceAsStream("JSON/StructureDefinition-C4BB-Patient.json");
FHIRParser parser = FHIRParser.parser(Format.JSON);
StructureDefinition profile = parser.parse(in);
ConstraintGenerator generator = new ConstraintGenerator(profile);
List<Constraint> constraints = generator.generate();
assertTrue(hasConstraint(constraints, "meta.where(lastUpdated.exists() and profile.where($this = 'http://hl7.org/fhir/us/carin-bb/StructureDefinition/C4BB-Patient|1.0.0').count() = 1).exists()"));
}

public boolean hasConstraint(List<Constraint> constraints, String expr) {
for (Constraint constraint : constraints) {
if (constraint.expression().equals(expr)) {
return true;
}
}
return false;
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,10 @@
import static com.ibm.fhir.path.util.FHIRPathUtil.hasStringValue;
import static com.ibm.fhir.path.util.FHIRPathUtil.hasSystemValue;
import static com.ibm.fhir.path.util.FHIRPathUtil.hasTemporalValue;
import static com.ibm.fhir.path.util.FHIRPathUtil.isCodedElementNode;
import static com.ibm.fhir.path.util.FHIRPathUtil.isFalse;
import static com.ibm.fhir.path.util.FHIRPathUtil.isQuantityNode;
import static com.ibm.fhir.path.util.FHIRPathUtil.isSingleton;
import static com.ibm.fhir.path.util.FHIRPathUtil.isStringElementNode;
import static com.ibm.fhir.path.util.FHIRPathUtil.isStringValue;
import static com.ibm.fhir.path.util.FHIRPathUtil.isTypeCompatible;
import static com.ibm.fhir.path.util.FHIRPathUtil.isUriElementNode;
import static com.ibm.fhir.path.util.FHIRPathUtil.singleton;
import static com.ibm.fhir.path.util.FHIRPathUtil.unescape;

Expand Down Expand Up @@ -793,11 +789,7 @@ public Collection<FHIRPathNode> visitMembershipExpression(FHIRPathParser.Members

switch (operator) {
case "in":
if ((isCodedElementNode(left) || isStringElementNode(left) || isUriElementNode(left)) && isStringValue(right)) {
// For backwards compatibility per: https://jira.hl7.org/projects/FHIR/issues/FHIR-26605
FHIRPathFunction memberOfFunction = FHIRPathFunction.registry().getFunction("memberOf");
result = memberOfFunction.apply(evaluationContext, left, Collections.singletonList(right));
} else if (left.isEmpty()) {
if (left.isEmpty()) {
result = empty();
} else if (right.containsAll(left)) {
result = SINGLETON_TRUE;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 2019, 2020
* (C) Copyright IBM Corp. 2019, 2021
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -118,7 +118,7 @@ public void testMemberOfFunction6() throws Exception {
Assert.assertEquals(result, SINGLETON_FALSE);
}

@Test
@Test(enabled = false)
public void testMemberOfFunction7() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();

Expand Down Expand Up @@ -254,14 +254,14 @@ public void testMemberOfFunction17() throws Exception {

Assert.assertEquals(result, SINGLETON_FALSE);
}

@Test
public void testMemberOfFunction18() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Collection<FHIRPathNode> result = evaluator.evaluate(Code.of(ENGLISH_US), "$this.memberOf('" + MemberOfFunction.ALL_LANG_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_TRUE);
}

@Test
public void testMemberOfFunction19() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Expand All @@ -279,7 +279,7 @@ public void testMemberOfFunction20() throws Exception {
Collection<FHIRPathNode> result = evaluator.evaluate(coding, "$this.memberOf('" + MemberOfFunction.ALL_LANG_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_TRUE);
}

@Test
public void testMemberOfFunction21() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Expand All @@ -290,7 +290,7 @@ public void testMemberOfFunction21() throws Exception {
Collection<FHIRPathNode> result = evaluator.evaluate(coding, "$this.memberOf('" + MemberOfFunction.ALL_LANG_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_FALSE);
}

@Test
public void testMemberOfFunction22() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Expand All @@ -314,7 +314,7 @@ public void testMemberOfFunction23() throws Exception {
Collection<FHIRPathNode> result = evaluator.evaluate(codeableConcept, "$this.memberOf('" + MemberOfFunction.ALL_LANG_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_TRUE);
}

@Test
public void testMemberOfFunction24() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Expand All @@ -327,7 +327,7 @@ public void testMemberOfFunction24() throws Exception {
Collection<FHIRPathNode> result = evaluator.evaluate(codeableConcept, "$this.memberOf('" + MemberOfFunction.ALL_LANG_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_FALSE);
}

@Test
public void testMemberOfFunction25() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Expand All @@ -351,7 +351,7 @@ public void testMemberOfFunction26() throws Exception {
Collection<FHIRPathNode> result = evaluator.evaluate(quantity, "$this.memberOf('" + MemberOfFunction.ALL_LANG_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_TRUE);
}

@Test
public void testMemberOfFunction27() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Expand All @@ -362,7 +362,7 @@ public void testMemberOfFunction27() throws Exception {
Collection<FHIRPathNode> result = evaluator.evaluate(quantity, "$this.memberOf('" + MemberOfFunction.ALL_LANG_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_FALSE);
}

@Test
public void testMemberOfFunction28() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Expand All @@ -373,28 +373,28 @@ public void testMemberOfFunction28() throws Exception {
Collection<FHIRPathNode> result = evaluator.evaluate(quantity, "$this.memberOf('" + MemberOfFunction.ALL_LANG_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_FALSE);
}

@Test
public void testMemberOfFunction29() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Collection<FHIRPathNode> result = evaluator.evaluate(com.ibm.fhir.model.type.String.of(ENGLISH_US), "$this.memberOf('" + MemberOfFunction.ALL_LANG_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_TRUE);
}

@Test
public void testMemberOfFunction30() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Collection<FHIRPathNode> result = evaluator.evaluate(com.ibm.fhir.model.type.String.of("invalidLanguageCode"), "$this.memberOf('" + MemberOfFunction.ALL_LANG_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_FALSE);
}

@Test
public void testMemberOfFunction31() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Collection<FHIRPathNode> result = evaluator.evaluate(Code.of(UNITS_PER_LITER), "$this.memberOf('" + MemberOfFunction.UCUM_UNITS_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_TRUE);
}

@Test
public void testMemberOfFunction32() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Expand All @@ -412,7 +412,7 @@ public void testMemberOfFunction33() throws Exception {
Collection<FHIRPathNode> result = evaluator.evaluate(coding, "$this.memberOf('" + MemberOfFunction.UCUM_UNITS_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_TRUE);
}

@Test
public void testMemberOfFunction34() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Expand All @@ -423,7 +423,7 @@ public void testMemberOfFunction34() throws Exception {
Collection<FHIRPathNode> result = evaluator.evaluate(coding, "$this.memberOf('" + MemberOfFunction.UCUM_UNITS_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_FALSE);
}

@Test
public void testMemberOfFunction35() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Expand All @@ -447,7 +447,7 @@ public void testMemberOfFunction36() throws Exception {
Collection<FHIRPathNode> result = evaluator.evaluate(codeableConcept, "$this.memberOf('" + MemberOfFunction.UCUM_UNITS_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_TRUE);
}

@Test
public void testMemberOfFunction37() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Expand All @@ -460,7 +460,7 @@ public void testMemberOfFunction37() throws Exception {
Collection<FHIRPathNode> result = evaluator.evaluate(codeableConcept, "$this.memberOf('" + MemberOfFunction.UCUM_UNITS_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_FALSE);
}

@Test
public void testMemberOfFunction38() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Expand All @@ -484,7 +484,7 @@ public void testMemberOfFunction39() throws Exception {
Collection<FHIRPathNode> result = evaluator.evaluate(quantity, "$this.memberOf('" + MemberOfFunction.UCUM_UNITS_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_TRUE);
}

@Test
public void testMemberOfFunction40() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Expand All @@ -495,7 +495,7 @@ public void testMemberOfFunction40() throws Exception {
Collection<FHIRPathNode> result = evaluator.evaluate(quantity, "$this.memberOf('" + MemberOfFunction.UCUM_UNITS_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_FALSE);
}

@Test
public void testMemberOfFunction41() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Expand All @@ -506,21 +506,21 @@ public void testMemberOfFunction41() throws Exception {
Collection<FHIRPathNode> result = evaluator.evaluate(quantity, "$this.memberOf('" + MemberOfFunction.UCUM_UNITS_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_FALSE);
}

@Test
public void testMemberOfFunction42() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Collection<FHIRPathNode> result = evaluator.evaluate(com.ibm.fhir.model.type.String.of(UNITS_PER_LITER), "$this.memberOf('" + MemberOfFunction.UCUM_UNITS_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_TRUE);
}

@Test
public void testMemberOfFunction43() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Collection<FHIRPathNode> result = evaluator.evaluate(com.ibm.fhir.model.type.String.of("invalid ucum code"), "$this.memberOf('" + MemberOfFunction.UCUM_UNITS_VALUE_SET_URL + "')");
Assert.assertEquals(result, SINGLETON_FALSE);
}

@Test
public void testMemberOfFunction44() throws Exception {
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,14 @@ private String generatePatternValueConstraint(Node node, boolean discriminator)
sb.append(cardinality(node, sb.toString()));
}
} else if (pattern.is(Uri.class)) {
sb.append(identifier).append(" = '").append(pattern.as(Uri.class).getValue()).append("'");
if (isSlice(elementDefinition) && hasDiscriminatorPath(elementDefinition, "$this")) {
sb.append(identifier).append(".where($this = '").append(pattern.as(Uri.class).getValue()).append("')");
if (!discriminator) {
sb.append(cardinality(node, sb.toString()));
}
} else {
sb.append(identifier).append(" = '").append(pattern.as(Uri.class).getValue()).append("'");
}
} else if (pattern.is(Code.class)) {
sb.append(identifier).append(" = '").append(pattern.as(Code.class).getValue()).append("'");
}
Expand Down Expand Up @@ -797,6 +804,18 @@ private boolean hasConstraint(Node node) {
return false;
}

private boolean hasDiscriminatorPath(ElementDefinition slice, String path) {
ElementDefinition sliceDefinition = getSliceDefinition(slice);
if (sliceDefinition != null) {
Slicing slicing = sliceDefinition.getSlicing();
List<String> paths = slicing.getDiscriminator().stream()
.map(discriminator -> discriminator.getPath().getValue())
.collect(Collectors.toList());
return paths.size() == 1 && path.equals(paths.get(0));
}
return false;
}

private boolean hasExtensionConstraint(ElementDefinition elementDefinition) {
List<Type> types = getTypes(elementDefinition);

Expand Down

0 comments on commit d6fbdad

Please sign in to comment.