/*
* Licensed to ElasticSearch and Shay Banon 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 com.google.common.collect.Sets;
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.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.
* <p/>
* This method allows you to switch this code
* <code>injector.getInstance(Key.get(type, Names.named(name)));</code>
* <p/>
* to the more concise
* <code>Injectors.getInstance(injector, type, name);</code>
*/
public static <T> T getInstance(Injector injector, java.lang.Class<T> 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 <T> the base type
* @return a set of objects returned from this injector
*/
public static <T> Set<T> getInstancesOf(Injector injector, Class<T> baseClass) {
Set<T> answer = Sets.newHashSet();
Set<Entry<Key<?>, Binding<?>>> entries = injector.getBindings().entrySet();
for (Entry<Key<?>, 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 <T> Set<T> getInstancesOf(Injector injector, Matcher<Class> matcher) {
Set<T> answer = Sets.newHashSet();
Set<Entry<Key<?>, Binding<?>>> entries = injector.getBindings().entrySet();
for (Entry<Key<?>, 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 <T> Set<Provider<T>> getProvidersOf(Injector injector, Matcher<Class> matcher) {
Set<Provider<T>> answer = Sets.newHashSet();
Set<Entry<Key<?>, Binding<?>>> entries = injector.getBindings().entrySet();
for (Entry<Key<?>, Binding<?>> entry : entries) {
Key<?> key = entry.getKey();
Class<?> keyType = getKeyType(key);
if (keyType != null && matcher.matches(keyType)) {
Binding<?> binding = entry.getValue();
answer.add((Provider<T>) binding.getProvider());
}
}
return answer;
}
/**
* Returns a collection of all providers of the given base type
*
* @param baseClass the base type of objects required
* @param <T> the base type
* @return a set of objects returned from this injector
*/
public static <T> Set<Provider<T>> getProvidersOf(Injector injector, Class<T> baseClass) {
Set<Provider<T>> answer = Sets.newHashSet();
Set<Entry<Key<?>, Binding<?>>> entries = injector.getBindings().entrySet();
for (Entry<Key<?>, Binding<?>> entry : entries) {
Key<?> key = entry.getKey();
Class<?> keyType = getKeyType(key);
if (keyType != null && baseClass.isAssignableFrom(keyType)) {
Binding<?> binding = entry.getValue();
answer.add((Provider<T>) binding.getProvider());
}
}
return answer;
}
/**
* Returns true if a binding exists for the given matcher
*/
public static boolean hasBinding(Injector injector, Matcher<Class> 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<Key<?>, 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<Binding<?>> getBindingsOf(Injector injector, Matcher<Class> matcher) {
Set<Binding<?>> answer = Sets.newHashSet();
Set<Entry<Key<?>, Binding<?>>> entries = injector.getBindings().entrySet();
for (Entry<Key<?>, 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<Binding<?>> getBindingsOf(Injector injector, Class<?> baseClass) {
Set<Binding<?>> answer = Sets.newHashSet();
Set<Entry<Key<?>, Binding<?>>> entries = injector.getBindings().entrySet();
for (Entry<Key<?>, 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 <T> 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 close(Injector injector) {
}
public static void cleanCaches(Injector injector) {
((InjectorImpl) injector).clearCache();
if (injector.getParent() != null) {
cleanCaches(injector.getParent());
}
}
}