Package org.jboss.ejb3.timerservice.deployer

Source Code of org.jboss.ejb3.timerservice.deployer.AutoTimerInitializer

/*
* JBoss, Home of Professional Open Source.
* Copyright 2009, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.ejb3.timerservice.deployer;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

import javax.ejb.TimerConfig;
import javax.ejb.TimerService;

import org.jboss.beans.metadata.api.annotations.Install;
import org.jboss.dependency.spi.ControllerState;
import org.jboss.ejb3.EJBContainer;
import org.jboss.ejb3.timeout.spi.TimeoutMethodCallbackRequirements;
import org.jboss.ejb3.util.Service;
import org.jboss.logging.Logger;
import org.jboss.metadata.ejb.jboss.JBossEnterpriseBeanMetaData;
import org.jboss.metadata.ejb.jboss.JBossMessageDrivenBean31MetaData;
import org.jboss.metadata.ejb.jboss.JBossSessionBean31MetaData;
import org.jboss.metadata.ejb.spec.MethodParametersMetaData;
import org.jboss.metadata.ejb.spec.NamedMethodMetaData;
import org.jboss.metadata.ejb.spec.TimerMetaData;

/**
* Responsible for creating any necessary auto timers for an EJB
*
* <p>
*  The {@link AutoTimerInitializer} "listens" for {@link EJBContainer}s which
*  reach {@link ControllerState#START} state. The {@link AutoTimerInitializer}
*  then checks the EJB metadata associated with such containers and decides whether auto-timers
*  have to be created for that container. For any such relevant container, this {@link AutoTimerInitializer}
*  then creates the auto-timer(s). 
* </p>
*
* @author Jaikiran Pai
* @version $Revision: $
*/
public class AutoTimerInitializer
{

   /**
    * Logger
    */
   private static Logger logger = Logger.getLogger(AutoTimerInitializer.class);

   /** timeout method requirements checker */
   private static TimeoutMethodCallbackRequirements timeoutMethodCallbackRequirements = Service
         .loadService(TimeoutMethodCallbackRequirements.class);

  
   /**
    * Creates auto-timer(s) for the passed {@link EJBContainer} if the corresponding EJB has auto-timers
    * configured
    *
    * @param container The EJB container
    */
   @Install (dependentState = "Start") // we work with containers in "Start" state because that's when the container
   // is available for invocations (for timeout methods).
   public void initializeAutoTimers(EJBContainer container)
   {
      JBossEnterpriseBeanMetaData enterpriseBeanMetaData = container.getXml();
      // Auto timers are only since EJB3.1
      // TODO: This check will fail when EJB3.2 or any newer versions are introduced.
      // A better check would be to look for any version greater than EJB3.1
      if (enterpriseBeanMetaData.getJBossMetaData().isEJB31() == false)
      {
         return;
      }
      List<TimerMetaData> autoTimersMetaData = null;
      // Session bean
      if (enterpriseBeanMetaData.isSession() && enterpriseBeanMetaData instanceof JBossSessionBean31MetaData)
      {
         JBossSessionBean31MetaData sessionBean = (JBossSessionBean31MetaData) enterpriseBeanMetaData;
         // Stateful beans don't have timerservice/timers
         if (sessionBean.isStateful())
         {
            return;
         }
         // Get hold of the auto timer metadata
         autoTimersMetaData = sessionBean.getTimers();
      }
      // MDB
      else if (enterpriseBeanMetaData.isMessageDriven()
            && enterpriseBeanMetaData instanceof JBossMessageDrivenBean31MetaData)
      {
         JBossMessageDrivenBean31MetaData mdb = (JBossMessageDrivenBean31MetaData) enterpriseBeanMetaData;
         // get hold of auto timer metadata
         autoTimersMetaData = mdb.getTimers();
      }
      // If there's no auto timers, then there's nothing to do
      if (autoTimersMetaData == null)
      {
         return;
      }

      // get hold of the timerservice since we need it to create the autotimers
      TimerService timerService = container.getTimerService();

      if (timerService instanceof org.jboss.ejb3.timerservice.extension.TimerService == false)
      {
         // can't do anything about this
         logger.warn("Cannot create auto timers for EJB: " + enterpriseBeanMetaData.getEjbName()
               + " since the timerservice isn't of type "
               + org.jboss.ejb3.timerservice.extension.TimerService.class.getName());
         return;
      }
      org.jboss.ejb3.timerservice.extension.TimerService ejb31TimerService = (org.jboss.ejb3.timerservice.extension.TimerService) timerService;
      // process each auto timer
      for (TimerMetaData autoTimerMetaData : autoTimersMetaData)
      {
         // create a timer config
         TimerConfig timerConfig = new TimerConfig();
         timerConfig.setPersistent(autoTimerMetaData.isPersistent());
         String info = autoTimerMetaData.getInfo();
         if (info != null && !info.isEmpty())
         {
            timerConfig.setInfo(autoTimerMetaData.getInfo());
         }
         NamedMethodMetaData timeoutMethodMetaData = autoTimerMetaData.getTimeoutMethod();
         // get hold of the timeout method for this auto-timer
         Method timeoutMethod = this.getTimeoutMethod(timeoutMethodMetaData, container.getBeanClass());
         if (timeoutMethod == null)
         {
            StringBuilder methodStringBuilder = new StringBuilder();
            methodStringBuilder.append(timeoutMethodMetaData.getMethodName());
            if (timeoutMethodMetaData.getMethodParams() != null)
            {
               methodStringBuilder.append(Arrays.toString(timeoutMethodMetaData.getMethodParams().toArray()));
            }
            throw new IllegalStateException("Timeout method: " + methodStringBuilder.toString()
                  + " not found for bean class: " + enterpriseBeanMetaData.getEjbClass());
         }
         // finally create/get the auto timer
         ejb31TimerService.getAutoTimer(autoTimerMetaData.getScheduleExpression(), timerConfig, timeoutMethod);
      }

   }

   /**
    * Returns the {@link Method}, represented by the {@link NamedMethodMetaData}, from the <code>beanClass</code>
    * <p>
    *   This method looks for private, protected, package and public methods on the <code>beanClass</code>
    *   and its superclass(es). If no matching method is found, then this method returns null.
    * </p>
    * @param timeoutMethodMetaData The method metadata
    * @param beanClass The class on which the method has to be looked for
    * @return
    * @throws NullPointerException If either of the passed parameters is null
    */
   private Method getTimeoutMethod(NamedMethodMetaData timeoutMethodMetaData, Class<?> beanClass)
   {

      String timeoutMethodName = timeoutMethodMetaData.getMethodName();
      MethodParametersMetaData timeoutMethodParams = timeoutMethodMetaData.getMethodParams();
      Class<?>[] timeoutMethodParamTypes = null;
      if (timeoutMethodParams != null)
      {
         // load the method param classes
         timeoutMethodParamTypes = new Class<?>[timeoutMethodParams.size()];
         int i = 0;
         for (String paramClassName : timeoutMethodParams)
         {
            Class<?> methodParamClass = null;
            try
            {
               methodParamClass = Class.forName(paramClassName, false, beanClass.getClassLoader());
            }
            catch (ClassNotFoundException cnfe)
            {
               throw new RuntimeException("Could not load method param class: " + paramClassName + " of timeout method");
            }
            timeoutMethodParamTypes[i++] = methodParamClass;
         }
      }
      return timeoutMethodCallbackRequirements.getTimeoutMethod(beanClass, timeoutMethodName, timeoutMethodParamTypes);
   }


}
TOP

Related Classes of org.jboss.ejb3.timerservice.deployer.AutoTimerInitializer

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.