/* * Copyright 2011-2017 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 com.amazonaws.protocol.json.internal; import com.amazonaws.annotation.SdkInternalApi; import com.amazonaws.internal.SdkInternalList; import com.amazonaws.internal.SdkInternalMap; import com.amazonaws.protocol.MarshallLocation; import com.amazonaws.protocol.StructuredPojo; import com.amazonaws.protocol.json.StructuredJsonGenerator; import java.math.BigDecimal; import java.nio.ByteBuffer; import java.util.Date; import java.util.List; import java.util.Map; @SdkInternalApi public class SimpleTypeJsonMarshallers { public static final JsonMarshaller<Void> NULL = new JsonMarshaller<Void>() { @Override public void marshall(Void val, JsonMarshallerContext context, String paramName) { // If paramName is non null then we are emitting a field of an object, in that // we just don't write the field. If param name is null then we are either in a container // or the thing being marshalled is the payload itself in which case we want to preserve // the JSON null. if (paramName == null) { context.jsonGenerator().writeNull(); } } }; public static final JsonMarshaller<String> STRING = new BaseJsonMarshaller<String>() { @Override public void marshall(String val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) { jsonGenerator.writeValue(val); } }; public static final JsonMarshaller<Integer> INTEGER = new BaseJsonMarshaller<Integer>() { @Override public void marshall(Integer val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) { jsonGenerator.writeValue(val); } }; public static final JsonMarshaller<Long> LONG = new BaseJsonMarshaller<Long>() { @Override public void marshall(Long val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) { jsonGenerator.writeValue(val); } }; public static final JsonMarshaller<Float> FLOAT = new BaseJsonMarshaller<Float>() { @Override public void marshall(Float val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) { jsonGenerator.writeValue(val); } }; public static final JsonMarshaller<BigDecimal> BIG_DECIMAL = new BaseJsonMarshaller<BigDecimal>() { @Override public void marshall(BigDecimal val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) { jsonGenerator.writeValue(val); } }; public static final JsonMarshaller<Double> DOUBLE = new BaseJsonMarshaller<Double>() { @Override public void marshall(Double val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) { jsonGenerator.writeValue(val); } }; public static final JsonMarshaller<Boolean> BOOLEAN = new BaseJsonMarshaller<Boolean>() { @Override public void marshall(Boolean val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) { jsonGenerator.writeValue(val); } }; public static final JsonMarshaller<Date> DATE = new BaseJsonMarshaller<Date>() { @Override public void marshall(Date val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) { jsonGenerator.writeValue(val); } }; public static final JsonMarshaller<ByteBuffer> BYTE_BUFFER = new BaseJsonMarshaller<ByteBuffer>() { @Override public void marshall(ByteBuffer val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) { jsonGenerator.writeValue(val); } }; public static final JsonMarshaller<StructuredPojo> STRUCTURED = new BaseJsonMarshaller<StructuredPojo>() { @Override public void marshall(StructuredPojo val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) { jsonGenerator.writeStartObject(); val.marshall(context.protocolHandler()); jsonGenerator.writeEndObject(); } }; public static final JsonMarshaller<List> LIST = new BaseJsonMarshaller<List>() { @Override public void marshall(List list, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) { jsonGenerator.writeStartArray(); for (Object listValue : list) { context.marshall(MarshallLocation.PAYLOAD, listValue); } jsonGenerator.writeEndArray(); } @Override protected boolean shouldEmit(List list) { return !(list.isEmpty() && list instanceof SdkInternalList && ((SdkInternalList) list).isAutoConstruct()); } }; /** * Marshalls a Map as a JSON object where each key becomes a field. */ public static final JsonMarshaller<Map> MAP = new BaseJsonMarshaller<Map>() { @Override public void marshall(Map map, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) { jsonGenerator.writeStartObject(); for (Map.Entry<String, ?> entry : ((Map<String, ?>) map).entrySet()) { if (entry.getValue() != null) { final Object value = entry.getValue(); jsonGenerator.writeFieldName(entry.getKey()); context.marshall(MarshallLocation.PAYLOAD, value); } } jsonGenerator.writeEndObject(); } @Override protected boolean shouldEmit(Map map) { return !(map.isEmpty() && map instanceof SdkInternalMap && ((SdkInternalMap) map).isAutoConstruct()); } }; /** * Base marshaller that emits the field name if present. The field name may be null in cases like * marshalling something inside a list or if the object is the explicit payload member. * * @param <T> Type to marshall. */ private abstract static class BaseJsonMarshaller<T> implements JsonMarshaller<T> { @Override public final void marshall(T val, JsonMarshallerContext context, String paramName) { if (!shouldEmit(val)) { return; } if (paramName != null) { context.jsonGenerator().writeFieldName(paramName); } marshall(val, context.jsonGenerator(), context); } public abstract void marshall(T val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context); /** * Hook to prevent emitting the field name. Used for maps and lists since we treat empty auto constructed * containers as null. */ protected boolean shouldEmit(T val) { return true; } } }