15
15
import java .util .ArrayList ;
16
16
import java .util .Arrays ;
17
17
import java .util .Collections ;
18
- import java .util .Iterator ;
19
18
import java .util .List ;
20
19
import java .util .Map ;
21
20
@@ -236,9 +235,9 @@ public ReflectionOptimizer getReflectionOptimizer(
236
235
return null ;
237
236
}
238
237
239
- Class <?> superClass = determineAccessOptimizerSuperClass ( clazz , getters , setters );
240
-
241
238
final String [] propertyNames = propertyAccessMap .keySet ().toArray ( new String [0 ] );
239
+ final Class <?> superClass = determineAccessOptimizerSuperClass ( clazz , propertyNames , getters , setters );
240
+
242
241
final Class <?> bulkAccessor = byteBuddyState .load ( clazz , byteBuddy -> byteBuddy
243
242
.with ( new NamingStrategy .SuffixingRandom (
244
243
OPTIMIZER_PROXY_NAMING_SUFFIX ,
@@ -265,106 +264,94 @@ public ReflectionOptimizer getReflectionOptimizer(
265
264
}
266
265
}
267
266
268
- private static class ForeignPackageClassInfo {
267
+ private static class BridgeMembersClassInfo {
269
268
final Class <?> clazz ;
269
+ final List <String > propertyNames = new ArrayList <>();
270
270
final List <Member > getters = new ArrayList <>();
271
271
final List <Member > setters = new ArrayList <>();
272
272
273
- public ForeignPackageClassInfo (Class <?> clazz ) {
273
+ public BridgeMembersClassInfo (Class <?> clazz ) {
274
274
this .clazz = clazz ;
275
275
}
276
276
}
277
277
278
- private Class <?> determineAccessOptimizerSuperClass (Class <?> clazz , Member [] getters , Member [] setters ) {
278
+ private Class <?> determineAccessOptimizerSuperClass (Class <?> clazz , String [] propertyNames , Member [] getters , Member [] setters ) {
279
279
if ( clazz .isInterface () ) {
280
280
return Object .class ;
281
281
}
282
- // generate access optimizer super classes for foreign package super classes that declare fields
282
+ // generate access optimizer super classes for super classes that declare members requiring bridge methods
283
283
// each should declare protected static methods get_FIELDNAME(OWNER)/set_FIELDNAME(OWNER, TYPE)
284
284
// which should be called then from within GetPropertyValues/SetPropertyValues
285
285
// Since these super classes will be in the correct package, the package-private entity field access is fine
286
- final List <ForeignPackageClassInfo > foreignPackageClassInfos = createForeignPackageClassInfos ( clazz );
287
- for ( Iterator <ForeignPackageClassInfo > iterator = foreignPackageClassInfos .iterator (); iterator .hasNext (); ) {
288
- final ForeignPackageClassInfo foreignPackageClassInfo = iterator .next ();
289
- for ( int i = 0 ; i < getters .length ; i ++ ) {
290
- final Member getter = getters [i ];
291
- final Member setter = setters [i ];
292
- if ( getter .getDeclaringClass () == foreignPackageClassInfo .clazz && !Modifier .isPublic ( getter .getModifiers () ) ) {
293
- foreignPackageClassInfo .getters .add ( getter );
294
- }
295
- if ( setter .getDeclaringClass () == foreignPackageClassInfo .clazz && !Modifier .isPublic ( setter .getModifiers () ) ) {
296
- foreignPackageClassInfo .setters .add ( setter );
297
- }
298
- }
299
- if ( foreignPackageClassInfo .getters .isEmpty () && foreignPackageClassInfo .setters .isEmpty () ) {
300
- iterator .remove ();
301
- }
302
- }
286
+ final List <BridgeMembersClassInfo > bridgeMembersClassInfos = createBridgeMembersClassInfos ( clazz , getters , setters , propertyNames );
303
287
304
288
Class <?> superClass = Object .class ;
305
- for ( int i = foreignPackageClassInfos .size () - 1 ; i >= 0 ; i -- ) {
306
- final ForeignPackageClassInfo foreignPackageClassInfo = foreignPackageClassInfos .get ( i );
289
+ for ( int i = bridgeMembersClassInfos .size () - 1 ; i >= 0 ; i -- ) {
290
+ final BridgeMembersClassInfo bridgeMembersClassInfo = bridgeMembersClassInfos .get ( i );
307
291
final Class <?> newSuperClass = superClass ;
308
292
309
- final String suffix = OPTIMIZER_PROXY_BRIDGE_NAMING_SUFFIX + encodeName ( foreignPackageClassInfo .propertyNames , foreignPackageClassInfo .getters , foreignPackageClassInfo .setters );
310
293
superClass = byteBuddyState .load (
311
- foreignPackageClassInfo .clazz ,
294
+ bridgeMembersClassInfo .clazz ,
312
295
byteBuddy -> {
313
296
DynamicType .Builder <?> builder = byteBuddy .with (
314
297
new NamingStrategy .SuffixingRandom (
315
- suffix ,
298
+ OPTIMIZER_PROXY_BRIDGE_NAMING_SUFFIX ,
316
299
new NamingStrategy .SuffixingRandom .BaseNameResolver .ForFixedValue (
317
- foreignPackageClassInfo .clazz .getName () )
300
+ bridgeMembersClassInfo .clazz .getName () )
318
301
)
319
302
).subclass ( newSuperClass );
320
- for ( Member getter : foreignPackageClassInfo .getters ) {
321
- final Class <?> getterType ;
322
- if ( getter instanceof Field ) {
323
- getterType = ( (Field ) getter ).getType ();
324
- }
325
- else {
326
- getterType = ( (Method ) getter ).getReturnType ();
303
+ for ( Member getter : bridgeMembersClassInfo .getters ) {
304
+ if ( !Modifier .isPublic ( getter .getModifiers () ) ) {
305
+ final Class <?> getterType ;
306
+ if ( getter instanceof Field ) {
307
+ getterType = ( (Field ) getter ).getType ();
308
+ }
309
+ else {
310
+ getterType = ( (Method ) getter ).getReturnType ();
311
+ }
312
+
313
+ builder = builder .defineMethod (
314
+ "get_" + getter .getName (),
315
+ TypeDescription .Generic .OfNonGenericType .ForLoadedType .of (
316
+ getterType
317
+ ),
318
+ Opcodes .ACC_PROTECTED | Opcodes .ACC_STATIC
319
+ )
320
+ .withParameter ( bridgeMembersClassInfo .clazz )
321
+ .intercept (
322
+ new Implementation .Simple (
323
+ new GetFieldOnArgument (
324
+ getter
325
+ )
326
+ )
327
+ );
327
328
}
328
-
329
- builder = builder .defineMethod (
330
- "get_" + getter .getName (),
331
- TypeDescription .Generic .OfNonGenericType .ForLoadedType .of (
332
- getterType
333
- ),
334
- Opcodes .ACC_PROTECTED | Opcodes .ACC_STATIC
335
- )
336
- .withParameter ( foreignPackageClassInfo .clazz )
337
- .intercept (
338
- new Implementation .Simple (
339
- new GetFieldOnArgument (
340
- getter
341
- )
342
- )
343
- );
344
329
}
345
- for ( Member setter : foreignPackageClassInfo .setters ) {
346
- final Class <?> setterType ;
347
- if ( setter instanceof Field ) {
348
- setterType = ( (Field ) setter ).getType ();
349
- }
350
- else {
351
- setterType = ( (Method ) setter ).getParameterTypes ()[0 ];
330
+ for ( Member setter : bridgeMembersClassInfo .setters ) {
331
+ if ( !Modifier .isPublic ( setter .getModifiers () ) ) {
332
+ final Class <?> setterType ;
333
+ if ( setter instanceof Field ) {
334
+ setterType = ( (Field ) setter ).getType ();
335
+ }
336
+ else {
337
+ setterType = ( (Method ) setter ).getParameterTypes ()[0 ];
338
+ }
339
+
340
+ builder = builder .defineMethod (
341
+ "set_" + setter .getName (),
342
+ TypeDescription .Generic .VOID ,
343
+ Opcodes .ACC_PROTECTED | Opcodes .ACC_STATIC
344
+ )
345
+ .withParameter ( bridgeMembersClassInfo .clazz )
346
+ .withParameter ( setterType )
347
+ .intercept (
348
+ new Implementation .Simple (
349
+ new SetFieldOnArgument (
350
+ setter
351
+ )
352
+ )
353
+ );
352
354
}
353
-
354
- builder = builder .defineMethod (
355
- "set_" + setter .getName (),
356
- TypeDescription .Generic .VOID ,
357
- Opcodes .ACC_PROTECTED | Opcodes .ACC_STATIC
358
- )
359
- .withParameter ( foreignPackageClassInfo .clazz )
360
- .withParameter ( setterType )
361
- .intercept (
362
- new Implementation .Simple (
363
- new SetFieldOnArgument (
364
- setter
365
- )
366
- )
367
- );
368
355
}
369
356
370
357
return builder ;
@@ -374,10 +361,10 @@ private Class<?> determineAccessOptimizerSuperClass(Class<?> clazz, Member[] get
374
361
for ( int j = 0 ; j < getters .length ; j ++ ) {
375
362
final Member getter = getters [j ];
376
363
final Member setter = setters [j ];
377
- if ( foreignPackageClassInfo .getters .contains ( getter ) ) {
364
+ if ( bridgeMembersClassInfo .getters .contains ( getter ) && ! Modifier . isPublic ( getter . getModifiers () ) ) {
378
365
getters [j ] = new ForeignPackageMember ( superClass , getter );
379
366
}
380
- if ( foreignPackageClassInfo .setters .contains ( setter ) ) {
367
+ if ( bridgeMembersClassInfo .setters .contains ( setter ) && ! Modifier . isPublic ( setter . getModifiers () ) ) {
381
368
setters [j ] = new ForeignPackageMember ( superClass , setter );
382
369
}
383
370
}
@@ -565,16 +552,31 @@ private boolean is64BitType(Class<?> type) {
565
552
}
566
553
}
567
554
568
- private List <ForeignPackageClassInfo > createForeignPackageClassInfos (Class <?> clazz ) {
569
- final List <ForeignPackageClassInfo > foreignPackageClassInfos = new ArrayList <>();
555
+ private List <BridgeMembersClassInfo > createBridgeMembersClassInfos (
556
+ Class <?> clazz ,
557
+ Member [] getters ,
558
+ Member [] setters ,
559
+ String [] propertyNames ) {
560
+ final List <BridgeMembersClassInfo > bridgeMembersClassInfos = new ArrayList <>();
570
561
Class <?> c = clazz .getSuperclass ();
571
562
while (c != Object .class ) {
572
- if ( !c .getPackageName ().equals ( clazz .getPackageName () ) ) {
573
- foreignPackageClassInfos .add ( new ForeignPackageClassInfo ( c ) );
563
+ final BridgeMembersClassInfo bridgeMemberClassInfo = new BridgeMembersClassInfo ( c );
564
+ for ( int i = 0 ; i < getters .length ; i ++ ) {
565
+ final Member getter = getters [i ];
566
+ final Member setter = setters [i ];
567
+ if ( getter .getDeclaringClass () == c && !Modifier .isPublic ( getter .getModifiers () )
568
+ || setter .getDeclaringClass () == c && !Modifier .isPublic ( setter .getModifiers () ) ) {
569
+ bridgeMemberClassInfo .getters .add ( getter );
570
+ bridgeMemberClassInfo .setters .add ( setter );
571
+ bridgeMemberClassInfo .propertyNames .add ( propertyNames [i ] );
572
+ }
573
+ }
574
+ if ( !bridgeMemberClassInfo .propertyNames .isEmpty () ) {
575
+ bridgeMembersClassInfos .add ( bridgeMemberClassInfo );
574
576
}
575
577
c = c .getSuperclass ();
576
578
}
577
- return foreignPackageClassInfos ;
579
+ return bridgeMembersClassInfos ;
578
580
}
579
581
580
582
public ByteBuddyProxyHelper getByteBuddyProxyHelper () {
0 commit comments