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