/** * A method reference is compilable if it has been resolved to a reflectively accessible method * and the child nodes (arguments to the method) are also compilable. */ @Override public boolean isCompilable() { CachedMethodExecutor executorToCheck = this.cachedExecutor; if (executorToCheck == null || executorToCheck.hasProxyTarget() || !(executorToCheck.get() instanceof ReflectiveMethodExecutor)) { return false; } for (SpelNodeImpl child : this.children) { if (!child.isCompilable()) { return false; } } ReflectiveMethodExecutor executor = (ReflectiveMethodExecutor) executorToCheck.get(); if (executor.didArgumentConversionOccur()) { return false; } Class<?> clazz = executor.getMethod().getDeclaringClass(); if (!Modifier.isPublic(clazz.getModifiers()) && executor.getPublicDeclaringClass() == null) { return false; } return true; }
return new ReflectiveMethodExecutor(method); return new ReflectiveMethodExecutor(closeMatch); throw new SpelEvaluationException(SpelMessage.MULTIPLE_POSSIBLE_METHODS, name); return new ReflectiveMethodExecutor(matchRequiringConversion);
/** * Find the first public class in the methods declaring class hierarchy that declares this method. * Sometimes the reflective method discovery logic finds a suitable method that can easily be * called via reflection but cannot be called from generated code when compiling the expression * because of visibility restrictions. For example if a non-public class overrides toString(), * this helper method will walk up the type hierarchy to find the first public type that declares * the method (if there is one!). For toString() it may walk as far as Object. */ @Nullable public Class<?> getPublicDeclaringClass() { if (!this.computedPublicDeclaringClass) { this.publicDeclaringClass = discoverPublicDeclaringClass(this.originalMethod, this.originalMethod.getDeclaringClass()); this.computedPublicDeclaringClass = true; } return this.publicDeclaringClass; }
Method method = methodExecutor.getMethod(); boolean isStaticMethod = Modifier.isStatic(method.getModifiers()); String descriptor = cf.lastDescriptor(); Class<?> publicDeclaringClass = methodExecutor.getPublicDeclaringClass(); Assert.state(publicDeclaringClass != null, "No public declaring class"); classDesc = publicDeclaringClass.getName().replace('.', '/');
private void updateExitTypeDescriptor() { CachedMethodExecutor executorToCheck = this.cachedExecutor; if (executorToCheck != null && executorToCheck.get() instanceof ReflectiveMethodExecutor) { Method method = ((ReflectiveMethodExecutor) executorToCheck.get()).getMethod(); String descriptor = CodeFlow.toDescriptor(method.getReturnType()); if (this.nullSafe && CodeFlow.isPrimitive(descriptor)) { this.originalPrimitiveExitTypeDescriptor = descriptor; this.exitTypeDescriptor = CodeFlow.toBoxedDescriptor(descriptor); } else { this.exitTypeDescriptor = descriptor; } } }
Method method = methodExecutor.getMethod(); boolean isStaticMethod = Modifier.isStatic(method.getModifiers()); String descriptor = cf.lastDescriptor(); Class<?> publicDeclaringClass = methodExecutor.getPublicDeclaringClass(); Assert.state(publicDeclaringClass != null, "No public declaring class"); classDesc = publicDeclaringClass.getName().replace('.', '/');
private void updateExitTypeDescriptor() { CachedMethodExecutor executorToCheck = this.cachedExecutor; if (executorToCheck != null && executorToCheck.get() instanceof ReflectiveMethodExecutor) { Method method = ((ReflectiveMethodExecutor) executorToCheck.get()).getMethod(); String descriptor = CodeFlow.toDescriptor(method.getReturnType()); if (this.nullSafe && CodeFlow.isPrimitive(descriptor)) { this.originalPrimitiveExitTypeDescriptor = descriptor; this.exitTypeDescriptor = CodeFlow.toBoxedDescriptor(descriptor); } else { this.exitTypeDescriptor = descriptor; } } }
/** * A method reference is compilable if it has been resolved to a reflectively accessible method * and the child nodes (arguments to the method) are also compilable. */ @Override public boolean isCompilable() { CachedMethodExecutor executorToCheck = this.cachedExecutor; if (executorToCheck == null || executorToCheck.hasProxyTarget() || !(executorToCheck.get() instanceof ReflectiveMethodExecutor)) { return false; } for (SpelNodeImpl child : this.children) { if (!child.isCompilable()) { return false; } } ReflectiveMethodExecutor executor = (ReflectiveMethodExecutor) executorToCheck.get(); if (executor.didArgumentConversionOccur()) { return false; } Class<?> clazz = executor.getMethod().getDeclaringClass(); if (!Modifier.isPublic(clazz.getModifiers()) && executor.getPublicDeclaringClass() == null) { return false; } return true; }
Method method = methodExecutor.getMethod(); boolean isStaticMethod = Modifier.isStatic(method.getModifiers()); String descriptor = cf.lastDescriptor(); Class<?> publicDeclaringClass = methodExecutor.getPublicDeclaringClass(); Assert.state(publicDeclaringClass != null, "No public declaring class"); classDesc = publicDeclaringClass.getName().replace('.', '/');
public OmitAnnotationsMethodExecutor(ReflectiveMethodExecutor original) { super(original.getMethod()); this.method = original.getMethod(); if (method.isVarArgs()) { Class<?>[] paramTypes = method.getParameterTypes(); this.varargsPosition = paramTypes.length - 1; } else { this.varargsPosition = null; } }
@Nullable private Class<?> discoverPublicDeclaringClass(Method method, Class<?> clazz) { if (Modifier.isPublic(clazz.getModifiers())) { try { clazz.getDeclaredMethod(method.getName(), method.getParameterTypes()); return clazz; } catch (NoSuchMethodException ex) { // Continue below... } } if (clazz.getSuperclass() != null) { return discoverPublicDeclaringClass(method, clazz.getSuperclass()); } return null; }
return new ReflectiveMethodExecutor(method); return new ReflectiveMethodExecutor(closeMatch); throw new SpelEvaluationException(SpelMessage.MULTIPLE_POSSIBLE_METHODS, name); return new ReflectiveMethodExecutor(matchRequiringConversion);
/** * A method reference is compilable if it has been resolved to a reflectively accessible method * and the child nodes (arguments to the method) are also compilable. */ @Override public boolean isCompilable() { CachedMethodExecutor executorToCheck = this.cachedExecutor; if (executorToCheck == null || executorToCheck.hasProxyTarget() || !(executorToCheck.get() instanceof ReflectiveMethodExecutor)) { return false; } for (SpelNodeImpl child : this.children) { if (!child.isCompilable()) { return false; } } ReflectiveMethodExecutor executor = (ReflectiveMethodExecutor) executorToCheck.get(); if (executor.didArgumentConversionOccur()) { return false; } Class<?> clazz = executor.getMethod().getDeclaringClass(); if (!Modifier.isPublic(clazz.getModifiers()) && executor.getPublicDeclaringClass() == null) { return false; } return true; }
private void updateExitTypeDescriptor() { CachedMethodExecutor executorToCheck = this.cachedExecutor; if (executorToCheck != null && executorToCheck.get() instanceof ReflectiveMethodExecutor) { Method method = ((ReflectiveMethodExecutor) executorToCheck.get()).getMethod(); String descriptor = CodeFlow.toDescriptor(method.getReturnType()); if (this.nullSafe && CodeFlow.isPrimitive(descriptor)) { this.originalPrimitiveExitTypeDescriptor = descriptor; this.exitTypeDescriptor = CodeFlow.toBoxedDescriptor(descriptor); } else { this.exitTypeDescriptor = descriptor; } } }
/** * Find the first public class in the methods declaring class hierarchy that declares this method. * Sometimes the reflective method discovery logic finds a suitable method that can easily be * called via reflection but cannot be called from generated code when compiling the expression * because of visibility restrictions. For example if a non-public class overrides toString(), * this helper method will walk up the type hierarchy to find the first public type that declares * the method (if there is one!). For toString() it may walk as far as Object. */ @Nullable public Class<?> getPublicDeclaringClass() { if (!this.computedPublicDeclaringClass) { this.publicDeclaringClass = discoverPublicDeclaringClass(this.originalMethod, this.originalMethod.getDeclaringClass()); this.computedPublicDeclaringClass = true; } return this.publicDeclaringClass; }
return new ReflectiveMethodExecutor(method); return new ReflectiveMethodExecutor(closeMatch); throw new SpelEvaluationException(SpelMessage.MULTIPLE_POSSIBLE_METHODS, name); return new ReflectiveMethodExecutor(matchRequiringConversion);
@Nullable private Class<?> discoverPublicDeclaringClass(Method method, Class<?> clazz) { if (Modifier.isPublic(clazz.getModifiers())) { try { clazz.getDeclaredMethod(method.getName(), method.getParameterTypes()); return clazz; } catch (NoSuchMethodException ex) { // Continue below... } } if (clazz.getSuperclass() != null) { return discoverPublicDeclaringClass(method, clazz.getSuperclass()); } return null; }
/** * Find the first public class in the methods declaring class hierarchy that declares this method. * Sometimes the reflective method discovery logic finds a suitable method that can easily be * called via reflection but cannot be called from generated code when compiling the expression * because of visibility restrictions. For example if a non-public class overrides toString(), * this helper method will walk up the type hierarchy to find the first public type that declares * the method (if there is one!). For toString() it may walk as far as Object. */ @Nullable public Class<?> getPublicDeclaringClass() { if (!this.computedPublicDeclaringClass) { this.publicDeclaringClass = discoverPublicDeclaringClass(this.method, this.method.getDeclaringClass()); this.computedPublicDeclaringClass = true; } return this.publicDeclaringClass; }
@Nullable private Class<?> discoverPublicDeclaringClass(Method method, Class<?> clazz) { if (Modifier.isPublic(clazz.getModifiers())) { try { clazz.getDeclaredMethod(method.getName(), method.getParameterTypes()); return clazz; } catch (NoSuchMethodException ex) { // Continue below... } } if (clazz.getSuperclass() != null) { return discoverPublicDeclaringClass(method, clazz.getSuperclass()); } return null; }