diff --git a/.DS_Store b/.DS_Store index 486ca695a..60a1e0082 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/libs/chat-workflow-coverage/pom.xml b/libs/chat-workflow-coverage/pom.xml index 970046b7c..549bcd6df 100644 --- a/libs/chat-workflow-coverage/pom.xml +++ b/libs/chat-workflow-coverage/pom.xml @@ -5,6 +5,7 @@ chat-workflow-coverage Chat Workflow Coverage Report Used For Jacoco + pom org.finos.springbot @@ -18,7 +19,7 @@ 1.8 - + symphony-ci diff --git a/libs/chat-workflow-testing/src/main/java/org/finos/springbot/tests/controller/AbstractHandlerMappingTest.java b/libs/chat-workflow-testing/src/main/java/org/finos/springbot/tests/controller/AbstractHandlerMappingTest.java index f13fc3f56..48d7b5a23 100644 --- a/libs/chat-workflow-testing/src/main/java/org/finos/springbot/tests/controller/AbstractHandlerMappingTest.java +++ b/libs/chat-workflow-testing/src/main/java/org/finos/springbot/tests/controller/AbstractHandlerMappingTest.java @@ -27,7 +27,8 @@ @ExtendWith(SpringExtension.class) @TestPropertySource( properties = { - "bdk.bot.username="+AbstractHandlerMappingTest.BOT_NAME + "bdk.bot.username="+AbstractHandlerMappingTest.BOT_NAME, + "logging.level.org.finos.springbot=TRACE" }) public abstract class AbstractHandlerMappingTest { diff --git a/libs/chat-workflow/src/main/java/org/finos/springbot/workflow/java/mapping/AbstractSpringComponentHandlerMapping.java b/libs/chat-workflow/src/main/java/org/finos/springbot/workflow/java/mapping/AbstractSpringComponentHandlerMapping.java index 2564ec355..d29a73f5c 100644 --- a/libs/chat-workflow/src/main/java/org/finos/springbot/workflow/java/mapping/AbstractSpringComponentHandlerMapping.java +++ b/libs/chat-workflow/src/main/java/org/finos/springbot/workflow/java/mapping/AbstractSpringComponentHandlerMapping.java @@ -235,10 +235,6 @@ public void register(T mapping, Object handler, Method method) { } protected ChatHandlerMethod createHandlerMethod(Object handler, Method method) { - if (handler instanceof String) { - return new ChatHandlerMethod((String) handler, - obtainApplicationContext().getAutowireCapableBeanFactory(), method); - } return new ChatHandlerMethod(handler, method); } diff --git a/libs/chat-workflow/src/main/java/org/finos/springbot/workflow/java/mapping/ChatHandlerMethod.java b/libs/chat-workflow/src/main/java/org/finos/springbot/workflow/java/mapping/ChatHandlerMethod.java index e5b923e5c..99664b569 100644 --- a/libs/chat-workflow/src/main/java/org/finos/springbot/workflow/java/mapping/ChatHandlerMethod.java +++ b/libs/chat-workflow/src/main/java/org/finos/springbot/workflow/java/mapping/ChatHandlerMethod.java @@ -18,44 +18,22 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.StringJoiner; -import java.util.stream.Collectors; -import java.util.stream.IntStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.BeanFactory; import org.springframework.core.BridgeMethodResolver; import org.springframework.core.MethodParameter; -import org.springframework.core.ResolvableType; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.annotation.SynthesizingMethodParameter; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; /** - * Encapsulates information about a handler method consisting of a - * {@linkplain #getMethod() method} and a {@linkplain #getBean() bean}. - * Provides convenient access to method parameters, the method return value, - * method annotations, etc. - * - *

The class may be created with a bean instance or with a bean name - * (e.g. lazy-init bean, prototype bean). Use {@link #createWithResolvedBean()} - * to obtain a {@code HandlerMethod} instance with a bean instance resolved - * through the associated {@link BeanFactory}. - * - * @author Arjen Poutsma - * @author Rossen Stoyanchev - * @author Juergen Hoeller - * @author Sam Brannen - * @since 3.1 + * Originally stolen from spring code. */ public class ChatHandlerMethod { @@ -64,9 +42,6 @@ public class ChatHandlerMethod { private final Object bean; - @Nullable - private final BeanFactory beanFactory; - private final Class beanType; private final Method method; @@ -78,9 +53,6 @@ public class ChatHandlerMethod { @Nullable private ChatHandlerMethod resolvedFromHandlerMethod; - @Nullable - private volatile List interfaceParameterAnnotations; - private final String description; @@ -91,7 +63,6 @@ public ChatHandlerMethod(Object bean, Method method) { Assert.notNull(bean, "Bean is required"); Assert.notNull(method, "Method is required"); this.bean = bean; - this.beanFactory = null; this.beanType = ClassUtils.getUserClass(bean); this.method = method; this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); @@ -99,74 +70,6 @@ public ChatHandlerMethod(Object bean, Method method) { this.description = initDescription(this.beanType, this.method); } - /** - * Create an instance from a bean instance, method name, and parameter types. - * @throws NoSuchMethodException when the method cannot be found - */ - public ChatHandlerMethod(Object bean, String methodName, Class... parameterTypes) throws NoSuchMethodException { - Assert.notNull(bean, "Bean is required"); - Assert.notNull(methodName, "Method name is required"); - this.bean = bean; - this.beanFactory = null; - this.beanType = ClassUtils.getUserClass(bean); - this.method = bean.getClass().getMethod(methodName, parameterTypes); - this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(this.method); - this.parameters = initMethodParameters(); - this.description = initDescription(this.beanType, this.method); - } - - /** - * Create an instance from a bean name, a method, and a {@code BeanFactory}. - * The method {@link #createWithResolvedBean()} may be used later to - * re-create the {@code HandlerMethod} with an initialized bean. - */ - public ChatHandlerMethod(String beanName, BeanFactory beanFactory, Method method) { - Assert.hasText(beanName, "Bean name is required"); - Assert.notNull(beanFactory, "BeanFactory is required"); - Assert.notNull(method, "Method is required"); - this.bean = beanName; - this.beanFactory = beanFactory; - Class beanType = beanFactory.getType(beanName); - if (beanType == null) { - throw new IllegalStateException("Cannot resolve bean type for bean with name '" + beanName + "'"); - } - this.beanType = ClassUtils.getUserClass(beanType); - this.method = method; - this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); - this.parameters = initMethodParameters(); - this.description = initDescription(this.beanType, this.method); - } - - /** - * Copy constructor for use in subclasses. - */ - protected ChatHandlerMethod(ChatHandlerMethod handlerMethod) { - Assert.notNull(handlerMethod, "HandlerMethod is required"); - this.bean = handlerMethod.bean; - this.beanFactory = handlerMethod.beanFactory; - this.beanType = handlerMethod.beanType; - this.method = handlerMethod.method; - this.bridgedMethod = handlerMethod.bridgedMethod; - this.parameters = handlerMethod.parameters; - this.description = handlerMethod.description; - this.resolvedFromHandlerMethod = handlerMethod.resolvedFromHandlerMethod; - } - - /** - * Re-create HandlerMethod with the resolved handler. - */ - private ChatHandlerMethod(ChatHandlerMethod handlerMethod, Object handler) { - Assert.notNull(handlerMethod, "HandlerMethod is required"); - Assert.notNull(handler, "Handler object is required"); - this.bean = handler; - this.beanFactory = handlerMethod.beanFactory; - this.beanType = handlerMethod.beanType; - this.method = handlerMethod.method; - this.bridgedMethod = handlerMethod.bridgedMethod; - this.parameters = handlerMethod.parameters; - this.resolvedFromHandlerMethod = handlerMethod; - this.description = handlerMethod.description; - } private MethodParameter[] initMethodParameters() { int count = this.bridgedMethod.getParameterCount(); @@ -231,12 +134,7 @@ public MethodParameter getReturnType() { return new HandlerMethodParameter(-1); } - /** - * Return the actual return value type. - */ - public MethodParameter getReturnValueType(@Nullable Object returnValue) { - return new ReturnValueMethodParameter(returnValue); - } + /** * Return {@code true} if the method return type is void, {@code false} otherwise. @@ -278,65 +176,6 @@ public ChatHandlerMethod getResolvedFromHandlerMethod() { return this.resolvedFromHandlerMethod; } - /** - * If the provided instance contains a bean name rather than an object instance, - * the bean name is resolved before a {@link ChatHandlerMethod} is created and returned. - */ - public ChatHandlerMethod createWithResolvedBean() { - Object handler = this.bean; - if (this.bean instanceof String) { - Assert.state(this.beanFactory != null, "Cannot resolve bean name without BeanFactory"); - String beanName = (String) this.bean; - handler = this.beanFactory.getBean(beanName); - } - return new ChatHandlerMethod(this, handler); - } - - /** - * Return a short representation of this handler method for log message purposes. - * @since 4.3 - */ - public String getShortLogMessage() { - return getBeanType().getName() + "#" + this.method.getName() + - "[" + this.method.getParameterCount() + " args]"; - } - - - private List getInterfaceParameterAnnotations() { - List parameterAnnotations = this.interfaceParameterAnnotations; - if (parameterAnnotations == null) { - parameterAnnotations = new ArrayList<>(); - for (Class ifc : ClassUtils.getAllInterfacesForClassAsSet(this.method.getDeclaringClass())) { - for (Method candidate : ifc.getMethods()) { - if (isOverrideFor(candidate)) { - parameterAnnotations.add(candidate.getParameterAnnotations()); - } - } - } - this.interfaceParameterAnnotations = parameterAnnotations; - } - return parameterAnnotations; - } - - private boolean isOverrideFor(Method candidate) { - if (!candidate.getName().equals(this.method.getName()) || - candidate.getParameterCount() != this.method.getParameterCount()) { - return false; - } - Class[] paramTypes = this.method.getParameterTypes(); - if (Arrays.equals(candidate.getParameterTypes(), paramTypes)) { - return true; - } - for (int i = 0; i < paramTypes.length; i++) { - if (paramTypes[i] != - ResolvableType.forMethodParameter(candidate, i, this.method.getDeclaringClass()).resolve()) { - return false; - } - } - return true; - } - - @Override public boolean equals(@Nullable Object other) { if (this == other) { @@ -359,58 +198,6 @@ public String toString() { return this.description; } - - // Support methods for use in "InvocableHandlerMethod" sub-class variants.. - - @Nullable - protected static Object findProvidedArgument(MethodParameter parameter, @Nullable Object... providedArgs) { - if (!ObjectUtils.isEmpty(providedArgs)) { - for (Object providedArg : providedArgs) { - if (parameter.getParameterType().isInstance(providedArg)) { - return providedArg; - } - } - } - return null; - } - - protected static String formatArgumentError(MethodParameter param, String message) { - return "Could not resolve parameter [" + param.getParameterIndex() + "] in " + - param.getExecutable().toGenericString() + (StringUtils.hasText(message) ? ": " + message : ""); - } - - /** - * Assert that the target bean class is an instance of the class where the given - * method is declared. In some cases the actual controller instance at request- - * processing time may be a JDK dynamic proxy (lazy initialization, prototype - * beans, and others). {@code @Controller}'s that require proxying should prefer - * class-based proxy mechanisms. - */ - protected void assertTargetBean(Method method, Object targetBean, Object[] args) { - Class methodDeclaringClass = method.getDeclaringClass(); - Class targetBeanClass = targetBean.getClass(); - if (!methodDeclaringClass.isAssignableFrom(targetBeanClass)) { - String text = "The mapped handler method class '" + methodDeclaringClass.getName() + - "' is not an instance of the actual controller bean class '" + - targetBeanClass.getName() + "'. If the controller requires proxying " + - "(e.g. due to @Transactional), please use class-based proxying."; - throw new IllegalStateException(formatInvokeError(text, args)); - } - } - - protected String formatInvokeError(String text, Object[] args) { - String formattedArgs = IntStream.range(0, args.length) - .mapToObj(i -> (args[i] != null ? - "[" + i + "] [type=" + args[i].getClass().getName() + "] [value=" + args[i] + "]" : - "[" + i + "] [null]")) - .collect(Collectors.joining(",\n", " ", " ")); - return text + "\n" + - "Controller [" + getBeanType().getName() + "]\n" + - "Method [" + getBridgedMethod().toGenericString() + "] " + - "with argument values:\n" + formattedArgs; - } - - /** * A MethodParameter with HandlerMethod-specific behavior. */ @@ -453,31 +240,6 @@ public Annotation[] getParameterAnnotations() { Annotation[] anns = this.combinedAnnotations; if (anns == null) { anns = super.getParameterAnnotations(); - int index = getParameterIndex(); - if (index >= 0) { - for (Annotation[][] ifcAnns : getInterfaceParameterAnnotations()) { - if (index < ifcAnns.length) { - Annotation[] paramAnns = ifcAnns[index]; - if (paramAnns.length > 0) { - List merged = new ArrayList<>(anns.length + paramAnns.length); - merged.addAll(Arrays.asList(anns)); - for (Annotation paramAnn : paramAnns) { - boolean existingType = false; - for (Annotation ann : anns) { - if (ann.annotationType() == paramAnn.annotationType()) { - existingType = true; - break; - } - } - if (!existingType) { - merged.add(adaptAnnotation(paramAnn)); - } - } - anns = merged.toArray(new Annotation[0]); - } - } - } - } this.combinedAnnotations = anns; } return anns; @@ -490,33 +252,6 @@ public HandlerMethodParameter clone() { } - /** - * A MethodParameter for a HandlerMethod return type based on an actual return value. - */ - private class ReturnValueMethodParameter extends HandlerMethodParameter { - - @Nullable - private final Object returnValue; - - public ReturnValueMethodParameter(@Nullable Object returnValue) { - super(-1); - this.returnValue = returnValue; - } - - protected ReturnValueMethodParameter(ReturnValueMethodParameter original) { - super(original); - this.returnValue = original.returnValue; - } - - @Override - public Class getParameterType() { - return (this.returnValue != null ? this.returnValue.getClass() : super.getParameterType()); - } - - @Override - public ReturnValueMethodParameter clone() { - return new ReturnValueMethodParameter(this); - } - } + }