33import java .io .IOException ;
44import java .util .AbstractMap .SimpleEntry ;
55import java .util .ArrayList ;
6+ import java .util .Arrays ;
67import java .util .Collections ;
78import java .util .HashMap ;
89import java .util .HashSet ;
910import java .util .List ;
1011import java .util .Map ;
12+ import java .util .Map .Entry ;
1113import java .util .Set ;
1214import java .util .function .Consumer ;
15+ import java .util .function .UnaryOperator ;
16+
1317import io .apimatic .core .authentication .AuthBuilder ;
1418import io .apimatic .core .exceptions .AuthValidationException ;
1519import io .apimatic .core .types .http .request .MultipartFileWrapper ;
@@ -84,10 +88,12 @@ private HttpRequest(final GlobalConfiguration coreConfig, final String server,
8488 // Creating a basic request to provide it to auth instances
8589 Request request = buildBasicRequest (httpMethod , requestHeaders );
8690
87- applyAuthentication (request , authentication );
88- // include auth query parameters in request query params to have them in the query url
89- if (request .getQueryParameters () != null ) {
90- queryParams .putAll (request .getQueryParameters ());
91+ if (request != null ) {
92+ applyAuthentication (request , authentication );
93+ // include auth query parameters in request query params to have them in the query url
94+ if (request .getQueryParameters () != null ) {
95+ queryParams .putAll (request .getQueryParameters ());
96+ }
9197 }
9298
9399 queryUrlBuilder = getStringBuilder (server , path , queryParams , arraySerializationFormat );
@@ -284,7 +290,7 @@ public static class Builder {
284290 /**
285291 * A map of header parameters.
286292 */
287- private Map <String , List <String >> headerParams = new HashMap <>();
293+ private Map <String , List <Object >> headerParams = new HashMap <>();
288294
289295 /**
290296 * A set of {@link Parameter}.
@@ -322,6 +328,78 @@ public static class Builder {
322328 */
323329 private Parameter .Builder parameterBuilder = new Parameter .Builder ();
324330
331+ /**
332+ * Update the request parameters using a setter.
333+ *
334+ * @param pointer A JSON pointer pointing to any request field.
335+ * @param setter A function that takes in an old value and returns a new value.
336+ * @return The updated instance of current request builder.
337+ */
338+ public Builder updateByReference (String pointer , UnaryOperator <Object > setter ) {
339+ if (pointer == null ) {
340+ return this ;
341+ }
342+
343+ String [] pointerParts = pointer .split ("#" );
344+ String prefix = pointerParts [0 ];
345+ String point = pointerParts .length > 1 ? pointerParts [1 ] : "" ;
346+
347+ switch (prefix ) {
348+ case "$request.path" :
349+ updateTemplateParams (setter , point );
350+ return this ;
351+ case "$request.query" :
352+ queryParams = CoreHelper .updateValueByPointer (queryParams , point , setter );
353+ return this ;
354+ case "$request.headers" :
355+ updateHeaderParams (setter , point );
356+ return this ;
357+ default :
358+ return this ;
359+ }
360+ }
361+
362+ @ SuppressWarnings ("unchecked" )
363+ private void updateHeaderParams (UnaryOperator <Object > setter , String point ) {
364+ Map <String , Object > simplifiedHeaders = new HashMap <>();
365+ for (Entry <String , List <Object >> entry : headerParams .entrySet ()) {
366+ if (entry .getValue ().size () == 1 ) {
367+ simplifiedHeaders .put (entry .getKey (), entry .getValue ().get (0 ));
368+ } else {
369+ simplifiedHeaders .put (entry .getKey (), entry .getValue ());
370+ }
371+ }
372+
373+ simplifiedHeaders = CoreHelper .updateValueByPointer (simplifiedHeaders , point , setter );
374+
375+ for (Map .Entry <String , Object > entry : simplifiedHeaders .entrySet ()) {
376+ if (entry .getValue () instanceof List <?>) {
377+ headerParams .put (entry .getKey (), (List <Object >) entry .getValue ());
378+ } else {
379+ headerParams .put (entry .getKey (), Arrays .asList (entry .getValue ()));
380+ }
381+ }
382+ }
383+
384+ private void updateTemplateParams (UnaryOperator <Object > setter , String point ) {
385+ Map <String , Object > simplifiedPath = new HashMap <>();
386+ for (Map .Entry <String , SimpleEntry <Object , Boolean >> entry
387+ : templateParams .entrySet ()) {
388+ simplifiedPath .put (entry .getKey (), entry .getValue ().getKey ());
389+ }
390+
391+ simplifiedPath = CoreHelper .updateValueByPointer (simplifiedPath , point , setter );
392+
393+ for (Map .Entry <String , Object > entry : simplifiedPath .entrySet ()) {
394+ // Preserve the original boolean if it exists, otherwise set default (e.g., false)
395+ Boolean originalFlag = templateParams .containsKey (entry .getKey ())
396+ ? templateParams .get (entry .getKey ()).getValue ()
397+ : false ;
398+ templateParams .put (entry .getKey (),
399+ new SimpleEntry <>(entry .getValue (), originalFlag ));
400+ }
401+ }
402+
325403 /**
326404 * Base uri server address.
327405 * @param server the base uri address.
@@ -372,7 +450,6 @@ public Builder queryParam(Map<String, Object> queryParameters) {
372450 return this ;
373451 }
374452
375-
376453 /**
377454 * To configure the query paramater.
378455 * @param action the query parameter {@link Consumer}.
@@ -414,32 +491,17 @@ public Builder headerParam(Consumer<Parameter.Builder> action) {
414491 Parameter httpHeaderParameter = parameterBuilder .build ();
415492 httpHeaderParameter .validate ();
416493 String key = httpHeaderParameter .getKey ();
417- String value = getSerializedHeaderValue (httpHeaderParameter .getValue ());
418494
419495 if (headerParams .containsKey (key )) {
420- headerParams .get (key ).add (value );
496+ headerParams .get (key ).add (httpHeaderParameter . getValue () );
421497 } else {
422- List <String > headerValues = new ArrayList <String >();
423- headerValues .add (value );
498+ List <Object > headerValues = new ArrayList <Object >();
499+ headerValues .add (httpHeaderParameter . getValue () );
424500 headerParams .put (key , headerValues );
425501 }
426502 return this ;
427503 }
428504
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-
443505 /**
444506 * To configure the form parameter.
445507 * @param action the form parameter {@link Consumer}.
@@ -505,6 +567,38 @@ public Builder arraySerializationFormat(ArraySerializationFormat arraySerializat
505567 return this ;
506568 }
507569
570+ private Map <String , List <String >> getHeaderParams () {
571+ Map <String , List <String >> converted = new HashMap <>();
572+
573+ for (Map .Entry <String , List <Object >> entry : headerParams .entrySet ()) {
574+ String key = entry .getKey ();
575+ List <Object > originalList = entry .getValue ();
576+
577+ List <String > serializedList = new ArrayList <>();
578+ for (Object obj : originalList ) {
579+ serializedList .add (getSerializedHeaderValue (obj ));
580+ }
581+
582+ converted .put (key , serializedList );
583+ }
584+
585+ return converted ;
586+ }
587+
588+ private static String getSerializedHeaderValue (Object obj ) {
589+ if (obj == null ) {
590+ return null ;
591+ }
592+
593+ if (CoreHelper .isTypeCombinatorStringCase (obj )
594+ || CoreHelper .isTypeCombinatorDateTimeCase (obj )
595+ || obj instanceof String ) {
596+ return obj .toString ();
597+ }
598+
599+ return CoreHelper .trySerialize (obj );
600+ }
601+
508602 /**
509603 * Initialise the CoreHttpRequest.
510604 * @param coreConfig the configuration for the Http request.
@@ -515,8 +609,9 @@ public Request build(GlobalConfiguration coreConfig) throws IOException {
515609 Authentication authentication = authBuilder .build (coreConfig .getAuthentications ());
516610 HttpRequest coreRequest =
517611 new HttpRequest (coreConfig , server , path , httpMethod , authentication ,
518- queryParams , templateParams , headerParams , formParams , formParamaters ,
519- body , bodySerializer , bodyParameters , arraySerializationFormat );
612+ queryParams , templateParams , getHeaderParams (), formParams ,
613+ formParamaters , body , bodySerializer , bodyParameters ,
614+ arraySerializationFormat );
520615 Request coreHttpRequest = coreRequest .getCoreHttpRequest ();
521616
522617 if (coreConfig .getHttpCallback () != null ) {
0 commit comments