CDI3ExtendedInstance.java
package com.github.jonasrutishauser.jakarta.enterprise.inject.impl;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import com.github.jonasrutishauser.jakarta.enterprise.inject.ExtendedInstance;
import jakarta.enterprise.inject.Instance;
import jakarta.enterprise.inject.spi.Bean;
import jakarta.enterprise.inject.spi.BeanManager;
import jakarta.enterprise.util.TypeLiteral;
class CDI3ExtendedInstance<T> implements ExtendedInstance<T> {
private final BeanManager beanManager;
private final Instance<T> instance;
private final Type targetType;
private final Set<Annotation> qualifiers;
public CDI3ExtendedInstance(BeanManager beanManager, Instance<T> instance, Type targetType, Set<Annotation> qualifiers) {
this.beanManager = beanManager;
this.targetType = targetType;
this.instance = instance;
this.qualifiers = qualifiers;
}
public ExtendedInstance<T> select(Annotation... qualifiers) {
return new CDI3ExtendedInstance<>(beanManager, instance.select(qualifiers), targetType, addedQualifiers(qualifiers));
}
public <U extends T> ExtendedInstance<U> select(Class<U> subtype, Annotation... qualifiers) {
return new CDI3ExtendedInstance<>(beanManager, instance.select(subtype, qualifiers), subtype, addedQualifiers(qualifiers));
}
public <U extends T> ExtendedInstance<U> select(TypeLiteral<U> subtype, Annotation... qualifiers) {
return new CDI3ExtendedInstance<>(beanManager, instance.select(subtype, qualifiers), subtype.getType(), addedQualifiers(qualifiers));
}
@Override
public Instance<T> getInstance() {
return instance;
}
@Override
public Handle<T> getPseudoScopeClosingHandle() {
return new HandleImpl();
}
private Set<Annotation> addedQualifiers(Annotation... qualifiers) {
Set<Annotation> newQualifiers = new HashSet<>(this.qualifiers);
Collections.addAll(newQualifiers, qualifiers);
return newQualifiers;
}
private class HandleImpl implements Handle<T> {
private T bean;
public T get() {
if (bean == null) {
bean = instance.get();
}
return bean;
}
public Bean<T> getBean() {
return (Bean<T>) beanManager.resolve(beanManager.getBeans(targetType, qualifiers.toArray(Annotation[]::new)));
}
public void destroy() {
if (bean != null) {
instance.destroy(bean);
bean = null;
}
}
public void close() {
if (!beanManager.isNormalScope(getBean().getScope())) {
destroy();
}
}
}
}