Skip to content

Commit 4485214

Browse files
Use Jackson instead of Gson
1 parent b13a275 commit 4485214

15 files changed

Lines changed: 89 additions & 119 deletions

build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ repositories {
1313

1414
dependencies {
1515
implementation 'org.slf4j:slf4j-api:2.0.7'
16-
implementation 'com.google.code.gson:gson:2.9.1'
16+
implementation 'com.fasterxml.jackson.core:jackson-core:2.15.2'
17+
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'
1718
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
1819
testImplementation platform('org.junit:junit-bom:5.9.1')
1920
testImplementation 'org.junit.jupiter:junit-jupiter'
Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
package ankiconnect;
22

3-
import ankiconnect.exception.AnkiConnectException;
4-
import ankiconnect.gson.GsonFactory;
5-
import ankiconnect.model.AnkiConnectRequest;
6-
import ankiconnect.model.AnkiConnectResponse;
7-
import ankiconnect.model.Card;
8-
import com.google.gson.Gson;
9-
import com.google.gson.JsonSyntaxException;
10-
import com.google.gson.reflect.TypeToken;
3+
import com.fasterxml.jackson.core.type.TypeReference;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
115
import lombok.extern.slf4j.Slf4j;
126
import okhttp3.MediaType;
137
import okhttp3.OkHttpClient;
@@ -30,7 +24,7 @@ public class AnkiConnect {
3024
private final Integer bindPort;
3125
private final String apiKey;
3226
private final OkHttpClient client;
33-
private final Gson gson;
27+
private final ObjectMapper mapper;
3428

3529
public AnkiConnect(String bindAddress, Integer bindPort) {
3630
this(bindAddress, bindPort, null);
@@ -41,48 +35,51 @@ public AnkiConnect(String bindAddress, Integer bindPort, String apiKey) {
4135
this.bindPort = bindPort;
4236
this.apiKey = apiKey;
4337
this.client = new OkHttpClient.Builder().readTimeout(60, TimeUnit.SECONDS).build();
44-
this.gson = new GsonFactory().getInstance();
38+
this.mapper = new ObjectMapper();
4539
}
4640

4741
public List<Long> findCards(String query) {
4842
log.info("Finding cards in Anki with query: {}", query);
4943
Map<String, String> params = new HashMap<>();
5044
params.put("query", query);
51-
return request("findCards", params, new TypeToken<AnkiConnectResponse<List<Long>>>() {});
45+
return request("findCards", params, new TypeReference<AnkiConnectResponse<List<Long>>>() {});
5246
}
5347

5448
public List<Card> cardsInfo(List<Long> ids) {
5549
log.info("Finding card info from Anki for ids: {}", ids);
5650
Map<String, List<Long>> params = new HashMap<>();
5751
params.put("cards", ids);
58-
return request("cardsInfo", params, new TypeToken<AnkiConnectResponse<List<Card>>>() {});
52+
return request("cardsInfo", params, new TypeReference<AnkiConnectResponse<List<Card>>>() {});
5953
}
6054

61-
private <P, R> R request(String action, Map<String, P> params, TypeToken<AnkiConnectResponse<R>> token) {
55+
private <P, R> R request(String action, Map<String, P> params, TypeReference<AnkiConnectResponse<R>> token) {
6256
AnkiConnectRequest<P> body = new AnkiConnectRequest<>();
6357
body.setAction(action);
6458
body.setKey(apiKey);
6559
body.setVersion(VERSION);
6660
body.setParams(params);
6761

68-
Request request = new Request.Builder()
69-
.url("http://" + bindAddress + ":" + bindPort)
70-
.post(RequestBody.create(gson.toJson(body), MediaType.parse("application/json")))
71-
.build();
72-
73-
try (Response response = client.newCall(request).execute()) {
62+
Response response = null;
63+
try {
64+
Request request = new Request.Builder()
65+
.url("http://" + bindAddress + ":" + bindPort)
66+
.post(RequestBody.create(mapper.writeValueAsString(body), MediaType.parse("application/json")))
67+
.build();
68+
response = client.newCall(request).execute();
7469
if (response.body() == null) {
7570
throw new AnkiConnectException("Response body was null");
7671
}
77-
AnkiConnectResponse<R> output = gson.fromJson(response.body().string(), token.getType());
72+
AnkiConnectResponse<R> output = mapper.readValue(response.body().string(), token);
7873
if (output.getError() != null) {
7974
throw new AnkiConnectException("An error was returning from the AnkiConnect API: " + output.getError());
8075
}
8176
return output.getResult();
82-
} catch (JsonSyntaxException e) {
83-
throw new AnkiConnectException("The JSON body was not in the expected format", e);
8477
} catch (IOException e) {
8578
throw new AnkiConnectException("Could not make request to the AnkiConnect API", e);
79+
} finally {
80+
if (response != null) {
81+
response.close();
82+
}
8683
}
8784
}
8885
}

src/main/java/ankiconnect/exception/AnkiConnectException.java renamed to src/main/java/ankiconnect/AnkiConnectException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package ankiconnect.exception;
1+
package ankiconnect;
22

33
public class AnkiConnectException extends RuntimeException {
44

src/main/java/ankiconnect/model/AnkiConnectRequest.java renamed to src/main/java/ankiconnect/AnkiConnectRequest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package ankiconnect.model;
1+
package ankiconnect;
22

33
import lombok.Getter;
44
import lombok.Setter;
@@ -7,7 +7,7 @@
77

88
@Getter
99
@Setter
10-
public class AnkiConnectRequest<T> {
10+
class AnkiConnectRequest<T> {
1111

1212
private String action;
1313
private int version;
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
package ankiconnect.model;
1+
package ankiconnect;
22

33
import lombok.Getter;
44
import lombok.Setter;
55

66
@Getter
77
@Setter
8-
public class AnkiConnectResponse<T> {
8+
class AnkiConnectResponse<T> {
99
private T result;
1010
private String error;
1111
}
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
package ankiconnect.model;
1+
package ankiconnect;
22

3-
import com.google.gson.annotations.SerializedName;
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
45
import lombok.Getter;
56
import lombok.Setter;
67

@@ -9,12 +10,11 @@
910
@Getter
1011
@Setter
1112
public class Card {
12-
private String modelName;
13-
private String deckName;
14-
15-
@SerializedName("note")
13+
@JsonProperty("note")
1614
private long noteId;
1715
private long cardId;
16+
private String modelName;
17+
private String deckName;
1818
private String question;
1919
private String answer;
2020
private String css;
@@ -27,7 +27,9 @@ public class Card {
2727
private int interval;
2828
private int factor;
2929
private int fieldOrder;
30+
private Map<String, CardField> fields;
31+
@JsonDeserialize(using = CardTypeDeserializer.class)
3032
private CardType type;
33+
@JsonDeserialize(using = CardQueueDeserializer.class)
3134
private CardQueue queue;
32-
private Map<String, CardField> fields;
3335
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package ankiconnect;
2+
3+
import lombok.Getter;
4+
import lombok.Setter;
5+
6+
@Getter
7+
@Setter
8+
public class CardField {
9+
private String value;
10+
private int order;
11+
12+
public String toString() {
13+
return value;
14+
}
15+
}

src/main/java/ankiconnect/model/CardQueue.java renamed to src/main/java/ankiconnect/CardQueue.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package ankiconnect.model;
1+
package ankiconnect;
22

33
import lombok.Getter;
44
import lombok.RequiredArgsConstructor;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package ankiconnect;
2+
3+
import com.fasterxml.jackson.core.JsonParser;
4+
import com.fasterxml.jackson.databind.DeserializationContext;
5+
import com.fasterxml.jackson.databind.JsonDeserializer;
6+
7+
import java.io.IOException;
8+
import java.util.Arrays;
9+
10+
class CardQueueDeserializer extends JsonDeserializer<CardQueue> {
11+
12+
@Override
13+
public CardQueue deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
14+
final int index = p.getIntValue();
15+
return Arrays.stream(CardQueue.values())
16+
.filter(queue -> queue.getIndex() == index)
17+
.findFirst()
18+
.orElse(null);
19+
}
20+
}

src/main/java/ankiconnect/model/CardType.java renamed to src/main/java/ankiconnect/CardType.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package ankiconnect.model;
1+
package ankiconnect;
22

33
import lombok.Getter;
44
import lombok.RequiredArgsConstructor;

0 commit comments

Comments
 (0)