1de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar/*
2564e43098c323d1a90be53c190b8fdbdde973505Sumir Kataria * Copyright 2018 The Android Open Source Project
3de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar *
4de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar * Licensed under the Apache License, Version 2.0 (the "License");
5de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar * you may not use this file except in compliance with the License.
6de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar * You may obtain a copy of the License at
7de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar *
8de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar *      http://www.apache.org/licenses/LICENSE-2.0
9de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar *
10de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar * Unless required by applicable law or agreed to in writing, software
11de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar * distributed under the License is distributed on an "AS IS" BASIS,
12de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar * See the License for the specific language governing permissions and
14de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar * limitations under the License.
15de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar */
16de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
17564e43098c323d1a90be53c190b8fdbdde973505Sumir Katariapackage androidx.work;
18de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
19de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagarimport android.arch.persistence.room.TypeConverter;
20d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumarimport android.support.annotation.NonNull;
215641e4d9db96738ed9960bd25f8469c4f019caaaSumir Katariaimport android.support.annotation.VisibleForTesting;
22b5728f4e1a4b3f4f1fabf033b1363ca6b1cffdefSumir Kataria
23de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagarimport java.io.ByteArrayInputStream;
24de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagarimport java.io.ByteArrayOutputStream;
25de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagarimport java.io.IOException;
26de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagarimport java.io.ObjectInputStream;
27de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagarimport java.io.ObjectOutputStream;
2818aa0f0a4d1416c8bedad720da7178d130735340Sumir Katariaimport java.util.Collections;
29de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagarimport java.util.HashMap;
30de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagarimport java.util.Map;
31de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
32de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar/**
33af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria * Persistable set of key/value pairs which are passed as inputs and outputs for {@link Worker}s.
34af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria * This is a lightweight container, and should not be considered your data store.  As such, there is
35af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria * an enforced {@link #MAX_DATA_BYTES} limit on the serialized (byte array) size of the payloads.
36af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria * This class will throw {@link IllegalStateException}s if you try to serialize or deserialize past
37af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria * this limit.
38de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar */
39de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
4064e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Katariapublic final class Data {
417fb09aaf7d3e1beb6b135738a1471c019b592c1bSumir Kataria
42af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria    public static final Data EMPTY = new Data.Builder().build();
43af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria    public static final int MAX_DATA_BYTES = 10 * 1024;    // 10KB
44af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria
4564e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria    private static final String TAG = "Data";
46a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria
47de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    private Map<String, Object> mValues;
48de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
4964e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria    Data() {    // stub required for room
501e9589d6482d2690e2eabb21f732377d268a5c05Sumir Kataria    }
511e9589d6482d2690e2eabb21f732377d268a5c05Sumir Kataria
5264e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria    Data(Map<String, ?> values) {
53de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        mValues = new HashMap<>(values);
54de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    }
55de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
56de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    /**
575641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * Get the boolean value for the given key.
58de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     *
595641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @param key The key for the argument
605641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @param defaultValue The default value to return if the key is not found
615641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @return The value specified by the key if it exists; the default value otherwise
62de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     */
635f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    public boolean getBoolean(String key, boolean defaultValue) {
64de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        Object value = mValues.get(key);
65de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        if (value instanceof Boolean) {
665f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            return (boolean) value;
67de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        } else {
68de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            return defaultValue;
69de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        }
70de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    }
71de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
72de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    /**
735f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria     * Get the boolean array value for the given key.
745f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria     *
755f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria     * @param key The key for the argument
765f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria     * @return The value specified by the key if it exists; {@code null} otherwise
775f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria     */
785f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    public boolean[] getBooleanArray(String key) {
795f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        Object value = mValues.get(key);
805f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        if (value instanceof Boolean[]) {
815f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            Boolean[] array = (Boolean[]) value;
825f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            boolean[] returnArray = new boolean[array.length];
835f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            for (int i = 0; i < array.length; ++i) {
845f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria                returnArray[i] = array[i];
855f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            }
865f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            return returnArray;
875f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        } else {
885f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            return null;
895f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        }
905f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    }
915f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria
925f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria
935f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    /**
945641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * Get the integer value for the given key.
95de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     *
965641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @param key The key for the argument
975641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @param defaultValue The default value to return if the key is not found
985641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @return The value specified by the key if it exists; the default value otherwise
99de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     */
1005f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    public int getInt(String key, int defaultValue) {
101de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        Object value = mValues.get(key);
102de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        if (value instanceof Integer) {
1035f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            return (int) value;
104de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        } else {
105de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            return defaultValue;
106de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        }
107de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    }
108de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
109de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    /**
1105641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * Get the integer array value for the given key.
111de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     *
1125641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @param key The key for the argument
1135641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @return The value specified by the key if it exists; {@code null} otherwise
114de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     */
1155f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    public int[] getIntArray(String key) {
116de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        Object value = mValues.get(key);
117a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria        if (value instanceof Integer[]) {
1185f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            Integer[] array = (Integer[]) value;
1195f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            int[] returnArray = new int[array.length];
1205f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            for (int i = 0; i < array.length; ++i) {
1215f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria                returnArray[i] = array[i];
1225f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            }
1235f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            return returnArray;
124de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        } else {
125de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            return null;
126de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        }
127de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    }
128de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
129de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    /**
1305641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * Get the long value for the given key.
131de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     *
1325641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @param key The key for the argument
1335641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @param defaultValue The default value to return if the key is not found
1345641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @return The value specified by the key if it exists; the default value otherwise
135de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     */
1365f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    public long getLong(String key, long defaultValue) {
137de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        Object value = mValues.get(key);
138de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        if (value instanceof Long) {
1395f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            return (long) value;
140de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        } else {
141de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            return defaultValue;
142de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        }
143de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    }
144de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
145de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    /**
1465641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * Get the long array value for the given key.
147de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     *
1485641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @param key The key for the argument
1495641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @return The value specified by the key if it exists; {@code null} otherwise
150de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     */
1515f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    public long[] getLongArray(String key) {
152de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        Object value = mValues.get(key);
153a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria        if (value instanceof Long[]) {
1545f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            Long[] array = (Long[]) value;
1555f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            long[] returnArray = new long[array.length];
1565f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            for (int i = 0; i < array.length; ++i) {
1575f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria                returnArray[i] = array[i];
1585f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            }
1595f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            return returnArray;
1605f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        } else {
1615f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            return null;
1625f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        }
1635f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    }
1645f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria
1655f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    /**
1665f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria     * Get the float value for the given key.
1675f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria     *
1685f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria     * @param key The key for the argument
1695f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria     * @param defaultValue The default value to return if the key is not found
1705f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria     * @return The value specified by the key if it exists; the default value otherwise
1715f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria     */
1725f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    public float getFloat(String key, float defaultValue) {
1735f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        Object value = mValues.get(key);
1745f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        if (value instanceof Float) {
1755f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            return (float) value;
1765f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        } else {
1775f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            return defaultValue;
1785f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        }
1795f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    }
1805f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria
1815f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    /**
1825f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria     * Get the float array value for the given key.
1835f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria     *
1845f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria     * @param key The key for the argument
1855f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria     * @return The value specified by the key if it exists; {@code null} otherwise
1865f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria     */
1875f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    public float[] getFloatArray(String key) {
1885f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        Object value = mValues.get(key);
1895f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        if (value instanceof Float[]) {
1905f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            Float[] array = (Float[]) value;
1915f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            float[] returnArray = new float[array.length];
1925f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            for (int i = 0; i < array.length; ++i) {
1935f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria                returnArray[i] = array[i];
1945f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            }
1955f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            return returnArray;
196de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        } else {
197de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            return null;
198de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        }
199de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    }
200de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
201de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    /**
2025641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * Get the double value for the given key.
203de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     *
2045641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @param key The key for the argument
2055641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @param defaultValue The default value to return if the key is not found
2065641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @return The value specified by the key if it exists; the default value otherwise
207de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     */
2085f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    public double getDouble(String key, double defaultValue) {
209de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        Object value = mValues.get(key);
210de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        if (value instanceof Double) {
2115f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            return (double) value;
212de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        } else {
213de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            return defaultValue;
214de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        }
215de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    }
216de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
217de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    /**
2185641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * Get the double array value for the given key.
219de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     *
2205641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @param key The key for the argument
2215641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @return The value specified by the key if it exists; {@code null} otherwise
222de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     */
2235f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    public double[] getDoubleArray(String key) {
224de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        Object value = mValues.get(key);
225a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria        if (value instanceof Double[]) {
2265f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            Double[] array = (Double[]) value;
2275f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            double[] returnArray = new double[array.length];
2285f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            for (int i = 0; i < array.length; ++i) {
2295f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria                returnArray[i] = array[i];
2305f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            }
2315f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            return returnArray;
232de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        } else {
233de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            return null;
234de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        }
235de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    }
236de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
237de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    /**
2385641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * Get the String value for the given key.
239de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     *
2405641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @param key The key for the argument
2415641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @param defaultValue The default value to return if the key is not found
2425641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @return The value specified by the key if it exists; the default value otherwise
243de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     */
244de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    public String getString(String key, String defaultValue) {
245de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        Object value = mValues.get(key);
246de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        if (value instanceof String) {
247de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            return (String) value;
248de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        } else {
249de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            return defaultValue;
250de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        }
251de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    }
252de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
253de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    /**
2545641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * Get the String array value for the given key.
255de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     *
2565641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @param key The key for the argument
2575641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @return The value specified by the key if it exists; {@code null} otherwise
258de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     */
259de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    public String[] getStringArray(String key) {
260de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        Object value = mValues.get(key);
261de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        if (value instanceof String[]) {
262de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            return (String[]) value;
263de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        } else {
264de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            return null;
265de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        }
266de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    }
267de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
268de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    /**
26964e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria     * Gets all the values in this Data object.
2701e9589d6482d2690e2eabb21f732377d268a5c05Sumir Kataria     *
27118aa0f0a4d1416c8bedad720da7178d130735340Sumir Kataria     * @return A {@link Map} of key-value pairs for this object; this Map is unmodifiable and should
27218aa0f0a4d1416c8bedad720da7178d130735340Sumir Kataria     * be used for reads only.
2731e9589d6482d2690e2eabb21f732377d268a5c05Sumir Kataria     */
274a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria    public Map<String, Object> getKeyValueMap() {
27518aa0f0a4d1416c8bedad720da7178d130735340Sumir Kataria        return Collections.unmodifiableMap(mValues);
2761e9589d6482d2690e2eabb21f732377d268a5c05Sumir Kataria    }
2771e9589d6482d2690e2eabb21f732377d268a5c05Sumir Kataria
2781e9589d6482d2690e2eabb21f732377d268a5c05Sumir Kataria    /**
2795641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @return The number of arguments
280de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     */
2815641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria    @VisibleForTesting
282de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    public int size() {
283de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        return mValues.size();
284de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    }
285de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
286de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    /**
28764e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria     * Converts {@link Data} to a byte array for persistent storage.
288de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     *
28964e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria     * @param data The {@link Data} object to convert
2905641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @return The byte array representation of the input
291af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria     * @throws IllegalStateException if the serialized payload is bigger than
292af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria     *         {@link #MAX_DATA_BYTES}
293de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     */
294de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    @TypeConverter
295af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria    public static byte[] toByteArray(Data data) throws IllegalStateException {
296de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
297de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        ObjectOutputStream objectOutputStream = null;
298de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        try {
299de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            objectOutputStream = new ObjectOutputStream(outputStream);
30064e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria            objectOutputStream.writeInt(data.size());
30164e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria            for (Map.Entry<String, Object> entry : data.mValues.entrySet()) {
302de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                objectOutputStream.writeUTF(entry.getKey());
303de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                objectOutputStream.writeObject(entry.getValue());
304de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            }
305de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        } catch (IOException e) {
306de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            e.printStackTrace();
307de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        } finally {
308de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            if (objectOutputStream != null) {
309de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                try {
310de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                    objectOutputStream.close();
311de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                } catch (IOException e) {
312de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                    e.printStackTrace();
313de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                }
314de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            }
315de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            try {
316de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                outputStream.close();
317de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            } catch (IOException e) {
318de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                e.printStackTrace();
319de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            }
320de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        }
321af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria
322af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria        if (outputStream.size() > MAX_DATA_BYTES) {
323af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria            throw new IllegalStateException(
324af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria                    "Data cannot occupy more than " + MAX_DATA_BYTES + "KB when serialized");
325af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria        }
326de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        return outputStream.toByteArray();
327de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    }
328de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar
329de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    /**
33064e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria     * Converts a byte array to {@link Data}.
331de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     *
3325641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     * @param bytes The byte array representation to convert
33364e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria     * @return An {@link Data} object built from the input
334af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria     * @throws IllegalStateException if bytes is bigger than {@link #MAX_DATA_BYTES}
335de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar     */
336de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    @TypeConverter
337af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria    public static Data fromByteArray(byte[] bytes) throws IllegalStateException {
338af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria        if (bytes.length > MAX_DATA_BYTES) {
339af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria            throw new IllegalStateException(
340af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria                    "Data cannot occupy more than " + MAX_DATA_BYTES + "KB when serialized");
341af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria        }
342af8f22e6edb02d57014b04327d919a9fac988e70Sumir Kataria
343de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        Map<String, Object> map = new HashMap<>();
344de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
345de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        ObjectInputStream objectInputStream = null;
346de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        try {
347de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            objectInputStream = new ObjectInputStream(inputStream);
348de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            for (int i = objectInputStream.readInt(); i > 0; i--) {
349de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                map.put(objectInputStream.readUTF(), objectInputStream.readObject());
350de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            }
351de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        } catch (IOException | ClassNotFoundException e) {
352de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            e.printStackTrace();
353de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        } finally {
354de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            if (objectInputStream != null) {
355de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                try {
356de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                    objectInputStream.close();
357de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                } catch (IOException e) {
358de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                    e.printStackTrace();
359de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                }
360de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            }
361de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            try {
362de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                inputStream.close();
363de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            } catch (IOException e) {
364de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar                e.printStackTrace();
365de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar            }
366de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar        }
36764e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria        return new Data(map);
368de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar    }
36991bccff38857dcb76dbc15c165eef9c79b684e52Jan Clarin
37091bccff38857dcb76dbc15c165eef9c79b684e52Jan Clarin    @Override
37191bccff38857dcb76dbc15c165eef9c79b684e52Jan Clarin    public boolean equals(Object o) {
37291bccff38857dcb76dbc15c165eef9c79b684e52Jan Clarin        if (this == o) {
37391bccff38857dcb76dbc15c165eef9c79b684e52Jan Clarin            return true;
37491bccff38857dcb76dbc15c165eef9c79b684e52Jan Clarin        }
37591bccff38857dcb76dbc15c165eef9c79b684e52Jan Clarin        if (o == null || getClass() != o.getClass()) {
37691bccff38857dcb76dbc15c165eef9c79b684e52Jan Clarin            return false;
37791bccff38857dcb76dbc15c165eef9c79b684e52Jan Clarin        }
37864e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria        Data other = (Data) o;
37991bccff38857dcb76dbc15c165eef9c79b684e52Jan Clarin        return mValues.equals(other.mValues);
38091bccff38857dcb76dbc15c165eef9c79b684e52Jan Clarin    }
38191bccff38857dcb76dbc15c165eef9c79b684e52Jan Clarin
38291bccff38857dcb76dbc15c165eef9c79b684e52Jan Clarin    @Override
38391bccff38857dcb76dbc15c165eef9c79b684e52Jan Clarin    public int hashCode() {
3845641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        return 31 * mValues.hashCode();
3855641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria    }
3865641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria
3875f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    private static Boolean[] convertPrimitiveBooleanArray(boolean[] value) {
3885f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        Boolean[] returnValue = new Boolean[value.length];
3895f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        for (int i = 0; i < value.length; ++i) {
3905f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            returnValue[i] = value[i];
3915f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        }
3925f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        return returnValue;
3935f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    }
3945f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria
3955f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    private static Integer[] convertPrimitiveIntArray(int[] value) {
3965f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        Integer[] returnValue = new Integer[value.length];
3975f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        for (int i = 0; i < value.length; ++i) {
3985f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            returnValue[i] = value[i];
3995f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        }
4005f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        return returnValue;
4015f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    }
4025f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria
4035f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    private static Long[] convertPrimitiveLongArray(long[] value) {
4045f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        Long[] returnValue = new Long[value.length];
4055f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        for (int i = 0; i < value.length; ++i) {
4065f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            returnValue[i] = value[i];
4075f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        }
4085f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        return returnValue;
4095f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    }
4105f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria
4115f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    private static Float[] convertPrimitiveFloatArray(float[] value) {
4125f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        Float[] returnValue = new Float[value.length];
4135f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        for (int i = 0; i < value.length; ++i) {
4145f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            returnValue[i] = value[i];
4155f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        }
4165f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        return returnValue;
4175f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    }
4185f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria
4195f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    private static Double[] convertPrimitiveDoubleArray(double[] value) {
4205f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        Double[] returnValue = new Double[value.length];
4215f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        for (int i = 0; i < value.length; ++i) {
4225f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            returnValue[i] = value[i];
4235f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        }
4245f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        return returnValue;
4255f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria    }
4265f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria
4275641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria    /**
42864e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria     * A builder for {@link Data}.
4295641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria     */
430fc2a8ab13635ffc1903edd8d3b8bc388ede4a3e6Sumir Kataria    public static final class Builder {
4315641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria
4325641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        private Map<String, Object> mValues = new HashMap<>();
4335641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria
4345641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        /**
4355641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * Puts a boolean into the arguments.
4365641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         *
4375641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param key The key for this argument
4385641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param value The value for this argument
4395641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @return The {@link Builder}
4405641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         */
4415f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        public Builder putBoolean(String key, boolean value) {
4425641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria            mValues.put(key, value);
4435641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria            return this;
4445641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        }
4455641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria
4465641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        /**
4475f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         * Puts a boolean array into the arguments.
4485f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         *
4495f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         * @param key The key for this argument
4505f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         * @param value The value for this argument
4515f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         * @return The {@link Builder}
4525f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         */
4535f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        public Builder putBooleanArray(String key, boolean[] value) {
4545f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            mValues.put(key, convertPrimitiveBooleanArray(value));
4555f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            return this;
4565f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        }
4575f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria
4585f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        /**
4595641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * Puts an integer into the arguments.
4605641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         *
4615641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param key The key for this argument
4625641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param value The value for this argument
4635641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @return The {@link Builder}
4645641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         */
4655f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        public Builder putInt(String key, int value) {
4665641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria            mValues.put(key, value);
4675641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria            return this;
4685641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        }
4695641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria
4705641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        /**
4715641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * Puts an integer array into the arguments.
4725641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         *
4735641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param key The key for this argument
4745641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param value The value for this argument
4755641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @return The {@link Builder}
4765641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         */
4775f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        public Builder putIntArray(String key, int[] value) {
4785f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            mValues.put(key, convertPrimitiveIntArray(value));
4795641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria            return this;
4805641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        }
4815641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria
4825641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        /**
4835641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * Puts a long into the arguments.
4845641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         *
4855641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param key The key for this argument
4865641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param value The value for this argument
4875641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @return The {@link Builder}
4885641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         */
4895f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        public Builder putLong(String key, long value) {
4905641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria            mValues.put(key, value);
4915641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria            return this;
4925641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        }
4935641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria
4945641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        /**
4955641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * Puts a long array into the arguments.
4965641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         *
4975641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param key The key for this argument
4985641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param value The value for this argument
4995641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @return The {@link Builder}
5005641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         */
5015f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        public Builder putLongArray(String key, long[] value) {
5025f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            mValues.put(key, convertPrimitiveLongArray(value));
5035f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            return this;
5045f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        }
5055f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria
5065f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        /**
5075f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         * Puts a float into the arguments.
5085f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         *
5095f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         * @param key The key for this argument
5105f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         * @param value The value for this argument
5115f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         * @return The {@link Builder}
5125f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         */
5135f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        public Builder putFloat(String key, float value) {
5145641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria            mValues.put(key, value);
5155641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria            return this;
5165641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        }
5175641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria
5185641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        /**
5195f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         * Puts a float array into the arguments.
5205f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         *
5215f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         * @param key The key for this argument
5225f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         * @param value The value for this argument
5235f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         * @return The {@link Builder}
5245f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria         */
5255f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        public Builder putFloatArray(String key, float[] value) {
5265f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            mValues.put(key, convertPrimitiveFloatArray(value));
5275f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            return this;
5285f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        }
5295f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria
5305f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        /**
5315641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * Puts a double into the arguments.
5325641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         *
5335641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param key The key for this argument
5345641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param value The value for this argument
5355641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @return The {@link Builder}
5365641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         */
5375f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        public Builder putDouble(String key, double value) {
5385641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria            mValues.put(key, value);
5395641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria            return this;
5405641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        }
5415641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria
5425641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        /**
5435641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * Puts a double array into the arguments.
5445641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         *
5455641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param key The key for this argument
5465641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param value The value for this argument
5475641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @return The {@link Builder}
5485641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         */
5495f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria        public Builder putDoubleArray(String key, double[] value) {
5505f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria            mValues.put(key, convertPrimitiveDoubleArray(value));
5515641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria            return this;
5525641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        }
5535641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria
5545641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        /**
5555641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * Puts a String into the arguments.
5565641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         *
5575641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param key The key for this argument
5585641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param value The value for this argument
5595641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @return The {@link Builder}
5605641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         */
5615641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        public Builder putString(String key, String value) {
5625641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria            mValues.put(key, value);
5635641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria            return this;
5645641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        }
5655641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria
5665641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        /**
5675641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * Puts a String array into the arguments.
5685641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         *
5695641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param key The key for this argument
5705641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @param value The value for this argument
5715641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         * @return The {@link Builder}
5725641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         */
5735641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        public Builder putStringArray(String key, String[] value) {
5745641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria            mValues.put(key, value);
5755641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria            return this;
5765641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        }
5775641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria
5785641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        /**
57964e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria         * Puts all input key-value pairs from the {@link Data} into the Builder.
580d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar         * Any non-valid types will be logged and ignored.  Valid types are: Boolean, Integer,
581d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar         * Long, Double, String, and array versions of each of those types.
582d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar         * Any {@code null} values will also be ignored.
583d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar         *
58464e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria         * @param data {@link Data} containing key-value pairs to add
585d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar         * @return The {@link Builder}
586d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar         */
58764e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria        public Builder putAll(@NonNull Data data) {
58864e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria            putAll(data.mValues);
589d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar            return this;
590d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar        }
591d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar
592d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar        /**
593661e8f993ba909ac20ad04e9eaa5ac4f8793c975Rahul Ravikumar         * Puts all input key-value pairs into the Builder. Valid types are: Boolean, Integer,
594661e8f993ba909ac20ad04e9eaa5ac4f8793c975Rahul Ravikumar         * Long, Float, Double, String, and array versions of each of those types.
595661e8f993ba909ac20ad04e9eaa5ac4f8793c975Rahul Ravikumar         * Invalid types throw an {@link IllegalArgumentException}.
596a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria         *
597a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria         * @param values A {@link Map} of key-value pairs to add
598625fc280e37458ab9527aa47ab8c741a06c1a5bbRahul Ravikumar         * @return The {@link Builder}
599a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria         */
600625fc280e37458ab9527aa47ab8c741a06c1a5bbRahul Ravikumar        public Builder putAll(Map<String, Object> values) {
601a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria            for (Map.Entry<String, Object> entry : values.entrySet()) {
602a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                String key = entry.getKey();
603a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                Object value = entry.getValue();
604a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                if (value == null) {
6050d0bff688907f53fb41d6a8f6fd3a8958a744735Sumir Kataria                    mValues.put(key, null);
606a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                    continue;
607a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                }
608a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                Class valueType = value.getClass();
609a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                if (valueType == Boolean.class
610a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                        || valueType == Integer.class
611a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                        || valueType == Long.class
6127298da6794c8fe2d98a946176987d0668b59b79cSumir Kataria                        || valueType == Float.class
613a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                        || valueType == Double.class
614a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                        || valueType == String.class
615a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                        || valueType == Boolean[].class
616a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                        || valueType == Integer[].class
617a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                        || valueType == Long[].class
6185f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria                        || valueType == Float[].class
619a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                        || valueType == Double[].class
620a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                        || valueType == String[].class) {
621a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                    mValues.put(key, value);
6225f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria                } else if (valueType == boolean[].class) {
6235f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria                    mValues.put(key, convertPrimitiveBooleanArray((boolean[]) value));
6245f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria                } else if (valueType == int[].class) {
6255f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria                    mValues.put(key, convertPrimitiveIntArray((int[]) value));
6265f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria                } else if (valueType == long[].class) {
6275f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria                    mValues.put(key, convertPrimitiveLongArray((long[]) value));
6285f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria                } else if (valueType == float[].class) {
6295f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria                    mValues.put(key, convertPrimitiveFloatArray((float[]) value));
6305f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria                } else if (valueType == double[].class) {
6315f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria                    mValues.put(key, convertPrimitiveDoubleArray((double[]) value));
632a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                } else {
6330d0bff688907f53fb41d6a8f6fd3a8958a744735Sumir Kataria                    throw new IllegalArgumentException(
6340d0bff688907f53fb41d6a8f6fd3a8958a744735Sumir Kataria                            String.format("Key %s has invalid type %s", key, valueType));
635a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria                }
636a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria            }
637625fc280e37458ab9527aa47ab8c741a06c1a5bbRahul Ravikumar            return this;
638a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria        }
639a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria
640a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria        /**
64164e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria         * Builds an {@link Data} object.
6425641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         *
64364e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria         * @return The {@link Data} object containing all key-value pairs specified by this
6445641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         *         {@link Builder}.
6455641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria         */
64664e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria        public Data build() {
64764e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria            return new Data(mValues);
6485641e4d9db96738ed9960bd25f8469c4f019caaaSumir Kataria        }
64991bccff38857dcb76dbc15c165eef9c79b684e52Jan Clarin    }
650de813efd0159cd173ae560723e325655504f2474Xyan Bhatnagar}
651