All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.zodiac.autoconfigure.web.remote.smart.SmartHandlerMappingRegistrar Maven / Gradle / Ivy
package org.zodiac.autoconfigure.web.remote.smart;
import java.util.Set;
import java.util.function.Predicate;
import org.slf4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.SingletonBeanRegistry;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.zodiac.commons.logging.SmartSlf4jLoggerFactory;
import org.zodiac.commons.reflection.ObjectInstantiators;
import org.zodiac.commons.util.Asserts;
import org.zodiac.commons.util.Colls;
import org.zodiac.commons.util.lang.Strings;
import org.zodiac.commons.util.spring.Springs;
public class SmartHandlerMappingRegistrar
implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware, BeanFactoryAware {
protected final Logger log = SmartSlf4jLoggerFactory.getLogger(getClass());
private ResourceLoader resourceLoader;
private Environment environment;
@SuppressWarnings("unused")
private BeanFactory beanFactory;
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = Asserts.notNullOf(resourceLoader, "resourceLoader");
}
@Override
public void setEnvironment(Environment environment) {
this.environment = Asserts.notNullOf(environment, "environment");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = Asserts.notNullOf(beanFactory, "beanFactory");
}
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
AnnotationAttributes attrs = AnnotationAttributes
.fromMap(metadata.getAnnotationAttributes(EnableSmartRequestMapping.class.getName()));
if (null != attrs) {
BeanNameGenerator beanNameGenerator = resolveBeanNameGenerator(registry);
/*Register rqeust handler mapping.*/
if (Springs.isReactiveWeb(getClass().getClassLoader(), environment, resourceLoader)) {
/*Reactive WebFlux .*/
registerSmartHandlerMappingConfigurer(metadata, attrs, registry, WebFluxSmartHandlerMappingConfiguration.class,
beanNameGenerator);
} else if (Springs.isServletWeb(getClass().getClassLoader(), environment, resourceLoader)) {
/*Servlet WebMvc .*/
registerSmartHandlerMappingConfigurer(metadata, attrs, registry, WebMvcSmartHandlerMappingConfiguration.class,
beanNameGenerator);
}
}
}
protected void registerSmartHandlerMappingConfigurer(AnnotationMetadata metadata, AnnotationAttributes attrs,
BeanDefinitionRegistry registry, Class> beanClass, BeanNameGenerator beanNameGenerator) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(beanClass);
builder.addPropertyValue(EnableSmartRequestMapping.PACKAGE_PATTERNS, resolvePackagePatterns(metadata, attrs));
builder.addPropertyValue(EnableSmartRequestMapping.PACKAGE_PATTERNS_FOR_INCLUDE,attrs.getBoolean(EnableSmartRequestMapping.PACKAGE_PATTERNS_FOR_INCLUDE));
builder.addPropertyValue(EnableSmartRequestMapping.FILTERS, resolveIncludeFilters(attrs, registry));
builder.addPropertyValue(EnableSmartRequestMapping.OVERRIDE_AMBIGUOUS, attrs.getBoolean(EnableSmartRequestMapping.OVERRIDE_AMBIGUOUS));
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
String beanName = beanNameGenerator.generateBeanName(beanDefinition, registry);
registry.registerBeanDefinition(beanName, beanDefinition);
}
@SuppressWarnings("unchecked")
private Predicate>[] resolveIncludeFilters(AnnotationAttributes annoAttrs, BeanDefinitionRegistry registry) {
return Colls.safeArrayToList(annoAttrs.getClassArray(EnableSmartRequestMapping.FILTERS)).stream()
.map(c -> ObjectInstantiators.newInstance(c)).toArray(Predicate[]::new);
}
/**
* It'd better to use BeanNameGenerator instance that should reference
* {@link ConfigurationClassPostProcessor#componentScanBeanNameGenerator},
* thus it maybe a potential problem on bean name generation.
*
* @param registry {@link BeanDefinitionRegistry}
* @return {@link BeanNameGenerator} instance
* @see SingletonBeanRegistry
* @see AnnotationConfigUtils#CONFIGURATION_BEAN_NAME_GENERATOR
* @see ConfigurationClassPostProcessor#processConfigBeanDefinitions
*/
private BeanNameGenerator resolveBeanNameGenerator(BeanDefinitionRegistry registry) {
BeanNameGenerator beanNameGenerator = null;
if (registry instanceof SingletonBeanRegistry) {
SingletonBeanRegistry singletonBeanRegistry = SingletonBeanRegistry.class.cast(registry);
beanNameGenerator = (BeanNameGenerator) singletonBeanRegistry.getSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
}
if (beanNameGenerator == null) {
log.warn("BeanNameGenerator bean can't be found in BeanFactory with name [" + AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR
+ "], BeanNameGenerator will be a instance of " + AnnotationBeanNameGenerator.class.getName()
+ " , it maybe a potential problem on bean name generation.");
beanNameGenerator = new AnnotationBeanNameGenerator();
}
return beanNameGenerator;
}
private String[] resolvePackagePatterns(AnnotationMetadata metadata, AnnotationAttributes attrs) {
return getPackagePatterns(metadata, attrs).stream().filter(v -> Strings.notBlank(v))
.map(v -> environment.resolveRequiredPlaceholders(v)).toArray(String[]::new);
}
private Set getPackagePatterns(AnnotationMetadata metadata, AnnotationAttributes attrs) {
Set basePackages = Colls.set();
for (String pkg : attrs.getStringArray("value")) {
if (Strings.hasText(pkg)) {
basePackages.add(pkg);
}
}
for (String pkg : attrs.getStringArray(EnableSmartRequestMapping.PACKAGE_PATTERNS)) {
if (Strings.hasText(pkg)) {
basePackages.add(pkg);
}
}
/*
* [Must Ignore] We must strictly handle only the specified values, so
* that we can be transparent to the outside world, because the
* conditions here are too sensitive.
*/
// if (basePackages.isEmpty()) {
// basePackages.add(ClassUtils.getPackageName(metadata.getClassName()));
// }
return basePackages;
}
}