Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a generic json mapper for any entity. #183

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,62 +15,76 @@
*/
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.ParameterizedType;
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 {
public class EntityJsonMapper<T> {

private final Gson gson;
private final Type type;
private ParameterizedType parameterizedType;

@Inject
public UserEntityJsonMapper() {
public EntityJsonMapper(Class<T> clazz) {
this.gson = new Gson();
this.type = clazz;
}

/**
* Transform from valid json string to {@link UserEntity}.
* Transform from valid json string to an object type {@link T}.
*
* @param userJsonResponse A json representing a user profile.
* @return {@link UserEntity}.
* @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 UserEntity transformUserEntity(String userJsonResponse) throws JsonSyntaxException {
public T transformEntity(String json) throws JsonSyntaxException {
try {
Type userEntityType = new TypeToken<UserEntity>() {}.getType();
UserEntity userEntity = this.gson.fromJson(userJsonResponse, userEntityType);

return userEntity;
return gson.fromJson(json, type);
} catch (JsonSyntaxException jsonException) {
throw jsonException;
}
}

/**
* Transform from valid json string to List of {@link UserEntity}.
* Transform from valid json string to List of {@link T}.
*
* @param userListJsonResponse A json representing a collection of users.
* @return List of {@link UserEntity}.
* @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<UserEntity> transformUserEntityCollection(String userListJsonResponse)
public List<T> transformEntityCollection(String json)
throws JsonSyntaxException {

List<UserEntity> userEntityCollection;
try {
Type listOfUserEntityType = new TypeToken<List<UserEntity>>() {}.getType();
userEntityCollection = this.gson.fromJson(userListJsonResponse, listOfUserEntityType);

return userEntityCollection;
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 com.fernandocejas.frodo.annotation.RxLogObservable;
import java.net.MalformedURLException;
Expand All @@ -32,20 +32,20 @@
public class RestApiImpl implements RestApi {

private final Context context;
private final UserEntityJsonMapper userEntityJsonMapper;
private final EntityJsonMapper<UserEntity> 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;
}

@RxLogObservable
Expand All @@ -55,7 +55,7 @@ public RestApiImpl(Context context, UserEntityJsonMapper userEntityJsonMapper) {
try {
String responseUserEntities = getUserEntitiesFromApi();
if (responseUserEntities != null) {
subscriber.onNext(userEntityJsonMapper.transformUserEntityCollection(
subscriber.onNext(entityJsonMapper.transformEntityCollection(
responseUserEntities));
subscriber.onCompleted();
} else {
Expand All @@ -77,7 +77,7 @@ public RestApiImpl(Context context, UserEntityJsonMapper userEntityJsonMapper) {
try {
String responseUserDetails = getUserDetailsFromApi(userId);
if (responseUserDetails != null) {
subscriber.onNext(userEntityJsonMapper.transformUserEntity(responseUserDetails));
subscriber.onNext(entityJsonMapper.transformEntity(responseUserDetails));
subscriber.onCompleted();
} else {
subscriber.onError(new NetworkConnectionException());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -58,8 +59,8 @@ public UserDataStore create(int userId) {
* Create {@link UserDataStore} to retrieve data from the Cloud.
*/
public UserDataStore createCloudDataStore() {
UserEntityJsonMapper userEntityJsonMapper = new UserEntityJsonMapper();
RestApi restApi = new RestApiImpl(this.context, userEntityJsonMapper);
EntityJsonMapper<UserEntity> entityJsonMapper = new EntityJsonMapper<>(UserEntity.class);
RestApi restApi = new RestApiImpl(this.context, entityJsonMapper);

return new CloudUserDataStore(restApi, this.userCache);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

public class UserEntityJsonMapperTest extends ApplicationTestCase {
public class EntityMapperUtilTest extends ApplicationTestCase {

private static final String JSON_RESPONSE_USER_DETAILS = "{\n"
+ " \"id\": 1,\n"
Expand All @@ -49,19 +49,19 @@ public class UserEntityJsonMapperTest extends ApplicationTestCase {
+ " \"followers\": 1381\n"
+ "}]";

private UserEntityJsonMapper userEntityJsonMapper;
private EntityJsonMapper<UserEntity> entityJsonMapper;

@Rule
public ExpectedException expectedException = ExpectedException.none();

@Before
public void setUp() {
userEntityJsonMapper = new UserEntityJsonMapper();
entityJsonMapper = new EntityJsonMapper<UserEntity>(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")));
Expand All @@ -71,7 +71,7 @@ public void testTransformUserEntityHappyCase() {
@Test
public void testTransformUserEntityCollectionHappyCase() {
Collection<UserEntity> userEntityCollection =
userEntityJsonMapper.transformUserEntityCollection(
entityJsonMapper.transformEntityCollection(
JSON_RESPONSE_USER_COLLECTION);

assertThat(((UserEntity) userEntityCollection.toArray()[0]).getUserId(), is(1));
Expand All @@ -82,12 +82,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");
}
}