package org.ovirt.engine.core.di;

import javax.annotation.PostConstruct;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.InjectionTarget;
import javax.inject.Inject;
import javax.inject.Singleton;

/**
 * an application wide interaction point with the CDI container mostly to gap all the existing unmanged code
 * or for unmanaged code which wants interaction with managed beans.
 * Typically this injector could be used anywhere to get a manage instance from instances which
 * aren't managed like some utility singletons etc
 */
@Singleton
public class Injector {

    private static Injector injector;

    @Inject
    private BeanManager manager;

    @PostConstruct
    private void init() {
        injector = this;
    }

    /**
     * This method will take an instance and will fulfill all its dependencies, which are members
     * annotated with <code>@Inject</code>.
     * @param instance unmanaged CDI bean, essentially a regular object which is not managed by
     *                  the CDI container.
     * @param <T> an unmanaged CDI instance with some members containing <code>@Inject</code> annotated
     *           members
     */
    public static <T> T injectMembers(T instance) {
        AnnotatedType type = injector.manager.createAnnotatedType(instance.getClass());
        InjectionTarget injectionTarget = injector.manager.createInjectionTarget(type);
        injectionTarget.inject(instance, injector.manager.createCreationalContext(null));
        injectionTarget.postConstruct(instance);
        return instance;
    }

    /**
     * This method will fetch a managed CDI bean from the CDI container.
     * Using this method should help us bridge all places where we are in unmanaged instances
     * and we want an already managed instance. e.g all our Singletons getInstance methods are candidates for this usage,
     * meaning we Make the Singleton a manged bean but let the existing code still
     * get a reference by invoking getInstance which delegate to this method.
     * @param clazz the Runtime class representing the desired instance
     * @param <T>
     * @return the instance of type <code><T></T></code> which is manged by the CDI container
     */
    public static <T extends Object> T get(Class<T> clazz) {
        return injector.instanceOf(clazz);
    }

    /**
     * convenience method, good for mocking and whoever holds a direct instance of Injector in hand.<br>
     * after all its a jdk "bug" to call a static method on an instance.<br>
     *{@link Injector#get(Class)} should supply the same behaiour exactly
     * @param clazz
     * @param <T>
     * @return instance of T
     * @see #get(Class)
     */
    public <T extends Object> T instanceOf(Class<T> clazz) {
        Bean bean = injector.manager.getBeans(clazz).iterator().next();
        return (T) injector.manager.getReference(bean, clazz, injector.manager.createCreationalContext(bean));
    }
}

@@ -422,16 +422,17 @@
 ng unman
+a
 ged code
@@ -432,16 +432,16 @@
 ed code%0A
-
  * or fo
@@ -1268,32 +1268,83 @@
 members%0A     */%0A
+    @SuppressWarnings(%7B %22unchecked%22, %22rawtypes%22 %7D)%0A
     public stati
@@ -2061,24 +2061,25 @@
 gleton a man
+a
 ged bean but
@@ -2344,16 +2344,17 @@
 h is man
+a
 ged by t
@@ -2744,11 +2744,11 @@
 beha
+v
 io
-u
 r ex
@@ -2844,32 +2844,67 @@
 (Class)%0A     */%0A
+    @SuppressWarnings(%22unchecked%22)%0A
     public %3CT ex
@@ -2940,32 +2940,32 @@
 ass%3CT%3E clazz) %7B%0A
-
         Bean bea
@@ -2960,16 +2960,19 @@
     Bean
+%3C?%3E
  bean = 

Fix typos and suppress warnings in Injector