You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by gp...@apache.org on 2012/01/25 00:26:08 UTC

[2/3] DELTASPIKE-58 utils and helper moved to a separated package

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/f3cc5673/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/util/Types.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/util/Types.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/util/Types.java
deleted file mode 100644
index 7d4919c..0000000
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/util/Types.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.deltaspike.core.api.util;
-
-import javax.enterprise.inject.Typed;
-import java.lang.reflect.Type;
-
-/**
- * Utilities for Types.
- */
-@Typed()
-public class Types
-{
-    private Types()
-    {
-    }
-
-    /**
-     * Gets the boxed type of a class
-     *
-     * @param type The type
-     * @return The boxed type
-     */
-    public static Type boxedType(Type type)
-    {
-        if (type instanceof Class<?>)
-        {
-            return boxedClass((Class<?>) type);
-        }
-        else
-        {
-            return type;
-        }
-    }
-
-    public static Class<?> boxedClass(Class<?> type)
-    {
-        if (!type.isPrimitive())
-        {
-            return type;
-        }
-        else if (type.equals(Boolean.TYPE))
-        {
-            return Boolean.class;
-        }
-        else if (type.equals(Character.TYPE))
-        {
-            return Character.class;
-        }
-        else if (type.equals(Byte.TYPE))
-        {
-            return Byte.class;
-        }
-        else if (type.equals(Short.TYPE))
-        {
-            return Short.class;
-        }
-        else if (type.equals(Integer.TYPE))
-        {
-            return Integer.class;
-        }
-        else if (type.equals(Long.TYPE))
-        {
-            return Long.class;
-        }
-        else if (type.equals(Float.TYPE))
-        {
-            return Float.class;
-        }
-        else if (type.equals(Double.TYPE))
-        {
-            return Double.class;
-        }
-        else if (type.equals(Void.TYPE))
-        {
-            return Void.class;
-        }
-        else
-        {
-            // Vagaries of if/else statement, can't be reached ;-)
-            return type;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/f3cc5673/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/activation/Deactivatable.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/activation/Deactivatable.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/activation/Deactivatable.java
index 8a02057..df68350 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/activation/Deactivatable.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/activation/Deactivatable.java
@@ -29,7 +29,7 @@ package org.apache.deltaspike.core.spi.activation;
  * used for other Extension libraries as well.</p>
  *
  * <p><b>Note:</b> It is suggested that the implementations
- * use the {@link org.apache.deltaspike.core.spi.activation.util.ClassDeactivation} for implementing the lookup</p>
+ * use the {@link org.apache.deltaspike.core.util.ClassDeactivation} for implementing the lookup</p>
  */
 public interface Deactivatable
 {

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/f3cc5673/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/activation/util/ClassDeactivation.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/activation/util/ClassDeactivation.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/activation/util/ClassDeactivation.java
deleted file mode 100644
index c265ad4..0000000
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/activation/util/ClassDeactivation.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.deltaspike.core.spi.activation.util;
-
-import org.apache.deltaspike.core.api.config.ConfigResolver;
-import org.apache.deltaspike.core.api.util.ClassUtils;
-import org.apache.deltaspike.core.spi.activation.ClassDeactivator;
-import org.apache.deltaspike.core.spi.activation.Deactivatable;
-
-import javax.enterprise.inject.Typed;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Logger;
-
-/**
- * Helper methods for {@link ClassDeactivator}
- */
-@Typed()
-public final class ClassDeactivation
-{
-    private static final Logger LOG = Logger.getLogger(ClassDeactivation.class.getName());
-
-    /**
-     * This Map holds the ClassLoader as first level to make it possible to have different configurations per 
-     * WebApplication in an EAR or other Multi-ClassLoader scenario.
-     * 
-     * The Map then contains a List of {@link ClassDeactivator}s in order of their configured ordinal.
-     */
-    private static Map<ClassLoader, List<ClassDeactivator>> classDeactivatorMap
-        = new ConcurrentHashMap<ClassLoader, List<ClassDeactivator>>();
-
-    /**
-     * Cache for the result. It won't contain many classes but it might be accessed frequently.
-     * Valid entries are only true or false. If an entry isn't available or null, it gets calculated.
-     */
-    private static Map<Class<? extends Deactivatable>, Boolean> activationStatusCache
-        = new ConcurrentHashMap<Class<? extends Deactivatable>, Boolean>();
-    
-    private ClassDeactivation()
-    {
-        // private ct to prevent utility class from instantiation.
-    }
-
-    /**
-     * Evaluates if the given {@link Deactivatable} is active.
-     *
-     * @param targetClass {@link Deactivatable} under test.
-     * @return <code>true</code> if it is active, <code>false</code> otherwise
-     */
-    public static boolean isActivated(Class<? extends Deactivatable> targetClass)
-    {
-        Boolean activatedClassCacheEntry = activationStatusCache.get(targetClass);
-
-        if (activatedClassCacheEntry == null)
-        {
-            initDeactivatableCacheFor(targetClass);
-            activatedClassCacheEntry = activationStatusCache.get(targetClass);
-        }
-        return activatedClassCacheEntry;
-    }
-
-    private static synchronized void initDeactivatableCacheFor(Class<? extends Deactivatable> targetClass)
-    {
-        Boolean activatedClassCacheEntry = activationStatusCache.get(targetClass);
-
-        if (activatedClassCacheEntry != null) //double-check
-        {
-            return;
-        }
-
-        List<ClassDeactivator> classDeactivators = getClassDeactivators();
-
-        Boolean isActivated = Boolean.TRUE;
-        Class<? extends ClassDeactivator> deactivatedBy = null;
-
-        LOG.fine("start evaluation if " + targetClass.getName() + " is de-/activated");
-
-        // we get the classActivators ordered by it's ordinal
-        // thus the last one which returns != null 'wins' ;)
-        for (ClassDeactivator classDeactivator : classDeactivators)
-        {
-            Boolean isLocallyActivated = classDeactivator.isActivated(targetClass);
-
-            if (isLocallyActivated != null)
-            {
-                isActivated = isLocallyActivated;
-
-                /*
-                * Check and log the details across class-deactivators
-                */
-                if (!isActivated)
-                {
-                    deactivatedBy = classDeactivator.getClass();
-                    LOG.fine("Deactivating class " + targetClass);
-                }
-                else if (deactivatedBy != null)
-                {
-                    LOG.fine("Reactivation of: " + targetClass.getName() + " by " +
-                            classDeactivator.getClass().getName() +
-                            " - original deactivated by: " + deactivatedBy.getName() + ".\n" +
-                            "If that isn't the intended behaviour, you have to use a higher ordinal for " +
-                            deactivatedBy.getName());
-                }
-            }
-        }
-
-        cacheResult(targetClass, isActivated);
-    }
-
-    private static void cacheResult(Class<? extends Deactivatable> targetClass, Boolean activated)
-    {
-        activationStatusCache.put(targetClass, activated);
-        LOG.info("class: " + targetClass.getName() + " activated=" + activated);
-    }
-
-    /**
-     * @return the List of configured @{link ClassDeactivator}s for the current context ClassLoader.
-     */
-    private static List<ClassDeactivator> getClassDeactivators()
-    {
-        ClassLoader classLoader = ClassUtils.getClassLoader(null);
-        List<ClassDeactivator> classDeactivators = classDeactivatorMap.get(classLoader);
-
-        if (classDeactivators == null)
-        {
-            return initConfiguredClassDeactivators(classLoader);
-        }
-
-        return classDeactivators;
-    }
-
-    //synchronized isn't needed - #initDeactivatableCacheFor is already synchronized
-    private static List<ClassDeactivator> initConfiguredClassDeactivators(ClassLoader classLoader)
-    {
-        List<String> classDeactivatorClassNames = ConfigResolver.getAllPropertyValues(ClassDeactivator.class.getName());
-
-        List<ClassDeactivator> classDeactivators = new ArrayList<ClassDeactivator>();
-
-        for (String classDeactivatorClassName : classDeactivatorClassNames)
-        {
-            LOG.fine("processing ClassDeactivator: " + classDeactivatorClassName);
-
-            try
-            {
-                ClassDeactivator currentClassDeactivator =
-                        (ClassDeactivator) ClassUtils.instantiateClassForName(classDeactivatorClassName);
-                classDeactivators.add(currentClassDeactivator);
-            }
-            catch (Exception e)
-            {
-                LOG.warning(classDeactivatorClassName + " can't be instantiated");
-                throw new IllegalStateException(e);
-            }
-        }
-
-        classDeactivatorMap.put(classLoader, classDeactivators);
-        return classDeactivators;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/f3cc5673/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassDeactivation.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassDeactivation.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassDeactivation.java
new file mode 100644
index 0000000..f12fea3
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassDeactivation.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.deltaspike.core.util;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+import org.apache.deltaspike.core.spi.activation.ClassDeactivator;
+import org.apache.deltaspike.core.spi.activation.Deactivatable;
+
+import javax.enterprise.inject.Typed;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+/**
+ * Helper methods for {@link ClassDeactivator}
+ */
+@Typed()
+public final class ClassDeactivation
+{
+    private static final Logger LOG = Logger.getLogger(ClassDeactivation.class.getName());
+
+    /**
+     * This Map holds the ClassLoader as first level to make it possible to have different configurations per 
+     * WebApplication in an EAR or other Multi-ClassLoader scenario.
+     * 
+     * The Map then contains a List of {@link ClassDeactivator}s in order of their configured ordinal.
+     */
+    private static Map<ClassLoader, List<ClassDeactivator>> classDeactivatorMap
+        = new ConcurrentHashMap<ClassLoader, List<ClassDeactivator>>();
+
+    /**
+     * Cache for the result. It won't contain many classes but it might be accessed frequently.
+     * Valid entries are only true or false. If an entry isn't available or null, it gets calculated.
+     */
+    private static Map<Class<? extends Deactivatable>, Boolean> activationStatusCache
+        = new ConcurrentHashMap<Class<? extends Deactivatable>, Boolean>();
+    
+    private ClassDeactivation()
+    {
+        // private ct to prevent utility class from instantiation.
+    }
+
+    /**
+     * Evaluates if the given {@link Deactivatable} is active.
+     *
+     * @param targetClass {@link Deactivatable} under test.
+     * @return <code>true</code> if it is active, <code>false</code> otherwise
+     */
+    public static boolean isActivated(Class<? extends Deactivatable> targetClass)
+    {
+        Boolean activatedClassCacheEntry = activationStatusCache.get(targetClass);
+
+        if (activatedClassCacheEntry == null)
+        {
+            initDeactivatableCacheFor(targetClass);
+            activatedClassCacheEntry = activationStatusCache.get(targetClass);
+        }
+        return activatedClassCacheEntry;
+    }
+
+    private static synchronized void initDeactivatableCacheFor(Class<? extends Deactivatable> targetClass)
+    {
+        Boolean activatedClassCacheEntry = activationStatusCache.get(targetClass);
+
+        if (activatedClassCacheEntry != null) //double-check
+        {
+            return;
+        }
+
+        List<ClassDeactivator> classDeactivators = getClassDeactivators();
+
+        Boolean isActivated = Boolean.TRUE;
+        Class<? extends ClassDeactivator> deactivatedBy = null;
+
+        LOG.fine("start evaluation if " + targetClass.getName() + " is de-/activated");
+
+        // we get the classActivators ordered by it's ordinal
+        // thus the last one which returns != null 'wins' ;)
+        for (ClassDeactivator classDeactivator : classDeactivators)
+        {
+            Boolean isLocallyActivated = classDeactivator.isActivated(targetClass);
+
+            if (isLocallyActivated != null)
+            {
+                isActivated = isLocallyActivated;
+
+                /*
+                * Check and log the details across class-deactivators
+                */
+                if (!isActivated)
+                {
+                    deactivatedBy = classDeactivator.getClass();
+                    LOG.fine("Deactivating class " + targetClass);
+                }
+                else if (deactivatedBy != null)
+                {
+                    LOG.fine("Reactivation of: " + targetClass.getName() + " by " +
+                            classDeactivator.getClass().getName() +
+                            " - original deactivated by: " + deactivatedBy.getName() + ".\n" +
+                            "If that isn't the intended behaviour, you have to use a higher ordinal for " +
+                            deactivatedBy.getName());
+                }
+            }
+        }
+
+        cacheResult(targetClass, isActivated);
+    }
+
+    private static void cacheResult(Class<? extends Deactivatable> targetClass, Boolean activated)
+    {
+        activationStatusCache.put(targetClass, activated);
+        LOG.info("class: " + targetClass.getName() + " activated=" + activated);
+    }
+
+    /**
+     * @return the List of configured @{link ClassDeactivator}s for the current context ClassLoader.
+     */
+    private static List<ClassDeactivator> getClassDeactivators()
+    {
+        ClassLoader classLoader = ClassUtils.getClassLoader(null);
+        List<ClassDeactivator> classDeactivators = classDeactivatorMap.get(classLoader);
+
+        if (classDeactivators == null)
+        {
+            return initConfiguredClassDeactivators(classLoader);
+        }
+
+        return classDeactivators;
+    }
+
+    //synchronized isn't needed - #initDeactivatableCacheFor is already synchronized
+    private static List<ClassDeactivator> initConfiguredClassDeactivators(ClassLoader classLoader)
+    {
+        List<String> classDeactivatorClassNames = ConfigResolver.getAllPropertyValues(ClassDeactivator.class.getName());
+
+        List<ClassDeactivator> classDeactivators = new ArrayList<ClassDeactivator>();
+
+        for (String classDeactivatorClassName : classDeactivatorClassNames)
+        {
+            LOG.fine("processing ClassDeactivator: " + classDeactivatorClassName);
+
+            try
+            {
+                ClassDeactivator currentClassDeactivator =
+                        (ClassDeactivator) ClassUtils.instantiateClassForName(classDeactivatorClassName);
+                classDeactivators.add(currentClassDeactivator);
+            }
+            catch (Exception e)
+            {
+                LOG.warning(classDeactivatorClassName + " can't be instantiated");
+                throw new IllegalStateException(e);
+            }
+        }
+
+        classDeactivatorMap.put(classLoader, classDeactivators);
+        return classDeactivators;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/f3cc5673/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassUtils.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassUtils.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassUtils.java
new file mode 100644
index 0000000..5c7836b
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassUtils.java
@@ -0,0 +1,276 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.deltaspike.core.util;
+
+import javax.enterprise.inject.Typed;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.jar.Manifest;
+import java.util.jar.Attributes;
+import java.net.URL;
+
+/**
+ * Util methods for classes, {@link ClassLoader} and {@link Manifest} handling
+ */
+//X TODO quite a few of this methods needs merging with Seam Solder and a few can get dropped at all.
+@Typed()
+public abstract class ClassUtils
+{
+    /**
+     * Constructor which prevents the instantiation of this class
+     */
+    private ClassUtils()
+    {
+        // prevent instantiation
+    }
+
+    /**
+     * Detect the right ClassLoader.
+     * The lookup order is determined by:
+     * <ol>
+     * <li>ContextClassLoader of the current Thread</li>
+     * <li>ClassLoader of the given Object 'o'</li>
+     * <li>ClassLoader of this very ClassUtils class</li>
+     * </ol>
+     *
+     * @param o if not <code>null</code> it may get used to detect the classloader.
+     * @return The {@link ClassLoader} which should get used to create new instances
+     */
+    public static ClassLoader getClassLoader(Object o)
+    {
+        ClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+        {
+            /**
+             * {@inheritDoc}
+             */
+            @Override
+            public ClassLoader run()
+            {
+                try
+                {
+                    return Thread.currentThread().getContextClassLoader();
+                }
+                catch (Exception e)
+                {
+                    return null;
+                }
+            }
+        }
+        );
+
+        if (loader == null && o != null)
+        {
+            loader = o.getClass().getClassLoader();
+        }
+
+        if (loader == null)
+        {
+            loader = ClassUtils.class.getClassLoader();
+        }
+
+        return loader;
+    }
+
+    /**
+     * Tries to load a class based on the given name and interface or abstract class.
+     * @param name name of the concrete class
+     * @param targetType target type (interface or abstract class)
+     * @param <T> current type
+     * @return loaded class or null if it isn't in the classpath
+     */
+    public static <T> Class<T> tryToLoadClassForName(String name, Class<T> targetType)
+    {
+        return (Class<T>) tryToLoadClassForName(name);
+    }
+
+    /**
+     * Tries to load a class based on the given name
+     * @param name name of the class
+     * @return loaded class or <code>null</code> if it isn't in the classpath
+     */
+    public static Class tryToLoadClassForName(String name)
+    {
+        try
+        {
+            return loadClassForName(name);
+        }
+        catch (ClassNotFoundException e)
+        {
+            //do nothing - it's just a try
+            return null;
+        }
+    }
+
+    /**
+     * Loads class for the given name
+     * @param name name of the class
+     * @return loaded class
+     * @throws ClassNotFoundException if the class can't be loaded
+     */
+    public static Class loadClassForName(String name) throws ClassNotFoundException
+    {
+        try
+        {
+            // Try WebApp ClassLoader first
+            return Class.forName(name, false, // do not initialize for faster startup
+                    getClassLoader(null));
+        }
+        catch (ClassNotFoundException ignore)
+        {
+            // fallback: Try ClassLoader for ClassUtils (i.e. the myfaces.jar lib)
+            return Class.forName(name, false, // do not initialize for faster startup
+                    ClassUtils.class.getClassLoader());
+        }
+    }
+
+    /**
+     * Instantiates a given class via the default constructor
+     * @param targetClass class which should be instantiated
+     * @param <T> current type
+     * @return created instance or null if the instantiation failed
+     */
+    public static <T> T tryToInstantiateClass(Class<T> targetClass)
+    {
+        try
+        {
+            return targetClass.newInstance();
+        }
+        catch (InstantiationException e)
+        {
+            //do nothing - it was just a try
+        }
+        catch (IllegalAccessException e)
+        {
+            //do nothing - it was just a try
+        }
+        return null;
+    }
+
+    /**
+     * Tries to instantiate a class for the given name and type via the default constructor
+     * @param className name of the class
+     * @param targetType target type
+     * @param <T> current type
+     * @return created instance or null if the instantiation failed
+     */
+    public static <T> T tryToInstantiateClassForName(String className, Class<T> targetType)
+    {
+        Object result = tryToInstantiateClassForName(className);
+
+        //noinspection unchecked
+        return result != null ? (T) result : null;
+    }
+
+    /**
+     * Tries to instantiate a class for the given name via the default constructor
+     * @param className name of the class
+     * @return created instance or null if the instantiation failed
+     */
+    public static Object tryToInstantiateClassForName(String className)
+    {
+        try
+        {
+            return instantiateClassForName(className);
+        }
+        catch (Exception e)
+        {
+            //do nothing - it was just a try
+        }
+        return null;
+    }
+
+    /**
+     * Creates an instance for the given class-name
+     * @param className name of the class which should be instantiated
+     * @return created instance
+     * @throws ClassNotFoundException if the instantiation failed
+     * @throws IllegalAccessException if the instantiation failed
+     * @throws InstantiationException if the instantiation failed
+     */
+    public static Object instantiateClassForName(String className)
+        throws ClassNotFoundException, IllegalAccessException, InstantiationException
+    {
+        return loadClassForName(className).newInstance();
+    }
+
+    /**
+     * Reads the version of the jar which contains the given class
+     * @param targetClass class within the jar
+     * @return version-string which has been found in the manifest or null if there is no version information available
+     */
+    public static String getJarVersion(Class targetClass)
+    {
+        String manifestFileLocation = getManifestFileLocationOfClass(targetClass);
+
+        try
+        {
+            return new Manifest(new URL(manifestFileLocation).openStream())
+                    .getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION);
+        }
+        catch (Exception e)
+        {
+            return null;
+        }
+    }
+
+    /**
+     * Reads the VCS revision which was used for creating the jar
+     * @param targetClass class within the jar
+     * @return revision-string which has been found in the manifest or null if there is no information available
+     */
+    public static String getRevision(Class targetClass)
+    {
+        String manifestFileLocation = getManifestFileLocationOfClass(targetClass);
+
+        try
+        {
+            return new Manifest(new URL(manifestFileLocation).openStream())
+                    .getMainAttributes().getValue("Revision");
+        }
+        catch (Exception e)
+        {
+            return null;
+        }
+    }
+
+    private static String getManifestFileLocationOfClass(Class targetClass)
+    {
+        String manifestFileLocation;
+
+        try
+        {
+            manifestFileLocation = getManifestLocation(targetClass);
+        }
+        catch (Exception e)
+        {
+            //in this case we have a proxy
+            manifestFileLocation = getManifestLocation(targetClass.getSuperclass());
+        }
+        return manifestFileLocation;
+    }
+
+    private static String getManifestLocation(Class targetClass)
+    {
+        String classFilePath = targetClass.getCanonicalName().replace('.', '/') + ".class";
+        String manifestFilePath = "/META-INF/MANIFEST.MF";
+
+        String classLocation = targetClass.getResource(targetClass.getSimpleName() + ".class").toString();
+        return classLocation.substring(0, classLocation.indexOf(classFilePath) - 1) + manifestFilePath;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/f3cc5673/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/HierarchyDiscovery.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/HierarchyDiscovery.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/HierarchyDiscovery.java
new file mode 100644
index 0000000..41b2f93
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/HierarchyDiscovery.java
@@ -0,0 +1,230 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.deltaspike.core.util;
+
+import javax.enterprise.inject.Typed;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Utility class for resolving all bean types from a given type.
+ */
+//X TODO: Look at merging this with ClassUtils perhaps
+//X TODO: JavaDoc
+@Typed()
+public class HierarchyDiscovery
+{
+    private final Type type;
+
+    private Map<Type, Class<?>> types;
+
+    public HierarchyDiscovery(Type type)
+    {
+        this.type = type;
+    }
+
+    protected void add(Class<?> clazz, Type type)
+    {
+        types.put(type, clazz);
+    }
+
+    public Set<Type> getTypeClosure()
+    {
+        if (types == null)
+        {
+            init();
+        }
+        // Return an independent set with no ties to the BiMap used
+        return new HashSet<Type>(types.keySet());
+    }
+
+    private void init()
+    {
+        this.types = new HashMap<Type, Class<?>>();
+        try
+        {
+            discoverTypes(type);
+        }
+        catch (StackOverflowError e)
+        {
+            System.out.println("type" + type);
+            Thread.dumpStack();
+            throw e;
+        }
+    }
+
+    public Type getResolvedType()
+    {
+        if (type instanceof Class<?>)
+        {
+            Class<?> clazz = (Class<?>) type;
+            return resolveType(clazz);
+        }
+        return type;
+    }
+
+    private void discoverTypes(Type type)
+    {
+        if (type != null)
+        {
+            if (type instanceof Class<?>)
+            {
+                Class<?> clazz = (Class<?>) type;
+                add(clazz, resolveType(clazz));
+                discoverFromClass(clazz);
+            }
+            else
+            {
+                Class<?> clazz = null;
+                if (type instanceof ParameterizedType)
+                {
+                    Type rawType = ((ParameterizedType) type).getRawType();
+                    if (rawType instanceof Class<?>)
+                    {
+                        discoverFromClass((Class<?>) rawType);
+                        clazz = (Class<?>) rawType;
+                    }
+                }
+                add(clazz, type);
+            }
+        }
+    }
+
+    private Type resolveType(Class<?> clazz)
+    {
+        if (clazz.getTypeParameters().length > 0)
+        {
+            TypeVariable<?>[] actualTypeParameters = clazz.getTypeParameters();
+
+            @SuppressWarnings("UnnecessaryLocalVariable")
+            ParameterizedType parameterizedType =
+                    new ParameterizedTypeImpl(clazz, actualTypeParameters, clazz.getDeclaringClass());
+            return parameterizedType;
+        }
+        else
+        {
+            return clazz;
+        }
+    }
+
+    private void discoverFromClass(Class<?> clazz)
+    {
+        discoverTypes(resolveType(type, type, clazz.getGenericSuperclass()));
+        for (Type c : clazz.getGenericInterfaces())
+        {
+            discoverTypes(resolveType(type, type, c));
+        }
+    }
+
+    /**
+     * Gets the actual types by resolving TypeParameters.
+     *
+     * @param beanType
+     * @param type
+     * @return actual type
+     */
+    private Type resolveType(Type beanType, Type beanType2, Type type)
+    {
+        if (type instanceof ParameterizedType)
+        {
+            if (beanType instanceof ParameterizedType)
+            {
+                return resolveParameterizedType((ParameterizedType) beanType, (ParameterizedType) type);
+            }
+            if (beanType instanceof Class<?>)
+            {
+                return resolveType(((Class<?>) beanType).getGenericSuperclass(), beanType2, type);
+            }
+        }
+
+        if (type instanceof TypeVariable<?>)
+        {
+            if (beanType instanceof ParameterizedType)
+            {
+                return resolveTypeParameter((ParameterizedType) beanType, beanType2, (TypeVariable<?>) type);
+            }
+            if (beanType instanceof Class<?>)
+            {
+                return resolveType(((Class<?>) beanType).getGenericSuperclass(), beanType2, type);
+            }
+        }
+        return type;
+    }
+
+    private Type resolveParameterizedType(ParameterizedType beanType, ParameterizedType parameterizedType)
+    {
+        Type rawType = parameterizedType.getRawType();
+        Type[] actualTypes = parameterizedType.getActualTypeArguments();
+
+        Type resolvedRawType = resolveType(beanType, beanType, rawType);
+        Type[] resolvedActualTypes = new Type[actualTypes.length];
+
+        for (int i = 0; i < actualTypes.length; i++)
+        {
+            resolvedActualTypes[i] = resolveType(beanType, beanType, actualTypes[i]);
+        }
+        // reconstruct ParameterizedType by types resolved TypeVariable.
+        return new ParameterizedTypeImpl(resolvedRawType, resolvedActualTypes, parameterizedType.getOwnerType());
+    }
+
+    private Type resolveTypeParameter(ParameterizedType type, Type beanType, TypeVariable<?> typeVariable)
+    {
+        // step1. raw type
+        Class<?> actualType = (Class<?>) type.getRawType();
+        TypeVariable<?>[] typeVariables = actualType.getTypeParameters();
+        Type[] actualTypes = type.getActualTypeArguments();
+        for (int i = 0; i < typeVariables.length; i++)
+        {
+            if (typeVariables[i].equals(typeVariable) && !actualTypes[i].equals(typeVariable))
+            {
+                return resolveType(this.type, beanType, actualTypes[i]);
+            }
+        }
+
+        // step2. generic super class
+        Type genericSuperType = actualType.getGenericSuperclass();
+        Type resolvedGenericSuperType = resolveType(genericSuperType, beanType, typeVariable);
+        if (!(resolvedGenericSuperType instanceof TypeVariable<?>))
+        {
+            return resolvedGenericSuperType;
+        }
+
+        // step3. generic interfaces
+        if (beanType instanceof ParameterizedType)
+        {
+            for (Type interfaceType : ((Class<?>) ((ParameterizedType) beanType).getRawType()).getGenericInterfaces())
+            {
+                Type resolvedType = resolveType(interfaceType, interfaceType, typeVariable);
+                if (!(resolvedType instanceof TypeVariable<?>))
+                {
+                    return resolvedType;
+                }
+            }
+        }
+
+        // don't resolve type variable
+        return typeVariable;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/f3cc5673/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ParameterizedTypeImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ParameterizedTypeImpl.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ParameterizedTypeImpl.java
new file mode 100644
index 0000000..99f7ea0
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ParameterizedTypeImpl.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.deltaspike.core.util;
+
+import javax.enterprise.inject.Typed;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+
+/**
+ * A basic implementation of {@link ParameterizedType}.
+ */
+@Typed()
+class ParameterizedTypeImpl implements ParameterizedType
+{
+    private final Type[] actualTypeArguments;
+    private final Type rawType;
+    private final Type ownerType;
+
+    ParameterizedTypeImpl(Type rawType, Type[] actualTypeArguments, Type ownerType)
+    {
+        this.actualTypeArguments = actualTypeArguments;
+        this.rawType = rawType;
+        this.ownerType = ownerType;
+    }
+
+    public Type[] getActualTypeArguments()
+    {
+        return Arrays.copyOf(actualTypeArguments, actualTypeArguments.length);
+    }
+
+    public Type getOwnerType()
+    {
+        return ownerType;
+    }
+
+    public Type getRawType()
+    {
+        return rawType;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return Arrays.hashCode(actualTypeArguments) ^ (ownerType == null ? 0 :
+                ownerType.hashCode()) ^ (rawType == null ? 0 : rawType.hashCode());
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj)
+        {
+            return true;
+        }
+        else if (obj instanceof ParameterizedType)
+        {
+            ParameterizedType that = (ParameterizedType) obj;
+            Type thatOwnerType = that.getOwnerType();
+            Type thatRawType = that.getRawType();
+            return (ownerType == null ? thatOwnerType == null : ownerType.equals(thatOwnerType))
+                    && (rawType == null ? thatRawType == null : rawType.equals(thatRawType))
+                    && Arrays.equals(actualTypeArguments, that.getActualTypeArguments());
+        }
+        else
+        {
+            return false;
+        }
+
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+        sb.append(rawType);
+        if (actualTypeArguments.length > 0)
+        {
+            sb.append("<");
+            for (Type actualType : actualTypeArguments)
+            {
+                sb.append(actualType);
+                sb.append(",");
+            }
+            sb.delete(sb.length() - 1, sb.length());
+            sb.append(">");
+        }
+        return sb.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/f3cc5673/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ProjectStageProducer.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ProjectStageProducer.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ProjectStageProducer.java
new file mode 100644
index 0000000..35abe82
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ProjectStageProducer.java
@@ -0,0 +1,218 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.deltaspike.core.util;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+import org.apache.deltaspike.core.api.projectstage.ProjectStage;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.Dependent;
+import javax.enterprise.inject.Default;
+import javax.enterprise.inject.Produces;
+import java.io.Serializable;
+import java.util.logging.Logger;
+
+/**
+ * <p>Produces {@link org.apache.deltaspike.core.api.projectstage.ProjectStage} configurations.</p>
+ *
+ * <p>The producer will try to detect the currently active ProjectStage on startup
+ * and use that for all generated fields.</p>
+ * <p>Usage:</p>
+ * Simply inject the current ProjectStage into any bean:
+ * <pre>
+ * public class MyBean {
+ *   private @Inject ProjectStage projectStage;
+ *
+ *   public void fn() {
+ *     if(projectStage == ProjectStage.Production) {
+ *        // do some prodution stuff...
+ *     }
+ *   }
+ * }
+ * </pre>
+ *
+ */
+@ApplicationScoped
+public class ProjectStageProducer implements Serializable
+{
+    protected static final Logger LOG = Logger.getLogger(ProjectStageProducer.class.getName());
+
+    private static final long serialVersionUID = -2987762608635612074L;
+
+    /**
+     * The detected ProjectStage
+     */
+    private static ProjectStage projectStage;
+
+    /**
+     * for the singleton factory
+     */
+    private static volatile ProjectStageProducer projectStageProducer;
+
+    /**
+     * ProjectStageProducers must only be created by subclassing producers
+     */
+    protected ProjectStageProducer()
+    {
+    }
+
+    /**
+     * We can only produce @Dependent scopes since an enum is final.
+     * @return current ProjectStage
+     */
+    @Produces
+    @Dependent
+    @Default
+    public ProjectStage getProjectStage()
+    {
+        if (projectStage == null)
+        {
+            //triggers initialization
+            getInstance();
+        }
+        return projectStage;
+    }
+
+    /**
+     * <p>This factory method should only get used if there is absolutly no way
+     * to get the current {@link ProjectStage} via &#064;Inject.</p>
+     *
+     * <p></p>
+     *
+     * @return the ProjectStageProducer instance.
+     */
+    public static ProjectStageProducer getInstance()
+    {
+        if (projectStageProducer == null)
+        {
+            lazyInit();
+        }
+
+        if (projectStage == null)
+        {
+            projectStageProducer.initProjectStage();
+        }
+
+        return projectStageProducer;
+    }
+
+    private static synchronized void lazyInit()
+    {
+        // switch into paranoia mode
+        if (projectStageProducer != null)
+        {
+            return;
+        }
+
+        String customProjectStageProducerName = ConfigResolver.getPropertyValue(ProjectStageProducer.class.getName());
+
+        if (customProjectStageProducerName != null)
+        {
+            //e.g. the JSF module can provide a config-source implementation which
+            //returns a custom implementation which is aware of the JSF project-stage
+            //if a custom ProjectStageProducer is needed a custom config-source with a higher ordinal can be used
+            ProjectStageProducer customConfiguredProducer =
+                    ClassUtils.tryToInstantiateClassForName(customProjectStageProducerName, ProjectStageProducer.class);
+
+            if (customConfiguredProducer != null)
+            {
+                projectStageProducer = customConfiguredProducer;
+
+                LOG.fine("Using custom project-stage-producer: " + customConfiguredProducer.getClass().getName());
+            }
+            else
+            {
+                LOG.warning("Custom project-stage-producer couldn't be instantiated - class-name: " +
+                        customProjectStageProducerName);
+            }
+        }
+
+        if (projectStageProducer == null)
+        {
+            projectStageProducer = new ProjectStageProducer();
+        }
+
+        projectStageProducer.initProjectStage();
+    }
+
+    /**
+     * Resolves the project-stage configured for DeltaSpike
+     * @return the resolved {@link ProjectStage} or <code>null</code> if none defined.
+     */
+    protected ProjectStage resolveProjectStage()
+    {
+        String stageName = ConfigResolver.getPropertyValue("org.apache.deltaspike.ProjectStage");
+
+        if (stageName != null)
+        {
+            return ProjectStage.valueOf(stageName);
+        }
+
+        return null;
+    }
+
+    protected void initProjectStage()
+    {
+        // switch into paranoia mode
+        synchronized (ProjectStageProducer.class)
+        {
+            if (projectStage == null)
+            {
+                projectStage = resolveProjectStage();
+
+                if (projectStage == null)
+                {
+                    projectStage = ProjectStage.Production;
+                }
+
+                LOG.info("Computed the following DeltaSpike ProjectStage: " + projectStage);
+            }
+        }
+    }
+
+    /*
+     * Methods which might be needed for unti tests
+     */
+
+    /**
+     * Can be used esp. for internal tests.
+     * Usage:
+     * <pre>
+     * new ProjectStageProducer() {
+     *     @Override
+     *     protected void reset() { super.reset(); }
+     * }.reset();
+     * </pre>
+     */
+    protected void reset()
+    {
+        projectStage = null;
+        projectStageProducer = null;
+    }
+
+    /**
+     * This function can be used to manually set the ProjectStage for the application.
+     * This is e.g. useful in unit tests.
+     * @param ps the ProjectStage to set
+     */
+    public static void setProjectStage(ProjectStage ps)
+    {
+        projectStage = ps;
+    }
+}