com.coditory.quark.context.ContextResolver Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of quark-context Show documentation
Show all versions of quark-context Show documentation
Coditory Quark Configuration Library
package com.coditory.quark.context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
final class ContextResolver {
private static final Logger log = LoggerFactory.getLogger(ContextResolver.class);
private ContextResolver() {
throw new UnsupportedOperationException("Do not instantiate utility class");
}
static Map, List>> resolve(Set> beanHolders, Map properties) {
Set> holders = new HashSet<>(beanHolders);
ConditionContext contextWithAllBeans = ConditionContext.from(holders, properties);
ConditionContext contextWithNoBeans = ConditionContext.from(properties);
Set> stableBeanHolders = findStableBeans(holders, contextWithAllBeans, contextWithNoBeans);
holders.removeAll(stableBeanHolders);
Set> additiveBeanHolders = findAdditiveBeans(holders, contextWithAllBeans);
holders.removeAll(additiveBeanHolders);
return resolve(stableBeanHolders, additiveBeanHolders, holders, properties);
}
private static Set> findStableBeans(Set> holders, ConditionContext contextWithAllBeans, ConditionContext contextWithNoBeans) {
return holders.stream()
.filter(it -> it.isActive(contextWithNoBeans))
.filter(it -> it.isActive(contextWithAllBeans))
.collect(toSet());
}
private static Set> findAdditiveBeans(Set> holders, ConditionContext contextWithAllBeans) {
return holders.stream()
.filter(it -> it.isActive(contextWithAllBeans))
.collect(toSet());
}
private static Map, List>> resolve(
Set> stableBeanHolders,
Set> additiveBeanHolders,
Set> remainingBeanHolders,
Map properties
) {
Set beanNames = new HashSet<>();
Set> registeredBeans = new HashSet<>();
Map, List>> result = new HashMap<>();
stableBeanHolders.forEach(holder -> {
addBeanName(beanNames, holder);
addBeanHolderWithClassHierarchy(result, holder);
registeredBeans.add(holder);
});
ConditionContext context = ConditionContext.from(registeredBeans, properties);
int registered;
do {
do {
registered = registeredBeans.size();
for (BeanHolder> holder : additiveBeanHolders) {
if (canBeAddedToContext(holder, registeredBeans, context)) {
addBeanName(beanNames, holder);
addBeanHolderWithClassHierarchy(result, holder);
registeredBeans.add(holder);
context = context.with(holder);
}
}
additiveBeanHolders.removeAll(registeredBeans);
} while (registered < registeredBeans.size());
for (BeanHolder> holder : remainingBeanHolders) {
if (canBeAddedToContext(holder, registeredBeans, context)) {
addBeanName(beanNames, holder);
addBeanHolderWithClassHierarchy(result, holder);
registeredBeans.add(holder);
context = context.with(holder);
break;
}
}
remainingBeanHolders.removeAll(registeredBeans);
} while (registered < registeredBeans.size());
logResolvedBeans(registeredBeans, additiveBeanHolders, remainingBeanHolders);
return result;
}
private static void logResolvedBeans(Set> registered, Set> additiveBeanHolders, Set> remainingBeanHolders) {
if (log.isInfoEnabled()) {
List names = registered.stream()
.map(h -> h.getDescriptor().toShortString())
.sorted()
.collect(toList());
log.info("Registered beans: {}", names);
}
Set> skipped = new HashSet<>();
skipped.addAll(additiveBeanHolders);
skipped.addAll(remainingBeanHolders);
if (log.isDebugEnabled() && !skipped.isEmpty()) {
List names = skipped.stream()
.map(h -> h.getDescriptor().toShortString())
.sorted()
.collect(toList());
log.debug("Skipped beans: {}", names);
}
}
private static boolean canBeAddedToContext(BeanHolder> holder, Set> registeredBeans, ConditionContext context) {
if (!holder.isActive(context)) {
return false;
}
ConditionContext contextWithBean = context.with(holder);
return registeredBeans.stream()
.allMatch(registered -> registered.isActive(contextWithBean));
}
private static void addBeanName(Set beanNames, BeanHolder> holder) {
String name = holder.getBeanName();
if (name == null) {
return;
}
if (beanNames.contains(name)) {
throw new ContextException("Duplicated bean name: " + name);
}
beanNames.add(name);
}
private static void addBeanHolderWithClassHierarchy(Map, List>> holders, BeanHolder holder) {
holder.getBeanClassHierarchyDescriptors().forEach(descriptor -> {
List> registeredBeanCreators = holders
.computeIfAbsent(descriptor, (k) -> new ArrayList<>());
registeredBeanCreators.add(holder);
});
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy