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.
com.github.nill14.utils.init.impl.ServiceRegistry Maven / Gradle / Ivy
package com.github.nill14.utils.init.impl;
import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import javax.inject.Named;
import javax.inject.Provider;
import com.github.nill14.utils.init.api.IBeanDescriptor;
import com.github.nill14.utils.init.api.IBeanInjector;
import com.github.nill14.utils.init.api.ILazyPojo;
import com.github.nill14.utils.init.api.IPojoInitializer;
import com.github.nill14.utils.init.api.IPropertyResolver;
import com.github.nill14.utils.init.api.IServiceContext;
import com.github.nill14.utils.init.api.IServiceRegistry;
import com.github.nill14.utils.init.inject.PojoInjectionDescriptor;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableMap;
/**
*
* The ServiceRegistry must not be serializable. Serializing the registry indicates a programming error.
*
*/
public class ServiceRegistry implements IServiceRegistry {
private final ConcurrentHashMap> beans = new ConcurrentHashMap<>();
private final ConcurrentHashMap, Map>> services = new ConcurrentHashMap<>();
private final ConcurrentHashMap, Map>> qualifiers = new ConcurrentHashMap<>();
private final IPropertyResolver resolver = new ServiceRegistryPropertyResolver();
private final ChainingPojoInitializer pojoInitializer = ChainingPojoInitializer.defaultInitializer();
public ServiceRegistry() {
}
private String generateGlobalName(Class> type) {
Named named = type.getAnnotation(Named.class);
if (named != null) {
return type.getTypeName() + "$" + named.value();
} else {
return type.getTypeName();
}
}
@Override
public void addService(Class serviceBean, IServiceContext context) {
addService(generateGlobalName(serviceBean), serviceBean, context);
}
private IPojoInitializer getInitializer(IServiceContext context) {
Optional> contextInitializer = context.getInitializer();
if (contextInitializer.isPresent()) {
return pojoInitializer.with(contextInitializer.get());
} else {
return pojoInitializer;
}
}
private IPropertyResolver getResolver(IServiceContext context) {
Optional customResolver = context.getCustomResolver();
if (customResolver.isPresent()) {
return new ChainingPropertyResolver(customResolver.get(), resolver);
} else {
return resolver;
}
}
@SuppressWarnings("unchecked")
private ILazyPojo newProxy(ILazyPojo> lazyPojo, Class serviceBean) {
// Object proxy = LazyJdkProxy.newProxy(lazyPojo);
// Object proxy = LazyJavassistProxy.newProxy(lazyPojo);
// return serviceBean.cast(proxy);
return (ILazyPojo) lazyPojo;
}
@Override
public void addService(String name, Class serviceBean, IServiceContext context) {
IPojoInitializer initializer = getInitializer(context);
IPropertyResolver resolver = getResolver(context);
ILazyPojo lazyPojo = LazyPojo.forClass(serviceBean, resolver, initializer);
ILazyPojo proxy = newProxy(lazyPojo, serviceBean);
IBeanDescriptor pd = new PojoInjectionDescriptor<>(serviceBean);
pd.getDeclaredTypes().forEach((type) -> addElement(type, name, proxy, pd.getDeclaredQualifiers()));
Object old = beans.put(name, proxy);
Preconditions.checkArgument(old == null, "Duplicate bean " + old);
}
@Override
public > void addServiceFactory(
Class iface, Class factoryBean, IServiceContext context) {
addServiceFactory(iface, generateGlobalName(iface), factoryBean, context);
}
@Override
public > void addServiceFactory(
Class iface, String name, Class factoryBean, IServiceContext context) {
IPojoInitializer initializer = getInitializer(context);
IPropertyResolver resolver = getResolver(context);
ILazyPojo lazyPojo = LazyPojo.forFactory(iface, factoryBean, resolver, initializer);
ILazyPojo proxy = newProxy(lazyPojo, factoryBean);
IBeanDescriptor pd = new PojoInjectionDescriptor<>(iface);
pd.getDeclaredTypes().forEach((type) -> addElement(type, name, proxy, pd.getDeclaredQualifiers()));
beans.put(name, proxy);
}
@Override
public S getService(Class iface) {
Optional optional = getOptionalService(iface);
Preconditions.checkArgument(optional.isPresent(), String.format("Missing %s", iface));
return iface.cast(optional.get());
}
@Override
public S getService(Class iface, String name) {
S service = iface.cast(beans.get(name));
Objects.requireNonNull(service);
return service;
}
@Override
public Optional getOptionalService(Class iface) {
Optional> first = getServiceMap(iface).values().stream().findFirst();
return first.map(ILazyPojo::getInstance);
}
@Override
public Optional getOptionalService(Class iface, String name) {
Object bean = beans.get(name);
if (bean != null && iface.isAssignableFrom(bean.getClass())) {
return Optional.of(iface.cast(bean));
}
return Optional.empty();
}
private void addElement(Class> registrable, String name, ILazyPojo> proxy, Set qualifiers) {
Map> s = services.computeIfAbsent(registrable, r -> new ConcurrentHashMap<>());
s.put(name, proxy);
Map> q = this.qualifiers.computeIfAbsent(registrable, r -> new ConcurrentHashMap<>());
for (Annotation qualifier : qualifiers) {
Object prev = q.put(qualifier, proxy);
Preconditions.checkArgument(prev == null,
String.format("Duplicate qualifier %s for type %s", qualifier, registrable));
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private Map> getServiceMap(Class registrable) {
Preconditions.checkNotNull(registrable);
Map map = services.getOrDefault(registrable, Collections.emptyMap());
if (map != null) {
return map;
} else {
return ImmutableMap.of();
}
}
@Override
public Collection getServices(Class registrable) {
Map> map = getServiceMap(registrable);
if (map != null) {
return ImmutableList.copyOf(map.values().stream().map(ILazyPojo::getInstance).iterator());
} else {
return ImmutableList.of();
}
}
@Override
public void addSingleton(T serviceBean) {
addSingleton(Objects.toString(serviceBean), serviceBean);
}
@SuppressWarnings("unchecked")
@Override
public void addSingleton(String name, T serviceBean) {
ILazyPojo pojo = LazyPojo.forSingleton(serviceBean);
IBeanDescriptor pd = new PojoInjectionDescriptor((Class) serviceBean.getClass());
pd.getDeclaredTypes().forEach((type) -> addElement(type, name, pojo, pd.getDeclaredQualifiers()));
beans.put(name, pojo);
}
public Collection> getBeans() {
Builder> builder = ImmutableList.builder();
builder.addAll(services.keySet());
// builder.addAll(providers.values())
return builder.build();
}
public Collection getBeanNames() {
return beans.keySet();
}
public Map getBeansOfType(Class type) {
Map> map = getServiceMap(type);
return map.entrySet().stream().collect(
Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getInstance()));
}
public Object getBean(String name) {
ILazyPojo> pojo = beans.get(name);
if (pojo != null) {
return pojo.getInstance();
} else {
return null;
}
}
@Override
public IPropertyResolver toResolver() {
return resolver;
}
@Override
public IBeanInjector toBeanInjector() {
return new BeanInjector(toResolver(), pojoInitializer);
}
@SuppressWarnings("serial")
private class ServiceRegistryPropertyResolver extends AbstractPropertyResolver {
@Override
protected Object findByQualifier(Object pojo, Class> type, Annotation qualifier) {
ILazyPojo> lazyPojo = qualifiers.getOrDefault(type, Collections.emptyMap()).get(qualifier);
if (lazyPojo != null) {
return lazyPojo.getInstance();
} else {
return null;
}
}
@Override
protected Object findByName(Object pojo, String name, Class> type) {
return getOptionalService(type, name).orElse(null);
}
@Override
protected Object findByType(Object pojo, Class> type) {
return getOptionalService(type).orElse(null);
}
@Override
protected Collection> findAllByType(Object pojo, Class> type) {
return getServices(type);
}
};
}