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

com.github.ruediste.salta.standard.ProviderMethodBinder Maven / Gradle / Ivy

Go to download

Core of the Salta Framework. Provides most of the infrastructure, but no API

There is a newer version: 1.1
Show newest version
package com.github.ruediste.salta.standard;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.util.ArrayList;

import org.objectweb.asm.commons.GeneratorAdapter;

import com.github.ruediste.salta.core.CoreDependencyKey;
import com.github.ruediste.salta.core.RecipeCreationContext;
import com.github.ruediste.salta.core.Scope;
import com.github.ruediste.salta.core.StaticBinding;
import com.github.ruediste.salta.core.compile.MethodCompilationContext;
import com.github.ruediste.salta.core.compile.SupplierRecipe;
import com.github.ruediste.salta.matchers.Matcher;
import com.github.ruediste.salta.standard.config.StandardInjectorConfiguration;
import com.github.ruediste.salta.standard.recipe.FixedMethodInvocationFunctionRecipe;
import com.google.common.reflect.TypeToken;

/**
 * Scans an instance for methods which are used to create instances and binds
 * them.
 */
public abstract class ProviderMethodBinder {
	private StandardInjectorConfiguration config;

	public ProviderMethodBinder(StandardInjectorConfiguration config) {
		this.config = config;
	}

	public void bindProviderMethodsOf(Object instance) {
		for (TypeToken t : TypeToken.of(instance.getClass()).getTypes()) {
			Class cls = t.getRawType();
			if (cls.isInterface())
				continue;

			for (Method m : cls.getDeclaredMethods()) {
				if (Modifier.isStatic(m.getModifiers()) || m.isBridge()
						|| m.isSynthetic()) {
					continue;
				}
				if (!isProviderMethod(m)) {
					continue;
				}
				m.setAccessible(true);

				TypeToken boundType = t
						.resolveType(m.getGenericReturnType());
				Matcher> matcher = CoreDependencyKey
						.typeMatcher(boundType).and(
								config.requredQualifierMatcher(config
										.getAvailableQualifier(m)));

				config.config.staticBindings.add(new StaticBinding() {

					@Override
					protected SupplierRecipe createRecipe(
							RecipeCreationContext ctx) {
						ArrayList args = new ArrayList<>();
						Parameter[] parameters = m.getParameters();
						for (int i = 0; i < parameters.length; i++) {
							Parameter p = parameters[i];
							args.add(ctx.getRecipe(new InjectionPoint<>(t
									.resolveType(p.getParameterizedType()), m,
									p, i)));
						}
						FixedMethodInvocationFunctionRecipe methodRecipe = new FixedMethodInvocationFunctionRecipe(
								m, args, config.config.injectionStrategy);
						return new SupplierRecipe() {

							@Override
							protected Class compileImpl(GeneratorAdapter mv,
									MethodCompilationContext ctx) {
								ctx.addFieldAndLoad(Object.class, instance);
								return methodRecipe.compile(Object.class, ctx);
							}
						};
					}

					@Override
					public String toString() {
						return "ProviderMethodBinding " + m;
					}

					@Override
					public Matcher> getMatcher() {
						return matcher;
					}

					@Override
					protected Scope getScopeImpl() {
						return config.getScope(m);
					}
				});
			}
			cls = cls.getSuperclass();
		}
	}

	protected abstract boolean isProviderMethod(Method m);
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy