Skip to content

Commit

Permalink
Merge branch 'master' into add-timezone-offset-test
Browse files Browse the repository at this point in the history
  • Loading branch information
JPercival authored Oct 15, 2024
2 parents 64d97a6 + a7c1636 commit fa3ef71
Show file tree
Hide file tree
Showing 11 changed files with 702 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public boolean isFhirType(Object value) {
}

@Override
public Iterable<Object> toFhirTypes(Iterable<?> values) {
public List<Object> toFhirTypes(Iterable<?> values) {
List<Object> converted = new ArrayList<>();
for (Object value : values) {
if (value == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,86 @@ public ICompositeType toFhirRange(Interval value) {
return range;
}

private static BooleanType emptyBooleanWithExtension(String url, Type value) {
var result = new BooleanType((String) null);
result.addExtension().setUrl(url).setValue(value);
return result;
}

private static void addPartWithNameAndValue(
Parameters.ParametersParameterComponent param, String key, Object value) {
if (value instanceof Parameters.ParametersParameterComponent) {
var part = (Parameters.ParametersParameterComponent) value;
part.setName(key);
param.addPart(part);
} else {
var part = param.addPart().setName(key);
if (value instanceof Resource) {
part.setResource((Resource) value);
} else if (value instanceof Type) {
part.setValue((Type) value);
} else {
throw new IllegalArgumentException(
"Unsupported FHIR type: " + value.getClass().getName());
}
}
}

private static Iterable<?> asIterable(Object value) {
if (value instanceof Iterable) {
return (Iterable<?>) value;
} else {
return null;
}
}

private void addElementToParameter(Parameters.ParametersParameterComponent param, String key, Object value) {
if (value == null) {
// Null value, add a single empty value with an extension indicating the reason
var dataAbsentValue = emptyBooleanWithExtension(
DATA_ABSENT_REASON_EXT_URL, new CodeType(DATA_ABSENT_REASON_UNKNOWN_CODE));
addPartWithNameAndValue(param, key, dataAbsentValue);
return;
}

var iterable = asIterable(value);
if (iterable == null) {
// Single, non-null value
addPartWithNameAndValue(param, key, toFhirType(value));
return;
}

if (!iterable.iterator().hasNext()) {
// Empty list
var emptyListValue = emptyBooleanWithExtension(EMPTY_LIST_EXT_URL, new BooleanType(true));
addPartWithNameAndValue(param, key, emptyListValue);
} else {
// Non-empty list, one part per value
var fhirTypes = this.toFhirTypes(iterable);
for (var fhirType : fhirTypes) {
addPartWithNameAndValue(param, key, fhirType);
}
}
}

@Override
public IBase toFhirTuple(Tuple value) {
if (value == null) {
return null;
}

throw new NotImplementedException("can't convert Tuples");
var parameters = new Parameters();
var param = parameters.addParameter();

if (value.getElements().isEmpty()) {
param.setValue(emptyBooleanWithExtension(EMPTY_TUPLE_EXT_URL, new BooleanType(true)));
}

for (String key : value.getElements().keySet()) {
addElementToParameter(param, key, value.getElements().get(key));
}

return param;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,13 +220,86 @@ public ICompositeType toFhirRange(Interval value) {
return range;
}

private static BooleanType emptyBooleanWithExtension(String url, Type value) {
var result = new BooleanType((String) null);
result.addExtension().setUrl(url).setValue(value);
return result;
}

private static void addPartWithNameAndValue(
Parameters.ParametersParameterComponent param, String key, Object value) {
if (value instanceof Parameters.ParametersParameterComponent) {
var part = (Parameters.ParametersParameterComponent) value;
part.setName(key);
param.addPart(part);
} else {
var part = param.addPart().setName(key);
if (value instanceof Resource) {
part.setResource((Resource) value);
} else if (value instanceof Type) {
part.setValue((Type) value);
} else {
throw new IllegalArgumentException(
"Unsupported FHIR type: " + value.getClass().getName());
}
}
}

private static Iterable<?> asIterable(Object value) {
if (value instanceof Iterable) {
return (Iterable<?>) value;
} else {
return null;
}
}

private void addElementToParameter(Parameters.ParametersParameterComponent param, String key, Object value) {
if (value == null) {
// Null value, add a single empty value with an extension indicating the reason
var dataAbsentValue = emptyBooleanWithExtension(
DATA_ABSENT_REASON_EXT_URL, new CodeType(DATA_ABSENT_REASON_UNKNOWN_CODE));
addPartWithNameAndValue(param, key, dataAbsentValue);
return;
}

var iterable = asIterable(value);
if (iterable == null) {
// Single, non-null value
addPartWithNameAndValue(param, key, toFhirType(value));
return;
}

if (!iterable.iterator().hasNext()) {
// Empty list
var emptyListValue = emptyBooleanWithExtension(EMPTY_LIST_EXT_URL, new BooleanType(true));
addPartWithNameAndValue(param, key, emptyListValue);
} else {
// Non-empty list, one part per value
var fhirTypes = this.toFhirTypes(iterable);
for (var fhirType : fhirTypes) {
addPartWithNameAndValue(param, key, fhirType);
}
}
}

@Override
public IBase toFhirTuple(Tuple value) {
if (value == null) {
return null;
}

throw new NotImplementedException("can't convert Tuples");
var parameters = new Parameters();
var param = parameters.addParameter();

if (value.getElements().isEmpty()) {
param.setValue(emptyBooleanWithExtension(EMPTY_TUPLE_EXT_URL, new BooleanType(true)));
}

for (String key : value.getElements().keySet()) {
addElementToParameter(param, key, value.getElements().get(key));
}

return param;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.opencds.cqf.cql.engine.fhir.converter;

import java.math.BigDecimal;
import java.util.List;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseCoding;
import org.hl7.fhir.instance.model.api.ICompositeType;
Expand Down Expand Up @@ -28,6 +29,12 @@
*/
public interface FhirTypeConverter {

static final String EMPTY_LIST_EXT_URL = "http://hl7.org/fhir/StructureDefinition/cqf-isEmptyList";
static final String EMPTY_TUPLE_EXT_URL = "http://hl7.org/fhir/StructureDefinition/cqf-isEmptyTuple";
static final String DATA_ABSENT_REASON_EXT_URL = "http://hl7.org/fhir/StructureDefinition/data-absent-reason";
static final String DATA_ABSENT_REASON_UNKNOWN_CODE = "unknown";
static final String CQL_TYPE_EXT_URL = "http://hl7.org/fhir/StructureDefinition/cqf-cqlType";

// CQL-to-FHIR conversions

/**
Expand All @@ -53,9 +60,9 @@ public interface FhirTypeConverter {
* nulls, and sublist hierarchy
*
* @param values an Iterable containing CQL structures, nulls, or sublists
* @return an Iterable containing FHIR types, nulls, and sublists
* @return an List containing FHIR types, nulls, and sublists
*/
public Iterable<Object> toFhirTypes(Iterable<?> values);
public List<Object> toFhirTypes(Iterable<?> values);

/**
* Converts a String to a FHIR Id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ public ICompositeType toFhirPeriod(Interval value) {

return period;
} else if (getSimpleName(value.getPointType().getTypeName()).equals("Date")) {
// TODO: This will construct DateTimeType values in FHIR with the system timezone id, not the
// TODO: This will construct DateTimeType values in FHIR with the system
// timezone id, not the
// timezoneoffset of the evaluation request..... this is a bug waiting to happen
if (value.getStart() != null) {
period.setStart(toFhirDate((Date) value.getStart()).getValue());
Expand Down Expand Up @@ -212,13 +213,86 @@ public ICompositeType toFhirRange(Interval value) {
return range;
}

private static BooleanType emptyBooleanWithExtension(String url, Type value) {
var result = new BooleanType((String) null);
result.addExtension().setUrl(url).setValue(value);
return result;
}

private static void addPartWithNameAndValue(
Parameters.ParametersParameterComponent param, String key, Object value) {
if (value instanceof Parameters.ParametersParameterComponent) {
var part = (Parameters.ParametersParameterComponent) value;
part.setName(key);
param.addPart(part);
} else {
var part = param.addPart().setName(key);
if (value instanceof Resource) {
part.setResource((Resource) value);
} else if (value instanceof Type) {
part.setValue((Type) value);
} else {
throw new IllegalArgumentException(
"Unsupported FHIR type: " + value.getClass().getName());
}
}
}

private static Iterable<?> asIterable(Object value) {
if (value instanceof Iterable) {
return (Iterable<?>) value;
} else {
return null;
}
}

private void addElementToParameter(Parameters.ParametersParameterComponent param, String key, Object value) {
if (value == null) {
// Null value, add a single empty value with an extension indicating the reason
var dataAbsentValue = emptyBooleanWithExtension(
DATA_ABSENT_REASON_EXT_URL, new CodeType(DATA_ABSENT_REASON_UNKNOWN_CODE));
addPartWithNameAndValue(param, key, dataAbsentValue);
return;
}

var iterable = asIterable(value);
if (iterable == null) {
// Single, non-null value
addPartWithNameAndValue(param, key, toFhirType(value));
return;
}

if (!iterable.iterator().hasNext()) {
// Empty list
var emptyListValue = emptyBooleanWithExtension(EMPTY_LIST_EXT_URL, new BooleanType(true));
addPartWithNameAndValue(param, key, emptyListValue);
} else {
// Non-empty list, one part per value
var fhirTypes = this.toFhirTypes(iterable);
for (var fhirType : fhirTypes) {
addPartWithNameAndValue(param, key, fhirType);
}
}
}

@Override
public IBase toFhirTuple(Tuple value) {
if (value == null) {
return null;
}

throw new NotImplementedException("can't convert Tuples");
var parameters = new Parameters();
var param = parameters.addParameter();

if (value.getElements().isEmpty()) {
param.setValue(emptyBooleanWithExtension(EMPTY_TUPLE_EXT_URL, new BooleanType(true)));
}

for (String key : value.getElements().keySet()) {
addElementToParameter(param, key, value.getElements().get(key));
}

return param;
}

@Override
Expand Down
Loading

0 comments on commit fa3ef71

Please sign in to comment.