
software.amazon.awssdk.protocols.json.internal.unmarshall.JsonProtocolUnmarshaller Maven / Gradle / Ivy
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package software.amazon.awssdk.protocols.json.internal.unmarshall;
import static software.amazon.awssdk.protocols.core.StringToValueConverter.TO_SDK_BYTES;
import java.io.IOException;
import java.time.Instant;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.annotations.ThreadSafe;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.core.SdkField;
import software.amazon.awssdk.core.SdkPojo;
import software.amazon.awssdk.core.document.Document;
import software.amazon.awssdk.core.protocol.MarshallLocation;
import software.amazon.awssdk.core.protocol.MarshallingType;
import software.amazon.awssdk.core.traits.ListTrait;
import software.amazon.awssdk.core.traits.MapTrait;
import software.amazon.awssdk.core.traits.PayloadTrait;
import software.amazon.awssdk.core.traits.TimestampFormatTrait;
import software.amazon.awssdk.http.AbortableInputStream;
import software.amazon.awssdk.http.SdkHttpFullResponse;
import software.amazon.awssdk.protocols.core.StringToInstant;
import software.amazon.awssdk.protocols.core.StringToValueConverter;
import software.amazon.awssdk.protocols.json.internal.MarshallerUtil;
import software.amazon.awssdk.protocols.json.internal.unmarshall.document.DocumentUnmarshaller;
import software.amazon.awssdk.protocols.jsoncore.JsonNode;
import software.amazon.awssdk.protocols.jsoncore.JsonNodeParser;
import software.amazon.awssdk.utils.builder.Buildable;
/**
* Unmarshaller implementation for both JSON RPC and REST JSON services. This class is thread-safe and it is
* recommended to reuse a single instance for best performance.
*/
@SdkInternalApi
@ThreadSafe
public final class JsonProtocolUnmarshaller {
public final StringToValueConverter.StringToValue instantStringToValue;
private final JsonUnmarshallerRegistry registry;
private final JsonNodeParser parser;
private JsonProtocolUnmarshaller(Builder builder) {
this.parser = builder.parser;
this.instantStringToValue = StringToInstant.create(builder.defaultTimestampFormats.isEmpty() ?
new EnumMap<>(MarshallLocation.class) :
new EnumMap<>(builder.defaultTimestampFormats));
this.registry = createUnmarshallerRegistry(instantStringToValue);
}
private static JsonUnmarshallerRegistry createUnmarshallerRegistry(
StringToValueConverter.StringToValue instantStringToValue) {
return JsonUnmarshallerRegistry
.builder()
.statusCodeUnmarshaller(MarshallingType.INTEGER, (context, json, f) -> context.response().statusCode())
.headerUnmarshaller(MarshallingType.STRING, HeaderUnmarshaller.STRING)
.headerUnmarshaller(MarshallingType.INTEGER, HeaderUnmarshaller.INTEGER)
.headerUnmarshaller(MarshallingType.LONG, HeaderUnmarshaller.LONG)
.headerUnmarshaller(MarshallingType.SHORT, HeaderUnmarshaller.SHORT)
.headerUnmarshaller(MarshallingType.DOUBLE, HeaderUnmarshaller.DOUBLE)
.headerUnmarshaller(MarshallingType.BOOLEAN, HeaderUnmarshaller.BOOLEAN)
.headerUnmarshaller(MarshallingType.INSTANT, HeaderUnmarshaller.createInstantHeaderUnmarshaller(instantStringToValue))
.headerUnmarshaller(MarshallingType.FLOAT, HeaderUnmarshaller.FLOAT)
.headerUnmarshaller(MarshallingType.LIST, HeaderUnmarshaller.LIST)
.payloadUnmarshaller(MarshallingType.STRING, new SimpleTypeJsonUnmarshaller<>(StringToValueConverter.TO_STRING))
.payloadUnmarshaller(MarshallingType.INTEGER, new SimpleTypeJsonUnmarshaller<>(StringToValueConverter.TO_INTEGER))
.payloadUnmarshaller(MarshallingType.LONG, new SimpleTypeJsonUnmarshaller<>(StringToValueConverter.TO_LONG))
.payloadUnmarshaller(MarshallingType.SHORT, new SimpleTypeJsonUnmarshaller<>(StringToValueConverter.TO_SHORT))
.payloadUnmarshaller(MarshallingType.FLOAT, new SimpleTypeJsonUnmarshaller<>(StringToValueConverter.TO_FLOAT))
.payloadUnmarshaller(MarshallingType.DOUBLE, new SimpleTypeJsonUnmarshaller<>(StringToValueConverter.TO_DOUBLE))
.payloadUnmarshaller(MarshallingType.BIG_DECIMAL, new SimpleTypeJsonUnmarshaller<>(
StringToValueConverter.TO_BIG_DECIMAL))
.payloadUnmarshaller(MarshallingType.BOOLEAN, new SimpleTypeJsonUnmarshaller<>(StringToValueConverter.TO_BOOLEAN))
.payloadUnmarshaller(MarshallingType.SDK_BYTES, JsonProtocolUnmarshaller::unmarshallSdkBytes)
.payloadUnmarshaller(MarshallingType.INSTANT, new SimpleTypeJsonUnmarshaller<>(instantStringToValue))
.payloadUnmarshaller(MarshallingType.SDK_POJO, JsonProtocolUnmarshaller::unmarshallStructured)
.payloadUnmarshaller(MarshallingType.LIST, JsonProtocolUnmarshaller::unmarshallList)
.payloadUnmarshaller(MarshallingType.MAP, JsonProtocolUnmarshaller::unmarshallMap)
.payloadUnmarshaller(MarshallingType.DOCUMENT, JsonProtocolUnmarshaller::unmarshallDocument)
.build();
}
private static SdkBytes unmarshallSdkBytes(JsonUnmarshallerContext context,
JsonNode jsonContent,
SdkField field) {
if (jsonContent == null || jsonContent.isNull()) {
return null;
}
// Binary protocols like CBOR may already have the raw bytes extracted.
if (jsonContent.isEmbeddedObject()) {
return SdkBytes.fromByteArray((byte[]) jsonContent.asEmbeddedObject());
} else {
// Otherwise decode the JSON string as Base64
return TO_SDK_BYTES.convert(jsonContent.text(), field);
}
}
private static SdkPojo unmarshallStructured(JsonUnmarshallerContext context, JsonNode jsonContent, SdkField f) {
if (jsonContent == null || jsonContent.isNull()) {
return null;
} else {
return unmarshallStructured(f.constructor().get(), jsonContent, context);
}
}
private static Document unmarshallDocument(JsonUnmarshallerContext context,
JsonNode jsonContent,
SdkField field) {
if (jsonContent == null) {
return null;
}
return jsonContent.isNull() ? Document.fromNull() : getDocumentFromJsonContent(jsonContent);
}
private static Document getDocumentFromJsonContent(JsonNode jsonContent) {
return jsonContent.visit(new DocumentUnmarshaller());
}
private static Map unmarshallMap(JsonUnmarshallerContext context,
JsonNode jsonContent,
SdkField
© 2015 - 2025 Weber Informatics LLC | Privacy Policy