16
16
package org .springframework .data .neo4j .core .mapping ;
17
17
18
18
import java .lang .reflect .Constructor ;
19
+ import java .lang .reflect .Method ;
19
20
import java .lang .reflect .Modifier ;
20
21
import java .lang .reflect .ParameterizedType ;
21
22
import java .lang .reflect .Type ;
34
35
import org .neo4j .driver .types .TypeSystem ;
35
36
import org .springframework .beans .BeanUtils ;
36
37
import org .springframework .beans .BeansException ;
38
+ import org .springframework .beans .factory .BeanFactory ;
37
39
import org .springframework .beans .factory .NoSuchBeanDefinitionException ;
38
40
import org .springframework .beans .factory .config .AutowireCapableBeanFactory ;
39
41
import org .springframework .context .ApplicationContext ;
52
54
import org .springframework .data .neo4j .core .convert .Neo4jPersistentPropertyConverterFactory ;
53
55
import org .springframework .data .neo4j .core .schema .IdGenerator ;
54
56
import org .springframework .data .neo4j .core .schema .Node ;
55
- import org .springframework .data .util .ReflectionUtils ;
56
57
import org .springframework .data .util .TypeInformation ;
57
58
import org .springframework .lang .Nullable ;
59
+ import org .springframework .util .ReflectionUtils ;
58
60
59
61
/**
60
62
* An implementation of both a {@link Schema} as well as a Neo4j version of Spring Data's
@@ -328,12 +330,37 @@ public <T extends IdGenerator<?>> Optional<T> getIdGenerator(String reference) {
328
330
}
329
331
}
330
332
333
+ @ Nullable
334
+ Constructor <?> findConstructor (Class <?> clazz , Class <?>... parameterTypes ) {
335
+ try {
336
+ return ReflectionUtils .accessibleConstructor (clazz , parameterTypes );
337
+ } catch (NoSuchMethodException e ) {
338
+ return null ;
339
+ }
340
+ }
341
+
331
342
private <T extends Neo4jPersistentPropertyConverterFactory > T getOrCreateConverterFactoryOfType (Class <T > converterFactoryType ) {
332
343
333
344
return converterFactoryType .cast (this .converterFactories .computeIfAbsent (converterFactoryType , t -> {
334
- Optional <Constructor <?>> optionalConstructor = ReflectionUtils .findConstructor (t , this .conversionService );
335
- if (optionalConstructor .isPresent ()) {
336
- return t .cast (BeanUtils .instantiateClass (optionalConstructor .get (), this .conversionService ));
345
+ Constructor <?> optionalConstructor ;
346
+ optionalConstructor = findConstructor (t , BeanFactory .class , Neo4jConversionService .class );
347
+ if (optionalConstructor != null ) {
348
+ return t .cast (BeanUtils .instantiateClass (optionalConstructor , this .beanFactory , this .conversionService ));
349
+ }
350
+
351
+ optionalConstructor = findConstructor (t , Neo4jConversionService .class , BeanFactory .class );
352
+ if (optionalConstructor != null ) {
353
+ return t .cast (BeanUtils .instantiateClass (optionalConstructor , this .beanFactory , this .conversionService ));
354
+ }
355
+
356
+ optionalConstructor = findConstructor (t , BeanFactory .class );
357
+ if (optionalConstructor != null ) {
358
+ return t .cast (BeanUtils .instantiateClass (optionalConstructor , this .beanFactory ));
359
+ }
360
+
361
+ optionalConstructor = findConstructor (t , Neo4jConversionService .class );
362
+ if (optionalConstructor != null ) {
363
+ return t .cast (BeanUtils .instantiateClass (optionalConstructor , this .conversionService ));
337
364
}
338
365
return BeanUtils .instantiateClass (t );
339
366
}));
@@ -353,11 +380,19 @@ Neo4jPersistentPropertyConverter<?> getOptionalCustomConversionsFor(Neo4jPersist
353
380
354
381
ConvertWith convertWith = persistentProperty .getRequiredAnnotation (ConvertWith .class );
355
382
Neo4jPersistentPropertyConverterFactory persistentPropertyConverterFactory = this .getOrCreateConverterFactoryOfType (convertWith .converterFactory ());
356
- Neo4jPersistentPropertyConverter <?> customConversions = persistentPropertyConverterFactory .getPropertyConverterFor (persistentProperty );
383
+ Neo4jPersistentPropertyConverter <?> customConverter = persistentPropertyConverterFactory .getPropertyConverterFor (persistentProperty );
357
384
358
385
boolean forCollection = false ;
359
- if (persistentProperty .isCollectionLike () && convertWith .converter () != ConvertWith .UnsetConverter .class ) {
360
- Map <String , Type > typeVariableMap = GenericTypeResolver .getTypeVariableMap (convertWith .converter ())
386
+ if (persistentProperty .isCollectionLike ()) {
387
+ Class <?> converterClass ;
388
+ Method getClassOfDelegate = ReflectionUtils .findMethod (customConverter .getClass (), "getClassOfDelegate" );
389
+ if (getClassOfDelegate != null ) {
390
+ ReflectionUtils .makeAccessible (getClassOfDelegate );
391
+ converterClass = (Class <?>) ReflectionUtils .invokeMethod (getClassOfDelegate , customConverter );
392
+ } else {
393
+ converterClass = customConverter .getClass ();
394
+ }
395
+ Map <String , Type > typeVariableMap = GenericTypeResolver .getTypeVariableMap (converterClass )
361
396
.entrySet ()
362
397
.stream ()
363
398
.collect (Collectors .toMap (e -> e .getKey ().getName (), Map .Entry ::getValue ));
@@ -367,12 +402,11 @@ Neo4jPersistentPropertyConverter<?> getOptionalCustomConversionsFor(Neo4jPersist
367
402
} else if (typeVariableMap .containsKey ("P" )) {
368
403
propertyType = typeVariableMap .get ("P" );
369
404
}
370
- forCollection =
371
- propertyType != null && propertyType instanceof ParameterizedType && persistentProperty .getType ()
372
- .equals (((ParameterizedType ) propertyType ).getRawType ());
405
+ forCollection = propertyType instanceof ParameterizedType &&
406
+ persistentProperty .getType ().equals (((ParameterizedType ) propertyType ).getRawType ());
373
407
}
374
408
375
- return new NullSafeNeo4jPersistentPropertyConverter <>(customConversions , persistentProperty .isComposite (), forCollection );
409
+ return new NullSafeNeo4jPersistentPropertyConverter <>(customConverter , persistentProperty .isComposite (), forCollection );
376
410
}
377
411
378
412
@ Override
0 commit comments