package nl.ipo.cds.admin.i18n;
import java.io.IOException;
import java.lang.reflect.Method;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
public class MessageInterfaceRegistar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
final String basePackage = (String)importingClassMetadata.getAnnotationAttributes(EnableI18N.class.getName()).get("basePackage");
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(false) {
@Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
try {
final String beanClassName = beanDefinition.getBeanClassName();
final Class<?> clazz = Class.forName(beanClassName);
for(Method method : clazz.getDeclaredMethods()) {
if(!method.getReturnType().equals(String.class)) {
throw new IllegalArgumentException("i18n message interface with non-String returning method: " + beanClassName + "." + method.getName());
}
}
return true;
} catch(ClassNotFoundException e) {
return false;
}
}
};
componentProvider.addIncludeFilter(new TypeFilter() {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
return metadataReader.getClassMetadata().isInterface();
}
});
for(final BeanDefinition component : componentProvider.findCandidateComponents(basePackage)) {
final GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setFactoryBeanName("i18nFactory");
beanDefinition.setFactoryMethodName("create");
final ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
constructorArgumentValues.addGenericArgumentValue(component.getBeanClassName());
beanDefinition.setConstructorArgumentValues(constructorArgumentValues);
final String beanClassName = component.getBeanClassName();
final int lastIndex = beanClassName.lastIndexOf(".");
final String name;
if(lastIndex == -1) {
name = beanClassName;
} else {
name = beanClassName.substring(lastIndex + 1);
}
registry.registerBeanDefinition("i18n." + name.toLowerCase(), beanDefinition);
}
}
}