Package com.caucho.config.inject

Source Code of com.caucho.config.inject.ManagedBeanImpl$BeanTimeoutCaller

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

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import javax.ejb.Timer;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.NormalScope;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedField;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedParameter;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.InjectionTarget;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Qualifier;

import com.caucho.config.Names;
import com.caucho.config.bytecode.ScopeAdapter;
import com.caucho.config.program.Arg;
import com.caucho.config.program.BeanArg;
import com.caucho.config.timer.ScheduleIntrospector;
import com.caucho.config.timer.TimeoutCaller;
import com.caucho.config.timer.TimerTask;
import com.caucho.inject.Module;
import com.caucho.util.L10N;

/**
* SimpleBean represents a POJO Java bean registered as a WebBean.
*/
@Module
public class ManagedBeanImpl<X> extends InjectionTargetImpl<X>
  implements ScopeAdapterBean<X>
{
  private static final L10N L = new L10N(ManagedBeanImpl.class);
 
  private AnnotatedType<X> _annotatedType;

  private InjectionTarget<X> _injectionTarget;

  private HashSet<Bean<?>> _producerBeans
    = new LinkedHashSet<Bean<?>>();

  private HashSet<ObserverMethodImpl<X,?>> _observerMethods
    = new LinkedHashSet<ObserverMethodImpl<X,?>>();

  private Object _scopeAdapter;

  public ManagedBeanImpl(InjectManager webBeans,
                         AnnotatedType<X> beanType)
  {
    super(webBeans, beanType);

    _annotatedType = beanType;

    /*
    if (beanType.getType() instanceof Class)
      validateType((Class) beanType.getType());
    */

    _injectionTarget = this;
  }

  public ManagedBeanImpl(InjectManager webBeans,
                         AnnotatedType<X> beanType,
                         InjectionTarget<X> injectionTarget)
  {
    this(webBeans, beanType);

    _injectionTarget = injectionTarget;
  }

  @Override
  public AnnotatedType<X> getAnnotatedType()
  {
    return _annotatedType;
  }

  @Override
  public InjectionTarget<X> getInjectionTarget()
  {
    return _injectionTarget;
  }

  public void setInjectionTarget(InjectionTarget<X> target)
  {
    _injectionTarget = target;
  }

  /**
   * Creates a new instance of the component.
   */
  @Override
  public X create(CreationalContext<X> context)
  {
    X instance = _injectionTarget.produce(context);

    if (context != null)
      context.push(instance);

    _injectionTarget.inject(instance, context);
    _injectionTarget.postConstruct(instance);

    return instance;
  }

  @Override
  public X getScopeAdapter(Bean<?> topBean, CreationalContext<X> cxt)
  {
    NormalScope scopeType = getScope().getAnnotation(NormalScope.class);

    // ioc/0520
    if (scopeType != null
        && ! getScope().equals(ApplicationScoped.class)) {
      // && scopeType.normal()
      //  && ! env.canInject(getScope())) {

      Object value = _scopeAdapter;

      if (value == null) {
        ScopeAdapter scopeAdapter = ScopeAdapter.create(getBaseType().getRawClass());
        _scopeAdapter = scopeAdapter.wrap(getBeanManager(), topBean);
        value = _scopeAdapter;
      }

      return (X) value;
    }

    return null;
  }
 
  protected boolean isProxiedScope()
  {
    NormalScope scopeType = getScope().getAnnotation(NormalScope.class);
   
    if (scopeType != null
        && ! getScope().equals(ApplicationScoped.class)) {
      return true;
    }
    else
      return false;
  }

  public Object getScopeAdapter()
  {
    Object value = _scopeAdapter;

    if (value == null) {
      ScopeAdapter scopeAdapter = ScopeAdapter.create(getTargetClass());
      _scopeAdapter = scopeAdapter.wrap(getBeanManager(), this);
      value = _scopeAdapter;
    }

    return value;
  }

  public Set<Bean<?>> getProducerBeans()
  {
    return _producerBeans;
  }

  /**
   * Returns the observer methods
   */
  public Set<ObserverMethodImpl<X,?>> getObserverMethods()
  {
    return _observerMethods;
  }

  /**
   * Call post-construct
   */
  public void dispose(X instance)
  {

  }

  /**
   * Call pre-destroy
   */
  public void destroy(X instance, CreationalContext<X> env)
  {
    getInjectionTarget().preDestroy(instance);
  }

  //
  // introspection
  //

  @Override
  public void introspect()
  {
    super.introspect();

    // ioc/0e13
    if (_injectionTarget instanceof PassivationSetter)
      ((PassivationSetter) _injectionTarget).setPassivationId(getId());
  }

  /**
   * Called for implicit introspection.
   */
  @Override
  public void introspect(AnnotatedType<X> beanType)
  {
    super.introspect(beanType);

    introspectProduces(beanType);

    introspectObservers(beanType);
  }

  /**
   * Introspects the methods for any @Produces
   */
  protected void introspectProduces(AnnotatedType<X> beanType)
  {
    for (AnnotatedMethod<? super X> beanMethod : beanType.getMethods()) {
      if (beanMethod.isAnnotationPresent(Produces.class)) {
        AnnotatedMethod<? super X> disposesMethod
          = findDisposesMethod(beanType, beanMethod);
       
        addProduces(beanMethod, disposesMethod);
      }
    }
   
    for (AnnotatedField<?> beanField : beanType.getFields()) {
      if (beanField.isAnnotationPresent(Produces.class))
        addProduces(beanField);
    }
  }

  protected void addProduces(AnnotatedMethod producesMethod,
                             AnnotatedMethod disposesMethod)
  {
    Arg<?> []args = introspectArguments(producesMethod.getParameters());

    ProducesBean<?,?> bean = ProducesBean.create(getBeanManager(), this,
                                                 producesMethod, args,
                                                 disposesMethod);

    // bean.init();

    _producerBeans.add(bean);
  }
 
  private AnnotatedMethod<? super X>
  findDisposesMethod(AnnotatedType<X> beanType,
                     AnnotatedMethod<? super X> producesMethod)
  {
    for (AnnotatedMethod beanMethod : beanType.getMethods()) {
      List<AnnotatedParameter<?>> params = beanMethod.getParameters();
     
      if (params.size() != 1)
        continue;
     
      AnnotatedParameter<?> param = params.get(0);
     
      if (! param.isAnnotationPresent(Disposes.class))
        continue;
     
      if (! producesMethod.getBaseType().equals(param.getBaseType()))
        continue;


      // XXX: check @Qualifiers
     
      return beanMethod;
    }
   
    return null;
  }

  protected void addProduces(AnnotatedField<?> beanField)
  {
    ProducesFieldBean bean
      = ProducesFieldBean.create(getBeanManager(), this, beanField);

    // bean.init();

    _producerBeans.add(bean);
  }

  protected Arg []introspectArguments(List<AnnotatedParameter<X>> params)
  {
    Arg []args = new Arg[params.size()];

    for (int i = 0; i < args.length; i++) {
      AnnotatedParameter<X> param = params.get(i);

      if (InjectionPoint.class.equals(param.getBaseType()))
        args[i] = new InjectionPointArg();
      else
        args[i] = new BeanArg(param.getBaseType(), getQualifiers(param));
    }

    return args;
  }

  private Annotation []getQualifiers(Annotated annotated)
  {
    ArrayList<Annotation> qualifierList = new ArrayList<Annotation>();

    for (Annotation ann : annotated.getAnnotations()) {
      if (ann.annotationType().equals(Named.class)) {
        String namedValue = getNamedValue(ann);

        if ("".equals(namedValue)) {
          String name = getBeanClass().getSimpleName();

          ann = Names.create(name);
        }

        qualifierList.add(ann);

      }
      else if (ann.annotationType().isAnnotationPresent(Qualifier.class)) {
        qualifierList.add(ann);
      }
    }

    if (qualifierList.size() == 0)
      qualifierList.add(CurrentLiteral.CURRENT);

    Annotation []qualifiers = new Annotation[qualifierList.size()];
    qualifierList.toArray(qualifiers);

    return qualifiers;
  }

  /**
   * Introspects the methods for any @Produces
   */
  protected void introspectObservers(AnnotatedType<?> beanType)
  {
    for (AnnotatedMethod<?> beanMethod : beanType.getMethods()) {
      for (AnnotatedParameter param : beanMethod.getParameters()) {
        if (param.isAnnotationPresent(Observes.class)) {
          addObserver(beanMethod);
          break;
        }
      }
    }
  }

  protected void addObserver(AnnotatedMethod beanMethod)
  {
    int param = findObserverAnnotation(beanMethod);

    if (param < 0)
      return;

    Method method = beanMethod.getJavaMember();
    Type eventType = method.getGenericParameterTypes()[param];

    HashSet<Annotation> bindingSet = new HashSet<Annotation>();

    Annotation [][]annList = method.getParameterAnnotations();
    if (annList != null && annList[param] != null) {
      for (Annotation ann : annList[param]) {
        if (ann.annotationType().isAnnotationPresent(Qualifier.class))
          bindingSet.add(ann);
      }
    }

    if (method.isAnnotationPresent(Inject.class)) {
      throw InjectManager.error(method, L.l("A method may not have both an @Observer and an @Inject annotation."));
    }

    if (method.isAnnotationPresent(Produces.class)) {
      throw InjectManager.error(method, L.l("A method may not have both an @Observer and a @Produces annotation."));
    }

    if (method.isAnnotationPresent(Disposes.class)) {
      throw InjectManager.error(method, L.l("A method may not have both an @Observer and a @Disposes annotation."));
    }

    ObserverMethodImpl observerMethod
      = new ObserverMethodImpl(getBeanManager(), this, beanMethod,
                               eventType, bindingSet);

    _observerMethods.add(observerMethod);
  }

  private <X> int findObserverAnnotation(AnnotatedMethod<X> method)
  {
    List<AnnotatedParameter<X>> params = method.getParameters();
    int size = params.size();
    int observer = -1;

    for (int i = 0; i < size; i++) {
      AnnotatedParameter param = params.get(i);

      for (Annotation ann : param.getAnnotations()) {
        if (ann instanceof Observes) {
          if (observer >= 0)
            throw InjectManager.error(method.getJavaMember(), L.l("Only one param may have an @Observer"));

          observer = i;
        }
      }
    }

    return observer;
  }

  /**
   *
   */
  public void scheduleTimers(Object value)
  {
    ScheduleIntrospector introspector = new ScheduleIntrospector();
   
    TimeoutCaller timeoutCaller = new BeanTimeoutCaller(value);
   
    ArrayList<TimerTask> taskList
      = introspector.introspect(timeoutCaller, _annotatedType);
   
    if (taskList != null) {
      for (TimerTask task : taskList) {
        task.start();
      }
    }
  }
 
  static class BeanTimeoutCaller implements TimeoutCaller
  {
    private Object _bean;
   
    BeanTimeoutCaller(Object bean)
    {
      _bean = bean;
    }

    @Override
    public void timeout(Method method)
    throws InvocationTargetException,
           IllegalAccessException
    {
      method.invoke(_bean);
    }

    @Override
    public void timeout(Method method, Timer timer)
        throws InvocationTargetException, IllegalAccessException
    {
     
    }
   
  }
}
TOP

Related Classes of com.caucho.config.inject.ManagedBeanImpl$BeanTimeoutCaller

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.