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

refactor: Type inference hack for fromJson #492

Merged
merged 1 commit into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
49 changes: 49 additions & 0 deletions src/main/java/com/vonage/client/Jsonable.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,23 @@
*/
public interface Jsonable {

/**
* Convenience method for creating an ObjectMapper with standard settings.
*
* @return A new ObjectMapper with appropriate configuration.
*/
static ObjectMapper createDefaultObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
return mapper;
}

/**
* Serialises this class to a JSON payload.
*
* @return The JSON string representing this class's marked properties.
*/
default String toJson() {
try {
return createDefaultObjectMapper().writeValueAsString(this);
Expand All @@ -45,6 +55,13 @@ default String toJson() {
}
}

/**
* Updates this class's fields from the JSON payload.
*
* @param json The JSON string.
*
* @throws VonageResponseParseException If the JSON was invalid or this class couldn't be updated.
*/
default void updateFromJson(String json) {
if (json == null || json.trim().isEmpty()) {
return;
Expand All @@ -57,6 +74,38 @@ default void updateFromJson(String json) {
}
}

/**
* Delegates to {@linkplain #fromJson(String, Class)}, using the type varargs for inferring the class.
*
* @param json The JSON string to parse.
* @param type Unused. This is a hack to get the array class's component type.
*
* @return A new instance of the inferred Jsonable.
*
* @param <J> A class which implements this interface.
*
* @throws VonageUnexpectedException If a no-args constructor for the class was not found.
* @throws VonageResponseParseException If the JSON was invalid or this class couldn't be updated.
*/
@SuppressWarnings("unchecked")
static <J extends Jsonable> J fromJson(String json, J... type) {
return fromJson(json, (Class<J>) type.getClass().getComponentType());
}

/**
* Creates a new instance of the designated Jsonable class, calling its no-args constructor
* followed by {@link #updateFromJson(String)}.
*
* @param json The JSON string to parse.
* @param jsonable The Jsonable class to construct.
*
* @return A new instance of the Jsonable class.
*
* @param <J> A class which implements this interface.
*
* @throws VonageUnexpectedException If a no-args constructor for the class was not found.
* @throws VonageResponseParseException If the JSON was invalid or this class couldn't be updated.
*/
static <J extends Jsonable> J fromJson(String json, Class<? extends J> jsonable) {
try {
Constructor<? extends J> constructor = jsonable.getDeclaredConstructor();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -219,21 +216,6 @@ protected static <E extends VonageApiResponseException> E fromJson(Class<E> claz
throw new VonageUnexpectedException(ex);
}
}
try {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(json, clazz);
}
catch (IOException ex) {
throw new VonageResponseParseException("Failed to produce "+clazz.getSimpleName()+" from json.", ex);
}
}

protected static <E extends VonageApiResponseException> E fromHttpResponse(Class<E> clazz, HttpResponse response) throws IOException {
E crx = fromJson(clazz, EntityUtils.toString(response.getEntity()));
if (crx.title == null) {
crx.title = response.getStatusLine().getReasonPhrase();
}
crx.statusCode = response.getStatusLine().getStatusCode();
return crx;
else return Jsonable.fromJson(json, clazz);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@ public boolean isAutoReload() {
}

public static BalanceResponse fromJson(String json) {
return Jsonable.fromJson(json, BalanceResponse.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,6 @@ public void updateFromJson(String json) {
}

public static ListSecretsResponse fromJson(String json) {
return Jsonable.fromJson(json, ListSecretsResponse.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ public List<PricingResponse> getCountries() {
}

public static PrefixPricingResponse fromJson(String json) {
return Jsonable.fromJson(json, PrefixPricingResponse.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@ public List<Network> getNetworks() {
}

public static PricingResponse fromJson(String json) {
return Jsonable.fromJson(json, PricingResponse.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@ public void updateFromJson(String json) {
}

public static SecretResponse fromJson(String json) {
return Jsonable.fromJson(json, SecretResponse.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,6 @@ public Integer getMaxApiCallsPerSecond() {
}

public static SettingsResponse fromJson(String json) {
return Jsonable.fromJson(json, SettingsResponse.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public Privacy getPrivacy() {
}

public static Application fromJson(String json) {
return Jsonable.fromJson(json, Application.class);
return Jsonable.fromJson(json);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ public List<Application> getApplications() {
}

public static ApplicationList fromJson(String json) {
return Jsonable.fromJson(json, ApplicationList.class);
return Jsonable.fromJson(json);
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/vonage/client/incoming/CallEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,6 @@ public CallStatusDetail getDetailEnum() {
}

public static CallEvent fromJson(String json) {
return Jsonable.fromJson(json, CallEvent.class);
return Jsonable.fromJson(json);
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/vonage/client/incoming/InputEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,6 @@ public SpeechResults getSpeech() {
}

public static InputEvent fromJson(String json) {
return Jsonable.fromJson(json, InputEvent.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,6 @@ public void updateFromJson(String json) {
}

public static MessageEvent fromJson(String json) {
return Jsonable.fromJson(json, MessageEvent.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,6 @@ public String toString() {
}

public static NotifyEvent fromJson(String json) {
return Jsonable.fromJson(json, NotifyEvent.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,6 @@ public Date getTimestamp() {
}

public static RecordEvent fromJson(String json) {
return Jsonable.fromJson(json, RecordEvent.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class AdvancedInsightResponse extends StandardInsightResponse {
private String errorText;

public static AdvancedInsightResponse fromJson(String json) {
return Jsonable.fromJson(json, AdvancedInsightResponse.class);
return Jsonable.fromJson(json);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class BasicInsightResponse implements Jsonable {
countryCode, countryCodeIso3, countryName, countryPrefix;

public static BasicInsightResponse fromJson(String json) {
return Jsonable.fromJson(json, BasicInsightResponse.class);
return Jsonable.fromJson(json);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class StandardInsightResponse extends BasicInsightResponse {
private CallerType callerType;

public static StandardInsightResponse fromJson(String json) {
return Jsonable.fromJson(json, StandardInsightResponse.class);
return Jsonable.fromJson(json);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,6 @@ public UUID getDefaultThemeId() {
* @return An instance of this class with the fields populated, if present.
*/
public static Application fromJson(String json) {
return Jsonable.fromJson(json, Application.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ public List<Recording> getRecordings() {
}

public static ListRecordingsResponse fromJson(String json) {
return Jsonable.fromJson(json, ListRecordingsResponse.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ public List<MeetingRoom> getMeetingRooms() {
* @return An instance of this class with the fields populated, if present.
*/
public static ListRoomsResponse fromJson(String json) {
return Jsonable.fromJson(json, ListRoomsResponse.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ public RoomLinks getLinks() {
* @return An instance of this class with the fields populated, if present.
*/
public static MeetingRoom fromJson(String json) {
return Jsonable.fromJson(json, MeetingRoom.class);
return Jsonable.fromJson(json);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,6 @@ public Boolean getIsHost() {
* @throws VonageResponseParseException If the response could not be deserialized.
*/
public static MeetingsEventCallback fromJson(String json) {
return Jsonable.fromJson(json, MeetingsEventCallback.class);
return Jsonable.fromJson(json);
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/vonage/client/meetings/Recording.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,6 @@ public URI getUrl() {
* @return An instance of this class with the fields populated, if present.
*/
public static Recording fromJson(String json) {
return Jsonable.fromJson(json, Recording.class);
return Jsonable.fromJson(json);
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/vonage/client/meetings/Theme.java
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ public String toJson() {
* @return An instance of this class with the fields populated, if present.
*/
public static Theme fromJson(String json) {
return Jsonable.fromJson(json, Theme.class);
return Jsonable.fromJson(json);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,6 @@ public SmsInboundMetadata getSmsMetadata() {
* @throws com.vonage.client.VonageResponseParseException If the response could not be deserialized.
*/
public static InboundMessage fromJson(String json) {
return Jsonable.fromJson(json, InboundMessage.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ public String toString() {
* @return An instance of this class with the fields populated, if present.
*/
public static MessageResponse fromJson(String json) {
return Jsonable.fromJson(json, MessageResponse.class);
return Jsonable.fromJson(json);
}
}
13 changes: 1 addition & 12 deletions src/main/java/com/vonage/client/messages/MessageStatus.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@
package com.vonage.client.messages;

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.vonage.client.Jsonable;
import com.vonage.client.VonageUnexpectedException;
import java.io.IOException;
import java.net.URI;
import java.time.Instant;
import java.util.Currency;
Expand Down Expand Up @@ -304,14 +300,7 @@ public Usage getUsage() {
* @return An instance of this class with the fields populated, if present.
*/
public static MessageStatus fromJson(String json) {
try {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
return mapper.readValue(json, MessageStatus.class);
}
catch (IOException ex) {
throw new VonageUnexpectedException("Failed to produce MessageStatus from json.", ex);
}
return Jsonable.fromJson(json);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ public OwnedNumber[] getNumbers() {
}

public static ListNumbersResponse fromJson(String json) {
return Jsonable.fromJson(json, ListNumbersResponse.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public AvailableNumber[] getNumbers() {
}

public static SearchNumbersResponse fromJson(String json) {
return Jsonable.fromJson(json, SearchNumbersResponse.class);
return Jsonable.fromJson(json);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ public SyncStatus getSyncStatus() {
* @return An instance of this class with the fields populated, if present.
*/
public static ContactsList fromJson(String json) {
return Jsonable.fromJson(json, ContactsList.class);
return Jsonable.fromJson(json);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,6 @@ public EventType getType() {
* @return An instance of this class with the fields populated, if present.
*/
public static Event fromJson(String json) {
return Jsonable.fromJson(json, Event.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,6 @@ public List<Event> getEvents() {
* @return An instance of this class with the fields populated, if present.
*/
public static ListEventsResponse fromJson(String json) {
return Jsonable.fromJson(json, ListEventsResponse.class);
return Jsonable.fromJson(json);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,6 @@ public UUID getListId() {
* @return An instance of this class with the fields populated, if present.
*/
public static ListItem fromJson(String json) {
return Jsonable.fromJson(json, ListItem.class);
return Jsonable.fromJson(json);
}
}
Loading
Loading