/* * Copyright (C) 2014 SCVNGR, Inc. d/b/a LevelUp * * 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 com.scvngr.levelup.core.model.factory.json; import android.support.annotation.NonNull; import com.scvngr.levelup.core.annotation.JsonValueType; import com.scvngr.levelup.core.annotation.JsonValueType.JsonType; import com.scvngr.levelup.core.annotation.LevelUpApi; import com.scvngr.levelup.core.annotation.LevelUpApi.Contract; import com.scvngr.levelup.core.annotation.VisibleForTesting; import com.scvngr.levelup.core.annotation.VisibleForTesting.Visibility; import com.scvngr.levelup.core.model.MonetaryValue; import com.scvngr.levelup.core.model.User; import com.scvngr.levelup.core.model.User.Gender; import com.scvngr.levelup.core.model.util.JsonUtils; import net.jcip.annotations.Immutable; import org.json.JSONException; import org.json.JSONObject; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * Factory for creating {@link User}s from JSON. */ @Immutable @LevelUpApi(contract = Contract.DRAFT) public final class UserJsonFactory extends AbstractJsonModelFactory<User> { /** * Constructs new factory. */ public UserJsonFactory() { super(JsonKeys.MODEL_ROOT); } @Override @NonNull protected User createFrom(@NonNull final JSONObject json) throws JSONException { final String bornAt = JsonUtils.optString(json, JsonKeys.BORN_AT); final boolean isConnectedToFacebook = json.optBoolean(JsonKeys.CONNECTED_TO_FACEBOOK, false); final JSONObject customAttributesJson = json.optJSONObject(JsonKeys.CUSTOM_ATTRIBUTES); Map<String, String> customAttributes = null; if (null != customAttributesJson) { customAttributes = new HashMap<String, String>(); final Iterator<?> keys = customAttributesJson.keys(); while (keys.hasNext()) { final String key = (String) keys.next(); customAttributes.put(key, customAttributesJson.get(key).toString()); } } final boolean isDebitCardOnly = json.optBoolean(JsonKeys.DEBIT_CARD_ONLY, false); final String email = JsonUtils.optString(json, JsonKeys.EMAIL); final String firstName = JsonUtils.optString(json, JsonKeys.FIRST_NAME); final Gender gender = Gender.forString(JsonUtils.optString(json, JsonKeys.GENDER)); final MonetaryValue globalCredit = JsonUtils.optMonetaryValue(json, JsonKeys.GLOBAL_CREDIT_AMOUNT); final long id = json.getLong(JsonKeys.ID); final String lastName = JsonUtils.optString(json, JsonKeys.LAST_NAME); final int merchantsVisitedCount = json.optInt(JsonKeys.MERCHANTS_VISITED_COUNT, 0); final int ordersCount = json.optInt(JsonKeys.ORDERS_COUNT, 0); final String termsAcceptedAt = JsonUtils.optString(json, JsonKeys.TERMS_ACCEPTED_AT); final MonetaryValue totalSavings = JsonUtils.optMonetaryValue(json, JsonKeys.TOTAL_SAVINGS_AMOUNT); return new User(bornAt, isConnectedToFacebook, customAttributes, isDebitCardOnly, email, firstName, gender, globalCredit, id, lastName, merchantsVisitedCount, ordersCount, termsAcceptedAt, totalSavings); } /** * Keys for JSON properties for this object for use in deserialization. */ @Immutable @VisibleForTesting(visibility = Visibility.PRIVATE) public static final class JsonKeys { /** * JSON object key that maps to the root object if it's nested. */ @JsonValueType(JsonType.JSON_OBJECT) public static final String MODEL_ROOT = "user"; @SuppressWarnings("javadoc") @JsonValueType(JsonType.STRING) public static final String BORN_AT = "born_at"; @SuppressWarnings("javadoc") @JsonValueType(JsonType.BOOLEAN) public static final String CONNECTED_TO_FACEBOOK = "connected_to_facebook"; @SuppressWarnings("javadoc") @JsonValueType(JsonType.JSON_OBJECT) public static final String CUSTOM_ATTRIBUTES = "custom_attributes"; @SuppressWarnings("javadoc") @JsonValueType(JsonType.BOOLEAN) public static final String DEBIT_CARD_ONLY = "debit_card_only"; @SuppressWarnings("javadoc") @JsonValueType(JsonType.STRING) public static final String EMAIL = "email"; /** * Maps to a {@link Gender} in the model; expects "male" or "female" as a string in JSON. */ @JsonValueType(JsonType.STRING) public static final String GENDER = "gender"; @SuppressWarnings("javadoc") @JsonValueType(JsonType.LONG) public static final String GLOBAL_CREDIT_AMOUNT = "global_credit_amount"; @SuppressWarnings("javadoc") @JsonValueType(JsonType.LONG) public static final String ID = "id"; @SuppressWarnings("javadoc") @JsonValueType(JsonType.STRING) public static final String FIRST_NAME = "first_name"; @SuppressWarnings("javadoc") @JsonValueType(JsonType.STRING) public static final String LAST_NAME = "last_name"; @SuppressWarnings("javadoc") @JsonValueType(JsonType.INT) public static final String MERCHANTS_VISITED_COUNT = "merchants_visited_count"; @SuppressWarnings("javadoc") @JsonValueType(JsonType.INT) public static final String ORDERS_COUNT = "orders_count"; @SuppressWarnings("javadoc") @JsonValueType(JsonType.STRING) public static final String TERMS_ACCEPTED_AT = "terms_accepted_at"; @SuppressWarnings("javadoc") @JsonValueType(JsonType.LONG) public static final String TOTAL_SAVINGS_AMOUNT = "total_savings_amount"; /** * Private constructor prevents instantiation. * * @throws UnsupportedOperationException because this class cannot be instantiated. */ private JsonKeys() { throw new UnsupportedOperationException("This class is non-instantiable"); } } }