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

org.jboss.weld.event.ExtensionObserverMethodImpl Maven / Gradle / Ivy

Go to download

This jar bundles all the bits of Weld and CDI required for running in a Servlet container.

There is a newer version: 6.0.0.Beta4
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2010, 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.event;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;

import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ObserverMethod;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import javax.enterprise.inject.spi.ProcessSyntheticAnnotatedType;
import javax.enterprise.inject.spi.WithAnnotations;

import org.jboss.weld.Container;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedMethod;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedParameter;
import org.jboss.weld.bean.RIBean;
import org.jboss.weld.bean.builtin.ExtensionBean;
import org.jboss.weld.bootstrap.events.NotificationListener;
import org.jboss.weld.injection.InjectionPointFactory;
import org.jboss.weld.injection.MethodInjectionPoint;
import org.jboss.weld.injection.MethodInjectionPoint.MethodInjectionPointType;
import org.jboss.weld.logging.EventLogger;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.util.collections.ImmutableSet;
import org.jboss.weld.util.reflection.Formats;
import org.jboss.weld.util.reflection.Reflections;

/**
 * An implementation of {@link ObserverMethod} used for events delivered to extensions.
 * The observer method does not require contexts to be active.
 *
 * @author Jozef Hartinger
 *
 */
public class ExtensionObserverMethodImpl extends ObserverMethodImpl implements ContainerLifecycleEventObserverMethod {

    private final Container containerLifecycleEventDeliveryLock;
    private final Set> requiredTypeAnnotations;
    private volatile Set> requiredScopeTypeAnnotations;

    protected ExtensionObserverMethodImpl(EnhancedAnnotatedMethod observer, RIBean declaringBean, BeanManagerImpl manager, boolean isAsync) {
        super(observer, declaringBean, manager, isAsync);
        this.containerLifecycleEventDeliveryLock = Container.instance(manager);
        this.requiredTypeAnnotations = initRequiredTypeAnnotations(observer);
    }

    protected Set> initRequiredTypeAnnotations(EnhancedAnnotatedMethod observer) {
        EnhancedAnnotatedParameter eventParameter = getEventParameter(observer);
        WithAnnotations annotation = eventParameter.getAnnotation(WithAnnotations.class);
        if (annotation != null) {
            return ImmutableSet.>of(annotation.value());
        }
        return Collections.emptySet();
    }

    @Override
    protected void checkRequiredTypeAnnotations(EnhancedAnnotatedParameter eventParameter) {
        Class rawObserverType = Reflections.getRawType(getObservedType());
        boolean isProcessAnnotatedType = rawObserverType.equals(ProcessAnnotatedType.class) || rawObserverType.equals(ProcessSyntheticAnnotatedType.class);
        if (!isProcessAnnotatedType && !requiredTypeAnnotations.isEmpty()) {
            throw EventLogger.LOG
                    .invalidWithAnnotations(this, Formats.formatAsStackTraceElement(eventParameter.getDeclaringEnhancedCallable().getJavaMember()));
        }
        if (isProcessAnnotatedType && requiredTypeAnnotations.isEmpty()) {
            Type[] typeArguments = eventParameter.getActualTypeArguments();
            if (typeArguments.length == 0 || Reflections.isUnboundedWildcard(typeArguments[0]) || Reflections.isUnboundedTypeVariable(typeArguments[0])) {
                EventLogger.LOG.unrestrictedProcessAnnotatedTypes(this);
            }
        }
    }

    @Override
    protected MethodInjectionPoint initMethodInjectionPoint(EnhancedAnnotatedMethod observer, RIBean declaringBean, BeanManagerImpl manager) {
        // use silent creation of injection points for ProcessInjectionPoint events not to be fired for extension observer methods
        return InjectionPointFactory.silentInstance().createMethodInjectionPoint(MethodInjectionPointType.OBSERVER, observer, declaringBean, declaringBean.getBeanClass(), SPECIAL_PARAM_MARKERS, manager);
    }

    @Override
    protected void preNotify(T event, Object receiver) {
        if (event instanceof NotificationListener) {
            NotificationListener.class.cast(event).preNotify((Extension) receiver);
        }
    }

    @Override
    protected void postNotify(T event, Object receiver) {
        if (event instanceof NotificationListener) {
            NotificationListener.class.cast(event).postNotify((Extension) receiver);
        }
    }

    /*
     * Contexts may not be active during notification of container lifecycle events. Therefore, we invoke the methods directly on
     * an extension instance.
     */
    @Override
    protected Object getReceiver(CreationalContext ctx) {
        return getDeclaringBean().create(null);
    }

    @Override
    protected void sendEvent(T event, Object receiver, CreationalContext creationalContext) {
        synchronized (containerLifecycleEventDeliveryLock) {
            super.sendEvent(event, receiver, creationalContext);
        }
    }

    protected String createTypeId(RIBean declaringBean) {
        if (declaringBean instanceof ExtensionBean) {
            ExtensionBean extensionBean = (ExtensionBean) declaringBean;
            return extensionBean.getAnnotatedType().getIdentifier().asString();
        }
        return super.createTypeId(declaringBean);
    }

    public Collection> getRequiredAnnotations() {
        return requiredTypeAnnotations;
    }

    public Collection> getRequiredScopeAnnotations() {
        if (requiredScopeTypeAnnotations == null) {
            // this init may be performed more than once - which is OK
            ImmutableSet.Builder> builder = ImmutableSet.builder();
            for (Class annotation : requiredTypeAnnotations) {
                if (beanManager.isScope(annotation)) {
                    builder.add(annotation);
                }
            }
            this.requiredScopeTypeAnnotations = builder.build();
        }
        return requiredScopeTypeAnnotations;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (this == obj) {
            return true;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        ExtensionObserverMethodImpl that = (ExtensionObserverMethodImpl) obj;
        return super.equals(that);
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy