Java tutorial
/* * Copyright 2015 Open mHealth * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.openmhealth.shim.ihealth.mapper; import com.fasterxml.jackson.databind.JsonNode; import org.openmhealth.schema.domain.omh.*; import java.util.Optional; import static com.google.common.base.Preconditions.checkNotNull; import static org.openmhealth.shim.common.mapper.JsonNodeMappingSupport.asRequiredDouble; /** * A mapper that translates responses from the iHealth <code>/weight.json</code> endpoint into {@link BodyWeight} * measures. * * @author Chris Schaefbauer * @author Emerson Farrugia * @see <a href="http://developer.ihealthlabs.com/dev_documentation_RequestfordataofWeight.htm">endpoint * documentation</a> */ public class IHealthBodyWeightDataPointMapper extends IHealthDataPointMapper<BodyWeight> { // Reference for conversion: https://en.wikipedia.org/wiki/Stone_(unit) private static final double STONE_TO_KG_FACTOR = 6.3503; @Override protected String getListNodeName() { return "WeightDataList"; } @Override protected Optional<String> getMeasureUnitNodeName() { return Optional.of("WeightUnit"); } @Override protected Optional<DataPoint<BodyWeight>> asDataPoint(JsonNode listEntryNode, Integer measureUnitMagicNumber) { checkNotNull(measureUnitMagicNumber); IHealthBodyWeightUnit bodyWeightUnitType = IHealthBodyWeightUnit.fromIntegerValue(measureUnitMagicNumber); MassUnit bodyWeightUnit = bodyWeightUnitType.getOmhUnit(); double bodyWeightValue = getBodyWeightValueForUnitType(listEntryNode, bodyWeightUnitType); if (bodyWeightValue == 0) { return Optional.empty(); } BodyWeight.Builder bodyWeightBuilder = new BodyWeight.Builder( new MassUnitValue(bodyWeightUnit, bodyWeightValue)); getEffectiveTimeFrameAsDateTime(listEntryNode).ifPresent(bodyWeightBuilder::setEffectiveTimeFrame); getUserNoteIfExists(listEntryNode).ifPresent(bodyWeightBuilder::setUserNotes); BodyWeight bodyWeight = bodyWeightBuilder.build(); return Optional.of(new DataPoint<>(createDataPointHeader(listEntryNode, bodyWeight), bodyWeight)); } /** * @param listEntryNode A single entry from the response result array. * @param bodyWeightUnitType The unit type for the measure. * @return The body weight value for the list entry that is rendered in the correct unit. */ protected double getBodyWeightValueForUnitType(JsonNode listEntryNode, IHealthBodyWeightUnit bodyWeightUnitType) { Double weightValueFromApi = asRequiredDouble(listEntryNode, "WeightValue"); return getBodyWeightValueForUnitType(weightValueFromApi, bodyWeightUnitType); } /** * @param bodyWeightValue The body weight value that has been extracted from the list entry node. * @param bodyWeightUnitType The unit type for the measure. * @return A body weight value that is rendered in the correct unit. */ protected double getBodyWeightValueForUnitType(double bodyWeightValue, IHealthBodyWeightUnit bodyWeightUnitType) { // iHealth has one unit type that is unsupported by OMH schemas, so we need to convert the value into a unit // system that is supported by the schemas. return bodyWeightValue * bodyWeightUnitType.getConversionFactorToOmh(); } enum IHealthBodyWeightUnit { /* The conversion factor handles conversions from unsupported mass units (currently the 'Stone' unit) to omh supported units such that: ValueIntoSchema = ValueFromApi * Conversion We map STONE into KG because it is the SI unit for mass and the most widely accepted for measuring human body weight in a clinical/scientific context. */ KG(0, MassUnit.KILOGRAM, 1), LB(1, MassUnit.POUND, 1), STONE(2, MassUnit.KILOGRAM, STONE_TO_KG_FACTOR); private final MassUnit omhUnit; private final double conversionFactorToOmh; private int magicNumber; IHealthBodyWeightUnit(int magicNumber, MassUnit omhUnit, double conversionFactor) { this.omhUnit = omhUnit; this.conversionFactorToOmh = conversionFactor; this.magicNumber = magicNumber; } public MassUnit getOmhUnit() { return omhUnit; } public double getConversionFactorToOmh() { return conversionFactorToOmh; } public static IHealthBodyWeightUnit fromIntegerValue(int unitValueFromApi) { for (IHealthBodyWeightUnit type : values()) { if (type.magicNumber == unitValueFromApi) { return type; } } throw new UnsupportedOperationException(); } } }