blob: bc40e757ac58b5745ed6b076712d7734455f9a4f [file] [log] [blame]
crazyboblee66b415a2006-08-25 02:01:19 +00001/**
2 * Copyright (C) 2006 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
17package com.google.inject;
18
crazyboblee07e41822006-11-21 01:27:08 +000019import static com.google.inject.util.Objects.nonNull;
crazyboblee6ab7e1f2006-12-02 00:20:36 +000020import java.lang.reflect.Type;
crazyboblee6ab7e1f2006-12-02 00:20:36 +000021
crazyboblee66b415a2006-08-25 02:01:19 +000022/**
kevinb9na99dca72007-02-11 04:48:57 +000023 * Binding key consisting of a type and a name. Matches the type and name
24 * ({@link Inject#value()}) at a point of injection.
crazyboblee41bc8522006-12-08 07:06:55 +000025 *
kevinb9na99dca72007-02-11 04:48:57 +000026 * <p>For example, {@code new Key<List<String>>("cities") {}} will match:
crazyboblee41bc8522006-12-08 07:06:55 +000027 *
crazyboblee63b592b2007-01-25 02:45:24 +000028 * <pre>
kevinb9na99dca72007-02-11 04:48:57 +000029 * {@literal @}Inject("cities")
crazyboblee7c5b2c42007-01-20 02:05:20 +000030 * public void setList(List&lt;String> cities) {
crazyboblee41bc8522006-12-08 07:06:55 +000031 * ...
32 * }
crazyboblee63b592b2007-01-25 02:45:24 +000033 * </pre>
crazyboblee66b415a2006-08-25 02:01:19 +000034 *
35 * @author crazybob@google.com (Bob Lee)
36 */
crazyboblee6ab7e1f2006-12-02 00:20:36 +000037public abstract class Key<T> {
38
39 /**
crazybobleeed8825f2006-12-06 01:28:10 +000040 * Default binding name.
crazyboblee6ab7e1f2006-12-02 00:20:36 +000041 */
42 public static final String DEFAULT_NAME = "default";
crazyboblee66b415a2006-08-25 02:01:19 +000043
crazyboblee66b415a2006-08-25 02:01:19 +000044 final String name;
crazyboblee0baa9fc2007-01-31 02:38:54 +000045 final TypeLiteral<T> typeLiteral;
crazyboblee41bc8522006-12-08 07:06:55 +000046 final int hashCode;
crazyboblee66b415a2006-08-25 02:01:19 +000047
crazybobleeed8825f2006-12-06 01:28:10 +000048 /**
49 * Constructs a new key. Derives the type from this class's type parameter.
crazyboblee41bc8522006-12-08 07:06:55 +000050 *
51 * <p>Clients create an empty anonymous subclass. Doing so embeds the type
kevinb9na99dca72007-02-11 04:48:57 +000052 * parameter in the anonymous class's type hierarchy so we can reconstitute it
53 * at runtime despite erasure.
crazybobleeed8825f2006-12-06 01:28:10 +000054 *
55 * <p>Example usage for a binding of type {@code Foo} named "bar":
56 * {@code new Key<Foo>("bar") {}}.
crazybobleeed8825f2006-12-06 01:28:10 +000057 */
kevinb9na99dca72007-02-11 04:48:57 +000058 @SuppressWarnings("unchecked")
crazyboblee6ab7e1f2006-12-02 00:20:36 +000059 protected Key(String name) {
60 this.name = nonNull(name, "name");
kevinb9na99dca72007-02-11 04:48:57 +000061 this.typeLiteral
62 = (TypeLiteral<T>) TypeLiteral.fromSuperclassTypeParameter(getClass());
crazyboblee41bc8522006-12-08 07:06:55 +000063 this.hashCode = computeHashCode();
crazyboblee6ab7e1f2006-12-02 00:20:36 +000064 }
65
crazybobleeed8825f2006-12-06 01:28:10 +000066 /**
67 * Convenience method. Delegates to {@link #Key(String)} with
68 * {@link #DEFAULT_NAME}.
69 */
crazyboblee6ab7e1f2006-12-02 00:20:36 +000070 protected Key() {
71 this(DEFAULT_NAME);
72 }
73
crazyboblee41bc8522006-12-08 07:06:55 +000074 /**
75 * Unsafe. Constructs a key from a manually specified type.
76 */
kevinb9na99dca72007-02-11 04:48:57 +000077 @SuppressWarnings("unchecked")
crazybobleeed8825f2006-12-06 01:28:10 +000078 private Key(Type type, String name) {
crazyboblee07e41822006-11-21 01:27:08 +000079 this.name = nonNull(name, "name");
crazyboblee0baa9fc2007-01-31 02:38:54 +000080 this.typeLiteral = (TypeLiteral<T>) TypeLiteral.get(type);
crazyboblee41bc8522006-12-08 07:06:55 +000081 this.hashCode = computeHashCode();
crazyboblee6ab7e1f2006-12-02 00:20:36 +000082 }
83
kevinb9na99dca72007-02-11 04:48:57 +000084 /** Constructs a key from a manually specified type. */
crazyboblee0baa9fc2007-01-31 02:38:54 +000085 private Key(TypeLiteral<T> typeLiteral, String name) {
crazyboblee41bc8522006-12-08 07:06:55 +000086 this.name = nonNull(name, "name");
crazyboblee0baa9fc2007-01-31 02:38:54 +000087 this.typeLiteral = typeLiteral;
crazyboblee41bc8522006-12-08 07:06:55 +000088 this.hashCode = computeHashCode();
crazyboblee66b415a2006-08-25 02:01:19 +000089 }
90
crazyboblee41bc8522006-12-08 07:06:55 +000091 private int computeHashCode() {
crazyboblee0baa9fc2007-01-31 02:38:54 +000092 return typeLiteral.hashCode() * 31 + name.hashCode();
crazybobleeed8825f2006-12-06 01:28:10 +000093 }
94
95 /**
crazybobleeb9446682006-12-11 07:16:41 +000096 * Returns {@code true} if this key has the default name.
97 */
98 public boolean hasDefaultName() {
99 return DEFAULT_NAME.equals(this.name);
100 }
101
102 /**
103 * Returns a new key with the same type as this key and the given name,
104 */
crazybobleefc9337f2007-01-26 00:51:34 +0000105 Key<T> named(String name) {
crazyboblee0baa9fc2007-01-31 02:38:54 +0000106 return new SimpleKey<T>(this.typeLiteral, name);
crazybobleeb9446682006-12-11 07:16:41 +0000107 }
108
109 /**
crazyboblee0baa9fc2007-01-31 02:38:54 +0000110 * Gets the key type.
crazybobleeed8825f2006-12-06 01:28:10 +0000111 */
crazyboblee0baa9fc2007-01-31 02:38:54 +0000112 public TypeLiteral<T> getType() {
113 return typeLiteral;
crazybobleeed8825f2006-12-06 01:28:10 +0000114 }
115
116 /**
117 * Gets the binding name.
118 */
kevinb9na99dca72007-02-11 04:48:57 +0000119 public String getName() {
crazyboblee66b415a2006-08-25 02:01:19 +0000120 return name;
121 }
122
crazybobleeed8825f2006-12-06 01:28:10 +0000123 public int hashCode() {
crazyboblee41bc8522006-12-08 07:06:55 +0000124 return this.hashCode;
crazybobleeed8825f2006-12-06 01:28:10 +0000125 }
126
crazybobleef1ba2b52007-01-29 21:19:53 +0000127 Class<? super T> getRawType() {
crazyboblee0baa9fc2007-01-31 02:38:54 +0000128 return typeLiteral.getRawType();
crazybobleed42a05b2006-12-07 01:00:33 +0000129 }
130
crazyboblee66b415a2006-08-25 02:01:19 +0000131 public boolean equals(Object o) {
crazyboblee66b415a2006-08-25 02:01:19 +0000132 if (o == this) {
133 return true;
134 }
crazyboblee41bc8522006-12-08 07:06:55 +0000135 if (!(o instanceof Key<?>)) {
crazybobleeed8825f2006-12-06 01:28:10 +0000136 return false;
137 }
crazyboblee41bc8522006-12-08 07:06:55 +0000138 Key<?> other = (Key<?>) o;
crazyboblee0baa9fc2007-01-31 02:38:54 +0000139 return name.equals(other.name) && typeLiteral.equals(other.typeLiteral);
crazyboblee66b415a2006-08-25 02:01:19 +0000140 }
141
142 public String toString() {
crazyboblee41bc8522006-12-08 07:06:55 +0000143 return Key.class.getSimpleName()
crazyboblee0baa9fc2007-01-31 02:38:54 +0000144 + "[type=" + typeLiteral + ", name='" + name + "']";
crazyboblee66b415a2006-08-25 02:01:19 +0000145 }
146
crazyboblee6ab7e1f2006-12-02 00:20:36 +0000147 /**
crazyboblee41bc8522006-12-08 07:06:55 +0000148 * Gets a key for a {@code Class}. Defaults name to {@link #DEFAULT_NAME}.
crazyboblee6ab7e1f2006-12-02 00:20:36 +0000149 */
crazyboblee41bc8522006-12-08 07:06:55 +0000150 public static <T> Key<T> get(Class<T> type) {
crazybobleeb9446682006-12-11 07:16:41 +0000151 return new SimpleKey<T>(type, DEFAULT_NAME);
crazyboblee6ab7e1f2006-12-02 00:20:36 +0000152 }
153
154 /**
crazyboblee41bc8522006-12-08 07:06:55 +0000155 * Gets a key for a {@code Class} and a name.
crazyboblee6ab7e1f2006-12-02 00:20:36 +0000156 */
crazybobleefc9337f2007-01-26 00:51:34 +0000157 public static <T> Key<T> get(Class<T> type, String name) {
crazybobleeb9446682006-12-11 07:16:41 +0000158 return new SimpleKey<T>(type, name);
crazyboblee66b415a2006-08-25 02:01:19 +0000159 }
crazybobleeed8825f2006-12-06 01:28:10 +0000160
161 /**
crazyboblee41bc8522006-12-08 07:06:55 +0000162 * Gets a key for a type. Defaults name to {@link #DEFAULT_NAME}.
crazybobleeed8825f2006-12-06 01:28:10 +0000163 */
crazyboblee41bc8522006-12-08 07:06:55 +0000164 public static Key<?> get(Type type) {
crazybobleeb9446682006-12-11 07:16:41 +0000165 return new SimpleKey<Object>(type, DEFAULT_NAME);
crazybobleeed8825f2006-12-06 01:28:10 +0000166 }
167
168 /**
crazyboblee41bc8522006-12-08 07:06:55 +0000169 * Gets a key for a type and a name.
crazybobleeed8825f2006-12-06 01:28:10 +0000170 */
crazybobleefc9337f2007-01-26 00:51:34 +0000171 public static Key<?> get(Type type, String name) {
crazybobleeb9446682006-12-11 07:16:41 +0000172 return new SimpleKey<Object>(type, name);
crazyboblee41bc8522006-12-08 07:06:55 +0000173 }
174
175 /**
crazyboblee0baa9fc2007-01-31 02:38:54 +0000176 * Gets a key for a type. Defaults name to {@link #DEFAULT_NAME}.
crazyboblee41bc8522006-12-08 07:06:55 +0000177 */
crazyboblee0baa9fc2007-01-31 02:38:54 +0000178 public static <T> Key<T> get(TypeLiteral<T> typeLiteral) {
179 return new SimpleKey<T>(typeLiteral, DEFAULT_NAME);
crazyboblee41bc8522006-12-08 07:06:55 +0000180 }
181
182 /**
crazyboblee0baa9fc2007-01-31 02:38:54 +0000183 * Gets key for a type and a name.
crazyboblee41bc8522006-12-08 07:06:55 +0000184 */
crazyboblee0baa9fc2007-01-31 02:38:54 +0000185 public static <T> Key<T> get(TypeLiteral<T> typeLiteral, String name) {
186 return new SimpleKey<T>(typeLiteral, name);
crazyboblee41bc8522006-12-08 07:06:55 +0000187 }
188
crazybobleeb9446682006-12-11 07:16:41 +0000189 private static class SimpleKey<T> extends Key<T> {
crazyboblee41bc8522006-12-08 07:06:55 +0000190
crazybobleeb9446682006-12-11 07:16:41 +0000191 private SimpleKey(Type type, String name) {
crazyboblee41bc8522006-12-08 07:06:55 +0000192 super(type, name);
193 }
194
crazyboblee0baa9fc2007-01-31 02:38:54 +0000195 private SimpleKey(TypeLiteral<T> typeLiteral, String name) {
196 super(typeLiteral, name);
crazyboblee41bc8522006-12-08 07:06:55 +0000197 }
crazybobleeed8825f2006-12-06 01:28:10 +0000198 }
crazyboblee66b415a2006-08-25 02:01:19 +0000199}