Package com.caucho.ejb.server

Source Code of com.caucho.ejb.server.AbstractServer

/*
* Copyright (c) 1998-2010 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.server;

import java.util.ArrayList;
import java.util.logging.Logger;

import javax.ejb.FinderException;
import javax.ejb.Timer;
import javax.ejb.TimerService;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.transaction.UserTransaction;

import com.caucho.config.ConfigException;
import com.caucho.config.LineConfigException;
import com.caucho.config.program.ConfigProgram;
import com.caucho.ejb.cfg.AroundInvokeConfig;
import com.caucho.ejb.manager.EjbContainer;
import com.caucho.ejb.session.AbstractSessionContext;
import com.caucho.jca.pool.UserTransactionProxy;
import com.caucho.lifecycle.Lifecycle;
import com.caucho.loader.DynamicClassLoader;
import com.caucho.loader.EnvironmentBean;
import com.caucho.loader.EnvironmentClassLoader;
import com.caucho.util.L10N;

/**
* Base server for a single home/object bean pair.
*/
abstract public class AbstractServer<T> implements EnvironmentBean {
  private final static Logger log
    = Logger.getLogger(AbstractServer.class.getName());
  private static final L10N L = new L10N(AbstractServer.class);

  protected final EjbContainer _ejbContainer;

  protected final UserTransaction _ut = UserTransactionProxy.getInstance();

  protected String _filename;
  protected int _line;
  protected String _location;

  // The original bean implementation class
  protected Class<T> _ejbClass;

  // introspected bean information
  private AnnotatedType<T> _annotatedType;
  private Bean<T> _bean;

  protected String _id;
  protected String _ejbName;
  protected String _moduleName;
  protected String _handleServerId;

  // name for IIOP, Hessian, JNDI
  protected String _mappedName;

  protected ArrayList<Class<?>> _remoteApiList = new ArrayList<Class<?>>();
  protected ArrayList<Class<?>> _localApiList = new ArrayList<Class<?>>();

  protected Class<?> _serviceEndpointClass;

  private Context _jndiEnv;
 
  // server-specific classloader
  protected EnvironmentClassLoader _loader;

  private ConfigProgram _serverProgram;

  // injection/postconstruct from Java Injection
  private EjbProducer<T> _producer;

  private boolean _isContainerTransaction = true;
  protected long _transactionTimeout;

  // Generated classes
  protected Class<? extends T> _contextImplClass;

  // generated Java Injection bean
  protected Bean<T> _component;

  private final Lifecycle _lifecycle = new Lifecycle();;

  /**
   * Creates a new server container
   *
   * @param manager
   *          the owning server container
   */
  public AbstractServer(EjbContainer container,
                        AnnotatedType<T> annotatedType)
  {
    _annotatedType = annotatedType;
    _ejbContainer = container;

    _loader = EnvironmentClassLoader.create(container.getClassLoader());
    _loader.setAttribute("caucho.inject", false);
   
    _producer = new EjbProducer<T>(this, annotatedType);
  }

  /**
   * Returns the id, module-path#ejb-name.
   */
  public String getId()
  {
    return _id;
  }

  /**
   * Sets the id, module-path#ejb-name.
   */
  public void setId(String id)
  {
    _id = id;

    int p = id.lastIndexOf('/');
    if (p > 0)
      _loader.setId(getType() + id.substring(p + 1));
    else
      _loader.setId(getType() + id);
  }

  public void setConfigLocation(String filename, int line)
  {
    _filename = filename;
    _line = line;
  }

  public void setLocation(String location)
  {
    _location = location;
  }

  protected String getType()
  {
    return "ejb:";
  }

  public Bean<T> getDeployBean()
  {
    return _bean;
  }
 
  public EjbProducer<T> getProducer()
  {
    return _producer;
  }

  public void setAroundInvoke(AroundInvokeConfig aroundInvoke)
  {
  }

  /**
   * Sets the ejb name.
   */
  public void setEJBName(String ejbName)
  {
    _ejbName = ejbName;
  }

  /**
   * Returns the ejb's name
   */
  public String getEJBName()
  {
    return _ejbName;
  }

  /**
   * Set's the module that defined this ejb.
   */
  public void setModuleName(String moduleName)
  {
    _moduleName = moduleName;
  }

  /**
   * Returns's the module that defined this ejb.
   */
  public String getModuleName()
  {
    return _moduleName;
  }

  /**
   * Sets the mapped name, default is to use the EJBName. This is the name for
   * both JNDI and the protocols such as IIOP and Hessian.
   */
  public void setMappedName(String mappedName)
  {
    if (mappedName == null) {
      _mappedName = null;
      return;
    }

    while (mappedName.startsWith("/"))
      mappedName = mappedName.substring(1);

    while (mappedName.endsWith("/"))
      mappedName = mappedName.substring(0, mappedName.length() - 1);

    _mappedName = mappedName;
  }

  /**
   * Returns the mapped name.
   */
  public String getMappedName()
  {
    return _mappedName == null ? getEJBName() : _mappedName;
  }

  /**
   * The name to use for remoting protocols, such as IIOP and Hessian.
   */
  public String getProtocolId()
  {
    return "/" + getMappedName();
  }

  /**
   * The name to use for remoting protocols, such as IIOP and Hessian.
   */
  public String getProtocolId(Class<?> cl)
  {
    if (cl == null)
      return getProtocolId();

    // XXX TCK:
    // ejb30/bb/session/stateless/callback/defaultinterceptor/descriptor/defaultInterceptorsForCallbackBean1
    if (cl.getName().startsWith("java."))
      return getProtocolId();

    // Adds the suffix "#com_sun_ts_tests_ejb30_common_sessioncontext_Three1IF";
    String url = getProtocolId() + "#" + cl.getName().replace(".", "_");

    return url;
  }

  public AnnotatedType<T> getAnnotatedType()
  {
    return _annotatedType;
  }

  /**
   * Sets the ejb class
   */
  public void setEjbClass(Class<T> cl)
  {
    _ejbClass = cl;
  }

  /**
   * Sets the ejb class
   */
  protected Class<T> getEjbClass()
  {
    return _ejbClass;
  }

  /**
   * Sets the context implementation class.
   */
  public void setContextImplClass(Class cl)
  {
    _contextImplClass = cl;
  }

  public void setBeanImplClass(Class<T> cl)
  {
  }

  /**
   * Sets the remote object list.
   */
  public void setRemoteApiList(ArrayList<Class<?>> list)
  {
    _remoteApiList = new ArrayList<Class<?>>(list);
  }

  /**
   * Returns the remote object list.
   */
  public ArrayList<Class<?>> getRemoteApiList()
  {
    return _remoteApiList;
  }

  /**
   * Returns true if there is any remote object.
   */
  public boolean hasRemoteObject()
  {
    return _remoteApiList.size() > 0;
  }

  /**
   * Sets the local api class list
   */
  public void setLocalApiList(ArrayList<Class<?>> list)
  {
    _localApiList = new ArrayList<Class<?>>(list);
  }

  /**
   * Sets the remote object class.
   */
  public ArrayList<Class<?>> getLocalApiList()
  {
    return _localApiList;
  }

  /**
   * Returns the encoded id.
   */
  public String encodeId(Object primaryKey)
  {
    return String.valueOf(primaryKey);
  }

  /**
   * Looks up the JNDI object.
   */
  public Object lookup(String jndiName)
  {
    try {
      if (_jndiEnv == null)
        _jndiEnv = (Context) new InitialContext().lookup("java:comp/env");

      // XXX: not tested
      return _jndiEnv.lookup(jndiName);
    } catch (NamingException e) {
      throw new IllegalArgumentException(e);
    }
  }

  public UserTransaction getUserTransaction()
  {
    return _ut;
  }

  /**
   * Returns the owning container.
   */
  public EjbContainer getEjbContainer()
  {
    return _ejbContainer;
  }

  /**
   * Sets the server program.
   */
  public void setServerProgram(ConfigProgram serverProgram)
  {
    _serverProgram = serverProgram;
  }

  /**
   * Sets the server program.
   */
  public ConfigProgram getServerProgram()
  {
    return _serverProgram;
  }

  /**
   * Sets the transaction timeout.
   */
  public void setTransactionTimeout(long timeout)
  {
    _transactionTimeout = timeout;
  }

  /**
   * Gets the transaction timeout.
   */
  public long getTransactionTimeout()
  {
    return _transactionTimeout;
  }

  /**
   * Returns the timer service.
   */
  public TimerService getTimerService()
  {
    // ejb/0fj0
    throw new UnsupportedOperationException(L.l("'{0}' does not support a timer service because it does not have a @Timeout method",
                                                this));
  }

  /**
   * Invalidates caches.
   */
  public void invalidateCache()
  {
  }

  /**
   * Gets the class loader
   */
  public DynamicClassLoader getClassLoader()
  {
    return _loader;
  }

  /**
   * Gets the generated skeleton class
   */
  public Class getBeanSkelClass()
  {
    return _contextImplClass;
  }

  /**
   * Returns the session context.
   */
  public AbstractSessionContext getSessionContext()
  {
    return null;
  }

  /**
   * Returns the remote skeleton for the given API
   *
   * @param api
   *          the bean's api to return a value for
   * @param protocol
   *          the remote protocol
   */
  abstract public Object getRemoteObject(Class<?> api, String protocol);

  /**
   * Returns the a new local stub for the given API
   *
   * @param api
   *          the bean's api to return a value for
   */
  abstract public Object getLocalObject(Class<?> api);

  /**
   * Returns the local jndi proxy for the given API
   *
   * @param api
   *          the bean's api to return a value for
   */
  abstract public Object getLocalProxy(Class<?> api);

  /**
   * Returns the remote object.
   */
  public Object getRemoteObject(Object key) throws FinderException
  {
    // XXX TCK: ejb30/.../remove
    return getContext(key).createRemoteView();
  }

  public AbstractContext getContext()
  {
    return null;
  }

  public AbstractContext getContext(Object key) throws FinderException
  {
    return getContext(key, true);
  }

  /**
   * Returns the context with the given key
   */
  abstract public AbstractContext getContext(Object key, boolean forceLoad)
      throws FinderException;

  public void timeout(Timer timer)
  {
    /*
    throw new UnsupportedOperationException(L.l("EJB '{0}' does not support a timeout, because it does not have a @Timeout method",
                                                this));
    */
    getContext().__caucho_timeout_callback(timer);
  }

  public void init() throws Exception
  {
    _loader.init();
    // _loader.setId("EnvironmentLoader[ejb:" + getId() + "]");
  }

  public boolean start() throws Exception
  {
    if (! _lifecycle.toActive())
      return false;

    Thread thread = Thread.currentThread();
    ClassLoader oldLoader = thread.getContextClassLoader();

    try {
      thread.setContextClassLoader(_loader);

      _loader.start();

      bindContext();

      if (_serverProgram != null)
        _serverProgram.configure(this);

      bindInjection();

      postStart();

      log.config(this + " active");
    } finally {
      thread.setContextClassLoader(oldLoader);
    }

    return true;
  }
 
  protected void bindContext()
  {
  }

  protected void bindInjection()
  {
    _producer.setEnvLoader(_loader);
    _producer.bindInjection();  
  }

  protected void postStart()
  {
  }

  /**
   * Returns true if container transaction is used.
   */
  public boolean isContainerTransaction()
  {
    return _isContainerTransaction;
  }

  /**
   * Sets true if container transaction is used.
   */
  public void setContainerTransaction(boolean isContainerTransaction)
  {
    _isContainerTransaction = isContainerTransaction;
  }

  /**
   * Returns true if the server is dead.
   */
  public boolean isDead()
  {
    return ! _lifecycle.isActive();
  }

  /**
   * Cleans up the server on shutdown
   */
  public void destroy()
  {
    _lifecycle.toDestroy();
  }

  public ConfigException error(String msg)
  {
    if (_filename != null)
      throw new LineConfigException(_filename, _line, msg);
    else
      throw new ConfigException(msg);
  }

  public String toString()
  {
    if (getMappedName() != null)
      return (getClass().getSimpleName()
              + "[" + getEJBName() + "," + getMappedName() + "]");
    else
      return getClass().getSimpleName() + "[" + getEJBName() + "]";
  }
}
TOP

Related Classes of com.caucho.ejb.server.AbstractServer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.