software.amazon.awssdk.protocols.xml.internal.marshall.XmlProtocolMarshaller Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aws-xml-protocol Show documentation
Show all versions of aws-xml-protocol Show documentation
The AWS SDK for Java - module holds the classes for AWS Xml protocol
/*
* 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.xml.internal.marshall;
import static software.amazon.awssdk.http.Header.CONTENT_LENGTH;
import static software.amazon.awssdk.http.Header.CONTENT_TYPE;
import java.io.ByteArrayInputStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Collections;
import java.util.EnumMap;
import java.util.Map;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.core.SdkField;
import software.amazon.awssdk.core.SdkPojo;
import software.amazon.awssdk.core.protocol.MarshallLocation;
import software.amazon.awssdk.core.protocol.MarshallingType;
import software.amazon.awssdk.core.traits.PayloadTrait;
import software.amazon.awssdk.core.traits.TimestampFormatTrait;
import software.amazon.awssdk.core.traits.TraitType;
import software.amazon.awssdk.http.SdkHttpFullRequest;
import software.amazon.awssdk.protocols.core.InstantToString;
import software.amazon.awssdk.protocols.core.OperationInfo;
import software.amazon.awssdk.protocols.core.ProtocolMarshaller;
import software.amazon.awssdk.protocols.core.ProtocolUtils;
import software.amazon.awssdk.protocols.core.ValueToStringConverter;
import software.amazon.awssdk.protocols.xml.AwsXmlProtocolFactory;
import software.amazon.awssdk.utils.StringInputStream;
/**
* Implementation of {@link ProtocolMarshaller} for REST-XML services. This is currently only Cloudfront, Route53,
* and S3.
*/
@SdkInternalApi
public final class XmlProtocolMarshaller implements ProtocolMarshaller {
public static final ValueToStringConverter.ValueToString INSTANT_VALUE_TO_STRING =
InstantToString.create(getDefaultTimestampFormats());
private static final XmlMarshallerRegistry MARSHALLER_REGISTRY = createMarshallerRegistry();
private final URI endpoint;
private final SdkHttpFullRequest.Builder request;
private final String rootElement;
private final XmlMarshallerContext marshallerContext;
private XmlProtocolMarshaller(Builder builder) {
this.endpoint = builder.endpoint;
this.request = ProtocolUtils.createSdkHttpRequest(builder.operationInfo, this.endpoint);
this.rootElement = builder.operationInfo.addtionalMetadata(AwsXmlProtocolFactory.ROOT_MARSHALL_LOCATION_ATTRIBUTE);
this.marshallerContext = XmlMarshallerContext.builder()
.xmlGenerator(builder.xmlGenerator)
.marshallerRegistry(MARSHALLER_REGISTRY)
.protocolMarshaller(this)
.request(request)
.build();
}
@Override
public SdkHttpFullRequest marshall(SdkPojo pojo) {
if (rootElement != null) {
marshallerContext.xmlGenerator().startElement(rootElement);
}
doMarshall(pojo);
if (rootElement != null) {
marshallerContext.xmlGenerator().endElement();
}
return finishMarshalling(pojo);
}
void doMarshall(SdkPojo pojo) {
for (SdkField> field : pojo.sdkFields()) {
Object val = field.getValueOrDefault(pojo);
if (isBinary(field, val)) {
SdkBytes sdkBytes = (SdkBytes) val;
request.contentStreamProvider(sdkBytes::asInputStream);
setContentTypeHeaderIfNeeded("binary/octet-stream");
request.putHeader(CONTENT_LENGTH, Integer.toString(sdkBytes.asByteArrayUnsafe().length));
} else if (isExplicitPayloadMember(field) && val instanceof String) {
byte[] content = ((String) val).getBytes(StandardCharsets.UTF_8);
request.contentStreamProvider(() -> new ByteArrayInputStream(content));
request.putHeader(CONTENT_LENGTH, Integer.toString(content.length));
} else {
MARSHALLER_REGISTRY.getMarshaller(field.location(), field.marshallingType(), val)
.marshall(val, marshallerContext, field.locationName(), (SdkField