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