Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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 extends RuntimeException> exceptionTypeToThrow;
MethodInvocationStrategy(Class extends RuntimeException> exceptionTypeToThrow) {
this.exceptionTypeToThrow = exceptionTypeToThrow;
}
MethodInvocationStrategy() {
this.exceptionTypeToThrow = null;
}
public static MethodInvocationStrategy forDisposer(MethodInjectionPoint, ?> method, BeanManagerImpl manager) {
List extends ParameterInjectionPoint, ?>> 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 extends ParameterInjectionPoint, ?>> 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 extends RuntimeException> 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 extends RuntimeException> 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 extends RuntimeException> 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);
}
}
}