All Downloads are FREE. Search and download functionalities are using the official Maven repository.

software.amazon.awssdk.protocols.xml.internal.unmarshall.XmlPayloadUnmarshaller Maven / Gradle / Ivy

The newest version!
/*
 * 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.unmarshall;

import static java.util.Collections.singletonList;

import java.math.BigDecimal;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
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.traits.ListTrait;
import software.amazon.awssdk.core.traits.MapTrait;
import software.amazon.awssdk.core.traits.TraitType;
import software.amazon.awssdk.protocols.core.StringToValueConverter;
import software.amazon.awssdk.protocols.query.unmarshall.XmlElement;

@SdkInternalApi
public final class XmlPayloadUnmarshaller {
    public static final XmlUnmarshaller STRING = new SimpleTypePayloadUnmarshaller<>(StringToValueConverter.TO_STRING);
    public static final XmlUnmarshaller INTEGER = new SimpleTypePayloadUnmarshaller<>(StringToValueConverter.TO_INTEGER);
    public static final XmlUnmarshaller LONG = new SimpleTypePayloadUnmarshaller<>(StringToValueConverter.TO_LONG);
    public static final XmlUnmarshaller SHORT = new SimpleTypePayloadUnmarshaller<>(StringToValueConverter.TO_SHORT);
    public static final XmlUnmarshaller FLOAT = new SimpleTypePayloadUnmarshaller<>(StringToValueConverter.TO_FLOAT);
    public static final XmlUnmarshaller DOUBLE = new SimpleTypePayloadUnmarshaller<>(StringToValueConverter.TO_DOUBLE);
    public static final XmlUnmarshaller BIG_DECIMAL =
        new SimpleTypePayloadUnmarshaller<>(StringToValueConverter.TO_BIG_DECIMAL);
    public static final XmlUnmarshaller BOOLEAN = new SimpleTypePayloadUnmarshaller<>(StringToValueConverter.TO_BOOLEAN);
    public static final XmlUnmarshaller INSTANT =
        new SimpleTypePayloadUnmarshaller<>(XmlProtocolUnmarshaller.INSTANT_STRING_TO_VALUE);
    public static final XmlUnmarshaller SDK_BYTES =
        new SimpleTypePayloadUnmarshaller<>(StringToValueConverter.TO_SDK_BYTES);

    private XmlPayloadUnmarshaller() {
    }

    public static SdkPojo unmarshallSdkPojo(XmlUnmarshallerContext context, List content, SdkField field) {
        return context.protocolUnmarshaller()
                      .unmarshall(context, field.constructor().get(), content.get(0));
    }

    public static List unmarshallList(XmlUnmarshallerContext context, List content, SdkField> field) {
        ListTrait listTrait = field.getTrait(ListTrait.class, TraitType.LIST_TRAIT);
        List list = new ArrayList<>();

        getMembers(content, listTrait).forEach(member -> {
            XmlUnmarshaller unmarshaller = context.getUnmarshaller(listTrait.memberFieldInfo().location(),
                                                                   listTrait.memberFieldInfo().marshallingType());
            list.add(unmarshaller.unmarshall(context, singletonList(member), listTrait.memberFieldInfo()));
        });
        return list;
    }

    private static List getMembers(List content, ListTrait listTrait) {
        String memberLocation = listTrait.memberLocationName() != null ? listTrait.memberLocationName()
                                                                       : listTrait.memberFieldInfo().locationName();

        return listTrait.isFlattened() ?
               content :
               content.get(0).getElementsByName(memberLocation);
    }

    public static Map unmarshallMap(XmlUnmarshallerContext context, List content,
                                               SdkField> field) {
        Map map = new HashMap<>();
        MapTrait mapTrait = field.getTrait(MapTrait.class, TraitType.MAP_TRAIT);
        SdkField mapValueSdkField = mapTrait.valueFieldInfo();

        getEntries(content, mapTrait).forEach(entry -> {
            XmlElement key = entry.getElementByName(mapTrait.keyLocationName());
            XmlElement value = entry.getElementByName(mapTrait.valueLocationName());
            XmlUnmarshaller unmarshaller = context.getUnmarshaller(mapValueSdkField.location(),
                                                                   mapValueSdkField.marshallingType());
            map.put(key.textContent(),
                    unmarshaller.unmarshall(context, singletonList(value), mapValueSdkField));
        });
        return map;
    }

    private static List getEntries(List content, MapTrait mapTrait) {
        return mapTrait.isFlattened() ?
               content :
               content.get(0).getElementsByName("entry");
    }

    /**
     * Base payload unmarshaller for simple types of xml protocol
     * @param  Type to unmarshall
     */
    private static class SimpleTypePayloadUnmarshaller implements XmlUnmarshaller {
        private final StringToValueConverter.StringToValue converter;

        private SimpleTypePayloadUnmarshaller(StringToValueConverter.StringToValue converter) {
            this.converter = converter;
        }

        @Override
        public T unmarshall(XmlUnmarshallerContext context, List content, SdkField field) {
            if (content == null) {
                return null;
            }
            return converter.convert(content.get(0).textContent(), field);
        }
    }
}