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

software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.EnhancedAttributeValue 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.enhanced.dynamodb.internal.converter.attribute;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import software.amazon.awssdk.annotations.Immutable;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.annotations.ThreadSafe;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.core.util.SdkAutoConstructMap;
import software.amazon.awssdk.enhanced.dynamodb.AttributeConverter;
import software.amazon.awssdk.enhanced.dynamodb.AttributeValueType;
import software.amazon.awssdk.enhanced.dynamodb.internal.converter.TypeConvertingVisitor;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.utils.ToString;
import software.amazon.awssdk.utils.Validate;

/**
 * A simpler, and more user-friendly version of the generated {@link AttributeValue}.
 *
 * 

* This is a union type of the types exposed by DynamoDB, exactly as they're exposed by DynamoDB. * *

* An instance of {@link EnhancedAttributeValue} represents exactly one DynamoDB type, like String (s), Number (n) or Bytes (b). * This type can be determined with the {@link #type()} method or the {@code is*} methods like {@link #isString()} or * {@link #isNumber()}. Once the type is known, the value can be extracted with {@code as*} methods like {@link #asString()} * or {@link #asNumber()}. * *

* When converting an {@link EnhancedAttributeValue} into a concrete Java type, it can be tedious to use the {@link #type()} or * {@code is*} methods. For this reason, a {@link #convert(TypeConvertingVisitor)} method is provided that exposes a polymorphic * way of converting a value into another type. * *

* An instance of {@link EnhancedAttributeValue} is created with the {@code from*} methods, like {@link #fromString(String)} or * {@link #fromNumber(String)}. */ @SdkInternalApi @ThreadSafe @Immutable public final class EnhancedAttributeValue { private final AttributeValueType type; private final boolean isNull; private final Map mapValue; private final String stringValue; private final String numberValue; private final SdkBytes bytesValue; private final Boolean booleanValue; private final List setOfStringsValue; private final List setOfNumbersValue; private final List setOfBytesValue; private final List listOfAttributeValuesValue; private EnhancedAttributeValue(InternalBuilder builder) { this.type = builder.type; this.isNull = builder.isNull; this.stringValue = builder.stringValue; this.numberValue = builder.numberValue; this.bytesValue = builder.bytesValue; this.booleanValue = builder.booleanValue; this.mapValue = builder.mapValue == null ? null : Collections.unmodifiableMap(builder.mapValue); this.setOfStringsValue = builder.setOfStringsValue == null ? null : Collections.unmodifiableList(builder.setOfStringsValue); this.setOfNumbersValue = builder.setOfNumbersValue == null ? null : Collections.unmodifiableList(builder.setOfNumbersValue); this.setOfBytesValue = builder.setOfBytesValue == null ? null : Collections.unmodifiableList(builder.setOfBytesValue); this.listOfAttributeValuesValue = builder.listOfAttributeValuesValue == null ? null : Collections.unmodifiableList(builder.listOfAttributeValuesValue); } /** * Create an {@link EnhancedAttributeValue} for the null DynamoDB type. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().nul(true).build())} * *

* This call should never fail with an {@link Exception}. */ public static EnhancedAttributeValue nullValue() { return new InternalBuilder().isNull().build(); } /** * Create an {@link EnhancedAttributeValue} for a map (m) DynamoDB type. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().m(...).build())} * *

* This call will fail with a {@link RuntimeException} if the provided map is null or has null keys. */ public static EnhancedAttributeValue fromMap(Map mapValue) { Validate.paramNotNull(mapValue, "mapValue"); Validate.noNullElements(mapValue.keySet(), "Map must not have null keys."); return new InternalBuilder().mapValue(mapValue).build(); } /** * Create an {@link EnhancedAttributeValue} for a string (s) DynamoDB type. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().s(...).build())} * *

* This call will fail with a {@link RuntimeException} if the provided value is null. Use {@link #nullValue()} for * null values. */ public static EnhancedAttributeValue fromString(String stringValue) { Validate.paramNotNull(stringValue, "stringValue"); return new InternalBuilder().stringValue(stringValue).build(); } /** * Create an {@link EnhancedAttributeValue} for a number (n) DynamoDB type. * *

* This is a String, because it matches the underlying DynamoDB representation. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().n(...).build())} * *

* This call will fail with a {@link RuntimeException} if the provided value is null. Use {@link #nullValue()} for * null values. */ public static EnhancedAttributeValue fromNumber(String numberValue) { Validate.paramNotNull(numberValue, "numberValue"); return new InternalBuilder().numberValue(numberValue).build(); } /** * Create an {@link EnhancedAttributeValue} for a bytes (b) DynamoDB type. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().b(...).build())} * *

* This call will fail with a {@link RuntimeException} if the provided value is null. Use {@link #nullValue()} for * null values. */ public static EnhancedAttributeValue fromBytes(SdkBytes bytesValue) { Validate.paramNotNull(bytesValue, "bytesValue"); return new InternalBuilder().bytesValue(bytesValue).build(); } /** * Create an {@link EnhancedAttributeValue} for a boolean (bool) DynamoDB type. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().bool(...).build())} * *

* This call will fail with a {@link RuntimeException} if the provided value is null. Use {@link #nullValue()} for * null values. */ public static EnhancedAttributeValue fromBoolean(Boolean booleanValue) { Validate.paramNotNull(booleanValue, "booleanValue"); return new InternalBuilder().booleanValue(booleanValue).build(); } /** * Create an {@link EnhancedAttributeValue} for a set-of-strings (ss) DynamoDB type. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().ss(...).build())} * *

* This call will fail with a {@link RuntimeException} if the provided value is null or contains a null value. Use * {@link #fromListOfAttributeValues(List)} for null values. This will not validate that there are no * duplicate values. */ public static EnhancedAttributeValue fromSetOfStrings(String... setOfStringsValue) { Validate.paramNotNull(setOfStringsValue, "setOfStringsValue"); return fromSetOfStrings(Arrays.asList(setOfStringsValue)); } /** * Create an {@link EnhancedAttributeValue} for a set-of-strings (ss) DynamoDB type. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().ss(...).build())} * *

* This call will fail with a {@link RuntimeException} if the provided value is null or contains a null value. Use * {@link #fromListOfAttributeValues(List)} for null values. This will not validate that there are no * duplicate values. */ public static EnhancedAttributeValue fromSetOfStrings(Collection setOfStringsValue) { Validate.paramNotNull(setOfStringsValue, "setOfStringsValue"); return fromSetOfStrings(new ArrayList<>(setOfStringsValue)); } /** * Create an {@link EnhancedAttributeValue} for a set-of-strings (ss) DynamoDB type. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().ss(...).build())} * *

* This call will fail with a {@link RuntimeException} if the provided value is null or contains a null value. Use * {@link #fromListOfAttributeValues(List)} for null values. This will not validate that there are no * duplicate values. */ public static EnhancedAttributeValue fromSetOfStrings(List setOfStringsValue) { Validate.paramNotNull(setOfStringsValue, "setOfStringsValue"); Validate.noNullElements(setOfStringsValue, "Set must not have null values."); return new InternalBuilder().setOfStringsValue(setOfStringsValue).build(); } /** * Create an {@link EnhancedAttributeValue} for a set-of-numbers (ns) DynamoDB type. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().ns(...).build())} * *

* This call will fail with a {@link RuntimeException} if the provided value is null or contains a null value. Use * {@link #fromListOfAttributeValues(List)} for null values. This will not validate that there are no * duplicate values. */ public static EnhancedAttributeValue fromSetOfNumbers(String... setOfNumbersValue) { Validate.paramNotNull(setOfNumbersValue, "setOfNumbersValue"); return fromSetOfNumbers(Arrays.asList(setOfNumbersValue)); } /** * Create an {@link EnhancedAttributeValue} for a set-of-numbers (ns) DynamoDB type. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().ns(...).build())} * *

* This call will fail with a {@link RuntimeException} if the provided value is null or contains a null value. Use * {@link #fromListOfAttributeValues(List)} for null values. This will not validate that there are no * duplicate values. */ public static EnhancedAttributeValue fromSetOfNumbers(Collection setOfNumbersValue) { Validate.paramNotNull(setOfNumbersValue, "setOfNumbersValue"); return fromSetOfNumbers(new ArrayList<>(setOfNumbersValue)); } /** * Create an {@link EnhancedAttributeValue} for a set-of-numbers (ns) DynamoDB type. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().ns(...).build())} * *

* This call will fail with a {@link RuntimeException} if the provided value is null or contains a null value. Use * {@link #fromListOfAttributeValues(List)} for null values. This will not validate that there are no * duplicate values. */ public static EnhancedAttributeValue fromSetOfNumbers(List setOfNumbersValue) { Validate.paramNotNull(setOfNumbersValue, "setOfNumbersValue"); Validate.noNullElements(setOfNumbersValue, "Set must not have null values."); return new InternalBuilder().setOfNumbersValue(setOfNumbersValue).build(); } /** * Create an {@link EnhancedAttributeValue} for a set-of-bytes (bs) DynamoDB type. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().bs(...).build())} * *

* This call will fail with a {@link RuntimeException} if the provided value is null or contains a null value. Use * {@link #fromListOfAttributeValues(List)} for null values. This will not validate that there are no * duplicate values. */ public static EnhancedAttributeValue fromSetOfBytes(Collection setOfBytesValue) { Validate.paramNotNull(setOfBytesValue, "setOfBytesValue"); return fromSetOfBytes(new ArrayList<>(setOfBytesValue)); } /** * Create an {@link EnhancedAttributeValue} for a set-of-bytes (bs) DynamoDB type. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().bs(...).build())} * *

* This call will fail with a {@link RuntimeException} if the provided value is null or contains a null value. Use * {@link #fromListOfAttributeValues(List)} for null values. This will not validate that there are no * duplicate values. */ public static EnhancedAttributeValue fromSetOfBytes(SdkBytes... setOfBytesValue) { Validate.paramNotNull(setOfBytesValue, "setOfBytesValue"); return fromSetOfBytes(Arrays.asList(setOfBytesValue)); } /** * Create an {@link EnhancedAttributeValue} for a set-of-bytes (bs) DynamoDB type. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().bs(...).build())} * *

* This call will fail with a {@link RuntimeException} if the provided value is null or contains a null value. Use * {@link #fromListOfAttributeValues(List)} for null values. This will not validate that there are no * duplicate values. */ public static EnhancedAttributeValue fromSetOfBytes(List setOfBytesValue) { Validate.paramNotNull(setOfBytesValue, "setOfBytesValue"); Validate.noNullElements(setOfBytesValue, "Set must not have null values."); return new InternalBuilder().setOfBytesValue(setOfBytesValue).build(); } /** * Create an {@link EnhancedAttributeValue} for a list-of-attributes (l) DynamoDB type. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().l(...).build())} * *

* This call will fail with a {@link RuntimeException} if the provided value is null or contains a null value. Use * {@link #nullValue()} for null values. */ public static EnhancedAttributeValue fromListOfAttributeValues(AttributeValue... listOfAttributeValuesValue) { Validate.paramNotNull(listOfAttributeValuesValue, "listOfAttributeValuesValue"); return fromListOfAttributeValues(Arrays.asList(listOfAttributeValuesValue)); } /** * Create an {@link EnhancedAttributeValue} for a list-of-attributes (l) DynamoDB type. * *

* Equivalent to: {@code EnhancedAttributeValue.fromGeneratedAttributeValue(AttributeValue.builder().l(...).build())} * *

* This call will fail with a {@link RuntimeException} if the provided value is null or contains a null value. Use * {@link #nullValue()} for null values. */ public static EnhancedAttributeValue fromListOfAttributeValues(List listOfAttributeValuesValue) { Validate.paramNotNull(listOfAttributeValuesValue, "listOfAttributeValuesValue"); Validate.noNullElements(listOfAttributeValuesValue, "List must not have null values."); return new InternalBuilder().listOfAttributeValuesValue(listOfAttributeValuesValue).build(); } /** * Create an {@link EnhancedAttributeValue} from a generated {@link AttributeValue}. * *

* This call will fail with a {@link RuntimeException} if the provided value is null ({@link AttributeValue#nul()} is okay). */ public static EnhancedAttributeValue fromAttributeValue(AttributeValue attributeValue) { Validate.notNull(attributeValue, "Generated attribute value must not contain null values. " + "Use AttributeValue#nul() instead."); if (attributeValue.s() != null) { return EnhancedAttributeValue.fromString(attributeValue.s()); } if (attributeValue.n() != null) { return EnhancedAttributeValue.fromNumber(attributeValue.n()); } if (attributeValue.bool() != null) { return EnhancedAttributeValue.fromBoolean(attributeValue.bool()); } if (Boolean.TRUE.equals(attributeValue.nul())) { return EnhancedAttributeValue.nullValue(); } if (attributeValue.b() != null) { return EnhancedAttributeValue.fromBytes(attributeValue.b()); } if (attributeValue.hasM()) { return EnhancedAttributeValue.fromMap(attributeValue.m()); } if (attributeValue.hasL()) { return EnhancedAttributeValue.fromListOfAttributeValues(attributeValue.l()); } if (attributeValue.hasBs()) { return EnhancedAttributeValue.fromSetOfBytes(attributeValue.bs()); } if (attributeValue.hasSs()) { return EnhancedAttributeValue.fromSetOfStrings(attributeValue.ss()); } if (attributeValue.hasNs()) { return EnhancedAttributeValue.fromSetOfNumbers(attributeValue.ns()); } throw new IllegalStateException("Unable to convert attribute value: " + attributeValue); } /** * Retrieve the underlying DynamoDB type of this value, such as String (s) or Number (n). * *

* This call should never fail with an {@link Exception}. */ public AttributeValueType type() { return type; } /** * Apply the provided visitor to this item attribute value, converting it into a specific type. This is useful in * {@link AttributeConverter} implementations, without having to write a switch statement on the {@link #type()}. * *

* Reasons this call may fail with a {@link RuntimeException}: *

    *
  1. If the provided visitor is null.
  2. *
  3. If the value cannot be converted by this visitor.
  4. *
*/ public T convert(TypeConvertingVisitor convertingVisitor) { Validate.paramNotNull(convertingVisitor, "convertingVisitor"); return convertingVisitor.convert(this); } /** * Returns true if the underlying DynamoDB type of this value is a Map (m). * *

* This call should never fail with an {@link Exception}. */ public boolean isMap() { return mapValue != null; } /** * Returns true if the underlying DynamoDB type of this value is a String (s). * *

* This call should never fail with an {@link Exception}. */ public boolean isString() { return stringValue != null; } /** * Returns true if the underlying DynamoDB type of this value is a Number (n). * *

* This call should never fail with an {@link Exception}. */ public boolean isNumber() { return numberValue != null; } /** * Returns true if the underlying DynamoDB type of this value is Bytes (b). * *

* This call should never fail with an {@link Exception}. */ public boolean isBytes() { return bytesValue != null; } /** * Returns true if the underlying DynamoDB type of this value is a Boolean (bool). * *

* This call should never fail with an {@link Exception}. */ public boolean isBoolean() { return booleanValue != null; } /** * Returns true if the underlying DynamoDB type of this value is a Set of Strings (ss). * *

* This call should never fail with an {@link Exception}. */ public boolean isSetOfStrings() { return setOfStringsValue != null; } /** * Returns true if the underlying DynamoDB type of this value is a Set of Numbers (ns). * *

* This call should never fail with an {@link Exception}. */ public boolean isSetOfNumbers() { return setOfNumbersValue != null; } /** * Returns true if the underlying DynamoDB type of this value is a Set of Bytes (bs). * *

* This call should never fail with an {@link Exception}. */ public boolean isSetOfBytes() { return setOfBytesValue != null; } /** * Returns true if the underlying DynamoDB type of this value is a List of AttributeValues (l). * *

* This call should never fail with an {@link Exception}. */ public boolean isListOfAttributeValues() { return listOfAttributeValuesValue != null; } /** * Returns true if the underlying DynamoDB type of this value is Null (null). * *

* This call should never fail with an {@link Exception}. */ public boolean isNull() { return isNull; } /** * Retrieve this value as a map. * *

* This call will fail with a {@link RuntimeException} if {@link #isMap()} is false. */ public Map asMap() { Validate.isTrue(isMap(), "Value is not a map."); return mapValue; } /** * Retrieve this value as a string. * *

* This call will fail with a {@link RuntimeException} if {@link #isString()} is false. */ public String asString() { Validate.isTrue(isString(), "Value is not a string."); return stringValue; } /** * Retrieve this value as a number. * * Note: This returns a {@code String} (instead of a {@code Number}), because that's the generated type from * DynamoDB: {@link AttributeValue#n()}. * *

* This call will fail with a {@link RuntimeException} if {@link #isNumber()} is false. */ public String asNumber() { Validate.isTrue(isNumber(), "Value is not a number."); return numberValue; } /** * Retrieve this value as bytes. * *

* This call will fail with a {@link RuntimeException} if {@link #isBytes()} is false. */ public SdkBytes asBytes() { Validate.isTrue(isBytes(), "Value is not bytes."); return bytesValue; } /** * Retrieve this value as a boolean. * *

* This call will fail with a {@link RuntimeException} if {@link #isBoolean()} is false. */ public Boolean asBoolean() { Validate.isTrue(isBoolean(), "Value is not a boolean."); return booleanValue; } /** * Retrieve this value as a set of strings. * *

* Note: This returns a {@code List} (instead of a {@code Set}), because that's the generated type from * DynamoDB: {@link AttributeValue#ss()}. * *

* This call will fail with a {@link RuntimeException} if {@link #isSetOfStrings()} is false. */ public List asSetOfStrings() { Validate.isTrue(isSetOfStrings(), "Value is not a list of strings."); return setOfStringsValue; } /** * Retrieve this value as a set of numbers. * *

* Note: This returns a {@code List} (instead of a {@code Set}), because that's the generated type from * DynamoDB: {@link AttributeValue#ns()}. * *

* This call will fail with a {@link RuntimeException} if {@link #isSetOfNumbers()} is false. */ public List asSetOfNumbers() { Validate.isTrue(isSetOfNumbers(), "Value is not a list of numbers."); return setOfNumbersValue; } /** * Retrieve this value as a set of bytes. * *

* Note: This returns a {@code List} (instead of a {@code Set}), because that's the generated type from * DynamoDB: {@link AttributeValue#bs()}. * *

* This call will fail with a {@link RuntimeException} if {@link #isSetOfBytes()} is false. */ public List asSetOfBytes() { Validate.isTrue(isSetOfBytes(), "Value is not a list of bytes."); return setOfBytesValue; } /** * Retrieve this value as a list of attribute values. * *

* This call will fail with a {@link RuntimeException} if {@link #isListOfAttributeValues()} is false. */ public List asListOfAttributeValues() { Validate.isTrue(isListOfAttributeValues(), "Value is not a list of attribute values."); return listOfAttributeValuesValue; } /** * Convert this {@link EnhancedAttributeValue} into a generated {@code Map}. * *

* This call will fail with a {@link RuntimeException} if {@link #isMap()} is false. */ public Map toAttributeValueMap() { Validate.validState(isMap(), "Cannot convert an attribute value of type %s to a generated item. Must be %s.", type(), AttributeValueType.M); AttributeValue generatedAttributeValue = toAttributeValue(); Validate.validState(generatedAttributeValue.m() != null && !(generatedAttributeValue.m() instanceof SdkAutoConstructMap), "Map EnhancedAttributeValue was not converted into a Map AttributeValue."); return generatedAttributeValue.m(); } /** * Convert this {@link EnhancedAttributeValue} into a generated {@link AttributeValue}. * *

* This call should never fail with an {@link Exception}. */ public AttributeValue toAttributeValue() { return convert(ToGeneratedAttributeValueVisitor.INSTANCE); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } EnhancedAttributeValue that = (EnhancedAttributeValue) o; if (isNull != that.isNull) { return false; } if (type != that.type) { return false; } if (mapValue != null ? !mapValue.equals(that.mapValue) : that.mapValue != null) { return false; } if (stringValue != null ? !stringValue.equals(that.stringValue) : that.stringValue != null) { return false; } if (numberValue != null ? !numberValue.equals(that.numberValue) : that.numberValue != null) { return false; } if (bytesValue != null ? !bytesValue.equals(that.bytesValue) : that.bytesValue != null) { return false; } if (booleanValue != null ? !booleanValue.equals(that.booleanValue) : that.booleanValue != null) { return false; } if (setOfStringsValue != null ? !setOfStringsValue.equals(that.setOfStringsValue) : that.setOfStringsValue != null) { return false; } if (setOfNumbersValue != null ? !setOfNumbersValue.equals(that.setOfNumbersValue) : that.setOfNumbersValue != null) { return false; } if (setOfBytesValue != null ? !setOfBytesValue.equals(that.setOfBytesValue) : that.setOfBytesValue != null) { return false; } return listOfAttributeValuesValue != null ? listOfAttributeValuesValue.equals(that.listOfAttributeValuesValue) : that.listOfAttributeValuesValue == null; } @Override public int hashCode() { int result = type.hashCode(); result = 31 * result + (isNull ? 1 : 0); result = 31 * result + (mapValue != null ? mapValue.hashCode() : 0); result = 31 * result + (stringValue != null ? stringValue.hashCode() : 0); result = 31 * result + (numberValue != null ? numberValue.hashCode() : 0); result = 31 * result + (bytesValue != null ? bytesValue.hashCode() : 0); result = 31 * result + (booleanValue != null ? booleanValue.hashCode() : 0); result = 31 * result + (setOfStringsValue != null ? setOfStringsValue.hashCode() : 0); result = 31 * result + (setOfNumbersValue != null ? setOfNumbersValue.hashCode() : 0); result = 31 * result + (setOfBytesValue != null ? setOfBytesValue.hashCode() : 0); result = 31 * result + (listOfAttributeValuesValue != null ? listOfAttributeValuesValue.hashCode() : 0); return result; } @Override public String toString() { Object value = convert(ToStringVisitor.INSTANCE); return ToString.builder("EnhancedAttributeValue") .add("type", type) .add("value", value) .build(); } private static class ToGeneratedAttributeValueVisitor extends TypeConvertingVisitor { private static final ToGeneratedAttributeValueVisitor INSTANCE = new ToGeneratedAttributeValueVisitor(); private ToGeneratedAttributeValueVisitor() { super(AttributeValue.class); } @Override public AttributeValue convertNull() { return AttributeValue.builder().nul(true).build(); } @Override public AttributeValue convertMap(Map value) { return AttributeValue.builder().m(value).build(); } @Override public AttributeValue convertString(String value) { return AttributeValue.builder().s(value).build(); } @Override public AttributeValue convertNumber(String value) { return AttributeValue.builder().n(value).build(); } @Override public AttributeValue convertBytes(SdkBytes value) { return AttributeValue.builder().b(value).build(); } @Override public AttributeValue convertBoolean(Boolean value) { return AttributeValue.builder().bool(value).build(); } @Override public AttributeValue convertSetOfStrings(List value) { return AttributeValue.builder().ss(value).build(); } @Override public AttributeValue convertSetOfNumbers(List value) { return AttributeValue.builder().ns(value).build(); } @Override public AttributeValue convertSetOfBytes(List value) { return AttributeValue.builder().bs(value).build(); } @Override public AttributeValue convertListOfAttributeValues(List value) { return AttributeValue.builder().l(value).build(); } } private static class ToStringVisitor extends TypeConvertingVisitor { private static final ToStringVisitor INSTANCE = new ToStringVisitor(); private ToStringVisitor() { super(Object.class); } @Override public Object convertNull() { return "null"; } @Override public Object defaultConvert(AttributeValueType type, Object value) { return value; } } private static class InternalBuilder { private AttributeValueType type; private boolean isNull = false; private Map mapValue; private String stringValue; private String numberValue; private SdkBytes bytesValue; private Boolean booleanValue; private List setOfStringsValue; private List setOfNumbersValue; private List setOfBytesValue; private List listOfAttributeValuesValue; public InternalBuilder isNull() { this.type = AttributeValueType.NULL; this.isNull = true; return this; } private InternalBuilder mapValue(Map mapValue) { this.type = AttributeValueType.M; this.mapValue = mapValue; return this; } private InternalBuilder stringValue(String stringValue) { this.type = AttributeValueType.S; this.stringValue = stringValue; return this; } private InternalBuilder numberValue(String numberValue) { this.type = AttributeValueType.N; this.numberValue = numberValue; return this; } private InternalBuilder bytesValue(SdkBytes bytesValue) { this.type = AttributeValueType.B; this.bytesValue = bytesValue; return this; } private InternalBuilder booleanValue(Boolean booleanValue) { this.type = AttributeValueType.BOOL; this.booleanValue = booleanValue; return this; } private InternalBuilder setOfStringsValue(List setOfStringsValue) { this.type = AttributeValueType.SS; this.setOfStringsValue = setOfStringsValue; return this; } private InternalBuilder setOfNumbersValue(List setOfNumbersValue) { this.type = AttributeValueType.NS; this.setOfNumbersValue = setOfNumbersValue; return this; } private InternalBuilder setOfBytesValue(List setOfBytesValue) { this.type = AttributeValueType.BS; this.setOfBytesValue = setOfBytesValue; return this; } private InternalBuilder listOfAttributeValuesValue(List listOfAttributeValuesValue) { this.type = AttributeValueType.L; this.listOfAttributeValuesValue = listOfAttributeValuesValue; return this; } private EnhancedAttributeValue build() { return new EnhancedAttributeValue(this); } } }