| /* |
| * Copyright (c) 2021 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.inject.weld.internal.bean; |
| |
| import java.lang.annotation.Annotation; |
| import java.lang.reflect.Type; |
| import java.util.HashSet; |
| import java.util.Set; |
| import java.util.function.Supplier; |
| |
| import javax.enterprise.context.Dependent; |
| import javax.enterprise.context.spi.CreationalContext; |
| import javax.enterprise.inject.spi.InjectionTarget; |
| import javax.ws.rs.RuntimeType; |
| |
| import org.glassfish.jersey.inject.weld.internal.injector.JerseyInjectionTarget; |
| import org.glassfish.jersey.inject.weld.internal.type.ParameterizedTypeImpl; |
| import org.glassfish.jersey.internal.inject.DisposableSupplier; |
| import org.glassfish.jersey.internal.inject.SupplierClassBinding; |
| |
| /** |
| * Creates an implementation of {@link javax.enterprise.inject.spi.Bean} interface using Jersey's {@link SupplierClassBinding}. |
| * Binding provides the information about the bean also called {@link javax.enterprise.inject.spi.BeanAttributes} information and |
| * {@link JerseyInjectionTarget} provides the contextual part of the bean because implements |
| * {@link javax.enterprise.context.spi.Contextual} with Jersey injection extension (is able to inject into JAX-RS/Jersey specified |
| * annotation). |
| * <p> |
| * Bean's implementation provides possibility to register {@link Supplier} and {@link DisposableSupplier}. |
| * <p> |
| * Inject example: |
| * <pre> |
| * AbstractBinder { |
| * @Override |
| * protected void configure() { |
| * bindFactory(MyBeanSupplier.class) |
| * .to(MyBean.class) |
| * .in(Singleton.class); |
| * } |
| * } |
| * </pre> |
| * Register example: |
| * <pre> |
| * @Path("/") |
| * public class MyResource { |
| * @Inject |
| * private Supplier<MyBean> myBean; |
| * } |
| * </pre> |
| * |
| * @author Petr Bouda |
| */ |
| class SupplierClassBean<T> extends JerseyBean<Supplier<T>> { |
| |
| private final Set<Type> contracts = new HashSet<>(); |
| private final Class<? extends Supplier<T>> supplierClass; |
| private final Class<? extends Annotation> supplierScope; |
| private InjectionTarget<Supplier<T>> injectionTarget; |
| |
| /** |
| * Creates a new Jersey-specific {@link javax.enterprise.inject.spi.Bean} instance. |
| * |
| * @param binding {@link javax.enterprise.inject.spi.BeanAttributes} part of the bean. |
| */ |
| SupplierClassBean(RuntimeType runtimeType, SupplierClassBinding<T> binding) { |
| super(runtimeType, binding); |
| this.supplierClass = binding.getSupplierClass(); |
| this.supplierScope = binding.getSupplierScope(); |
| |
| for (Type contract : binding.getContracts()) { |
| this.contracts.add(new ParameterizedTypeImpl(Supplier.class, contract)); |
| if (DisposableSupplier.class.isAssignableFrom(supplierClass)) { |
| this.contracts.add(new ParameterizedTypeImpl(DisposableSupplier.class, contract)); |
| } |
| } |
| } |
| |
| @Override |
| public Class<? extends Annotation> getScope() { |
| return supplierScope == null ? Dependent.class : transformScope(supplierScope); |
| } |
| |
| @Override |
| public Set<Type> getTypes() { |
| return contracts; |
| } |
| |
| @Override |
| public Supplier<T> create(CreationalContext<Supplier<T>> context) { |
| Supplier<T> instance = injectionTarget.produce(context); |
| injectionTarget.inject(instance, context); |
| injectionTarget.postConstruct(instance); |
| return instance; |
| } |
| |
| @Override |
| public void destroy(Supplier<T> instance, CreationalContext<Supplier<T>> context) { |
| injectionTarget.preDestroy(instance); |
| injectionTarget.dispose(instance); |
| context.release(); |
| } |
| |
| @Override |
| public Class<?> getBeanClass() { |
| return supplierClass; |
| } |
| |
| /** |
| * Lazy set of an injection target because to create fully functional injection target needs already created bean. |
| * |
| * @param injectionTarget {@link javax.enterprise.context.spi.Contextual} information belonging to this bean. |
| */ |
| void setInjectionTarget(InjectionTarget<Supplier<T>> injectionTarget) { |
| this.injectionTarget = injectionTarget; |
| } |
| |
| public InjectionTarget<Supplier<T>> getInjectionTarget() { |
| return injectionTarget; |
| } |
| } |