diff --git a/core/src/main/java/org/elasticsearch/common/inject/Injector.java b/core/src/main/java/org/elasticsearch/common/inject/Injector.java index bfc1fb42db3..2417e3b1411 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/Injector.java +++ b/core/src/main/java/org/elasticsearch/common/inject/Injector.java @@ -38,12 +38,6 @@ import java.util.Map; * An injector can also {@link #injectMembers(Object) inject the dependencies} of * already-constructed instances. This can be used to interoperate with objects created by other * frameworks or services. - *

- * Injectors can be {@link #createChildInjector(Iterable) hierarchical}. Child injectors inherit - * the configuration of their parent injectors, but the converse does not hold. - *

- * The injector's {@link #getBindings() internal bindings} are available for introspection. This - * enables tools and extensions to operate on an injector reflectively. * * @author crazybob@google.com (Bob Lee) * @author jessewilson@google.com (Jesse Wilson) @@ -87,41 +81,6 @@ public interface Injector { */ MembersInjector getMembersInjector(Class type); - /** - * Returns all explicit bindings. - *

- * The returned map does not include bindings inherited from a {@link #getParent() parent - * injector}, should one exist. The returned map is guaranteed to iterate (for example, with - * its {@link java.util.Map#entrySet()} iterator) in the order of insertion. In other words, - * the order in which bindings appear in user Modules. - *

- * This method is part of the Guice SPI and is intended for use by tools and extensions. - */ - Map, Binding> getBindings(); - - /** - * Returns the binding for the given injection key. This will be an explicit bindings if the key - * was bound explicitly by a module, or an implicit binding otherwise. The implicit binding will - * be created if necessary. - *

- * This method is part of the Guice SPI and is intended for use by tools and extensions. - * - * @throws ConfigurationException if this injector cannot find or create the binding. - */ - Binding getBinding(Key key); - - /** - * Returns the binding for the given type. This will be an explicit bindings if the injection key - * was bound explicitly by a module, or an implicit binding otherwise. The implicit binding will - * be created if necessary. - *

- * This method is part of the Guice SPI and is intended for use by tools and extensions. - * - * @throws ConfigurationException if this injector cannot find or create the binding. - * @since 2.0 - */ - Binding getBinding(Class type); - /** * Returns all explicit bindings for {@code type}. *

@@ -166,45 +125,4 @@ public interface Injector { * @throws ProvisionException if there was a runtime failure while providing an instance. */ T getInstance(Class type); - - /** - * Returns this injector's parent, or {@code null} if this is a top-level injector. - * - * @since 2.0 - */ - Injector getParent(); - - /** - * Returns a new injector that inherits all state from this injector. All bindings, scopes, - * interceptors and type converters are inherited -- they are visible to the child injector. - * Elements of the child injector are not visible to its parent. - *

- * Just-in-time bindings created for child injectors will be created in an ancestor injector - * whenever possible. This allows for scoped instances to be shared between injectors. Use - * explicit bindings to prevent bindings from being shared with the parent injector. - *

- * No key may be bound by both an injector and one of its ancestors. This includes just-in-time - * bindings. The lone exception is the key for {@code Injector.class}, which is bound by each - * injector to itself. - * - * @since 2.0 - */ - Injector createChildInjector(Iterable modules); - - /** - * Returns a new injector that inherits all state from this injector. All bindings, scopes, - * interceptors and type converters are inherited -- they are visible to the child injector. - * Elements of the child injector are not visible to its parent. - *

- * Just-in-time bindings created for child injectors will be created in an ancestor injector - * whenever possible. This allows for scoped instances to be shared between injectors. Use - * explicit bindings to prevent bindings from being shared with the parent injector. - *

- * No key may be bound by both an injector and one of its ancestors. This includes just-in-time - * bindings. The lone exception is the key for {@code Injector.class}, which is bound by each - * injector to itself. - * - * @since 2.0 - */ - Injector createChildInjector(Module... modules); } diff --git a/core/src/main/java/org/elasticsearch/common/inject/InjectorBuilder.java b/core/src/main/java/org/elasticsearch/common/inject/InjectorBuilder.java index 2f9a3f1e7cb..93c92d480e2 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/InjectorBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/inject/InjectorBuilder.java @@ -74,15 +74,6 @@ class InjectorBuilder { return this; } - /** - * Sets the parent of the injector to-be-constructed. As a side effect, this sets this injector's - * stage to the stage of {@code parent}. - */ - InjectorBuilder parentInjector(InjectorImpl parent) { - shellBuilder.parent(parent); - return stage(parent.getInstance(Stage.class)); - } - InjectorBuilder addModules(Iterable modules) { shellBuilder.addModules(modules); return this; @@ -102,11 +93,6 @@ class InjectorBuilder { initializeStatically(); } - // If we're in the tool stage, stop here. Don't eagerly inject or load anything. - if (stage == Stage.TOOL) { - return new ToolStageInjector(primaryInjector()); - } - injectDynamically(); return primaryInjector(); @@ -217,92 +203,4 @@ class InjectorBuilder { } } } - - /** - * {@link Injector} exposed to users in {@link Stage#TOOL}. - */ - static class ToolStageInjector implements Injector { - private final Injector delegateInjector; - - ToolStageInjector(Injector delegateInjector) { - this.delegateInjector = delegateInjector; - } - - @Override - public void injectMembers(Object o) { - throw new UnsupportedOperationException( - "Injector.injectMembers(Object) is not supported in Stage.TOOL"); - } - - @Override - public Map, Binding> getBindings() { - return this.delegateInjector.getBindings(); - } - - @Override - public Binding getBinding(Key key) { - return this.delegateInjector.getBinding(key); - } - - @Override - public Binding getBinding(Class type) { - return this.delegateInjector.getBinding(type); - } - - @Override - public List> findBindingsByType(TypeLiteral type) { - return this.delegateInjector.findBindingsByType(type); - } - - @Override - public Injector getParent() { - return delegateInjector.getParent(); - } - - @Override - public Injector createChildInjector(Iterable modules) { - return delegateInjector.createChildInjector(modules); - } - - @Override - public Injector createChildInjector(Module... modules) { - return delegateInjector.createChildInjector(modules); - } - - @Override - public Provider getProvider(Key key) { - throw new UnsupportedOperationException( - "Injector.getProvider(Key) is not supported in Stage.TOOL"); - } - - @Override - public Provider getProvider(Class type) { - throw new UnsupportedOperationException( - "Injector.getProvider(Class) is not supported in Stage.TOOL"); - } - - @Override - public MembersInjector getMembersInjector(TypeLiteral typeLiteral) { - throw new UnsupportedOperationException( - "Injector.getMembersInjector(TypeLiteral) is not supported in Stage.TOOL"); - } - - @Override - public MembersInjector getMembersInjector(Class type) { - throw new UnsupportedOperationException( - "Injector.getMembersInjector(Class) is not supported in Stage.TOOL"); - } - - @Override - public T getInstance(Key key) { - throw new UnsupportedOperationException( - "Injector.getInstance(Key) is not supported in Stage.TOOL"); - } - - @Override - public T getInstance(Class type) { - throw new UnsupportedOperationException( - "Injector.getInstance(Class) is not supported in Stage.TOOL"); - } - } } diff --git a/core/src/main/java/org/elasticsearch/common/inject/InjectorImpl.java b/core/src/main/java/org/elasticsearch/common/inject/InjectorImpl.java index ae4cd744dd0..817d52ea743 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/InjectorImpl.java +++ b/core/src/main/java/org/elasticsearch/common/inject/InjectorImpl.java @@ -64,7 +64,6 @@ import static org.elasticsearch.common.inject.internal.Annotations.findScopeAnno */ class InjectorImpl implements Injector, Lookups { final State state; - final InjectorImpl parent; boolean readOnly; BindingsMultimap bindingsMultimap = new BindingsMultimap(); final Initializer initializer; @@ -76,16 +75,10 @@ class InjectorImpl implements Injector, Lookups { Lookups lookups = new DeferredLookups(this); - InjectorImpl(@Nullable InjectorImpl parent, State state, Initializer initializer) { - this.parent = parent; + InjectorImpl(State state, Initializer initializer) { this.state = state; this.initializer = initializer; - - if (parent != null) { - localContext = parent.localContext; - } else { - localContext = new ThreadLocal<>(); - } + localContext = new ThreadLocal<>(); } /** @@ -106,21 +99,6 @@ class InjectorImpl implements Injector, Lookups { return bindingsMultimap.getAll(type); } - /** - * Returns the binding for {@code key} - */ - @Override - public BindingImpl getBinding(Key key) { - Errors errors = new Errors(key); - try { - BindingImpl result = getBindingOrThrow(key, errors); - errors.throwConfigurationExceptionIfErrorsExist(); - return result; - } catch (ErrorsException e) { - throw new ConfigurationException(errors.merge(e.getErrors()).getMessages()); - } - } - /** * Gets a binding implementation. First, it check to see if the parent has a binding. If the * parent has a binding and the binding is scoped, it will use that binding. Otherwise, this @@ -139,29 +117,6 @@ class InjectorImpl implements Injector, Lookups { return getJustInTimeBinding(key, errors); } - @Override - public Binding getBinding(Class type) { - return getBinding(Key.get(type)); - } - - @Override - public Injector getParent() { - return parent; - } - - @Override - public Injector createChildInjector(Iterable modules) { - return new InjectorBuilder() - .parentInjector(this) - .addModules(modules) - .build(); - } - - @Override - public Injector createChildInjector(Module... modules) { - return createChildInjector(Arrays.asList(modules)); - } - /** * Returns a just-in-time binding for {@code key}, creating it if necessary. * @@ -171,13 +126,11 @@ class InjectorImpl implements Injector, Lookups { throws ErrorsException { synchronized (state.lock()) { // first try to find a JIT binding that we've already created - for (InjectorImpl injector = this; injector != null; injector = injector.parent) { - @SuppressWarnings("unchecked") // we only store bindings that match their key - BindingImpl binding = (BindingImpl) injector.jitBindings.get(key); + @SuppressWarnings("unchecked") // we only store bindings that match their key + BindingImpl binding = (BindingImpl) jitBindings.get(key); - if (binding != null) { - return binding; - } + if (binding != null) { + return binding; } return createJustInTimeBindingRecursive(key, errors); @@ -600,14 +553,6 @@ class InjectorImpl implements Injector, Lookups { */ private BindingImpl createJustInTimeBindingRecursive(Key key, Errors errors) throws ErrorsException { - // ask the parent to create the JIT binding - if (parent != null && !parent.readOnly /* ES: don't check on parent if its read only, its already created all the bindings it can*/) { - try { - return parent.createJustInTimeBindingRecursive(key, new Errors()); - } catch (ErrorsException ignored) { - } - } - if (state.isBlacklisted(key)) { throw errors.childBindingAlreadySet(key).toException(); } @@ -686,12 +631,6 @@ class InjectorImpl implements Injector, Lookups { return getBindingOrThrow(key, errors).getInternalFactory(); } - // not test-covered - @Override - public Map, Binding> getBindings() { - return state.getExplicitBindingsThisLevel(); - } - private static class BindingsMultimap { final Map, List>> multimap = new HashMap<>(); diff --git a/core/src/main/java/org/elasticsearch/common/inject/InjectorShell.java b/core/src/main/java/org/elasticsearch/common/inject/InjectorShell.java index 7307fb4a6fe..793540aba73 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/InjectorShell.java +++ b/core/src/main/java/org/elasticsearch/common/inject/InjectorShell.java @@ -50,18 +50,12 @@ class InjectorShell { private final List elements; private final InjectorImpl injector; - private final PrivateElements privateElements; - private InjectorShell(Builder builder, List elements, InjectorImpl injector) { - this.privateElements = builder.privateElements; + private InjectorShell(List elements, InjectorImpl injector) { this.elements = elements; this.injector = injector; } - PrivateElements getPrivateElements() { - return privateElements; - } - InjectorImpl getInjector() { return injector; } @@ -134,7 +128,7 @@ class InjectorShell { throw new IllegalStateException("no state. Did you remember to lock() ?"); } - InjectorImpl injector = new InjectorImpl(parent, state, initializer); + InjectorImpl injector = new InjectorImpl(state, initializer); if (privateElements != null) { privateElements.initInjector(injector); } @@ -167,7 +161,7 @@ class InjectorShell { stopwatch.resetAndLog("Binding creation"); List injectorShells = new ArrayList<>(); - injectorShells.add(new InjectorShell(this, elements, injector)); + injectorShells.add(new InjectorShell(elements, injector)); // recursively build child shells PrivateElementProcessor processor = new PrivateElementProcessor(errors, stage); diff --git a/core/src/main/java/org/elasticsearch/common/inject/Injectors.java b/core/src/main/java/org/elasticsearch/common/inject/Injectors.java deleted file mode 100644 index 900d2588b52..00000000000 --- a/core/src/main/java/org/elasticsearch/common/inject/Injectors.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you 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.elasticsearch.common.inject; - -import org.elasticsearch.common.inject.matcher.Matcher; -import org.elasticsearch.common.inject.name.Names; -import org.elasticsearch.common.inject.spi.Message; - -import java.lang.reflect.Type; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -/** - * - */ -public class Injectors { - - public static Throwable getFirstErrorFailure(CreationException e) { - if (e.getErrorMessages().isEmpty()) { - return e; - } - // return the first message that has root cause, probably an actual error - for (Message message : e.getErrorMessages()) { - if (message.getCause() != null) { - return message.getCause(); - } - } - return e; - } - - /** - * Returns an instance of the given type with the {@link org.elasticsearch.common.inject.name.Named} - * annotation value. - *

- * This method allows you to switch this code - * injector.getInstance(Key.get(type, Names.named(name))); - *

- * to the more concise - * Injectors.getInstance(injector, type, name); - */ - public static T getInstance(Injector injector, java.lang.Class type, String name) { - return injector.getInstance(Key.get(type, Names.named(name))); - } - - /** - * Returns a collection of all instances of the given base type - * - * @param baseClass the base type of objects required - * @param the base type - * @return a set of objects returned from this injector - */ - public static Set getInstancesOf(Injector injector, Class baseClass) { - Set answer = new HashSet<>(); - Set, Binding>> entries = injector.getBindings().entrySet(); - for (Entry, Binding> entry : entries) { - Key key = entry.getKey(); - Class keyType = getKeyType(key); - if (keyType != null && baseClass.isAssignableFrom(keyType)) { - Binding binding = entry.getValue(); - Object value = binding.getProvider().get(); - if (value != null) { - T castValue = baseClass.cast(value); - answer.add(castValue); - } - } - } - return answer; - } - - /** - * Returns a collection of all instances matching the given matcher - * - * @param matcher matches the types to return instances - * @return a set of objects returned from this injector - */ - public static Set getInstancesOf(Injector injector, Matcher matcher) { - Set answer = new HashSet<>(); - Set, Binding>> entries = injector.getBindings().entrySet(); - for (Entry, Binding> entry : entries) { - Key key = entry.getKey(); - Class keyType = getKeyType(key); - if (keyType != null && matcher.matches(keyType)) { - Binding binding = entry.getValue(); - Object value = binding.getProvider().get(); - answer.add((T) value); - } - } - return answer; - } - - /** - * Returns a collection of all of the providers matching the given matcher - * - * @param matcher matches the types to return instances - * @return a set of objects returned from this injector - */ - public static Set> getProvidersOf(Injector injector, Matcher matcher) { - Set> answer = new HashSet<>(); - Set, Binding>> entries = injector.getBindings().entrySet(); - for (Entry, Binding> entry : entries) { - Key key = entry.getKey(); - Class keyType = getKeyType(key); - if (keyType != null && matcher.matches(keyType)) { - Binding binding = entry.getValue(); - answer.add((Provider) binding.getProvider()); - } - } - return answer; - } - - /** - * Returns a collection of all providers of the given base type - * - * @param baseClass the base type of objects required - * @param the base type - * @return a set of objects returned from this injector - */ - public static Set> getProvidersOf(Injector injector, Class baseClass) { - Set> answer = new HashSet<>(); - Set, Binding>> entries = injector.getBindings().entrySet(); - for (Entry, Binding> entry : entries) { - Key key = entry.getKey(); - Class keyType = getKeyType(key); - if (keyType != null && baseClass.isAssignableFrom(keyType)) { - Binding binding = entry.getValue(); - answer.add((Provider) binding.getProvider()); - } - } - return answer; - } - - /** - * Returns true if a binding exists for the given matcher - */ - public static boolean hasBinding(Injector injector, Matcher matcher) { - return !getBindingsOf(injector, matcher).isEmpty(); - } - - /** - * Returns true if a binding exists for the given base class - */ - public static boolean hasBinding(Injector injector, Class baseClass) { - return !getBindingsOf(injector, baseClass).isEmpty(); - } - - /** - * Returns true if a binding exists for the given key - */ - public static boolean hasBinding(Injector injector, Key key) { - Binding binding = getBinding(injector, key); - return binding != null; - } - - /** - * Returns the binding for the given key or null if there is no such binding - */ - public static Binding getBinding(Injector injector, Key key) { - Map, Binding> bindings = injector.getBindings(); - Binding binding = bindings.get(key); - return binding; - } - - /** - * Returns a collection of all of the bindings matching the given matcher - * - * @param matcher matches the types to return instances - * @return a set of objects returned from this injector - */ - public static Set> getBindingsOf(Injector injector, Matcher matcher) { - Set> answer = new HashSet<>(); - Set, Binding>> entries = injector.getBindings().entrySet(); - for (Entry, Binding> entry : entries) { - Key key = entry.getKey(); - Class keyType = getKeyType(key); - if (keyType != null && matcher.matches(keyType)) { - answer.add(entry.getValue()); - } - } - return answer; - } - - /** - * Returns a collection of all bindings of the given base type - * - * @param baseClass the base type of objects required - * @return a set of objects returned from this injector - */ - public static Set> getBindingsOf(Injector injector, Class baseClass) { - Set> answer = new HashSet<>(); - Set, Binding>> entries = injector.getBindings().entrySet(); - for (Entry, Binding> entry : entries) { - Key key = entry.getKey(); - Class keyType = getKeyType(key); - if (keyType != null && baseClass.isAssignableFrom(keyType)) { - answer.add(entry.getValue()); - } - } - return answer; - } - - /** - * Returns the key type of the given key - */ - public static Class getKeyType(Key key) { - Class keyType = null; - TypeLiteral typeLiteral = key.getTypeLiteral(); - Type type = typeLiteral.getType(); - if (type instanceof Class) { - keyType = (Class) type; - } - return keyType; - } - - public static void cleanCaches(Injector injector) { - ((InjectorImpl) injector).clearCache(); - if (injector.getParent() != null) { - cleanCaches(injector.getParent()); - } - } -} diff --git a/core/src/main/java/org/elasticsearch/common/inject/ModulesBuilder.java b/core/src/main/java/org/elasticsearch/common/inject/ModulesBuilder.java index 41cdecfbcad..3321b75f4e5 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/ModulesBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/inject/ModulesBuilder.java @@ -23,9 +23,6 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -/** - * - */ public class ModulesBuilder implements Iterable { private final List modules = new ArrayList<>(); @@ -44,19 +41,10 @@ public class ModulesBuilder implements Iterable { public Injector createInjector() { Injector injector = Guice.createInjector(modules); - Injectors.cleanCaches(injector); + ((InjectorImpl) injector).clearCache(); // in ES, we always create all instances as if they are eager singletons // this allows for considerable memory savings (no need to store construction info) as well as cycles ((InjectorImpl) injector).readOnlyAllSingletons(); return injector; } - - public Injector createChildInjector(Injector injector) { - Injector childInjector = injector.createChildInjector(modules); - Injectors.cleanCaches(childInjector); - // in ES, we always create all instances as if they are eager singletons - // this allows for considerable memory savings (no need to store construction info) as well as cycles - ((InjectorImpl) childInjector).readOnlyAllSingletons(); - return childInjector; - } } diff --git a/core/src/main/java/org/elasticsearch/common/inject/PrivateModule.java b/core/src/main/java/org/elasticsearch/common/inject/PrivateModule.java index 4413028f908..b56c0e11ab1 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/PrivateModule.java +++ b/core/src/main/java/org/elasticsearch/common/inject/PrivateModule.java @@ -61,10 +61,6 @@ import java.lang.annotation.Annotation; * } * *

- * Private modules are implemented using {@link Injector#createChildInjector(Module[]) parent - * injectors}. When it can satisfy their dependencies, just-in-time bindings will be created in the - * root environment. Such bindings are shared among all environments in the tree. - *

* The scope of a binding is constrained to its environment. A singleton bound in a private * module will be unique to its environment. But a binding for the same type in a different private * module will yield a different instance. @@ -143,13 +139,6 @@ public abstract class PrivateModule implements Module { return binder; } - /** - * @see Binder#bindScope(Class, Scope) - */ - protected final void bindScope(Class scopeAnnotation, Scope scope) { - binder.bindScope(scopeAnnotation, scope); - } - /** * @see Binder#bind(Key) */ @@ -171,13 +160,6 @@ public abstract class PrivateModule implements Module { return binder.bind(clazz); } - /** - * @see Binder#bindConstant() - */ - protected final AnnotatedConstantBindingBuilder bindConstant() { - return binder.bindConstant(); - } - /** * @see Binder#install(Module) */ @@ -206,34 +188,6 @@ public abstract class PrivateModule implements Module { binder.addError(message); } - /** - * @see Binder#requestInjection(Object) - */ - protected final void requestInjection(Object instance) { - binder.requestInjection(instance); - } - - /** - * @see Binder#requestStaticInjection(Class[]) - */ - protected final void requestStaticInjection(Class... types) { - binder.requestStaticInjection(types); - } - - /** - * Instructs Guice to require a binding to the given key. - */ - protected final void requireBinding(Key key) { - binder.getProvider(key); - } - - /** - * Instructs Guice to require a binding to the given type. - */ - protected final void requireBinding(Class type) { - binder.getProvider(type); - } - /** * @see Binder#getProvider(Key) */ @@ -248,21 +202,6 @@ public abstract class PrivateModule implements Module { return binder.getProvider(type); } - /** - * @see Binder#convertToTypes(org.elasticsearch.common.inject.matcher.Matcher, org.elasticsearch.common.inject.spi.TypeConverter) - */ - protected final void convertToTypes(Matcher> typeMatcher, - TypeConverter converter) { - binder.convertToTypes(typeMatcher, converter); - } - - /** - * @see Binder#currentStage() - */ - protected final Stage currentStage() { - return binder.currentStage(); - } - /** * @see Binder#getMembersInjector(Class) */ @@ -276,12 +215,4 @@ public abstract class PrivateModule implements Module { protected MembersInjector getMembersInjector(TypeLiteral type) { return binder.getMembersInjector(type); } - - /** - * @see Binder#bindListener(org.elasticsearch.common.inject.matcher.Matcher, org.elasticsearch.common.inject.spi.TypeListener) - */ - protected void bindListener(Matcher> typeMatcher, - TypeListener listener) { - binder.bindListener(typeMatcher, listener); - } } diff --git a/core/src/main/java/org/elasticsearch/common/inject/assistedinject/FactoryProvider.java b/core/src/main/java/org/elasticsearch/common/inject/assistedinject/FactoryProvider.java index 0def65b9a13..099ff661595 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/assistedinject/FactoryProvider.java +++ b/core/src/main/java/org/elasticsearch/common/inject/assistedinject/FactoryProvider.java @@ -134,7 +134,7 @@ public class FactoryProvider implements Provider, HasDependencies { /* * This class implements the old @AssistedInject implementation that manually matches constructors - * to factory methods. The new child injector implementation lives in FactoryProvider2. + * to factory methods. */ private Injector injector; @@ -142,23 +142,6 @@ public class FactoryProvider implements Provider, HasDependencies { private final TypeLiteral factoryType; private final Map> factoryMethodToConstructor; - public static Provider newFactory( - Class factoryType, Class implementationType) { - return newFactory(TypeLiteral.get(factoryType), TypeLiteral.get(implementationType)); - } - - public static Provider newFactory( - TypeLiteral factoryType, TypeLiteral implementationType) { - Map> factoryMethodToConstructor - = createMethodMapping(factoryType, implementationType); - - if (!factoryMethodToConstructor.isEmpty()) { - return new FactoryProvider<>(factoryType, factoryMethodToConstructor); - } else { - return new FactoryProvider2<>(factoryType, Key.get(implementationType)); - } - } - private FactoryProvider(TypeLiteral factoryType, Map> factoryMethodToConstructor) { this.factoryType = factoryType; @@ -166,22 +149,6 @@ public class FactoryProvider implements Provider, HasDependencies { checkDeclaredExceptionsMatch(); } - @Inject - void setInjectorAndCheckUnboundParametersAreInjectable(Injector injector) { - this.injector = injector; - for (AssistedConstructor c : factoryMethodToConstructor.values()) { - for (Parameter p : c.getAllParameters()) { - if (!p.isProvidedByFactory() && !paramCanBeInjected(p, injector)) { - // this is lame - we're not using the proper mechanism to add an - // error to the injector. Throughout this class we throw exceptions - // to add errors, which isn't really the best way in Guice - throw newConfigurationException("Parameter of type '%s' is not injectable or annotated " - + "with @Assisted for Constructor '%s'", p, c); - } - } - } - } - private void checkDeclaredExceptionsMatch() { for (Map.Entry> entry : factoryMethodToConstructor.entrySet()) { for (Class constructorException : entry.getValue().getDeclaredExceptions()) { @@ -204,82 +171,6 @@ public class FactoryProvider implements Provider, HasDependencies { return false; } - private boolean paramCanBeInjected(Parameter parameter, Injector injector) { - return parameter.isBound(injector); - } - - private static Map> createMethodMapping( - TypeLiteral factoryType, TypeLiteral implementationType) { - List> constructors = new ArrayList<>(); - - for (Constructor constructor : implementationType.getRawType().getConstructors()) { - if (constructor.getAnnotation(AssistedInject.class) != null) { - @SuppressWarnings("unchecked") // the constructor type and implementation type agree - AssistedConstructor assistedConstructor = new AssistedConstructor( - constructor, implementationType.getParameterTypes(constructor)); - constructors.add(assistedConstructor); - } - } - - if (constructors.isEmpty()) { - return emptyMap(); - } - - Method[] factoryMethods = factoryType.getRawType().getMethods(); - - if (constructors.size() != factoryMethods.length) { - throw newConfigurationException("Constructor mismatch: %s has %s @AssistedInject " - + "constructors, factory %s has %s creation methods", implementationType, - constructors.size(), factoryType, factoryMethods.length); - } - - Map paramsToConstructor = new HashMap<>(); - - for (AssistedConstructor c : constructors) { - if (paramsToConstructor.containsKey(c.getAssistedParameters())) { - throw new RuntimeException("Duplicate constructor, " + c); - } - paramsToConstructor.put(c.getAssistedParameters(), c); - } - - Map> result = new HashMap<>(); - for (Method method : factoryMethods) { - if (!method.getReturnType().isAssignableFrom(implementationType.getRawType())) { - throw newConfigurationException("Return type of method %s is not assignable from %s", - method, implementationType); - } - - List parameterTypes = new ArrayList<>(); - for (TypeLiteral parameterType : factoryType.getParameterTypes(method)) { - parameterTypes.add(parameterType.getType()); - } - ParameterListKey methodParams = new ParameterListKey(parameterTypes); - - if (!paramsToConstructor.containsKey(methodParams)) { - throw newConfigurationException("%s has no @AssistInject constructor that takes the " - + "@Assisted parameters %s in that order. @AssistInject constructors are %s", - implementationType, methodParams, paramsToConstructor.values()); - } - - method.getParameterAnnotations(); - for (Annotation[] parameterAnnotations : method.getParameterAnnotations()) { - for (Annotation parameterAnnotation : parameterAnnotations) { - if (parameterAnnotation.annotationType() == Assisted.class) { - throw newConfigurationException("Factory method %s has an @Assisted parameter, which " - + "is incompatible with the deprecated @AssistedInject annotation. Please replace " - + "@AssistedInject with @Inject on the %s constructor.", - method, implementationType); - } - } - } - - AssistedConstructor matchingConstructor = paramsToConstructor.remove(methodParams); - - result.put(method, matchingConstructor); - } - return result; - } - @Override public Set> getDependencies() { Set> dependencies = new HashSet<>(); diff --git a/core/src/main/java/org/elasticsearch/common/inject/assistedinject/FactoryProvider2.java b/core/src/main/java/org/elasticsearch/common/inject/assistedinject/FactoryProvider2.java deleted file mode 100644 index 29863527202..00000000000 --- a/core/src/main/java/org/elasticsearch/common/inject/assistedinject/FactoryProvider2.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (C) 2008 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 org.elasticsearch.common.inject.assistedinject; - -import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.common.inject.Binder; -import org.elasticsearch.common.inject.Binding; -import org.elasticsearch.common.inject.ConfigurationException; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.inject.Injector; -import org.elasticsearch.common.inject.Key; -import org.elasticsearch.common.inject.Module; -import org.elasticsearch.common.inject.Provider; -import org.elasticsearch.common.inject.ProvisionException; -import org.elasticsearch.common.inject.TypeLiteral; -import org.elasticsearch.common.inject.internal.Errors; -import org.elasticsearch.common.inject.internal.ErrorsException; -import org.elasticsearch.common.inject.spi.Message; -import org.elasticsearch.common.inject.util.Providers; - -import java.lang.annotation.Annotation; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static java.util.Collections.unmodifiableMap; -import static org.elasticsearch.common.inject.internal.Annotations.getKey; - -/** - * The newer implementation of factory provider. This implementation uses a child injector to - * create values. - * - * @author jessewilson@google.com (Jesse Wilson) - * @author dtm@google.com (Daniel Martin) - */ -public final class FactoryProvider2 implements InvocationHandler, Provider { - - /** - * if a factory method parameter isn't annotated, it gets this annotation. - */ - static final Assisted DEFAULT_ANNOTATION = new Assisted() { - @Override - public String value() { - return ""; - } - - @Override - public Class annotationType() { - return Assisted.class; - } - - @Override - public boolean equals(Object o) { - return o instanceof Assisted - && ((Assisted) o).value().equals(""); - } - - @Override - public int hashCode() { - return 127 * "value".hashCode() ^ "".hashCode(); - } - - @Override - public String toString() { - return "@" + Assisted.class.getName() + "(value=)"; - } - }; - - /** - * the produced type, or null if all methods return concrete types - */ - private final Key producedType; - private final Map> returnTypesByMethod; - private final Map>> paramTypes; - - /** - * the hosting injector, or null if we haven't been initialized yet - */ - private Injector injector; - - /** - * the factory interface, implemented and provided - */ - private final F factory; - - /** - * @param factoryType a Java interface that defines one or more create methods. - * @param producedType a concrete type that is assignable to the return types of all factory - * methods. - */ - FactoryProvider2(TypeLiteral factoryType, Key producedType) { - this.producedType = producedType; - - Errors errors = new Errors(); - - @SuppressWarnings("unchecked") // we imprecisely treat the class literal of T as a Class - Class factoryRawType = (Class) factoryType.getRawType(); - - try { - Map> returnTypesBuilder = new HashMap<>(); - Map>> paramTypesBuilder = new HashMap<>(); - // TODO: also grab methods from superinterfaces - for (Method method : factoryRawType.getMethods()) { - Key returnType = getKey( - factoryType.getReturnType(method), method, method.getAnnotations(), errors); - returnTypesBuilder.put(method, returnType); - List> params = factoryType.getParameterTypes(method); - Annotation[][] paramAnnotations = method.getParameterAnnotations(); - int p = 0; - List> keys = new ArrayList<>(); - for (TypeLiteral param : params) { - Key paramKey = getKey(param, method, paramAnnotations[p++], errors); - keys.add(assistKey(method, paramKey, errors)); - } - paramTypesBuilder.put(method, Collections.unmodifiableList(keys)); - } - returnTypesByMethod = unmodifiableMap(returnTypesBuilder); - paramTypes = unmodifiableMap(paramTypesBuilder); - } catch (ErrorsException e) { - throw new ConfigurationException(e.getErrors().getMessages()); - } - - factory = factoryRawType.cast(Proxy.newProxyInstance(factoryRawType.getClassLoader(), - new Class[]{factoryRawType}, this)); - } - - @Override - public F get() { - return factory; - } - - /** - * Returns a key similar to {@code key}, but with an {@literal @}Assisted binding annotation. - * This fails if another binding annotation is clobbered in the process. If the key already has - * the {@literal @}Assisted annotation, it is returned as-is to preserve any String value. - */ - private Key assistKey(Method method, Key key, Errors errors) throws ErrorsException { - if (key.getAnnotationType() == null) { - return Key.get(key.getTypeLiteral(), DEFAULT_ANNOTATION); - } else if (key.getAnnotationType() == Assisted.class) { - return key; - } else { - errors.withSource(method).addMessage( - "Only @Assisted is allowed for factory parameters, but found @%s", - key.getAnnotationType()); - throw errors.toException(); - } - } - - /** - * At injector-creation time, we initialize the invocation handler. At this time we make sure - * all factory methods will be able to build the target types. - */ - @Inject - public void initialize(Injector injector) { - if (this.injector != null) { - throw new ConfigurationException(Collections.singletonList(new Message(FactoryProvider2.class, - "Factories.create() factories may only be used in one Injector!"))); - } - - this.injector = injector; - - for (Method method : returnTypesByMethod.keySet()) { - Object[] args = new Object[method.getParameterTypes().length]; - Arrays.fill(args, "dummy object for validating Factories"); - getBindingFromNewInjector(method, args); // throws if the binding isn't properly configured - } - } - - /** - * Creates a child injector that binds the args, and returns the binding for the method's result. - */ - public Binding getBindingFromNewInjector(final Method method, final Object[] args) { - if (injector == null) { - throw new IllegalStateException("Factories.create() factories cannot be used until they're initialized by Guice."); - } - - final Key returnType = returnTypesByMethod.get(method); - - Module assistedModule = new AbstractModule() { - @Override - @SuppressWarnings("unchecked") // raw keys are necessary for the args array and return value - protected void configure() { - Binder binder = binder().withSource(method); - - int p = 0; - for (Key paramKey : paramTypes.get(method)) { - // Wrap in a Provider to cover null, and to prevent Guice from injecting the parameter - binder.bind((Key) paramKey).toProvider(Providers.of(args[p++])); - } - - if (producedType != null && !returnType.equals(producedType)) { - binder.bind(returnType).to((Key) producedType); - } else { - binder.bind(returnType); - } - } - }; - - Injector forCreate = injector.createChildInjector(assistedModule); - return forCreate.getBinding(returnType); - } - - /** - * When a factory method is invoked, we create a child injector that binds all parameters, then - * use that to get an instance of the return type. - */ - @Override - public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable { - if (method.getDeclaringClass() == Object.class) { - return method.invoke(this, args); - } - - Provider provider = getBindingFromNewInjector(method, args).getProvider(); - try { - return provider.get(); - } catch (ProvisionException e) { - // if this is an exception declared by the factory method, throw it as-is - if (e.getErrorMessages().size() == 1) { - Message onlyError = e.getErrorMessages().iterator().next(); - Throwable cause = onlyError.getCause(); - if (cause != null && canRethrow(method, cause)) { - throw cause; - } - } - throw e; - } - } - - @Override - public String toString() { - return factory.getClass().getInterfaces()[0].getName() - + " for " + producedType.getTypeLiteral(); - } - - @Override - public boolean equals(Object o) { - return o == this || o == factory; - } - - @Override - public int hashCode() { - // This way both this and its factory hash to the same spot, making hashCode consistent. - return factory.hashCode(); - } - - /** - * Returns true if {@code thrown} can be thrown by {@code invoked} without wrapping. - */ - static boolean canRethrow(Method invoked, Throwable thrown) { - if (thrown instanceof Error || thrown instanceof RuntimeException) { - return true; - } - - for (Class declared : invoked.getExceptionTypes()) { - if (declared.isInstance(thrown)) { - return true; - } - } - - return false; - } -} diff --git a/core/src/main/java/org/elasticsearch/common/inject/assistedinject/Parameter.java b/core/src/main/java/org/elasticsearch/common/inject/assistedinject/Parameter.java index 0fae9dede5b..5ceb086db9f 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/assistedinject/Parameter.java +++ b/core/src/main/java/org/elasticsearch/common/inject/assistedinject/Parameter.java @@ -87,34 +87,6 @@ class Parameter { : injector.getInstance(getPrimaryBindingKey()); } - public boolean isBound(Injector injector) { - return isBound(injector, getPrimaryBindingKey()) - || isBound(injector, fixAnnotations(getPrimaryBindingKey())); - } - - private boolean isBound(Injector injector, Key key) { - // This method is particularly lame - we really need an API that can test - // for any binding, implicit or explicit - try { - return injector.getBinding(key) != null; - } catch (ConfigurationException e) { - return false; - } - } - - /** - * Replace annotation instances with annotation types, this is only - * appropriate for testing if a key is bound and not for injecting. - *

- * See Guice bug 125, - * http://code.google.com/p/google-guice/issues/detail?id=125 - */ - public Key fixAnnotations(Key key) { - return key.getAnnotation() == null - ? key - : Key.get(key.getTypeLiteral(), key.getAnnotation().annotationType()); - } - Key getPrimaryBindingKey() { return isProvider ? getBindingForType(getProvidedType(type)) diff --git a/core/src/main/java/org/elasticsearch/common/inject/spi/ConvertedConstantBinding.java b/core/src/main/java/org/elasticsearch/common/inject/spi/ConvertedConstantBinding.java index 3c4ec4d9ed5..1963919c0c5 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/spi/ConvertedConstantBinding.java +++ b/core/src/main/java/org/elasticsearch/common/inject/spi/ConvertedConstantBinding.java @@ -36,8 +36,7 @@ public interface ConvertedConstantBinding extends Binding, HasDependencies T getValue(); /** - * Returns the key for the source binding. That binding can e retrieved from an injector using - * {@link org.elasticsearch.common.inject.Injector#getBinding(Key) Injector.getBinding(key)}. + * Returns the key for the source binding. */ Key getSourceKey(); diff --git a/core/src/main/java/org/elasticsearch/common/inject/spi/Element.java b/core/src/main/java/org/elasticsearch/common/inject/spi/Element.java index f9128d98f56..a2eaf995c70 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/spi/Element.java +++ b/core/src/main/java/org/elasticsearch/common/inject/spi/Element.java @@ -25,9 +25,6 @@ import org.elasticsearch.common.inject.Binder; * Elements#getElements(org.elasticsearch.common.inject.Module[]) Elements.getElements()} to read the elements * from a module, and {@link Elements#getModule(Iterable) Elements.getModule()} to rewrite them. * This can be used for static analysis and generation of Guice modules. - *

- * The elements of an injector can be inspected and exercised. Use {@link - * org.elasticsearch.common.inject.Injector#getBindings Injector.getBindings()} to reflect on Guice injectors. * * @author jessewilson@google.com (Jesse Wilson) * @author crazybob@google.com (Bob Lee) diff --git a/core/src/main/java/org/elasticsearch/common/inject/spi/Elements.java b/core/src/main/java/org/elasticsearch/common/inject/spi/Elements.java index 4b3660fe47a..30911def551 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/spi/Elements.java +++ b/core/src/main/java/org/elasticsearch/common/inject/spi/Elements.java @@ -80,13 +80,6 @@ public final class Elements { return getElements(Stage.DEVELOPMENT, Arrays.asList(modules)); } - /** - * Records the elements executed by {@code modules}. - */ - public static List getElements(Stage stage, Module... modules) { - return getElements(stage, Arrays.asList(modules)); - } - /** * Records the elements executed by {@code modules}. */ @@ -119,11 +112,6 @@ public final class Elements { }; } - @SuppressWarnings("unchecked") - static BindingTargetVisitor getInstanceVisitor() { - return (BindingTargetVisitor) GET_INSTANCE_VISITOR; - } - private static class RecordingBinder implements Binder, PrivateBinder { private final Stage stage; private final Set modules; diff --git a/core/src/main/java/org/elasticsearch/common/inject/spi/LinkedKeyBinding.java b/core/src/main/java/org/elasticsearch/common/inject/spi/LinkedKeyBinding.java index 82c36c7c2e2..60b7adced3e 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/spi/LinkedKeyBinding.java +++ b/core/src/main/java/org/elasticsearch/common/inject/spi/LinkedKeyBinding.java @@ -28,8 +28,7 @@ import org.elasticsearch.common.inject.Key; public interface LinkedKeyBinding extends Binding { /** - * Returns the linked key used to resolve injections. That binding can be retrieved from an - * injector using {@link org.elasticsearch.common.inject.Injector#getBinding(Key) Injector.getBinding(key)}. + * Returns the linked key used to resolve injections. */ Key getLinkedKey(); diff --git a/core/src/main/java/org/elasticsearch/common/inject/spi/ProviderBinding.java b/core/src/main/java/org/elasticsearch/common/inject/spi/ProviderBinding.java index 04fb78d0288..c6ac377c051 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/spi/ProviderBinding.java +++ b/core/src/main/java/org/elasticsearch/common/inject/spi/ProviderBinding.java @@ -30,9 +30,7 @@ import org.elasticsearch.common.inject.Provider; public interface ProviderBinding> extends Binding { /** - * Returns the key whose binding is used to {@link Provider#get provide instances}. That binding - * can be retrieved from an injector using {@link org.elasticsearch.common.inject.Injector#getBinding(Key) - * Injector.getBinding(providedKey)} + * Returns the key whose binding is used to {@link Provider#get provide instances}. */ Key getProvidedKey(); } \ No newline at end of file diff --git a/core/src/main/java/org/elasticsearch/common/inject/spi/ProviderKeyBinding.java b/core/src/main/java/org/elasticsearch/common/inject/spi/ProviderKeyBinding.java index 15aa751f4a6..78191621561 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/spi/ProviderKeyBinding.java +++ b/core/src/main/java/org/elasticsearch/common/inject/spi/ProviderKeyBinding.java @@ -30,9 +30,7 @@ import org.elasticsearch.common.inject.Provider; public interface ProviderKeyBinding extends Binding { /** - * Returns the key used to resolve the provider's binding. That binding can be retrieved from an - * injector using {@link org.elasticsearch.common.inject.Injector#getBinding(Key) - * Injector.getBinding(providerKey)} + * Returns the key used to resolve the provider's binding. */ Key> getProviderKey();