com.github.leeonky.jfactory.FactorySet Maven / Gradle / Ivy
package com.github.leeonky.jfactory;
import com.github.leeonky.util.BeanClass;
import com.github.leeonky.util.Classes;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
class FactorySet {
public final TypeSequence typeSequence = new TypeSequence();
private final DefaultValueFactories defaultValueFactories = new DefaultValueFactories();
private final Map, ObjectFactory>> objectFactories = new HashMap<>();
private final Map, SpecClassFactory>> specClassFactoriesWithType = new HashMap<>();
private final Map> specClassFactoriesWithName = new HashMap<>();
@SuppressWarnings("unchecked")
public ObjectFactory queryObjectFactory(BeanClass type) {
return (ObjectFactory) objectFactories.computeIfAbsent(type,
key -> new ObjectFactory<>(key, this));
}
public > void registerSpecClassFactory(Class specClass) {
Spec spec = Classes.newInstance(specClass);
boolean globalSpec = isGlobalSpec(specClass);
SpecClassFactory> specClassFactory = specClassFactoriesWithType.computeIfAbsent(specClass,
type -> new SpecClassFactory<>(specClass, this, globalSpec));
specClassFactoriesWithName.put(spec.getName(), specClassFactory);
if (globalSpec)
registerGlobalSpec(specClassFactory);
if (!specClass.getSuperclass().equals(Spec.class))
registerSpecClassFactory((Class) specClass.getSuperclass());
}
private > boolean isGlobalSpec(Class specClass) {
return specClass.getAnnotation(Global.class) != null;
}
private void registerGlobalSpec(SpecClassFactory> specClassFactory) {
Class extends Spec>> specClass = specClassFactory.getSpecClass();
if (specClassFactory.getBase() instanceof SpecClassFactory)
throw new IllegalArgumentException(String.format("More than one @Global Spec class `%s` and `%s`",
((SpecClassFactory>) specClassFactory.getBase()).getSpecClass().getName(), specClass.getName()));
if (!specClass.getSuperclass().equals(Spec.class))
throw new IllegalArgumentException(String.format("Global Spec %s should not have super Spec %s.",
specClass.getName(), specClass.getSuperclass().getName()));
objectFactories.put(specClassFactory.getType(), specClassFactory);
}
public void removeGlobalSpec(BeanClass> type) {
objectFactories.computeIfPresent(type, (key, factory) -> factory.getBase());
}
@SuppressWarnings("unchecked")
public SpecClassFactory querySpecClassFactory(String specName) {
return (SpecClassFactory) specClassFactoriesWithName.computeIfAbsent(specName, key -> {
throw new IllegalArgumentException("Spec `" + specName + "` not exist");
});
}
@SuppressWarnings("unchecked")
public SpecClassFactory querySpecClassFactory(Class extends Spec> specClass) {
return (SpecClassFactory) specClassFactoriesWithType.computeIfAbsent(specClass, key -> {
throw new IllegalArgumentException("Spec `" + specClass.getName() + "` not exist");
});
}
public Optional> queryDefaultValueBuilder(BeanClass type) {
return defaultValueFactories.query(type.getType());
}
public DefaultValueFactory getDefaultValueBuilder(BeanClass type) {
return queryDefaultValueBuilder(type).orElseGet(() -> new DefaultValueFactories.DefaultTypeFactory<>(type));
}
public int nextSequence(Class> type) {
return typeSequence.generate(type);
}
public > SpecFactory createSpecFactory(Class specClass, Consumer trait) {
return new SpecFactory<>(Classes.newInstance(specClass), this, trait);
}
public void registerDefaultValueFactory(Class type, DefaultValueFactory factory) {
defaultValueFactories.register(type, factory);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy