1 /*
2  * Copyright (C) 2007 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 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.Sets;
24 import com.google.inject.Inject;
25 import com.google.inject.Injector;
26 import com.google.inject.Provider;
27 import com.google.inject.spi.Dependency;
28 import com.google.inject.spi.InjectionPoint;
29 import com.google.inject.spi.ProviderWithDependencies;
30 import java.util.Set;
31 
32 /**
33  * Static utility methods for creating and working with instances of {@link Provider}.
34  *
35  * @author Kevin Bourrillion (kevinb9n@gmail.com)
36  * @since 2.0
37  */
38 public final class Providers {
39 
Providers()40   private Providers() {}
41 
42   /**
43    * Returns a provider which always provides {@code instance}. This should not be necessary to use
44    * in your application, but is helpful for several types of unit tests.
45    *
46    * @param instance the instance that should always be provided. This is also permitted to be null,
47    *     to enable aggressive testing, although in real life a Guice-supplied Provider will never
48    *     return null.
49    */
of(final T instance)50   public static <T> Provider<T> of(final T instance) {
51     return new ConstantProvider<T>(instance);
52   }
53 
54   private static final class ConstantProvider<T> implements Provider<T> {
55     private final T instance;
56 
ConstantProvider(T instance)57     private ConstantProvider(T instance) {
58       this.instance = instance;
59     }
60 
61     @Override
get()62     public T get() {
63       return instance;
64     }
65 
66     @Override
toString()67     public String toString() {
68       return "of(" + instance + ")";
69     }
70 
71     @Override
equals(Object obj)72     public boolean equals(Object obj) {
73       return (obj instanceof ConstantProvider)
74           && Objects.equal(instance, ((ConstantProvider<?>) obj).instance);
75     }
76 
77     @Override
hashCode()78     public int hashCode() {
79       return Objects.hashCode(instance);
80     }
81   }
82 
83   /**
84    * Returns a Guice-friendly {@code com.google.inject.Provider} for the given JSR-330 {@code
85    * javax.inject.Provider}. The converse method is unnecessary, since Guice providers directly
86    * implement the JSR-330 interface.
87    *
88    * @since 3.0
89    */
guicify(javax.inject.Provider<T> provider)90   public static <T> Provider<T> guicify(javax.inject.Provider<T> provider) {
91     if (provider instanceof Provider) {
92       return (Provider<T>) provider;
93     }
94 
95     final javax.inject.Provider<T> delegate = checkNotNull(provider, "provider");
96 
97     // Ensure that we inject all injection points from the delegate provider.
98     Set<InjectionPoint> injectionPoints =
99         InjectionPoint.forInstanceMethodsAndFields(provider.getClass());
100     if (injectionPoints.isEmpty()) {
101       return new GuicifiedProvider<T>(delegate);
102     } else {
103       Set<Dependency<?>> mutableDeps = Sets.newHashSet();
104       for (InjectionPoint ip : injectionPoints) {
105         mutableDeps.addAll(ip.getDependencies());
106       }
107       final Set<Dependency<?>> dependencies = ImmutableSet.copyOf(mutableDeps);
108       return new GuicifiedProviderWithDependencies<T>(dependencies, delegate);
109     }
110   }
111 
112   private static class GuicifiedProvider<T> implements Provider<T> {
113     protected final javax.inject.Provider<T> delegate;
114 
GuicifiedProvider(javax.inject.Provider<T> delegate)115     private GuicifiedProvider(javax.inject.Provider<T> delegate) {
116       this.delegate = delegate;
117     }
118 
119     @Override
get()120     public T get() {
121       return delegate.get();
122     }
123 
124     @Override
toString()125     public String toString() {
126       return "guicified(" + delegate + ")";
127     }
128 
129     @Override
equals(Object obj)130     public boolean equals(Object obj) {
131       return (obj instanceof GuicifiedProvider)
132           && Objects.equal(delegate, ((GuicifiedProvider<?>) obj).delegate);
133     }
134 
135     @Override
hashCode()136     public int hashCode() {
137       return Objects.hashCode(delegate);
138     }
139   }
140 
141   private static final class GuicifiedProviderWithDependencies<T> extends GuicifiedProvider<T>
142       implements ProviderWithDependencies<T> {
143     private final Set<Dependency<?>> dependencies;
144 
GuicifiedProviderWithDependencies( Set<Dependency<?>> dependencies, javax.inject.Provider<T> delegate)145     private GuicifiedProviderWithDependencies(
146         Set<Dependency<?>> dependencies, javax.inject.Provider<T> delegate) {
147       super(delegate);
148       this.dependencies = dependencies;
149     }
150 
151     @SuppressWarnings("unused")
152     @Inject
initialize(Injector injector)153     void initialize(Injector injector) {
154       injector.injectMembers(delegate);
155     }
156 
157     @Override
getDependencies()158     public Set<Dependency<?>> getDependencies() {
159       return dependencies;
160     }
161   }
162 }
163