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

com.caucho.ejb.protocol.EjbProtocolManager 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.protocol;

import com.caucho.config.ConfigException;
import com.caucho.ejb.manager.EjbManager;
import com.caucho.ejb.server.AbstractEjbBeanManager;
import com.caucho.server.e_app.EnterpriseApplication;
import com.caucho.naming.Jndi;
import com.caucho.util.L10N;

import javax.enterprise.inject.spi.AnnotatedType;
import javax.naming.NamingException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Server containing all the EJBs for a given configuration.
 * 
 * 

* Each protocol will extend the container to override Handle creation. */ public class EjbProtocolManager { @SuppressWarnings("unused") private static final L10N L = new L10N(EjbProtocolManager.class); protected static final Logger log = Logger.getLogger(EjbProtocolManager.class .getName()); private static ThreadLocal _protocolLocal = new ThreadLocal(); private static Hashtable>> _staticServerMap = new Hashtable>>(); private final EjbManager _ejbContainer; private final ClassLoader _loader; private String _localJndiPrefix; // = "java:comp/env/cmp"; private String _remoteJndiPrefix; // = "java:comp/env/ejb"; private String _jndiPrefix; // java:comp/env/ejb/FooBean/local private HashMap> _serverMap = new HashMap>(); // handles remote stuff protected ProtocolContainer _protocolContainer; protected HashMap _protocolMap = new HashMap(); /** * Create a server with the given prefix name. */ public EjbProtocolManager(EjbManager ejbContainer) throws ConfigException { _ejbContainer = ejbContainer; _loader = _ejbContainer.getClassLoader(); EjbManager parent = ejbContainer.getParent(); if (parent != null) { _localJndiPrefix = parent.getProtocolManager().getLocalJndiPrefix(); _remoteJndiPrefix = parent.getProtocolManager().getRemoteJndiPrefix(); _jndiPrefix = parent.getProtocolManager().getJndiPrefix(); } } public void setJndiPrefix(String name) { _jndiPrefix = name; } public String getJndiPrefix() { return _jndiPrefix; } public void setLocalJndiPrefix(String name) { _localJndiPrefix = name; } public String getLocalJndiPrefix() { return _localJndiPrefix; } public void setRemoteJndiPrefix(String name) { _remoteJndiPrefix = name; } public String getRemoteJndiPrefix() { return _remoteJndiPrefix; } /** * Returns the EJB server. */ public EjbManager getEjbContainer() { return _ejbContainer; } /** * Initialize the protocol manager. */ public void init() throws NamingException { } /** * Gets the current protocol. */ public static String getThreadProtocol() { return _protocolLocal.get(); } /** * Gets the current protocol. */ public static String setThreadProtocol(String protocol) { String oldProtocol = _protocolLocal.get(); _protocolLocal.set(protocol); return oldProtocol; } public void setProtocolContainer(ProtocolContainer protocol) { _protocolContainer = protocol; synchronized (_protocolMap) { _protocolMap.put(protocol.getName(), protocol); } addProtocolServers(protocol); } public void addProtocolContainer(ProtocolContainer protocol) { if (_protocolContainer == null) _protocolContainer = protocol; addProtocolContainer(protocol.getName(), protocol); } public void removeProtocolContainer(ProtocolContainer protocol) { if (_protocolContainer == protocol) _protocolContainer = null; synchronized (_protocolMap) { _protocolMap.remove(protocol.getName()); } } public void addProtocolContainer(String name, ProtocolContainer protocol) { synchronized (_protocolMap) { if (_protocolMap.get(name) == null) _protocolMap.put(name, protocol); } addProtocolServers(protocol); } public ProtocolContainer getProtocol(String name) { synchronized (_protocolMap) { return _protocolMap.get(name); } } private void addProtocolServers(ProtocolContainer protocol) { for (AbstractEjbBeanManager server : _serverMap.values()) { protocol.addServer(server); } } /** * Returns the named server if it's in the same JVM. */ public static AbstractEjbBeanManager getJVMServer(String serverId) { WeakReference> serverRef = _staticServerMap.get(serverId); return serverRef != null ? serverRef.get() : null; } /** * Adds a server. */ public void addServer(AbstractEjbBeanManager server) { _serverMap.put(server.getProtocolId(), server); for (ProtocolContainer protocol : _protocolMap.values()) { protocol.addServer(server); } Thread thread = Thread.currentThread(); ClassLoader loader = thread.getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(_loader); // ejb/0g11 // remote without a local interface should not get bound // with the local prefix bindDefaultJndi(_jndiPrefix, server); bindPortableJndiApis(server); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw ConfigException.create(e); } finally { Thread.currentThread().setContextClassLoader(loader); } } @SuppressWarnings("unchecked") private void bindDefaultJndi(String prefix, AbstractEjbBeanManager server) { try { EnterpriseApplication eApp = EnterpriseApplication.getCurrent(); if (prefix == null) prefix = ""; else if (!prefix.endsWith("/")) prefix = prefix + "/"; if (eApp != null && eApp.getName() != null) prefix = prefix + eApp.getName() + "/"; prefix = prefix + server.getEJBName(); ClassLoader loader = Thread.currentThread().getContextClassLoader(); ArrayList> apiList = server.getLocalApi(); if (apiList != null && apiList.size() > 0) { String jndiName = prefix + "/local"; Class localApi = apiList.get(0).getJavaClass(); Jndi.bindDeep(jndiName, new ServerLocalProxy(server, localApi)); log.finest(server + " local binding to '" + jndiName + "' " + loader); } Object localHome = null; if (localHome != null) { String jndiName = prefix + "/local-home"; Jndi.bindDeep(jndiName, localHome); log.finest(server + " local-home binding to '" + jndiName + "' " + loader); } } catch (Exception e) { throw ConfigException.create(e); } } private void bindPortableJndi(String appName, String moduleName, String suffix, ServerLocalProxy proxy) { try { Thread thread = Thread.currentThread(); ClassLoader oldLoader = thread.getContextClassLoader(); try { thread.setContextClassLoader(_loader); String jndiName = null; // global _may_ mean across applications, but is not required // (EJB 3.1 spec. sec. 3.2.2). if (appName != null) jndiName = "java:global/" + appName + '/' + moduleName + '/' + suffix; else jndiName = "java:global/" + moduleName + '/' + suffix; // XXX: for embed client must be true global thread.setContextClassLoader(_ejbContainer.getGlobalClassLoader()); Jndi.bindDeep(jndiName, proxy); log.finer(proxy + " global binding to '" + jndiName + "' " + _loader); thread.setContextClassLoader(_loader); // application means across modules within an application jndiName = "java:app/" + moduleName + '/' + suffix; Jndi.bindDeep(jndiName, proxy); log.finest(proxy + " application binding to '" + jndiName + "' " + _loader); // XXX module binding - this is problematic because this will // expose a module-level binding to the application context // used by the EJBContainer // module means local to a single module within an application jndiName = "java:module/" + suffix; Jndi.bindDeep(jndiName, proxy); log.finest(proxy + " module binding to '" + jndiName + "' " + _loader); } finally { Thread.currentThread().setContextClassLoader(oldLoader); } } catch (Exception e) { throw ConfigException.create(e); } } private void bindPortableJndiApis(AbstractEjbBeanManager manager) { String appName = null; EnterpriseApplication app = EnterpriseApplication.getCurrent(); if (app != null) appName = app.getName(); String moduleName = manager.getModuleName(); if (moduleName != null) { ServerLocalProxy proxy = null; if (manager.getLocalBean() != null) { String suffix = manager.getEJBName(); Class api = manager.getEjbClass(); proxy = new ServerLocalProxy(manager, api); bindPortableJndi(appName, moduleName, suffix, proxy); suffix = suffix + '!' + manager.getEjbClass().getName(); bindPortableJndi(appName, moduleName, suffix, proxy); } ArrayList> apiList = manager.getLocalApi(); if (apiList.size() == 1) { String suffix = manager.getEJBName(); Class api = apiList.get(0).getJavaClass(); proxy = new ServerLocalProxy(manager, api); if (manager.getLocalBean() == null) bindPortableJndi(appName, moduleName, suffix, proxy); suffix = suffix + '!' + api.getName(); bindPortableJndi(appName, moduleName, suffix, proxy); } else { for (AnnotatedType api : apiList) { String suffix = manager.getEJBName() + '!' + api.getJavaClass().getName(); proxy = new ServerLocalProxy(manager, api.getJavaClass()); bindPortableJndi(appName, moduleName, suffix, proxy); } } } } /** * Adds a server. */ public void removeServer(AbstractEjbBeanManager server) throws NamingException { for (ProtocolContainer protocol : _protocolMap.values()) { protocol.removeServer(server); } } /** * Returns the server specified by the serverId. */ public AbstractEjbBeanManager getServerByEJBName(String ejbName) { if (!ejbName.startsWith("/")) ejbName = "/" + ejbName; return _serverMap.get(ejbName); } /** * Returns the server specified by the serverId. */ public AbstractEjbBeanManager getServerByServerId(String protocolId) { for (AbstractEjbBeanManager server : _serverMap.values()) { if (protocolId.equals(server.getProtocolId())) return server; } return null; } @SuppressWarnings("unchecked") public Iterator getLocalNames() { return _serverMap.keySet().iterator(); } /** * Returns a list of child EJB names. * * @param ejbName * the name which might be a prefix. */ public ArrayList getLocalChildren(String ejbName) { if (!ejbName.startsWith("/")) ejbName = "/" + ejbName; if (!ejbName.endsWith("/")) ejbName = ejbName + "/"; ArrayList children = new ArrayList(); Iterator iter = _serverMap.keySet().iterator(); while (iter.hasNext()) { String name = iter.next(); AbstractEjbBeanManager server = _serverMap.get(name); if (server.getLocalProxy(null) == null) continue; if (name.startsWith(ejbName)) { int prefixLength = ejbName.length(); int p = name.indexOf('/', prefixLength); if (p > 0) name = name.substring(prefixLength, p); else name = name.substring(prefixLength); if (!children.contains(name)) children.add(name); } } return children; } /** * Returns a list of child EJB names. * * @param ejbName * the name which might be a prefix. */ public ArrayList getRemoteChildren(String ejbName) { if (!ejbName.startsWith("/")) ejbName = "/" + ejbName; ArrayList children = new ArrayList(); Iterator iter = _serverMap.keySet().iterator(); while (iter.hasNext()) { String name = iter.next(); AbstractEjbBeanManager server = _serverMap.get(name); } if (children.size() == 0) return null; else return children; } /** * Destroys the manager. */ public void destroy() { } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy