1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package com.codebox.bean;
16
17 import java.lang.reflect.Modifier;
18
19 import net.bytebuddy.ByteBuddy;
20 import net.bytebuddy.NamingStrategy;
21 import net.bytebuddy.description.NamedElement;
22 import net.bytebuddy.description.modifier.Visibility;
23 import net.bytebuddy.description.type.TypeDescription;
24 import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
25 import net.bytebuddy.implementation.EqualsMethod;
26 import net.bytebuddy.implementation.HashCodeMethod;
27 import net.bytebuddy.implementation.MethodDelegation;
28 import net.bytebuddy.implementation.ToStringMethod;
29 import net.bytebuddy.matcher.ElementMatchers;
30
31
32
33
34
35 public enum JavaBeanTester {
36
37
38 ;
39
40
41
42
43
44
45
46
47
48
49
50 public static <T> JavaBeanTesterBuilder<T, ?> builder(final Class<T> clazz) {
51
52 if (Modifier.isFinal(clazz.getModifiers())) {
53 return new JavaBeanTesterBuilder<>(clazz, Object.class);
54 }
55
56
57 Class<? extends T> loaded = new ByteBuddy().with(new NamingStrategy.AbstractBase() {
58 @Override
59 protected String name(TypeDescription superClass) {
60 return clazz.getPackageName() + ".ByteBuddyExt" + superClass.getSimpleName();
61 }
62 }).subclass(clazz).method(ElementMatchers.isEquals()).intercept(EqualsMethod.requiringSuperClassEquality())
63 .method(ElementMatchers.isHashCode()).intercept(HashCodeMethod.usingSuperClassOffset())
64 .method(ElementMatchers.isToString()).intercept(ToStringMethod.prefixedBySimpleClassName())
65 .method(ElementMatchers.named("canEqual")).intercept(MethodDelegation.to(CanEqualInterceptor.class))
66 .defineField("javabeanExtension", String.class, Visibility.PACKAGE_PRIVATE).make()
67 .load(clazz.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER).getLoaded();
68
69
70 return builder(clazz, loaded);
71 }
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87 public static <T, E> JavaBeanTesterBuilder<T, E> builder(final Class<T> clazz, final Class<E> extension) {
88 return new JavaBeanTesterBuilder<>(clazz, extension);
89 }
90
91
92
93
94 public static class CanEqualInterceptor {
95
96
97
98
99
100
101
102
103 public static boolean canEqual(final Object object) {
104 return object instanceof NamedElement.WithRuntimeName;
105 }
106
107 }
108 }