1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 package software.amazon.awssdk.enhanced.dynamodb.document;
17 
18 import static software.amazon.awssdk.enhanced.dynamodb.AttributeConverterProvider.defaultProvider;
19 
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Set;
23 import java.util.UUID;
24 import software.amazon.awssdk.annotations.NotThreadSafe;
25 import software.amazon.awssdk.annotations.SdkPublicApi;
26 import software.amazon.awssdk.core.SdkBytes;
27 import software.amazon.awssdk.core.SdkNumber;
28 import software.amazon.awssdk.enhanced.dynamodb.AttributeConverter;
29 import software.amazon.awssdk.enhanced.dynamodb.AttributeConverterProvider;
30 import software.amazon.awssdk.enhanced.dynamodb.EnhancedType;
31 import software.amazon.awssdk.enhanced.dynamodb.internal.document.DefaultEnhancedDocument;
32 import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
33 import software.amazon.awssdk.utils.Validate;
34 
35 
36 /**
37  * Interface representing the Document API for DynamoDB. The Document API operations are designed to work with open content,
38  * such as data with no fixed schema, data that cannot be modeled using rigid types, or data that has a schema.
39  * This interface provides all the methods required to access a Document, as well as constructor methods for creating a
40  * Document that can be used to read and write to DynamoDB using the EnhancedDynamoDB client.
41  * Additionally, this interface provides flexibility when working with data, as it allows you to work with data that is not
42  * necessarily tied to a specific data model.
43  * The EnhancedDocument interface provides two ways to use AttributeConverterProviders:
44  * <p>Enhanced Document with default attribute Converter to convert the attribute of DDB item to basic default primitive types in
45  * Java
46  * {@snippet :
47  * EnhancedDocument enhancedDocument = EnhancedDocument.builder().attributeConverterProviders(AttributeConverterProvider
48  * .defaultProvider()).build();
49  *}
50  * <p>Enhanced Document with Custom attribute Converter to convert the attribute of DDB Item to Custom Type.
51  * {@snippet :
52  * // CustomAttributeConverterProvider.create() is an example for some Custom converter provider
53  * EnhancedDocument enhancedDocumentWithCustomConverter = EnhancedDocument.builder().attributeConverterProviders
54  * (CustomAttributeConverterProvider.create(), AttributeConverterProvide.defaultProvider()
55  * .put("customObject", customObject, EnhancedType.of(CustomClass.class))
56  * .build();
57  *}
58  * <p>Enhanced Document can be created with Json as input using Static factory method.In this case it used
59  * defaultConverterProviders.
60  * {@snippet :
61  * EnhancedDocument enhancedDocumentWithCustomConverter = EnhancedDocument.fromJson("{\"k\":\"v\"}");
62  *}
63  * The attribute converter are always required to be provided, thus for default conversion
64  * {@link AttributeConverterProvider#defaultProvider()} must be supplied.
65  */
66 @SdkPublicApi
67 public interface EnhancedDocument {
68 
69     /**
70      * Creates a new <code>EnhancedDocument</code> instance from a JSON string.
71      * The {@link AttributeConverterProvider#defaultProvider()} is used as the default ConverterProvider.
72      * To use a custom ConverterProvider, use the builder methods: {@link Builder#json(String)} to supply the JSON string,
73      * then use {@link Builder#attributeConverterProviders(AttributeConverterProvider...)} to provide the custom
74      * ConverterProvider.
75      * {@snippet :
76      * EnhancedDocument documentFromJson = EnhancedDocument.fromJson("{\"key\": \"Value\"}");
77      *}
78      * @param json The JSON string representation of a DynamoDB Item.
79      * @return A new instance of EnhancedDocument.
80      * @throws IllegalArgumentException if the json parameter is null
81      */
fromJson(String json)82     static EnhancedDocument fromJson(String json) {
83         Validate.paramNotNull(json, "json");
84         return DefaultEnhancedDocument.builder()
85                                       .json(json)
86                                       .attributeConverterProviders(defaultProvider())
87                                       .build();
88     }
89 
90     /**
91      * Creates a new <code>EnhancedDocument</code> instance from a AttributeValue Map.
92      * The {@link AttributeConverterProvider#defaultProvider()} is used as the default ConverterProvider.
93      * Example usage:
94      * {@snippet :
95      * EnhancedDocument documentFromJson = EnhancedDocument.fromAttributeValueMap(stringKeyAttributeValueMao)});
96      *}
97      * @param attributeValueMap - Map with Attributes as String keys and AttributeValue as Value.
98      * @return A new instance of EnhancedDocument.
99      * @throws IllegalArgumentException if the json parameter is null
100      */
fromAttributeValueMap(Map<String, AttributeValue> attributeValueMap)101     static EnhancedDocument fromAttributeValueMap(Map<String, AttributeValue> attributeValueMap) {
102         Validate.paramNotNull(attributeValueMap, "attributeValueMap");
103         return DefaultEnhancedDocument.builder()
104                                       .attributeValueMap(attributeValueMap)
105                                       .attributeConverterProviders(defaultProvider())
106                                       .build();
107     }
108 
109     /**
110      * Creates a default builder for {@link EnhancedDocument}.
111      */
builder()112     static Builder builder() {
113         return DefaultEnhancedDocument.builder();
114     }
115 
116     /**
117      * Converts an existing EnhancedDocument into a builder object that can be used to modify its values and then create a new
118      * EnhancedDocument.
119      *
120      * @return A {@link EnhancedDocument.Builder} initialized with the values of this EnhancedDocument.
121      */
toBuilder()122     Builder toBuilder();
123 
124     /**
125      * Checks if the document is a {@code null} value.
126      *
127      * @param attributeName Name of the attribute that needs to be checked.
128      * @return true if the specified attribute exists with a null value; false otherwise.
129      */
isNull(String attributeName)130     boolean isNull(String attributeName);
131 
132     /**
133      * Checks if the attribute exists in the document.
134      *
135      * @param attributeName Name of the attribute that needs to be checked.
136      * @return true if the specified attribute exists with a null/non-null value; false otherwise.
137      */
isPresent(String attributeName)138     boolean isPresent(String attributeName);
139 
140     /**
141      * Returns the value of the specified attribute in the current document as a specified {@link EnhancedType}; or null if the
142      * attribute either doesn't exist or the attribute value is null.
143      * <p>
144      * <b>Retrieving String Type for a document</b>
145      * {@snippet :
146      * String resultCustom = document.get("key", EnhancedType.of(String.class));
147      * }
148      * <b>Retrieving Custom Type for which Convertor Provider was defined while creating the document</b>
149      * {@snippet :
150      * Custom resultCustom = document.get("key", EnhancedType.of(Custom.class));
151      * }
152      * <b>Retrieving list of strings in a document</b>
153      * {@snippet :
154      * List<String> resultList = document.get("key", EnhancedType.listOf(String.class));
155      * }
156      * <b>Retrieving a Map with List of strings in its values</b>
157      * {@snippet :
158      * Map<String, List<String>>> resultNested = document.get("key", new EnhancedType<Map<String, List<String>>>(){});
159      * }
160      * </p>
161      * @param attributeName Name of the attribute.
162      * @param type          EnhancedType of the value
163      * @param <T>           The type of the attribute value.
164      * @return Attribute value of type T
165      * }
166      */
get(String attributeName, EnhancedType<T> type)167     <T> T get(String attributeName, EnhancedType<T> type);
168 
169     /**
170      * Returns the value of the specified attribute in the current document as a specified class type; or null if the
171      * attribute either doesn't exist or the attribute value is null.
172      * <p>
173      * <b>Retrieving String Type for a document</b>
174      * {@snippet :
175      * String resultCustom = document.get("key", String.class);
176      * }
177      * <b>Retrieving Custom Type for which Convertor Provider was defined while creating the document</b>
178      * {@snippet :
179      * Custom resultCustom = document.get("key", Custom.class);
180      * }
181      * <p>
182      * Note :
183      * This API should not be used to retrieve values of List and Map types.
184      * Instead, getList and getMap APIs should be used to retrieve attributes of type List and Map, respectively.
185      * </p>
186      * @param attributeName Name of the attribute.
187      * @param clazz         Class type of value.
188      * @param <T>           The type of the attribute value.
189      * @return Attribute value of type T
190      * }
191      */
get(String attributeName, Class<T> clazz)192     <T> T get(String attributeName, Class<T> clazz);
193 
194     /**
195      * Gets the String value of specified attribute in the document.
196      *
197      * @param attributeName Name of the attribute.
198      * @return value of the specified attribute in the current document as a string; or null if the attribute either doesn't exist
199      * or the attribute value is null
200      */
getString(String attributeName)201     String getString(String attributeName);
202 
203     /**
204      * Gets the {@link SdkNumber} value of specified attribute in the document.
205      *
206      * @param attributeName Name of the attribute.
207      * @return value of the specified attribute in the current document as a number; or null if the attribute either doesn't exist
208      * or the attribute value is null
209      */
getNumber(String attributeName)210     SdkNumber getNumber(String attributeName);
211 
212     /**
213      * Gets the {@link SdkBytes} value of specified attribute in the document.
214      *
215      * @param attributeName Name of the attribute.
216      * @return the value of the specified attribute in the current document as SdkBytes; or null if the attribute either
217      * doesn't exist or the attribute value is null.
218      */
getBytes(String attributeName)219     SdkBytes getBytes(String attributeName);
220 
221     /**
222      * Gets the Set of String values of the given attribute in the current document.
223      * @param attributeName the name of the attribute.
224      * @return the value of the specified attribute in the current document as a set of strings; or null if the attribute either
225      * does not exist or the attribute value is null.
226      */
getStringSet(String attributeName)227     Set<String> getStringSet(String attributeName);
228 
229     /**
230      * Gets the Set of String values of the given attribute in the current document.
231      * @param attributeName Name of the attribute.
232      * @return value of the specified attribute in the current document as a set of SdkNumber; or null if the attribute either
233      * doesn't exist or the attribute value is null.
234      */
getNumberSet(String attributeName)235     Set<SdkNumber> getNumberSet(String attributeName);
236 
237     /**
238      * Gets the Set of String values of the given attribute in the current document.
239      * @param attributeName Name of the attribute.
240      * @return value of the specified attribute in the current document as a set of SdkBytes;
241      * or null if the attribute doesn't exist.
242      */
getBytesSet(String attributeName)243     Set<SdkBytes> getBytesSet(String attributeName);
244 
245     /**
246      * Gets the List of values of type T for the given attribute in the current document.
247      *
248      * @param attributeName Name of the attribute.
249      * @param type          {@link EnhancedType} of Type T.
250      * @param <T>           Type T of List elements
251      * @return value of the specified attribute in the current document as a list of type T,
252      * or null if the attribute does not exist.
253      */
254 
getList(String attributeName, EnhancedType<T> type)255     <T> List<T> getList(String attributeName, EnhancedType<T> type);
256 
257     /**
258      *  Returns a map of a specific Key-type and Value-type based on the given attribute name, key type, and value type.
259      * Example usage: When getting an attribute as a map of  {@link UUID} keys and {@link Integer} values, use this API
260      * as shown below:
261      * {@snippet :
262         Map<String, Integer> result = document.getMap("key", EnhancedType.of(String.class), EnhancedType.of(Integer.class));
263      * }
264      * @param attributeName The name of the attribute that needs to be get as Map.
265      * @param keyType Enhanced Type of Key attribute, like String, UUID etc that can be represented as String Keys.
266      * @param valueType Enhanced Type of Values , which have converters defineds in
267      * {@link Builder#attributeConverterProviders(AttributeConverterProvider...)} for the document
268      * @return Map of type K and V with the given attribute name, key type, and value type.
269      * @param <K> The type of the Map keys.
270      * @param <V> The type of the Map values.
271      */
getMap(String attributeName, EnhancedType<K> keyType, EnhancedType<V> valueType)272     <K, V> Map<K, V> getMap(String attributeName, EnhancedType<K> keyType, EnhancedType<V> valueType);
273 
274     /**
275      * Gets the JSON document value of the specified attribute.
276      *
277      * @param attributeName Name of the attribute.
278      * @return value of the specified attribute in the current document as a JSON string; or null if the attribute either
279      * doesn't exist or the attribute value is null.
280      */
getJson(String attributeName)281     String getJson(String attributeName);
282 
283     /**
284      * Gets the {@link Boolean} value for the specified attribute.
285      *
286      * @param attributeName Name of the attribute.
287      * @return value of the specified attribute in the current document as a Boolean representation; or null if the attribute
288      * either doesn't exist or the attribute value is null.
289      * @throws RuntimeException
290      *             if the attribute value cannot be converted to a Boolean representation.
291      *             Note that the Boolean representation of 0 and 1 in Numbers and "0" and "1" in Strings is false and true,
292      *             respectively.
293      *
294      */
getBoolean(String attributeName)295     Boolean getBoolean(String attributeName);
296 
297 
298     /**
299      * Retrieves a list of {@link AttributeValue} objects for a specified attribute in a document.
300      * This API should be used when the elements of the list are a combination of different types such as Strings, Maps,
301      * and Numbers.
302      * If all elements in the list are of a known fixed type, use {@link EnhancedDocument#getList(String, EnhancedType)} instead.
303      *
304      * @param attributeName Name of the attribute.
305      * @return value of the specified attribute in the current document as a List of {@link AttributeValue}
306      */
getListOfUnknownType(String attributeName)307     List<AttributeValue> getListOfUnknownType(String attributeName);
308 
309     /**
310      * Retrieves a Map with String keys and corresponding AttributeValue objects as values for a specified attribute in a
311      * document. This API is particularly useful when the values of the map are of different types such as strings, maps, and
312      * numbers. However, if all the values in the map for a given attribute key are of a known fixed type, it is recommended to
313      * use the method EnhancedDocument#getMap(String, EnhancedType, EnhancedType) instead.
314      *
315      * @param attributeName Name of the attribute.
316      * @return value of the specified attribute in the current document as a {@link AttributeValue}
317      */
getMapOfUnknownType(String attributeName)318     Map<String, AttributeValue> getMapOfUnknownType(String attributeName);
319 
320     /**
321      *
322      * @return document as a JSON string. Note all binary data will become base-64 encoded in the resultant string.
323      */
toJson()324     String toJson();
325 
326     /**
327      * This method converts a document into a key-value map with the keys as String objects and the values as AttributeValue
328      * objects. It can be particularly useful for documents with attributes of unknown types, as it allows for further processing
329      * or manipulation of the document data in a AttributeValue format.
330      * @return Document as a String AttributeValue Key-Value Map
331      */
toMap()332     Map<String, AttributeValue> toMap();
333 
334     /**
335      *
336      * @return List of AttributeConverterProvider defined for the given Document.
337      */
attributeConverterProviders()338     List<AttributeConverterProvider> attributeConverterProviders();
339 
340     @NotThreadSafe
341     interface Builder {
342 
343         /**
344          * Appends an attribute of name attributeName with specified  {@link String} value to the document builder.
345          * Use this method when you need to add a string value to a document. If you need to add an attribute with a value of a
346          * different type, such as a number or a map, use the appropriate put method instead
347          *
348          * @param attributeName the name of the attribute to be added to the document.
349          * @param value         The string value that needs to be set.
350          * @return Builder instance to construct a {@link EnhancedDocument}
351          */
putString(String attributeName, String value)352         Builder putString(String attributeName, String value);
353 
354         /**
355          * Appends an attribute of name attributeName with specified  {@link Number} value to the document builder.
356          * Use this method when you need to add a number value to a document. If you need to add an attribute with a value of a
357          * different type, such as a string or a map, use the appropriate put method instead
358          * @param attributeName the name of the attribute to be added to the document.
359          * @param value         The number value that needs to be set.
360          * @return Builder instance to construct a {@link EnhancedDocument}
361          */
putNumber(String attributeName, Number value)362         Builder putNumber(String attributeName, Number value);
363 
364         /**
365          * Appends an attribute of name attributeName with specified  {@link SdkBytes} value to the document builder.
366          * Use this method when you need to add a binary value to a document. If you need to add an attribute with a value of a
367          * different type, such as a string or a map, use the appropriate put method instead
368          * @param attributeName the name of the attribute to be added to the document.
369          * @param value         The byte array value that needs to be set.
370          * @return Builder instance to construct a {@link EnhancedDocument}
371          */
putBytes(String attributeName, SdkBytes value)372         Builder putBytes(String attributeName, SdkBytes value);
373 
374         /**
375          * Use this method when you need to add a boolean value to a document. If you need to add an attribute with a value of a
376          * different type, such as a string or a map, use the appropriate put method instead.
377          * @param attributeName the name of the attribute to be added to the document.
378          * @param value         The boolean value that needs to be set.
379          * @return Builder instance to construct a {@link EnhancedDocument}
380          */
putBoolean(String attributeName, boolean value)381         Builder putBoolean(String attributeName, boolean value);
382 
383         /**
384          * Appends an attribute of name attributeName with a null value.
385          * Use this method is the attribute needs to explicitly set to null in Dynamo DB table.
386          *
387          * @param attributeName the name of the attribute to be added to the document.
388          * @return Builder instance to construct a {@link EnhancedDocument}
389          */
putNull(String attributeName)390         Builder putNull(String attributeName);
391 
392         /**
393          * Appends an attribute to the document builder with a Set of Strings as its value.
394          * This method is intended for use in DynamoDB where attribute values are stored as Sets of Strings.
395          * @param attributeName the name of the attribute to be added to the document.
396          * @param values        Set of String values that needs to be set.
397          * @return Builder instance to construct a {@link EnhancedDocument}
398          */
putStringSet(String attributeName, Set<String> values)399         Builder putStringSet(String attributeName, Set<String> values);
400 
401         /**
402          * Appends an attribute of name attributeName with specified Set of {@link Number} values to the document builder.
403          *
404          * @param attributeName the name of the attribute to be added to the document.
405          * @param values        Set of Number values that needs to be set.
406          * @return Builder instance to construct a {@link EnhancedDocument}
407          */
putNumberSet(String attributeName, Set<Number> values)408         Builder putNumberSet(String attributeName, Set<Number> values);
409 
410         /**
411          * Appends an attribute of name attributeName with specified Set of {@link SdkBytes} values to the document builder.
412          *
413          * @param attributeName the name of the attribute to be added to the document.
414          * @param values        Set of SdkBytes values that needs to be set.
415          * @return Builder instance to construct a {@link EnhancedDocument}
416          */
putBytesSet(String attributeName, Set<SdkBytes> values)417         Builder putBytesSet(String attributeName, Set<SdkBytes> values);
418 
419         /**
420          * Appends an attribute with the specified name and a list of {@link EnhancedType}  T type elements to the document
421          * builder.
422          * Use {@link EnhancedType#of(Class)} to specify the class type of the list elements.
423          * <p>For example, to insert a list of String type:
424          * {@snippet :
425          * EnhancedDocument.builder().putList(stringList, EnhancedType.of(String.class))
426          * }
427          * <p>Example for inserting a List of Custom type .
428          * {@snippet :
429          * EnhancedDocument.builder().putList(stringList, EnhancedType.of(CustomClass.class));
430          * }
431          * Note that the AttributeConverterProvider added to the DocumentBuilder should provide the converter for the class T that
432          * is to be inserted.
433          * @param attributeName the name of the attribute to be added to the document.
434          * @param value         The list of values that needs to be set.
435          * @return Builder instance to construct a {@link EnhancedDocument}
436          */
putList(String attributeName, List<T> value, EnhancedType<T> type)437         <T> Builder putList(String attributeName, List<T> value, EnhancedType<T> type);
438 
439         /**
440          * Appends an attribute named {@code attributeName} with a value of type {@link EnhancedType} T.
441          * Use this method to insert attribute values of custom types that have attribute converters defined in a converter
442          * provider.
443          * Example:
444          {@snippet :
445           * EnhancedDocument.builder().put("customKey", customValue, EnhancedType.of(CustomClass.class));
446           *}
447          * Use {@link #putString(String, String)} or {@link #putNumber(String, Number)} for inserting simple value types of
448          * attributes.
449          * Use {@link #putList(String, List, EnhancedType)} or {@link #putMap(String, Map, EnhancedType, EnhancedType)} for
450          * inserting collections of attribute values.
451          * Note that the attribute converter provider added to the DocumentBuilder must provide the converter for the class T
452          * that is to be inserted.
453          @param attributeName the name of the attribute to be added to the document.
454          @param value the value to set.
455          @param type the Enhanced type of the value to set.
456          @return a builder instance to construct a {@link EnhancedDocument}.
457          @param <T> the type of the value to set.
458          */
put(String attributeName, T value, EnhancedType<T> type)459         <T> Builder put(String attributeName, T value, EnhancedType<T> type);
460 
461         /**
462          * Appends an attribute named {@code attributeName} with a value of Class type T.
463          * Use this method to insert attribute values of custom types that have attribute converters defined in a converter
464          * provider.
465          * Example:
466          {@snippet :
467           * EnhancedDocument.builder().put("customKey", customValue, CustomClass.class);
468           *}
469          * Use {@link #putString(String, String)} or {@link #putNumber(String, Number)} for inserting simple value types of
470          * attributes.
471          * Use {@link #putList(String, List, EnhancedType)} or {@link #putMap(String, Map, EnhancedType, EnhancedType)} for
472          * inserting collections of attribute values.
473          * Note that the attribute converter provider added to the DocumentBuilder must provide the converter for the class T
474          * that is to be inserted.
475          @param attributeName the name of the attribute to be added to the document.
476          @param value the value to set.
477          @param type the type of the value to set.
478          @return a builder instance to construct a {@link EnhancedDocument}.
479          @param <T> the type of the value to set.
480          */
put(String attributeName, T value, Class<T> type)481         <T> Builder put(String attributeName, T value, Class<T> type);
482 
483         /**
484          * Appends an attribute with the specified name and a Map containing keys and values of {@link EnhancedType} K
485          * and V types,
486          * respectively, to the document builder. Use {@link EnhancedType#of(Class)} to specify the class type of the keys and
487          * values.
488          * <p>For example, to insert a map with String keys and Long values:
489          * {@snippet :
490          * EnhancedDocument.builder().putMap("stringMap", mapWithStringKeyNumberValue, EnhancedType.of(String.class),
491          * EnhancedType.of(String.class), EnhancedType.of(Long.class))
492          *}
493          * <p>For example, to insert a map of String Key and Custom Values:
494          * {@snippet :
495          * EnhancedDocument.builder().putMap("customMap", mapWithStringKeyCustomValue, EnhancedType.of(String.class),
496          * EnhancedType.of(String.class), EnhancedType.of(Custom.class))
497          *}
498          * Note that the AttributeConverterProvider added to the DocumentBuilder should provide the converter for the classes
499          * K and V that
500          * are to be inserted.
501          * @param attributeName the name of the attribute to be added to the document
502          * @param value         The Map of values that needs to be set.
503          * @param keyType       Enhanced type of Key class
504          * @param valueType     Enhanced type of Value class.
505          * @return Builder instance to construct a {@link EnhancedDocument}
506          */
putMap(String attributeName, Map<K, V> value, EnhancedType<K> keyType, EnhancedType<V> valueType)507         <K, V> Builder putMap(String attributeName, Map<K, V> value, EnhancedType<K> keyType, EnhancedType<V> valueType);
508 
509         /**
510          Appends an attribute to the document builder with the specified name and value of a JSON document in string format.
511          * @param attributeName the name of the attribute to be added to the document.
512          * @param json          JSON document in the form of a string.
513          * @return Builder instance to construct a {@link EnhancedDocument}
514          */
putJson(String attributeName, String json)515         Builder putJson(String attributeName, String json);
516 
517 
518         /**
519          * Removes a previously appended attribute.
520          * This can be used where a previously added attribute to the Builder is no longer needed.
521          * @param attributeName The attribute that needs to be removed.
522          * @return Builder instance to construct a {@link EnhancedDocument}
523          */
remove(String attributeName)524         Builder remove(String attributeName);
525 
526         /**
527          * Appends collection of attributeConverterProvider to the document builder. These
528          * AttributeConverterProvider will be used to convert any given key to custom type T.
529          * The first matching converter from the given provider will be selected based on the order in which they are added.
530          * @param attributeConverterProvider determining the {@link AttributeConverter} to use for converting a value.
531          * @return Builder instance to construct a {@link EnhancedDocument}
532          */
addAttributeConverterProvider(AttributeConverterProvider attributeConverterProvider)533         Builder addAttributeConverterProvider(AttributeConverterProvider attributeConverterProvider);
534 
535         /**
536          * Sets the collection of attributeConverterProviders to the document builder. These AttributeConverterProvider will be
537          * used to convert value of any given key to custom type T.
538          * The first matching converter from the given provider will be selected based on the order in which they are added.
539          * @param attributeConverterProviders determining the {@link AttributeConverter} to use for converting a value.
540          * @return Builder instance to construct a {@link EnhancedDocument}
541          */
attributeConverterProviders(List<AttributeConverterProvider> attributeConverterProviders)542         Builder attributeConverterProviders(List<AttributeConverterProvider> attributeConverterProviders);
543 
544         /**
545          * Sets collection of attributeConverterProviders to the document builder. These AttributeConverterProvider will be
546          * used to convert any given key to custom type T.
547          * The first matching converter from the given provider will be selected based on the order in which they are added.
548          * @param attributeConverterProvider determining the {@link AttributeConverter} to use for converting a value.
549          * @return Builder instance to construct a {@link EnhancedDocument}
550          */
attributeConverterProviders(AttributeConverterProvider... attributeConverterProvider)551         Builder attributeConverterProviders(AttributeConverterProvider... attributeConverterProvider);
552 
553         /**
554          * Sets the attributes of the document builder to those specified in the provided JSON string, and completely replaces
555          * any previously set attributes.
556          *
557          * @param json a JSON document represented as a string
558          * @return a builder instance to construct a {@link EnhancedDocument}
559          * @throws NullPointerException if the json parameter is null
560          */
json(String json)561         Builder json(String json);
562 
563         /**
564          * Sets the attributes of the document builder to those specified in the provided from a AttributeValue Map, and
565          * completely replaces any previously set attributes.
566          *
567          * @param attributeValueMap - Map with Attributes as String keys and AttributeValue as Value.
568          * @return Builder instance to construct a {@link EnhancedDocument}
569          */
attributeValueMap(Map<String, AttributeValue> attributeValueMap)570         Builder attributeValueMap(Map<String, AttributeValue> attributeValueMap);
571 
572         /**
573          * Builds an instance of {@link EnhancedDocument}.
574          *
575          * @return instance of {@link EnhancedDocument} implementation.
576          */
build()577         EnhancedDocument build();
578     }
579 
580 }
581