com.caucho.ejb.cfg.EjbConfig 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.ejb.cfg;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.sql.DataSourceDefinition;
import javax.annotation.sql.DataSourceDefinitions;
import javax.ejb.ApplicationException;
import javax.ejb.EJBs;
import javax.ejb.MessageDriven;
import javax.ejb.Singleton;
import javax.ejb.Stateful;
import javax.ejb.Stateless;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.InjectionTarget;
import com.caucho.config.ConfigException;
import com.caucho.config.gen.ApplicationExceptionConfig;
import com.caucho.config.inject.InjectManager;
import com.caucho.config.types.FileSetType;
import com.caucho.ejb.manager.EjbManager;
import com.caucho.ejb.server.AbstractEjbBeanManager;
import com.caucho.ejb.util.AppExceptionItem;
import com.caucho.java.gen.JavaClassGenerator;
import com.caucho.jms.JmsMessageListener;
import com.caucho.util.L10N;
import com.caucho.vfs.Path;
/**
* Manages the EJB configuration files.
*/
public class EjbConfig {
private static final L10N L = new L10N(EjbConfig.class);
protected final EjbManager _ejbManager;
private ArrayList _fileSetList = new ArrayList();
private HashMap> _cfgBeans
= new HashMap>();
private HashSet> _beanSet = new HashSet>();
private ArrayList> _pendingBeans = new ArrayList>();
private ArrayList> _deployingBeans = new ArrayList>();
private ArrayList _proxyList
= new ArrayList();
private ArrayList _functions
= new ArrayList();
private HashMap _messageDestinations;
private ArrayList _cfgInterceptors
= new ArrayList();
private ArrayList _cfgInterceptorBindings
= new ArrayList();
private HashMap,ApplicationExceptionConfig> _appExceptionConfig
= new HashMap,ApplicationExceptionConfig>();
private Map,AppExceptionItem> _appExceptionMap
= new ConcurrentHashMap,AppExceptionItem>();
private ArrayList> _bindTypes
= new ArrayList>();
public EjbConfig(EjbManager ejbContainer)
{
_ejbManager = ejbContainer;
}
/**
* Adds a path for an EJB config file to the config list.
*/
public void addEjbPath(Path path)
throws ConfigException
{
throw new UnsupportedOperationException();
}
public void addConfigProxy(EjbBeanConfigProxy proxy)
{
_proxyList.add(proxy);
_beanSet.add(proxy.getEjbClass());
}
/**
* Returns the schema name.
*/
public String getSchema()
{
return "com/caucho/ejb/cfg/resin-ejb.rnc";
}
/**
* Returns the EJB manager.
*/
public EjbManager getEjbContainer()
{
return _ejbManager;
}
/**
* Returns the cfg bean with the given name.
*/
public EjbBean> getBeanConfig(String name)
{
assert name != null;
return _cfgBeans.get(name);
}
/**
* Sets the cfg bean with the given name.
*/
public void setBeanConfig(String name, EjbBean> bean)
{
if (name == null || bean == null)
throw new NullPointerException();
EjbBean> oldBean = _cfgBeans.get(name);
if (oldBean == bean)
return;
else if (oldBean != null) {
throw new IllegalStateException(L.l("{0}: duplicate bean '{1}' old ejb-class={2} new ejb-class={3}",
this, name,
oldBean, // .getEJBClass().getName()));
bean)); // .getEJBClass().getName()));
}
_pendingBeans.add(bean);
_cfgBeans.put(name, bean);
_beanSet.add(bean.getEJBClass());
}
/**
* Returns the interceptor with the given class name.
*/
public Interceptor getInterceptor(String className)
{
assert className != null;
for (Interceptor interceptor : _cfgInterceptors) {
if (interceptor.getInterceptorClass().equals(className))
return interceptor;
}
return null;
}
/**
* Adds an interceptor.
*/
public void addInterceptor(Interceptor interceptor)
{
if (interceptor == null)
throw new NullPointerException();
_cfgInterceptors.add(interceptor);
}
/**
* Returns the interceptor bindings for a given ejb name.
*/
public ArrayList
getInterceptorBinding(String ejbName,
boolean isExcludeDefault)
{
assert ejbName != null;
ArrayList bindings
= new ArrayList();
for (InterceptorBinding binding : _cfgInterceptorBindings) {
if (binding.getEjbName().equals(ejbName))
bindings.add(binding);
else if (binding.getEjbName().equals("*") && ! isExcludeDefault) {
bindings.add(binding);
}
}
return bindings;
}
/**
* Adds an application exception.
*/
public void addApplicationException(ApplicationExceptionConfig applicationException)
{
Class> appExnClass = applicationException.getExceptionClass();
_appExceptionConfig.put(appExnClass, applicationException);
}
/**
* Returns the application exceptions.
*/
public AppExceptionItem getApplicationException(Class> exn,
boolean isSystem)
{
AppExceptionItem appExn = _appExceptionMap.get(exn);
if (appExn == null) {
appExn = createApplicationException(exn, isSystem);
_appExceptionMap.put(exn, appExn);
}
return appExn;
}
private AppExceptionItem createApplicationException(Class> exn,
boolean isSystem)
{
if (exn == Error.class || exn == RuntimeException.class)
return new AppExceptionItem(false, true, true);
else if (exn == Exception.class)
return new AppExceptionItem(true, false, true);
ApplicationExceptionConfig cfg = _appExceptionConfig.get(exn);
if (cfg != null) {
return new AppExceptionItem(true, cfg.isRollback(), cfg.isInherited());
}
ApplicationException appExn = exn.getAnnotation(ApplicationException.class);
if (appExn != null) {
// ejb/1276
return new AppExceptionItem(true, appExn.rollback(), appExn.inherited());
}
AppExceptionItem parentItem = getApplicationException(exn.getSuperclass(),
isSystem);
if (parentItem.isInherited())
return parentItem;
else if (isSystem)
return new AppExceptionItem(false, true, true);
else
return new AppExceptionItem(true, false, true);
}
/**
* Binds an interceptor to an ejb.
*/
public void addInterceptorBinding(InterceptorBinding interceptorBinding)
{
_cfgInterceptorBindings.add(interceptorBinding);
}
/**
* Adds the message destination mapping
*/
public void addMessageDestination(MessageDestination messageDestination)
{
if (_messageDestinations == null)
_messageDestinations = new HashMap();
String name = messageDestination.getMessageDestinationName();
_messageDestinations.put(name, messageDestination);
}
public MessageDestination getMessageDestination(String name)
{
if (_messageDestinations == null)
return null;
return _messageDestinations.get(name);
}
public boolean isConfiguredBean(Class> beanType)
{
return _beanSet.contains(beanType);
}
public void addAnnotatedType(AnnotatedType rawAnnType,
AnnotatedType annType,
InjectionTarget injectTarget,
String moduleName)
{
try {
Class> type = annType.getJavaClass();
if (findBeanByType(type) != null)
return;
if (annType.isAnnotationPresent(Stateless.class)) {
EjbStatelessBean bean
= new EjbStatelessBean(this, rawAnnType, annType, moduleName);
bean.setInjectionTarget(injectTarget);
Stateless stateless = annType.getAnnotation(Stateless.class);
if (! "".equals(stateless.name()) && stateless.name() != null)
bean.setEJBName(stateless.name());
setBeanConfig(bean.getEJBName(), bean);
}
else if (annType.isAnnotationPresent(Stateful.class)) {
EjbStatefulBean bean
= new EjbStatefulBean(this, rawAnnType, annType, moduleName);
bean.setInjectionTarget(injectTarget);
Stateful stateful = annType.getAnnotation(Stateful.class);
if (! "".equals(stateful.name()) && stateful.name() != null)
bean.setEJBName(stateful.name());
setBeanConfig(bean.getEJBName(), bean);
}
else if (annType.isAnnotationPresent(Singleton.class)) {
EjbSingletonBean bean
= new EjbSingletonBean(this, rawAnnType, annType, moduleName);
bean.setInjectionTarget(injectTarget);
Singleton singleton = annType.getAnnotation(Singleton.class);
if (! "".equals(singleton.name()) && singleton.name() != null)
bean.setEJBName(singleton.name());
setBeanConfig(bean.getEJBName(), bean);
}
else if (annType.isAnnotationPresent(MessageDriven.class)) {
EjbMessageBean bean
= new EjbMessageBean(this, rawAnnType, annType, moduleName);
bean.setInjectionTarget(injectTarget);
setBeanConfig(bean.getEJBName(), bean);
}
else if (annType.isAnnotationPresent(JmsMessageListener.class)) {
JmsMessageListener listener
= annType.getAnnotation(JmsMessageListener.class);
EjbMessageBean bean
= new EjbMessageBean(this, rawAnnType, annType, listener.destination());
bean.setInjectionTarget(injectTarget);
setBeanConfig(bean.getEJBName(), bean);
}
EJBs ejbs = annType.getAnnotation(EJBs.class);
if (ejbs != null) {
_bindTypes.add(annType);
}
// ejb/3042
DataSourceDefinition dbDef
= annType.getAnnotation(DataSourceDefinition.class);
if (dbDef != null) {
_bindTypes.add(annType);
}
DataSourceDefinitions dbDefs
= annType.getAnnotation(DataSourceDefinitions.class);
if (dbDefs != null) {
_bindTypes.add(annType);
}
} catch (ConfigException e) {
throw e;
} catch (Exception e) {
throw ConfigException.create(e);
}
}
/**
* Finds an entity bean by its abstract schema.
*/
@SuppressWarnings("unchecked")
public EjbBean findBeanByType(Class type)
{
for (EjbBean> bean : _cfgBeans.values()) {
Class> cl = bean.getEJBClass();
// ejb/0j03
if (cl != null && cl.getName().equals(type.getName()))
return (EjbBean) bean;
}
return null;
}
/**
* Adds a function.
*/
public void addFunction(FunctionSignature sig, String sql)
{
_functions.add(sig);
}
/**
* Gets the function list.
*/
public ArrayList getFunctions()
{
return _functions;
}
/**
* Configures the pending beans.
*/
public void configure()
throws ConfigException
{
findConfigurationFiles();
try {
for (EjbBeanConfigProxy configProxy : _proxyList) {
configProxy.configure();
}
_proxyList.clear();
ArrayList> beanConfig = new ArrayList>(_pendingBeans);
_pendingBeans.clear();
_deployingBeans.addAll(beanConfig);
/*
for (EjbBean> bean : beanConfig) {
bean.init();
}
*/
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw ConfigException.create(e);
}
}
/**
* Configures the pending beans.
*/
private void findConfigurationFiles()
throws ConfigException
{
for (FileSetType fileSet : _fileSetList) {
for (Path path : fileSet.getPaths()) {
addEjbPath(path);
}
}
}
/**
* Configures the pending beans.
*/
public void deploy()
throws ConfigException
{
try {
ClassLoader parentLoader = _ejbManager.getClassLoader();
Path workDir = _ejbManager.getWorkDir();
JavaClassGenerator javaGen = new JavaClassGenerator();
javaGen.setWorkDir(workDir);
javaGen.setParentLoader(parentLoader);
ArrayList> deployingBeans
= new ArrayList>(_deployingBeans);
_deployingBeans.clear();
deployBeans(deployingBeans, javaGen);
deployBindings(_bindTypes);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw ConfigException.create(e);
}
}
/**
* Configures the pending beans.
*/
public void deployBeans(ArrayList> beanConfig,
JavaClassGenerator javaGen)
throws Exception
{
Thread thread = Thread.currentThread();
ClassLoader oldLoader = thread.getContextClassLoader();
try {
thread.setContextClassLoader(_ejbManager.getClassLoader());
// ejb/0g1c, ejb/0f68, ejb/0f69
ArrayList> beanList = new ArrayList>();
for (EjbBean> bean : beanConfig) {
if (beanList.contains(bean))
continue;
bean.init();
deployBean(beanConfig, javaGen, beanList, bean);
}
} finally {
thread.setContextClassLoader(oldLoader);
}
}
private void deployBean(ArrayList> beanConfig,
JavaClassGenerator javaGen,
ArrayList> beanList,
EjbBean bean)
throws Exception
{
Thread thread = Thread.currentThread();
EjbLazyGenerator lazyGenerator
= new EjbLazyGenerator(bean.getAnnotatedType(), javaGen,
bean.getLocalList(), bean.getLocalBean(),
bean.getRemoteList());
AbstractEjbBeanManager server = initBean(bean, lazyGenerator);
_ejbManager.addServer(server);
ArrayList dependList = bean.getBeanDependList();
for (String depend : dependList) {
for (EjbBean> b : beanConfig) {
if (bean == b)
continue;
// XXX: what test case is this for?
if (depend.equals(b.getEJBName())) {
beanList.add(b);
/*
AbstractEjbBeanManager> dependServer = initBean(b, lazyGenerator);
initResources(b, dependServer);
*/
thread.setContextClassLoader(server.getClassLoader());
}
}
}
// XXX: 4.0.8 timing issues
// initResources(bean, server);
}
private AbstractEjbBeanManager
initBean(EjbBean bean,
EjbLazyGenerator lazyGenerator)
throws Exception
{
AbstractEjbBeanManager server = bean.deployServer(_ejbManager, lazyGenerator);
server.init();
return server;
}
private void deployBindings(ArrayList> bindTypes)
{
InjectManager cdiManager = _ejbManager.getInjectManager();
for (AnnotatedType> annType : bindTypes) {
// ioc/123q
cdiManager.getInjectionPointHandler(EJBs.class).introspectType(annType);
cdiManager.getInjectionPointHandler(DataSourceDefinition.class).introspectType(annType);
cdiManager.getInjectionPointHandler(DataSourceDefinitions.class).introspectType(annType);
}
}
@Override
public String toString()
{
String id = _ejbManager.getClassLoader().getId();
return getClass().getSimpleName() + "[" + id + "]";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy