diff --git a/src/main/java/com/twilio/converter/Converter.java b/src/main/java/com/twilio/converter/Converter.java index 9ee29e0e3d..2a9a5befbf 100644 --- a/src/main/java/com/twilio/converter/Converter.java +++ b/src/main/java/com/twilio/converter/Converter.java @@ -5,6 +5,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -12,6 +14,52 @@ public class Converter { private static final ObjectMapper MAPPER = new ObjectMapper(); + /** + * Convert a generic object to a JSON String. + * + * @param value object to convert + * @return converted JSON string + */ + public static String objectToJson(Object value) { + if (value == null) { + return "null"; + } + + // Primitive wrappers + if (value instanceof String || value instanceof Number || value instanceof Boolean || value instanceof Character) { + return value.toString(); + } + // Arrays: handle any arrays (primitive or object) + if (value.getClass().isArray()) { + // For primitive arrays, handle differently + if (value instanceof int[]) return Arrays.toString((int[]) value); + if (value instanceof long[]) return Arrays.toString((long[]) value); + if (value instanceof double[]) return Arrays.toString((double[]) value); + if (value instanceof float[]) return Arrays.toString((float[]) value); + if (value instanceof boolean[]) return Arrays.toString((boolean[]) value); + if (value instanceof byte[]) return Arrays.toString((byte[]) value); + if (value instanceof short[]) return Arrays.toString((short[]) value); + if (value instanceof char[]) return Arrays.toString((char[]) value); + // Object array + return Arrays.deepToString((Object[]) value); + } + + // Collection (List, Set, etc.) + if (value instanceof Collection || value instanceof Map) { + try { + return MAPPER.writeValueAsString(value); + } catch (JsonProcessingException e) { + return value.toString(); + } + } + // Fallback: Try JSON, else toString + try { + return MAPPER.writeValueAsString(value); + } catch (JsonProcessingException e) { + return value.toString(); + } + } + /** * Convert a map to a JSON String. * diff --git a/src/main/java/com/twilio/rest/assistants/v1/Knowledge.java b/src/main/java/com/twilio/rest/assistants/v1/Knowledge.java index 613ee5323c..0f5b469bb2 100644 --- a/src/main/java/com/twilio/rest/assistants/v1/Knowledge.java +++ b/src/main/java/com/twilio/rest/assistants/v1/Knowledge.java @@ -69,10 +69,10 @@ public static class AssistantsV1ServiceCreatePolicyRequest { @JsonProperty("policy_details") @Getter @Setter - private Map policyDetails; + private Object policyDetails; public String getPolicyDetails() { - return Converter.mapToJson(policyDetails); + return Converter.objectToJson(policyDetails); } @JsonInclude(JsonInclude.Include.NON_EMPTY) diff --git a/src/main/java/com/twilio/rest/assistants/v1/Tool.java b/src/main/java/com/twilio/rest/assistants/v1/Tool.java index 1744594cd6..c4dbbf3be2 100644 --- a/src/main/java/com/twilio/rest/assistants/v1/Tool.java +++ b/src/main/java/com/twilio/rest/assistants/v1/Tool.java @@ -70,10 +70,10 @@ public static class AssistantsV1ServiceCreatePolicyRequest { @JsonProperty("policy_details") @Getter @Setter - private Map policyDetails; + private Object policyDetails; public String getPolicyDetails() { - return Converter.mapToJson(policyDetails); + return Converter.objectToJson(policyDetails); } @JsonInclude(JsonInclude.Include.NON_EMPTY) diff --git a/src/main/java/com/twilio/rest/content/v1/Content.java b/src/main/java/com/twilio/rest/content/v1/Content.java index e36fa5e764..addc44ae73 100644 --- a/src/main/java/com/twilio/rest/content/v1/Content.java +++ b/src/main/java/com/twilio/rest/content/v1/Content.java @@ -191,7 +191,7 @@ public static class CallToActionAction { @JsonProperty("type") @Getter @Setter - private Content.CallToActionActionType type; + private CallToActionActionType type; @JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonProperty("title") @@ -261,7 +261,7 @@ public static class QuickReplyAction { @JsonProperty("type") @Getter @Setter - private Content.QuickReplyActionType type; + private QuickReplyActionType type; @JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonProperty("title") @@ -313,7 +313,7 @@ public static class CardAction { @JsonProperty("type") @Getter @Setter - private Content.CardActionType type; + private CardActionType type; @JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonProperty("title") @@ -489,7 +489,7 @@ public static class CarouselAction { @JsonProperty("type") @Getter @Setter - private Content.CarouselActionType type; + private CarouselActionType type; @JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonProperty("title") @@ -769,7 +769,7 @@ public static class AuthenticationAction { @JsonProperty("type") @Getter @Setter - private Content.AuthenticationActionType type; + private AuthenticationActionType type; @JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonProperty("copy_code_text") diff --git a/src/main/java/com/twilio/rest/iam/v1/ApiKeyUpdater.java b/src/main/java/com/twilio/rest/iam/v1/ApiKeyUpdater.java index edc001f805..4d33ce3945 100644 --- a/src/main/java/com/twilio/rest/iam/v1/ApiKeyUpdater.java +++ b/src/main/java/com/twilio/rest/iam/v1/ApiKeyUpdater.java @@ -25,13 +25,12 @@ import com.twilio.http.Response; import com.twilio.http.TwilioRestClient; import com.twilio.rest.Domains; -import java.util.Map; public class ApiKeyUpdater extends Updater { private String pathSid; private String friendlyName; - private Map policy; + private Object policy; public ApiKeyUpdater(final String pathSid) { this.pathSid = pathSid; @@ -42,7 +41,7 @@ public ApiKeyUpdater setFriendlyName(final String friendlyName) { return this; } - public ApiKeyUpdater setPolicy(final Map policy) { + public ApiKeyUpdater setPolicy(final Object policy) { this.policy = policy; return this; } @@ -87,7 +86,7 @@ private void addPostParams(final Request request) { request.addPostParam("FriendlyName", friendlyName); } if (policy != null) { - request.addPostParam("Policy", Converter.mapToJson(policy)); + request.addPostParam("Policy", Converter.objectToJson(policy)); } } } diff --git a/src/main/java/com/twilio/rest/iam/v1/NewApiKeyCreator.java b/src/main/java/com/twilio/rest/iam/v1/NewApiKeyCreator.java index bad41944a6..df5c0c2a42 100644 --- a/src/main/java/com/twilio/rest/iam/v1/NewApiKeyCreator.java +++ b/src/main/java/com/twilio/rest/iam/v1/NewApiKeyCreator.java @@ -26,15 +26,13 @@ import com.twilio.http.Response; import com.twilio.http.TwilioRestClient; import com.twilio.rest.Domains; -import java.util.Map; -import java.util.Map; public class NewApiKeyCreator extends Creator { private String accountSid; private String friendlyName; private NewApiKey.Keytype keyType; - private Map policy; + private Object policy; public NewApiKeyCreator(final String accountSid) { this.accountSid = accountSid; @@ -55,7 +53,7 @@ public NewApiKeyCreator setKeyType(final NewApiKey.Keytype keyType) { return this; } - public NewApiKeyCreator setPolicy(final Map policy) { + public NewApiKeyCreator setPolicy(final Object policy) { this.policy = policy; return this; } @@ -110,7 +108,7 @@ private void addPostParams(final Request request) { request.addPostParam("KeyType", keyType.toString()); } if (policy != null) { - request.addPostParam("Policy", Converter.mapToJson(policy)); + request.addPostParam("Policy", Converter.objectToJson(policy)); } } } diff --git a/src/main/java/com/twilio/rest/knowledge/v1/Knowledge.java b/src/main/java/com/twilio/rest/knowledge/v1/Knowledge.java index badd1abb17..a2a7a572e3 100644 --- a/src/main/java/com/twilio/rest/knowledge/v1/Knowledge.java +++ b/src/main/java/com/twilio/rest/knowledge/v1/Knowledge.java @@ -69,10 +69,10 @@ public static class KnowledgeV1ServiceCreatePolicyRequest { @JsonProperty("policy_details") @Getter @Setter - private Map policyDetails; + private Object policyDetails; public String getPolicyDetails() { - return Converter.mapToJson(policyDetails); + return Converter.objectToJson(policyDetails); } @JsonInclude(JsonInclude.Include.NON_EMPTY) diff --git a/src/main/java/com/twilio/rest/marketplace/v1/InstalledAddOnCreator.java b/src/main/java/com/twilio/rest/marketplace/v1/InstalledAddOnCreator.java index ee0f998762..daafa5c509 100644 --- a/src/main/java/com/twilio/rest/marketplace/v1/InstalledAddOnCreator.java +++ b/src/main/java/com/twilio/rest/marketplace/v1/InstalledAddOnCreator.java @@ -26,14 +26,12 @@ import com.twilio.http.Response; import com.twilio.http.TwilioRestClient; import com.twilio.rest.Domains; -import java.util.Map; -import java.util.Map; public class InstalledAddOnCreator extends Creator { private String availableAddOnSid; private Boolean acceptTermsOfService; - private Map configuration; + private Object configuration; private String uniqueName; public InstalledAddOnCreator( @@ -58,9 +56,7 @@ public InstalledAddOnCreator setAcceptTermsOfService( return this; } - public InstalledAddOnCreator setConfiguration( - final Map configuration - ) { + public InstalledAddOnCreator setConfiguration(final Object configuration) { this.configuration = configuration; return this; } @@ -130,7 +126,7 @@ private void addPostParams(final Request request) { if (configuration != null) { request.addPostParam( "Configuration", - Converter.mapToJson(configuration) + Converter.objectToJson(configuration) ); } if (uniqueName != null) { diff --git a/src/main/java/com/twilio/rest/marketplace/v1/InstalledAddOnUpdater.java b/src/main/java/com/twilio/rest/marketplace/v1/InstalledAddOnUpdater.java index 4ed526bbea..4863943fb4 100644 --- a/src/main/java/com/twilio/rest/marketplace/v1/InstalledAddOnUpdater.java +++ b/src/main/java/com/twilio/rest/marketplace/v1/InstalledAddOnUpdater.java @@ -25,21 +25,18 @@ import com.twilio.http.Response; import com.twilio.http.TwilioRestClient; import com.twilio.rest.Domains; -import java.util.Map; public class InstalledAddOnUpdater extends Updater { private String pathSid; - private Map configuration; + private Object configuration; private String uniqueName; public InstalledAddOnUpdater(final String pathSid) { this.pathSid = pathSid; } - public InstalledAddOnUpdater setConfiguration( - final Map configuration - ) { + public InstalledAddOnUpdater setConfiguration(final Object configuration) { this.configuration = configuration; return this; } @@ -91,7 +88,7 @@ private void addPostParams(final Request request) { if (configuration != null) { request.addPostParam( "Configuration", - Converter.mapToJson(configuration) + Converter.objectToJson(configuration) ); } if (uniqueName != null) { diff --git a/src/main/java/com/twilio/rest/messaging/v2/ChannelsSender.java b/src/main/java/com/twilio/rest/messaging/v2/ChannelsSender.java index cd51cb9005..0560e1d4ce 100644 --- a/src/main/java/com/twilio/rest/messaging/v2/ChannelsSender.java +++ b/src/main/java/com/twilio/rest/messaging/v2/ChannelsSender.java @@ -31,8 +31,6 @@ import java.io.InputStream; import java.net.URI; import java.util.List; -import java.util.Map; -import java.util.Map; import java.util.Objects; import lombok.Getter; import lombok.Setter; @@ -58,7 +56,7 @@ public static class MessagingV2ChannelsSenderConfiguration { @JsonProperty("verification_method") @Getter @Setter - private ChannelsSender.VerificationMethodEnum verificationMethod; + private VerificationMethodEnum verificationMethod; @JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonProperty("verification_code") @@ -96,7 +94,7 @@ public static class MessagingV2ChannelsSenderWebhook { @JsonProperty("callback_method") @Getter @Setter - private ChannelsSender.CallbackMethodEnum callbackMethod; + private CallbackMethodEnum callbackMethod; @JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonProperty("fallback_url") @@ -108,7 +106,7 @@ public static class MessagingV2ChannelsSenderWebhook { @JsonProperty("fallback_method") @Getter @Setter - private ChannelsSender.FallbackMethodEnum fallbackMethod; + private FallbackMethodEnum fallbackMethod; @JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonProperty("status_callback_url") @@ -164,10 +162,10 @@ public static class MessagingV2ChannelsSenderProfile { @JsonProperty("emails") @Getter @Setter - private Map emails; + private Object emails; public String getEmails() { - return Converter.mapToJson(emails); + return Converter.objectToJson(emails); } @JsonInclude(JsonInclude.Include.NON_EMPTY) @@ -186,10 +184,10 @@ public String getEmails() { @JsonProperty("websites") @Getter @Setter - private Map websites; + private Object websites; public String getWebsites() { - return Converter.mapToJson(websites); + return Converter.objectToJson(websites); } public static MessagingV2ChannelsSenderProfile fromJson( diff --git a/src/test/java/com/twilio/converter/ConverterTest.java b/src/test/java/com/twilio/converter/ConverterTest.java new file mode 100644 index 0000000000..cef54fd7a0 --- /dev/null +++ b/src/test/java/com/twilio/converter/ConverterTest.java @@ -0,0 +1,134 @@ +package com.twilio.converter; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.util.*; + +/** + * Test class for {@link Converter}. + */ +public class ConverterTest { + + private static class Container { + @JsonInclude(JsonInclude.Include.NON_EMPTY) + @JsonProperty("emails") + @Getter + @Setter + private Object emails; + + public String getEmails() { + return Converter.objectToJson(emails); + } + + public Container(Object emails) { + this.emails = emails; + } + } + + @Test + public void testAnyTypeNull() throws IOException { + Container c = new Container(null); + Assert.assertEquals("null", c.getEmails()); + } + + @Test + public void testAnyTypeString() throws IOException { + Container c = new Container("emails"); + Assert.assertEquals("emails", c.getEmails()); + } + + @Test + public void testAnyTypeInteger() throws IOException { + Container c = new Container(2); + Assert.assertEquals("2", c.getEmails()); + } + + @Test + public void testAnyTypeBoolean() { + Container c = new Container(true); + Assert.assertEquals("true", c.getEmails()); + } + + @Test + public void testAnyTypeIntArray() { + Container c = new Container(new int[]{1, 2, 3}); + Assert.assertEquals("[1, 2, 3]", c.getEmails()); + } + + @Test + public void testAnyTypeLongArray() { + Container c = new Container(new long[]{1L, 2L, 3L}); + Assert.assertEquals("[1, 2, 3]", c.getEmails()); + } + + @Test + public void testAnyTypeDoubleArray() { + Container c = new Container(new double[]{1.1, 2.2, 3.3}); + Assert.assertEquals("[1.1, 2.2, 3.3]", c.getEmails()); + } + + @Test + public void testAnyTypeFloatArray() { + Container c = new Container(new float[]{1.1f, 2.2f, 3.3f}); + Assert.assertEquals("[1.1, 2.2, 3.3]", c.getEmails()); + } + + @Test + public void testAnyTypeBooleanArray() { + Container c = new Container(new boolean[]{true, false}); + Assert.assertEquals("[true, false]", c.getEmails()); + } + + @Test + public void testAnyTypeByteArray() { + Container c = new Container(new byte[]{1, 2, 3}); + Assert.assertEquals("[1, 2, 3]", c.getEmails()); + } + + @Test + public void testAnyTypeShortArray() { + Container c = new Container(new short[]{1, 2, 3}); + Assert.assertEquals("[1, 2, 3]", c.getEmails()); + } + + @Test + public void testAnyTypeCharArray() { + Container c = new Container(new char[]{'a', 'b', 'c'}); + Assert.assertEquals("[a, b, c]", c.getEmails()); + } + + @Test + public void testAnyTypeStringArray() { + Container c = new Container(new String[]{"a", "b", "c"}); + Assert.assertEquals("[a, b, c]", c.getEmails()); + } + + @Test + public void testAnyTypeList() { + Container c = new Container(Arrays.asList("test@example.com", "admin@example.com")); + Assert.assertEquals("[\"test@example.com\",\"admin@example.com\"]", c.getEmails()); + } + + @Test + public void testAnyTypeSet() { + Container c = new Container(new HashSet<>(Arrays.asList(5, 6))); + // Sets have no order, so either possibility is allowed + String result = c.getEmails(); + Assert.assertTrue(result.equals("[5,6]") || result.equals("[6,5]")); + } + + @Test + public void testAnyTypeMap() { + Map emails = new LinkedHashMap<>(); + emails.put("a", 1); + emails.put("b", "two"); + Container c = new Container(emails); + Assert.assertEquals("{\"a\":1,\"b\":\"two\"}", c.getEmails()); + } +}