@@ -71,6 +71,7 @@ public class EnhancerImpl implements Enhancer {
71
71
72
72
private static final CoreMessageLogger log = CoreLogging .messageLogger ( Enhancer .class );
73
73
private static final Annotation HIBERNATE_VERSION_ANNOTATION ;
74
+ private static final Annotation SUPPRESS_FB_WARNINGS_ANNOTATION ;
74
75
75
76
static {
76
77
HIBERNATE_VERSION_ANNOTATION = new EnhancementInfo () {
@@ -84,6 +85,23 @@ public Class<? extends Annotation> annotationType() {
84
85
return EnhancementInfo .class ;
85
86
}
86
87
};
88
+
89
+ SUPPRESS_FB_WARNINGS_ANNOTATION = new CodeTemplates .SuppressFBWarnings () {
90
+ @ Override
91
+ public String [] value () {
92
+ return new String [0 ];
93
+ }
94
+
95
+ @ Override
96
+ public String justification () {
97
+ return "generated code" ;
98
+ }
99
+
100
+ @ Override
101
+ public Class <? extends Annotation > annotationType () {
102
+ return CodeTemplates .SuppressFBWarnings .class ;
103
+ }
104
+ };
87
105
}
88
106
89
107
private static final AnnotationDescription TRANSIENT_ANNOTATION = AnnotationDescription .Builder .ofType ( Transient .class ).build ();
@@ -162,6 +180,16 @@ private TypePool buildTypePool(final ClassFileLocator classFileLocator) {
162
180
return TypePool .Default .WithLazyResolution .of ( classFileLocator );
163
181
}
164
182
183
+ private List <Annotation > buildOptInAnnotationList (TypeDescription managedCtClass ) {
184
+ List <Annotation > optInAnnotations = new ArrayList <>();
185
+
186
+ if ( enhancementContext .addSuppressFBWarnings ( managedCtClass ) ) {
187
+ optInAnnotations .add (SUPPRESS_FB_WARNINGS_ANNOTATION );
188
+ }
189
+
190
+ return optInAnnotations ;
191
+ }
192
+
165
193
private DynamicType .Builder <?> doEnhance (DynamicType .Builder <?> builder , TypeDescription managedCtClass ) {
166
194
// can't effectively enhance interfaces
167
195
if ( managedCtClass .isInterface () ) {
@@ -179,37 +207,43 @@ private DynamicType.Builder<?> doEnhance(DynamicType.Builder<?> builder, TypeDes
179
207
return null ;
180
208
}
181
209
210
+ List <Annotation > optInAnnotations = buildOptInAnnotationList ( managedCtClass );
211
+
182
212
builder = builder .annotateType ( HIBERNATE_VERSION_ANNOTATION );
183
213
184
214
if ( enhancementContext .isEntityClass ( managedCtClass ) ) {
185
215
log .debugf ( "Enhancing [%s] as Entity" , managedCtClass .getName () );
186
216
builder = builder .implement ( ManagedEntity .class )
187
217
.defineMethod ( EnhancerConstants .ENTITY_INSTANCE_GETTER_NAME , Object .class , Visibility .PUBLIC )
188
- .intercept ( FixedValue .self () );
218
+ .intercept ( FixedValue .self () )
219
+ .annotateMethod ( optInAnnotations );
189
220
190
221
builder = addFieldWithGetterAndSetter (
191
222
builder ,
192
223
EntityEntry .class ,
224
+ optInAnnotations ,
193
225
EnhancerConstants .ENTITY_ENTRY_FIELD_NAME ,
194
226
EnhancerConstants .ENTITY_ENTRY_GETTER_NAME ,
195
227
EnhancerConstants .ENTITY_ENTRY_SETTER_NAME
196
228
);
197
229
builder = addFieldWithGetterAndSetter (
198
230
builder ,
199
231
ManagedEntity .class ,
232
+ optInAnnotations ,
200
233
EnhancerConstants .PREVIOUS_FIELD_NAME ,
201
234
EnhancerConstants .PREVIOUS_GETTER_NAME ,
202
235
EnhancerConstants .PREVIOUS_SETTER_NAME
203
236
);
204
237
builder = addFieldWithGetterAndSetter (
205
238
builder ,
206
239
ManagedEntity .class ,
240
+ optInAnnotations ,
207
241
EnhancerConstants .NEXT_FIELD_NAME ,
208
242
EnhancerConstants .NEXT_GETTER_NAME ,
209
243
EnhancerConstants .NEXT_SETTER_NAME
210
244
);
211
245
212
- builder = addInterceptorHandling ( builder , managedCtClass );
246
+ builder = addInterceptorHandling ( builder , managedCtClass , optInAnnotations );
213
247
214
248
if ( enhancementContext .doDirtyCheckingInline ( managedCtClass ) ) {
215
249
List <AnnotatedFieldDescription > collectionFields = collectCollectionFields ( managedCtClass );
@@ -218,42 +252,57 @@ private DynamicType.Builder<?> doEnhance(DynamicType.Builder<?> builder, TypeDes
218
252
builder = builder .implement ( SelfDirtinessTracker .class )
219
253
.defineField ( EnhancerConstants .TRACKER_FIELD_NAME , DirtyTracker .class , FieldPersistence .TRANSIENT , Visibility .PRIVATE )
220
254
.annotateField ( TRANSIENT_ANNOTATION )
255
+ .annotateField ( optInAnnotations )
221
256
.defineMethod ( EnhancerConstants .TRACKER_CHANGER_NAME , void .class , Visibility .PUBLIC )
222
257
.withParameters ( String .class )
223
258
.intercept ( implementationTrackChange )
259
+ .annotateMethod ( optInAnnotations )
224
260
.defineMethod ( EnhancerConstants .TRACKER_GET_NAME , String [].class , Visibility .PUBLIC )
225
261
.intercept ( implementationGetDirtyAttributesWithoutCollections )
262
+ .annotateMethod ( optInAnnotations )
226
263
.defineMethod ( EnhancerConstants .TRACKER_HAS_CHANGED_NAME , boolean .class , Visibility .PUBLIC )
227
264
.intercept ( implementationAreFieldsDirtyWithoutCollections )
265
+ .annotateMethod ( optInAnnotations )
228
266
.defineMethod ( EnhancerConstants .TRACKER_CLEAR_NAME , void .class , Visibility .PUBLIC )
229
267
.intercept ( implementationClearDirtyAttributesWithoutCollections )
268
+ .annotateMethod ( optInAnnotations )
230
269
.defineMethod ( EnhancerConstants .TRACKER_SUSPEND_NAME , void .class , Visibility .PUBLIC )
231
270
.withParameters ( boolean .class )
232
271
.intercept ( implementationSuspendDirtyTracking )
272
+ .annotateMethod ( optInAnnotations )
233
273
.defineMethod ( EnhancerConstants .TRACKER_COLLECTION_GET_NAME , CollectionTracker .class , Visibility .PUBLIC )
234
- .intercept ( implementationGetCollectionTrackerWithoutCollections );
274
+ .intercept ( implementationGetCollectionTrackerWithoutCollections )
275
+ .annotateMethod ( optInAnnotations );
235
276
}
236
277
else {
237
278
//TODO es.enableInterfaceExtendedSelfDirtinessTracker ? Careful with consequences..
238
279
builder = builder .implement ( ExtendedSelfDirtinessTracker .class )
239
280
.defineField ( EnhancerConstants .TRACKER_FIELD_NAME , DirtyTracker .class , FieldPersistence .TRANSIENT , Visibility .PRIVATE )
240
281
.annotateField ( TRANSIENT_ANNOTATION )
282
+ .annotateField ( optInAnnotations )
241
283
.defineField ( EnhancerConstants .TRACKER_COLLECTION_NAME , CollectionTracker .class , FieldPersistence .TRANSIENT , Visibility .PRIVATE )
242
284
.annotateField ( TRANSIENT_ANNOTATION )
285
+ .annotateField ( optInAnnotations )
243
286
.defineMethod ( EnhancerConstants .TRACKER_CHANGER_NAME , void .class , Visibility .PUBLIC )
244
287
.withParameters ( String .class )
245
288
.intercept ( implementationTrackChange )
289
+ .annotateMethod ( optInAnnotations )
246
290
.defineMethod ( EnhancerConstants .TRACKER_GET_NAME , String [].class , Visibility .PUBLIC )
247
291
.intercept ( implementationGetDirtyAttributes )
292
+ .annotateMethod ( optInAnnotations )
248
293
.defineMethod ( EnhancerConstants .TRACKER_HAS_CHANGED_NAME , boolean .class , Visibility .PUBLIC )
249
294
.intercept ( implementationAreFieldsDirty )
295
+ .annotateMethod ( optInAnnotations )
250
296
.defineMethod ( EnhancerConstants .TRACKER_CLEAR_NAME , void .class , Visibility .PUBLIC )
251
297
.intercept ( implementationClearDirtyAttributes )
298
+ .annotateMethod ( optInAnnotations )
252
299
.defineMethod ( EnhancerConstants .TRACKER_SUSPEND_NAME , void .class , Visibility .PUBLIC )
253
300
.withParameters ( boolean .class )
254
301
.intercept ( implementationSuspendDirtyTracking )
302
+ .annotateMethod ( optInAnnotations )
255
303
.defineMethod ( EnhancerConstants .TRACKER_COLLECTION_GET_NAME , CollectionTracker .class , Visibility .PUBLIC )
256
- .intercept ( FieldAccessor .ofField ( EnhancerConstants .TRACKER_COLLECTION_NAME ) );
304
+ .intercept ( FieldAccessor .ofField ( EnhancerConstants .TRACKER_COLLECTION_NAME ) )
305
+ .annotateMethod ( optInAnnotations );
257
306
258
307
Implementation isDirty = StubMethod .INSTANCE , getDirtyNames = StubMethod .INSTANCE , clearDirtyNames = StubMethod .INSTANCE ;
259
308
for ( AnnotatedFieldDescription collectionField : collectionFields ) {
@@ -319,23 +368,26 @@ private DynamicType.Builder<?> doEnhance(DynamicType.Builder<?> builder, TypeDes
319
368
.defineMethod ( EnhancerConstants .TRACKER_COLLECTION_CHANGED_FIELD_NAME , void .class , Visibility .PUBLIC )
320
369
.withParameters ( DirtyTracker .class )
321
370
.intercept ( getDirtyNames )
371
+ .annotateMethod ( optInAnnotations )
322
372
.defineMethod ( EnhancerConstants .TRACKER_COLLECTION_CLEAR_NAME , void .class , Visibility .PUBLIC )
323
373
.intercept ( Advice .withCustomMapping ()
324
374
.to ( CodeTemplates .ClearDirtyCollectionNames .class , adviceLocator )
325
375
.wrap ( StubMethod .INSTANCE ) )
376
+ .annotateMethod ( optInAnnotations )
326
377
.defineMethod ( ExtendedSelfDirtinessTracker .REMOVE_DIRTY_FIELDS_NAME , void .class , Visibility .PUBLIC )
327
378
.withParameters ( LazyAttributeLoadingInterceptor .class )
328
- .intercept ( clearDirtyNames );
379
+ .intercept ( clearDirtyNames )
380
+ .annotateMethod ( optInAnnotations );
329
381
}
330
382
}
331
383
332
- return createTransformer ( managedCtClass ).applyTo ( builder );
384
+ return createTransformer ( managedCtClass , optInAnnotations ).applyTo ( builder );
333
385
}
334
386
else if ( enhancementContext .isCompositeClass ( managedCtClass ) ) {
335
387
log .debugf ( "Enhancing [%s] as Composite" , managedCtClass .getName () );
336
388
337
389
builder = builder .implement ( ManagedComposite .class );
338
- builder = addInterceptorHandling ( builder , managedCtClass );
390
+ builder = addInterceptorHandling ( builder , managedCtClass , optInAnnotations );
339
391
340
392
if ( enhancementContext .doDirtyCheckingInline ( managedCtClass ) ) {
341
393
builder = builder .implement ( CompositeTracker .class )
@@ -346,42 +398,45 @@ else if ( enhancementContext.isCompositeClass( managedCtClass ) ) {
346
398
Visibility .PRIVATE
347
399
)
348
400
.annotateField ( TRANSIENT_ANNOTATION )
401
+ .annotateField ( optInAnnotations )
349
402
.defineMethod (
350
403
EnhancerConstants .TRACKER_COMPOSITE_SET_OWNER ,
351
404
void .class ,
352
405
Visibility .PUBLIC
353
406
)
354
407
.withParameters ( String .class , CompositeOwner .class )
355
408
.intercept ( implementationSetOwner )
409
+ .annotateMethod ( optInAnnotations )
356
410
.defineMethod (
357
411
EnhancerConstants .TRACKER_COMPOSITE_CLEAR_OWNER ,
358
412
void .class ,
359
413
Visibility .PUBLIC
360
414
)
361
415
.withParameters ( String .class )
362
- .intercept ( implementationClearOwner );
416
+ .intercept ( implementationClearOwner )
417
+ .annotateMethod ( optInAnnotations );
363
418
}
364
419
365
- return createTransformer ( managedCtClass ).applyTo ( builder );
420
+ return createTransformer ( managedCtClass , optInAnnotations ).applyTo ( builder );
366
421
}
367
422
else if ( enhancementContext .isMappedSuperclassClass ( managedCtClass ) ) {
368
423
log .debugf ( "Enhancing [%s] as MappedSuperclass" , managedCtClass .getName () );
369
424
370
425
builder = builder .implement ( ManagedMappedSuperclass .class );
371
- return createTransformer ( managedCtClass ).applyTo ( builder );
426
+ return createTransformer ( managedCtClass , optInAnnotations ).applyTo ( builder );
372
427
}
373
428
else if ( enhancementContext .doExtendedEnhancement ( managedCtClass ) ) {
374
429
log .debugf ( "Extended enhancement of [%s]" , managedCtClass .getName () );
375
- return createTransformer ( managedCtClass ).applyExtended ( builder );
430
+ return createTransformer ( managedCtClass , optInAnnotations ).applyExtended ( builder );
376
431
}
377
432
else {
378
433
log .debugf ( "Skipping enhancement of [%s]: not entity or composite" , managedCtClass .getName () );
379
434
return null ;
380
435
}
381
436
}
382
437
383
- private PersistentAttributeTransformer createTransformer (TypeDescription typeDescription ) {
384
- return PersistentAttributeTransformer .collectPersistentFields ( typeDescription , enhancementContext , typePool );
438
+ private PersistentAttributeTransformer createTransformer (TypeDescription typeDescription , List < Annotation > optInAnnotations ) {
439
+ return PersistentAttributeTransformer .collectPersistentFields ( typeDescription , optInAnnotations , enhancementContext , typePool );
385
440
}
386
441
387
442
// See HHH-10977 HHH-11284 HHH-11404 --- check for declaration of Managed interface on the class, not inherited
@@ -394,7 +449,7 @@ private boolean alreadyEnhanced(TypeDescription managedCtClass) {
394
449
return false ;
395
450
}
396
451
397
- private DynamicType .Builder <?> addInterceptorHandling (DynamicType .Builder <?> builder , TypeDescription managedCtClass ) {
452
+ private DynamicType .Builder <?> addInterceptorHandling (DynamicType .Builder <?> builder , TypeDescription managedCtClass , List < Annotation > optInAnnotations ) {
398
453
// interceptor handling is only needed if class has lazy-loadable attributes
399
454
if ( enhancementContext .hasLazyLoadableAttributes ( managedCtClass ) ) {
400
455
log .debugf ( "Weaving in PersistentAttributeInterceptable implementation on [%s]" , managedCtClass .getName () );
@@ -404,6 +459,7 @@ private DynamicType.Builder<?> addInterceptorHandling(DynamicType.Builder<?> bui
404
459
builder = addFieldWithGetterAndSetter (
405
460
builder ,
406
461
PersistentAttributeInterceptor .class ,
462
+ optInAnnotations ,
407
463
EnhancerConstants .INTERCEPTOR_FIELD_NAME ,
408
464
EnhancerConstants .INTERCEPTOR_GETTER_NAME ,
409
465
EnhancerConstants .INTERCEPTOR_SETTER_NAME
@@ -414,19 +470,23 @@ private DynamicType.Builder<?> addInterceptorHandling(DynamicType.Builder<?> bui
414
470
}
415
471
416
472
private static DynamicType .Builder <?> addFieldWithGetterAndSetter (
417
- DynamicType .Builder <?> builder ,
418
- Class <?> type ,
419
- String fieldName ,
420
- String getterName ,
421
- String setterName ) {
473
+ DynamicType .Builder <?> builder ,
474
+ Class <?> type ,
475
+ List <Annotation > annotations ,
476
+ String fieldName ,
477
+ String getterName ,
478
+ String setterName ) {
422
479
return builder
423
480
.defineField ( fieldName , type , Visibility .PRIVATE , FieldPersistence .TRANSIENT )
424
481
.annotateField ( TRANSIENT_ANNOTATION )
482
+ .annotateField ( annotations )
425
483
.defineMethod ( getterName , type , Visibility .PUBLIC )
426
484
.intercept ( FieldAccessor .ofField ( fieldName ) )
485
+ .annotateMethod ( annotations )
427
486
.defineMethod ( setterName , void .class , Visibility .PUBLIC )
428
487
.withParameters ( type )
429
- .intercept ( FieldAccessor .ofField ( fieldName ) );
488
+ .intercept ( FieldAccessor .ofField ( fieldName ) )
489
+ .annotateMethod ( annotations );
430
490
}
431
491
432
492
private List <AnnotatedFieldDescription > collectCollectionFields (TypeDescription managedCtClass ) {
0 commit comments