package org.openmhealth.shim.common.mapper;
import org.openmhealth.schema.domain.omh.DataPoint;
import org.openmhealth.schema.domain.omh.SchemaId;
import org.openmhealth.schema.domain.omh.SchemaSupport;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import static java.util.Collections.singletonList;
/**
* A mapper that creates data points from one or more inputs.
*
* @param <B> the body type of the data points to create
* @param <I> the input type
* @author Emerson Farrugia
*/
public interface DataPointMapper<B extends SchemaSupport, I> {
/**
* Maps one or more inputs into one or more data points. The parameter cardinality allows a mapper to use different
* inputs to assemble a data point, e.g. combining a user profile API response and a blood pressure API response to
* build an identified blood pressure data point.
*
* @param inputs the list of inputs
* @return the list of data points mapped from those inputs
*/
List<DataPoint<B>> asDataPoints(List<I> inputs);
/**
* @see #asDataPoints(List)
*/
default List<DataPoint<B>> asDataPoints(I input) {
return asDataPoints(singletonList(input));
}
/**
* Gets the schema identifier of the data point body that this mapper creates. This default implementation assumes
* that body classes have a default constructor used for serialization, and must be overridden if they don't.
*
* @return the schema identifier of the body type
*/
@SuppressWarnings("unchecked")
default SchemaId getBodySchemaId() {
try {
Class<B> bodyClass = (Class<B>)
((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
Constructor<B> bodyClassConstructor = bodyClass.getDeclaredConstructor();
bodyClassConstructor.setAccessible(true);
return bodyClassConstructor.newInstance().getSchemaId();
}
catch (NoSuchMethodException | InstantiationException | InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}