package org.session.libsession.messaging.jobs; import android.os.Parcelable; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.fasterxml.jackson.annotation.JsonProperty; import org.session.libsession.utilities.ParcelableUtil; import java.util.HashMap; import java.util.Map; // Introduce a dedicated Map field specifically for parcelable needs. public class Data { public static final Data EMPTY = new Data.Builder().build(); @JsonProperty private final Map strings; @JsonProperty private final Map stringArrays; @JsonProperty private final Map integers; @JsonProperty private final Map integerArrays; @JsonProperty private final Map longs; @JsonProperty private final Map longArrays; @JsonProperty private final Map floats; @JsonProperty private final Map floatArrays; @JsonProperty private final Map doubles; @JsonProperty private final Map doubleArrays; @JsonProperty private final Map booleans; @JsonProperty private final Map booleanArrays; @JsonProperty private final Map byteArrays; public Data(@JsonProperty("strings") @NonNull Map strings, @JsonProperty("stringArrays") @NonNull Map stringArrays, @JsonProperty("integers") @NonNull Map integers, @JsonProperty("integerArrays") @NonNull Map integerArrays, @JsonProperty("longs") @NonNull Map longs, @JsonProperty("longArrays") @NonNull Map longArrays, @JsonProperty("floats") @NonNull Map floats, @JsonProperty("floatArrays") @NonNull Map floatArrays, @JsonProperty("doubles") @NonNull Map doubles, @JsonProperty("doubleArrays") @NonNull Map doubleArrays, @JsonProperty("booleans") @NonNull Map booleans, @JsonProperty("booleanArrays") @NonNull Map booleanArrays, @JsonProperty("byteArrays") @NonNull Map byteArrays) { this.strings = strings; this.stringArrays = stringArrays; this.integers = integers; this.integerArrays = integerArrays; this.longs = longs; this.longArrays = longArrays; this.floats = floats; this.floatArrays = floatArrays; this.doubles = doubles; this.doubleArrays = doubleArrays; this.booleans = booleans; this.booleanArrays = booleanArrays; this.byteArrays = byteArrays; } public boolean hasString(@NonNull String key) { return strings.containsKey(key); } public String getString(@NonNull String key) { throwIfAbsent(strings, key); return strings.get(key); } public String getStringOrDefault(@NonNull String key, String defaultValue) { if (hasString(key)) return getString(key); else return defaultValue; } public boolean hasStringArray(@NonNull String key) { return stringArrays.containsKey(key); } public String[] getStringArray(@NonNull String key) { throwIfAbsent(stringArrays, key); return stringArrays.get(key); } public boolean hasInt(@NonNull String key) { return integers.containsKey(key); } public int getInt(@NonNull String key) { throwIfAbsent(integers, key); return integers.get(key); } public int getIntOrDefault(@NonNull String key, int defaultValue) { if (hasInt(key)) return getInt(key); else return defaultValue; } public boolean hasIntegerArray(@NonNull String key) { return integerArrays.containsKey(key); } public int[] getIntegerArray(@NonNull String key) { throwIfAbsent(integerArrays, key); return integerArrays.get(key); } public boolean hasLong(@NonNull String key) { return longs.containsKey(key); } public long getLong(@NonNull String key) { throwIfAbsent(longs, key); return longs.get(key); } public long getLongOrDefault(@NonNull String key, long defaultValue) { if (hasLong(key)) return getLong(key); else return defaultValue; } public boolean hasLongArray(@NonNull String key) { return longArrays.containsKey(key); } public long[] getLongArray(@NonNull String key) { throwIfAbsent(longArrays, key); return longArrays.get(key); } public boolean hasFloat(@NonNull String key) { return floats.containsKey(key); } public float getFloat(@NonNull String key) { throwIfAbsent(floats, key); return floats.get(key); } public float getFloatOrDefault(@NonNull String key, float defaultValue) { if (hasFloat(key)) return getFloat(key); else return defaultValue; } public boolean hasFloatArray(@NonNull String key) { return floatArrays.containsKey(key); } public float[] getFloatArray(@NonNull String key) { throwIfAbsent(floatArrays, key); return floatArrays.get(key); } public boolean hasDouble(@NonNull String key) { return doubles.containsKey(key); } public double getDouble(@NonNull String key) { throwIfAbsent(doubles, key); return doubles.get(key); } public double getDoubleOrDefault(@NonNull String key, double defaultValue) { if (hasDouble(key)) return getDouble(key); else return defaultValue; } public boolean hasDoubleArray(@NonNull String key) { return floatArrays.containsKey(key); } public double[] getDoubleArray(@NonNull String key) { throwIfAbsent(doubleArrays, key); return doubleArrays.get(key); } public boolean hasBoolean(@NonNull String key) { return booleans.containsKey(key); } public boolean getBoolean(@NonNull String key) { throwIfAbsent(booleans, key); return booleans.get(key); } public boolean getBooleanOrDefault(@NonNull String key, boolean defaultValue) { if (hasBoolean(key)) return getBoolean(key); else return defaultValue; } public boolean hasBooleanArray(@NonNull String key) { return booleanArrays.containsKey(key); } public boolean[] getBooleanArray(@NonNull String key) { throwIfAbsent(booleanArrays, key); return booleanArrays.get(key); } public boolean hasByteArray(@NonNull String key) { return byteArrays.containsKey(key); } public byte[] getByteArray(@NonNull String key) { throwIfAbsent(byteArrays, key); return byteArrays.get(key); } public boolean hasParcelable(@NonNull String key) { return byteArrays.containsKey(key); } public T getParcelable(@NonNull String key, @NonNull Parcelable.Creator creator) { throwIfAbsent(byteArrays, key); byte[] bytes = byteArrays.get(key); return ParcelableUtil.unmarshall(bytes, creator); } private void throwIfAbsent(@NonNull Map map, @NonNull String key) { if (!map.containsKey(key)) { throw new IllegalStateException("Tried to retrieve a value with key '" + key + "', but it wasn't present."); } } public static class Builder { private final Map strings = new HashMap<>(); private final Map stringArrays = new HashMap<>(); private final Map integers = new HashMap<>(); private final Map integerArrays = new HashMap<>(); private final Map longs = new HashMap<>(); private final Map longArrays = new HashMap<>(); private final Map floats = new HashMap<>(); private final Map floatArrays = new HashMap<>(); private final Map doubles = new HashMap<>(); private final Map doubleArrays = new HashMap<>(); private final Map booleans = new HashMap<>(); private final Map booleanArrays = new HashMap<>(); private final Map byteArrays = new HashMap<>(); public Builder putString(@NonNull String key, @Nullable String value) { strings.put(key, value); return this; } public Builder putStringArray(@NonNull String key, @NonNull String[] value) { stringArrays.put(key, value); return this; } public Builder putInt(@NonNull String key, int value) { integers.put(key, value); return this; } public Builder putIntArray(@NonNull String key, @NonNull int[] value) { integerArrays.put(key, value); return this; } public Builder putLong(@NonNull String key, long value) { longs.put(key, value); return this; } public Builder putLongArray(@NonNull String key, @NonNull long[] value) { longArrays.put(key, value); return this; } public Builder putFloat(@NonNull String key, float value) { floats.put(key, value); return this; } public Builder putFloatArray(@NonNull String key, @NonNull float[] value) { floatArrays.put(key, value); return this; } public Builder putDouble(@NonNull String key, double value) { doubles.put(key, value); return this; } public Builder putDoubleArray(@NonNull String key, @NonNull double[] value) { doubleArrays.put(key, value); return this; } public Builder putBoolean(@NonNull String key, boolean value) { booleans.put(key, value); return this; } public Builder putBooleanArray(@NonNull String key, @NonNull boolean[] value) { booleanArrays.put(key, value); return this; } public Builder putByteArray(@NonNull String key, @NonNull byte[] value) { byteArrays.put(key, value); return this; } public Builder putParcelable(@NonNull String key, @NonNull Parcelable value) { byte[] bytes = ParcelableUtil.marshall(value); byteArrays.put(key, bytes); return this; } public Data build() { return new Data(strings, stringArrays, integers, integerArrays, longs, longArrays, floats, floatArrays, doubles, doubleArrays, booleans, booleanArrays, byteArrays); } } public interface Serializer { @NonNull String serialize(@NonNull Data data); @NonNull Data deserialize(@NonNull String serialized); } }