Package com.caucho.ejb.server

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

/*
* 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.lang.reflect.Method;
import java.util.ArrayList;

import javax.ejb.TimedObject;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.InjectionTarget;

import com.caucho.config.gen.BeanProducer;
import com.caucho.config.inject.AbstractBean;
import com.caucho.config.inject.BeanFactory;
import com.caucho.config.inject.CreationalContextImpl;
import com.caucho.config.inject.InjectManager;
import com.caucho.config.inject.InjectionTargetImpl;
import com.caucho.config.inject.ManagedBeanImpl;
import com.caucho.config.program.ConfigProgram;
import com.caucho.config.xml.XmlConfigContext;
import com.caucho.ejb.cfg.PostConstructConfig;
import com.caucho.ejb.cfg.PreDestroyConfig;
import com.caucho.ejb.timer.EjbTimerService;

/**
* Creates an configures an ejb instance
*/
public class EjbProducer<T> {
  private AbstractServer<T> _server;
 
  private Class<T> _ejbClass;
  private AnnotatedType<T> _annotatedType;
 
  private Bean<T> _bean;
 
  private ClassLoader _envLoader;
 
  private BeanProducer<T> _beanProducer;
 
  private InjectionTarget<T> _injectionTarget;

  private ConfigProgram _initProgram;
  private ConfigProgram[] _initInject;
 
  private ConfigProgram[] _destroyInject;
 
  private PreDestroyConfig _preDestroyConfig;
  private PostConstructConfig _postConstructConfig;
  private Method _cauchoPostConstruct;

  private Method _timeoutMethod;
  private TimerService _timerService;
 
  EjbProducer(AbstractServer<T> server,
              AnnotatedType<T> annotatedType)
  {
    _server = server;
    _ejbClass = annotatedType.getJavaClass();
    _annotatedType = annotatedType;
   
    try {
      _cauchoPostConstruct = _ejbClass.getDeclaredMethod("__caucho_postConstruct");
      _cauchoPostConstruct.setAccessible(true);
    } catch (NoSuchMethodException e) {
    }
  }
 
  /**
   * Sets the classloader for the EJB's private environment
   *
   * @param loader the environment classloader
   */
  public void setEnvLoader(ClassLoader envLoader)
  {
    _envLoader = envLoader;
  }
 

  /**
   * Sets the injection target
   */
  public void setInjectionTarget(InjectionTarget<T> injectionTarget)
  {
    _injectionTarget = injectionTarget;
   
    if (injectionTarget instanceof InjectionTargetImpl<?>) {
      InjectionTargetImpl<T> targetImpl = (InjectionTargetImpl<T>) injectionTarget;
     
      targetImpl.setGenerateInterception(false);
    }
  }

  /**
   * Gets the injection target
   */
  public InjectionTarget<T> getInjectionTarget()
  {
    return _injectionTarget;
  }

  /**
   * Sets the init program.
   */
  public void setInitProgram(ConfigProgram init)
  {
    _initProgram = init;
  }

  /**
   * Gets the init program.
   */
  public ConfigProgram getInitProgram()
  {
    return _initProgram;
  }

  public PostConstructConfig getPostConstruct()
  {
    return _postConstructConfig;
  }

  public PreDestroyConfig getPreDestroy()
  {
    return _preDestroyConfig;
  }

  public void setPostConstruct(PostConstructConfig postConstruct)
  {
    _postConstructConfig = postConstruct;
  }

  public void setPreDestroy(PreDestroyConfig preDestroy)
  {
    _preDestroyConfig = preDestroy;
  }
 
  public void setBeanProducer(BeanProducer<T> producer)
  {
    _beanProducer = producer;
  }
 
  public BeanProducer<T> getBeanProducer()
  {
    return _beanProducer;
  }


  public void bindInjection()
  {
    InjectManager beanManager = InjectManager.create();
    ManagedBeanImpl<T> managedBean
      = beanManager.createManagedBean(_annotatedType);
   
    _bean = managedBean;
    setInjectionTarget(managedBean.getInjectionTarget());

    _timeoutMethod = getTimeoutMethod(_bean.getBeanClass());

    if (_timeoutMethod != null)
      _timerService = new EjbTimerService(_server);

    // Injection binding occurs in the start phase

    InjectManager inject = InjectManager.create();

    // server/4751
    if (_injectionTarget == null)
      _injectionTarget = inject.createInjectionTarget(_ejbClass);

    if (_timerService != null) {
      BeanFactory<TimerService> factory = inject.createBeanFactory(TimerService.class);
      inject.addBean(factory.singleton(_timerService));
    }
    /*
    ArrayList<ConfigProgram> injectList = new ArrayList<ConfigProgram>();
    InjectIntrospector.introspectInject(injectList, getEjbClass());
    // XXX: add inject from xml here
    */

    ArrayList<ConfigProgram> injectList = null;
    if (_initProgram != null) {
      injectList = new ArrayList<ConfigProgram>();
      injectList.add(_initProgram);
    }

    // InjectIntrospector.introspectInit(injectList, getEjbClass(), null);
    // XXX: add init from xml here

    if (injectList != null && injectList.size() > 0) {
      ConfigProgram[] injectArray = new ConfigProgram[injectList.size()];
      injectList.toArray(injectArray);

      if (injectArray.length > 0)
        _initInject = injectArray;
    }

    injectList = new ArrayList<ConfigProgram>();

    // XXX:
    // InjectIntrospector.introspectDestroy(injectList, _ejbClass);

    ConfigProgram[] injectArray;
    injectArray = new ConfigProgram[injectList.size()];
    injectList.toArray(injectArray);

    if (injectArray.length > 0)
      _destroyInject = injectArray;
  }

  private Method getTimeoutMethod(Class<?> targetBean)
  {
    if (TimedObject.class.isAssignableFrom(targetBean)) {
      try {
        return targetBean.getMethod("ejbTimeout", Timer.class);
      } catch (Exception e) {
        throw new IllegalStateException(e);
      }
    }

    for (Method method : targetBean.getMethods()) {
      if (method.getAnnotation(Timeout.class) != null) {
        return method;
      }
    }

    return null;
  }

  public T newInstance()
  {
    T instance = _beanProducer.__caucho_new();
    initInstance(instance);
    _beanProducer.__caucho_postConstruct(instance);
   
    return instance;
  }
 
  /**
   * Initialize an instance
   */
  public void initInstance(T instance)
  {
    initInstance(instance, null, null, CreationalContextImpl.create());
  }

  /**
   * Initialize an instance
   */
  public <X> void initInstance(T instance,
                               InjectionTarget<T> target,
                               X proxy,
                               CreationalContext<X> env)
  {
    Bean<T> bean = _bean;

    if (env != null && bean != null) {
      // server/4762
      // env.put((AbstractBean) bean, proxy);
      env.push(proxy);
    }

    Thread thread = Thread.currentThread();
    ClassLoader oldLoader = thread.getContextClassLoader();
   
    CreationalContextImpl<T> cxt = new CreationalContextImpl<T>(bean, env);

    try {
      thread.setContextClassLoader(_envLoader);

      if (target != null) {
        target.inject(instance, cxt);
      }

      if (getInjectionTarget() != null && target != getInjectionTarget()) {
        getInjectionTarget().inject(instance, cxt);
      }

      if (_initInject != null) {
        for (ConfigProgram inject : _initInject)
          inject.inject(instance, cxt);
      }

      if (_initProgram != null) {
        _initProgram.inject(instance, cxt);
      }
     
      if (getInjectionTarget() != null) {
        getInjectionTarget().postConstruct(instance);
      }

      /*
      try {
        if (_cauchoPostConstruct != null)
          _cauchoPostConstruct.invoke(instance);
      } catch (RuntimeException e) {
        throw e;
      } catch (InvocationTargetException e) {
        throw new RuntimeException(e.getCause());
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
      */
     
      if (_beanProducer != null)
        _beanProducer.__caucho_postConstruct(instance);
    } finally {
      thread.setContextClassLoader(oldLoader);
    }

    /*
    if (cxt != null && bean != null)
      cxt.remove(bean);
      */
  }
 
  /**
   * Remove an object.
   */
  public void destroyInstance(T instance)
  {
    Thread thread = Thread.currentThread();
    ClassLoader oldLoader = thread.getContextClassLoader();

    try {
      thread.setContextClassLoader(_envLoader);

      /*
      if (_destroyInject != null) {
        ConfigContext env = null;
        if (env == null)
          env = new ConfigContext();
 
        for (ConfigProgram inject : _destroyInject)
          inject.inject(instance, env);
      }
      */

      if (getInjectionTarget() != null) {
        getInjectionTarget().preDestroy(instance);
      }
    } finally {
      thread.setContextClassLoader(oldLoader);
    }
  }
 
  public String toString()
  {
    return getClass().getSimpleName() + "[" + _ejbClass + "]";
  }
}
TOP

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

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.