1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.shiro.guice.web;
20
21 import java.lang.reflect.Constructor;
22 import java.util.Collections;
23 import java.util.HashSet;
24 import java.util.Set;
25
26 import com.google.inject.Inject;
27 import com.google.inject.Injector;
28 import com.google.inject.Key;
29 import com.google.inject.ProvisionException;
30 import com.google.inject.spi.Dependency;
31 import com.google.inject.spi.InjectionPoint;
32 import com.google.inject.spi.ProviderWithDependencies;
33
34 class AbstractInjectionProvider<T> implements ProviderWithDependencies<T> {
35 private Key<T> key;
36
37 @Inject
38 Injector injector;
39
40 private InjectionPoint constructorInjectionPoint;
41 private Set<Dependency<?>> dependencies;
42
43 public AbstractInjectionProvider(Key<T> key) {
44 this.key = key;
45 constructorInjectionPoint = InjectionPoint.forConstructorOf(key.getTypeLiteral());
46
47 Set<Dependency<?>> dependencyBuilder = new HashSet<Dependency<?>>();
48 dependencyBuilder.addAll(constructorInjectionPoint.getDependencies());
49 for (InjectionPoint injectionPoint : InjectionPoint.forInstanceMethodsAndFields(key.getTypeLiteral())) {
50 dependencyBuilder.addAll(injectionPoint.getDependencies());
51 }
52 this.dependencies = Collections.unmodifiableSet(dependencyBuilder);
53 }
54
55 public T get() {
56 Constructor<T> constructor = getConstructor();
57 Object[] params = new Object[constructor.getParameterTypes().length];
58 for (Dependency<?> dependency : constructorInjectionPoint.getDependencies()) {
59 params[dependency.getParameterIndex()] = injector.getInstance(dependency.getKey());
60 }
61 T t;
62 try {
63 t = constructor.newInstance(params);
64 } catch (Exception e) {
65 throw new ProvisionException("Could not instantiate " + key + "", e);
66 }
67 injector.injectMembers(t);
68 return postProcess(t);
69 }
70
71 @SuppressWarnings({"unchecked"})
72 private Constructor<T> getConstructor() {
73 return (Constructor<T>) constructorInjectionPoint.getMember();
74 }
75
76 protected T postProcess(T t) {
77
78 return t;
79 }
80
81 public Set<Dependency<?>> getDependencies() {
82 return dependencies;
83 }
84 }