Revision: e6abeff86010
Author: Sam Berlin <[email protected]>
Date: Sun May 27 10:39:59 2012
Log: Change the new ThrowingProviderBinder.providing to look for
@ThrowingInject instead of @Inject.
Revision created by MOE tool push_codebase.
MOE_MIGRATION=4875
http://code.google.com/p/google-guice/source/detail?r=e6abeff86010
Added:
/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingInject.java
Modified:
/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvideUtils.java
/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java
/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProviderTest.java
=======================================
--- /dev/null
+++
/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingInject.java
Sun May 27 10:39:59 2012
@@ -0,0 +1,42 @@
+/**
+ * Copyright (C) 2012 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.inject.throwingproviders;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.google.inject.Inject;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * A version of {@literal @}{@link Inject} designed for
ThrowingProviders. Use by:
+ * <pre><code>ThrowingProviderBinder.create(binder())
+ * .bind(RemoteProvider.class, Customer.class)
+ * .providing(CustomerImpl.class);
+ * </code></pre>
+ * where CustomerImpl has a constructor annotated with ThrowingInject.
+ *
+ * @author [email protected] (Sam Berlin)
+ */
+@Target({ CONSTRUCTOR })
+@Retention(RUNTIME)
+@Documented
+public @interface ThrowingInject {
+}
=======================================
---
/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvideUtils.java
Thu Mar 1 11:21:26 2012
+++
/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvideUtils.java
Sun May 27 10:39:59 2012
@@ -4,6 +4,13 @@
import com.google.inject.Binder;
import com.google.inject.TypeLiteral;
+import com.google.inject.internal.Annotations;
+import com.google.inject.internal.Errors;
+import com.google.inject.spi.Message;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Constructor;
/**
* Utilities for the throwing provider module.
@@ -13,6 +20,43 @@
class CheckedProvideUtils {
private CheckedProvideUtils() {}
+
+ private static final String CONSTRUCTOR_RULES =
+ "Classes must have either one (and only one) constructor annotated
with @ThrowingInject.";
+
+ @SuppressWarnings("unchecked") // safe because it's a constructor of the
typeLiteral
+ static <T> Constructor<? extends T> findThrowingConstructor(
+ TypeLiteral<? extends T> typeLiteral, Binder binder) {
+
+ Class<?> rawType = typeLiteral.getRawType();
+ Errors errors = new Errors(rawType);
+ Constructor<?> cxtor = null;
+ for (Constructor<?> constructor : rawType.getDeclaredConstructors()) {
+ if (constructor.isAnnotationPresent(ThrowingInject.class)) {
+ if (cxtor != null) {
+ errors.addMessage("%s has more than one constructor annotated
with @ThrowingInject. "
+ + CONSTRUCTOR_RULES, rawType);
+ }
+
+ cxtor = constructor;
+ Annotation misplacedBindingAnnotation =
Annotations.findBindingAnnotation(
+ errors, cxtor, ((AnnotatedElement) cxtor).getAnnotations());
+ if (misplacedBindingAnnotation != null) {
+ errors.misplacedBindingAnnotation(cxtor,
misplacedBindingAnnotation);
+ }
+ }
+ }
+
+ if (cxtor == null) {
+ errors.addMessage(
+ "Could not find a suitable constructor in %s. " +
CONSTRUCTOR_RULES, rawType);
+ }
+
+ for (Message msg : errors.getMessages()) {
+ binder.addError(msg);
+ }
+ return (Constructor<? extends T>) cxtor;
+ }
/** Adds errors to the binder if the exceptions aren't valid. */
static void validateExceptions(Binder binder,
=======================================
---
/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java
Thu Mar 1 11:21:26 2012
+++
/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java
Sun May 27 10:39:59 2012
@@ -188,21 +188,14 @@
@SuppressWarnings("unchecked") // safe because this is the cxtor of
the literal
public ScopedBindingBuilder providing(TypeLiteral<? extends T>
cxtorLiteral) {
- // Find the injection point of the class we want to create & get its
constructor.
- InjectionPoint ip = null;
- try {
- ip = InjectionPoint.forConstructorOf(cxtorLiteral);
- } catch (ConfigurationException ce) {
- for (Message message : ce.getErrorMessages()) {
- binder.addError(message);
- }
- }
+ // Find a constructor that has @ThrowingInject.
+ Constructor<? extends T> cxtor =
+ CheckedProvideUtils.findThrowingConstructor(cxtorLiteral,
binder);
final Provider<T> typeProvider;
final Key<? extends T> typeKey;
// If we found an injection point, then bind the cxtor to a unique
key
- if (ip != null) {
- Constructor<? extends T> cxtor = (Constructor<? extends T>)
ip.getMember();
+ if (cxtor != null) {
// Validate the exceptions are consistent with the CheckedProvider
interface.
CheckedProvideUtils.validateExceptions(
binder, cxtorLiteral.getExceptionTypes(cxtor), exceptionTypes,
interfaceType);
=======================================
---
/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProviderTest.java
Thu Mar 1 11:21:26 2012
+++
/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProviderTest.java
Sun May 27 10:39:59 2012
@@ -568,7 +568,7 @@
static class DependentMockFoo implements Foo {
@Inject double foo;
- @Inject public DependentMockFoo(String foo, int bar) {
+ @ThrowingInject public DependentMockFoo(String foo, int bar) {
}
@Inject void initialize(long foo) {}
@@ -618,6 +618,7 @@
static Exception nextToThrow;
static String nextToReturn;
+ @ThrowingInject
MockFoo() throws RemoteException, BindException {
if (nextToThrow instanceof RemoteException) {
throw (RemoteException) nextToThrow;
@@ -647,6 +648,7 @@
static Exception nextToThrow;
static String nextToReturn;
+ @ThrowingInject
AnotherMockFoo() throws RemoteException, BindException {
if (nextToThrow instanceof RemoteException) {
throw (RemoteException) nextToThrow;
@@ -801,7 +803,7 @@
protected void configure() {
ThrowingProviderBinder.create(binder())
.bind(RemoteProvider.class, new TypeLiteral<List<String>>() {})
- .providing(new TypeLiteral<ArrayList<String>>() {});
+ .providing(new TypeLiteral<ThrowingArrayList<String>>() {});
}
});
@@ -809,6 +811,12 @@
= Key.get(new TypeLiteral<RemoteProvider<List<String>>>() { });
assertEquals(Arrays.asList(), cxtorInjector.getInstance(key).get());
}
+
+ private static class ThrowingArrayList<T> extends ArrayList<T> {
+ @SuppressWarnings("unused")
+ @ThrowingInject
+ ThrowingArrayList() {}
+ }
public void testProviderMethodWithWrongException() {
try {
@@ -860,6 +868,7 @@
static class WrongExceptionFoo implements Foo {
@SuppressWarnings("unused")
+ @ThrowingInject
public WrongExceptionFoo() throws InterruptedException {
}
@@ -916,6 +925,7 @@
}
static class SubclassExceptionFoo implements Foo {
+ @ThrowingInject
public SubclassExceptionFoo() throws AccessException {
throw new AccessException("boo!");
}
@@ -974,6 +984,7 @@
static class SuperclassExceptionFoo implements Foo {
@SuppressWarnings("unused")
+ @ThrowingInject
public SuperclassExceptionFoo() throws IOException {
}
@@ -1028,6 +1039,7 @@
}
static class RuntimeExceptionFoo implements Foo {
+ @ThrowingInject
public RuntimeExceptionFoo() throws RuntimeException {
throw new RuntimeException("boo!");
}
@@ -1110,6 +1122,7 @@
static class ManyExceptionFoo implements Foo {
@SuppressWarnings("unused")
+ @ThrowingInject
public ManyExceptionFoo()
throws InterruptedException,
RuntimeException,
@@ -1331,7 +1344,7 @@
} catch (CreationException ce) {
assertEquals("Could not find a suitable constructor in " +
InvalidFoo.class.getName()
+ ". Classes must have either one (and only one) constructor
annotated with "
- + "@Inject or a zero-argument constructor that is not private.",
+ + "@ThrowingInject.",
Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
}
}
@@ -1339,6 +1352,33 @@
static class InvalidFoo implements Foo {
public InvalidFoo(String dep) {
}
+
+ @Override public String s() { return null; }
+ }
+
+ public void testNoThrowingInject() {
+ try {
+ Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+ ThrowingProviderBinder.create(binder())
+ .bind(RemoteProvider.class, Foo.class)
+ .providing(NormalInjectableFoo.class);
+ }
+ });
+ fail();
+ } catch (CreationException ce) {
+ assertEquals("Could not find a suitable constructor in " +
NormalInjectableFoo.class.getName()
+ + ". Classes must have either one (and only one) constructor
annotated with "
+ + "@ThrowingInject.",
+ Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
+ }
+ }
+
+ static class NormalInjectableFoo implements Foo {
+ @Inject
+ public NormalInjectableFoo() {
+ }
@Override public String s() { return null; }
}
--
You received this message because you are subscribed to the Google Groups
"google-guice-dev" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-guice-dev?hl=en.