1477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit/** 2477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * Copyright (C) 2008 Google Inc. 3477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * 4477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * Licensed under the Apache License, Version 2.0 (the "License"); 5477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * you may not use this file except in compliance with the License. 6477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * You may obtain a copy of the License at 7477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * 8477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * http://www.apache.org/licenses/LICENSE-2.0 9477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * 10477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * Unless required by applicable law or agreed to in writing, software 11477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * distributed under the License is distributed on an "AS IS" BASIS, 12477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * See the License for the specific language governing permissions and 14477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * limitations under the License. 15477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit */ 16477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 175ae41eb77073b47e75c2dcf3766137f2352fbaf9limpbizkitpackage com.google.inject.internal; 185ae41eb77073b47e75c2dcf3766137f2352fbaf9limpbizkit 195ae41eb77073b47e75c2dcf3766137f2352fbaf9limpbizkitimport com.google.inject.Binder; 205ae41eb77073b47e75c2dcf3766137f2352fbaf9limpbizkitimport com.google.inject.Binding; 215ae41eb77073b47e75c2dcf3766137f2352fbaf9limpbizkitimport com.google.inject.Key; 225ae41eb77073b47e75c2dcf3766137f2352fbaf9limpbizkitimport com.google.inject.Provider; 2376c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkitimport com.google.inject.spi.ConstructorBinding; 2476c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkitimport com.google.inject.spi.ConvertedConstantBinding; 2576c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkitimport com.google.inject.spi.ExposedBinding; 26b3a8f0bda3259af41e639f1872c42377989704d9limpbizkitimport com.google.inject.spi.InjectionPoint; 2776c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkitimport com.google.inject.spi.InstanceBinding; 2876c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkitimport com.google.inject.spi.LinkedKeyBinding; 29c3f928404a91cf837d809dcc465ba43442bc1198limpbizkitimport com.google.inject.spi.PrivateElements; 3076c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkitimport com.google.inject.spi.ProviderBinding; 3176c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkitimport com.google.inject.spi.ProviderInstanceBinding; 3276c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkitimport com.google.inject.spi.ProviderKeyBinding; 3376c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkitimport com.google.inject.spi.UntargettedBinding; 34b7a02b02d81c830d148355c90bc309bcd66fb592sberlin 35477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport java.util.Set; 36477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 37477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit/** 38477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * Handles {@link Binder#bind} and {@link Binder#bindConstant} elements. 39477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * 40477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * @author crazybob@google.com (Bob Lee) 41477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * @author jessewilson@google.com (Jesse Wilson) 42477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit */ 4307170cc3f59f08954c97e19f2d3cf165d3a8601asberlinfinal class BindingProcessor extends AbstractBindingProcessor { 44477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 455fb9d927f35fb7a3eaba259c985710143231d4belimpbizkit private final Initializer initializer; 46477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 4707170cc3f59f08954c97e19f2d3cf165d3a8601asberlin BindingProcessor(Errors errors, Initializer initializer, ProcessedBindingData bindingData) { 4807170cc3f59f08954c97e19f2d3cf165d3a8601asberlin super(errors, bindingData); 495fb9d927f35fb7a3eaba259c985710143231d4belimpbizkit this.initializer = initializer; 50477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 51477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 5203b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit @Override public <T> Boolean visit(Binding<T> command) { 5307170cc3f59f08954c97e19f2d3cf165d3a8601asberlin Class<?> rawType = command.getKey().getTypeLiteral().getRawType(); 5407170cc3f59f08954c97e19f2d3cf165d3a8601asberlin if (Void.class.equals(rawType)) { 55759662bf0bdea0666dc10341efef685da7f2392climpbizkit if (command instanceof ProviderInstanceBinding 568ad60eb50961e000c89099bb767489cf551d995bSam Berlin && ((ProviderInstanceBinding) command).getUserSuppliedProvider() 578ad60eb50961e000c89099bb767489cf551d995bSam Berlin instanceof ProviderMethod) { 58759662bf0bdea0666dc10341efef685da7f2392climpbizkit errors.voidProviderMethod(); 59759662bf0bdea0666dc10341efef685da7f2392climpbizkit } else { 60759662bf0bdea0666dc10341efef685da7f2392climpbizkit errors.missingConstantValues(); 61759662bf0bdea0666dc10341efef685da7f2392climpbizkit } 62d1fe130a70a1b881d7b27079954b0e9140ab324climpbizkit return true; 63d1fe130a70a1b881d7b27079954b0e9140ab324climpbizkit } 6407170cc3f59f08954c97e19f2d3cf165d3a8601asberlin 65477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit if (rawType == Provider.class) { 66477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit errors.bindingToProvider(); 67477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit return true; 68477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 6907170cc3f59f08954c97e19f2d3cf165d3a8601asberlin 7007170cc3f59f08954c97e19f2d3cf165d3a8601asberlin return command.acceptTargetVisitor(new Processor<T, Boolean>((BindingImpl<T>)command) { 71d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin @Override 72920731718b6f3505cdfeefeabd789539603de18asberlin public Boolean visit(ConstructorBinding<? extends T> binding) { 7307170cc3f59f08954c97e19f2d3cf165d3a8601asberlin prepareBinding(); 7444475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit try { 7544475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit ConstructorBindingImpl<T> onInjector = ConstructorBindingImpl.create(injector, key, 76c756777526309dc6c9ff2b5df80a8f811d390c09Sam Berlin binding.getConstructor(), source, scoping, errors, false, false); 7744475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit scheduleInitialization(onInjector); 7844475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit putBinding(onInjector); 7944475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit } catch (ErrorsException e) { 8044475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit errors.merge(e.getErrors()); 8144475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit putBinding(invalidBinding(injector, key, source)); 8244475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit } 83920731718b6f3505cdfeefeabd789539603de18asberlin return true; 8444475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit } 8576c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkit 86d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin @Override 87920731718b6f3505cdfeefeabd789539603de18asberlin public Boolean visit(InstanceBinding<? extends T> binding) { 8807170cc3f59f08954c97e19f2d3cf165d3a8601asberlin prepareBinding(); 8976c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkit Set<InjectionPoint> injectionPoints = binding.getInjectionPoints(); 9076c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkit T instance = binding.getInstance(); 91bf2b16c06a5ff7c099fe60f9a46cfb130ce45962Christian Edward Gruber @SuppressWarnings("unchecked") // safe to cast to binding<T> because 92bf2b16c06a5ff7c099fe60f9a46cfb130ce45962Christian Edward Gruber // the processor was constructed w/ it 93fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit Initializable<T> ref = initializer.requestInjection( 94bf2b16c06a5ff7c099fe60f9a46cfb130ce45962Christian Edward Gruber injector, instance, (Binding<T>) binding, source, injectionPoints); 955fb9d927f35fb7a3eaba259c985710143231d4belimpbizkit ConstantFactory<? extends T> factory = new ConstantFactory<T>(ref); 960cb8b860dc71a16dcc08658d4abc8e0cfe6f605elimpbizkit InternalFactory<? extends T> scopedFactory 970cb8b860dc71a16dcc08658d4abc8e0cfe6f605elimpbizkit = Scoping.scope(key, injector, factory, source, scoping); 98b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit putBinding(new InstanceBindingImpl<T>(injector, key, source, scopedFactory, injectionPoints, 99b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit instance)); 100920731718b6f3505cdfeefeabd789539603de18asberlin return true; 101477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 102477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 103d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin @Override 104920731718b6f3505cdfeefeabd789539603de18asberlin public Boolean visit(ProviderInstanceBinding<? extends T> binding) { 10507170cc3f59f08954c97e19f2d3cf165d3a8601asberlin prepareBinding(); 1068ad60eb50961e000c89099bb767489cf551d995bSam Berlin javax.inject.Provider<? extends T> provider = binding.getUserSuppliedProvider(); 10776c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkit Set<InjectionPoint> injectionPoints = binding.getInjectionPoints(); 1088ad60eb50961e000c89099bb767489cf551d995bSam Berlin Initializable<? extends javax.inject.Provider<? extends T>> initializable = 1098ad60eb50961e000c89099bb767489cf551d995bSam Berlin initializer.<javax.inject.Provider<? extends T>>requestInjection( 1108ad60eb50961e000c89099bb767489cf551d995bSam Berlin injector, provider, null, source, injectionPoints); 111d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin // always visited with Binding<T> 112d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin @SuppressWarnings("unchecked") 113c94f4506c70ea41068ed9c5a00ddf6711eb7357fsberlin InternalFactory<T> factory = new InternalFactoryToInitializableAdapter<T>( 1145e6c93348c4250012801b6e41753789d760f06e4timofeyb initializable, source, 115d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin injector.provisionListenerStore.get((ProviderInstanceBinding<T>)binding)); 1160cb8b860dc71a16dcc08658d4abc8e0cfe6f605elimpbizkit InternalFactory<? extends T> scopedFactory 1170cb8b860dc71a16dcc08658d4abc8e0cfe6f605elimpbizkit = Scoping.scope(key, injector, factory, source, scoping); 11876c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkit putBinding(new ProviderInstanceBindingImpl<T>(injector, key, source, scopedFactory, scoping, 11976c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkit provider, injectionPoints)); 120920731718b6f3505cdfeefeabd789539603de18asberlin return true; 121477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 122477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 123d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin @Override 124920731718b6f3505cdfeefeabd789539603de18asberlin public Boolean visit(ProviderKeyBinding<? extends T> binding) { 12507170cc3f59f08954c97e19f2d3cf165d3a8601asberlin prepareBinding(); 126f2f7225c4042900a691b125672f516656c381608limpbizkit Key<? extends javax.inject.Provider<? extends T>> providerKey = binding.getProviderKey(); 127d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin // always visited with Binding<T> 128d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin @SuppressWarnings("unchecked") 129c94f4506c70ea41068ed9c5a00ddf6711eb7357fsberlin BoundProviderFactory<T> boundProviderFactory = new BoundProviderFactory<T>( 1305e6c93348c4250012801b6e41753789d760f06e4timofeyb injector, providerKey, source, 1318ad60eb50961e000c89099bb767489cf551d995bSam Berlin injector.provisionListenerStore.get((ProviderKeyBinding<T>) binding)); 13207170cc3f59f08954c97e19f2d3cf165d3a8601asberlin bindingData.addCreationListener(boundProviderFactory); 1335ae41eb77073b47e75c2dcf3766137f2352fbaf9limpbizkit InternalFactory<? extends T> scopedFactory = Scoping.scope( 1340cb8b860dc71a16dcc08658d4abc8e0cfe6f605elimpbizkit key, injector, (InternalFactory<? extends T>) boundProviderFactory, source, scoping); 135477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit putBinding(new LinkedProviderBindingImpl<T>( 13676c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkit injector, key, source, scopedFactory, scoping, providerKey)); 137920731718b6f3505cdfeefeabd789539603de18asberlin return true; 138477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 139477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 140d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin @Override 141920731718b6f3505cdfeefeabd789539603de18asberlin public Boolean visit(LinkedKeyBinding<? extends T> binding) { 14207170cc3f59f08954c97e19f2d3cf165d3a8601asberlin prepareBinding(); 14376c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkit Key<? extends T> linkedKey = binding.getLinkedKey(); 14476c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkit if (key.equals(linkedKey)) { 145477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit errors.recursiveBinding(); 146477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 147477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 14876c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkit FactoryProxy<T> factory = new FactoryProxy<T>(injector, key, linkedKey, source); 14907170cc3f59f08954c97e19f2d3cf165d3a8601asberlin bindingData.addCreationListener(factory); 1500cb8b860dc71a16dcc08658d4abc8e0cfe6f605elimpbizkit InternalFactory<? extends T> scopedFactory 1510cb8b860dc71a16dcc08658d4abc8e0cfe6f605elimpbizkit = Scoping.scope(key, injector, factory, source, scoping); 15276c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkit putBinding( 15376c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkit new LinkedBindingImpl<T>(injector, key, source, scopedFactory, scoping, linkedKey)); 154920731718b6f3505cdfeefeabd789539603de18asberlin return true; 155477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 156477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 157d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin @Override 15807170cc3f59f08954c97e19f2d3cf165d3a8601asberlin public Boolean visit(UntargettedBinding<? extends T> untargetted) { 15907170cc3f59f08954c97e19f2d3cf165d3a8601asberlin return false; 160477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 161477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 162d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin @Override 163920731718b6f3505cdfeefeabd789539603de18asberlin public Boolean visit(ExposedBinding<? extends T> binding) { 164aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit throw new IllegalArgumentException("Cannot apply a non-module element"); 165fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit } 166d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin 167d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin @Override 168920731718b6f3505cdfeefeabd789539603de18asberlin public Boolean visit(ConvertedConstantBinding<? extends T> binding) { 169477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit throw new IllegalArgumentException("Cannot apply a non-module element"); 170477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 171d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin 172d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin @Override 173920731718b6f3505cdfeefeabd789539603de18asberlin public Boolean visit(ProviderBinding<? extends T> binding) { 174477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit throw new IllegalArgumentException("Cannot apply a non-module element"); 175477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 17607170cc3f59f08954c97e19f2d3cf165d3a8601asberlin 17707170cc3f59f08954c97e19f2d3cf165d3a8601asberlin @Override 17807170cc3f59f08954c97e19f2d3cf165d3a8601asberlin protected Boolean visitOther(Binding<? extends T> binding) { 17907170cc3f59f08954c97e19f2d3cf165d3a8601asberlin throw new IllegalStateException("BindingProcessor should override all visitations"); 180477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 181477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit }); 182477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 183477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 184aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit @Override public Boolean visit(PrivateElements privateElements) { 185aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit for (Key<?> key : privateElements.getExposedKeys()) { 186aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit bindExposed(privateElements, key); 187aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit } 188aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit return false; // leave the private elements for the PrivateElementsProcessor to handle 189aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit } 190aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit 191aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit private <T> void bindExposed(PrivateElements privateElements, Key<T> key) { 192aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit ExposedKeyFactory<T> exposedKeyFactory = new ExposedKeyFactory<T>(key, privateElements); 19307170cc3f59f08954c97e19f2d3cf165d3a8601asberlin bindingData.addCreationListener(exposedKeyFactory); 194aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit putBinding(new ExposedBindingImpl<T>( 195aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit injector, privateElements.getExposedSource(key), key, exposedKeyFactory, privateElements)); 196aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit } 197477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit} 198