juzu.impl.inject.spi.InjectionContext Maven / Gradle / Ivy
/*
* Copyright 2013 eXo Platform SAS
*
* 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 juzu.impl.inject.spi;
import juzu.impl.inject.ScopeController;
import java.io.Closeable;
import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.NoSuchElementException;
/** @author Julien Viet */
public abstract class InjectionContext implements Closeable {
public abstract ScopeController getScopeController();
/**
* Returns the injector provider.
*
* @return the injector provider
*/
public abstract InjectorProvider getProvider();
public abstract ClassLoader getClassLoader();
public abstract B resolveBean(Class> type);
public abstract B resolveBean(String name);
public abstract Iterable resolveBeans(Class> type);
/**
* Create a bean context for the specified bean.
*
* @param bean the bean
* @return the bean context
* @throws InvocationTargetException wrap any exception thrown by the bean class during its creation.
*/
public abstract C createContext(B bean) throws InvocationTargetException;
/**
* Resolve the specified bean context.
*
* @param bean the bean
* @param context the bean context
*/
public abstract void releaseContext(B bean, C context);
/**
* Get the bean object associated the bean instance.
*
* @param bean the bean
* @param context the bean instance
* @return the bean instance
* @throws InvocationTargetException wrap any exception throws,by the bean class during its creation.
*/
public abstract Object getInstance(B bean, C context) throws InvocationTargetException;
/**
* Close the manager. The implementation should care bout shutting down the existing bean in particular the
* singleton beans that are managed outside of an explicit scope.
*/
public abstract void close();
private static class BeanLifeCycleImpl implements BeanLifeCycle {
final Class type;
final InjectionContext manager;
final B a;
private C context;
private I instance;
private BeanLifeCycleImpl(Class type, InjectionContext manager, B a) {
this.type = type;
this.manager = manager;
this.a = a;
}
public I get() throws InvocationTargetException {
if (instance == null) {
context = manager.createContext(a);
instance = type.cast(manager.getInstance(a, context));
}
return instance;
}
public I peek() {
return instance;
}
public void close() {
if (context != null) {
manager.releaseContext(a, context);
}
}
}
public final BeanLifeCycle get(Class type) {
final B a = resolveBean(type);
if (a == null) {
return null;
} else {
return new BeanLifeCycleImpl(type, this, a);
}
}
public final Iterable> resolve(final Class type) {
final Iterable a = resolveBeans(type);
return new Iterable>() {
public Iterator> iterator() {
return new Iterator>() {
final Iterator i = a.iterator();
public boolean hasNext() {
return i.hasNext();
}
public BeanLifeCycle next() {
B b = i.next();
return new BeanLifeCycleImpl(type, InjectionContext.this, b);
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
public final T resolveInstance(Class beanType) {
try {
BeanLifeCycle pluginLifeCycle = get(beanType);
return pluginLifeCycle != null ? pluginLifeCycle.get() : null;
}
catch (InvocationTargetException e) {
// log.log("Could not retrieve bean of type " + beanType, e.getCause());
return null;
}
}
public final Iterable resolveInstances(final Class beanType) {
return new Iterable() {
Iterable> lifecycles = resolve(beanType);
public Iterator iterator() {
return new Iterator() {
Iterator> iterator = lifecycles.iterator();
T next = null;
public boolean hasNext() {
while (next == null && iterator.hasNext()) {
try {
BeanLifeCycle pluginLifeCycle = iterator.next();
next = pluginLifeCycle.get();
}
catch (InvocationTargetException e) {
// log.log("Could not retrieve bean of type " + beanType.getName(), e);
}
}
return next != null;
}
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
} else {
T tmp = next;
next = null;
return tmp;
}
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
}