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.util;
18 
19 import com.google.inject.Provider;
20 import com.google.inject.internal.MoreTypes;
21 import com.google.inject.internal.MoreTypes.GenericArrayTypeImpl;
22 import com.google.inject.internal.MoreTypes.ParameterizedTypeImpl;
23 import com.google.inject.internal.MoreTypes.WildcardTypeImpl;
24 import java.lang.reflect.GenericArrayType;
25 import java.lang.reflect.ParameterizedType;
26 import java.lang.reflect.Type;
27 import java.lang.reflect.WildcardType;
28 import java.util.Collection;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Set;
32 
33 /**
34  * Static methods for working with types.
35  *
36  * @author crazybob@google.com (Bob Lee)
37  * @since 2.0
38  */
39 public final class Types {
Types()40   private Types() {}
41 
42   /**
43    * Returns a new parameterized type, applying {@code typeArguments} to {@code rawType}. The
44    * returned type does not have an owner type.
45    *
46    * @return a {@link java.io.Serializable serializable} parameterized type.
47    */
newParameterizedType(Type rawType, Type... typeArguments)48   public static ParameterizedType newParameterizedType(Type rawType, Type... typeArguments) {
49     return newParameterizedTypeWithOwner(null, rawType, typeArguments);
50   }
51 
52   /**
53    * Returns a new parameterized type, applying {@code typeArguments} to {@code rawType} and
54    * enclosed by {@code ownerType}.
55    *
56    * @return a {@link java.io.Serializable serializable} parameterized type.
57    */
newParameterizedTypeWithOwner( Type ownerType, Type rawType, Type... typeArguments)58   public static ParameterizedType newParameterizedTypeWithOwner(
59       Type ownerType, Type rawType, Type... typeArguments) {
60     return new ParameterizedTypeImpl(ownerType, rawType, typeArguments);
61   }
62 
63   /**
64    * Returns an array type whose elements are all instances of {@code componentType}.
65    *
66    * @return a {@link java.io.Serializable serializable} generic array type.
67    */
arrayOf(Type componentType)68   public static GenericArrayType arrayOf(Type componentType) {
69     return new GenericArrayTypeImpl(componentType);
70   }
71 
72   /**
73    * Returns a type that represents an unknown type that extends {@code bound}. For example, if
74    * {@code bound} is {@code CharSequence.class}, this returns {@code ? extends CharSequence}. If
75    * {@code bound} is {@code Object.class}, this returns {@code ?}, which is shorthand for {@code ?
76    * extends Object}.
77    */
subtypeOf(Type bound)78   public static WildcardType subtypeOf(Type bound) {
79     return new WildcardTypeImpl(new Type[] {bound}, MoreTypes.EMPTY_TYPE_ARRAY);
80   }
81 
82   /**
83    * Returns a type that represents an unknown supertype of {@code bound}. For example, if {@code
84    * bound} is {@code String.class}, this returns {@code ? super String}.
85    */
supertypeOf(Type bound)86   public static WildcardType supertypeOf(Type bound) {
87     return new WildcardTypeImpl(new Type[] {Object.class}, new Type[] {bound});
88   }
89 
90   /**
91    * Returns a type modelling a {@link List} whose elements are of type {@code elementType}.
92    *
93    * @return a {@link java.io.Serializable serializable} parameterized type.
94    */
listOf(Type elementType)95   public static ParameterizedType listOf(Type elementType) {
96     return newParameterizedType(List.class, elementType);
97   }
98 
99   /**
100    * Returns a type modelling a {@link Collection} whose elements are of type {@code elementType}.
101    *
102    * @return a {@link java.io.Serializable serializable} parameterized type.
103    */
collectionOf(Type elementType)104   public static ParameterizedType collectionOf(Type elementType) {
105     return newParameterizedType(Collection.class, elementType);
106   }
107 
108   /**
109    * Returns a type modelling a {@link Set} whose elements are of type {@code elementType}.
110    *
111    * @return a {@link java.io.Serializable serializable} parameterized type.
112    */
setOf(Type elementType)113   public static ParameterizedType setOf(Type elementType) {
114     return newParameterizedType(Set.class, elementType);
115   }
116 
117   /**
118    * Returns a type modelling a {@link Map} whose keys are of type {@code keyType} and whose values
119    * are of type {@code valueType}.
120    *
121    * @return a {@link java.io.Serializable serializable} parameterized type.
122    */
mapOf(Type keyType, Type valueType)123   public static ParameterizedType mapOf(Type keyType, Type valueType) {
124     return newParameterizedType(Map.class, keyType, valueType);
125   }
126 
127   // for other custom collections types, use newParameterizedType()
128 
129   /**
130    * Returns a type modelling a {@link Provider} that provides elements of type {@code elementType}.
131    *
132    * @return a {@link java.io.Serializable serializable} parameterized type.
133    */
providerOf(Type providedType)134   public static ParameterizedType providerOf(Type providedType) {
135     return newParameterizedType(Provider.class, providedType);
136   }
137 
138   /**
139    * Returns a type modelling a {@link javax.inject.Provider} that provides elements of type {@code
140    * elementType}.
141    *
142    * @return a {@link java.io.Serializable serializable} parameterized type.
143    */
javaxProviderOf(Type type)144   public static Type javaxProviderOf(Type type) {
145     return Types.newParameterizedType(javax.inject.Provider.class, type);
146   }
147 }
148