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.Start;
import org.jboss.ejb3.EJBContainer;
import org.jboss.ejb3.common.lang.ClassHelper;
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
*
* @author Jaikiran Pai
* @version $Revision: $
*/
public class AutoTimerInitializer
{

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

   /**
    * The EJB container
    */
   private EJBContainer container;

   /**
    *
    */
   public AutoTimerInitializer()
   {

   }

   /**
    * Creates a {@link AutoTimerInitializer} for a {@link EJBContainer}
    * @param container {@link EJBContainer}
    */
   public AutoTimerInitializer(EJBContainer container)
   {
      this.container = container;
   }

   /**
    * Sets the {@link EJBContainer}
    * @param container {@link EJBContainer}
    */
   public void setContainer(EJBContainer container)
   {
      this.container = container;
   }

   /**
    * Returns the {@link EJBContainer} for which this {@link AutoTimerInitializer} is responsible
    * for creating auto timers
    * @return
    */
   public EJBContainer getContainer()
   {
      return this.container;
   }

   /**
    * Creates any auto timers that are required for the {@link EJBContainer}, which this
    * {@link AutoTimerInitializer} represents.
    */
   @Start
   public void initializeAutoTimers()
   {
      if (this.container == null)
      {
         throw new IllegalStateException("Cannot initialize auto-timers since container is not present");
      }

      JBossEnterpriseBeanMetaData enterpriseBeanMetaData = this.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;

      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();
      }
      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 = this.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());
         timerConfig.setInfo(autoTimerMetaData.getInfo());
         NamedMethodMetaData timeoutMethodMetaData = autoTimerMetaData.getTimeoutMethod();
         // get hold of the timeout method for this auto-timer
         Method timeoutMethod = this.getTimeoutMethod(timeoutMethodMetaData, this.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();

      List<Method> probableTimeoutMethods = ClassHelper.getAllMethodsByName(beanClass, timeoutMethodName);
      if (probableTimeoutMethods == null || probableTimeoutMethods.isEmpty())
      {
         return null;
      }
      if (timeoutMethodParams == null)
      {
         if (probableTimeoutMethods.size() > 1)
         {
            throw new IllegalStateException("Found more than one timeout method with name: " + timeoutMethodName
                  + " on bean " + beanClass);
         }
         // match found
         return probableTimeoutMethods.get(0);
      }

      // load the method param classes
      Class<?>[] 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;
      }
      for (Method method : probableTimeoutMethods)
      {
         Class<?>[] methodParamTypes = method.getParameterTypes();
         if (equals(timeoutMethodParamTypes, methodParamTypes))
         {
            // match found
            return method;
         }
      }
      // no match found
      return null;
   }

   private boolean equals(Class<?>[] params, Class<?>[] otherParams)
   {

      if (params.length != otherParams.length)
      {
         return false;
      }
      for (int i = 0; i < params.length; i++)
      {
         // param type doesn't match
         if (!params[i].equals(otherParams[i]))
         {
            return false;
         }
      }
      return true;
   }
}
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.