FHIRPath fixes after last HAPI FHIR sync

This commit is contained in:
James Agnew 2019-04-23 22:00:22 -04:00
parent 3a1bd1c429
commit c5a8beb3d1
5 changed files with 169 additions and 97 deletions

View File

@ -876,10 +876,25 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
*/ */
public Boolean equalsUsingFhirPathRules(BaseDateTimeType theOther) { public Boolean equalsUsingFhirPathRules(BaseDateTimeType theOther) {
if (hasTimezoneIfRequired() != theOther.hasTimezoneIfRequired()) { BaseDateTimeType me = this;
if (getPrecision() == theOther.getPrecision()) {
if (getPrecision().ordinal() >= TemporalPrecisionEnum.MINUTE.ordinal() && theOther.getPrecision().ordinal() >= TemporalPrecisionEnum.MINUTE.ordinal()) { // Per FHIRPath rules, we compare equivalence at the lowest precision of the two values,
boolean couldBeTheSameTime = couldBeTheSameTime(this, theOther) || couldBeTheSameTime(theOther, this); // so if we need to, we'll clone either side and reduce its precision
int lowestPrecision = Math.min(me.getPrecision().ordinal(), theOther.getPrecision().ordinal());
TemporalPrecisionEnum lowestPrecisionEnum = TemporalPrecisionEnum.values()[lowestPrecision];
if (me.getPrecision() != lowestPrecisionEnum) {
me = new DateTimeType(me.getValueAsString());
me.setPrecision(lowestPrecisionEnum);
}
if (theOther.getPrecision() != lowestPrecisionEnum) {
theOther = new DateTimeType(theOther.getValueAsString());
theOther.setPrecision(lowestPrecisionEnum);
}
if (me.hasTimezoneIfRequired() != theOther.hasTimezoneIfRequired()) {
if (me.getPrecision() == theOther.getPrecision()) {
if (me.getPrecision().ordinal() >= TemporalPrecisionEnum.MINUTE.ordinal() && theOther.getPrecision().ordinal() >= TemporalPrecisionEnum.MINUTE.ordinal()) {
boolean couldBeTheSameTime = couldBeTheSameTime(me, theOther) || couldBeTheSameTime(theOther, me);
if (!couldBeTheSameTime) { if (!couldBeTheSameTime) {
return false; return false;
} }
@ -889,16 +904,24 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
} }
// Same precision // Same precision
if (getPrecision() == theOther.getPrecision()) { if (me.getPrecision() == theOther.getPrecision()) {
return getValue().getTime() == theOther.getValue().getTime(); if (me.getPrecision().ordinal() >= TemporalPrecisionEnum.MINUTE.ordinal()) {
long leftTime = me.getValue().getTime();
long rightTime = theOther.getValue().getTime();
return leftTime == rightTime;
} else {
String leftTime = me.getValueAsString();
String rightTime = theOther.getValueAsString();
return leftTime.equals(rightTime);
}
} }
// Both represent 0 millis but the millis are optional // Both represent 0 millis but the millis are optional
if (((Integer)0).equals(getMillis())) { if (((Integer)0).equals(me.getMillis())) {
if (((Integer)0).equals(theOther.getMillis())) { if (((Integer)0).equals(theOther.getMillis())) {
if (getPrecision().ordinal() >= TemporalPrecisionEnum.SECOND.ordinal()) { if (me.getPrecision().ordinal() >= TemporalPrecisionEnum.SECOND.ordinal()) {
if (theOther.getPrecision().ordinal() >= TemporalPrecisionEnum.SECOND.ordinal()) { if (theOther.getPrecision().ordinal() >= TemporalPrecisionEnum.SECOND.ordinal()) {
return getValue().getTime() == theOther.getValue().getTime(); return me.getValue().getTime() == theOther.getValue().getTime();
} }
} }
} }

View File

@ -1436,13 +1436,15 @@ public class FHIRPathEngine {
} }
private List<Base> opAs(List<Base> left, List<Base> right) { private List<Base> opAs(List<Base> left, List<Base> right) {
List<Base> result = new ArrayList<Base>(); List<Base> result = new ArrayList<>();
if (left.size() != 1 || right.size() != 1) if (right.size() != 1)
return result; return result;
else { else {
String tn = convertToString(right); String tn = convertToString(right);
if (tn.equals(left.get(0).fhirType())) for (Base nextLeft : left) {
result.add(left.get(0)); if (tn.equals(nextLeft.fhirType()))
result.add(nextLeft);
}
} }
return result; return result;
} }
@ -3298,7 +3300,7 @@ public class FHIRPathEngine {
if (s.startsWith("#")) { if (s.startsWith("#")) {
Property p = context.resource.getChildByName("contained"); Property p = context.resource.getChildByName("contained");
for (Base c : p.getValues()) { for (Base c : p.getValues()) {
if (s.substring(1).equals(c.getIdBase())) { if (chompHash(s).equals(chompHash(c.getIdBase()))) {
res = c; res = c;
break; break;
} }
@ -3314,6 +3316,17 @@ public class FHIRPathEngine {
return result; return result;
} }
/**
* Strips a leading hashmark (#) if present at the start of a string
*/
private String chompHash(String theId) {
String retVal = theId;
while (retVal.startsWith("#")) {
retVal = retVal.substring(1);
}
return retVal;
}
private List<Base> funcExtension(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws FHIRException { private List<Base> funcExtension(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws FHIRException {
List<Base> result = new ArrayList<Base>(); List<Base> result = new ArrayList<Base>();
List<Base> nl = execute(context, focus, exp.getParameters().get(0), true); List<Base> nl = execute(context, focus, exp.getParameters().get(0), true);

View File

@ -876,10 +876,25 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
*/ */
public Boolean equalsUsingFhirPathRules(BaseDateTimeType theOther) { public Boolean equalsUsingFhirPathRules(BaseDateTimeType theOther) {
if (hasTimezoneIfRequired() != theOther.hasTimezoneIfRequired()) { BaseDateTimeType me = this;
if (getPrecision() == theOther.getPrecision()) {
if (getPrecision().ordinal() >= TemporalPrecisionEnum.MINUTE.ordinal() && theOther.getPrecision().ordinal() >= TemporalPrecisionEnum.MINUTE.ordinal()) { // Per FHIRPath rules, we compare equivalence at the lowest precision of the two values,
boolean couldBeTheSameTime = couldBeTheSameTime(this, theOther) || couldBeTheSameTime(theOther, this); // so if we need to, we'll clone either side and reduce its precision
int lowestPrecision = Math.min(me.getPrecision().ordinal(), theOther.getPrecision().ordinal());
TemporalPrecisionEnum lowestPrecisionEnum = TemporalPrecisionEnum.values()[lowestPrecision];
if (me.getPrecision() != lowestPrecisionEnum) {
me = new DateTimeType(me.getValueAsString());
me.setPrecision(lowestPrecisionEnum);
}
if (theOther.getPrecision() != lowestPrecisionEnum) {
theOther = new DateTimeType(theOther.getValueAsString());
theOther.setPrecision(lowestPrecisionEnum);
}
if (me.hasTimezoneIfRequired() != theOther.hasTimezoneIfRequired()) {
if (me.getPrecision() == theOther.getPrecision()) {
if (me.getPrecision().ordinal() >= TemporalPrecisionEnum.MINUTE.ordinal() && theOther.getPrecision().ordinal() >= TemporalPrecisionEnum.MINUTE.ordinal()) {
boolean couldBeTheSameTime = couldBeTheSameTime(me, theOther) || couldBeTheSameTime(theOther, me);
if (!couldBeTheSameTime) { if (!couldBeTheSameTime) {
return false; return false;
} }
@ -889,16 +904,24 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
} }
// Same precision // Same precision
if (getPrecision() == theOther.getPrecision()) { if (me.getPrecision() == theOther.getPrecision()) {
return getValue().getTime() == theOther.getValue().getTime(); if (me.getPrecision().ordinal() >= TemporalPrecisionEnum.MINUTE.ordinal()) {
long leftTime = me.getValue().getTime();
long rightTime = theOther.getValue().getTime();
return leftTime == rightTime;
} else {
String leftTime = me.getValueAsString();
String rightTime = theOther.getValueAsString();
return leftTime.equals(rightTime);
}
} }
// Both represent 0 millis but the millis are optional // Both represent 0 millis but the millis are optional
if (((Integer)0).equals(getMillis())) { if (((Integer)0).equals(me.getMillis())) {
if (((Integer)0).equals(theOther.getMillis())) { if (((Integer)0).equals(theOther.getMillis())) {
if (getPrecision().ordinal() >= TemporalPrecisionEnum.SECOND.ordinal()) { if (me.getPrecision().ordinal() >= TemporalPrecisionEnum.SECOND.ordinal()) {
if (theOther.getPrecision().ordinal() >= TemporalPrecisionEnum.SECOND.ordinal()) { if (theOther.getPrecision().ordinal() >= TemporalPrecisionEnum.SECOND.ordinal()) {
return getValue().getTime() == theOther.getValue().getTime(); return me.getValue().getTime() == theOther.getValue().getTime();
} }
} }
} }

View File

@ -1436,13 +1436,15 @@ public class FHIRPathEngine {
} }
private List<Base> opAs(List<Base> left, List<Base> right) { private List<Base> opAs(List<Base> left, List<Base> right) {
List<Base> result = new ArrayList<Base>(); List<Base> result = new ArrayList<>();
if (left.size() != 1 || right.size() != 1) if (right.size() != 1)
return result; return result;
else { else {
String tn = convertToString(right); String tn = convertToString(right);
if (tn.equals(left.get(0).fhirType())) for (Base nextLeft : left) {
result.add(left.get(0)); if (tn.equals(nextLeft.fhirType()))
result.add(nextLeft);
}
} }
return result; return result;
} }
@ -3298,7 +3300,7 @@ public class FHIRPathEngine {
if (s.startsWith("#")) { if (s.startsWith("#")) {
Property p = context.resource.getChildByName("contained"); Property p = context.resource.getChildByName("contained");
for (Base c : p.getValues()) { for (Base c : p.getValues()) {
if (s.substring(1).equals(c.getIdBase())) { if (chompHash(s).equals(chompHash(c.getIdBase()))) {
res = c; res = c;
break; break;
} }
@ -3314,6 +3316,17 @@ public class FHIRPathEngine {
return result; return result;
} }
/**
* Strips a leading hashmark (#) if present at the start of a string
*/
private String chompHash(String theId) {
String retVal = theId;
while (retVal.startsWith("#")) {
retVal = retVal.substring(1);
}
return retVal;
}
private List<Base> funcExtension(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws FHIRException { private List<Base> funcExtension(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws FHIRException {
List<Base> result = new ArrayList<Base>(); List<Base> result = new ArrayList<Base>();
List<Base> nl = execute(context, focus, exp.getParameters().get(0), true); List<Base> nl = execute(context, focus, exp.getParameters().get(0), true);

View File

@ -111,7 +111,7 @@
<a href="Patient/f201">Roel</a> <a href="Patient/f201">Roel</a>
</p> </p>
<p> <p>
<b>authored</b>: 18/06/2013 9:00:00 AM <b>authored</b>: Jun. 17, 2013, 7:00:00 p.m.
</p> </p>
<p> <p>
<b>author</b>: <b>author</b>: