org.glassfish.jersey.ext.cdi1x.internal.AbstractCdiBeanSupplier Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jersey-cdi1x Show documentation
Show all versions of jersey-cdi1x Show documentation
Jersey CDI 1.1 integration
/*
* Copyright (c) 2014, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package org.glassfish.jersey.ext.cdi1x.internal;
import java.lang.annotation.Annotation;
import java.util.Iterator;
import java.util.NoSuchElementException;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.InjectionTarget;
import javax.enterprise.inject.spi.InjectionTargetFactory;
import org.glassfish.jersey.internal.inject.DisposableSupplier;
import org.glassfish.jersey.internal.inject.InjectionManager;
/**
* Abstract supplier to provide CDI components obtained from CDI bean manager.
* The factory handles CDI managed components as well as non-contextual managed beans.
* To specify scope of provided CDI beans, an extension of this supplier
* should implement properly annotated {@link java.util.function.Supplier#get()} method that
* could just delegate to the existing {@link #_provide()} method.
*
* @author Jakub Podlesak (jakub.podlesak at oracle.com)
*/
public abstract class AbstractCdiBeanSupplier implements DisposableSupplier {
final Class clazz;
final InstanceManager referenceProvider;
final Annotation[] qualifiers;
/**
* Create new factory instance for given type and bean manager.
*
* @param rawType type of the components to provide.
* @param injectionManager actual injection manager instance.
* @param beanManager current bean manager to get references from.
* @param cdiManaged set to {@code true} if the component should be managed by CDI.
*/
public AbstractCdiBeanSupplier(final Class rawType,
final InjectionManager injectionManager,
final BeanManager beanManager,
final boolean cdiManaged) {
this.clazz = rawType;
this.qualifiers = CdiUtil.getQualifiers(clazz.getAnnotations());
this.referenceProvider = cdiManaged ? new InstanceManager() {
final Iterator> beans = beanManager.getBeans(clazz, qualifiers).iterator();
final Bean bean = beans.hasNext() ? beans.next() : null;
@Override
public T getInstance(final Class clazz) {
return (bean != null) ? CdiUtil.getBeanReference(clazz, bean, beanManager) : null;
}
@Override
public void preDestroy(final T instance) {
// do nothing
}
} : new InstanceManager() {
final AnnotatedType annotatedType = beanManager.createAnnotatedType(clazz);
final InjectionTargetFactory injectionTargetFactory = beanManager.getInjectionTargetFactory(annotatedType);
final InjectionTarget injectionTarget = injectionTargetFactory.createInjectionTarget(null);
@Override
public T getInstance(final Class clazz) {
final CreationalContext creationalContext = beanManager.createCreationalContext(null);
final T instance = injectionTarget.produce(creationalContext);
injectionTarget.inject(instance, creationalContext);
if (injectionManager != null) {
injectionManager.inject(instance, CdiComponentProvider.CDI_CLASS_ANALYZER);
}
injectionTarget.postConstruct(instance);
return instance;
}
@Override
public void preDestroy(final T instance) {
injectionTarget.preDestroy(instance);
}
};
}
@SuppressWarnings(value = "unchecked")
/* package */ T _provide() {
final T instance = referenceProvider.getInstance(clazz);
if (instance != null) {
return instance;
}
throw new NoSuchElementException(LocalizationMessages.CDI_LOOKUP_FAILED(clazz));
}
@Override
public void dispose(final T instance) {
referenceProvider.preDestroy(instance);
}
private interface InstanceManager {
/**
* Get me correctly instantiated and injected instance.
*
* @param clazz type of the component to instantiate.
* @return injected component instance.
*/
T getInstance(Class clazz);
/**
* Do whatever needs to be done before given instance is destroyed.
*
* @param instance to be destroyed.
*/
void preDestroy(T instance);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy