com.caucho.config.event.ObserverMethodImpl Maven / Gradle / Ivy
/*
* Copyright (c) 1998-2018 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.config.event;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Set;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.spi.Context;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.event.ObserverException;
import javax.enterprise.event.Observes;
import javax.enterprise.event.Reception;
import javax.enterprise.event.TransactionPhase;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedParameter;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.InjectionPoint;
import com.caucho.config.ConfigException;
import com.caucho.config.bytecode.ScopeProxy;
import com.caucho.config.inject.CreationalContextImpl;
import com.caucho.config.inject.InjectManager;
import com.caucho.config.inject.InjectionPointImpl;
import com.caucho.config.inject.OwnerCreationalContext;
import com.caucho.config.program.BeanArg;
import com.caucho.util.L10N;
/**
* Internal implementation for a producer Bean
*/
public class ObserverMethodImpl extends AbstractObserverMethod {
private static final L10N L = new L10N(ObserverMethodImpl.class);
private InjectManager _cdiManager;
private Bean _bean;
private AnnotatedMethod _method;
private Type _type;
private Set _qualifiers;
private BeanArg []_args;
private boolean _isIfExists;
private boolean _isStatic;
private TransactionPhase _transactionPhase = TransactionPhase.IN_PROGRESS;
public ObserverMethodImpl(InjectManager beanManager,
Bean bean,
AnnotatedMethod method,
Type type,
Set qualifiers)
{
_cdiManager = beanManager;
_bean = bean;
_method = method;
_method.getJavaMember().setAccessible(true);
_isStatic = _method.isStatic();
_type = type;
_qualifiers = qualifiers;
introspect();
}
/**
* Returns the annotated method
*/
public AnnotatedMethod getAnnotatedMethod()
{
return _method;
}
/**
* Returns the declaring bean
*/
public Bean getParentBean()
{
return _bean;
}
@Override
public Class getBeanClass()
{
return (Class) _bean.getBeanClass();
}
/**
* Returns the observed event type
*/
@Override
public Type getObservedType()
{
return _type;
}
/**
* Returns the observed event bindings
*/
@Override
public Set getObservedQualifiers()
{
return _qualifiers;
}
private void introspect()
{
List> parameters = _method.getParameters();
/*
if (parameters.size() == 1) {
if (parameters.get(0).isAnnotationPresent(IfExists.class)) {
_isIfExists = true;
}
return;
}
*/
Method javaMethod = _method.getJavaMember();
_args = new BeanArg[parameters.size()];
for (int i = 0; i < _args.length; i++) {
AnnotatedParameter> param = parameters.get(i);
Observes observes = param.getAnnotation(Observes.class);
if (observes != null) {
_isIfExists = observes.notifyObserver() == Reception.IF_EXISTS;
_transactionPhase = observes.during();
}
else {
InjectionPoint ip = new InjectionPointImpl(_cdiManager,
_bean,
param);
_args[i] = new BeanArg(_cdiManager,
param.getBaseType(),
_cdiManager.getQualifiers(param.getAnnotations()),
ip);
}
if (param.isAnnotationPresent(Disposes.class)) {
throw new ConfigException(L.l("{0}.{1} may not have @Observes and @Disposes on the same method",
javaMethod.getDeclaringClass().getName(),
javaMethod.getName()));
}
}
if (_isIfExists && _bean.getScope() == Dependent.class) {
throw new ConfigException(L.l("{0}.{1} @Observer cannot use IF_EXISTS because the bean has Dependent scope",
javaMethod.getDeclaringClass().getName(),
javaMethod.getName()));
}
}
/**
* Send the event notification.
*/
@Override
public void notify(T event)
{
notifyImpl(event);
}
protected void notifyImpl(T event)
{
X instance;
CreationalContextImpl env = null;
OwnerCreationalContext argEnv = null;
if (_isIfExists) {
instance = getExistsInstance();
if (instance == null)
return;
}
else if (_isStatic) {
instance = null;
}
else {
if (_bean.getScope() == Dependent.class) {
env = new OwnerCreationalContext(getParentBean());
instance = getParentBean().create(env);
}
else {
instance = _cdiManager.getReference(getParentBean());
}
}
if (_args != null && _args.length > 1)
argEnv = new OwnerCreationalContext(null);
Method method = _method.getJavaMember();
try {
Object object;
if (instance instanceof ScopeProxy) {
object = ((ScopeProxy) instance).__caucho_getDelegate();
}
else
object = instance;
method.invoke(object, getEventArguments(event, argEnv));
} catch (IllegalArgumentException e) {
String loc = (method.getDeclaringClass().getSimpleName() + "."
+ method.getName() + ": ");
throw new ObserverException(loc + e.toString(), e.getCause());
} catch (RuntimeException e) {
throw e;
} catch (InvocationTargetException e) {
Throwable exn = e.getCause();
if (exn instanceof RuntimeException)
throw (RuntimeException) exn;
String loc = (method.getDeclaringClass().getSimpleName() + "."
+ method.getName() + ": ");
throw new ObserverException(loc + exn.toString(), exn.getCause());
} catch (Exception e) {
String loc = (method.getDeclaringClass().getSimpleName() + "."
+ method.getName() + ": ");
throw new ObserverException(loc + e.toString(), e.getCause());
} finally {
if (argEnv != null)
argEnv.release();
if (env != null)
getParentBean().destroy(instance, env);
}
}
protected X getExistsInstance()
{
Bean bean = getParentBean();
Class extends Annotation>scopeType = bean.getScope();
Context context = _cdiManager.getContext(scopeType);
if (context != null)
return (X) context.get(bean);
else
return null;
}
protected Object[] getEventArguments(Object event,
CreationalContextImpl> parentEnv)
{
if (_args == null)
return new Object[] { event };
Object []args = new Object[_args.length];
for (int i = 0; i < _args.length; i++) {
BeanArg arg = _args[i];
if (arg != null)
args[i] = arg.eval((CreationalContextImpl) parentEnv);
else
args[i] = event;
}
return args;
}
@Override
public Reception getReception()
{
if (_isIfExists)
return Reception.IF_EXISTS;
else
return Reception.ALWAYS;
}
@Override
public TransactionPhase getTransactionPhase()
{
return _transactionPhase;
}
/*
public Set getInjectionPoints()
{
throw new UnsupportedOperationException(getClass().getName());
}
public AnnotatedParameter getEventParameter()
{
throw new UnsupportedOperationException(getClass().getName());
}
*/
@Override
public String toString()
{
return getClass().getSimpleName() + "[" + _method + "]";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy