Skip to content

Commit

Permalink
Improving coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
robmoffat committed Feb 8, 2022
1 parent 48b230b commit dc337f7
Show file tree
Hide file tree
Showing 5 changed files with 7 additions and 274 deletions.
Binary file modified .DS_Store
Binary file not shown.
3 changes: 2 additions & 1 deletion libs/chat-workflow-coverage/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<artifactId>chat-workflow-coverage</artifactId>
<name>Chat Workflow Coverage Report</name>
<description>Used For Jacoco</description>
<packaging>pom</packaging>

<parent>
<groupId>org.finos.springbot</groupId>
Expand All @@ -18,7 +19,7 @@
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<profiles>
<profiles>
<profile>
<!-- this profile generates code coverage, should be run by the ci server -->
<id>symphony-ci</id>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
* <p>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 {

Expand All @@ -64,9 +42,6 @@ public class ChatHandlerMethod {

private final Object bean;

@Nullable
private final BeanFactory beanFactory;

private final Class<?> beanType;

private final Method method;
Expand All @@ -78,9 +53,6 @@ public class ChatHandlerMethod {
@Nullable
private ChatHandlerMethod resolvedFromHandlerMethod;

@Nullable
private volatile List<Annotation[][]> interfaceParameterAnnotations;

private final String description;


Expand All @@ -91,82 +63,13 @@ 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);
this.parameters = initMethodParameters();
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();
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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<Annotation[][]> getInterfaceParameterAnnotations() {
List<Annotation[][]> 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) {
Expand All @@ -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.
*/
Expand Down Expand Up @@ -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<Annotation> 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;
Expand All @@ -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);
}
}


}

0 comments on commit dc337f7

Please sign in to comment.