1 /*
2  * Copyright (C) 2008 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.inject.spi;
18 
19 import static com.google.common.base.Preconditions.checkNotNull;
20 
21 import com.google.common.base.Objects;
22 import com.google.common.collect.ImmutableSet;
23 import com.google.common.collect.Lists;
24 import com.google.inject.Key;
25 import com.google.inject.internal.MoreTypes;
26 import java.util.List;
27 import java.util.Set;
28 
29 /**
30  * A variable that can be resolved by an injector.
31  *
32  * <p>Use {@link #get} to build a freestanding dependency, or {@link InjectionPoint} to build one
33  * that's attached to a constructor, method or field.
34  *
35  * @author crazybob@google.com (Bob Lee)
36  * @author jessewilson@google.com (Jesse Wilson)
37  * @since 2.0
38  */
39 public final class Dependency<T> {
40   private final InjectionPoint injectionPoint;
41   private final Key<T> key;
42   private final boolean nullable;
43   private final int parameterIndex;
44 
Dependency(InjectionPoint injectionPoint, Key<T> key, boolean nullable, int parameterIndex)45   Dependency(InjectionPoint injectionPoint, Key<T> key, boolean nullable, int parameterIndex) {
46     this.injectionPoint = injectionPoint;
47     this.key = checkNotNull(key, "key");
48     this.nullable = nullable;
49     this.parameterIndex = parameterIndex;
50   }
51 
52   /**
53    * Returns a new dependency that is not attached to an injection point. The returned dependency is
54    * nullable.
55    */
get(Key<T> key)56   public static <T> Dependency<T> get(Key<T> key) {
57     return new Dependency<T>(null, MoreTypes.canonicalizeKey(key), true, -1);
58   }
59 
60   /** Returns the dependencies from the given injection points. */
forInjectionPoints(Set<InjectionPoint> injectionPoints)61   public static Set<Dependency<?>> forInjectionPoints(Set<InjectionPoint> injectionPoints) {
62     List<Dependency<?>> dependencies = Lists.newArrayList();
63     for (InjectionPoint injectionPoint : injectionPoints) {
64       dependencies.addAll(injectionPoint.getDependencies());
65     }
66     return ImmutableSet.copyOf(dependencies);
67   }
68 
69   /** Returns the key to the binding that satisfies this dependency. */
getKey()70   public Key<T> getKey() {
71     return this.key;
72   }
73 
74   /** Returns true if null is a legal value for this dependency. */
isNullable()75   public boolean isNullable() {
76     return nullable;
77   }
78 
79   /**
80    * Returns the injection point to which this dependency belongs, or null if this dependency isn't
81    * attached to a particular injection point.
82    */
getInjectionPoint()83   public InjectionPoint getInjectionPoint() {
84     return injectionPoint;
85   }
86 
87   /**
88    * Returns the index of this dependency in the injection point's parameter list, or {@code -1} if
89    * this dependency does not belong to a parameter list. Only method and constuctor dependencies
90    * are elements in a parameter list.
91    */
getParameterIndex()92   public int getParameterIndex() {
93     return parameterIndex;
94   }
95 
96   @Override
hashCode()97   public int hashCode() {
98     return Objects.hashCode(injectionPoint, parameterIndex, key);
99   }
100 
101   @Override
equals(Object o)102   public boolean equals(Object o) {
103     if (o instanceof Dependency) {
104       Dependency dependency = (Dependency) o;
105       return Objects.equal(injectionPoint, dependency.injectionPoint)
106           && Objects.equal(parameterIndex, dependency.parameterIndex)
107           && Objects.equal(key, dependency.key);
108     } else {
109       return false;
110     }
111   }
112 
113   @Override
toString()114   public String toString() {
115     StringBuilder builder = new StringBuilder();
116     builder.append(key);
117     if (injectionPoint != null) {
118       builder.append("@").append(injectionPoint);
119       if (parameterIndex != -1) {
120         builder.append("[").append(parameterIndex).append("]");
121       }
122     }
123     return builder.toString();
124   }
125 }
126