Skip to content

Commit 7272b89

Browse files
authored
feat: add Support for Complex object-typed header parameters (#124)
1 parent fc310e2 commit 7272b89

File tree

5 files changed

+135
-8
lines changed

5 files changed

+135
-8
lines changed

src/main/java/io/apimatic/core/HttpRequest.java

+15-3
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,7 @@ public Builder headerParam(Consumer<Parameter.Builder> action) {
414414
Parameter httpHeaderParameter = parameterBuilder.build();
415415
httpHeaderParameter.validate();
416416
String key = httpHeaderParameter.getKey();
417-
String value =
418-
httpHeaderParameter.getValue() == null ? null
419-
: httpHeaderParameter.getValue().toString();
417+
String value = getSerializedHeaderValue(httpHeaderParameter.getValue());
420418

421419
if (headerParams.containsKey(key)) {
422420
headerParams.get(key).add(value);
@@ -428,6 +426,20 @@ public Builder headerParam(Consumer<Parameter.Builder> action) {
428426
return this;
429427
}
430428

429+
private static String getSerializedHeaderValue(Object obj) {
430+
if (obj == null) {
431+
return null;
432+
}
433+
434+
if (CoreHelper.isTypeCombinatorStringCase(obj)
435+
|| CoreHelper.isTypeCombinatorDateTimeCase(obj)
436+
|| obj instanceof String) {
437+
return obj.toString();
438+
}
439+
440+
return CoreHelper.trySerialize(obj);
441+
}
442+
431443
/**
432444
* To configure the form parameter.
433445
* @param action the form parameter {@link Consumer}.

src/main/java/io/apimatic/core/utilities/CoreHelper.java

+33-4
Original file line numberDiff line numberDiff line change
@@ -338,16 +338,45 @@ public static String serializeTypeCombinator(Object obj) throws JsonProcessingEx
338338
return null;
339339
}
340340

341-
Annotation stringCaseAnnotation = obj.getClass()
342-
.getAnnotation(TypeCombinatorStringCase.class);
343-
344-
if (stringCaseAnnotation != null) {
341+
if (isTypeCombinatorStringCase(obj)) {
345342
return obj.toString();
346343
}
347344

348345
return serialize(obj);
349346
}
350347

348+
/**
349+
* Check either the object has TypeCombinatorStringCase annotation.
350+
*
351+
* @param obj The object to check annotation.
352+
* @return The boolean result.
353+
*/
354+
public static boolean isTypeCombinatorStringCase(Object obj) {
355+
if (obj == null) {
356+
return false;
357+
}
358+
359+
return obj.getClass().getAnnotation(TypeCombinatorStringCase.class) != null;
360+
}
361+
362+
/**
363+
* Check either the object has TypeCombinatorDateTimeCase annotation.
364+
*
365+
* @param obj The object to check annotation.
366+
* @return The boolean result.
367+
*/
368+
public static boolean isTypeCombinatorDateTimeCase(Object obj) {
369+
if (obj == null) {
370+
return false;
371+
}
372+
373+
HashSet<String> dateTimeList = new HashSet<>(
374+
Arrays.asList("LocalDateTime", "ZonedDateTime"));
375+
String classType = getTypeCombinatorCaseType(obj.getClass());
376+
377+
return dateTimeList.contains(classType);
378+
}
379+
351380
/**
352381
* Json deserialization of the given Json string using a specified
353382
* JsonDerializer.

src/test/java/apimatic/core/RequestBuilderTest.java

+48
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
import java.io.IOException;
1616
import java.time.LocalDateTime;
17+
import java.time.ZoneId;
18+
import java.time.ZonedDateTime;
1719
import java.util.AbstractMap.SimpleEntry;
1820
import java.util.Arrays;
1921
import java.util.Collections;
@@ -34,7 +36,10 @@
3436
import org.mockito.stubbing.Answer;
3537

3638
import apimatic.core.mocks.MockCoreConfig;
39+
import apimatic.core.models.Car;
3740
import apimatic.core.models.Employee;
41+
import apimatic.core.models.Rfc1123Date;
42+
import apimatic.core.models.containers.SendScalarParamBody;
3843
import io.apimatic.core.ApiCall;
3944
import io.apimatic.core.HttpRequest;
4045
import io.apimatic.core.authentication.HeaderAuth;
@@ -311,6 +316,49 @@ public void testHeaderPrecedenceOverAdditional() throws IOException {
311316
assertEquals(actualContentType, expectedContentType);
312317
}
313318

319+
/**
320+
* An instance of {@link LocalDateTime}.
321+
*/
322+
private static final LocalDateTime LOCAL_DATE_TIME = LocalDateTime.of(2021, 1, 20, 12, 12, 41);
323+
/**
324+
* An instance of {@link ZonedDateTime}.
325+
*/
326+
private static final ZonedDateTime ZONED_DATE_TIME =
327+
ZonedDateTime.of(LOCAL_DATE_TIME, ZoneId.of("GMT"));
328+
private static final double PRECISION_NUMBER1 = 100.11;
329+
private static final double PRECISION_NUMBER2 = 133.0;
330+
331+
@Test
332+
public void testComplexHeaderParameter() throws IOException {
333+
// when
334+
String jsonObject = "{\"NumberOfTyres\":\"4\",\"HaveTrunk\":true}";
335+
Car car = CoreHelper.tryDeserialize(jsonObject, Car.class);
336+
337+
SendScalarParamBody bodyStringType = SendScalarParamBody.fromMString("some string");
338+
SendScalarParamBody precisionArray = SendScalarParamBody.fromPrecision(
339+
Arrays.asList(PRECISION_NUMBER1, PRECISION_NUMBER2));
340+
Rfc1123Date rfc1123Date = new Rfc1123Date.Builder()
341+
.dateTime(LOCAL_DATE_TIME)
342+
.zonedDateTime(ZONED_DATE_TIME)
343+
.build();
344+
345+
Request coreHttpRequest =
346+
new HttpRequest.Builder().httpMethod(Method.GET)
347+
.formParam(param -> param.key("formKey").value("value"))
348+
.headerParam(param -> param.key("accept").value("application/json"))
349+
.headerParam(param -> param.key("car-complex-header").value(car))
350+
.headerParam(param -> param.key("any-of-string").value(bodyStringType))
351+
.headerParam(param -> param.key("precision-array").value(precisionArray))
352+
.headerParam(param -> param.key("date-time-header").value(rfc1123Date))
353+
.build(getMockGlobalConfig());
354+
355+
when(coreHttpRequest.getHeaders()).thenReturn(getHttpHeaders());
356+
when(getHttpHeaders().value("car-complex-header")).thenReturn(jsonObject);
357+
358+
// verify
359+
assertEquals(coreHttpRequest.getHeaders().value("car-complex-header"), jsonObject);
360+
}
361+
314362
@Test
315363
public void testHeaderParamMultiple() throws IOException {
316364
// when

src/test/java/apimatic/core/models/containers/SendParamsFormDateTime.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public String toString() {
125125
* This is a implementation class for DateTimeCase.
126126
*/
127127
@JsonDeserialize(using = JsonDeserializer.None.class)
128-
@TypeCombinatorCase
128+
@TypeCombinatorCase(type = "LocalDateTime")
129129
private static class DateTimeCase extends SendParamsFormDateTime {
130130

131131
@JsonValue

src/test/java/apimatic/core/utilities/CoreHelperTest.java

+38
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.LinkedHashMap;
2121
import java.util.List;
2222
import java.util.Map;
23+
import java.util.Random;
2324
import java.util.UUID;
2425

2526
import org.junit.Test;
@@ -124,6 +125,19 @@ public void testSerializeNullObject() throws JsonProcessingException {
124125
assertNull(CoreHelper.serialize(obj));
125126
}
126127

128+
@Test
129+
public void testSerializeBooleanObject() throws JsonProcessingException {
130+
Boolean obj = true;
131+
assertEquals(String.valueOf(obj), CoreHelper.serialize(obj));
132+
}
133+
134+
@Test
135+
public void testSerializeNumberObject() throws JsonProcessingException {
136+
Random random = new Random();
137+
float obj = random.nextFloat();
138+
assertEquals(String.valueOf(obj), CoreHelper.serialize(obj));
139+
}
140+
127141
@Test
128142
public void testTrySerializeValidObject() {
129143
Vehicle model = new Vehicle.Builder("4").build();
@@ -1410,6 +1424,30 @@ public void testTypeCombinatorSerializationString() throws JsonProcessingExcepti
14101424
assertEquals(actual, expected);
14111425
}
14121426

1427+
@Test
1428+
public void testIsTypeCombinatorStringCase() {
1429+
SendScalarParamBody body = SendScalarParamBody.fromMString("some string");
1430+
assertTrue(CoreHelper.isTypeCombinatorStringCase(body));
1431+
}
1432+
1433+
@Test
1434+
public void testIsTypeCombinatorStringCaseNull() {
1435+
SendScalarParamBody body = null;
1436+
assertFalse(CoreHelper.isTypeCombinatorStringCase(body));
1437+
}
1438+
1439+
@Test
1440+
public void testTypeCombinatorSerializationDateTime() {
1441+
SendParamsFormDateTime body = SendParamsFormDateTime.fromDateTime(LocalDateTime.now());
1442+
assertTrue(CoreHelper.isTypeCombinatorDateTimeCase(body));
1443+
}
1444+
1445+
@Test
1446+
public void testTypeCombinatorSerializationDateTimeNull() {
1447+
SendParamsFormDateTime body = null;
1448+
assertFalse(CoreHelper.isTypeCombinatorDateTimeCase(body));
1449+
}
1450+
14131451
@Test
14141452
public void testTypeCombinatorSerializationStringNull() throws JsonProcessingException {
14151453
SendScalarParamBody body = null;

0 commit comments

Comments
 (0)