Package org.jboss.injection

Source Code of org.jboss.injection.InjectionUtil

/*
* JBoss, Home of Professional Open Source.
* Copyright 2006, 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.injection;

import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jboss.ejb3.EJBContainer;
import org.jboss.injection.lang.reflect.BeanProperty;
import org.jboss.injection.lang.reflect.BeanPropertyFactory;
import org.jboss.logging.Logger;
import org.jboss.metadata.javaee.spec.RemoteEnvironment;
import org.jboss.metadata.javaee.spec.ResourceInjectionMetaData;
import org.jboss.metadata.javaee.spec.ResourceInjectionTargetMetaData;

/**
* Comment
*
* @author <a href="mailto:bill@jboss.org">Bill Burke</a>
* @version $Revision: 76905 $
*/
public class InjectionUtil
{
   private static final Logger log = Logger
           .getLogger(InjectionUtil.class);


   /**
    * This method will take a set of XML loaded injectors and collapse them based on spec inheritance rules
    * It will remove injectors that should not be used in the injection of the base component class.
    *
    * @param visitedMethods
    * @param clazz
    * @param xmlDefinedInjectors
    * @param classInjectors
    */
   public static void collapseXmlMethodInjectors(Set<String> visitedMethods, Class clazz, Map<String, Map<AccessibleObject, Injector>> xmlDefinedInjectors, Map<AccessibleObject, Injector> classInjectors)
   {
      if (clazz == null || clazz.equals(Object.class))
      {
         return;
      }
      Map<AccessibleObject, Injector> xmlInjectors = xmlDefinedInjectors.get(clazz.getName());
      if (xmlInjectors != null)
      {
         Method[] methods = clazz.getDeclaredMethods();
         for (Method method : methods)
         {
            if (method.getParameterTypes().length != 1) continue;

            if (!Modifier.isPrivate(method.getModifiers()))
            {
               if (visitedMethods.contains(method.getName()))
               {
                  xmlInjectors.remove(method); // if not private then it has been overriden
                  continue;
               }
               visitedMethods.add(method.getName());
            }
         }
         classInjectors.putAll(xmlInjectors);
      }
      // recursion needs to come last as the method could be overriden and we don't want the overriding method to be ignored
      collapseXmlMethodInjectors(visitedMethods, clazz.getSuperclass(), xmlDefinedInjectors, classInjectors);
   }

   /**
    * Create and add multiple injectors for injection targets.
    *
    * @param injectors          the list on which to add injectors
    * @param classLoader        the class loader to resolve an injection target
    * @param factory            the injector factory
    * @param injectionTargets   the injection targets
    */
   public static void createInjectors(List<Injector> injectors, ClassLoader classLoader, InjectorFactory<?> factory, Collection<ResourceInjectionTargetMetaData> injectionTargets)
   {
      for(ResourceInjectionTargetMetaData injectionTarget : injectionTargets)
      {
         AccessibleObject ao = findInjectionTarget(classLoader, injectionTarget);
         BeanProperty property = BeanPropertyFactory.create(ao);
         injectors.add(factory.create(property));
      }
   }
  
   public static <X extends RemoteEnvironment> void processMethodAnnotations(InjectionContainer container, Collection<InjectionHandler<X>> handlers, Set<String> visitedMethods, Class<?> clazz, Map<AccessibleObject, Injector> classInjectors)
   {
      if (clazz == null || clazz.equals(Object.class))
      {
         return;
      }
      Method[] methods = clazz.getDeclaredMethods();
      for (Method method : methods)
      {
         if (method.getParameterTypes().length != 1) continue;

         if (!Modifier.isPrivate(method.getModifiers()))
         {
            if (visitedMethods.contains(method.getName()))
            {
               continue;
            }
            visitedMethods.add(method.getName());
         }
       
         if (handlers != null)
         {
            for (InjectionHandler<?> handler : handlers)
            {
               handler.handleMethodAnnotations(method, container, classInjectors);
            }
         }
      }
      // recursion needs to come last as the method could be overriden and we don't want the overriding method to be ignored
      processMethodAnnotations(container, handlers, visitedMethods, clazz.getSuperclass(), classInjectors);
   }

   public static <X extends RemoteEnvironment> void processFieldAnnotations(InjectionContainer container, Collection<InjectionHandler<X>> handlers, Class<?> clazz, Map<AccessibleObject, Injector> classInjectors)
   {
      if (clazz == null || clazz.equals(Object.class))
      {
         return;
      }
      if (handlers != null)
      {
         Field[] fields = clazz.getDeclaredFields();
         for (Field field : fields)
         {
            log.trace("process field annotation for " + field.toGenericString());
            for (InjectionHandler<?> handler : handlers)
            {
               handler.handleFieldAnnotations(field, container, classInjectors);
            }
         }
      }
     
      // recursion needs to come last as the method could be overriden and we don't want the overriding method to be ignored
      processFieldAnnotations(container, handlers, clazz.getSuperclass(), classInjectors);
   }

   public static <X extends RemoteEnvironment> void processClassAnnotations(InjectionContainer container, Collection<InjectionHandler<X>> handlers, Class<?> clazz)
   {
      if (clazz == null || clazz.equals(Object.class))
      {
         return;
      }
   
      if (handlers != null)
      {
         for (InjectionHandler<?> handler : handlers)
         {
            handler.handleClassAnnotations(clazz, container);
         }
      }
     
      // recursion needs to come last as the method could be overriden and we don't want the overriding method to be ignored
      processClassAnnotations(container, handlers, clazz.getSuperclass());
   }

   public static <X extends RemoteEnvironment> Map<AccessibleObject, Injector> processAnnotations(InjectionContainer container, Collection<InjectionHandler<X>> handlers, Class<?> clazz)
   {
      Map<AccessibleObject, Injector> classInjectors = new HashMap<AccessibleObject, Injector>();
      HashSet<String> visitedMethods = new HashSet<String>();
      collapseXmlMethodInjectors(visitedMethods, clazz, container.getEncInjections(), classInjectors);

      processClassAnnotations(container, handlers, clazz);
      visitedMethods = new HashSet<String>();
      processMethodAnnotations(container, handlers, visitedMethods, clazz, classInjectors);
      processFieldAnnotations(container, handlers, clazz, classInjectors);
      return classInjectors;
   }

   public static AccessibleObject findInjectionTarget(ClassLoader loader, ResourceInjectionTargetMetaData target)
   {
      Class<?> clazz = null;
      try
      {
         clazz = loader.loadClass(target.getInjectionTargetClass());
      }
      catch (ClassNotFoundException e)
      {
         throw new RuntimeException("<injection-target> class: " + target.getInjectionTargetClass() + " was not found in deployment");
      }

      for (Field field : clazz.getDeclaredFields())
      {
         if (target.getInjectionTargetName().equals(field.getName())) return field;
      }

      for (java.lang.reflect.Method method : clazz.getDeclaredMethods())
      {
         if (method.getName().equals(target.getInjectionTargetName())) return method;
      }

      throw new RuntimeException("<injection-target> could not be found: " + target.getInjectionTargetClass() + "." + target.getInjectionTargetName());

   }

   public static String getEncName(Class type)
   {
      return "env/" + type.getName();
   }

   public static String getEncName(Method method)
   {
      String encName = method.getName().substring(3);
      if (encName.length() > 1)
      {
         encName = encName.substring(0, 1).toLowerCase() + encName.substring(1);
      }
      else
      {
         encName = encName.toLowerCase();
      }

      encName = getEncName(method.getDeclaringClass()) + "/" + encName;
      return encName;
   }

   public static String getEncName(Field field)
   {
      return getEncName(field.getDeclaringClass()) + "/" + field.getName();
   }

   public static Object getAnnotation(Class<? extends Annotation> annotation, EJBContainer container, Class<?> annotatedClass, boolean isContainer)
   {
      if (isContainer)
      {
         return container.resolveAnnotation(annotation);
      }
      else
      {
         return annotatedClass.getAnnotation(annotation);
      }
   }

   public static Object getAnnotation(Class<? extends Annotation> annotation, EJBContainer container, Method method, boolean isContainer)
   {
      if (isContainer)
      {
         return container.resolveAnnotation(method, annotation);
      }
      else
      {
         return method.getAnnotation(annotation);
      }
   }

   public static Object getAnnotation(Class<? extends Annotation> annotation, EJBContainer container, Field field, boolean isContainer)
   {
      if (isContainer)
      {
         return container.resolveAnnotation(field, annotation);
      }
      else
      {
         return field.getAnnotation(annotation);
      }
   }

   public static Class<?> injectionTarget(String encName, ResourceInjectionMetaData ref, InjectionContainer container, Map<String, Map<AccessibleObject, Injector>> classInjectors)
   {
      Class<?> injectionType = null;
     
      if(ref.getInjectionTargets() == null)
         return injectionType;
     
      for(ResourceInjectionTargetMetaData injectionTarget : ref.getInjectionTargets())
      {
         // todo, get injection target class
         AccessibleObject ao = findInjectionTarget(container.getClassloader(), injectionTarget);
         Map<AccessibleObject, Injector> injectors = classInjectors.get(injectionTarget.getInjectionTargetClass());
         if (injectors == null)
         {
            injectors = new HashMap<AccessibleObject, Injector>();
            classInjectors.put(injectionTarget.getInjectionTargetClass(), injectors);
         }
         Class<?> type;
         if (ao instanceof Field)
         {
            type = ((Field) ao).getType();
            injectors.put(ao, new JndiFieldInjector((Field) ao, encName, container.getEnc()));
         }
         else
         {
            type = ((Method) ao).getParameterTypes()[0];
            injectors.put(ao, new JndiMethodInjector((Method) ao, encName, container.getEnc()));
         }
         if(injectionType == null)
            injectionType = type;
         else
         {
            if(!injectionType.equals(type))
               throw new IllegalStateException("Found multiple injection targets with different types");
         }
      }
     
      return injectionType;
   }
}
TOP

Related Classes of org.jboss.injection.InjectionUtil

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.