/* * Copyright 2011 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.gwt.inject.client.packageprivate; import com.google.gwt.core.client.GWT; import com.google.gwt.inject.client.AbstractGinModule; import com.google.gwt.inject.client.GinModules; import com.google.gwt.inject.client.Ginjector; import com.google.gwt.inject.client.packageprivate.subpackage.SubPackageGinModule; import com.google.gwt.junit.client.GWTTestCase; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.name.Named; public class PackagePrivateTest extends GWTTestCase { // Tests http://code.google.com/p/google-gin/issues/detail?id=86 public void testPackagePrivateInjection() { CrossPackageGinjector injector = GWT.create(CrossPackageGinjector.class); // Exercise all the injector methods. assertNotNull(injector.getCrossPackageDepender()); assertNotNull(injector.getCrossPackageExtender()); assertNotNull(injector.getPublicImplementation()); assertNotNull(injector.getPublicInterface()); assertNotNull(injector.getPublicInterfaceProvider().get()); assertNotNull(injector.getPublicProvidedClass()); assertNotNull(injector.getPublicProvidedClassProvider().get()); assertNotNull(injector.getPublicServiceAsync()); injector.injectCrossPackageDepender(injector.getCrossPackageDepender()); injector.injectCrossPackageExtender(injector.getCrossPackageExtender()); injector.injectCrossPackageExtenderChild(injector.getCrossPackageExtenderChild()); injector.injectCrossPackageExtenderGrandchild(injector.getCrossPackageExtenderGrandchild()); injector.injectCrossPackageExtenderUninjectedChild( injector.getCrossPackageExtenderUninjectedChild()); injector.injectCrossPackageExtenderChildOfUninjectedChild( injector.getCrossPackageExtenderChildOfUninjectedChild()); } public String getModuleName() { return "com.google.gwt.inject.InjectTest"; } @GinModules({PackagePrivateGinModule.class, SubPackageGinModule.class}) interface CrossPackageGinjector extends Ginjector { CrossPackageDepender getCrossPackageDepender(); CrossPackageExtender getCrossPackageExtender(); CrossPackageExtenderChild getCrossPackageExtenderChild(); CrossPackageExtenderGrandchild getCrossPackageExtenderGrandchild(); CrossPackageExtenderUninjectedChild getCrossPackageExtenderUninjectedChild(); CrossPackageExtenderChildOfUninjectedChild getCrossPackageExtenderChildOfUninjectedChild(); SubPackageGinModule.PublicImplementation getPublicImplementation(); PublicInterface getPublicInterface(); Provider<PublicInterface> getPublicInterfaceProvider(); PublicProvidedClass getPublicProvidedClass(); Provider<PublicProvidedClass> getPublicProvidedClassProvider(); SubPackageGinModule.PublicServiceAsync getPublicServiceAsync(); void injectCrossPackageDepender(CrossPackageDepender injectee); void injectCrossPackageExtender(CrossPackageExtender injectee); void injectCrossPackageExtenderChild(CrossPackageExtenderChild injectee); void injectCrossPackageExtenderGrandchild(CrossPackageExtenderGrandchild injectee); void injectCrossPackageExtenderUninjectedChild(CrossPackageExtenderUninjectedChild injectee); void injectCrossPackageExtenderChildOfUninjectedChild( CrossPackageExtenderChildOfUninjectedChild injectee); } public static class PackagePrivateGinModule extends AbstractGinModule { @Override public void configure() { // Make sure that static injection doesn't cause compile errors. requestStaticInjection(CrossPackageDepender.class); requestStaticInjection(CrossPackageExtender.class); requestStaticInjection(CrossPackageExtenderChild.class); requestStaticInjection(CrossPackageExtenderGrandchild.class); requestStaticInjection(CrossPackageExtenderChildOfUninjectedChild.class); // Make sure we can static-inject a class from another package. requestStaticInjection(SubPackageGinModule.PublicImplementation.class); } } // Interface for use in factory tests (the implementation is in another // package, to verify that the creation code goes there and not here; we can // even have implementations from different packages with individual private // dependencies). public static interface PublicAssisted { public interface Factory { @Named("a") PublicAssisted createA(long value); @Named("b") PublicAssisted createB(long value); } } // Verify that the injector can return a package-private type. static class CrossPackageDepender { @Inject CrossPackageDepender( // Verify that we can inject the package-private injector. CrossPackageGinjector crossPackageGinjector, // Verify that from this package, we can inject a class that belongs to // another package via a public interface. PublicInterface publicInterface, // Verify that from this package, we can inject a class that belongs to // another package via a public factory. PublicAssisted.Factory publicAssisted) { publicAssisted.createA(10); publicAssisted.createB(10); } // Verify that field injection works. @Inject CrossPackageGinjector injectorField; @Inject PublicInterface publicInterfaceField; @Inject PublicAssisted.Factory publicAssistedField; // Verify that static field injection works. @Inject static CrossPackageGinjector staticInjectorField; @Inject static PublicInterface staticPublicInterfaceField; @Inject static PublicAssisted.Factory staticPublicAssistedField; // Verify that method injection works. @Inject public void setCrossPackageGinjector(CrossPackageGinjector injector) { } @Inject public void setPublicInterface(PublicInterface publicInterface) { } @Inject public void setPublicAssisted(PublicAssisted.Factory factory) { factory.createA(10); factory.createB(10); } } // Verify that nothing bad happens when we extend a type that also has // method/field injections. static class CrossPackageExtender extends SubPackageGinModule.PublicImplementation { @Inject CrossPackageExtender(PublicInterface publicInterface) { } protected CrossPackageExtender() { } @Inject PublicInterface fieldPublicInterface; @Inject static PublicInterface staticFieldPublicInterface; @Inject void setPublicInterface(PublicInterface publicInterface) { } } // Test some knotty corner cases involving subclassing and member injection: static class CrossPackageExtenderChild extends CrossPackageExtender { @Inject PublicInterface fieldPublicInterface2; @Inject static PublicInterface staticFieldPublicInterface2; void setPublicInterface2(PublicInterface publicInterface2) { } } static class CrossPackageExtenderGrandchild extends CrossPackageExtenderChild { @Inject PublicInterface fieldPublicInterface3; @Inject static PublicInterface staticFieldPublicInterface3; void setPublicInterface2(PublicInterface publicInterface3) { } } static class CrossPackageExtenderUninjectedChild extends CrossPackageExtender { } static class CrossPackageExtenderChildOfUninjectedChild extends CrossPackageExtenderUninjectedChild { @Inject PublicInterface fieldPublicInterface4; @Inject static PublicInterface staticFieldPublicInterface4; void setPublicInterface2(PublicInterface publicInterface4) { } } public interface PublicInterface { } public static class PublicGeneric<T> { } public static class PublicProvidedClass { } public static interface ProvidedInSubpackage { } }