From bfc0343b82a4ade1ef57a233b93a3c482fa2dc10 Mon Sep 17 00:00:00 2001 From: Bob Lee Date: Wed, 30 Sep 2009 21:15:57 +0000 Subject: Added rule to spec requiring injectors to support injecting user-specified subtypes. Clarified and otherwise improved docs on Tck. Added a test case that mixes package private with overridding. git-svn-id: https://atinject.googlecode.com/svn/trunk@44 3bc8319c-20ab-11de-9edc-3f40a397ab60 --- atinject.ipr | 5 +- build.sh | 28 ++++--- src/javax/inject/Inject.java | 10 ++- tck/org/atinject/tck/Tck.java | 85 +++++++++++++--------- tck/org/atinject/tck/auto/Convertible.java | 10 +++ tck/org/atinject/tck/auto/Tire.java | 9 ++- .../atinject/tck/auto/accessories/RoundThing.java | 28 +++++++ .../atinject/tck/auto/accessories/SpareTire.java | 6 ++ tck/org/atinject/tck/package-info.java | 8 ++ 9 files changed, 137 insertions(+), 52 deletions(-) create mode 100644 tck/org/atinject/tck/auto/accessories/RoundThing.java create mode 100644 tck/org/atinject/tck/package-info.java diff --git a/atinject.ipr b/atinject.ipr index 5caf3de..716284b 100644 --- a/atinject.ipr +++ b/atinject.ipr @@ -223,7 +223,7 @@ - @@ -252,9 +252,6 @@ - - - diff --git a/build.sh b/build.sh index 0efb34e..14f484a 100755 --- a/build.sh +++ b/build.sh @@ -5,10 +5,12 @@ rm -r build mkdir -p build/classes mkdir -p build/tck mkdir -p build/dist +mkdir -p build/tck/classes +mkdir -p build/tck/dist # Compile classes. javac -g -d build/classes `find src -name *.java` -javac -g -classpath build/classes:lib/junit.jar -d build/tck \ +javac -g -classpath build/classes:lib/junit.jar -d build/tck/classes \ `find tck -name *.java` FOOTER="Copyright (C) 2009 \ @@ -19,23 +21,29 @@ License, Version 2.0." # Generate Javadocs. javadoc -protected -bottom "$FOOTER" \ -sourcepath src -d build/javadoc javax.inject -javadoc -classpath build/classes:lib/junit.jar -private -bottom "$FOOTER" \ - -sourcepath tck -d build/tck-javadoc org.atinject.tck \ +javadoc -classpath build/classes:lib/junit.jar -protected -bottom "$FOOTER" \ + -sourcepath tck -d build/tck/javadoc org.atinject.tck \ org.atinject.tck.auto org.atinject.tck.auto.accessories # Generate jars. cp -R src build -cp -R tck build/tck-src -find build/src -name .svn -type d | xargs rm -r -find build/tck-src -name .svn -type d | xargs rm -r -rm build/tck-src/tck.iml +cp -R tck build/tck/src + +rmSvn() { + find $1 -name .svn -type d | xargs rm -r +} + +rmSvn build/src +rmSvn build/tck/src +rm build/tck/src/tck.iml jar cfM build/dist/$NAME-src.zip -C build/src . -jar cfM build/dist/$NAME-tck-src.zip -C build/tck-src . +jar cfM build/tck/dist/$NAME-tck-src.zip -C build/tck/src . jar cfM build/dist/$NAME-javadoc.zip -C build/javadoc . -jar cfM build/dist/$NAME-tck-javadoc.zip -C build/tck-javadoc . +jar cfM build/tck/dist/$NAME-tck-javadoc.zip -C build/tck/javadoc . jar cfM build/dist/$NAME.jar -C build/classes . -jar cfM build/dist/$NAME-tck.jar -C build/tck . +jar cfM build/tck/dist/$NAME-tck.jar -C build/tck/classes . jar cfM build/$NAME.zip -C build/dist . +jar cfM build/$NAME-tck.zip -C build/tck/dist . diff --git a/src/javax/inject/Inject.java b/src/javax/inject/Inject.java index be85146..fe41467 100644 --- a/src/javax/inject/Inject.java +++ b/src/javax/inject/Inject.java @@ -31,9 +31,11 @@ import static java.lang.annotation.ElementType.FIELD; * injected first, followed by fields, and then methods. Fields and methods * in superclasses are injected before those in subclasses. Ordering of * injection among fields and among methods in the same class is not specified. - * Which values are injected depends upon the injector implementation and its - * configuration. - * + * For a given type T and optional qualifier, an injector must + * be able to inject a user-specified subclass of T that has an injectable + * constructor. Beyond that, which values are injected depend upon the + * injector implementation and its configuration. + * *

Injectable constructors are annotated with {@code @Inject} and accept * zero or more dependencies as arguments. {@code @Inject} can apply to at most * one constructor per class. @@ -117,7 +119,7 @@ import static java.lang.annotation.ElementType.FIELD; * *

A {@linkplain Qualifier qualifier} may annotate an injectable field * or parameter and, combined with the type, identify the implementation to - * inject. Qualifiers are optional, and when used with {@code @Inject} in + * inject. Qualifiers are optional, and when used with {@code @Inject} in * injector-independent classes, no more than one qualifier should annotate a * single field or parameter. The qualifiers are bold in the following example: * diff --git a/tck/org/atinject/tck/Tck.java b/tck/org/atinject/tck/Tck.java index c915dcf..e489680 100644 --- a/tck/org/atinject/tck/Tck.java +++ b/tck/org/atinject/tck/Tck.java @@ -23,61 +23,80 @@ import junit.framework.Test; import junit.framework.TestSuite; /** - * Maufactures the compatibility test suite. Call {@link #testsFor testsFor} - * from a JUnit static {@code suite} method: + * Manufactures the compatibility test suite. This TCK relies on + * JUnit. To integrate the TCK with your + * injector, create a JUnit test suite class that passes an injected + * {@link Car Car} instance to {@link #testsFor testsFor(Car)}: * *

  * import junit.framework.Test;
  * import org.atinject.tck.Tck;
+ * import org.atinject.tck.auto.Car;
  *
  * public class MyTck {
  *   public static Test suite() {
  *     Car car = new MyInjector().getInstance(Car.class);
- *     return Tck.testsFor(car, true, true);
+ *     return Tck.testsFor(car,
+ *         true /* supportsStatic */,
+ *         true /* supportsPrivate */);
  *   }
- * }
- * 
+ * } * - *

Run the tests using JUnit. For example: + *

The static {@code suite} method that returns a {@code Test} is a JUnit + * convention. Feel free to run the returned tests in other ways. Configure the + * injector as follows: + * + *

    + *
  • {@link org.atinject.tck.auto.Car} is implemented by + * {@link org.atinject.tck.auto.Convertible Convertible}. + *
  • {@link org.atinject.tck.auto.Drivers @Drivers} + * {@link org.atinject.tck.auto.Seat Seat} is + * implemented by {@link org.atinject.tck.auto.DriversSeat DriversSeat}. + *
  • {@link org.atinject.tck.auto.Seat Seat} is + * implemented by {@link org.atinject.tck.auto.Seat Seat} itself (not a + * subclass). + *
  • {@link org.atinject.tck.auto.Engine Engine} is implemented by + * {@link org.atinject.tck.auto.V8Engine V8Engine}. + *
  • {@link javax.inject.Named @Named("spare")} + * {@link org.atinject.tck.auto.Tire Tire} is implemented by + * {@link org.atinject.tck.auto.accessories.SpareTire SpareTire}. + *
  • The following concrete classes may also be injected: + * {@link org.atinject.tck.auto.accessories.Cupholder Cupholder}, + * {@link org.atinject.tck.auto.Tire Tire} and + * {@link org.atinject.tck.auto.FuelTank FuelTank}. + *
+ * + *

Static and private member injection support is optional, but if your + * injector supports those features, it must pass those tests. If static member + * injection is supported, the static members of the following types shall + * also be injected once: + * {@link org.atinject.tck.auto.Convertible Convertible}, + * {@link org.atinject.tck.auto.Tire Tire}, and + * {@link org.atinject.tck.auto.accessories.SpareTire SpareTire}. + * + *

Use your favorite JUnit tool to run the tests. For example, you can use + * your IDE or JUnit's command line runner: * *

- * java junit.textui.TestRunner MyTck
- * 
+ * java -cp javax.inject-tck.jar:junit.jar:myinjector.jar \ + * junit.textui.TestRunner MyTck */ public class Tck { private Tck() {} /** - * Constructs a test suite for the given {@link Car} instance. Create the - * {@code Car} instance using an injector with the following configuration: - * - *
    - *
  • {@link org.atinject.tck.auto.Car} is implemented by - * {@link org.atinject.tck.auto.Convertible Convertible}. - *
  • {@link org.atinject.tck.auto.Drivers @Drivers} {@link org.atinject.tck.auto.Seat Seat} is - * implemented by {@link org.atinject.tck.auto.DriversSeat DriversSeat}. - *
  • {@link org.atinject.tck.auto.Engine Engine} is implemented by - * {@link org.atinject.tck.auto.V8Engine V8Engine}. - *
  • {@link javax.inject.Named @Named("spare")} {@link org.atinject.tck.auto.Tire Tire} is implemented by - * {@link org.atinject.tck.auto.accessories.SpareTire SpareTire}. - *
  • The following concrete classes may also be injected: {@link org.atinject.tck.auto.accessories.Cupholder - * Cupholder}, {@link org.atinject.tck.auto.Tire Tire} and {@link org.atinject.tck.auto.FuelTank - * FuelTank}. - *
- * - *

If static member injection is supported, the static members of the - * following types shall also be injected: - * {@link org.atinject.tck.auto.Convertible Convertible}, - * {@link org.atinject.tck.auto.Tire Tire}, and {@link - * org.atinject.tck.auto.accessories.SpareTire SpareTire}. + * Constructs a JUnit test suite for the given {@link Car} instance. * * @param car to test - * @param supportsStatic if the injector supports static member injection - * @param supportsPrivate if the injector supports private member injection + * @param supportsStatic true if the injector supports static member + * injection + * @param supportsPrivate true if the injector supports private member + * injection * * @throws NullPointerException if car is null - * @throws ClassCastException if car doesn't extend Convertible + * @throws ClassCastException if car doesn't extend + * {@link Convertible Convertible} */ public static Test testsFor(Car car, boolean supportsStatic, boolean supportsPrivate) { diff --git a/tck/org/atinject/tck/auto/Convertible.java b/tck/org/atinject/tck/auto/Convertible.java index 62ccd45..0eee4db 100644 --- a/tck/org/atinject/tck/auto/Convertible.java +++ b/tck/org/atinject/tck/auto/Convertible.java @@ -19,6 +19,7 @@ package org.atinject.tck.auto; import junit.framework.TestCase; import org.atinject.tck.auto.accessories.Cupholder; import org.atinject.tck.auto.accessories.SpareTire; +import org.atinject.tck.auto.accessories.RoundThing; import javax.inject.Inject; import javax.inject.Named; @@ -177,6 +178,7 @@ public class Convertible implements Car { private final Convertible car = localConvertible.get(); private final Cupholder cupholder = car.cupholder; private final SpareTire spareTire = car.spareTire; + private final Tire plainTire = car.fieldPlainTire; private final Engine engine = car.engineProvider.get(); // smoke tests: if these fail all bets are off @@ -426,6 +428,14 @@ public class Convertible implements Car { assertFalse(engine.overriddenTwiceWithOmissionInSubclassInjected); } + public void testOverriddingMixedWithPackagePrivate() { + assertTrue(spareTire.packagePrivateMethod2Injected); + assertTrue(((Tire) spareTire).packagePrivateMethod2Injected); + assertFalse(((RoundThing) spareTire).packagePrivateMethod2Injected); + + assertTrue(plainTire.packagePrivateMethod2Injected); + assertTrue(((RoundThing) plainTire).packagePrivateMethod2Injected); + } // inject only once diff --git a/tck/org/atinject/tck/auto/Tire.java b/tck/org/atinject/tck/auto/Tire.java index 9d4f665..e88a668 100644 --- a/tck/org/atinject/tck/auto/Tire.java +++ b/tck/org/atinject/tck/auto/Tire.java @@ -17,12 +17,13 @@ package org.atinject.tck.auto; import org.atinject.tck.auto.accessories.SpareTire; +import org.atinject.tck.auto.accessories.RoundThing; import javax.inject.Inject; import java.util.LinkedHashSet; import java.util.Set; -public class Tire { +public class Tire extends RoundThing { protected static final FuelTank NEVER_INJECTED = new FuelTank(); @@ -160,4 +161,10 @@ public class Tire { protected boolean hasSpareTireBeenMethodInjected() { return false; } + + boolean packagePrivateMethod2Injected; + + @Inject void injectPackagePrivateMethod2() { + packagePrivateMethod2Injected = true; + } } diff --git a/tck/org/atinject/tck/auto/accessories/RoundThing.java b/tck/org/atinject/tck/auto/accessories/RoundThing.java new file mode 100644 index 0000000..99495be --- /dev/null +++ b/tck/org/atinject/tck/auto/accessories/RoundThing.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2009 The JSR-330 Expert Group + * + * 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 org.atinject.tck.auto.accessories; + +import javax.inject.Inject; + +public class RoundThing { + + public boolean packagePrivateMethod2Injected; + + @Inject void injectPackagePrivateMethod2() { + packagePrivateMethod2Injected = true; + } +} diff --git a/tck/org/atinject/tck/auto/accessories/SpareTire.java b/tck/org/atinject/tck/auto/accessories/SpareTire.java index e9a7eb2..d41ec6e 100644 --- a/tck/org/atinject/tck/auto/accessories/SpareTire.java +++ b/tck/org/atinject/tck/auto/accessories/SpareTire.java @@ -107,4 +107,10 @@ public class SpareTire extends Tire { public static boolean hasBeenStaticMethodInjected() { return staticMethodInjection != NEVER_INJECTED; } + + public boolean packagePrivateMethod2Injected; + + @Inject void injectPackagePrivateMethod2() { + packagePrivateMethod2Injected = true; + } } diff --git a/tck/org/atinject/tck/package-info.java b/tck/org/atinject/tck/package-info.java new file mode 100644 index 0000000..fa72b16 --- /dev/null +++ b/tck/org/atinject/tck/package-info.java @@ -0,0 +1,8 @@ +/** + * The compatibility test suite for + * JSR-330: Dependency Injection + * for Java. + * + * @see org.atinject.tck.Tck + */ +package org.atinject.tck; -- cgit v1.2.3