• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.json.internal.unmarshall;
17 
18 import java.nio.charset.StandardCharsets;
19 import java.time.Instant;
20 import java.util.List;
21 import software.amazon.awssdk.annotations.SdkInternalApi;
22 import software.amazon.awssdk.core.SdkField;
23 import software.amazon.awssdk.core.traits.JsonValueTrait;
24 import software.amazon.awssdk.protocols.core.StringToValueConverter;
25 import software.amazon.awssdk.protocols.jsoncore.JsonNode;
26 import software.amazon.awssdk.utils.BinaryUtils;
27 
28 /**
29  * Header unmarshallers for all the simple types we support.
30  */
31 @SdkInternalApi
32 final class HeaderUnmarshaller {
33 
34     public static final JsonUnmarshaller<String> STRING =
35         new SimpleHeaderUnmarshaller<>(HeaderUnmarshaller::unmarshallStringHeader);
36     public static final JsonUnmarshaller<Integer> INTEGER = new SimpleHeaderUnmarshaller<>(StringToValueConverter.TO_INTEGER);
37     public static final JsonUnmarshaller<Long> LONG = new SimpleHeaderUnmarshaller<>(StringToValueConverter.TO_LONG);
38     public static final JsonUnmarshaller<Short> SHORT = new SimpleHeaderUnmarshaller<>(StringToValueConverter.TO_SHORT);
39     public static final JsonUnmarshaller<Double> DOUBLE = new SimpleHeaderUnmarshaller<>(StringToValueConverter.TO_DOUBLE);
40     public static final JsonUnmarshaller<Boolean> BOOLEAN = new SimpleHeaderUnmarshaller<>(StringToValueConverter.TO_BOOLEAN);
41     public static final JsonUnmarshaller<Float> FLOAT = new SimpleHeaderUnmarshaller<>(StringToValueConverter.TO_FLOAT);
42 
43     // Only supports string value type
44     public static final JsonUnmarshaller<List<?>> LIST =
45         (context, jsonContent, field) -> context.response().matchingHeaders(field.locationName());
46 
HeaderUnmarshaller()47     private HeaderUnmarshaller() {
48     }
49 
50     /**
51      * Unmarshalls a string header, taking into account whether it's a Base 64 encoded JSON value.
52      * <p>
53      * <em>Note:</em> This code does no attempt to validate whether the unmarshalled string does, in fact, represent valid
54      * JSON values. The string value is returned as-is, and it's up to the user to validate the results.
55      *
56      * @param value Value to unmarshall
57      * @param field {@link SdkField} containing metadata about member being unmarshalled.
58      * @return Unmarshalled value.
59      */
unmarshallStringHeader(String value, SdkField<String> field)60     private static String unmarshallStringHeader(String value,
61                                                  SdkField<String> field) {
62         return field.containsTrait(JsonValueTrait.class) ?
63                new String(BinaryUtils.fromBase64(value), StandardCharsets.UTF_8) : value;
64     }
65 
createInstantHeaderUnmarshaller( StringToValueConverter.StringToValue<Instant> instantStringToValue)66     public static JsonUnmarshaller<Instant> createInstantHeaderUnmarshaller(
67         StringToValueConverter.StringToValue<Instant> instantStringToValue) {
68         return new SimpleHeaderUnmarshaller<>(instantStringToValue);
69     }
70 
71     /**
72      * Simple unmarshaller implementation that calls a {@link StringToValueConverter} with the header value if it's present.
73      *
74      * @param <T> Type to unmarshall into.
75      */
76     private static class SimpleHeaderUnmarshaller<T> implements JsonUnmarshaller<T> {
77 
78         private final StringToValueConverter.StringToValue<T> stringToValue;
79 
SimpleHeaderUnmarshaller(StringToValueConverter.StringToValue<T> stringToValue)80         private SimpleHeaderUnmarshaller(StringToValueConverter.StringToValue<T> stringToValue) {
81             this.stringToValue = stringToValue;
82         }
83 
84         @Override
unmarshall(JsonUnmarshallerContext context, JsonNode jsonContent, SdkField<T> field)85         public T unmarshall(JsonUnmarshallerContext context,
86                             JsonNode jsonContent,
87                             SdkField<T> field) {
88             return context.response().firstMatchingHeader(field.locationName())
89                           .map(s -> stringToValue.convert(s, field))
90                           .orElse(null);
91         }
92     }
93 }
94