Package com.caucho.ejb.cfg

Source Code of com.caucho.ejb.cfg.EjbSessionBean

/*
* 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.cfg;

import static javax.ejb.TransactionAttributeType.REQUIRED;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;

import javax.annotation.PostConstruct;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
import javax.ejb.EJBLocalHome;
import javax.ejb.Local;
import javax.ejb.LocalHome;
import javax.ejb.Remote;
import javax.ejb.RemoteHome;
import javax.ejb.SessionSynchronization;
import javax.ejb.Singleton;
import javax.ejb.Stateful;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.enterprise.inject.spi.AnnotatedType;

import com.caucho.config.ConfigException;
import com.caucho.config.LineConfigException;
import com.caucho.config.gen.ApiClass;
import com.caucho.config.gen.ApiMethod;
import com.caucho.config.gen.BeanGenerator;
import com.caucho.config.gen.XaAnnotation;
import com.caucho.ejb.gen.SessionGenerator;
import com.caucho.ejb.gen.SingletonGenerator;
import com.caucho.ejb.gen.StatefulGenerator;
import com.caucho.ejb.gen.StatelessGenerator;
import com.caucho.ejb.manager.EjbContainer;
import com.caucho.ejb.server.AbstractServer;
import com.caucho.ejb.server.EjbProducer;
import com.caucho.ejb.session.SingletonManager;
import com.caucho.ejb.session.StatefulManager;
import com.caucho.ejb.session.StatelessManager;
import com.caucho.java.gen.JavaClassGenerator;
import com.caucho.util.L10N;

/**
* Configuration for an ejb entity bean.
*/
public class EjbSessionBean extends EjbBean {
  private static final L10N L = new L10N(EjbSessionBean.class);

  // Default is container managed transaction.
  private boolean _isContainerTransaction = true;

  private SessionGenerator _sessionBean;

  private Class<? extends Annotation> _sessionType;

  /**
   * Creates a new session bean configuration.
   */
  public EjbSessionBean(EjbConfig ejbConfig, String ejbModuleName) {
    super(ejbConfig, ejbModuleName);
  }

  /**
   * Creates a new session bean configuration.
   */
  public EjbSessionBean(EjbConfig ejbConfig,
                        AnnotatedType annType,
                        String ejbModuleName) {
    super(ejbConfig, annType, ejbModuleName);
  }

  /**
   * Returns the kind of bean.
   */
  public String getEJBKind() {
    return "session";
  }

  /**
   * Sets the ejb implementation class.
   */
  @Override
  public void setEJBClass(Class type) throws ConfigException {
    super.setEJBClass(type);

    ApiClass ejbClass = getEJBClassWrapper();

    if (ejbClass.isAbstract())
      throw error(L
          .l(
             "'{0}' must not be abstract.  Session bean implementations must be fully implemented.",
             ejbClass.getName()));

    if (ejbClass.isAnnotationPresent(Stateless.class)) {
      Stateless stateless = ejbClass.getAnnotation(Stateless.class);

      if (getEJBName() == null && !"".equals(stateless.name()))
        setEJBName(stateless.name());

      _sessionType = Stateless.class;
    } else if (ejbClass.isAnnotationPresent(Stateful.class)) {
      Stateful stateful = ejbClass.getAnnotation(Stateful.class);

      if (getEJBName() == null && !"".equals(stateful.name()))
        setEJBName(stateful.name());

      _sessionType = Stateful.class;
    }

    if (getEJBName() == null)
      setEJBName(ejbClass.getSimpleName());

    /*
     * if (! ejbClass.isAssignableTo(SessionBean.class) && !
     * ejbClass.isAnnotationPresent(Stateless.class) && !
     * ejbClass.isAnnotationPresent(Stateful.class)) throwerror(L.l(
     * "'{0}' must implement SessionBean or @Stateless or @Stateful.  Session beans must implement javax.ejb.SessionBean."
     * , ejbClass.getName()));
     */

    // introspectSession();
  }

  /**
   * Gets the session bean type.
   */
  public Class<? extends Annotation> getSessionType() {
    return _sessionType;
  }

  /**
   * Returns true if the container handles transactions.
   */
  public boolean isContainerTransaction() {
    return _isContainerTransaction;
  }

  /**
   * Set true if the container handles transactions.
   */
  public void setTransactionType(String type) throws ConfigException {
    if (type.equals("Container"))
      _isContainerTransaction = true;
    else if (type.equals("Bean"))
      _isContainerTransaction = false;
    else
      throw new ConfigException(
          L
              .l(
                 "'{0}' is an unknown transaction-type.  transaction-type must be 'Container' or 'Bean'.",
                 type));
  }

  /**
   * Configure initialization.
   */
  @PostConstruct
  public void init() throws ConfigException {
    super.init();

    try {
      for (ApiClass remoteApi : getRemoteList())
        validateRemote(remoteApi);

      for (ApiClass localApi : getLocalList())
        validateRemote(localApi);

      if (getEJBClass() == null) {
        throw error(L
            .l(
               "'{0}' does not have a defined ejb-class.  Session beans must have an ejb-class.",
               getEJBName()));
      }

      if (!SessionSynchronization.class.isAssignableFrom(getEJBClassWrapper()
          .getJavaClass())) {
      } else if (!Stateful.class.equals(getSessionType())) {
        throw error(L
            .l(
               "'{0}' must not implement SessionSynchronization.  Stateless session beans must not implement SessionSynchronization.",
               getEJBClass().getName()));
      } else if (!_isContainerTransaction) {
        throw error(L
            .l(
               "'{0}' must not implement SessionSynchronization.  Session beans with Bean-managed transactions may not use SessionSynchronization.",
               getEJBClass().getName()));
      }
    } catch (LineConfigException e) {
      throw e;
    } catch (ConfigException e) {
      throw new LineConfigException(getLocation() + e.getMessage(), e);
    }
  }

  /**
   * Creates the bean generator for the session bean.
   */
  @Override
  protected BeanGenerator createBeanGenerator() {
    ApiClass ejbClass = getEJBClassWrapper();

    fillClassDefaults(ejbClass);

    if (Stateless.class.equals(getSessionType())) {
      _sessionBean = new StatelessGenerator(getEJBName(), ejbClass,
          getLocalList(), getRemoteList());
    } else if (Stateful.class.equals(getSessionType())) {
      _sessionBean = new StatefulGenerator(getEJBName(), ejbClass,
          getLocalList(), getRemoteList());
    } else if (Singleton.class.equals(getSessionType())){
      _sessionBean = new SingletonGenerator(getEJBName(), ejbClass,
          getLocalList(), getRemoteList());
    }

    return _sessionBean;
  }

  private void fillClassDefaults(ApiClass ejbClass) {
    if (!_isContainerTransaction) {
      ejbClass.addAnnotation(XaAnnotation.createBeanManaged());
    }

    TransactionAttribute ann = ejbClass
        .getAnnotation(TransactionAttribute.class);

    if (ann == null) {
      // ejb/1100
      ejbClass.addAnnotation(XaAnnotation.create(REQUIRED));
    }
  }

  /**
   * Obtain and apply initialization from annotations.
   */
  public void initIntrospect() throws ConfigException {
    super.initIntrospect();

    ApiClass type = getEJBClassWrapper();

    // XXX: ejb/0f78
    if (type == null)
      return;

    // ejb/0j20
    if (!type.isAnnotationPresent(Stateful.class)
        && !type.isAnnotationPresent(Stateless.class) && !isAllowPOJO())
      return;

    /*
     * TCK: ejb/0f6d: bean with local and remote interfaces if (_localHome !=
     * null || _localList.size() != 0 || _remoteHome != null ||
     * _remoteList.size() != 0) return;
     */

    ArrayList<ApiClass> interfaceList = new ArrayList<ApiClass>();

    for (ApiClass localApi : type.getInterfaces()) {
      Class javaApi = localApi.getJavaClass();

      Local local = (Local) javaApi.getAnnotation(Local.class);

      if (local != null) {
        setLocalWrapper(localApi);
        continue;
      }

      javax.ejb.Remote remote = (javax.ejb.Remote) javaApi
          .getAnnotation(javax.ejb.Remote.class);

      if (remote != null || java.rmi.Remote.class.isAssignableFrom(javaApi)) {
        setRemoteWrapper(localApi);
        continue;
      }

      if (javaApi.getName().equals("java.io.Serializable"))
        continue;

      if (javaApi.getName().equals("java.io.Externalizable"))
        continue;

      if (javaApi.getName().startsWith("javax.ejb"))
        continue;

      if (javaApi.getName().equals("java.rmi.Remote"))
        continue;

      if (!interfaceList.contains(localApi))
        interfaceList.add(localApi);
    }

    Local local = type.getAnnotation(Local.class);
    if (local != null && local.value() != null) {
      _localList.clear();

      for (Class api : local.value()) {
        // XXX: grab from type?
        _localList.add(new ApiClass(api));
      }
    }

    Remote remote = type.getAnnotation(Remote.class);
    if (remote != null && remote.value() != null) {
      _remoteList.clear();

      for (Class api : remote.value()) {
        // XXX: grab from type?
        _remoteList.add(new ApiClass(api));
      }
    }

    // if (getLocalList().size() != 0 || getRemoteList().size() != 0) {
    if (_localHome != null || _localList.size() != 0 || _remoteHome != null
        || _remoteList.size() != 0) {
    } else if (interfaceList.size() == 0) {
      // Session bean no-interface view.
    } else if (interfaceList.size() != 1)
      throw new ConfigException(
          L
              .l(
                 "'{0}' has multiple interfaces, but none are marked as @Local or @Remote.\n{1}",
                 type.getName(), interfaceList.toString()));
    else {
      setLocalWrapper(interfaceList.get(0));
    }

    // XXX: Check ejb30/bb/session/stateless/migration/twothree/annotated
    // There is a conflict between 2.1 and 3.0 interfaces.

    // ejb/0f6f
    // The session bean might have @RemoteHome for EJB 2.1 and
    // the @Remote interface for EJB 3.0 (same with @LocalHome and @Local).
    // TCK: ejb30/bb/session/stateful/sessioncontext/annotated

    ApiClass ejbClass = getEJBClassWrapper();

    LocalHome localHomeAnn = ejbClass.getAnnotation(LocalHome.class);

    // ejb/0f6f
    if (localHomeAnn != null) {
      Class localHome = localHomeAnn.value();
      setLocalHome(localHome);
    }

    RemoteHome remoteHomeAnn = ejbClass.getAnnotation(RemoteHome.class);

    // ejb/0f6f
    if (remoteHomeAnn != null) {
      Class home = remoteHomeAnn.value();
      setHome(home);
    }
  }

  /**
   * Deploys the bean.
   */
  @Override
  public AbstractServer deployServer(EjbContainer ejbContainer,
                                     JavaClassGenerator javaGen)
      throws ClassNotFoundException, ConfigException {
    AbstractServer server;

    if (Stateless.class.equals(getSessionType()))
      server = new StatelessManager(ejbContainer, getAnnotatedType());
    else if (Stateful.class.equals(getSessionType()))
      server = new StatefulManager(ejbContainer, getAnnotatedType());
    else if (Singleton.class.equals(getSessionType()))
      server = new SingletonManager(ejbContainer, getAnnotatedType());
    else
      throw new IllegalStateException(String.valueOf(getSessionType()));

    server.setModuleName(getEJBModuleName());
    server.setEJBName(getEJBName());
    server.setMappedName(getMappedName());
    server.setId(getEJBModuleName() + "#" + getEJBName());
    server.setContainerTransaction(_isContainerTransaction);

    server.setEjbClass(loadClass(getEJBClass().getName()));

    ArrayList<ApiClass> remoteList = _sessionBean.getRemoteApi();
    if (remoteList.size() > 0) {
      ArrayList<Class> classList = new ArrayList<Class>();
      for (ApiClass apiClass : remoteList) {
        classList.add(loadClass(apiClass.getName()));
      }

      server.setRemoteApiList(classList);
    }

    /*
     * if (getRemote21() != null)
     * server.setRemote21(loadClass(getRemote21().getName()));
     */

    ArrayList<ApiClass> localList = _sessionBean.getLocalApi();
    if (localList.size() > 0) {
      ArrayList<Class> classList = new ArrayList<Class>();
      for (ApiClass apiClass : localList) {
        classList.add(loadClass(apiClass.getName()));
      }

      server.setLocalApiList(classList);
    }

    /*
     * if (getLocal21() != null)
     * server.setLocal21(loadClass(getLocal21().getName()));
     */

    Class contextImplClass = javaGen.loadClass(getSkeletonName());

    server.setContextImplClass(contextImplClass);

    Class beanClass = javaGen.loadClass(getEJBClass().getName());

    Class[] classes = contextImplClass.getDeclaredClasses();

    for (Class aClass : classes) {
      if (getEJBClass().isAssignableFrom(aClass)) {
        server.setBeanImplClass(aClass);

        break;
      }
    }

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

    try {
      thread.setContextClassLoader(server.getClassLoader());

      EjbProducer<?> producer = server.getProducer();

      producer.setInjectionTarget(getInjectionTarget());

      producer.setInitProgram(getInitProgram());

      try {
        if (getServerProgram() != null)
          getServerProgram().configure(server);
      } catch (RuntimeException e) {
        throw e;
      } catch (Exception e) {
        throw ConfigException.create(e);
      }

    } finally {
      thread.setContextClassLoader(oldLoader);
    }

    return server;
  }

  /**
   * @return Type of bean (Stateful, Stateless, etc.)
   */
  protected String getBeanType() {
    return getSessionType().getSimpleName();
  }

  private void introspectSession() throws ConfigException {
    ApiClass ejbClass = getEJBClassWrapper();

    if (ejbClass.isAnnotationPresent(Stateless.class))
      introspectStateless(ejbClass);
    else if (ejbClass.isAnnotationPresent(Stateful.class))
      introspectStateful(ejbClass);
  }

  private void introspectStateless(ApiClass type) throws ConfigException {
    String className = type.getName();

    Stateless stateless = type.getAnnotation(Stateless.class);

    setAllowPOJO(true);

    _sessionType = Stateless.class;

    setTransactionType(type);

    String name;
    if (stateless != null)
      name = stateless.name();
    else
      name = className;

    introspectBean(type, name);
  }

  private void introspectStateful(ApiClass type) throws ConfigException {
    String className = type.getName();

    Stateful stateful = type.getAnnotation(Stateful.class);

    setAllowPOJO(true);

    _sessionType = Stateful.class;
   
    setTransactionType(type);

    String name;
    if (stateful != null)
      name = stateful.name();
    else
      name = className;

    introspectBean(type, name);
  }

  private void setTransactionType(ApiClass type) {
    TransactionManagement transaction = type
        .getAnnotation(TransactionManagement.class);

    if (transaction == null)
      setTransactionType("Container");
    else if (TransactionManagementType.BEAN.equals(transaction.value()))
      setTransactionType("Bean");
    else
      setTransactionType("Container");
  }

  private void validateMethods() throws ConfigException {
  }
}
TOP

Related Classes of com.caucho.ejb.cfg.EjbSessionBean

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.