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 17477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitpackage com.google.inject.spi; 18477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 19b7a02b02d81c830d148355c90bc309bcd66fb592sberlinimport static com.google.common.base.Preconditions.checkArgument; 20ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruberimport static com.google.inject.internal.InternalFlags.getIncludeStackTraceOption; 21b7a02b02d81c830d148355c90bc309bcd66fb592sberlin 22b7a02b02d81c830d148355c90bc309bcd66fb592sberlinimport com.google.common.collect.ImmutableList; 23b7a02b02d81c830d148355c90bc309bcd66fb592sberlinimport com.google.common.collect.Lists; 2454da0e3ca924a5040e88a1c067f9f6760a14b20bsamebimport com.google.common.collect.Maps; 25b7a02b02d81c830d148355c90bc309bcd66fb592sberlinimport com.google.common.collect.Sets; 26477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport com.google.inject.AbstractModule; 27477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport com.google.inject.Binder; 2876c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkitimport com.google.inject.Binding; 29477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport com.google.inject.Key; 3097eac0fa7c42c3ebc409e63156899d3c889cb234limpbizkitimport com.google.inject.MembersInjector; 31477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport com.google.inject.Module; 32bf0d876bb767f45c5cfbed3929e2cf6acd7d061alimpbizkitimport com.google.inject.PrivateBinder; 33fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkitimport com.google.inject.PrivateModule; 34477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport com.google.inject.Provider; 35477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport com.google.inject.Scope; 36477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport com.google.inject.Stage; 37477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport com.google.inject.TypeLiteral; 38477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport com.google.inject.binder.AnnotatedBindingBuilder; 39477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport com.google.inject.binder.AnnotatedConstantBindingBuilder; 405ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkitimport com.google.inject.binder.AnnotatedElementBuilder; 4176c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkitimport com.google.inject.internal.AbstractBindingBuilder; 4276c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkitimport com.google.inject.internal.BindingBuilder; 4376c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkitimport com.google.inject.internal.ConstantBindingBuilderImpl; 4472d11dd102eeebf081aa5363469d28b25f9b1384limpbizkitimport com.google.inject.internal.Errors; 459a227bef3b82a045323ef2cf38ec60b2e42cf0felimpbizkit@gmail.comimport com.google.inject.internal.ExposureBuilder; 460910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport com.google.inject.internal.InternalFlags.IncludeStackTraceOption; 47825f8c1df885b9d7643a9e18e336984f0138edafsamebimport com.google.inject.internal.MoreTypes; 48c3f928404a91cf837d809dcc465ba43442bc1198limpbizkitimport com.google.inject.internal.PrivateElementsImpl; 4986cb3bb7d9b662398dc2b71433a9f6c6a6392b5climpbizkitimport com.google.inject.internal.ProviderMethodsModule; 509a227bef3b82a045323ef2cf38ec60b2e42cf0felimpbizkit@gmail.comimport com.google.inject.internal.util.SourceProvider; 51605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruberimport com.google.inject.internal.util.StackTraceElements; 52477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport com.google.inject.matcher.Matcher; 53b7a02b02d81c830d148355c90bc309bcd66fb592sberlin 54477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport java.lang.annotation.Annotation; 55477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport java.lang.reflect.Method; 56477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport java.util.Arrays; 575ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkitimport java.util.Collection; 58477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport java.util.Collections; 59477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport java.util.List; 6054da0e3ca924a5040e88a1c067f9f6760a14b20bsamebimport java.util.Map; 61477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitimport java.util.Set; 62477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 63477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit/** 64aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit * Exposes elements of a module so they can be inspected, validated or {@link 65aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit * Element#applyTo(Binder) rewritten}. 66477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * 67477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * @author jessewilson@google.com (Jesse Wilson) 68c489adf4671b41765698d167e13960d998190c5elimpbizkit * @since 2.0 69477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit */ 70477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkitpublic final class Elements { 71605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 72afa4b5dd2056a8427657186d1804313c3f34fbfelimpbizkit private static final BindingTargetVisitor<Object, Object> GET_INSTANCE_VISITOR 73afa4b5dd2056a8427657186d1804313c3f34fbfelimpbizkit = new DefaultBindingTargetVisitor<Object, Object>() { 7403b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit @Override public Object visit(InstanceBinding<?> binding) { 7576c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkit return binding.getInstance(); 76477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 77477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 788996e8059681c083744df50c7ad9e007eda1f648limpbizkit @Override protected Object visitOther(Binding<?> binding) { 79477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit throw new IllegalArgumentException(); 80477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 81477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit }; 82477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 83477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit /** 84477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * Records the elements executed by {@code modules}. 85477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit */ 86477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public static List<Element> getElements(Module... modules) { 87477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit return getElements(Stage.DEVELOPMENT, Arrays.asList(modules)); 88477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 89477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 90477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit /** 91477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * Records the elements executed by {@code modules}. 92477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit */ 93477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public static List<Element> getElements(Stage stage, Module... modules) { 94477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit return getElements(stage, Arrays.asList(modules)); 95477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 96477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 97477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit /** 98477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * Records the elements executed by {@code modules}. 99477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit */ 100477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public static List<Element> getElements(Iterable<? extends Module> modules) { 101477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit return getElements(Stage.DEVELOPMENT, modules); 102477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 103477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 104477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit /** 105477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit * Records the elements executed by {@code modules}. 106477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit */ 107477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public static List<Element> getElements(Stage stage, Iterable<? extends Module> modules) { 108477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit RecordingBinder binder = new RecordingBinder(stage); 109477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit for (Module module : modules) { 110477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit binder.install(module); 111477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 11254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb binder.scanForAnnotatedMethods(); 11354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb for (RecordingBinder child : binder.privateBinders) { 11454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb child.scanForAnnotatedMethods(); 11554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb } 116ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber // Free the memory consumed by the stack trace elements cache 117ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber StackTraceElements.clearCache(); 118477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit return Collections.unmodifiableList(binder.elements); 119477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 1200910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber 1212e39ef748a1c4e4dcab506ccfcdb14ca6e01c9c6Christian Edward Gruber private static class ElementsAsModule implements Module { 1222e39ef748a1c4e4dcab506ccfcdb14ca6e01c9c6Christian Edward Gruber private final Iterable<? extends Element> elements; 1232e39ef748a1c4e4dcab506ccfcdb14ca6e01c9c6Christian Edward Gruber 1242e39ef748a1c4e4dcab506ccfcdb14ca6e01c9c6Christian Edward Gruber ElementsAsModule(Iterable<? extends Element> elements) { 1252e39ef748a1c4e4dcab506ccfcdb14ca6e01c9c6Christian Edward Gruber this.elements = elements; 1262e39ef748a1c4e4dcab506ccfcdb14ca6e01c9c6Christian Edward Gruber } 1272e39ef748a1c4e4dcab506ccfcdb14ca6e01c9c6Christian Edward Gruber 1280910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber @Override 1292e39ef748a1c4e4dcab506ccfcdb14ca6e01c9c6Christian Edward Gruber public void configure(Binder binder) { 1302e39ef748a1c4e4dcab506ccfcdb14ca6e01c9c6Christian Edward Gruber for (Element element : elements) { 1312e39ef748a1c4e4dcab506ccfcdb14ca6e01c9c6Christian Edward Gruber element.applyTo(binder); 1322e39ef748a1c4e4dcab506ccfcdb14ca6e01c9c6Christian Edward Gruber } 1332e39ef748a1c4e4dcab506ccfcdb14ca6e01c9c6Christian Edward Gruber } 1342e39ef748a1c4e4dcab506ccfcdb14ca6e01c9c6Christian Edward Gruber } 1352e39ef748a1c4e4dcab506ccfcdb14ca6e01c9c6Christian Edward Gruber 136aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit /** 137aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit * Returns the module composed of {@code elements}. 138aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit */ 139aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit public static Module getModule(final Iterable<? extends Element> elements) { 1402e39ef748a1c4e4dcab506ccfcdb14ca6e01c9c6Christian Edward Gruber return new ElementsAsModule(elements); 141aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit } 142aa07ab09a27d4b83e66fb1666e7c780821ed106dlimpbizkit 143477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit @SuppressWarnings("unchecked") 1447e1e4f7fe3d8e552e3a4bcd4fe7a4ce8a8b07431limpbizkit static <T> BindingTargetVisitor<T, T> getInstanceVisitor() { 145afa4b5dd2056a8427657186d1804313c3f34fbfelimpbizkit return (BindingTargetVisitor<T, T>) GET_INSTANCE_VISITOR; 146477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 147477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 14854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb private static class ModuleInfo { 14954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb private final Binder binder; 15054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb private final ModuleSource moduleSource; 15102c489e4fbddf702c7932b55caab83e6d8cba9cesameb private final boolean skipScanning; 15254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb 15302c489e4fbddf702c7932b55caab83e6d8cba9cesameb private ModuleInfo(Binder binder, ModuleSource moduleSource, boolean skipScanning) { 15454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb this.binder = binder; 15554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb this.moduleSource = moduleSource; 15602c489e4fbddf702c7932b55caab83e6d8cba9cesameb this.skipScanning = skipScanning; 15754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb } 15854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb } 15954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb 160c34e0185fcf508a890c6cd13bdafeb505c3e9e8aSam Berlin private static class RecordingBinder implements Binder, PrivateBinder { 161477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit private final Stage stage; 16254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb private final Map<Module, ModuleInfo> modules; 163477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit private final List<Element> elements; 164477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit private final Object source; 165605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber /** The current modules stack */ 166605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber private ModuleSource moduleSource = null; 167477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit private final SourceProvider sourceProvider; 16854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb private final Set<ModuleAnnotatedMethodScanner> scanners; 169fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit 170fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit /** The binder where exposed bindings will be created */ 171fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit private final RecordingBinder parent; 172c3f928404a91cf837d809dcc465ba43442bc1198limpbizkit private final PrivateElementsImpl privateElements; 173477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 17454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb /** All children private binders, so we can scan through them. */ 17554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb private final List<RecordingBinder> privateBinders; 17654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb 177477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit private RecordingBinder(Stage stage) { 178477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit this.stage = stage; 17954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb this.modules = Maps.newLinkedHashMap(); 18054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb this.scanners = Sets.newLinkedHashSet(); 181477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit this.elements = Lists.newArrayList(); 182477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit this.source = null; 1835ae41eb77073b47e75c2dcf3766137f2352fbaf9limpbizkit this.sourceProvider = SourceProvider.DEFAULT_INSTANCE.plusSkippedClasses( 18476c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkit Elements.class, RecordingBinder.class, AbstractModule.class, 18576c24b172e5c4c4b6d51c10dd5c1f491a4033157limpbizkit ConstantBindingBuilderImpl.class, AbstractBindingBuilder.class, BindingBuilder.class); 186fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit this.parent = null; 187c3f928404a91cf837d809dcc465ba43442bc1198limpbizkit this.privateElements = null; 18854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb this.privateBinders = Lists.newArrayList(); 189477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 190477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 191fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit /** Creates a recording binder that's backed by {@code prototype}. */ 192fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit private RecordingBinder( 193fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit RecordingBinder prototype, Object source, SourceProvider sourceProvider) { 194477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit checkArgument(source == null ^ sourceProvider == null); 195477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 196fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit this.stage = prototype.stage; 197fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit this.modules = prototype.modules; 198fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit this.elements = prototype.elements; 19954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb this.scanners = prototype.scanners; 200477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit this.source = source; 201605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber this.moduleSource = prototype.moduleSource; 202477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit this.sourceProvider = sourceProvider; 203fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit this.parent = prototype.parent; 204c3f928404a91cf837d809dcc465ba43442bc1198limpbizkit this.privateElements = prototype.privateElements; 20554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb this.privateBinders = prototype.privateBinders; 2065ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit } 2075ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit 2085ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit /** Creates a private recording binder. */ 209c3f928404a91cf837d809dcc465ba43442bc1198limpbizkit private RecordingBinder(RecordingBinder parent, PrivateElementsImpl privateElements) { 2105ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit this.stage = parent.stage; 21154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb this.modules = Maps.newLinkedHashMap(); 21254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb this.scanners = Sets.newLinkedHashSet(parent.scanners); 213c3f928404a91cf837d809dcc465ba43442bc1198limpbizkit this.elements = privateElements.getElementsMutable(); 2145ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit this.source = parent.source; 215605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber this.moduleSource = parent.moduleSource; 2165ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit this.sourceProvider = parent.sourceProvider; 217fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit this.parent = parent; 218c3f928404a91cf837d809dcc465ba43442bc1198limpbizkit this.privateElements = privateElements; 21954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb this.privateBinders = parent.privateBinders; 220477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 221477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 222bf0d876bb767f45c5cfbed3929e2cf6acd7d061alimpbizkit /*if[AOP]*/ 2230910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber @Override 224477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public void bindInterceptor( 225477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit Matcher<? super Class<?>> classMatcher, 226477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit Matcher<? super Method> methodMatcher, 2274f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit org.aopalliance.intercept.MethodInterceptor... interceptors) { 228605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber elements.add(new InterceptorBinding( 229605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber getElementSource(), classMatcher, methodMatcher, interceptors)); 230477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 231bf0d876bb767f45c5cfbed3929e2cf6acd7d061alimpbizkit /*end[AOP]*/ 232477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 2330910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber @Override 234477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public void bindScope(Class<? extends Annotation> annotationType, Scope scope) { 235605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber elements.add(new ScopeBinding(getElementSource(), annotationType, scope)); 236477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 237477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 2380910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber @Override 23903b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit @SuppressWarnings("unchecked") // it is safe to use the type literal for the raw type 24003b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit public void requestInjection(Object instance) { 24196e81ba55441fd11c189d903ee2bd1806a23bd70Christian Edward Gruber requestInjection((TypeLiteral<Object>) TypeLiteral.get(instance.getClass()), instance); 24203b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit } 24303b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit 2440910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber @Override 24503b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit public <T> void requestInjection(TypeLiteral<T> type, T instance) { 246825f8c1df885b9d7643a9e18e336984f0138edafsameb elements.add(new InjectionRequest<T>(getElementSource(), MoreTypes.canonicalizeForKey(type), 247825f8c1df885b9d7643a9e18e336984f0138edafsameb instance)); 24803b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit } 24903b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit 2500910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber @Override 25197eac0fa7c42c3ebc409e63156899d3c889cb234limpbizkit public <T> MembersInjector<T> getMembersInjector(final TypeLiteral<T> typeLiteral) { 252825f8c1df885b9d7643a9e18e336984f0138edafsameb final MembersInjectorLookup<T> element = new MembersInjectorLookup<T>(getElementSource(), 253825f8c1df885b9d7643a9e18e336984f0138edafsameb MoreTypes.canonicalizeForKey(typeLiteral)); 25497eac0fa7c42c3ebc409e63156899d3c889cb234limpbizkit elements.add(element); 2558d62075e136d207b8fb8ea98d3fd7ec051bdee3climpbizkit return element.getMembersInjector(); 25603b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit } 25703b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit 25803b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit public <T> MembersInjector<T> getMembersInjector(Class<T> type) { 25997eac0fa7c42c3ebc409e63156899d3c889cb234limpbizkit return getMembersInjector(TypeLiteral.get(type)); 26003b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit } 26103b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit 262a843a95d620de9c8046e67a8f51619b3fedf77d3limpbizkit public void bindListener(Matcher<? super TypeLiteral<?>> typeMatcher, TypeListener listener) { 263605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber elements.add(new TypeListenerBinding(getElementSource(), listener, typeMatcher)); 264477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 265ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber 266d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin public void bindListener(Matcher<? super Binding<?>> bindingMatcher, 267d51292d5a4a788b1275eb9ad55cf612e68640bbfSam Berlin ProvisionListener... listeners) { 268605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber elements.add(new ProvisionListenerBinding(getElementSource(), bindingMatcher, listeners)); 269132a5db7c643b8f367eb5f09024cf13ea37c9831sberlin } 270477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 271477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public void requestStaticInjection(Class<?>... types) { 272b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit for (Class<?> type : types) { 273605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber elements.add(new StaticInjectionRequest(getElementSource(), type)); 274b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit } 275477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 276477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 27702c489e4fbddf702c7932b55caab83e6d8cba9cesameb /** 27802c489e4fbddf702c7932b55caab83e6d8cba9cesameb * Applies all scanners to the modules we've installed. We skip certain 27902c489e4fbddf702c7932b55caab83e6d8cba9cesameb * PrivateModules because store them in more than one Modules map and only 28002c489e4fbddf702c7932b55caab83e6d8cba9cesameb * want to process them through one of the maps. (They're stored in both 28102c489e4fbddf702c7932b55caab83e6d8cba9cesameb * maps to prevent a module from being installed more than once.) 28202c489e4fbddf702c7932b55caab83e6d8cba9cesameb */ 28354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb void scanForAnnotatedMethods() { 28454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb for (ModuleAnnotatedMethodScanner scanner : scanners) { 28554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb // Note: we must iterate over a copy of the modules because calling install(..) 28654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb // will mutate modules, otherwise causing a ConcurrentModificationException. 28754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb for (Map.Entry<Module, ModuleInfo> entry : Maps.newLinkedHashMap(modules).entrySet()) { 28854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb Module module = entry.getKey(); 28902c489e4fbddf702c7932b55caab83e6d8cba9cesameb ModuleInfo info = entry.getValue(); 29002c489e4fbddf702c7932b55caab83e6d8cba9cesameb if (info.skipScanning) { 29154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb continue; 29254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb } 29354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb moduleSource = entry.getValue().moduleSource; 29454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb try { 29502c489e4fbddf702c7932b55caab83e6d8cba9cesameb info.binder.install(ProviderMethodsModule.forModule(module, scanner)); 29654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb } catch(RuntimeException e) { 29754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb Collection<Message> messages = Errors.getMessagesFromThrowable(e); 29854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb if (!messages.isEmpty()) { 29954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb elements.addAll(messages); 30054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb } else { 30154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb addError(e); 30254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb } 30354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb } 30454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb } 30554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb } 30654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb moduleSource = null; 30754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb } 30854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb 309477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public void install(Module module) { 31054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb if (!modules.containsKey(module)) { 31102c489e4fbddf702c7932b55caab83e6d8cba9cesameb RecordingBinder binder = this; 3127445e44ba8acbbfc09116fec71d59066cdae8721sameb boolean unwrapModuleSource = false; 313605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber // Update the module source for the new module 3140910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber if (module instanceof ProviderMethodsModule) { 3157445e44ba8acbbfc09116fec71d59066cdae8721sameb // There are two reason's we'd want to get the module source in a ProviderMethodsModule. 3167445e44ba8acbbfc09116fec71d59066cdae8721sameb // ModuleAnnotatedMethodScanner lets users scan their own modules for @Provides-like 3177445e44ba8acbbfc09116fec71d59066cdae8721sameb // bindings. If they install the module at a top-level, then moduleSource can be null. 3187445e44ba8acbbfc09116fec71d59066cdae8721sameb // Also, if they pass something other than 'this' to it, we'd have the wrong source. 3190910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber Object delegate = ((ProviderMethodsModule) module).getDelegateModule(); 3200910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber if (moduleSource == null 3210910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber || !moduleSource.getModuleClassName().equals(delegate.getClass().getName())) { 3227445e44ba8acbbfc09116fec71d59066cdae8721sameb moduleSource = getModuleSource(delegate); 3237445e44ba8acbbfc09116fec71d59066cdae8721sameb unwrapModuleSource = true; 3247445e44ba8acbbfc09116fec71d59066cdae8721sameb } 3250910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber } else { 3260910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber moduleSource = getModuleSource(module); 3270910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber unwrapModuleSource = true; 328605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 32902c489e4fbddf702c7932b55caab83e6d8cba9cesameb boolean skipScanning = false; 330fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit if (module instanceof PrivateModule) { 33102c489e4fbddf702c7932b55caab83e6d8cba9cesameb binder = (RecordingBinder) binder.newPrivateBinder(); 33202c489e4fbddf702c7932b55caab83e6d8cba9cesameb // Store the module in the private binder too so we scan for it. 33302c489e4fbddf702c7932b55caab83e6d8cba9cesameb binder.modules.put(module, new ModuleInfo(binder, moduleSource, false)); 33402c489e4fbddf702c7932b55caab83e6d8cba9cesameb skipScanning = true; // don't scan this module in the parent's module set. 3357445e44ba8acbbfc09116fec71d59066cdae8721sameb } 33654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb // Always store this in the parent binder (even if it was a private module) 33754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb // so that we know not to process it again, and so that scanners inherit down. 33802c489e4fbddf702c7932b55caab83e6d8cba9cesameb modules.put(module, new ModuleInfo(binder, moduleSource, skipScanning)); 339477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit try { 340fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit module.configure(binder); 341477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } catch (RuntimeException e) { 34272d11dd102eeebf081aa5363469d28b25f9b1384limpbizkit Collection<Message> messages = Errors.getMessagesFromThrowable(e); 34372d11dd102eeebf081aa5363469d28b25f9b1384limpbizkit if (!messages.isEmpty()) { 34472d11dd102eeebf081aa5363469d28b25f9b1384limpbizkit elements.addAll(messages); 34572d11dd102eeebf081aa5363469d28b25f9b1384limpbizkit } else { 34672d11dd102eeebf081aa5363469d28b25f9b1384limpbizkit addError(e); 34772d11dd102eeebf081aa5363469d28b25f9b1384limpbizkit } 348477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 349fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit binder.install(ProviderMethodsModule.forModule(module)); 350605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber // We are done with this module, so undo module source change 3517445e44ba8acbbfc09116fec71d59066cdae8721sameb if (unwrapModuleSource) { 352605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber moduleSource = moduleSource.getParent(); 353605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 354477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 355477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 356477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 357477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public Stage currentStage() { 358477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit return stage; 359477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 360477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 361477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public void addError(String message, Object... arguments) { 362605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber elements.add(new Message(getElementSource(), Errors.format(message, arguments))); 363477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 364477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 365477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public void addError(Throwable t) { 366b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit String message = "An exception was caught and reported. Message: " + t.getMessage(); 367605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber elements.add(new Message(ImmutableList.of((Object) getElementSource()), message, t)); 368477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 369477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 370477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public void addError(Message message) { 371477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit elements.add(message); 372477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 373477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 374d1fe130a70a1b881d7b27079954b0e9140ab324climpbizkit public <T> AnnotatedBindingBuilder<T> bind(Key<T> key) { 375825f8c1df885b9d7643a9e18e336984f0138edafsameb BindingBuilder<T> builder = 376825f8c1df885b9d7643a9e18e336984f0138edafsameb new BindingBuilder<T>(this, elements, getElementSource(), MoreTypes.canonicalizeKey(key)); 37796e81ba55441fd11c189d903ee2bd1806a23bd70Christian Edward Gruber return builder; 378477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 379477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 380477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public <T> AnnotatedBindingBuilder<T> bind(TypeLiteral<T> typeLiteral) { 381477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit return bind(Key.get(typeLiteral)); 382477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 383477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 384477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public <T> AnnotatedBindingBuilder<T> bind(Class<T> type) { 385477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit return bind(Key.get(type)); 386477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 387477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 388477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public AnnotatedConstantBindingBuilder bindConstant() { 389605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return new ConstantBindingBuilderImpl<Void>(this, elements, getElementSource()); 390477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 391477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 392477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public <T> Provider<T> getProvider(final Key<T> key) { 3939867f9c2142355ae958f9eeb8fb96811082c8812sameb return getProvider(Dependency.get(key)); 3949867f9c2142355ae958f9eeb8fb96811082c8812sameb } 3959867f9c2142355ae958f9eeb8fb96811082c8812sameb 3969867f9c2142355ae958f9eeb8fb96811082c8812sameb public <T> Provider<T> getProvider(final Dependency<T> dependency) { 3979867f9c2142355ae958f9eeb8fb96811082c8812sameb final ProviderLookup<T> element = new ProviderLookup<T>(getElementSource(), dependency); 39897eac0fa7c42c3ebc409e63156899d3c889cb234limpbizkit elements.add(element); 3998d62075e136d207b8fb8ea98d3fd7ec051bdee3climpbizkit return element.getProvider(); 400477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 401477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 402477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public <T> Provider<T> getProvider(Class<T> type) { 403477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit return getProvider(Key.get(type)); 404477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 405477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 406477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit public void convertToTypes(Matcher<? super TypeLiteral<?>> typeMatcher, 407477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit TypeConverter converter) { 408605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber elements.add(new TypeConverterBinding(getElementSource(), typeMatcher, converter)); 409477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 410477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 411ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber public RecordingBinder withSource(final Object source) { 412c5848c0b57ad0f3f09acadff4be80c19d0c7d95fSam Berlin return source == this.source ? this : new RecordingBinder(this, source, null); 413477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 414477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 4155ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit public RecordingBinder skipSources(Class... classesToSkip) { 416477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit // if a source is specified explicitly, we don't need to skip sources 417477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit if (source != null) { 418477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit return this; 419477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 420477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 421477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit SourceProvider newSourceProvider = sourceProvider.plusSkippedClasses(classesToSkip); 422477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit return new RecordingBinder(this, null, newSourceProvider); 423477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 424477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit 4250910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber @Override 4265ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit public PrivateBinder newPrivateBinder() { 427605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber PrivateElementsImpl privateElements = new PrivateElementsImpl(getElementSource()); 42896e81ba55441fd11c189d903ee2bd1806a23bd70Christian Edward Gruber RecordingBinder binder = new RecordingBinder(this, privateElements); 42954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb privateBinders.add(binder); 430c3f928404a91cf837d809dcc465ba43442bc1198limpbizkit elements.add(privateElements); 43196e81ba55441fd11c189d903ee2bd1806a23bd70Christian Edward Gruber return binder; 4325ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit } 4330910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber 4340910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber @Override 4358b64d455b982d5841480a0247c15d68de0759c91sberlin public void disableCircularProxies() { 436605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber elements.add(new DisableCircularProxiesOption(getElementSource())); 4378b64d455b982d5841480a0247c15d68de0759c91sberlin } 4380910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber 4390910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber @Override 4408b64d455b982d5841480a0247c15d68de0759c91sberlin public void requireExplicitBindings() { 4410910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber elements.add(new RequireExplicitBindingsOption(getElementSource())); 4428b64d455b982d5841480a0247c15d68de0759c91sberlin } 4430910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber 4440910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber @Override 445c756777526309dc6c9ff2b5df80a8f811d390c09Sam Berlin public void requireAtInjectOnConstructors() { 446605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber elements.add(new RequireAtInjectOnConstructorsOption(getElementSource())); 447c756777526309dc6c9ff2b5df80a8f811d390c09Sam Berlin } 4485ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit 4490910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber @Override 450e39158525475eca7971966c667494d240be7e242Christian Edward Gruber public void requireExactBindingAnnotations() { 451605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber elements.add(new RequireExactBindingAnnotationsOption(getElementSource())); 452e39158525475eca7971966c667494d240be7e242Christian Edward Gruber } 453e39158525475eca7971966c667494d240be7e242Christian Edward Gruber 4540910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber @Override 45554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb public void scanModulesForAnnotatedMethods(ModuleAnnotatedMethodScanner scanner) { 45654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb scanners.add(scanner); 45754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb elements.add(new ModuleAnnotatedMethodScannerBinding(getElementSource(), scanner)); 45854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb } 45954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb 4604994bf6a8e9986ca9013a908c340f019084be30flimpbizkit public void expose(Key<?> key) { 4614994bf6a8e9986ca9013a908c340f019084be30flimpbizkit exposeInternal(key); 4625ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit } 4635ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit 4640910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber @Override 4655ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit public AnnotatedElementBuilder expose(Class<?> type) { 4665ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit return exposeInternal(Key.get(type)); 4675ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit } 4685ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit 4690910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber @Override 4705ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit public AnnotatedElementBuilder expose(TypeLiteral<?> type) { 4715ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit return exposeInternal(Key.get(type)); 4725ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit } 4735ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit 474fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit private <T> AnnotatedElementBuilder exposeInternal(Key<T> key) { 475c3f928404a91cf837d809dcc465ba43442bc1198limpbizkit if (privateElements == null) { 476b1f42f5df9c4cd8e157a28c24c4e8eb627a7f052limpbizkit addError("Cannot expose %s on a standard binder. " 477b1f42f5df9c4cd8e157a28c24c4e8eb627a7f052limpbizkit + "Exposed bindings are only applicable to private binders.", key); 478b1f42f5df9c4cd8e157a28c24c4e8eb627a7f052limpbizkit return new AnnotatedElementBuilder() { 4790910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber @Override 480b1f42f5df9c4cd8e157a28c24c4e8eb627a7f052limpbizkit public void annotatedWith(Class<? extends Annotation> annotationType) {} 4810910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber @Override 482b1f42f5df9c4cd8e157a28c24c4e8eb627a7f052limpbizkit public void annotatedWith(Annotation annotation) {} 483b1f42f5df9c4cd8e157a28c24c4e8eb627a7f052limpbizkit }; 4845ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit } 4855ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit 486825f8c1df885b9d7643a9e18e336984f0138edafsameb ExposureBuilder<T> builder = 487825f8c1df885b9d7643a9e18e336984f0138edafsameb new ExposureBuilder<T>(this, getElementSource(), MoreTypes.canonicalizeKey(key)); 488c3f928404a91cf837d809dcc465ba43442bc1198limpbizkit privateElements.addExposureBuilder(builder); 489fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit return builder; 4905ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit } 4915ea4ab2bca518a3ac24dc5c0713326e8699d3fadlimpbizkit 4920910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber private ModuleSource getModuleSource(Object module) { 493605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber StackTraceElement[] partialCallStack; 494ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber if (getIncludeStackTraceOption() == IncludeStackTraceOption.COMPLETE) { 495605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber partialCallStack = getPartialCallStack(new Throwable().getStackTrace()); 496ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber } else { 497ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber partialCallStack = new StackTraceElement[0]; 498605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 499605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber if (moduleSource == null) { 500605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return new ModuleSource(module, partialCallStack); 501605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 502605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return moduleSource.createChild(module, partialCallStack); 503605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 504605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 505605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber private ElementSource getElementSource() { 506605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber // Full call stack 507ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber StackTraceElement[] callStack = null; 508605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber // The call stack starts from current top module configure and ends at this method caller 509ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber StackTraceElement[] partialCallStack = new StackTraceElement[0]; 510ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber // The element original source 511ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber ElementSource originalSource = null; 512ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber // The element declaring source 513ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber Object declaringSource = source; 514ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber if (declaringSource instanceof ElementSource) { 515ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber originalSource = (ElementSource) declaringSource; 516ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber declaringSource = originalSource.getDeclaringSource(); 517ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber } 518ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber IncludeStackTraceOption stackTraceOption = getIncludeStackTraceOption(); 519ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber if (stackTraceOption == IncludeStackTraceOption.COMPLETE || 5200910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber (stackTraceOption == IncludeStackTraceOption.ONLY_FOR_DECLARING_SOURCE 521ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber && declaringSource == null)) { 522605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber callStack = new Throwable().getStackTrace(); 523ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber } 524ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber if (stackTraceOption == IncludeStackTraceOption.COMPLETE) { 525605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber partialCallStack = getPartialCallStack(callStack); 526605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 527605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber if (declaringSource == null) { 528ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber // So 'source' and 'originalSource' are null otherwise declaringSource has some value 529ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber if (stackTraceOption == IncludeStackTraceOption.COMPLETE || 530ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber stackTraceOption == IncludeStackTraceOption.ONLY_FOR_DECLARING_SOURCE) { 531ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber // With the above conditions and assignments 'callStack' is non-null 532ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber declaringSource = sourceProvider.get(callStack); 533ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber } else { // or if (stackTraceOption == IncludeStackTraceOptions.OFF) 534ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber // As neither 'declaring source' nor 'call stack' is available use 'module source' 535ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber declaringSource = sourceProvider.getFromClassNames(moduleSource.getModuleClassNames()); 536605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 537605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 538605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber // Build the binding call stack 539605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return new ElementSource( 540605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber originalSource, declaringSource, moduleSource, partialCallStack); 541605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 542605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 543605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber /** 5440910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * Removes the {@link #moduleSource} call stack from the beginning of current call stack. It 5450910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * also removes the last two elements in order to make {@link #install(Module)} the last call 5460910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * in the call stack. 547605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber */ 548605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber private StackTraceElement[] getPartialCallStack(StackTraceElement[] callStack) { 549605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber int toSkip = 0; 550605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber if (moduleSource != null) { 551605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber toSkip = moduleSource.getStackTraceSize(); 552605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 553605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber // -1 for skipping 'getModuleSource' and 'getElementSource' calls 554605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber int chunkSize = callStack.length - toSkip - 1; 555605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 556605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber StackTraceElement[] partialCallStack = new StackTraceElement[chunkSize]; 557605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber System.arraycopy(callStack, 1, partialCallStack, 0, chunkSize); 558605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return partialCallStack; 559477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 5600910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber 561477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit @Override public String toString() { 562477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit return "Binder"; 563477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 564477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit } 565477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit} 566