public Provider<T> asProvider() { return new ProviderWithDependencies<T>() { @Override public T get() { return Injection.wrappingExceptions(asSupplier()); } @Override public Set<Dependency<?>> getDependencies() { return dependencies; } }; }
private ProviderWithDependencies<Result> createResultProvider( final Key<? extends CheckedProvider<?>> targetKey, final Provider<? extends CheckedProvider<?>> targetProvider) { return new ProviderWithDependencies<Result>() { @Override public Result get() { try { return Result.forValue(targetProvider.get().get()); } catch (Exception e) { for (Class<? extends Throwable> exceptionType : exceptionTypes) { if (exceptionType.isInstance(e)) { if (scopeExceptions) { return Result.forException(e); } else { throw new ResultException(e); } } } if (e instanceof RuntimeException) { throw (RuntimeException) e; } else { // this should never happen throw new RuntimeException(e); } } } @Override public Set<Dependency<?>> getDependencies() { return ImmutableSet.<Dependency<?>>of(Dependency.get(targetKey)); } }; }
private ScopedBindingBuilder toInternal(final Key<? extends CheckedProvider<?>> targetKey) { final Key<Result> resultKey = Key.get(Result.class, UniqueAnnotations.create()); // Note that this provider will behave like the final provider Guice creates. // It will especially do scoping if the user adds that. final Provider<Result> resultProvider = binder.getProvider(resultKey); final Provider<? extends CheckedProvider<?>> targetProvider = binder.getProvider(targetKey); interfaceKey = createKey(); // don't bother binding the proxy type if this is in an invalid state. if (valid) { binder .bind(interfaceKey) .toProvider( new ProviderWithDependencies<P>() { private final P instance = interfaceType.cast( Proxy.newProxyInstance( interfaceType.getClassLoader(), new Class<?>[] {interfaceType}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // Allow methods like .equals(..), .hashcode(..), .toString(..) to work. if (method.getDeclaringClass() == Object.class) { return method.invoke(this, args); } if (scopeExceptions) { return resultProvider.get().getOrThrow(); } else { Result result; try { result = resultProvider.get(); } catch (ProvisionException pe) { Throwable cause = pe.getCause(); if (cause instanceof ResultException) { throw ((ResultException) cause).getCause(); } else { throw pe; } } return result.getOrThrow(); } } })); @Override public P get() { return instance; } @Override public Set<Dependency<?>> getDependencies() { return ImmutableSet.<Dependency<?>>of(Dependency.get(resultKey)); } }); } // The provider is unscoped, but the user may apply a scope to it through the // ScopedBindingBuilder this returns. return binder.bind(resultKey).toProvider(createResultProvider(targetKey, targetProvider)); }
private ScopedBindingBuilder toInternal(final Key<? extends CheckedProvider> targetKey) { final Key<Result> resultKey = Key.get(Result.class, UniqueAnnotations.create()); final Provider<Result> resultProvider = binder.getProvider(resultKey); final Provider<? extends CheckedProvider> targetProvider = binder.getProvider(targetKey); interfaceKey = createKey(); // don't bother binding the proxy type if this is in an invalid state. if(valid) { binder.bind(interfaceKey).toProvider(new ProviderWithDependencies<P>() { private final P instance = interfaceType.cast(Proxy.newProxyInstance( interfaceType.getClassLoader(), new Class<?>[] { interfaceType }, new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // Allow methods like .equals(..), .hashcode(..), .toString(..) to work. if (method.getDeclaringClass() == Object.class) { return method.invoke(this, args); } return resultProvider.get().getOrThrow(); } })); public P get() { return instance; } public Set<Dependency<?>> getDependencies() { return ImmutableSet.<Dependency<?>>of(Dependency.get(resultKey)); } }); } return binder.bind(resultKey).toProvider(new ProviderWithDependencies<Result>() { public Result get() { try { return Result.forValue(targetProvider.get().get()); } catch (Exception e) { for(Class<? extends Throwable> exceptionType : exceptionTypes) { if (exceptionType.isInstance(e)) { return Result.forException(e); } } if (e instanceof RuntimeException) { throw (RuntimeException) e; } else { // this should never happen throw new RuntimeException(e); } } } public Set<Dependency<?>> getDependencies() { return ImmutableSet.<Dependency<?>>of(Dependency.get(targetKey)); } }); }
/** * Returns a Guice-friendly {@code com.google.inject.Provider} for the given * JSR-330 {@code javax.inject.Provider}. The converse method is unnecessary, * since Guice providers directly implement the JSR-330 interface. * * @since 3.0 */ public static <T> Provider<T> guicify(javax.inject.Provider<T> provider) { if (provider instanceof Provider) { return (Provider<T>) provider; } final javax.inject.Provider<T> delegate = checkNotNull(provider, "provider"); // Ensure that we inject all injection points from the delegate provider. Set<InjectionPoint> injectionPoints = InjectionPoint.forInstanceMethodsAndFields(provider.getClass()); if(injectionPoints.isEmpty()) { return new Provider<T>() { public T get() { return delegate.get(); } @Override public String toString() { return "guicified(" + delegate + ")"; } }; } else { Set<Dependency<?>> mutableDeps = Sets.newHashSet(); for(InjectionPoint ip : injectionPoints) { mutableDeps.addAll(ip.getDependencies()); } final Set<Dependency<?>> dependencies = ImmutableSet.copyOf(mutableDeps); return new ProviderWithDependencies<T>() { @SuppressWarnings("unused") @Inject void initialize(Injector injector) { injector.injectMembers(delegate); } public Set<Dependency<?>> getDependencies() { return dependencies; } public T get() { return delegate.get(); } @Override public String toString() { return "guicified(" + delegate + ")"; } }; } }