/* Copyright (C) 2024 José Rebelo This file is part of Gadgetbridge. Gadgetbridge is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Gadgetbridge is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.model; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import com.google.gson.typeadapters.RuntimeTypeAdapterFactory; import org.apache.commons.lang3.StringUtils; import java.lang.reflect.Type; import java.util.LinkedHashMap; import java.util.Set; import nodomain.freeyourgadget.gadgetbridge.activities.workouts.entries.ActivitySummaryEntry; import nodomain.freeyourgadget.gadgetbridge.activities.workouts.entries.ActivitySummaryProgressEntry; import nodomain.freeyourgadget.gadgetbridge.activities.workouts.entries.ActivitySummarySimpleEntry; import nodomain.freeyourgadget.gadgetbridge.activities.workouts.entries.ActivitySummaryTableRowEntry; /** * A small wrapper for a JSONObject, with helper methods to add activity summary data in the format * Gadgetbridge expects. */ public class ActivitySummaryData { private static final Gson GSON = new GsonBuilder() .registerTypeAdapterFactory(RuntimeTypeAdapterFactory .of(ActivitySummaryEntry.class, "type") .registerSubtype(ActivitySummarySimpleEntry.class, null) // no type for backwards compatibility .registerSubtype(ActivitySummaryProgressEntry.class, "progress") .registerSubtype(ActivitySummaryTableRowEntry.class, "tableRow") .recognizeSubtypes() ) //.serializeNulls() //.setPrettyPrinting() .create(); private final LinkedHashMap entries; public ActivitySummaryData() { this.entries = new LinkedHashMap<>(); } public ActivitySummaryData(final LinkedHashMap entries) { this.entries = entries; } public void add(final String key, final Number value, final String unit) { add(null, key, value, unit, false); } public void add(final String key, final Number value, final String unit, boolean forceDisplay) { add(null, key, value, unit, forceDisplay); } public void add(final String group, final String key, final Number value, final String unit) { add(group, key, value, unit, false); } public void add(final String group, final String key, final Number value, final String unit, boolean forceDisplay) { if (value.doubleValue() != 0 || forceDisplay) { entries.put(key, new ActivitySummarySimpleEntry(group, value, unit)); } } public void add(final String key, final String value) { add(null, key, value); } public void add(final String group, final String key, final String value) { if (StringUtils.isBlank(key) || StringUtils.isBlank(value)) { return; } entries.put(key, new ActivitySummarySimpleEntry(group, value, ActivitySummaryEntries.UNIT_STRING)); } public void add(final String key, final ActivitySummaryEntry entry) { entries.put(key, entry); } public Set getKeys() { return entries.keySet(); } public ActivitySummaryEntry get(final String key) { return entries.get(key); } public boolean has(final String key) { return entries.containsKey(key); } public Number getNumber(final String key, final Number defaultValue) { final ActivitySummaryEntry entry = entries.get(key); if (!(entry instanceof ActivitySummarySimpleEntry)) { return defaultValue; } final ActivitySummarySimpleEntry simpleEntry = (ActivitySummarySimpleEntry) entry; final Object value = simpleEntry.getValue(); if (!(value instanceof Number)) { return defaultValue; } return ((Number) value).doubleValue(); } public boolean getBoolean(final String key, final boolean defaultValue) { final ActivitySummaryEntry entry = entries.get(key); if (!(entry instanceof ActivitySummarySimpleEntry)) { return defaultValue; } final ActivitySummarySimpleEntry simpleEntry = (ActivitySummarySimpleEntry) entry; final Object value = simpleEntry.getValue(); if (value instanceof Boolean) { return (boolean) value; } if (!(value instanceof String)) { return defaultValue; } return Boolean.parseBoolean((String) value); } @Nullable public static ActivitySummaryData fromJson(final String string) { if (StringUtils.isBlank(string)) { return null; } final Type type = new TypeToken>(){}.getType(); final LinkedHashMap entries = GSON.fromJson(string, type); return new ActivitySummaryData(entries); } @NonNull @Override public String toString() { return toJson(); } public String toJson() { return GSON.toJson(entries); } }