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

org.jboss.weld.injection.MethodInvocationStrategy Maven / Gradle / Ivy

There is a newer version: 3.0.0.Alpha1
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, 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.injection;

import java.util.List;

import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.event.ObserverException;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.EventMetadata;

import org.jboss.weld.bean.builtin.BeanManagerProxy;
import org.jboss.weld.event.CurrentEventMetadata;
import org.jboss.weld.manager.BeanManagerImpl;

/**
 * Encapsulates various strategies for invoking a method injection point. The default implementation supports all the possible scenarios including dependency
 * injection to parameters. In addition, there are optimized implementations for commonly used scenarios such as:
 * 
    *
  • an observer method with event parameter only
  • *
  • an observer method with event parameter and a {@link BeanManager} injection point (common in extensions)
  • *
  • an observer method with event parameter and an {@link EventMetadata} injection point
  • *
* * @author Jozef Hartinger * @author Martin Kouba */ public abstract class MethodInvocationStrategy { private static final MethodInvocationStrategy DISPOSER_DEFAULT_STRATEGY = new DefaultMethodInvocationStrategy(IllegalArgumentException.class); private static final MethodInvocationStrategy DISPOSER_SIMPLE_STRATEGY = new SimpleMethodInvocationStrategy(IllegalArgumentException.class); private static final MethodInvocationStrategy OBSERVER_DEFAULT_STRATEGY = new DefaultMethodInvocationStrategy(ObserverException.class); private static final MethodInvocationStrategy OBSERVER_SIMPLE_STRATEGY = new SimpleMethodInvocationStrategy(ObserverException.class); private static final MethodInvocationStrategy OBSERVER_EVENT_PLUS_BEAN_MANAGER_STRATEGY = new SpecialParamPlusBeanManagerStrategy(ObserverException.class); protected final Class exceptionTypeToThrow; MethodInvocationStrategy(Class exceptionTypeToThrow) { this.exceptionTypeToThrow = exceptionTypeToThrow; } MethodInvocationStrategy() { this.exceptionTypeToThrow = null; } public static MethodInvocationStrategy forDisposer(MethodInjectionPoint method, BeanManagerImpl manager) { List> parameters = method.getParameterInjectionPoints(); if (parameters.size() == 1 && parameters.get(0).getAnnotated().isAnnotationPresent(Observes.class)) { return DISPOSER_SIMPLE_STRATEGY; } else { return DISPOSER_DEFAULT_STRATEGY; } } public static MethodInvocationStrategy forObserver(MethodInjectionPoint method, BeanManagerImpl manager) { List> parameters = method.getParameterInjectionPoints(); if (parameters.size() == 1 && parameters.get(0).getAnnotated().isAnnotationPresent(Observes.class)) { return OBSERVER_SIMPLE_STRATEGY; } else if (parameters.size() == 2) { if (parameters.get(0).getAnnotated().isAnnotationPresent(Observes.class)) { if (BeanManager.class.equals(parameters.get(1).getType())) { return OBSERVER_EVENT_PLUS_BEAN_MANAGER_STRATEGY; } else if (EventMetadata.class.equals(parameters.get(1).getType())) { return new EventPlusMetadataStrategy(manager); } } } return OBSERVER_DEFAULT_STRATEGY; } public abstract void invoke(Object receiver, MethodInjectionPoint method, T instance, BeanManagerImpl manager, CreationalContext creationalContext); /** * The default general-purpose invocation strategy. */ private static class DefaultMethodInvocationStrategy extends MethodInvocationStrategy { public DefaultMethodInvocationStrategy(Class exceptionTypeToThrow) { super(exceptionTypeToThrow); } @Override public void invoke(Object receiver, MethodInjectionPoint method, T instance, BeanManagerImpl manager, CreationalContext creationalContext) { boolean release = creationalContext == null; if (release) { creationalContext = manager.createCreationalContext(null); } try { method.invoke(receiver, instance, manager, creationalContext, exceptionTypeToThrow); } finally { if (release) { creationalContext.release(); } } } } /** * Optimized invocation strategy that only supports methods with a single special parameter (e.g. the event parameter). */ private static class SimpleMethodInvocationStrategy extends MethodInvocationStrategy { public SimpleMethodInvocationStrategy(Class exceptionTypeToThrow) { super(exceptionTypeToThrow); } @Override public void invoke(Object receiver, MethodInjectionPoint method, T instance, BeanManagerImpl manager, CreationalContext creationalContext) { method.invoke(receiver, instance, manager, creationalContext, exceptionTypeToThrow); } } /** * Optimized invocation strategy that supports methods with exactly two parameters: special parameter plus {@link BeanManager} injection point. */ private static class SpecialParamPlusBeanManagerStrategy extends MethodInvocationStrategy { public SpecialParamPlusBeanManagerStrategy(Class exceptionTypeToThrow) { super(exceptionTypeToThrow); } @Override public void invoke(Object receiver, MethodInjectionPoint method, T instance, BeanManagerImpl manager, CreationalContext creationalContext) { method.invoke(receiver, new Object[] { instance, new BeanManagerProxy(manager) }, exceptionTypeToThrow); } } /** * Optimized invocation strategy that supports observer methods with exactly two parameters: event parameter plus {@link EventMetadata} injection point. */ private static class EventPlusMetadataStrategy extends MethodInvocationStrategy { private final CurrentEventMetadata metadata; private EventPlusMetadataStrategy(BeanManagerImpl manager) { this.metadata = manager.getServices().get(CurrentEventMetadata.class); } @Override public void invoke(Object receiver, MethodInjectionPoint method, T instance, BeanManagerImpl manager, CreationalContext creationalContext) { method.invoke(receiver, new Object[] { instance, metadata.peek() }, ObserverException.class); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy