All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.nill14.utils.moduledi.guice.GuiceServiceRegistry Maven / Gradle / Ivy

package com.github.nill14.utils.moduledi.guice;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.inject.Provider;

import com.github.nill14.utils.init.api.IBeanInjector;
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.impl.LazyPojo;
import com.google.inject.Binder;
import com.google.inject.Binding;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;

public class GuiceServiceRegistry implements IServiceRegistry {

	private final Injector injector;
	private final Binder b;

	public GuiceServiceRegistry() {
		ModuleInternal module = new ModuleInternal();
		injector = Guice.createInjector(module);
		b = module.binder;
		try {
			Field field = b.getClass().getDeclaredField("moduleSource");
			field.setAccessible(true);
			field.set(b, module.moduleSource);
		} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	private final class ModuleInternal implements Module {

		private Binder binder;
		private Object moduleSource;

		@Override
		public void configure(Binder binder) {
			this.binder = binder;
			try {
				Field field = binder.getClass().getDeclaredField("moduleSource");
				field.setAccessible(true);
				moduleSource = field.get(b);
			} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		
	}
	
	protected void configure() {
//		 *     bind(Service.class).to(ServiceImpl.class).in(Singleton.class);
//		 *     bind(CreditCardPaymentService.class);
//		 *     bind(PaymentService.class).to(CreditCardPaymentService.class);
//		 *     bindConstant().annotatedWith(Names.named("port")).to(8080);
	}
	
	@Override
	public  void addSingleton(T serviceBean) {
		Class clazz = getClass(serviceBean);
		b.bind(clazz).toInstance(serviceBean);
//		b.install(bn -> bn.bind(clazz).toInstance(serviceBean));
	}

	@SuppressWarnings("unchecked")
	private  Class getClass(T serviceBean) {
		return (Class) serviceBean.getClass();
	}

	@Override
	public  void addSingleton(String name, T serviceBean) {
		Class clazz = getClass(serviceBean);
		
		b.bind(clazz).annotatedWith(Names.named(name)).toInstance(serviceBean);
//		b.bind(clazz).toInstance(serviceBean);
	}

	@Override
	public  void addService(Class serviceBean, IServiceContext context) {
		b.bind(serviceBean);
	}

	@Override
	public  void addService(String name, Class serviceBean, IServiceContext context) {
		b.bind(serviceBean).annotatedWith(Names.named(name));
	}

	@Override
	public > void addServiceFactory(Class iface, String name,
			Class factoryBean, IServiceContext context) {
		b.bind(iface).annotatedWith(Names.named(name)).toProvider(toProvider(iface, factoryBean));
	}

	@Override
	public > void addServiceFactory(Class iface,
			Class factoryBean, IServiceContext context) {
		b.bind(iface).toProvider(toProvider(iface, factoryBean));
	}

	@Override
	public  S getService(Class iface) {
		return injector.getInstance(iface);
	}

	@Override
	public  Optional getOptionalService(Class iface) {
		Binding binding = injector.getBinding(iface);
//		binding.acceptVisitor(visitor)
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public  S getService(Class iface, String name) {
		return injector.getInstance(Key.get(iface, Names.named(name)));
	}

	@Override
	public  Optional getOptionalService(Class iface, String name) {
		Binding binding = injector.getBinding(Key.get(iface, Names.named(name)));
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public  Collection getServices(Class registrable) {
		List> bindings = injector.findBindingsByType(TypeLiteral.get(registrable));
		return bindings.stream()
				.map(b -> b.getProvider().get())
				.collect(Collectors.toList());
	}
	
	private > Provider toProvider(Class iface,	Class factoryClass) {
		//TODO injection for bean
		return () -> LazyPojo.forFactory(iface, factoryClass).getInstance();
	}

	@Override
	public IPropertyResolver toResolver() {
		return new GuicePropertyResolver(injector);
	}

	@Override
	public IBeanInjector toBeanInjector() {
		return new GuiceBeanInjector(injector);
	}
	
}