All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.weld.environment.se.ContainerLifecycleObserver Maven / Gradle / Ivy

/*
 * JBoss, Home of Professional Open Source
 * Copyright 2016, Red Hat, Inc., and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * 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 org.jboss.weld.environment.se;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

import jakarta.enterprise.event.Reception;
import jakarta.enterprise.event.TransactionPhase;
import jakarta.enterprise.inject.spi.AfterBeanDiscovery;
import jakarta.enterprise.inject.spi.AfterDeploymentValidation;
import jakarta.enterprise.inject.spi.AfterTypeDiscovery;
import jakarta.enterprise.inject.spi.BeanManager;
import jakarta.enterprise.inject.spi.BeforeBeanDiscovery;
import jakarta.enterprise.inject.spi.BeforeShutdown;
import jakarta.enterprise.inject.spi.Extension;
import jakarta.enterprise.inject.spi.ObserverMethod;
import jakarta.enterprise.inject.spi.ProcessAnnotatedType;
import jakarta.enterprise.inject.spi.ProcessBean;
import jakarta.enterprise.inject.spi.ProcessBeanAttributes;
import jakarta.enterprise.inject.spi.ProcessInjectionPoint;
import jakarta.enterprise.inject.spi.ProcessInjectionTarget;
import jakarta.enterprise.inject.spi.ProcessManagedBean;
import jakarta.enterprise.inject.spi.ProcessObserverMethod;
import jakarta.enterprise.inject.spi.ProcessProducer;
import jakarta.enterprise.inject.spi.ProcessProducerField;
import jakarta.enterprise.inject.spi.ProcessProducerMethod;
import jakarta.enterprise.inject.spi.ProcessSessionBean;
import jakarta.enterprise.inject.spi.ProcessSyntheticAnnotatedType;
import jakarta.enterprise.inject.spi.ProcessSyntheticBean;
import jakarta.enterprise.inject.spi.ProcessSyntheticObserverMethod;
import jakarta.enterprise.inject.spi.WithAnnotations;
import jakarta.enterprise.util.TypeLiteral;

import org.jboss.weld.bootstrap.SyntheticExtension;
import org.jboss.weld.bootstrap.event.WeldAfterBeanDiscovery;
import org.jboss.weld.bootstrap.events.NotificationListener;
import org.jboss.weld.environment.se.logging.WeldSELogger;
import org.jboss.weld.event.ContainerLifecycleEventObserverMethod;
import org.jboss.weld.util.Observers;
import org.jboss.weld.util.Preconditions;
import org.jboss.weld.util.reflection.Reflections;

/**
 * Represents a synthetic container lifecycle event observer.
 * 

* For parameterized container lifecycele events (such as {@link ProcessAnnotatedType} and {@link ProcessProducerMethod}) it is possible to specify the observed * container lifecycle event type, e.g. by means of {@link TypeLiteral}. To receive notifications for all observer methods with observed event type of * {@link String}: * *

 * ContainerLifecycleObserver.processObserverMethod(new TypeLiteral<ProcessObserverMethod<String, ?>>() {
 * }.getType()).notify((e) -> System.out.println("String observer"));
 * 
* * @author Martin Kouba * @see Weld#addContainerLifecycleObserver(ContainerLifecycleObserver) */ public final class ContainerLifecycleObserver implements ContainerLifecycleEventObserverMethod { /** * * @return a new builder instance * @see BeforeBeanDiscovery */ public static Builder beforeBeanDiscovery() { return ContainerLifecycleObserver. of(BeforeBeanDiscovery.class); } /** * * @param callback * @return a new container lifecycle observer * @see BeforeBeanDiscovery */ public static ContainerLifecycleObserver beforeBeanDiscovery(Consumer callback) { return beforeBeanDiscovery().notify(callback); } /** * * @return a new builder instance * @see AfterBeanDiscovery */ public static Builder afterBeanDiscovery() { return ContainerLifecycleObserver. of(WeldAfterBeanDiscovery.class); } /** * * @param callback * @return a new container lifecycle observer * @see AfterBeanDiscovery */ public static ContainerLifecycleObserver afterBeanDiscovery(Consumer callback) { return afterBeanDiscovery().notify(callback); } /** * * @return a new builder instance * @see AfterTypeDiscovery */ public static Builder afterTypeDiscovery() { return ContainerLifecycleObserver. of(AfterTypeDiscovery.class); } /** * * @param callback * @return a new container lifecycle observer * @see AfterTypeDiscovery */ public static ContainerLifecycleObserver afterTypeDiscovery(Consumer callback) { return afterTypeDiscovery().notify(callback); } /** * * @param callback * @return a new builder instance * @see AfterDeploymentValidation */ public static Builder afterDeploymentValidation() { return ContainerLifecycleObserver. of(AfterDeploymentValidation.class); } /** * * @param callback * @return a new container lifecycle observer * @see AfterDeploymentValidation */ public static ContainerLifecycleObserver afterDeploymentValidation(Consumer callback) { return afterDeploymentValidation().notify(callback); } /** * * @param callback * @return a new builder instance * @see BeforeShutdown */ public static Builder beforeShutdown() { return ContainerLifecycleObserver. of(BeforeShutdown.class); } /** * * @param callback * @return a new container lifecycle observer * @see BeforeShutdown */ public static ContainerLifecycleObserver beforeShutdown(Consumer callback) { return beforeShutdown().notify(callback); } /** * * @return a new builder instance * @see ProcessAnnotatedType */ @SuppressWarnings("serial") public static Builder> processAnnotatedType() { return processAnnotatedType(new TypeLiteral>() { }.getType()); } /** * * @param observedType * @return a new builder instance * @see ProcessAnnotatedType */ public static Builder> processAnnotatedType(Type observedType) { checkRawType(observedType, ProcessAnnotatedType.class); return ContainerLifecycleObserver.> of(observedType); } /** * * @param observedType * @return a new builder instance * @see ProcessSyntheticAnnotatedType */ public static Builder> processSyntheticAnnotatedType(Type observedType) { checkRawType(observedType, ProcessSyntheticAnnotatedType.class); return ContainerLifecycleObserver.> of(observedType); } /** * * @return a new builder instance * @see ProcessInjectionPoint */ @SuppressWarnings("serial") public static Builder> processInjectionPoint() { return processInjectionPoint(new TypeLiteral>() { }.getType()); } /** * * @param observedType * @return a new builder instance * @see ProcessInjectionPoint */ public static Builder> processInjectionPoint(Type observedType) { checkRawType(observedType, ProcessInjectionPoint.class); return ContainerLifecycleObserver.> of(observedType); } /** * * @return a new builder instance * @see ProcessInjectionTarget * */ @SuppressWarnings("serial") public static Builder> processInjectionTarget() { return processInjectionTarget(new TypeLiteral>() { }.getType()); } /** * * @param observedType * @return a new builder instance * @see ProcessInjectionTarget */ public static Builder> processInjectionTarget(Type observedType) { checkRawType(observedType, ProcessInjectionTarget.class); return ContainerLifecycleObserver.> of(observedType); } /** * * @return a new builder instance * @see ProcessBeanAttributes */ @SuppressWarnings("serial") public static Builder> processBeanAttributes() { return processBeanAttributes(new TypeLiteral>() { }.getType()); } /** * * @param observedType * @return a new builder instance * @see ProcessBeanAttributes */ public static Builder> processBeanAttributes(Type observedType) { checkRawType(observedType, ProcessBeanAttributes.class); return ContainerLifecycleObserver.> of(observedType); } /** * * @return a new builder instance * @see ProcessBean */ @SuppressWarnings("serial") public static Builder> processBean() { return processBean(new TypeLiteral>() { }.getType()); } /** * * @param observedType * @return a new builder instance * @see ProcessBean */ public static Builder> processBean(Type observedType) { checkRawType(observedType, ProcessBean.class); return ContainerLifecycleObserver.> of(observedType); } /** * * @return a new builder instance * @see ProcessManagedBean */ @SuppressWarnings("serial") public static Builder> processManagedBean() { return processManagedBean(new TypeLiteral>() { }.getType()); } /** * * @param observedType * @return a new builder instance * @see ProcessManagedBean */ public static Builder> processManagedBean(Type observedType) { checkRawType(observedType, ProcessManagedBean.class); return ContainerLifecycleObserver.> of(observedType); } /** * * @return a new builder instance * @see ProcessSessionBean */ @SuppressWarnings("serial") public static Builder> processSessionBean() { return processSessionBean(new TypeLiteral>() { }.getType()); } /** * * @param observedType * @return a new builder instance * @see ProcessSessionBean */ public static Builder> processSessionBean(Type observedType) { checkRawType(observedType, ProcessSessionBean.class); return ContainerLifecycleObserver.> of(observedType); } /** * * @return a new builder instance * @see ProcessProducerMethod */ @SuppressWarnings("serial") public static Builder> processProducerMethod() { return processProducerMethod(new TypeLiteral>() { }.getType()); } /** * * @param observedType * @return a new builder instance * @see ProcessProducerMethod */ public static Builder> processProducerMethod(Type observedType) { checkRawType(observedType, ProcessProducerMethod.class); return ContainerLifecycleObserver.> of(observedType); } /** * * @return a new builder instance * @see ProcessProducerField */ @SuppressWarnings("serial") public static Builder> processProducerField() { return processProducerField(new TypeLiteral>() { }.getType()); } /** * * @param observedType * @return a new builder instance * @see ProcessProducerField */ public static Builder> processProducerField(Type observedType) { checkRawType(observedType, ProcessProducerField.class); return ContainerLifecycleObserver.> of(observedType); } /** * * @return a new builder instance * @see ProcessSyntheticBean */ @SuppressWarnings("serial") public static Builder> processSyntheticBean() { return processSyntheticBean(new TypeLiteral>() { }.getType()); } /** * * @param observedType * @return a new builder instance * @see ProcessManagedBean */ public static Builder> processSyntheticBean(Type observedType) { checkRawType(observedType, ProcessSyntheticBean.class); return ContainerLifecycleObserver.> of(observedType); } /** * * @return a new builder instance * @see ProcessProducer */ @SuppressWarnings("serial") public static Builder> processProducer() { return processProducer(new TypeLiteral>() { }.getType()); } /** * * @param observedType * @return a new builder instance * @see ProcessProducer */ public static Builder> processProducer(Type observedType) { checkRawType(observedType, ProcessProducer.class); return ContainerLifecycleObserver.> of(observedType); } /** * * @return a new builder instance * @see ProcessObserverMethod */ @SuppressWarnings("serial") public static Builder> processObserverMethod() { return processObserverMethod(new TypeLiteral>() { }.getType()); } /** * * @param observedType * @return a new builder instance * @see ProcessObserverMethod */ public static Builder> processObserverMethod(Type observedType) { checkRawType(observedType, ProcessObserverMethod.class); return ContainerLifecycleObserver.> of(observedType); } /** * * @return a new builder instance * @see ProcessSyntheticObserverMethod */ @SuppressWarnings("serial") public static Builder> processSyntheticObserverMethod() { return processSyntheticObserverMethod(new TypeLiteral>() { }.getType()); } /** * * @param observedType * @return a new builder instance * @see ProcessSyntheticObserverMethod */ public static Builder> processSyntheticObserverMethod(Type observedType) { checkRawType(observedType, ProcessSyntheticObserverMethod.class); return ContainerLifecycleObserver.> of(observedType); } // Instance members private final int priority; private final Type observedType; private final BiConsumer callbackWithBeanManager; private final Consumer callback; private final Collection> requiredAnnotations; private volatile BeanManager beanManager; private volatile SyntheticExtension extension; private ContainerLifecycleObserver(int priority, Type observedType, BiConsumer callbackWithBeanManager, Consumer callback, Collection> requiredAnnotations) { this.priority = priority; this.observedType = observedType; this.callbackWithBeanManager = callbackWithBeanManager; this.callback = callback; this.requiredAnnotations = requiredAnnotations; } @Override public int getPriority() { return priority; } @Override public Class getBeanClass() { return ContainerLifecycleObserver.class; } @Override public Type getObservedType() { return observedType; } @Override public Set getObservedQualifiers() { return Collections.emptySet(); } @Override public Reception getReception() { return Reception.ALWAYS; } @Override public TransactionPhase getTransactionPhase() { return TransactionPhase.IN_PROGRESS; } @Override public void notify(T event) { if (beanManager == null || extension == null) { throw WeldSELogger.LOG.containerLifecycleObserverNotInitialized(toString()); } if (event instanceof NotificationListener) { NotificationListener.class.cast(event).preNotify(extension); } try { if (callbackWithBeanManager != null) { callbackWithBeanManager.accept(event, beanManager); } else { callback.accept(event); } } finally { if (event instanceof NotificationListener) { NotificationListener.class.cast(event).postNotify(null); } } } @Override public Collection> getRequiredAnnotations() { return requiredAnnotations; } private void setBeanManager(BeanManager beanManager) { this.beanManager = beanManager; } private void setExtension(SyntheticExtension extension) { this.extension = extension; } @Override public String toString() { return String.format("ContainerLifecyleObserver [priority=%s, observedType=%s]", priority, observedType); } /** * A synthetic extension is basically a container for synthetic container lifecycle event observers. * * @return a builder for a synthetic extension * @see Weld#addExtension(jakarta.enterprise.inject.spi.Extension) */ public static ExtensionBuilder extensionBuilder() { return new ExtensionBuilder(); } private static Builder of(Type observedType) { if (!Observers.CONTAINER_LIFECYCLE_EVENT_TYPES.contains(Reflections.getRawType(observedType))) { throw WeldSELogger.LOG.observedTypeNotContonainerLifecycleEventType(observedType); } return new Builder<>(observedType); } private static void checkRawType(Type observedType, Class rawType) { if (!rawType.equals(Reflections.getRawType(observedType))) { throw WeldSELogger.LOG.observedTypeDoesNotMatchContonainerLifecycleEventType(observedType, rawType); } } /** * This builder is used to create a synthetic container lifecycle event observer. * * @author Martin Kouba * * @param */ public static class Builder { private static final String OBSERVED_TYPE = "observedType"; private static final String CALLBACK = "callback"; @SuppressWarnings("checkstyle:magicnumber") private static final int DEFAULT_PRIORITY = jakarta.interceptor.Interceptor.Priority.APPLICATION + 500; private int priority = DEFAULT_PRIORITY; private Type observedType; private Collection> requiredAnnotations = Collections.emptySet(); private Builder(Type observedType) { Preconditions.checkArgumentNotNull(observedType, OBSERVED_TYPE); this.observedType = observedType; } /** * Set the priority. * * @param priority * @return self */ public Builder priority(int priority) { this.priority = priority; return this; } /** * The annotations are only considered for {@link ProcessAnnotatedType}, i.e. they are ignored for other container lifecycle events. * * @param annotations * @return self * @see WithAnnotations */ @SafeVarargs public final Builder withAnnotations(Class... annotations) { this.requiredAnnotations = new HashSet<>(); Collections.addAll(requiredAnnotations, annotations); return this; } /** * Set a callback used during observer notification. The first callback parameter is an event object and the second parameter is a {@link BeanManager} * instance. *

* This is a terminal operation. * * @param callback * @return the built observer * @see ObserverMethod#notify(Object) */ public ContainerLifecycleObserver notify(BiConsumer callback) { Preconditions.checkArgumentNotNull(callback, CALLBACK); return new ContainerLifecycleObserver<>(priority, observedType, callback, null, requiredAnnotations); } /** * Set a callback used during observer notification. The callback parameter is an event object. *

* This is a terminal operation. * * @param callback * @return the built observer * @see ObserverMethod#notify(Object) */ public ContainerLifecycleObserver notify(Consumer callback) { Preconditions.checkArgumentNotNull(callback, CALLBACK); return new ContainerLifecycleObserver<>(priority, observedType, null, callback, requiredAnnotations); } } static class ContainerLifecycleObserverExtension implements SyntheticExtension { private final List> observers; ContainerLifecycleObserverExtension(List> observers) { this.observers = new ArrayList<>(observers); } public void initialize(BeanManager beanManager) { for (ContainerLifecycleObserver observer : observers) { observer.setBeanManager(beanManager); observer.setExtension(this); } } @Override public Collection> getObservers() { return Reflections.cast(observers); } } /** * This builder is used to create a synthetic extension, i.e. a collection of synthetic container lifecycle observers. * * @author Martin Kouba */ public static class ExtensionBuilder { private final List> observers; private ExtensionBuilder() { this.observers = new LinkedList<>(); } /** * * @param observer * @return self */ public ExtensionBuilder add(ContainerLifecycleObserver observer) { observers.add(observer); return this; } public Extension build() { return new ContainerLifecycleObserverExtension(observers); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy