package eu.codearte.resteeth.config;
import eu.codearte.resteeth.annotation.RestClient;
import eu.codearte.resteeth.endpoint.EndpointProvider;
import eu.codearte.resteeth.endpoint.Endpoints;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.type.MethodMetadata;
import java.lang.annotation.Annotation;
/**
* @author Jakub Kubrynski
*/
class BeanResolver {
boolean beanNotDefinedExplicitly(ConfigurableListableBeanFactory configurableListableBeanFactory, Class<?> beanClass) {
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(configurableListableBeanFactory, beanClass, true, true);
return beanNames == null || beanNames.length == 0;
}
EndpointProvider findEndpointProvider(Class<?> beanClass, ConfigurableListableBeanFactory beanFactory, RestClient restClient) {
if (restClient.endpoints().length == 1) {
return Endpoints.fixedEndpoint(restClient.endpoints()[0]);
} else if (restClient.endpoints().length > 1) {
return Endpoints.roundRobinEndpoint(restClient.endpoints());
}
Qualifier qualifier = AnnotationUtils.findAnnotation(beanClass, Qualifier.class);
if (qualifier == null) {
// without qualifier
return BeanFactoryUtils.beanOfTypeIncludingAncestors(beanFactory, EndpointProvider.class);
}
Annotation qualifierAnnotation = qualifier;
for (Annotation annotation : beanClass.getAnnotations()) {
if (qualifier != annotation && annotation.annotationType().isAnnotationPresent(Qualifier.class)) {
qualifierAnnotation = annotation;
}
}
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, EndpointProvider.class, true, true);
for (String beanName : beanNames) {
if (checkQualifier(beanFactory.getBeanDefinition(beanName), qualifierAnnotation)) {
return (EndpointProvider) beanFactory.getBean(beanName);
}
}
throw new NoSuchBeanDefinitionException(EndpointProvider.class, "Cannot find proper for " + beanClass.getCanonicalName());
}
private boolean checkQualifier(BeanDefinition endpointBeanDefinition, Annotation qualifierAnnotation) {
if (endpointBeanDefinition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annotatedBeanDefinition = (AnnotatedBeanDefinition) endpointBeanDefinition;
String qualifierCanonicalName = qualifierAnnotation.annotationType().getCanonicalName();
MethodMetadata factoryMethodMetadata = annotatedBeanDefinition.getFactoryMethodMetadata();
if (factoryMethodMetadata.isAnnotated(qualifierCanonicalName)) {
if (qualifierAnnotation instanceof Qualifier) {
Object value1 = factoryMethodMetadata.getAnnotationAttributes(qualifierCanonicalName).get("value");
Object value2 = ((Qualifier) qualifierAnnotation).value();
if (value1 == null || value2 == null) {
throw new IllegalArgumentException("No value found on Qualifier annotation");
}
if (value1.equals(value2)) {
return true;
}
}
return true;
}
}
return false;
}
}