diff --git a/data/src/main/java/com/fernandocejas/android10/sample/data/entity/mapper/EntityJsonMapper.java b/data/src/main/java/com/fernandocejas/android10/sample/data/entity/mapper/EntityJsonMapper.java new file mode 100644 index 00000000..17a578d4 --- /dev/null +++ b/data/src/main/java/com/fernandocejas/android10/sample/data/entity/mapper/EntityJsonMapper.java @@ -0,0 +1,90 @@ +/** + * Copyright (C) 2015 Fernando Cejas Open Source Project + * + * 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.fernandocejas.android10.sample.data.entity.mapper; + +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.List; + +/** + * Class used to transform from Strings representing json to valid objects. + */ +public class EntityJsonMapper { + + private final Gson gson; + private final Type type; + private ParameterizedType parameterizedType; + + public EntityJsonMapper(Class clazz) { + this.gson = new Gson(); + this.type = clazz; + } + + /** + * Transform from valid json string to an object type {@link T}. + * + * @param json A json representing an object type {@link T}. + * @return {@link T}. + * @throws com.google.gson.JsonSyntaxException if the json string is not a valid json structure. + */ + public T transformEntity(String json) throws JsonSyntaxException { + try { + return gson.fromJson(json, type); + } catch (JsonSyntaxException jsonException) { + throw jsonException; + } + } + + /** + * Transform from valid json string to List of {@link T}. + * + * @param json A json representing a collection of objects type {@link T}. + * @return List of {@link T}. + * @throws com.google.gson.JsonSyntaxException if the json string is not a valid json structure. + */ + public List transformEntityCollection(String json) + throws JsonSyntaxException { + try { + return gson.fromJson(json, getParameterizedType()); + } catch (JsonSyntaxException jsonException) { + throw jsonException; + } + } + + private ParameterizedType getParameterizedType() { + if (parameterizedType == null) { + parameterizedType = new ParameterizedType() { + @Override public Type[] getActualTypeArguments() { + return new Type[] {type}; + } + + @Override public Type getOwnerType() { + return null; + } + + @Override public Type getRawType() { + return List.class; + } + }; + } + + return parameterizedType; + } +} diff --git a/data/src/main/java/com/fernandocejas/android10/sample/data/entity/mapper/UserEntityJsonMapper.java b/data/src/main/java/com/fernandocejas/android10/sample/data/entity/mapper/UserEntityJsonMapper.java deleted file mode 100644 index 1e344a34..00000000 --- a/data/src/main/java/com/fernandocejas/android10/sample/data/entity/mapper/UserEntityJsonMapper.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (C) 2015 Fernando Cejas Open Source Project - * - * 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.fernandocejas.android10.sample.data.entity.mapper; - -import com.fernandocejas.android10.sample.data.entity.UserEntity; -import com.google.gson.Gson; -import com.google.gson.JsonSyntaxException; -import com.google.gson.reflect.TypeToken; -import java.lang.reflect.Type; -import java.util.List; -import javax.inject.Inject; - -/** - * Class used to transform from Strings representing json to valid objects. - */ -public class UserEntityJsonMapper { - - private final Gson gson; - - @Inject - public UserEntityJsonMapper() { - this.gson = new Gson(); - } - - /** - * Transform from valid json string to {@link UserEntity}. - * - * @param userJsonResponse A json representing a user profile. - * @return {@link UserEntity}. - * @throws com.google.gson.JsonSyntaxException if the json string is not a valid json structure. - */ - public UserEntity transformUserEntity(String userJsonResponse) throws JsonSyntaxException { - final Type userEntityType = new TypeToken() {}.getType(); - return this.gson.fromJson(userJsonResponse, userEntityType); - } - - /** - * Transform from valid json string to List of {@link UserEntity}. - * - * @param userListJsonResponse A json representing a collection of users. - * @return List of {@link UserEntity}. - * @throws com.google.gson.JsonSyntaxException if the json string is not a valid json structure. - */ - public List transformUserEntityCollection(String userListJsonResponse) - throws JsonSyntaxException { - final Type listOfUserEntityType = new TypeToken>() {}.getType(); - return this.gson.fromJson(userListJsonResponse, listOfUserEntityType); - } -} diff --git a/data/src/main/java/com/fernandocejas/android10/sample/data/net/RestApiImpl.java b/data/src/main/java/com/fernandocejas/android10/sample/data/net/RestApiImpl.java index 279fe6f4..b4cdfdbb 100644 --- a/data/src/main/java/com/fernandocejas/android10/sample/data/net/RestApiImpl.java +++ b/data/src/main/java/com/fernandocejas/android10/sample/data/net/RestApiImpl.java @@ -19,7 +19,7 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo; import com.fernandocejas.android10.sample.data.entity.UserEntity; -import com.fernandocejas.android10.sample.data.entity.mapper.UserEntityJsonMapper; +import com.fernandocejas.android10.sample.data.entity.mapper.EntityJsonMapper; import com.fernandocejas.android10.sample.data.exception.NetworkConnectionException; import io.reactivex.Observable; import java.net.MalformedURLException; @@ -31,20 +31,20 @@ public class RestApiImpl implements RestApi { private final Context context; - private final UserEntityJsonMapper userEntityJsonMapper; + private final EntityJsonMapper entityJsonMapper; /** * Constructor of the class * * @param context {@link android.content.Context}. - * @param userEntityJsonMapper {@link UserEntityJsonMapper}. + * @param entityJsonMapper {@link EntityJsonMapper}. */ - public RestApiImpl(Context context, UserEntityJsonMapper userEntityJsonMapper) { - if (context == null || userEntityJsonMapper == null) { + public RestApiImpl(Context context, EntityJsonMapper entityJsonMapper) { + if (context == null || entityJsonMapper == null) { throw new IllegalArgumentException("The constructor parameters cannot be null!!!"); } this.context = context.getApplicationContext(); - this.userEntityJsonMapper = userEntityJsonMapper; + this.entityJsonMapper = entityJsonMapper; } @Override public Observable> userEntityList() { @@ -53,7 +53,7 @@ public RestApiImpl(Context context, UserEntityJsonMapper userEntityJsonMapper) { try { String responseUserEntities = getUserEntitiesFromApi(); if (responseUserEntities != null) { - emitter.onNext(userEntityJsonMapper.transformUserEntityCollection( + emitter.onNext(entityJsonMapper.transformEntityCollection( responseUserEntities)); emitter.onComplete(); } else { @@ -74,7 +74,7 @@ public RestApiImpl(Context context, UserEntityJsonMapper userEntityJsonMapper) { try { String responseUserDetails = getUserDetailsFromApi(userId); if (responseUserDetails != null) { - emitter.onNext(userEntityJsonMapper.transformUserEntity(responseUserDetails)); + emitter.onNext(entityJsonMapper.transformEntity(responseUserDetails)); emitter.onComplete(); } else { emitter.onError(new NetworkConnectionException()); diff --git a/data/src/main/java/com/fernandocejas/android10/sample/data/repository/datasource/UserDataStoreFactory.java b/data/src/main/java/com/fernandocejas/android10/sample/data/repository/datasource/UserDataStoreFactory.java index defc85df..798b68ae 100644 --- a/data/src/main/java/com/fernandocejas/android10/sample/data/repository/datasource/UserDataStoreFactory.java +++ b/data/src/main/java/com/fernandocejas/android10/sample/data/repository/datasource/UserDataStoreFactory.java @@ -18,7 +18,8 @@ import android.content.Context; import android.support.annotation.NonNull; import com.fernandocejas.android10.sample.data.cache.UserCache; -import com.fernandocejas.android10.sample.data.entity.mapper.UserEntityJsonMapper; +import com.fernandocejas.android10.sample.data.entity.UserEntity; +import com.fernandocejas.android10.sample.data.entity.mapper.EntityJsonMapper; import com.fernandocejas.android10.sample.data.net.RestApi; import com.fernandocejas.android10.sample.data.net.RestApiImpl; import javax.inject.Inject; @@ -58,8 +59,8 @@ public UserDataStore create(int userId) { * Create {@link UserDataStore} to retrieve data from the Cloud. */ public UserDataStore createCloudDataStore() { - final UserEntityJsonMapper userEntityJsonMapper = new UserEntityJsonMapper(); - final RestApi restApi = new RestApiImpl(this.context, userEntityJsonMapper); + final EntityJsonMapper entityJsonMapper = new EntityJsonMapper<>(UserEntity.class); + final RestApi restApi = new RestApiImpl(this.context, entityJsonMapper); return new CloudUserDataStore(restApi, this.userCache); } diff --git a/data/src/test/java/com/fernandocejas/android10/sample/data/entity/mapper/UserEntityJsonMapperTest.java b/data/src/test/java/com/fernandocejas/android10/sample/data/entity/mapper/EntityMapperUtilTest.java similarity index 88% rename from data/src/test/java/com/fernandocejas/android10/sample/data/entity/mapper/UserEntityJsonMapperTest.java rename to data/src/test/java/com/fernandocejas/android10/sample/data/entity/mapper/EntityMapperUtilTest.java index a6eb3fcc..171f7f22 100644 --- a/data/src/test/java/com/fernandocejas/android10/sample/data/entity/mapper/UserEntityJsonMapperTest.java +++ b/data/src/test/java/com/fernandocejas/android10/sample/data/entity/mapper/EntityMapperUtilTest.java @@ -30,7 +30,7 @@ import static org.hamcrest.MatcherAssert.assertThat; @RunWith(MockitoJUnitRunner.class) -public class UserEntityJsonMapperTest { +public class EntityMapperUtilTest { private static final String JSON_RESPONSE_USER_DETAILS = "{\n" + " \"id\": 1,\n" @@ -51,19 +51,19 @@ public class UserEntityJsonMapperTest { + " \"followers\": 1381\n" + "}]"; - private UserEntityJsonMapper userEntityJsonMapper; + private EntityJsonMapper entityJsonMapper; @Rule public ExpectedException expectedException = ExpectedException.none(); @Before public void setUp() { - userEntityJsonMapper = new UserEntityJsonMapper(); + entityJsonMapper = new EntityJsonMapper(UserEntity.class); } @Test public void testTransformUserEntityHappyCase() { - UserEntity userEntity = userEntityJsonMapper.transformUserEntity(JSON_RESPONSE_USER_DETAILS); + UserEntity userEntity = entityJsonMapper.transformEntity(JSON_RESPONSE_USER_DETAILS); assertThat(userEntity.getUserId(), is(1)); assertThat(userEntity.getFullname(), is(equalTo("Simon Hill"))); @@ -73,7 +73,7 @@ public void testTransformUserEntityHappyCase() { @Test public void testTransformUserEntityCollectionHappyCase() { Collection userEntityCollection = - userEntityJsonMapper.transformUserEntityCollection( + entityJsonMapper.transformEntityCollection( JSON_RESPONSE_USER_COLLECTION); assertThat(((UserEntity) userEntityCollection.toArray()[0]).getUserId(), is(1)); @@ -84,12 +84,12 @@ public void testTransformUserEntityCollectionHappyCase() { @Test public void testTransformUserEntityNotValidResponse() { expectedException.expect(JsonSyntaxException.class); - userEntityJsonMapper.transformUserEntity("ironman"); + entityJsonMapper.transformEntity("ironman"); } @Test public void testTransformUserEntityCollectionNotValidResponse() { expectedException.expect(JsonSyntaxException.class); - userEntityJsonMapper.transformUserEntityCollection("Tony Stark"); + entityJsonMapper.transformEntityCollection("Tony Stark"); } }