/*
 * JBoss, the OpenSource J2EE webOS
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package org.jboss.ejb3.injection.pojo;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import javax.annotation.EJB;
import javax.annotation.Resource;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
import org.jboss.ejb3.Container;
import org.jboss.annotation.ejb.Depends;
import org.jboss.annotation.JndiInject;

/**
 * Comment
 *
 * @author <a href="mailto:bill@jboss.org">Bill Burke</a>
 * @version $Revision: 1.1.2.3 $
 */
public class InjectionHelper
{
   public static void inject(Object target, Class clazz, Class<? extends Annotation> annotation, PojoInjector injector)
   {
      if (clazz.equals(Object.class)) return;

      Method[] methods = clazz.getDeclaredMethods();
      for (Method m : methods)
      {
         if (m.isAnnotationPresent(annotation))
         {
            injector.inject(m, m.getAnnotation(annotation), target);
         }
      }

      Field[] fields = clazz.getDeclaredFields();
      for (Field f : fields)
      {
         if (f.isAnnotationPresent(annotation))
         {
            injector.inject(f, f.getAnnotation(annotation), target);
         }
      }

      inject(target, clazz.getSuperclass(), annotation, injector);
   }

   public static void checkMethodSignature(Method m, Annotation a)
   {
      if (!m.getName().startsWith("set")) throw new RuntimeException("@" + a.getClass().getName() + " can only be used with a set method: " + m);
      if (m.getParameterTypes().length != 1) throw new RuntimeException("@" + a.getClass().getName() + " can only be used with a set method of one parameter: " + m);
   }

   public static void iterateHardcodedInjectors(Container container, Object target)
   {
      DependsInjector depends = new DependsInjector();
      EJBInjector ejb = new EJBInjector(container.getEjbLinkResolver(), container.getInitialContext());
      JndiInjector jndi = new JndiInjector(container.getInitialContextProperties());
      PersistenceContextInjector pc = new PersistenceContextInjector(container.getInitialContextProperties());
      PersistenceUnitInjector pu = new PersistenceUnitInjector(container.getInitialContextProperties());
      ResourceInjector resource = new ResourceInjector(container);

      inject(target, target.getClass(), Depends.class, depends);
      inject(target, target.getClass(), EJB.class, ejb);
      inject(target, target.getClass(), JndiInject.class, jndi);
      inject(target, target.getClass(), PersistenceContext.class, pc);
      inject(target, target.getClass(), PersistenceUnit.class, pu);
      inject(target, target.getClass(), Resource.class, resource);

   }

}
