3030import java .lang .reflect .Constructor ;
3131import java .lang .reflect .Method ;
3232import java .lang .reflect .Modifier ;
33- import java .util .ArrayList ;
3433import java .util .List ;
3534import java .util .Map ;
3635import java .util .WeakHashMap ;
3736import java .util .concurrent .ConcurrentHashMap ;
38- import lombok .experimental .UtilityClass ;
37+ import java .util .stream .Collectors ;
38+ import java .util .stream .Stream ;
3939import org .objectweb .asm .ClassWriter ;
4040import org .objectweb .asm .MethodVisitor ;
4141import org .objectweb .asm .Opcodes ;
5959 *
6060 * @author Javier Godoy / Flowing Code
6161 */
62- @ UtilityClass
6362final class ClassInstrumentationUtil {
6463
65- private static final Map <ClassLoader , InstrumentedClassLoader > classLoaderCache =
66- new WeakHashMap <>();
64+ private final int version ;
65+
66+ private static final Map <ClassLoader , InstrumentedClassLoader > classLoaderCache = new WeakHashMap <>();
67+
68+ ClassInstrumentationUtil (int version ) {
69+ this .version = version ;
70+ }
6771
6872 /**
6973 * Creates and returns an instance of a dynamically instrumented class that extends the specified
@@ -144,34 +148,54 @@ public <T extends Component> Class<? extends T> instrumentClass(Class<T> parent)
144148 }
145149 }
146150
147- private static boolean needsInstrumentation (Class <?> parent ) {
151+ private boolean needsInstrumentation (Class <?> parent ) {
148152 return !getInstrumentableMethods (parent ).isEmpty ();
149153 }
150154
151- private static List <Method > getInstrumentableMethods (Class <?> parent ) {
152- List <Method > methods = new ArrayList <>();
153- for (Method method : parent .getDeclaredMethods ()) {
154- if (!Modifier .isStatic (method .getModifiers ()) && !Modifier .isPrivate (method .getModifiers ())) {
155+ private boolean hasLegacyVaadin () {
156+ return version <= 24 ;
157+ }
158+
159+ private static Stream <Method > getDeclaredCallables (Class <?> parent ) {
160+ return Stream .of (parent .getDeclaredMethods ()).filter (method -> {
161+ int modifiers = method .getModifiers ();
162+ if (!Modifier .isStatic (modifiers ) && !Modifier .isPrivate (modifiers )) {
155163 boolean isCallable = method .isAnnotationPresent (ClientCallable .class );
156164 boolean isLegacyCallable = method .isAnnotationPresent (LegacyClientCallable .class );
157- if (isCallable || isLegacyCallable ) {
158- boolean hasJsonValueReturn = JsonValue .class .isAssignableFrom (method .getReturnType ());
159- boolean hasJsonValueParams = hasJsonValueParameters (method );
160-
161- if (isCallable && hasJsonValueParams ) {
162- throw new IllegalArgumentException (String .format (
163- "Instrumented method '%s' in class '%s' has JsonValue arguments and must be annotated with @%s instead of @ClientCallable" ,
164- method .getName (), method .getDeclaringClass ().getName (),
165- LegacyClientCallable .class .getName ()));
166- } else if (isCallable && hasJsonValueReturn ) {
167- methods .add (method );
168- } else if (isLegacyCallable ) {
169- methods .add (method );
170- }
165+ return isCallable || isLegacyCallable ;
166+ }
167+ return false ;
168+ });
169+ }
170+
171+ private List <Method > getInstrumentableMethods (Class <?> parent ) {
172+ return getDeclaredCallables (parent ).filter (method -> {
173+ boolean isCallable = method .isAnnotationPresent (ClientCallable .class );
174+ boolean isLegacyCallable = method .isAnnotationPresent (LegacyClientCallable .class );
175+
176+ if (hasLegacyVaadin ()) {
177+ return isLegacyCallable ;
178+ }
179+
180+ if (isCallable || isLegacyCallable ) {
181+ boolean hasJsonValueReturn = JsonValue .class .isAssignableFrom (method .getReturnType ());
182+ boolean hasJsonValueParams = hasJsonValueParameters (method );
183+
184+ if (isCallable && hasJsonValueParams ) {
185+ throw new IllegalArgumentException (String .format (
186+ "Instrumented method '%s' in class '%s' has JsonValue arguments and must be annotated with @%s instead of @ClientCallable" ,
187+ method .getName (), method .getDeclaringClass ().getName (),
188+ LegacyClientCallable .class .getName ()));
189+ } else if (isCallable && hasJsonValueReturn ) {
190+ return true ;
191+ } else if (isLegacyCallable ) {
192+ return true ;
171193 }
172194 }
173- }
174- return methods ;
195+
196+ return false ;
197+
198+ }).collect (Collectors .toList ());
175199 }
176200
177201 private static boolean hasJsonValueParameters (Method method ) {
@@ -185,8 +209,7 @@ private static boolean hasJsonValueParameters(Method method) {
185209
186210 private <T extends Component > Class <? extends T > createInstrumentedClass (Class <T > parent ,
187211 String className ) throws Exception {
188- InstrumentedClassLoader classLoader =
189- getOrCreateInstrumentedClassLoader (parent .getClassLoader ());
212+ InstrumentedClassLoader classLoader = getOrCreateInstrumentedClassLoader (parent .getClassLoader ());
190213 return classLoader .defineInstrumentedClass (className , parent ).asSubclass (parent );
191214 }
192215
@@ -196,7 +219,7 @@ private InstrumentedClassLoader getOrCreateInstrumentedClassLoader(ClassLoader p
196219 }
197220 }
198221
199- private static final class InstrumentedClassLoader extends ClassLoader {
222+ private final class InstrumentedClassLoader extends ClassLoader {
200223
201224 private final Map <Class <?>, Class <?>> instrumentedClassCache = new ConcurrentHashMap <>();
202225
@@ -244,8 +267,8 @@ private void generateClientCallableOverrides(ClassWriter cw, Class<?> parent,
244267 }
245268
246269 private void generateMethodOverride (ClassWriter cw , Method method , String internalParentName ) {
247- boolean hasJsonValueReturn = JsonValue .class .isAssignableFrom (method .getReturnType ());
248- boolean hasJsonValueParams = hasJsonValueParameters (method );
270+ boolean hasJsonValueReturn = ! hasLegacyVaadin () && JsonValue .class .isAssignableFrom (method .getReturnType ());
271+ boolean hasJsonValueParams = ! hasLegacyVaadin () && hasJsonValueParameters (method );
249272
250273 String overrideDescriptor = getMethodDescriptor (method , hasJsonValueParams );
251274 String superDescriptor = getMethodDescriptor (method , false );
@@ -300,7 +323,7 @@ private void generateMethodOverride(ClassWriter cw, Method method, String intern
300323 false );
301324 }
302325
303- // Return converted result or void
326+ // Return result or void
304327 if (method .getReturnType () == Void .TYPE ) {
305328 mv .visitInsn (Opcodes .RETURN );
306329 } else {
0 commit comments