1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */

15
16 package software.amazon.awssdk.protocols.xml.internal.marshall;
17
18 import java.time.Instant;
19 import java.util.Map;
20 import software.amazon.awssdk.annotations.SdkInternalApi;
21 import software.amazon.awssdk.core.SdkField;
22 import software.amazon.awssdk.core.protocol.MarshallLocation;
23 import software.amazon.awssdk.protocols.core.ValueToStringConverter;
24
25 @SdkInternalApi
26 public final class HeaderMarshaller {
27
28     public static final XmlMarshaller<String> STRING = new SimpleHeaderMarshaller<>(ValueToStringConverter.FROM_STRING);
29
30     public static final XmlMarshaller<Integer> INTEGER = new SimpleHeaderMarshaller<>(ValueToStringConverter.FROM_INTEGER);
31
32     public static final XmlMarshaller<Long> LONG = new SimpleHeaderMarshaller<>(ValueToStringConverter.FROM_LONG);
33
34     public static final XmlMarshaller<Double> DOUBLE = new SimpleHeaderMarshaller<>(ValueToStringConverter.FROM_DOUBLE);
35
36     public static final XmlMarshaller<Float> FLOAT = new SimpleHeaderMarshaller<>(ValueToStringConverter.FROM_FLOAT);
37
38     public static final XmlMarshaller<Boolean> BOOLEAN = new SimpleHeaderMarshaller<>(ValueToStringConverter.FROM_BOOLEAN);
39
40     public static final XmlMarshaller<Instant> INSTANT =
41         new SimpleHeaderMarshaller<>(XmlProtocolMarshaller.INSTANT_VALUE_TO_STRING);
42
43     public static final XmlMarshaller<Map<String, ?>> MAP = new SimpleHeaderMarshaller<Map<String, ?>>(null) {
44         @Override
45         public void marshall(Map<String, ?> map, XmlMarshallerContext context, String paramName,
46                              SdkField<Map<String, ?>> sdkField) {
47             if (!shouldEmit(map)) {
48                 return;
49             }
50
51             for (Map.Entry<String, ?> entry : map.entrySet()) {
52                 String key = entry.getKey().startsWith(paramName) ? entry.getKey()
53                                                                   : paramName + entry.getKey();
54
55                 XmlMarshaller marshaller = context.marshallerRegistry().getMarshaller(MarshallLocation.HEADER, entry.getValue());
56
57                 marshaller.marshall(entry.getValue(), context, key, null);
58             }
59         }
60
61         @Override
62         protected boolean shouldEmit(Map map) {
63             return map != null && !map.isEmpty();
64         }
65     };
66
67
68     private HeaderMarshaller() {
69     }
70
71     private static class SimpleHeaderMarshaller<T> implements XmlMarshaller<T> {
72         private final ValueToStringConverter.ValueToString<T> converter;
73
74         private SimpleHeaderMarshaller(ValueToStringConverter.ValueToString<T> converter) {
75             this.converter = converter;
76         }
77
78         @Override
79         public void marshall(T val, XmlMarshallerContext context, String paramName, SdkField<T> sdkField) {
80             if (!shouldEmit(val)) {
81                 return;
82             }
83
84             context.request().putHeader(paramName, converter.convert(val, sdkField));
85         }
86
87         protected boolean shouldEmit(T val) {
88             return val != null;
89         }
90     }
91 }
92