Skip to content

Commit 8168ef1

Browse files
Use jackson's TypeReference to deserialize into generic classes without warnings
1 parent bd6718b commit 8168ef1

6 files changed

Lines changed: 25 additions & 14 deletions

File tree

src/main/java/seedu/address/commons/util/ConfigUtil.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import java.nio.file.Path;
55
import java.util.Optional;
66

7+
import com.fasterxml.jackson.core.type.TypeReference;
8+
79
import seedu.address.commons.core.Config;
810
import seedu.address.commons.exceptions.DataLoadingException;
911

@@ -13,7 +15,7 @@
1315
public class ConfigUtil {
1416

1517
public static Optional<Config> readConfig(Path configFilePath) throws DataLoadingException {
16-
return JsonUtil.readJsonFile(configFilePath, Config.class);
18+
return JsonUtil.readJsonFile(configFilePath, new TypeReference<Config>() {});
1719
}
1820

1921
public static void saveConfig(Config config, Path configFilePath) throws IOException {

src/main/java/seedu/address/commons/util/JsonUtil.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.fasterxml.jackson.annotation.JsonAutoDetect;
1313
import com.fasterxml.jackson.annotation.PropertyAccessor;
1414
import com.fasterxml.jackson.core.JsonProcessingException;
15+
import com.fasterxml.jackson.core.type.TypeReference;
1516
import com.fasterxml.jackson.databind.DeserializationContext;
1617
import com.fasterxml.jackson.databind.DeserializationFeature;
1718
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -43,21 +44,21 @@ static <T> void serializeObjectToJsonFile(Path jsonFile, T objectToSerialize) th
4344
FileUtil.writeToFile(jsonFile, toJsonString(objectToSerialize));
4445
}
4546

46-
static <T> T deserializeObjectFromJsonFile(Path jsonFile, Class<T> classOfObjectToDeserialize)
47+
static <T> T deserializeObjectFromJsonFile(Path jsonFile, TypeReference<T> typeRef)
4748
throws IOException {
48-
return fromJsonString(FileUtil.readFromFile(jsonFile), classOfObjectToDeserialize);
49+
return fromJsonString(FileUtil.readFromFile(jsonFile), typeRef);
4950
}
5051

5152
/**
5253
* Returns the JSON object from the given file or {@code Optional.empty()} object if the file is not found.
5354
* If any values are missing from the file, default values will be used, as long as the file is a valid JSON file.
5455
*
5556
* @param filePath cannot be null.
56-
* @param classOfObjectToDeserialize JSON file has to correspond to the structure in the class given here.
57+
* @param typeRef JSON file has to correspond to the structure in the {@oode TypeReference} given here.
5758
* @throws DataLoadingException if loading of the JSON file failed.
5859
*/
5960
public static <T> Optional<T> readJsonFile(
60-
Path filePath, Class<T> classOfObjectToDeserialize) throws DataLoadingException {
61+
Path filePath, TypeReference<T> typeRef) throws DataLoadingException {
6162
requireNonNull(filePath);
6263

6364
if (!Files.exists(filePath)) {
@@ -68,7 +69,7 @@ public static <T> Optional<T> readJsonFile(
6869
T jsonFile;
6970

7071
try {
71-
jsonFile = deserializeObjectFromJsonFile(filePath, classOfObjectToDeserialize);
72+
jsonFile = deserializeObjectFromJsonFile(filePath, typeRef);
7273
} catch (IOException e) {
7374
logger.warning("Error reading from jsonFile file " + filePath + ": " + e);
7475
throw new DataLoadingException(e);
@@ -97,8 +98,8 @@ public static <T> void saveJsonFile(T jsonFile, Path filePath) throws IOExceptio
9798
* @param <T> The generic type to create an instance of
9899
* @return The instance of T with the specified values in the JSON string
99100
*/
100-
public static <T> T fromJsonString(String json, Class<T> instanceClass) throws IOException {
101-
return objectMapper.readValue(json, instanceClass);
101+
public static <T> T fromJsonString(String json, TypeReference<T> typeRef) throws IOException {
102+
return objectMapper.readValue(json, typeRef);
102103
}
103104

104105
/**

src/main/java/seedu/address/storage/JsonAddressBookStorage.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import java.util.Optional;
88
import java.util.logging.Logger;
99

10+
import com.fasterxml.jackson.core.type.TypeReference;
11+
1012
import seedu.address.commons.core.LogsCenter;
1113
import seedu.address.commons.exceptions.DataLoadingException;
1214
import seedu.address.commons.exceptions.IllegalValueException;
@@ -46,7 +48,7 @@ public Optional<ReadOnlyAddressBook> readAddressBook(Path filePath) throws DataL
4648
requireNonNull(filePath);
4749

4850
Optional<JsonSerializableAddressBook> jsonAddressBook = JsonUtil.readJsonFile(
49-
filePath, JsonSerializableAddressBook.class);
51+
filePath, new TypeReference<JsonSerializableAddressBook>() {});
5052
if (!jsonAddressBook.isPresent()) {
5153
return Optional.empty();
5254
}

src/main/java/seedu/address/storage/JsonUserPrefsStorage.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import java.nio.file.Path;
55
import java.util.Optional;
66

7+
import com.fasterxml.jackson.core.type.TypeReference;
8+
79
import seedu.address.commons.exceptions.DataLoadingException;
810
import seedu.address.commons.util.JsonUtil;
911
import seedu.address.model.ReadOnlyUserPrefs;
@@ -36,7 +38,7 @@ public Optional<UserPrefs> readUserPrefs() throws DataLoadingException {
3638
* @throws DataLoadingException if the file format is not as expected.
3739
*/
3840
public Optional<UserPrefs> readUserPrefs(Path prefsFilePath) throws DataLoadingException {
39-
return JsonUtil.readJsonFile(prefsFilePath, UserPrefs.class);
41+
return JsonUtil.readJsonFile(prefsFilePath, new TypeReference<UserPrefs>() {});
4042
}
4143

4244
@Override

src/test/java/seedu/address/commons/util/JsonUtilTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
import org.junit.jupiter.api.Test;
99

10+
import com.fasterxml.jackson.core.type.TypeReference;
11+
1012
import seedu.address.testutil.SerializableTestClass;
1113
import seedu.address.testutil.TestUtil;
1214

@@ -32,7 +34,7 @@ public void deserializeObjectFromJsonFile_noExceptionThrown() throws IOException
3234
FileUtil.writeToFile(SERIALIZATION_FILE, SerializableTestClass.JSON_STRING_REPRESENTATION);
3335

3436
SerializableTestClass serializableTestClass = JsonUtil
35-
.deserializeObjectFromJsonFile(SERIALIZATION_FILE, SerializableTestClass.class);
37+
.deserializeObjectFromJsonFile(SERIALIZATION_FILE, new TypeReference<SerializableTestClass>() {});
3638

3739
assertEquals(serializableTestClass.getName(), SerializableTestClass.getNameTestValue());
3840
assertEquals(serializableTestClass.getListOfLocalDateTimes(), SerializableTestClass.getListTestValues());

src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
import org.junit.jupiter.api.Test;
1010

11+
import com.fasterxml.jackson.core.type.TypeReference;
12+
1113
import seedu.address.commons.exceptions.IllegalValueException;
1214
import seedu.address.commons.util.JsonUtil;
1315
import seedu.address.model.AddressBook;
@@ -23,7 +25,7 @@ public class JsonSerializableAddressBookTest {
2325
@Test
2426
public void toModelType_typicalPersonsFile_success() throws Exception {
2527
JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(TYPICAL_PERSONS_FILE,
26-
JsonSerializableAddressBook.class).get();
28+
new TypeReference<JsonSerializableAddressBook>() {}).get();
2729
AddressBook addressBookFromFile = dataFromFile.toModelType();
2830
AddressBook typicalPersonsAddressBook = TypicalPersons.getTypicalAddressBook();
2931
assertEquals(addressBookFromFile, typicalPersonsAddressBook);
@@ -32,14 +34,14 @@ public void toModelType_typicalPersonsFile_success() throws Exception {
3234
@Test
3335
public void toModelType_invalidPersonFile_throwsIllegalValueException() throws Exception {
3436
JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(INVALID_PERSON_FILE,
35-
JsonSerializableAddressBook.class).get();
37+
new TypeReference<JsonSerializableAddressBook>() {}).get();
3638
assertThrows(IllegalValueException.class, dataFromFile::toModelType);
3739
}
3840

3941
@Test
4042
public void toModelType_duplicatePersons_throwsIllegalValueException() throws Exception {
4143
JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(DUPLICATE_PERSON_FILE,
42-
JsonSerializableAddressBook.class).get();
44+
new TypeReference<JsonSerializableAddressBook>() {}).get();
4345
assertThrows(IllegalValueException.class, JsonSerializableAddressBook.MESSAGE_DUPLICATE_PERSON,
4446
dataFromFile::toModelType);
4547
}

0 commit comments

Comments
 (0)