org.zodiac.scaff.crud.annotation.FastOrmRepositoryRegistrar Maven / Gradle / Ivy
The newest version!
package org.zodiac.scaff.crud.annotation;
import org.zodiac.commons.util.Annotations;
import org.zodiac.fastorm.rdb.mapping.defaults.DefaultReactiveRepository;
import org.zodiac.fastorm.rdb.mapping.defaults.DefaultSyncRepository;
import org.zodiac.scaff.api.crud.entity.GenericEntity;
import org.zodiac.scaff.api.crud.entity.ImplementFor;
import org.zodiac.scaff.crud.AutoDDLProcessor;
import org.zodiac.scaff.crud.EntityInfo;
import org.zodiac.scaff.crud.ReactiveRepositoryFactoryBean;
import org.zodiac.scaff.crud.SyncRepositoryFactoryBean;
import org.zodiac.sdk.toolkit.util.ClassUtil;
import org.zodiac.sdk.toolkit.util.ExceptionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
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.classreading.SimpleMetadataReaderFactory;
import org.springframework.util.ClassUtils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class FastOrmRepositoryRegistrar implements ImportBeanDefinitionRegistrar {
static AtomicInteger count = new AtomicInteger();
protected final Logger log = LoggerFactory.getLogger(getClass());
private final ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
private final MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
public FastOrmRepositoryRegistrar() {
super();
}
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
try {
Map attr = importingClassMetadata.getAnnotationAttributes(EnableFastOrmRepository.class.getName());
if (attr == null) {
return;
}
boolean reactiveEnabled = Boolean.TRUE.equals(attr.get("reactive"));
boolean nonReactiveEnabled = Boolean.TRUE.equals(attr.get("nonReactive"));
String[] arr = (String[]) attr.get("value");
Set resources = Arrays.stream(arr)
.flatMap(this::doGetResources)
.collect(Collectors.toSet());
Class[] anno = (Class[]) attr.get("annotation");
Set entityInfos = new HashSet<>();
for (Resource resource : resources) {
MetadataReader reader = metadataReaderFactory.getMetadataReader(resource);
String className = reader.getClassMetadata().getClassName();
Class> entityType = ClassUtils.forName(className, null);
if (Arrays.stream(anno)
.noneMatch(ann -> Annotations.findAnnotation(entityType, ann) != null)) {
continue;
}
ImplementFor implementFor = Annotations.findAnnotation(entityType, ImplementFor.class);
Reactive reactive = Annotations.findAnnotation(entityType, Reactive.class);
Class genericType = Optional
.ofNullable(implementFor)
.map(ImplementFor::value)
.orElseGet(() -> {
return Stream
.of(entityType.getInterfaces())
.filter(e -> GenericEntity.class.isAssignableFrom(e))
.findFirst()
.orElse(entityType);
});
Class idType = null;
if (implementFor == null || implementFor.idType() == Void.class) {
try {
if (GenericEntity.class.isAssignableFrom(entityType)) {
idType = ClassUtil.getGenericType(entityType);
}
if (idType == null) {
Method getId = ClassUtils.getMethod(entityType, "getId");
idType = getId.getReturnType();
}
} catch (Exception e) {
idType = String.class;
}
} else {
idType = implementFor.idType();
}
EntityInfo entityInfo = new EntityInfo(genericType,
entityType,
idType,
reactiveEnabled,
nonReactiveEnabled);
if (!entityInfos.contains(entityInfo) || implementFor != null) {
entityInfos.add(entityInfo);
}
}
for (EntityInfo entityInfo : entityInfos) {
Class entityType = entityInfo.getEntityType();
Class idType = entityInfo.getIdType();
Class realType = entityInfo.getRealType();
if (entityInfo.isReactive()) {
log.trace("register ReactiveRepository<{},{}>", entityType.getName(), idType.getSimpleName());
ResolvableType repositoryType = ResolvableType.forClassWithGenerics(DefaultReactiveRepository.class, entityType, idType);
RootBeanDefinition definition = new RootBeanDefinition();
definition.setTargetType(repositoryType);
definition.setBeanClass(ReactiveRepositoryFactoryBean.class);
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
definition.getPropertyValues().add("entityType", realType);
registry.registerBeanDefinition(realType.getSimpleName().concat("ReactiveRepository"), definition);
}
if (entityInfo.isNonReactive()) {
log.trace("register SyncRepository<{},{}>", entityType.getName(), idType.getSimpleName());
ResolvableType repositoryType = ResolvableType.forClassWithGenerics(DefaultSyncRepository.class, entityType, idType);
RootBeanDefinition definition = new RootBeanDefinition();
definition.setTargetType(repositoryType);
definition.setBeanClass(SyncRepositoryFactoryBean.class);
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
definition.getPropertyValues().add("entityType", realType);
registry.registerBeanDefinition(realType.getSimpleName().concat("SyncRepository"), definition);
}
}
Map> group = entityInfos.stream()
.collect(Collectors.groupingBy(EntityInfo::isReactive, Collectors.toSet()));
for (Map.Entry> entry : group.entrySet()) {
RootBeanDefinition definition = new RootBeanDefinition();
definition.setTargetType(AutoDDLProcessor.class);
definition.setBeanClass(AutoDDLProcessor.class);
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
definition.getPropertyValues().add("entities", entityInfos);
definition.getPropertyValues().add("reactive", entry.getKey());
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
definition.setSynthetic(true);
registry.registerBeanDefinition(AutoDDLProcessor.class.getName() + "_" + count.incrementAndGet(), definition);
}
// try {
// BeanDefinition definition = registry.getBeanDefinition(AutoDDLProcessor.class.getName());
// Set infos = (Set) definition.getPropertyValues().get("entities");
// infos.addAll(entityInfos);
// } catch (NoSuchBeanDefinitionException e) {
//
// }
} catch (Exception e) {
ExceptionUtil.chuck(e);
}
}
private Stream doGetResources(String packageStr) {
Stream result = null;
try {
String path = ResourcePatternResolver
.CLASSPATH_ALL_URL_PREFIX
.concat(packageStr.replace(".", "/")).concat("/**/*.class");
result = Arrays.stream(resourcePatternResolver.getResources(path));
} catch (Exception e) {
ExceptionUtil.chuck(e);
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy