4
4
*/
5
5
package org .hibernate .processor .annotation ;
6
6
7
-
8
7
import javax .lang .model .element .ExecutableElement ;
9
-
8
+ import javax .lang .model .element .TypeElement ;
9
+ import javax .lang .model .element .TypeParameterElement ;
10
+ import javax .lang .model .element .VariableElement ;
11
+ import javax .lang .model .type .ArrayType ;
12
+ import javax .lang .model .type .DeclaredType ;
13
+ import javax .lang .model .type .IntersectionType ;
14
+ import javax .lang .model .type .TypeKind ;
15
+ import javax .lang .model .type .TypeMirror ;
16
+ import javax .lang .model .type .TypeVariable ;
17
+ import javax .lang .model .type .WildcardType ;
18
+ import java .util .Collection ;
10
19
import java .util .Set ;
11
20
12
21
import static java .lang .Character .toUpperCase ;
22
+ import static java .util .stream .Collectors .joining ;
23
+ import static java .util .stream .Collectors .toSet ;
24
+ import static javax .lang .model .type .TypeKind .VOID ;
13
25
import static org .hibernate .processor .util .Constants .EVENT ;
14
26
import static org .hibernate .processor .util .Constants .INJECT ;
15
27
import static org .hibernate .processor .util .Constants .JD_LIFECYCLE_EVENT ;
16
28
import static org .hibernate .processor .util .Constants .LIST ;
17
29
import static org .hibernate .processor .util .Constants .NONNULL ;
18
30
import static org .hibernate .processor .util .Constants .TYPE_LITERAL ;
19
31
import static org .hibernate .processor .util .Constants .UNI ;
32
+ import static org .hibernate .processor .util .TypeUtils .resolveTypeName ;
20
33
21
34
public class LifecycleMethod extends AbstractAnnotatedMethod {
22
35
private final String entity ;
@@ -28,6 +41,8 @@ public class LifecycleMethod extends AbstractAnnotatedMethod {
28
41
private final ParameterKind parameterKind ;
29
42
private final boolean returnArgument ;
30
43
private final boolean hasGeneratedId ;
44
+ private final Collection <String > methodTypeParameters ;
45
+ private final TypeElement element ;
31
46
32
47
public enum ParameterKind {
33
48
NORMAL ,
@@ -48,7 +63,8 @@ public LifecycleMethod(
48
63
boolean addNonnullAnnotation ,
49
64
ParameterKind parameterKind ,
50
65
boolean returnArgument ,
51
- boolean hasGeneratedId ) {
66
+ boolean hasGeneratedId ,
67
+ TypeElement element ) {
52
68
super (annotationMetaEntity , method , sessionName , sessionType );
53
69
this .entity = entity ;
54
70
this .actualEntity = actualEntity ;
@@ -59,6 +75,11 @@ public LifecycleMethod(
59
75
this .parameterKind = parameterKind ;
60
76
this .returnArgument = returnArgument ;
61
77
this .hasGeneratedId = hasGeneratedId ;
78
+ this .methodTypeParameters = method .getTypeParameters ().stream ()
79
+ .map ( TypeParameterElement ::asType )
80
+ .map ( TypeMirror ::toString )
81
+ .collect ( toSet () );
82
+ this .element = element ;
62
83
}
63
84
64
85
@ Override
@@ -334,27 +355,86 @@ private boolean isGeneratedIdUpsert() {
334
355
private void preamble (StringBuilder declaration ) {
335
356
declaration
336
357
.append ("\n @Override\n public " )
358
+ .append (parameterTypeBopunds ())
337
359
.append (returnType ())
338
360
.append (' ' )
339
361
.append (methodName )
340
362
.append ('(' );
341
363
notNull (declaration );
364
+ final var parameters = method .getParameters ();
365
+ assert parameters .size () == 1 ;
366
+ final VariableElement element = parameters .get (0 );
342
367
declaration
343
- .append (annotationMetaEntity . importType ( entity ))
368
+ .append (resolveAsString ( element . asType () ))
344
369
.append (' ' )
345
- .append (parameterName )
370
+ .append (element . getSimpleName () )
346
371
.append (')' )
347
372
.append (" {\n " );
348
373
}
349
374
375
+ private String parameterTypeBopunds () {
376
+ if ( method .getTypeParameters ().isEmpty () ) {
377
+ return "" ;
378
+ }
379
+ return method .getTypeParameters ().stream ()
380
+ .map ( this ::resolveTypeParameter )
381
+ .collect ( joining ( ", " , " <" , "> " ) );
382
+ }
383
+
384
+ private String resolveAsString (TypeMirror type ) {
385
+ if ( type .getKind ().isPrimitive () || type .getKind () == VOID ) {
386
+ return type .toString ();
387
+ }
388
+ else if ( type instanceof DeclaredType declaredType ) {
389
+ final var element = annotationMetaEntity .importType (
390
+ ((TypeElement ) declaredType .asElement ()).getQualifiedName ().toString ()
391
+ );
392
+ if ( declaredType .getTypeArguments ().isEmpty () ) {
393
+ return element ;
394
+ }
395
+ return element + declaredType .getTypeArguments ().stream ().map ( this ::resolveAsString )
396
+ .collect ( joining ( "," , "<" , ">" ) );
397
+ }
398
+ else if ( type instanceof TypeVariable typeVariable ) {
399
+ final var value = typeVariable .toString ();
400
+ if ( methodTypeParameters .contains ( value ) ) {
401
+ return value ;
402
+ }
403
+ return annotationMetaEntity .importType ( resolveTypeName ( element , method .getEnclosingElement (), value ) );
404
+ }
405
+ else if ( type instanceof WildcardType wildcardType ) {
406
+ return "?"
407
+ + (wildcardType .getExtendsBound () == null ? ""
408
+ : " extends " + resolveAsString ( wildcardType .getExtendsBound () ))
409
+ + (wildcardType .getSuperBound () == null ? ""
410
+ : " super " + resolveAsString ( wildcardType .getExtendsBound () ));
411
+ }
412
+ else if ( type instanceof ArrayType arrayType ) {
413
+ return resolveAsString ( arrayType .getComponentType () ) + "[]" ;
414
+ }
415
+ else if ( type instanceof IntersectionType intersectionType ) {
416
+ return intersectionType .getBounds ().stream ().map ( this ::resolveAsString ).collect ( joining ( "&" ) );
417
+ }
418
+ else {
419
+ return type .toString ();
420
+ }
421
+ }
422
+
423
+ private String resolveTypeParameter (TypeParameterElement p ) {
424
+ final var type = (TypeVariable ) p .asType ();
425
+ return type .toString ()
426
+ + (type .getUpperBound ().getKind () == TypeKind .NULL ? ""
427
+ : " extends " + resolveAsString ( type .getUpperBound () ))
428
+ + (type .getLowerBound ().getKind () == TypeKind .NULL ? ""
429
+ : " super " + resolveAsString ( type .getLowerBound () ));
430
+ }
431
+
350
432
private String returnType () {
351
- final String entityType = annotationMetaEntity .importType (entity );
352
- if ( isReactive () ) {
353
- return annotationMetaEntity .importType (UNI )
354
- + '<' + (returnArgument ? entityType : "Void" ) + '>' ;
433
+ if ( returnArgument ) {
434
+ return resolveAsString (method .getReturnType ());
355
435
}
356
436
else {
357
- return returnArgument ? entityType : "void" ;
437
+ return isReactive () ? annotationMetaEntity . importType ( UNI ) + "<Void>" : "void" ;
358
438
}
359
439
}
360
440
0 commit comments