Work on #873
This commit is contained in:
parent
ecf570ced9
commit
b2ceb87a70
File diff suppressed because it is too large
Load Diff
|
@ -1,27 +1,59 @@
|
|||
package org.hl7.fhir.r4.utils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
import org.fhir.ucum.Decimal;
|
||||
import org.fhir.ucum.UcumException;
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.PathEngineException;
|
||||
import org.hl7.fhir.r4.conformance.ProfileUtilities;
|
||||
import org.hl7.fhir.r4.context.IWorkerContext;
|
||||
import org.hl7.fhir.r4.model.*;
|
||||
import org.hl7.fhir.r4.elementmodel.Element;
|
||||
import org.hl7.fhir.r4.elementmodel.ObjectConverter;
|
||||
import org.hl7.fhir.r4.model.Base;
|
||||
import org.hl7.fhir.r4.model.BooleanType;
|
||||
import org.hl7.fhir.r4.model.Coding;
|
||||
import org.hl7.fhir.r4.model.DateTimeType;
|
||||
import org.hl7.fhir.r4.model.DateType;
|
||||
import org.hl7.fhir.r4.model.DecimalType;
|
||||
import org.hl7.fhir.r4.model.ElementDefinition;
|
||||
import org.hl7.fhir.r4.model.ElementDefinition.TypeRefComponent;
|
||||
import org.hl7.fhir.r4.model.ExpressionNode.*;
|
||||
import org.hl7.fhir.r4.model.ExpressionNode;
|
||||
import org.hl7.fhir.r4.model.ExpressionNode.CollectionStatus;
|
||||
import org.hl7.fhir.r4.model.ExpressionNode.Function;
|
||||
import org.hl7.fhir.r4.model.ExpressionNode.Kind;
|
||||
import org.hl7.fhir.r4.model.ExpressionNode.Operation;
|
||||
import org.hl7.fhir.r4.model.ExpressionNode.SourceLocation;
|
||||
import org.hl7.fhir.r4.model.IntegerType;
|
||||
import org.hl7.fhir.r4.model.Property;
|
||||
import org.hl7.fhir.r4.model.Resource;
|
||||
import org.hl7.fhir.r4.model.StringType;
|
||||
import org.hl7.fhir.r4.model.StructureDefinition;
|
||||
import org.hl7.fhir.r4.model.StructureDefinition.StructureDefinitionKind;
|
||||
import org.hl7.fhir.r4.model.StructureDefinition.TypeDerivationRule;
|
||||
//import org.hl7.fhir.r4.model.TemporalPrecisionEnum;
|
||||
import org.hl7.fhir.r4.model.TimeType;
|
||||
import org.hl7.fhir.r4.model.TypeDetails;
|
||||
import org.hl7.fhir.r4.model.ValueSet;
|
||||
import org.hl7.fhir.r4.model.TypeDetails.ProfiledType;
|
||||
import org.hl7.fhir.r4.utils.FHIRLexer.FHIRLexerException;
|
||||
import org.hl7.fhir.r4.utils.FHIRPathEngine.IEvaluationContext.FunctionDetails;
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.PathEngineException;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.fhir.ucum.Decimal;
|
||||
import org.fhir.ucum.UcumException;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.length;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -282,6 +314,21 @@ public class FHIRPathEngine {
|
|||
return check(appContext, resourceType, context, parse(expr));
|
||||
}
|
||||
|
||||
private int compareDateTimeElements(Base theL, Base theR) {
|
||||
String dateLeftString = theL.primitiveValue();
|
||||
if (length(dateLeftString) > 10) {
|
||||
DateTimeType dateLeft = new DateTimeType(dateLeftString);
|
||||
dateLeft.setTimeZoneZulu(true);
|
||||
dateLeftString = dateLeft.getValueAsString();
|
||||
}
|
||||
String dateRightString = theR.primitiveValue();
|
||||
if (length(dateRightString) > 10) {
|
||||
DateTimeType dateRight = new DateTimeType(dateRightString);
|
||||
dateRight.setTimeZoneZulu(true);
|
||||
dateRightString = dateRight.getValueAsString();
|
||||
}
|
||||
return dateLeftString.compareTo(dateRightString);
|
||||
}
|
||||
|
||||
/**
|
||||
* evaluate a path and return the matching elements
|
||||
|
@ -1191,6 +1238,8 @@ public class FHIRPathEngine {
|
|||
result.addType("decimal");
|
||||
return result;
|
||||
case Concatenate:
|
||||
result = new TypeDetails(CollectionStatus.SINGLETON, "");
|
||||
return result;
|
||||
case Plus:
|
||||
result = new TypeDetails(CollectionStatus.SINGLETON);
|
||||
if (left.hasType(worker, "integer") && right.hasType(worker, "integer"))
|
||||
|
@ -1267,7 +1316,7 @@ public class FHIRPathEngine {
|
|||
if (left.hasType("integer", "decimal", "unsignedInt", "positiveInt") && right.hasType("integer", "decimal", "unsignedInt", "positiveInt"))
|
||||
return Utilities.equivalentNumber(left.primitiveValue(), right.primitiveValue());
|
||||
if (left.hasType("date", "dateTime", "time", "instant") && right.hasType("date", "dateTime", "time", "instant"))
|
||||
return Utilities.equivalentNumber(left.primitiveValue(), right.primitiveValue());
|
||||
return compareDateTimeElements(left, right) == 0;
|
||||
if (left.hasType("string", "id", "code", "uri") && right.hasType("string", "id", "code", "uri"))
|
||||
return Utilities.equivalent(convertToString(left), convertToString(right));
|
||||
|
||||
|
@ -1324,8 +1373,8 @@ public class FHIRPathEngine {
|
|||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) < 0);
|
||||
else if ((l.hasType("integer") || l.hasType("decimal")) && (r.hasType("integer") || r.hasType("decimal")))
|
||||
return makeBoolean(new Double(l.primitiveValue()) < new Double(r.primitiveValue()));
|
||||
else if ((l.hasType("date", "dateTime", "instant")) && (r.hasType("date", "dateTime", "instant")))
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) < 0);
|
||||
else if ((l.hasType("date", "dateTime", "instant")) && (r.hasType("date", "dateTime", "instant")))
|
||||
return makeBoolean(compareDateTimeElements(l, r) < 0);
|
||||
else if ((l.hasType("time")) && (r.hasType("time")))
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) < 0);
|
||||
} else if (left.size() == 1 && right.size() == 1 && left.get(0).fhirType().equals("Quantity") && right.get(0).fhirType().equals("Quantity") ) {
|
||||
|
@ -1348,8 +1397,8 @@ public class FHIRPathEngine {
|
|||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) > 0);
|
||||
else if ((l.hasType("integer", "decimal", "unsignedInt", "positiveInt")) && (r.hasType("integer", "decimal", "unsignedInt", "positiveInt")))
|
||||
return makeBoolean(new Double(l.primitiveValue()) > new Double(r.primitiveValue()));
|
||||
else if ((l.hasType("date", "dateTime", "instant")) && (r.hasType("date", "dateTime", "instant")))
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) > 0);
|
||||
else if ((l.hasType("date", "dateTime", "instant")) && (r.hasType("date", "dateTime", "instant")))
|
||||
return makeBoolean(compareDateTimeElements(l, r) > 0);
|
||||
else if ((l.hasType("time")) && (r.hasType("time")))
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) > 0);
|
||||
} else if (left.size() == 1 && right.size() == 1 && left.get(0).fhirType().equals("Quantity") && right.get(0).fhirType().equals("Quantity") ) {
|
||||
|
@ -1372,8 +1421,8 @@ public class FHIRPathEngine {
|
|||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) <= 0);
|
||||
else if ((l.hasType("integer", "decimal", "unsignedInt", "positiveInt")) && (r.hasType("integer", "decimal", "unsignedInt", "positiveInt")))
|
||||
return makeBoolean(new Double(l.primitiveValue()) <= new Double(r.primitiveValue()));
|
||||
else if ((l.hasType("date", "dateTime", "instant")) && (r.hasType("date", "dateTime", "instant")))
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) <= 0);
|
||||
else if ((l.hasType("date", "dateTime", "instant")) && (r.hasType("date", "dateTime", "instant")))
|
||||
return makeBoolean(compareDateTimeElements(l, r) <= 0);
|
||||
else if ((l.hasType("time")) && (r.hasType("time")))
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) <= 0);
|
||||
} else if (left.size() == 1 && right.size() == 1 && left.get(0).fhirType().equals("Quantity") && right.get(0).fhirType().equals("Quantity") ) {
|
||||
|
@ -1398,8 +1447,8 @@ public class FHIRPathEngine {
|
|||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) >= 0);
|
||||
else if ((l.hasType("integer", "decimal", "unsignedInt", "positiveInt")) && (r.hasType("integer", "decimal", "unsignedInt", "positiveInt")))
|
||||
return makeBoolean(new Double(l.primitiveValue()) >= new Double(r.primitiveValue()));
|
||||
else if ((l.hasType("date", "dateTime", "instant")) && (r.hasType("date", "dateTime", "instant")))
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) >= 0);
|
||||
else if ((l.hasType("date", "dateTime", "instant")) && (r.hasType("date", "dateTime", "instant")))
|
||||
return makeBoolean(compareDateTimeElements(l, r) >= 0);
|
||||
else if ((l.hasType("time")) && (r.hasType("time")))
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) >= 0);
|
||||
} else if (left.size() == 1 && right.size() == 1 && left.get(0).fhirType().equals("Quantity") && right.get(0).fhirType().equals("Quantity") ) {
|
||||
|
@ -2209,8 +2258,34 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
|
||||
private List<Base> funcReplace(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
||||
throw new Error("not Implemented yet");
|
||||
private List<Base> funcReplace(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws FHIRException, PathEngineException {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
|
||||
if (focus.size() == 1) {
|
||||
String f = convertToString(focus.get(0));
|
||||
|
||||
if (!Utilities.noString(f)) {
|
||||
|
||||
if (exp.getParameters().size() != 2) {
|
||||
|
||||
String t = convertToString(execute(context, focus, exp.getParameters().get(0), true));
|
||||
String r = convertToString(execute(context, focus, exp.getParameters().get(1), true));
|
||||
|
||||
String n = f.replace(t, r);
|
||||
result.add(new StringType(n));
|
||||
}
|
||||
else {
|
||||
throw new PathEngineException(String.format("funcReplace() : checking for 2 arguments (pattern, substitution) but found %d items", exp.getParameters().size()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new PathEngineException(String.format("funcReplace() : checking for 1 string item but found empty item"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new PathEngineException(String.format("funcReplace() : checking for 1 string item but found %d items", focus.size()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package org.hl7.fhir.dstu3.hapi.validation;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.composite.PeriodDt;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.ProcedureStatusEnum;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
import ca.uhn.fhir.validation.ResultSeverityEnum;
|
||||
|
@ -64,6 +67,34 @@ public class FhirInstanceValidatorDstu3Test {
|
|||
myValidConcepts.add(theSystem + "___" + theCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* See #873
|
||||
*/
|
||||
@Test
|
||||
public void testCompareTimesWithDifferentTimezones() {
|
||||
Procedure procedure = new Procedure();
|
||||
procedure.setStatus(Procedure.ProcedureStatus.COMPLETED);
|
||||
procedure.getSubject().setReference("Patient/1");
|
||||
procedure.getCode().setText("Some proc");
|
||||
|
||||
Period period = new Period();
|
||||
period.setStartElement(new DateTimeType("2000-01-01T00:00:01+05:00"));
|
||||
period.setEndElement(new DateTimeType("2000-01-01T00:00:00+04:00"));
|
||||
assertThat(period.getStart().getTime(), lessThan(period.getEnd().getTime()));
|
||||
procedure.setPerformed(period);
|
||||
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.registerValidatorModule(new FhirInstanceValidator(myDefaultValidationSupport));
|
||||
|
||||
ValidationResult result = val.validateWithResult(procedure);
|
||||
|
||||
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome());
|
||||
ourLog.info(encoded);
|
||||
|
||||
assertTrue(result.isSuccessful());
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Before
|
||||
public void before() {
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
package org.hl7.fhir.instance.hapi.validation;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.composite.PeriodDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Parameters;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Procedure;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.ProcedureStatusEnum;
|
||||
import ca.uhn.fhir.model.primitive.DateDt;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
|
@ -23,6 +27,7 @@ import org.junit.Test;
|
|||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.lessThan;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
@ -49,34 +54,6 @@ public class FhirInstanceValidatorTest {
|
|||
assertTrue(result.isSuccessful());
|
||||
}
|
||||
|
||||
/*
|
||||
* {
|
||||
"resourceType": "Observation",
|
||||
"meta": {
|
||||
"profile": [
|
||||
"http://example.com/foo/bar/testValidateResourceContainingProfileDeclarationJson"
|
||||
]
|
||||
},
|
||||
"identifier": [
|
||||
{
|
||||
"system": "http://acme",
|
||||
"value": "12345"
|
||||
}
|
||||
],
|
||||
"status": "final",
|
||||
"code": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "12345"
|
||||
}
|
||||
]
|
||||
},
|
||||
"encounter": {
|
||||
"reference": "http://foo.com/Encounter/9"
|
||||
}
|
||||
}
|
||||
*/
|
||||
@Test
|
||||
public void testObservation() {
|
||||
Observation o = new Observation();
|
||||
|
@ -97,6 +74,34 @@ public class FhirInstanceValidatorTest {
|
|||
assertTrue(result.isSuccessful());
|
||||
}
|
||||
|
||||
/**
|
||||
* See #873
|
||||
*/
|
||||
@Test
|
||||
public void testCompareTimesWithDifferentTimezones() {
|
||||
Procedure procedure = new Procedure();
|
||||
procedure.setStatus(ProcedureStatusEnum.COMPLETED);
|
||||
procedure.getSubject().setReference("Patient/1");
|
||||
procedure.getCode().setText("Some proc");
|
||||
|
||||
PeriodDt period = new PeriodDt();
|
||||
period.setStart(new DateTimeDt("2000-01-01T00:00:01+05:00"));
|
||||
period.setEnd(new DateTimeDt("2000-01-01T00:00:00+04:00"));
|
||||
assertThat(period.getStart().getTime(), lessThan(period.getEnd().getTime()));
|
||||
procedure.setPerformed(period);
|
||||
|
||||
FhirValidator val = ourCtxDstu2.newValidator();
|
||||
|
||||
val.registerValidatorModule(ourValidator);
|
||||
|
||||
ValidationResult result = val.validateWithResult(procedure);
|
||||
|
||||
String encoded = ourCtxDstu2.newJsonParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome());
|
||||
ourLog.info(encoded);
|
||||
|
||||
assertTrue(result.isSuccessful());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParametersHl7OrgDstu2() {
|
||||
org.hl7.fhir.instance.model.Patient patient = new org.hl7.fhir.instance.model.Patient();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue