2121import java .util .HashMap ;
2222import java .util .List ;
2323import java .util .Map ;
24+ import java .util .Objects ;
2425import java .util .Optional ;
2526import java .util .regex .Pattern ;
2627import software .amazon .awssdk .annotations .SdkInternalApi ;
@@ -65,45 +66,47 @@ public static TableSchema<?> getTableSchemaForListElement(TableSchema<?> rootSch
6566 public static TableSchema <?> getTableSchemaForListElement (
6667 TableSchema <?> rootSchema ,
6768 String key ,
68- Map <SchemaLookupKey , Optional <? extends TableSchema <?>>> nestedSchemaCache ) {
69- TableSchema <?> listElementSchema ;
70-
71- if (!key .contains (NESTED_OBJECT_UPDATE )) {
72- Optional <? extends TableSchema <?>> staticSchema = getNestedSchemaCached (nestedSchemaCache , rootSchema , key );
73- if (staticSchema .isPresent ()) {
74- listElementSchema = staticSchema .get ();
75- } else {
76- AttributeConverter <?> converter = rootSchema .converterForAttribute (key );
77- if (converter == null ) {
78- throw new IllegalArgumentException ("No converter found for attribute: " + key );
79- }
80- List <EnhancedType <?>> rawClassParameters = converter .type ().rawClassParameters ();
81- if (CollectionUtils .isNullOrEmpty (rawClassParameters )) {
82- throw new IllegalArgumentException ("No type parameters found for list attribute: " + key );
83- }
84- listElementSchema = TableSchema .fromClass (rawClassParameters .get (0 ).rawClass ());
85- }
86- } else {
87- String [] parts = NESTED_OBJECT_PATTERN .split (key );
88- TableSchema <?> currentSchema = rootSchema ;
69+ Map <SchemaLookupKey , Optional <TableSchema <?>>> nestedSchemaCache ) {
8970
90- for (int i = 0 ; i < parts .length - 1 ; i ++) {
91- Optional <? extends TableSchema <?>> nestedSchema =
92- getNestedSchemaCached (nestedSchemaCache , currentSchema , parts [i ]);
93- if (nestedSchema .isPresent ()) {
94- currentSchema = nestedSchema .get ();
95- }
96- }
71+ if (key .contains (NESTED_OBJECT_UPDATE )) {
72+ return listElementSchemaForDelimitedKey (rootSchema , key , nestedSchemaCache );
73+ }
9774
98- String attributeName = parts [parts .length - 1 ];
99- Optional <? extends TableSchema <?>> nestedListSchema =
100- getNestedSchemaCached (nestedSchemaCache , currentSchema , attributeName );
75+ Optional <TableSchema <?>> staticSchema = getNestedSchemaCached (nestedSchemaCache , rootSchema , key );
76+ if (staticSchema .isPresent ()) {
77+ return staticSchema .get ();
78+ }
10179
102- listElementSchema = nestedListSchema .orElseThrow (
103- () -> new IllegalArgumentException ("Unable to resolve schema for list element at: " + key ));
80+ AttributeConverter <?> converter = rootSchema .converterForAttribute (key );
81+ if (converter == null ) {
82+ throw new IllegalArgumentException ("No converter found for attribute: " + key );
83+ }
84+ List <EnhancedType <?>> rawClassParameters = converter .type ().rawClassParameters ();
85+ if (CollectionUtils .isNullOrEmpty (rawClassParameters )) {
86+ throw new IllegalArgumentException ("No type parameters found for list attribute: " + key );
10487 }
88+ return TableSchema .fromClass (rawClassParameters .get (0 ).rawClass ());
89+ }
90+
91+ private static TableSchema <?> listElementSchemaForDelimitedKey (
92+ TableSchema <?> rootSchema ,
93+ String key ,
94+ Map <SchemaLookupKey , Optional <TableSchema <?>>> nestedSchemaCache ) {
95+
96+ String [] parts = NESTED_OBJECT_PATTERN .split (key );
97+ TableSchema <?> currentSchema = rootSchema ;
10598
106- return listElementSchema ;
99+ for (int i = 0 ; i < parts .length - 1 ; i ++) {
100+ Optional <TableSchema <?>> nestedSchema =
101+ getNestedSchemaCached (nestedSchemaCache , currentSchema , parts [i ]);
102+ if (nestedSchema .isPresent ()) {
103+ currentSchema = nestedSchema .get ();
104+ }
105+ }
106+
107+ String attributeName = parts [parts .length - 1 ];
108+ return getNestedSchemaCached (nestedSchemaCache , currentSchema , attributeName )
109+ .orElseThrow (() -> new IllegalArgumentException ("Unable to resolve schema for list element at: " + key ));
107110 }
108111
109112 /**
@@ -134,7 +137,7 @@ public static Map<String, TableSchema<?>> resolveSchemasPerPath(Map<String, Attr
134137 public static Map <String , TableSchema <?>> resolveSchemasPerPath (
135138 Map <String , AttributeValue > attributesToSet ,
136139 TableSchema <?> rootSchema ,
137- Map <SchemaLookupKey , Optional <? extends TableSchema <?>>> nestedSchemaCache ) {
140+ Map <SchemaLookupKey , Optional <TableSchema <?>>> nestedSchemaCache ) {
138141
139142 Map <String , TableSchema <?>> schemaMap = new HashMap <>();
140143 schemaMap .put ("" , rootSchema );
@@ -154,7 +157,7 @@ public static Map<String, TableSchema<?>> resolveSchemasPerPath(
154157 String path = pathBuilder .toString ();
155158
156159 if (!schemaMap .containsKey (path )) {
157- Optional <? extends TableSchema <?>> nestedSchema =
160+ Optional <TableSchema <?>> nestedSchema =
158161 getNestedSchemaCached (nestedSchemaCache , currentSchema , parts [i ]);
159162
160163 if (nestedSchema .isPresent ()) {
@@ -197,8 +200,8 @@ public static String reconstructCompositeKey(String path, String attributeName)
197200 * Cached wrapper around {@link software.amazon.awssdk.enhanced.dynamodb.internal.EnhancedClientUtils#getNestedSchema}. Cache
198201 * key is based on (parent schema identity, attribute name).
199202 */
200- public static Optional <? extends TableSchema <?>> getNestedSchemaCached (
201- Map <SchemaLookupKey , Optional <? extends TableSchema <?>>> cache ,
203+ public static Optional <TableSchema <?>> getNestedSchemaCached (
204+ Map <SchemaLookupKey , Optional <TableSchema <?>>> cache ,
202205 TableSchema <?> parentSchema ,
203206 String attributeName ) {
204207
@@ -215,15 +218,16 @@ public static Optional<? extends TableSchema<?>> getNestedSchemaCached(
215218 public static TableSchema <?> getListElementSchemaCached (
216219 Map <SchemaLookupKey , TableSchema <?>> cache ,
217220 TableSchema <?> parentSchema ,
218- String attributeName ) {
221+ String attributeName ,
222+ Map <SchemaLookupKey , Optional <TableSchema <?>>> nestedSchemaCache ) {
219223
220224 SchemaLookupKey key = new SchemaLookupKey (parentSchema , attributeName );
221225
222226 if (cache .containsKey (key )) {
223227 return cache .get (key );
224228 }
225229
226- TableSchema <?> schema = getTableSchemaForListElement (parentSchema , attributeName , new HashMap <>() );
230+ TableSchema <?> schema = getTableSchemaForListElement (parentSchema , attributeName , nestedSchemaCache );
227231 cache .put (key , schema );
228232 return schema ;
229233 }
@@ -235,29 +239,24 @@ public static TableSchema<?> getListElementSchemaCached(
235239 public static final class SchemaLookupKey {
236240 private final TableSchema <?> parentSchema ;
237241 private final String attributeName ;
238- private final int hash ;
239242
240243 public SchemaLookupKey (TableSchema <?> parentSchema , String attributeName ) {
241244 this .parentSchema = parentSchema ;
242245 this .attributeName = attributeName ;
243- this .hash = 31 * System .identityHashCode (parentSchema ) + attributeName .hashCode ();
244246 }
245247
246248 @ Override
247249 public boolean equals (Object o ) {
248- if (this == o ) {
249- return true ;
250- }
251- if (!(o instanceof SchemaLookupKey )) {
250+ if (o == null || getClass () != o .getClass ()) {
252251 return false ;
253252 }
254- SchemaLookupKey other = (SchemaLookupKey ) o ;
255- return this . parentSchema == other .parentSchema && this . attributeName . equals (other .attributeName );
253+ SchemaLookupKey that = (SchemaLookupKey ) o ;
254+ return Objects . equals ( parentSchema , that .parentSchema ) && Objects . equals (attributeName , that .attributeName );
256255 }
257256
258257 @ Override
259258 public int hashCode () {
260- return hash ;
259+ return 31 * System . identityHashCode ( parentSchema ) + ( attributeName == null ? 0 : attributeName . hashCode ()) ;
261260 }
262261 }
263262}
0 commit comments