View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.shiro.guice.web;
20  
21  import com.google.common.collect.ImmutableSet;
22  import com.google.inject.Inject;
23  import com.google.inject.Injector;
24  import com.google.inject.Key;
25  import com.google.inject.ProvisionException;
26  import com.google.inject.spi.Dependency;
27  import com.google.inject.spi.InjectionPoint;
28  import com.google.inject.spi.ProviderWithDependencies;
29  
30  import java.lang.reflect.Constructor;
31  import java.util.Set;
32  
33  class AbstractInjectionProvider<T> implements ProviderWithDependencies<T> {
34      private Key<T> key;
35  
36      @Inject
37      Injector injector;
38  
39      private InjectionPoint constructorInjectionPoint;
40      private Set<Dependency<?>> dependencies;
41  
42      public AbstractInjectionProvider(Key<T> key) {
43          this.key = key;
44          constructorInjectionPoint = InjectionPoint.forConstructorOf(key.getTypeLiteral());
45  
46          ImmutableSet.Builder<Dependency<?>> dependencyBuilder = ImmutableSet.builder();
47          dependencyBuilder.addAll(constructorInjectionPoint.getDependencies());
48          for (InjectionPoint injectionPoint : InjectionPoint.forInstanceMethodsAndFields(key.getTypeLiteral())) {
49              dependencyBuilder.addAll(injectionPoint.getDependencies());
50          }
51          this.dependencies = dependencyBuilder.build();
52      }
53  
54      public T get() {
55          Constructor<T> constructor = getConstructor();
56          Object[] params = new Object[constructor.getParameterTypes().length];
57          for (Dependency<?> dependency : constructorInjectionPoint.getDependencies()) {
58              params[dependency.getParameterIndex()] = injector.getInstance(dependency.getKey());
59          }
60          T t;
61          try {
62              t = constructor.newInstance(params);
63          } catch (Exception e) {
64              throw new ProvisionException("Could not instantiate " + key + "", e);
65          }
66          injector.injectMembers(t);
67          return postProcess(t);
68      }
69  
70      @SuppressWarnings({"unchecked"})
71      private Constructor<T> getConstructor() {
72          return (Constructor<T>) constructorInjectionPoint.getMember();
73      }
74  
75      protected T postProcess(T t) {
76          // do nothing by default
77          return t;
78      }
79  
80      public Set<Dependency<?>> getDependencies() {
81          return dependencies;
82      }
83  }