/** * Copyright (c) 2013-2016, The SeedStack authors <http://seedstack.org> * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.seedstack.seed.web.security.internal.shiro; import com.google.common.collect.ImmutableSet; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.ProvisionException; import com.google.inject.spi.Dependency; import com.google.inject.spi.InjectionPoint; import com.google.inject.spi.ProviderWithDependencies; import java.lang.reflect.Constructor; import java.util.Set; class AbstractInjectionProvider<T> implements ProviderWithDependencies<T> { private Key<T> key; @Inject Injector injector; private InjectionPoint constructorInjectionPoint; private Set<Dependency<?>> dependencies; public AbstractInjectionProvider(Key<T> key) { this.key = key; constructorInjectionPoint = InjectionPoint.forConstructorOf(key.getTypeLiteral()); ImmutableSet.Builder<Dependency<?>> dependencyBuilder = ImmutableSet.builder(); dependencyBuilder.addAll(constructorInjectionPoint.getDependencies()); for (InjectionPoint injectionPoint : InjectionPoint.forInstanceMethodsAndFields(key.getTypeLiteral())) { dependencyBuilder.addAll(injectionPoint.getDependencies()); } this.dependencies = dependencyBuilder.build(); } public T get() { Constructor<T> constructor = getConstructor(); Object[] params = new Object[constructor.getParameterTypes().length]; for (Dependency<?> dependency : constructorInjectionPoint.getDependencies()) { params[dependency.getParameterIndex()] = injector.getInstance(dependency.getKey()); } T t; try { t = constructor.newInstance(params); } catch (Exception e) { throw new ProvisionException("Could not instantiate " + key + "", e); } injector.injectMembers(t); return postProcess(t); } @SuppressWarnings({"unchecked"}) private Constructor<T> getConstructor() { return (Constructor<T>) constructorInjectionPoint.getMember(); } protected T postProcess(T t) { // do nothing by default return t; } public Set<Dependency<?>> getDependencies() { return dependencies; } }