1
1
/*
2
- * Copyright 2002-2021 the original author or authors.
2
+ * Copyright 2002-2022 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
@@ -203,8 +203,25 @@ void copyPropertiesWithDifferentTypes2() throws Exception {
203
203
assertThat (tb2 .getTouchy ().equals (tb .getTouchy ())).as ("Touchy copied" ).isTrue ();
204
204
}
205
205
206
+ /**
207
+ * {@code Integer} can be copied to {@code Number}.
208
+ */
206
209
@ Test
207
- void copyPropertiesHonorsGenericTypeMatches () {
210
+ void copyPropertiesFromSubTypeToSuperType () {
211
+ IntegerHolder integerHolder = new IntegerHolder ();
212
+ integerHolder .setNumber (42 );
213
+ NumberHolder numberHolder = new NumberHolder ();
214
+
215
+ BeanUtils .copyProperties (integerHolder , numberHolder );
216
+ assertThat (integerHolder .getNumber ()).isEqualTo (42 );
217
+ assertThat (numberHolder .getNumber ()).isEqualTo (42 );
218
+ }
219
+
220
+ /**
221
+ * {@code List<Integer>} can be copied to {@code List<Integer>}.
222
+ */
223
+ @ Test
224
+ void copyPropertiesHonorsGenericTypeMatchesFromIntegerToInteger () {
208
225
IntegerListHolder1 integerListHolder1 = new IntegerListHolder1 ();
209
226
integerListHolder1 .getList ().add (42 );
210
227
IntegerListHolder2 integerListHolder2 = new IntegerListHolder2 ();
@@ -214,6 +231,68 @@ void copyPropertiesHonorsGenericTypeMatches() {
214
231
assertThat (integerListHolder2 .getList ()).containsOnly (42 );
215
232
}
216
233
234
+ /**
235
+ * {@code List<?>} can be copied to {@code List<?>}.
236
+ */
237
+ @ Test
238
+ void copyPropertiesHonorsGenericTypeMatchesFromWildcardToWildcard () {
239
+ List <?> list = Arrays .asList ("foo" , 42 );
240
+ WildcardListHolder1 wildcardListHolder1 = new WildcardListHolder1 ();
241
+ wildcardListHolder1 .setList (list );
242
+ WildcardListHolder2 wildcardListHolder2 = new WildcardListHolder2 ();
243
+ assertThat (wildcardListHolder2 .getList ()).isEmpty ();
244
+
245
+ BeanUtils .copyProperties (wildcardListHolder1 , wildcardListHolder2 );
246
+ assertThat (wildcardListHolder1 .getList ()).isEqualTo (list );
247
+ assertThat (wildcardListHolder2 .getList ()).isEqualTo (list );
248
+ }
249
+
250
+ /**
251
+ * {@code List<Integer>} can be copied to {@code List<?>}.
252
+ */
253
+ @ Test
254
+ void copyPropertiesHonorsGenericTypeMatchesFromIntegerToWildcard () {
255
+ IntegerListHolder1 integerListHolder1 = new IntegerListHolder1 ();
256
+ integerListHolder1 .getList ().add (42 );
257
+ WildcardListHolder2 wildcardListHolder2 = new WildcardListHolder2 ();
258
+
259
+ BeanUtils .copyProperties (integerListHolder1 , wildcardListHolder2 );
260
+ assertThat (integerListHolder1 .getList ()).containsOnly (42 );
261
+ assertThat (wildcardListHolder2 .getList ()).isEqualTo (Arrays .asList (42 ));
262
+ }
263
+
264
+ /**
265
+ * {@code List<Integer>} can be copied to {@code List<? extends Number>}.
266
+ */
267
+ @ Test
268
+ void copyPropertiesHonorsGenericTypeMatchesForUpperBoundedWildcard () {
269
+ IntegerListHolder1 integerListHolder1 = new IntegerListHolder1 ();
270
+ integerListHolder1 .getList ().add (42 );
271
+ NumberUpperBoundedWildcardListHolder numberListHolder = new NumberUpperBoundedWildcardListHolder ();
272
+
273
+ BeanUtils .copyProperties (integerListHolder1 , numberListHolder );
274
+ assertThat (integerListHolder1 .getList ()).containsOnly (42 );
275
+ assertThat (numberListHolder .getList ()).hasSize (1 );
276
+ assertThat (numberListHolder .getList ().contains (Integer .valueOf (42 ))).isTrue ();
277
+ }
278
+
279
+ /**
280
+ * {@code Number} can NOT be copied to {@code Integer}.
281
+ */
282
+ @ Test
283
+ void copyPropertiesDoesNotCopyeFromSuperTypeToSubType () {
284
+ NumberHolder numberHolder = new NumberHolder ();
285
+ numberHolder .setNumber (Integer .valueOf (42 ));
286
+ IntegerHolder integerHolder = new IntegerHolder ();
287
+
288
+ BeanUtils .copyProperties (numberHolder , integerHolder );
289
+ assertThat (numberHolder .getNumber ()).isEqualTo (42 );
290
+ assertThat (integerHolder .getNumber ()).isNull ();
291
+ }
292
+
293
+ /**
294
+ * {@code List<Integer>} can NOT be copied to {@code List<Long>}.
295
+ */
217
296
@ Test
218
297
void copyPropertiesDoesNotHonorGenericTypeMismatches () {
219
298
IntegerListHolder1 integerListHolder = new IntegerListHolder1 ();
@@ -225,6 +304,20 @@ void copyPropertiesDoesNotHonorGenericTypeMismatches() {
225
304
assertThat (longListHolder .getList ()).isEmpty ();
226
305
}
227
306
307
+ /**
308
+ * {@code List<Integer>} can NOT be copied to {@code List<Number>}.
309
+ */
310
+ @ Test
311
+ void copyPropertiesDoesNotHonorGenericTypeMismatchesFromSubTypeToSuperType () {
312
+ IntegerListHolder1 integerListHolder = new IntegerListHolder1 ();
313
+ integerListHolder .getList ().add (42 );
314
+ NumberListHolder numberListHolder = new NumberListHolder ();
315
+
316
+ BeanUtils .copyProperties (integerListHolder , numberListHolder );
317
+ assertThat (integerListHolder .getList ()).containsOnly (42 );
318
+ assertThat (numberListHolder .getList ()).isEmpty ();
319
+ }
320
+
228
321
@ Test // gh-26531
229
322
void copyPropertiesIgnoresGenericsIfSourceOrTargetHasUnresolvableGenerics () throws Exception {
230
323
Order original = new Order ("test" , Arrays .asList ("foo" , "bar" ));
@@ -413,6 +506,90 @@ private void assertSignatureEquals(Method desiredMethod, String signature) {
413
506
}
414
507
415
508
509
+ @ SuppressWarnings ("unused" )
510
+ private static class NumberHolder {
511
+
512
+ private Number number ;
513
+
514
+ public Number getNumber () {
515
+ return number ;
516
+ }
517
+
518
+ public void setNumber (Number number ) {
519
+ this .number = number ;
520
+ }
521
+ }
522
+
523
+ @ SuppressWarnings ("unused" )
524
+ private static class IntegerHolder {
525
+
526
+ private Integer number ;
527
+
528
+ public Integer getNumber () {
529
+ return number ;
530
+ }
531
+
532
+ public void setNumber (Integer number ) {
533
+ this .number = number ;
534
+ }
535
+ }
536
+
537
+ @ SuppressWarnings ("unused" )
538
+ private static class WildcardListHolder1 {
539
+
540
+ private List <?> list = new ArrayList <>();
541
+
542
+ public List <?> getList () {
543
+ return list ;
544
+ }
545
+
546
+ public void setList (List <?> list ) {
547
+ this .list = list ;
548
+ }
549
+ }
550
+
551
+ @ SuppressWarnings ("unused" )
552
+ private static class WildcardListHolder2 {
553
+
554
+ private List <?> list = new ArrayList <>();
555
+
556
+ public List <?> getList () {
557
+ return list ;
558
+ }
559
+
560
+ public void setList (List <?> list ) {
561
+ this .list = list ;
562
+ }
563
+ }
564
+
565
+ @ SuppressWarnings ("unused" )
566
+ private static class NumberUpperBoundedWildcardListHolder {
567
+
568
+ private List <? extends Number > list = new ArrayList <>();
569
+
570
+ public List <? extends Number > getList () {
571
+ return list ;
572
+ }
573
+
574
+ public void setList (List <? extends Number > list ) {
575
+ this .list = list ;
576
+ }
577
+ }
578
+
579
+ @ SuppressWarnings ("unused" )
580
+ private static class NumberListHolder {
581
+
582
+ private List <Number > list = new ArrayList <>();
583
+
584
+ public List <Number > getList () {
585
+ return list ;
586
+ }
587
+
588
+ public void setList (List <Number > list ) {
589
+ this .list = list ;
590
+ }
591
+ }
592
+
416
593
@ SuppressWarnings ("unused" )
417
594
private static class IntegerListHolder1 {
418
595
0 commit comments